将取消已发送请求的操作同步

当驱动程序尝试取消它已转发到 I/O 目标的 I/O 请求时,驱动程序必须确保将有效的请求句柄传递给 WdfRequestCancelSentRequest 方法。 如果 I/O 目标完成请求,则请求句柄将变为无效,因为驱动程序的 CompletionRoutine 回调函数将调用 WdfRequestComplete (尝试) 删除请求对象。

若要避免此问题,驱动程序可以通过创建请求对象的 集合 等方式跟踪已发送到 I/O 目标的请求。 驱动程序可以调用 WdfSpinLockAcquire 来同步对集合的访问。

调用驱动程序的 CompletionRoutine 回调函数时,它会获取锁,从集合中删除已完成请求的句柄,并调用 WdfSpinLockRelease 以释放锁。

在尝试取消驱动程序已转发到 I/O 目标的请求之前,驱动程序可以:

  1. 调用 WdfSpinLockAcquire 以获取旋转锁。

  2. 在集合中查找请求对象的句柄,以确保驱动程序的完成例程尚未完成请求,并从集合中删除了句柄。

  3. 调用 WdfObjectReference 以递增请求对象的引用计数,以便无法删除该对象。

  4. 调用 WdfSpinLockRelease 以释放旋转锁。

  5. 调用 WdfRequestCancelSentRequest

  6. 调用 WdfObjectDereference 以递减对象的引用计数。

此序列可确保如果 I/O 目标在驱动程序调用 WdfRequestCancelSentRequest 之前完成请求,则即使驱动程序的 CompletionRoutine 回调函数调用 WdfRequestComplete,由于递增的引用计数) ,请求的句柄仍 (有效。