同步 IRP 取消

从驱动程序的角度来看,可以随时取消 IRP。 IRP 取消以异步方式发生;因此,如果 IRP 在以下任何一点取消,则驾驶员必须能够处理许多潜在的争用条件:

  • 在调用驱动程序例程之后,但在将 IRP 排队之前。

  • 在调用驱动程序例程之后,但在它尝试处理 IRP 之前。 例如,在调用驱动程序的 StartIo 例程之后,但在 StartIo 例程从设备队列中删除 IRP 之前,可能会取消 IRP。

  • 在驱动程序例程取消 IRP 排队之后,但在启动请求的 I/O 之前。

请注意,在驱动程序将 IRP 排队并释放任何保护队列的旋转锁之后,另一个线程可以访问和更改 IRP。 当原始线程恢复时(即使只要下一行代码),IRP 可能已取消或以其他方式更改。

驱动程序可以使用取消安全的 IRP 队列框架来实现 IRP 队列。 然后,系统为驱动程序注册 取消 例程,该例程会自动处理同步以安全取消 IRP。 有关详细信息 ,请参阅取消安全 IRP 队列 。 否则,驱动程序必须实现其自己的同步。

IRP 的以下成员包含有关取消的信息:

  • Irp->“取消” 指示 IRP 是正在取消还是应取消。

  • Irp->CancelRoutine 指示 IRP 是否可取消。 如果此成员包含指向取消例程的指针,则 IRP 是可取消的。 如果此成员为 NULL,则 IRP 不可取消。 如果此成员为 NULL,但设置了 Irp-Cancel>,则表示取消例程正在运行,并且 IRP 正在取消。

如果驱动程序处理可取消的 IRP,则负责在保持可取消状态的每个 IRP 中 设置相应的 Cancel 例程。

本部分包含以下有关同步 IRP 取消的主题。

使用系统的取消自旋锁

在处理 IRP 的驱动程序例程中同步取消

在不包含 Cancel 例程的较高级驱动程序中同步取消

使用驱动程序提供的自旋锁