用户模式下对所有驱动程序的I/O请求都会,全部由操作系统转化为一个叫做IRP(I/O Request Package)的数据结构,不同的IRP数据结构会被派遣到不同的派遣函数中进行请求的处理。
在一个驱动程序中对应的DriverObject中,有个函数指针数组MajorFunction,里面存放的是派遣函数的地址,通过这个数组,可以将IRP请求与对应的派遣函数关联起来。
接下来首先介绍一个重要的数据结构I/O堆栈,IO_STACK_LOCATION,这个数据结构和IRP紧密相连。每一个IRP都会被操作系统发送到设备栈的顶层,如果顶层设备对象的派遣函数结束了IRP请求,则这次I/O请求结束。如果没有将IRP的请求结束,那么操作系统将IRP转发到设备栈的下一层去设备处理,一直到IRP请求被设备对象处理,则停止向下转发。
因此一个IRP就可能被转发很多次,那么我们怎么记录这些操作和需要操作的数据呢?IRP中有一个IO_STACK_LOCATION数组,数组的元素应该大于IRP穿越过的设备数,每个IO_STACK_LOCATION元素记录着对应设备中做的操作。对于本层设备对应的IO_STACK_LOCATION,可以通过IoGetCurrentIrpStackLocation来得到。
#