重要函数学习:IoBuildDeviceIoControlRequest

来源:互联网 发布:centos路由跟踪命令 编辑:程序博客网 时间:2024/05/16 14:35

重要函数学习:IoBuildDeviceIoControlRequest

这个函数主要用来构造一个用于设备i/o控制请求的irp包,该irp包将被同步处理,其原型如下:

 

 

参数解释:

       IoControlCode      

              提供i/o控制请求所需的i/o控制码。这个i/o控制码可以在msdn中查询到。

       DeviceObject

              指向下层驱动的设备对象的指针。这个就是构造的irp要被发向的目标对象。

       InputBuffer

指向输入缓冲区的指针,这个缓冲区中的内容是给下层驱动使用的。此指针可为NULL

       InputBufferLength

              输入缓冲区的长度,按字节计算。如果InputBufferNULL,则此参数必须为0

       OutputBuffer

指向输出缓冲区的指针,这个缓冲区是用于给下层驱动返回数据用的。此指针可为NULL

       OutputBufferLength

              输出缓冲区的长度,按字节计算。如果OutputBufferNULL,则此参数必须为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、  InputBufferOutputBuffer这两个参数如何存放在所构造的irp中将取决于IoControlCodeTransferType,具体可查相关资料。

5、  IoBuildDeviceIoControlRequest的调用者必须运行在IRQL <= APC_LEVEL

6、  这个函数并不初始化所构造irp中的FileObject指针,因此如果你在写和文件系统相关的驱动,你必须自己初始化这个指针。

7、  使用IoBuildDeviceIoControlRequest构造的irp其主函数代码只能是IRP_MJ_DEVICE_CONTROL IRP_MJ_INTERNAL_DEVICE_CONTROL

 

 

 

 

 

 

 

 

原创粉丝点击