使用直接 I/O 执行 DispatchReadWrite
为直接 I/O 设置设备对象的任何较低级别设备驱动程序都通过返回从设备传输到系统物理内存的数据来满足读取请求,这由 Irp-MdlAddress> 处的 MDL 描述。 它通过将数据从系统物理内存传输到其设备来满足写入请求。
较低级别的驱动程序必须异步处理读/写请求。 因此,每个较低级别驱动程序的 DispatchReadWrite 例程都必须 将IRP_MJ_READ 并将具有有效参数 IRP_MJ_WRITE IRP 传递给其他驱动程序例程,如 将 IRP 向下传递驱动程序堆栈中所述。
对于发送到较低级别驱动程序的读/写 IRP,已探测 MDL 在 Irp-MdlAddress> 处描述的分页物理内存,以获取执行请求的传输的正确访问权限,并且已被链中的最高级别驱动程序或 I/O 管理器锁定。 为直接 I/O 设置其设备对象的任何中间或最低级别驱动程序不应调用 MmProbeAndLockPages ,因为这已经完成。 最低级别的驱动程序调用 MmGetSystemAddressForMdlSafe。 (Windows 98 驱动程序改为调用 MmGetSystemAddressForMdl 。Windows Me、Windows 2000 及更高版本的 Windows 驱动程序应使用 MmGetSystemAddressForMdlSafe.)
如果任何中间或最低级别设备驱动程序的 DispatchReadWrite 例程无法信任较高级别的驱动程序仅传递具有有效参数的 IRP,则应验证读/写 IRP 的 I/O 堆栈位置中的参数。 如果 DispatchReadWrite 例程发现参数错误,它应使用适当的错误STATUS_XXX 值完成 IRP,如 完成 IRP 中所述。 如果参数有效,则中间驱动程序的 DispatchReadWrite 例程必须根据 Higher-Level Drivers 中的 DispatchReadWrite 中的准则传递请求,以便进一步处理。
最低级别设备驱动程序的 DispatchReadWrite 例程必须使用传输请求调用 IoMarkIrpPending ,传递 IRP 以供其他驱动程序例程进一步处理,并返回STATUS_PENDING,如在 驱动程序堆栈中传递 IRP 中所述。
请注意,设备驱动程序的 DispatchReadWrite 例程可以通过使用驱动程序确定的 Key 值调用 IoStartPacket 来控制 IRP 排队到其设备的顺序,以加快 I/O 吞吐量。 驱动程序中的另一个例程稍后取消 IRP 的排队,确定是否必须将请求的长度拆分为部分传输操作,并对设备进行程序以传输数据。
通常,必须拆分大型传输请求以满足其设备限制的设备驱动程序应将这些操作推迟到为给定传输请求设置设备之前。 此类设备驱动程序的 DispatchReadWrite 例程不应针对任何特定于设备的传输约束检查传入 IRP 的 I/O 堆栈位置,也不应尝试计算部分传输范围,而驱动程序可以将这些检查推迟到其 StartIo (或其他驱动程序例程) 设备进行传输操作。