如何在 Dispatch 例程中完成 IRP

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

  1. 用适当的值设置 IRP 的 i/o 状态块的 状态信息 成员,一般为:

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

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

    • 如果满足了传输数据(如读取或写入请求)的请求,则它会将 信息 设置为成功传输的字节数。

    • 它将 信息 设置为一个值,该值因特定请求对 STATUS_SUCCESS 的其他 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 向下发送到持有自旋锁的较低驱动程序,则可能会发生死锁。