分类: Windows平台
2015-03-06 16:14:53
重要函数学习:IoBuildDeviceIoControlRequest
这个函数主要用来构造一个用于设备i/o控制请求的irp包,该irp包将被同步处理,其原型如下:
参数解释:
IoControlCode
提供i/o控制请求所需的i/o控制码。这个i/o控制码可以在msdn中查询到。
DeviceObject
指向下层驱动的设备对象的指针。这个就是构造的irp要被发向的目标对象。
InputBuffer
指向输入缓冲区的指针,这个缓冲区中的内容是给下层驱动使用的。此指针可为NULL。
InputBufferLength
输入缓冲区的长度,按字节计算。如果InputBuffer为NULL,则此参数必须为0。
OutputBuffer
指向输出缓冲区的指针,这个缓冲区是用于给下层驱动返回数据用的。此指针可为NULL。
OutputBufferLength
输出缓冲区的长度,按字节计算。如果OutputBuffer为NULL,则此参数必须为0。
InternalDeviceIoControl
如果此参数为TRUE,这个函数设置所构造的irp的主函数码(major function code)为IRP_MJ_INTERNAL_DEVICE_CONTROL,否则这个函数设置所构造的irp的主函数码(major function code)为IRP_MJ _DEVICE_CONTROL。
Event
提供一个指向事件对象的指针,该事件对象由调用者分配并初始化。当下层驱动程序完成这个irp请求时i/o管理器将此事件对象设置为通知状态(signaled)。当调用IoCallDriver后,调用者可以等待这个事件对象成为通知状态。
IoStatusBlock
调用者指定一个i/o状态块,当这个irp完成时,下层驱动会把相应信息填入这个i/o状态块。
关于返回:
当这个函数调用成功时,将返回一个指向所构造的irp的指针并且下一层驱动的i/o堆栈会根据调用此函数提供的参数设置好,若调用失败,将返回NULL。
注意事项:
1、 此函数构造的irp包将被同步处理。当构造好irp包后,调用者调用IoCallDriver将这个irp发送给目标对象,如果IoCallDriver返回STATUS_PENDING,调用者必须调用KeWaitForSingleObject等待调用IoBuildDeviceIoControlRequest时所提供的那个Event。对于大多数的驱动程序我们不用给该irp设置完成函数。
2、 由IoBuildDeviceIoControlRequest构造的irp必须由某个驱动调用IoCompleteRequest来完成,并且注意调用IoBuildDeviceIoControlRequest的驱动程序不能调用IoFreeIrp来释放这些构造的irp,因为i/o管理器会在IoCompleteRequest被调用后自动释放这些irp。
3、 IoBuildDeviceIoControlRequest将把它构造的irp放在当前线程特有的一个irp队列上,如果当前线程退出,则i/o管理器将取消这些irp。
4、 InputBuffer和OutputBuffer这两个参数如何存放在所构造的irp中将取决于IoControlCode的TransferTyp