取消 I/O 要求
裝置進行中的 I/O 作業 (,例如要求從磁片讀取數個區塊) 可由應用程式、系統或驅動程式取消。 如果裝置的 I/O 作業已取消,I/O 管理員會嘗試取消與 I/O 作業相關聯的所有未處理 I/O 要求。 當 I/O 管理員嘗試取消 I/O 要求時,裝置的驅動程式可以註冊以收到通知,而驅動程式可以 透過完成 狀態完成STATUS_CANCELLED來取消其擁有的要求。
架構會處理架構型驅動程式的一些取消工作。 如果裝置的 I/O 作業已取消,架構會完成下列 I/O 要求, (完成狀態為與取消作業相關聯的STATUS_CANCELLED) :
架構已放置於驅動程式的預設 I/O 佇列中未傳遞的 I/O 要求。
架構已轉送至另一個佇列的未傳遞 I/O 要求,因為驅動程式稱為 WdfDeviceConfigureRequestDispatching。
因為架構會取消這些要求,所以不會將它們傳遞給驅動程式。
在架構將 I/O 要求傳遞給驅動程式之後,驅動程式 會擁有 要求,而且架構無法取消它。 此時,只有驅動程式可以取消 I/O 要求,但架構必須通知驅動程式應該取消要求。 驅動程式會藉由提供 EvtRequestCancel 回呼函式來接收此通知。
有時候,驅動程式會從 I/O 佇列收到 I/O 要求,但驅動程式不會處理要求,而是將要求重新佇列至相同或另一個 I/O 佇列,以供稍後處理。 這種情況的範例包括:
架構會將 I/O 要求傳遞給其中一個驅動程式 的要求處理常式,而驅動程式接著會呼叫 WdfRequestForwardToIoQueue (或 WdfRequestForwardToParentDeviceIoQueue) 將要求放在不同的佇列或 WdfRequestRequeue 中,將要求放回相同的佇列。
架構會將 I/O 要求傳遞給驅動程式的 EvtIoInCallerCoNtext 回呼函式、驅動程式會呼叫 WdfDeviceEnqueueRequest 將要求傳回架構,而架構接著會將要求放在驅動程式的其中一個 I/O 佇列中。
在這些情況下,架構可以取消 I/O 要求,因為要求位於 I/O 佇列中。 不過,如果驅動程式已註冊要求所在 I/O 佇列的 EvtIoCanceledOnQueue 回呼函式,架構會呼叫回呼函式,而不是在取消相關聯的 I/O 作業時取消要求。 如果架構呼叫驅動程式的 EvtIoCanceledOnQueue 回呼函式,驅動程式必須 完成 要求。
總而言之,取消 I/O 作業時,架構一律會取消從未傳遞至驅動程式的所有相關聯 I/O 要求。 如果驅動程式收到要求,然後重新排入佇列,除非驅動程式為 I/O 佇列提供 EvtIoCanceledOnQueue 回呼函式,否則架構將會取消要求) (。
呼叫 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx
驅動程式可以呼叫 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx 來註冊 EvtRequestCancel 回呼函式。 如果驅動程式已呼叫 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx,而且如果取消與要求相關聯的 I/O 作業,架構會呼叫驅動程式的 EvtRequestCancel 回呼函式,讓驅動程式可以取消 I/O 要求。
如果驅動程式擁有相當長的時間,驅動程式應該呼叫 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx 。 例如,驅動程式可能必須等候裝置回應,或者可能會等候較低的驅動程式完成驅動程式收到單一要求時所建立的一組要求。
如果驅動程式未呼叫WdfRequestMarkCancelable或WdfRequestMarkCancelableEx,或驅動程式在呼叫WdfRequestMarkCancelable或WdfRequestMarkCancelableEx之後呼叫WdfRequestMarkCancelableEx,則驅動程式不會察覺取消,因此會像平常一樣處理要求。
呼叫 WdfRequestIsCanceled
如果驅動程式尚未呼叫 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx 來註冊 EvtRequestCancel 回呼函式,它可以呼叫 WdfRequestIsCanceled 來判斷 I/O 管理員是否嘗試取消 I/O 要求。 如果 WdfRequestIsCanceled 傳回 TRUE 且驅動程式擁有要求,則驅動程式應該取消要求。 如果驅動程式沒有擁有要求,它不應該呼叫 WdfRequestIsCanceled。
未呼叫 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx 的驅動程式,可能會在下列情況下呼叫 WdfRequestIsCanceled :
等候裝置中斷的驅動程式可能會從其EvtInterruptDpc回呼函式呼叫WdfRequestIsCanceled。
輪詢其裝置的驅動程式可能會從其輪詢執行緒呼叫 WdfRequestIsCanceled 。
將 DMA 交易 分成數個較小的傳輸的驅動程式,可能會在每次傳輸完成後呼叫 WdfRequestIsCanceled 。
如果驅動程式尚未呼叫WdfRequestMarkCancelable或WdfRequestMarkCancelableEx,則接收大量讀取或寫入要求,可能會在驅動程式的 I/O 目標完成每個較小的要求之後呼叫WdfRequestIsCanceled。
取消要求
取消 I/O 要求可能牽涉到下列任一項:
停止進行中的 I/O 作業。
未將要求轉送至 I/O 目標。
呼叫 WdfRequestCancelSentRequest 嘗試取消驅動程式先前已提交至 I/O 目標的要求。
如果驅動程式正在取消從架構接收之要求物件的 I/O 要求,則驅動程式一律必須呼叫WdfRequestComplete、WdfRequestCompleteWithInformation或WdfRequestCompleteWithPriorityBoost來完成要求,且狀態參數為 STATUS_CANCELLED。 (如果驅動程式稱為 WdfRequestCreate 來建立要求物件,驅動程式會呼叫 WdfObjectDelete ,而不是完成 request.)
同步處理取消
如需同步處理取消 I/O 要求之程式碼的詳細資訊,請參閱: