如何在 Dispatch 例程中完成 IRP

如果输入 IRP 可以立即完成,则调度例程将执行以下操作:

  1. 通常 ,使用 适当的值设置 IRP 的 I/O 状态块的 Status 和 Information 成员:

    • 调度例程将 “状态” 设置为STATUS_SUCCESS或 (STATUS_XXX) 的相应错误,可以是调用支持例程返回的值,或者对于某些同步请求,由较低驱动程序返回的值。

      如果较低级别的驱动程序返回STATUS_PENDING,则较高级别的驱动程序不应为 IRP 调用 IoCompleteRequest ,但有一个例外:较高级别的驱动程序可以使用 事件在其 IoCompletion 例程和调度例程之间同步,在这种情况下, IoCompletion 例程会发出事件信号并返回STATUS_MORE_PROCESSING_REQUIRED。 调度例程等待事件,然后调用 IoCompleteRequest 以完成 IRP。

    • 它将 “信息” 设置为满足数据传输请求(如读取或写入请求)时成功传输的字节数。

    • 它将 “信息” 设置为一个值,该值根据STATUS_SUCCESS完成的其他 IRP 的特定请求而异。

    • 它将 “信息” 设置为一个值,该值根据 IRP 的特定请求而变化,该请求完成时会发出警告STATUS_XXX。 例如,它会将 “信息” 设置为为STATUS_BUFFER_OVERFLOW等警告传输的字节数。

    • 通常,对于其完成且STATUS_XXX 错误的请求,它将“信息”设置为零。

  2. 使用 IRP 和 PriorityBoost = IO_NO_INCREMENT 调用 IoCompleteRequest

  3. 返回已在 I/O 状态块中设置的相应STATUS_XXX 。 请注意,调用 IoCompleteRequest 会使给定的 IRP 不可被调用方访问,因此无法从已完成的 IRP 的 I/O 状态块设置调度例程的返回值。

遵循以下实现准则,使用 IRP 调用 IoCompleteRequest:

在调用 IoCompleteRequest 之前,始终释放驱动程序持有) (的任何旋转锁。

完成 IRP 需要不确定的时间,尤其是在分层驱动程序链中。 此外,如果较高级别的驱动程序的 IoCompletion 例程将 IRP 向下发送到持有旋转锁的较低驱动程序,则可能会出现死锁。