在不包含 Cancel 例程的较高级驱动程序中同步取消
较高级别的驱动程序不能假设现有的较低级别驱动程序是否或如何处理可取消的 IRP。 只要任何更高级别的驱动程序为 IRP 调用 IoCallDriver ,它就不再拥有该 IRP,并且它既无法确定也无法控制较低级别的驱动程序对 IRP 的处理。
但是,任何更高级别的驱动程序都可以在调用 IoCallDriver 之前调用 IoSetCompletionRoutine 来为 IRP 设置 IoCompletion 例程。 在将 IRP 传递给较低驱动程序之前,较高级别的驱动程序可以通过调用将 InvokeOnCancel 参数设置为 TRUE 的 IoSetCompletionRoutine 来确定是否取消任何挂起的 IRP。 这样做可确保无论 IRP 是取消还是完成,都将调用驱动程序的 IoCompletion 例程。
更高级别的驱动程序可以使用驱动程序分配的任何挂起的 IRP 调用 IoCancelIrp 。 但是,进行此调用并不能保证驱动程序分配的 IRP 完成其 I/O 状态块设置为 STATUS_CANCELLED;另一个线程可能已在完成 IRP。 若要检查 IRP 是否已取消,更高级别的驱动程序必须调用 IoSetCompletionRoutine,并将 InvokeOnCancel 参数设置为 TRUE,然后再将 IRP 传递到下一个较低的驱动程序。 有关完成例程的详细信息,请参阅完成 IRP 。
更高级别的驱动程序不得使用它未分配的 IRP 调用 IoCancelIrp 。