在处理 IRP 的驱动程序例程中同步取消
取消排队或使用处于可取消状态的 IRP 调用的任何驱动程序例程(包括驱动程序的 StartIo 例程)都必须执行以下操作:
检查以确保 Irp 等于 DeviceObject-CurrentIrp>。 如果没有,请调用 IoReleaseCancelSpinLock 并返回控制权。
如果两者不相同,则从 IoStartPacket 释放取消旋转锁到此例程获取该锁之间,CurrentIrp 可能已取消。
使用 NULLCancelRoutine 指针调用 IoSetCancelRoutine,以将 IRP 从可取消状态中删除。
检查 Irp-Cancel> 字段以确定是取消 IRP 还是开始处理 I/O 请求。
如果 Irp-Cancel> 设置为 TRUE,请执行以下操作:
调用 IoReleaseCancelSpinLock。
将 Irp-IoStatus.Status> 设置为 STATUS_CANCELLED。
将 Irp-IoStatus.Information> 设置为 0。
在 StartIo 例程) 调用 IoStartNextPacket (以启动下一个数据包。
调用 IoCompleteRequest ,优先级提升为 IO_NO_INCREMENT 以完成 IRP。
如果 Irp-Cancel> 设置为 FALSE,请调用 IoReleaseCancelSpinLock 并启动请求处理 I/O 请求,或根据需要将 IRP 传递给下一个较低的驱动程序。
管理自己的 IRP 队列(而不是使用 I/O 管理器提供的设备队列)的驱动程序在调用 IoSetCancelRoutine 时不需要获取取消旋转锁。 但是,这些驱动程序应检查 IoSetCancelRoutine 返回的 Cancel 例程指针,以确定取消例程是否已启动。
在任何处理可取消 IRP 的驱动程序中,在针对请求的 I/O 操作对基础设备进行编程之前处理 IRP 的每个驱动程序例程都应检查所有传入 IRP 的可取消状态。 具体而言,具有 StartIo 和 ControllerControl 例程的最高级别设备驱动程序应处理这两个驱动程序例程中的传入 IRP,如前所述。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈