(IoRequestDpc),等待一个驱动程序提供的 DPC(延迟过程调
用)例程以在比 ISR 更低的硬件优先级上完成请求的操作。
9) 当驱动程序的 DPC 获得控制,它使用环境(在 ISR 的调用中被传递给
IoRequestDpc)以完成 I/O 操作。DPC 调用支持例程将下一个 IRP
(如果有)取出队列,然后传递这个 IRP 到驱动程序提供的例程上,这
个例程在设备上开始 I/O 操作(见第 5 步)。DPC 然后在 IRP 的 I/O 状
态块中设置刚刚完成的操作的状态,并使用 IoCompleteRequest 将
它返回给 I/O 管理器。
10)I/O 管理器将 IRP 中最低层的驱动程序的 I/O 栈位置赋零,并用 FSD 分
配的 IRP 调用文件系统的已注册的完成例程(见第 3 步)。这个完成例
程检查 I/O 状态块,以确定是否重试请求或更新任何保存原始请求的内
部状态,以及是否释放它的驱动程序分配的 IRP。文件系统能收集所有
驱动程序分配的发送给低层驱动程序的 IRP 的状态信息,所以它能设置
I/O 状态,并能完成原始 IRP。当文件系统完成原始 IRP,I/O 管理器返
回 Windows NT 状态给 I/O 操作的原始请求者(子系统的本地函数)。
注意:任何分配 IRP 给低层驱动程序的高层驱动程序通过设置相邻的较低
层驱动程序的设备对象的 StackSize 值,来决定新 IRP 拥有多少 I/O 栈位
置。
3. IRP 中每个驱动程序指定的 I/O 栈位置包含了下列通用的信息:
1) 主功能代码(IRP_MJ_XXX),指定驱动程序应该完成的基本操作
2) 对于一些被 FSD 操纵的主功能代码、更高层 SCSI 驱动程序、和所有的
PnP 驱动程序,一个次功能代码(IRP_MN_XXX),指明驱动程序应该
完成的基本操作的子项。
3) 一组操作特定的参数,例如驱动程序用来传递数据的缓冲区的大小和起
始位置。
4) 指向驱动程序创建的设备对象的指针,为请求操作描述目标设备(物理
的、逻辑的或虚拟的)
5) 指向文件对象的指针,描述打开的文件、设备、目录或卷
4. 低层驱动程序(包括 PnP 函数和过滤器驱动程序)和中间层驱动程序通常
操作下列基本请求集:
1) IRP_MJ_CREATE——打开目标设备对象,指明它对 I/O 操作是现存的和
可用的;