Cancel 例程简介

任何可以无限期地将 IRP 保持挂起状态的驱动程序都必须具有一个或多个 Cancel 例程。 例如,键盘驱动程序可能会无限期地等待用户按一个键。 相反,如果驱动程序永远不会排队等待超过 5 分钟内可完成数的 IRPS,则它可能不需要 取消 例程。

假设用户模式线程进行 I/O 请求,该请求由最高级别的设备驱动程序的调度例程排队,请求线程在 IRP 排队时终止。 应取消代表已终止线程排队的 IRPs。 因此,驱动程序必须在它排队的每个 IRP 中设置驱动程序提供的 Cancel 例程。

创建关联 IRP 的驱动程序必须在主 IRP 取消时取消它们。 由于关联的 IRP 不与请求线程关联,因此主 IRP 的 Cancel 例程负责在主 IRP 取消时取消任何关联的 IRP。

任何驱动程序 都有的" 取消"例程数取决于驱动程序的设计。 一般情况下,驱动程序在其 I/O 处理的每个阶段都应有一个 Cancel 例程,在此阶段,IRP 可能会无限期地处于挂起状态。 此类挂起的 IRP 被说为 可取消状态

请考虑以下设计准则:

  • 如果分层驱动程序链中最高级别的驱动程序将 IRPs 排到队列,或者将 IRPs 保留为可取消状态,则它必须至少具有一个 Cancel 例程。 如有必要,它可以具有多个 Cancel 例程。

  • 在较低级别的驱动程序中,可以长时间保持可取消状态 IRP 的驱动程序还应具有一个或多个 Cancel 例程。

  • 如果驱动程序管理其自己的内部 IRP 队列,则它应针对其每个队列具有单独的 Cancel 例程。

交互式设备(如键盘、鼠标、声音、并行类和串行驱动程序)的一些最高级别驱动程序必须具有 Cancel 例程。 某些较低级别的驱动程序(如并行端口驱动程序)还应具有 Cancel 例程,该驱动程序将排队等待一些较高级别类驱动程序的 IRPs 排队一段时间。

大容量存储设备驱动程序以及分层在它们上的中间驱动程序不太可能具有 Cancel 例程。 文件系统驱动程序负责处理文件 I/O 请求的取消,而较低级别大容量存储驱动程序的 IIP 输入处理速度过快,无法取消。