创建IRP的四种不同方式

在驱动程序中,经常会调用其他的驱动程序;其中,手动构造 IRP ,然后将 IRP 传递到相应驱动程序的派遣函数中是一种比较简单的方法,下面就来介绍下手动创建 IRP 的几种不同的方法及其特点。

         创建 IRP 总共有 4 种方法。分别通过调用: IoBuildSynchronousFsdRequest 、 IoBuildAsynchronousFsdRequest 、 IoBuildDeviceIoControl 和 IoAllocateIrp 这 4 个内核函数来完成。这其中, IoAllocateIrp 是比较底层的内核函数,其余的三个内核函数是属于靠近上层的内核函数,而且这三个函数都是通过调用 IoAllocateIrp 实现的。

         这几个函数都是文档化的函数,原型都可以在 DDK Documentation 中查到,这里就不多说了,下面主要来说说它们的不同点:

1.       可创建的 IRP 类型

这四个函数可以创建的 IRP 的类型是不同的。 IoBuildSynchronousFsdRequest 用于创建同步的 IRP 请求,但是只可以创建以下类型的 IRP : IRP_MJ_PNP ,IRP_MJ_READ,IRP_MJ_WRITE,IRP_MJ_FLUSH_BUFFERS 和IRP_MJ_SHUTDOWN ; IoBuildAsynchronousFsdRequest 可创建的 IRP 类型和 IoBuildSynchronousFsdRequest 一样(从名字就可以看出来),只是它是用来创建异步的 IRP 请求。 IoBuildDeviceIoControl 可以创建的 IRP 类型为:IRP_MJ_DEVICE_CONTROL 和IRP_MJ_INTERNAL_DEVICE_CONTROL 。而且 IoBuildDeviceIoControl 只能创建同步的 IRP 。在这三个函数中,都有一个 ULONG 的输入参数指定创建的 IRP 类型。 IoAllocateIrp 函数的使用比较灵活,他可以创建任意类型的 IRP ,但不是由参数指定,而是创建后自行填写,要求用户对 IRP 的结构有比较熟悉的理解。

2.       创建后 IRP 对象的删除

IoBuildSynchronousFsdRequest 、 IoBuildAsynchronousFsdRequest 和 IoBuildDeviceIoControl 内核函数在创建完 IRP 后,不需要程序员负责删除 IRP ,操作系统会自动删除。而用 IoAllocateIrp 内核函数创建 IRP 时,需要程序员自己调用 IoFreeIrp 内核函数删除 IRP 对象。

3.       关联的事件

IoBuildSynchronousFsdRequest 和 IoBuildDeviceIoControl 在创建 IRP 时,需要为它们准备好一个事件,这个事件会和 IRP 请求相关联,当 IRP 请求被结束时该事件触发。程序中要用 KeWaitForSingleObject 函数等待。 IoBuildAsynchronousFsdRequest 函数创建 IRP 时则不需要准备事件,不过可以通过 IRP 的 UserEvent 子域来通知 IRP 请求的结束。

当执行 IoCompleteRequest 内核函数时,操作系统会检查 IRP 的 UserEvent 子域是否为空。如果该子域为空,则它代表一个事件指针,这时 IoCompleteRequest 会设置这个事件。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/vangoals/archive/2009/07/26/4381567.aspx

你可能感兴趣的:(创建IRP的四种不同方式)