将 I/O 请求重新排队
驱动程序可以重新排队从 I/O 队列获取的 I/O 请求。 驱动程序可以将 I/O 请求重新排到驱动程序为同一设备创建的另一个 I/O 队列。 此外, 总线驱动程序 可以将 I/O 请求从子设备的 I/O 队列重新排队到父设备的 I/O 队列。
将 I/O 请求重新排队到设备的不同 I/O 队列
在驱动程序的请求处理程序从驱动程序的 I/O 队列收到 I/O 请求后,驱动程序可以调用 WdfRequestForwardToIoQueue 将请求重新排队到另一个队列。
例如,如果希望驱动程序在处理请求之前将资源分配给请求,驱动程序的 EvtIoDefault 回调函数可以接收所有请求,将资源信息存储在每个请求的上下文内存中,然后调用 WdfRequestForwardToIoQueue 将每个请求重新排队到其他队列。
如果驱动程序调用 WdfRequestForwardToIoQueue 来重新排队驱动程序从使用顺序 调度方法的 I/O 队列中获取的 I/O 请求,则框架会将下一个 I/O 请求从顺序队列传递到驱动程序,而无需等待重新排队的请求完成。
如果驱动程序使用手动调度方法,它可以调用 WdfRequestRequeue 方法,将 I/O 请求返回到驱动程序从中获取它的 I/O 队列的头。 调用 WdfRequestRequeue 后,驱动程序对 WdfIoQueueRetrieveNextRequest 的下一次调用将检索重新排队的请求。
将 I/O 请求重新排队到父设备的 I/O 队列
父设备的函数驱动程序可以充当 总线驱动程序 ,该驱动程序 枚举 父设备的子设备,并为子 设备创建物理设备对象 (PDO) 。 此类驱动程序有时可以接收父设备必须处理的子设备的 I/O 请求。
例如,协议总线 ((如 USB) )通常控制分配给每个已连接设备的硬件资源。 因此,父总线的函数驱动程序通常处理每个子设备的 I/O 操作。 当 I/O 管理器将 I/O 请求发送到其中一个子 设备的设备堆栈 时,总线的函数驱动程序会在子设备的某个 I/O 队列中接收 I/O 请求,因为该驱动程序创建了子设备的 PDO。 在驱动程序可以在父总线设备的上下文中处理 I/O 请求之前,它必须将子设备的 I/O 队列中的 I/O 请求重新排队到属于父设备的 I/O 队列。
但是,驱动程序无法调用 WdfRequestForwardToIoQueue 将请求从子队列移动到父队列。 由于 I/O 管理器为父设备和子设备创建单独的设备堆栈,因此必须先将基础 WDM 设备对象从表示子设备的对象更改为表示父设备的对象。
在 KMDF 版本 1.9 之前,驱动程序只能通过创建远程 I/O 目标、增加子设备的设备堆栈大小以及指定正确的 WDM 设备对象,将 I /O 请求从子设备发送到其父设备。
从 KMDF 版本 1.9 开始,驱动程序可以在创建子设备之前调用 WdfPdoInitAllowForwardingRequestToParent ,然后调用 WdfRequestForwardToParentDeviceIoQueue 以将请求从子级 I/O 队列重新排队到父队列。 如果驱动程序使用WdfPdoInitAllowForwardingRequestToParent 和 WdfRequestForwardToParentDeviceIoQueue,框架将增加子级的设备堆栈大小,并将正确的 WDM 设备对象分配给 I/O 请求。