读/写 Dispatch 例程摘要

实现 DispatchReadDispatchWrite 或 DispatchReadWrite 例程时,请记住以下几点:

  • 分层驱动程序链中最高级别的驱动程序负责检查传入读/写 IRP 的参数以确保有效性,然后再在 IRP 中设置下一个较低级别的驱动程序的 I/O 堆栈位置。

  • 中间和最低级别的驱动程序通常可以依赖于其链中的最高级别驱动程序来传递具有有效参数的传输请求。 但是,任何驱动程序都可以对其 IRP 的 I/O 堆栈位置中的参数执行健全性检查,并且每个设备驱动程序应检查可能违反其设备施加的任何限制的条件的参数。

  • 如果 DispatchReadWrite 例程完成 IRP 时出现错误,则应使用适当的 NTSTATUS 类型值设置 I/O 堆栈位置 Status 成员,将 Information 成员设置为零,并使用 IRP 和 PriorityBoost IO_NO_INCREMENT调用 IoCompleteRequest

  • 如果驱动程序使用缓冲 I/O,则它可能需要定义一个结构来包含要传输的数据,并且可能需要在内部缓冲其中一些结构。

  • 如果驱动程序使用直接 I/O,则可能需要检查 Irp-MdlAddress> 中的 MDL 描述的是包含太多数据 (的缓冲区,还是) 过多的分页符,以便基础设备在单个传输操作中进行处理。 如果是这样,驱动程序必须将原始传输请求拆分为较小的传输操作序列。

    紧密耦合的类驱动程序可能会在其基础端口驱动程序的 DispatchReadWrite 例程中拆分此类请求。 为此,需要 SCSI 类驱动程序(尤其是对于大容量存储设备)。 有关 SCSI 驱动程序要求的详细信息,请参阅 存储驱动程序

  • 较低级别设备驱动程序的 DispatchReadWrite 例程应推迟将大型传输请求拆分为部分传输,直到另一个驱动程序例程取消 IRP 排队以设置设备进行传输。

  • 如果较低级别的设备驱动程序将读/写 IRP 排队,以供其自己的例程进一步处理,则必须在将 IRP 排队之前调用 IoMarkIrpPending 。 在这些情况下 ,DispatchReadWrite 例程还必须返回具有STATUS_PENDING的控制。

  • 如果 DispatchReadWrite 例程将 IRP 传递给较低的驱动程序,则必须为 IRP 中下一个较低级别的驱动程序设置 I/O 堆栈位置。 在将 IoCallDriver 传递到 IRP 之前,较高级别的驱动程序是否还在 IRP 中设置 IoCompletion 例程,取决于驱动程序的设计以及该驱动程序下分层的设计。

    但是,如果较高级别的驱动程序分配了任何资源(如 IRP 或内存),则必须在调用 IoCallDriver 之前调用 IoSetCompletionRoutine。 其 IoCompletion 例程必须释放驱动程序分配的任何资源时,较低的驱动程序已完成请求,但在 IoCompletion 例程使用原始 IRP 调用 IoCompleteRequest 之前。

  • 如果较高级别的驱动程序为可能包含基础可移动媒体设备驱动程序的较低驱动程序分配 IRP,则分配驱动程序必须在它分配的每个 IRP 中建立线程上下文。