在處理 IRP 的驅動程式例程中同步處理取消
任何清除佇列或呼叫的驅動程式例程,其 IRP 都處於可取消狀態,包括驅動程式的 StartIo 例程,都必須執行下列動作:
檢查以確定 Irp 等於 DeviceObject-CurrentIrp>。 如果沒有,請呼叫 IoReleaseCancelSpinLock 並傳回控件。
如果兩者不同,則當IoStartPacket釋放取消微調鎖定且此例程取得時,CurrentIrp可能已經取消。
使用 NULL CancelRoutine 指標呼叫 IoSetCancelRoutine,以從可取消的狀態移除 IRP。
檢查 [Irp-Cancel>] 字段,以判斷要取消 IRP 還是開始處理 I/O 要求。
如果 Irp-Cancel> 設定為 TRUE,請執行下列動作:
呼叫 IoReleaseCancelSpinLock。
將 Irp-IoStatus.Status> 設定為 STATUS_CANCELLED。
將 Irp-IoStatus.Information> 設定為 0。
呼叫IoStartNextPacket (在 StartIo 例程中),以啟動下一個封包。
以 優先順序提升IO_NO_INCREMENT呼叫IoCompleteRequest 以完成 IRP。
如果 Irp-Cancel> 設定為 FALSE,請呼叫 IoReleaseCancelSpinLock 並啟動要求的處理 I/O 要求,或視需要將 IRP 傳遞給下一個較低的驅動程式。
管理自己的 IRP 佇列,而不是使用 I/O 管理員提供的裝置佇列的驅動程式,不需要在呼叫 IoSetCancelRoutine 時取得取消微調鎖定。 不過,這些驅動程式應該檢查 IoSetCancelRoutine 傳回的 Cancel 例程指標,以判斷取消例程是否已啟動。
在任何處理可取消 IRP 的驅動程式中,處理基礎裝置之前處理 IRP 的每個驅動程式例程都應該檢查所有傳入 IRP 的可取消狀態。 具體來說,具有 StartIo 和 ControllerControl 例程的最高層級設備驅動器,應該依照先前所述,在這兩個驅動程式例程中處理傳入的 IRP。