實作取消常式
I/O 管理員會呼叫驅動程式提供的 Cancel 常式,其中包含要取消的輸入 IRP,以及代表 I/O 要求之目標裝置的 DeviceObject 指標。
IRP 可能是驅動程式 DispatchReadWrite 常式已排入佇列的 IRP,就像使用者正在關閉目前的 Win32 應用程式一樣。 根據基礎裝置的本質而定,IRP 也可能是較高層級驅動程式明確取消的驅動程式。
呼叫Cancel常式時,如果驅動程式有StartIo常式,輸入 IRP 可能已經是目標裝置物件中的CurrentIrp,或可能已經位於與目標裝置物件相關聯的裝置佇列中。 如果驅動程式沒有 StartIo 常式,則呼叫其 Cancel 常式時,IRP 可能位於由驅動程式管理的 IRP 內部佇列中。 在任何情況下,在 I/O 管理員呼叫傳入 IRP 的Cancel常式之前,I/O 管理員會將此 IRP 中的 Cancel 成員設定為TRUE,並將 IRP 中的CancelRoutine成員設定為Null。
具有相關聯 IRP 之主要 IRP 的 Cancel 常式負責呼叫 IoCancelIrp 以取消那些相關聯的 IRP。
所有 Cancel 常式都必須遵循下列指導方針:
呼叫 IoReleaseCancelSpinLock 以釋放系統的取消微調鎖定。
將 I/O 狀態欄塊的 [狀態 ] 成員設定為 [STATUS_CANCELLED],並將其 [資訊 ] 成員設定為零。
呼叫 IoCompleteRequest來完成指定的 IRP。
由於 一 律會呼叫 Cancel 常式並保留系統取消微調鎖定,因此此常式不得呼叫 IoAcquireCancelSpinLock ,除非它先呼叫 IoReleaseCancelSpinLock 。
當取消常式傳回控制權時,無法保留系統取消微調鎖定。 也就是說,每個 Cancel 常式在傳回控制項之前,至少必須呼叫 IoReleaseCancelSpinLock 一次。
如果呼叫 IoAcquireCancelSpinLock, Cancel 常式必須儘快對 IoReleaseCancelSpinLock 進行相互呼叫。
在按住微調鎖定時,請勿使用 IRP 呼叫 IoCompleteRequest 。 嘗試在按住微調鎖定時完成 IRP 可能會導致死結。