I/O 请求数据包
发送到设备驱动程序的大部分请求都打包在 I/O 请求数据包 (IRP) 中。 操作系统组件或驱动程序将 IRP 发送到驱动程序,方法是调用 IoCallDriver,它有两个参数:指向 DEVICE_OBJECT 的指针和指向 IRP 的指针。 DEVICE_OBJECT 具有指向关联 DRIVER_OBJECT 的指针。 当组件调用 IoCallDriver 时,我们说组件“将 IRP 发送到设备对象”或“将 IRP 发送到与设备对象关联的驱动程序”。 有时,我们使用短语“传递 IRP”或“转发 IRP”而非“发送 IRP”。
通常,IRP 由在堆栈中排列的多个驱动程序进行处理。 堆栈中的每个驱动程序都与一个设备对象相关联。 有关详细信息,请参阅设备节点和设备堆栈。 如果 IRP 由设备堆栈进行处理,则通常先将 IRP 发送至设备堆栈中的顶部设备对象。 例如,如果 IRP 由此图所示的设备堆栈进行处理,则会先将 IRP 发送至设备堆栈顶部的筛选器设备对象(筛选器 DO)。
沿着设备堆栈向下传递 IRP
假设 I/O 管理器将 IRP 发送至图中的筛选器 DO。 与筛选器 DO 关联的驱动程序 AfterThought.sys 处理 IRP,然后将其传递至功能设备对象 (FDO),该对象是设备堆栈中下一个低层设备对象。 当驱动程序将 IRP 传递至设备堆栈中下一个低层设备对象时,我们说驱动程序“沿着设备堆栈向下传递 IRP”。
某些 IRP 会沿着设备堆栈一路向下传递至物理设备对象 (PDO)。 其他 IRP 从未到达 PDO,因为这些 IRP 由 PDO 上面的驱动程序之一完成。
IRP 为自包含
从某种意义上说,IRP 结构是自包含结构,因为它包含驱动程序处理 I/O 请求所需的所有信息。 IRP 结构的某些部分包含堆栈中所有参与驱动程序共同的信息。 IRP 的其他部分包含特定于堆栈中特定驱动程序的信息。