使用直接 I/O 执行 DispatchReadWrite

任何为直接 I/O 设置其设备对象的较低级别设备驱动程序都通过返回从设备传输到系统物理内存的数据(由 Irp-MdlAddress> 上的 MDL 描述)满足读取请求。 它通过将数据从系统物理内存传输到其设备来满足写入请求。

较低级别的驱动程序必须异步处理读/写请求。 因此,每个较低级别的驱动程序 的 DispatchReadWrite 例程都必须将具有有效参数 的IRP_MJ_READIRP_MJ_WRITE IRP 传递给其他驱动程序例程,如将 IRP 传递到驱动程序堆栈中所述。

对于发送到较低级别驱动程序的读/写 IRP>Irp-MdlAddress> 中 MDL 描述的分页物理内存已被检查以确认拥有正确的访问权限从而执行请求的传输,并且已被链中最高级别驱动程序或 I/O 管理器锁定。 任何为直接 I/O 设置其设备对象的中间或最低级别驱动程序都不应调用 MmProbeAndLockPages, 因为这已经完成。 最低级别的驱动程序调用 MmGetSystemAddressForMdlSafe。 (Windows 98 驱动程序改为调用 MmGetSystemAddressForMdl 。Windows Me、Windows 2000 及更高版本的 Windows 驱动程序应使用 MmGetSystemAddressForMdlSafe。)

任何中间级别或最低级别的设备驱动程序 的 DispatchReadWrite 例程都应验证其读取/写入 IRP 的 I/O 堆栈位置中的参数(如果无法信任更高级别的驱动程序仅传递具有有效参数的 IRP)。 如果 DispatchReadWrite 例程发现参数错误,则应根据完成 IRP中所述,用适当的 STATUS_XXX 错误值来完成 IRP。 如果参数有效,则中间驱动程序的 DispatchReadWrite 例程必须根据 Higher-Level Drivers 中的 DispatchReadWrite 中的准则传递请求以供进一步处理。

最低级别的设备驱动程序 的 DispatchReadWrite 例程必须调用 IoMarkIrpPending 和传输请求,传递 IRP 以供其他驱动程序例程进一步处理,并返回STATUS_PENDING,如在 驱动程序堆栈中传递 IRP 中所述。

请注意,设备驱动程序的 DispatchReadWrite 例程可以通过使用驱动程序确定的密钥值调用 IoStartPacket 来控制 I/O 队列到其设备的顺序,以加快 I/O 吞吐量。 驱动程序中的另一个例程会在稍后出队 IRP,确定请求的长度是否必须拆分为部分传输操作,并对设备进行编程以传输数据。

通常,必须拆分大型传输请求以适应设备限制的设备驱动程序应推迟这些操作,直到为给定传输请求设置设备前的最后阶段。 此类设备驱动程序的 DispatchReadWrite 例程不应检查传入 IRP 的 I/O 堆栈位置是否有任何特定于设备的传输约束,也不应尝试计算部分传输范围,当驱动程序可以推迟这些检查,直到其 StartIo (或其他驱动程序例程)对设备进行传输作之前。