使用删除锁
删除锁例程提供了一种方法来跟踪设备上未完成的 I/O 操作数,并确定何时可以安全分离和删除驱动程序的设备对象。 系统向驱动程序编写者提供这些例程,作为实现其自己的跟踪机制的替代方法。
驱动程序可以将此机制用于两个目的:
若要确保驱动程序的 DispatchPnP 例程不会完成 IRP_MN_REMOVE_DEVICE (锁定时,另一个驱动程序例程) 访问设备。
计算驱动程序不应删除其设备对象的原因数,并在该计数为零时设置事件。
若要初始化删除锁,驱动程序应在其设备扩展中分配IO_REMOVE_LOCK结构,然后调用 IoInitializeRemoveLock。 当驱动程序初始化设备对象的设备扩展的其余部分时,驱动程序通常会在其 AddDevice 例程中调用 IoInitializeRemoveLock。
驱动程序必须在每次启动 I/O 操作时调用 IoAcquireRemoveLock 。 每次完成 I/O 操作时,驱动程序都必须调用 IoReleaseRemoveLock 。 驱动程序可以多次获取锁。 remove lock 例程维护锁的未完成购置的计数。 每次调用 IoAcquireRemoveLock 都会递增计数, 而 IoReleaseRemoveLock 会递减计数。
驱动程序还应在将对计时器、DPC、回调等) 的代码 (的引用传出时调用 IoAcquireRemoveLock 。 然后,当事件返回时,驱动程序必须调用 IoReleaseRemoveLock 。
在其 用于IRP_MN_REMOVE_DEVICE的调度代码中,驱动程序必须再次获取锁,然后调用 IoReleaseRemoveLockAndWait。 在释放锁的所有未完成购置之前,此例程不会返回。 若要允许完成排队的 I/O 操作,每个驱动程序应在将IRP_MN_REMOVE_DEVICE请求传递给下一个较低级别的驱动程序之后调用 IoReleaseRemoveLockAndWait,并在它释放内存之前调用 IoDetachDevice 或调用 IoDeleteDevice。 为特定的删除锁调用 IoReleaseRemoveLockAndWait 后,针对同一删除锁对 IoAcquireRemoveLock 的所有后续调用都将失败。
IoReleaseRemoveLockAndWait 返回后,驱动程序应将设备视为处于已准备好删除且无法执行 I/O 操作的状态。 因此,驱动程序不得调用 IoInitializeRemoveLock 来重新初始化删除锁。 驱动程序验证程序验证驱动程序时违反此规则将导致 bug 检查。
由于驱动程序将 IO_REMOVE_LOCK 结构存储在设备对象的设备扩展中,因此当驱动程序在处理 IRP_MN_REMOVE_DEVICE 请求时删除设备扩展时,删除锁将被删除。
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈