Windows内核学习笔记(六)-- [总结]创建IRP的四种不同方式

来源:互联网 发布:个人信用查询软件 编辑:程序博客网 时间:2024/06/06 05:34

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

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

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

1.      可创建的IRP类型

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

2.      创建后IRP对象的删除

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

3.      关联的事件

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

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

 

原创粉丝点击