WdfRequestMarkCancelable 函式 (wdfrequest.h)

[適用於 KMDF 和 UMDF]

WdfRequestMarkCancelable 方法可讓您取消指定的 I/O 要求。

語法

void WdfRequestMarkCancelable(
  [in] WDFREQUEST             Request,
  [in] PFN_WDF_REQUEST_CANCEL EvtRequestCancel
);

參數

[in] Request

架構要求物件的句柄。

[in] EvtRequestCancel

驅動程式定義 EvtRequestCancel 回呼函式的指標,如果架構取消 I/O 要求,架構會呼叫此函式。

傳回值

備註

如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。

驅動程式從架構 收到 I/O 要求 之後,驅動程式可以呼叫 WdfRequestMarkCancelable ,或從 KMDF 1.9 版開始, WdfRequestMarkCancelableEx 來取消要求。

呼叫 WdfRequestMarkCancelable 時,您的驅動程式必須指定 EvtRequestCancel 回呼函式。 如果 I/O 管理員或其他驅動程式嘗試取消 I/O 要求,架構會呼叫回呼函式。

在 WdfRequestMarkCancelable 與 WdfRequestMarkCancelableEx 之間進行選擇

如果您的驅動程式使用架構的 自動同步處理,驅動程式可以呼叫 WdfRequestMarkCancelableWdfRequestMarkCancelableEx

如果驅動程式不使用自動同步處理,它必須呼叫 WdfRequestMarkCancelableEx ,而不是 WdfRequestMarkCancelable ,原因如下:

  • 如果指定的要求已經取消, WdfRequestMarkCancelable 會在傳回之前先呼叫驅動程式的 EvtRequestCancel 回呼函式。 如果驅動程式在呼叫 WdfRequestMarkCancelable 之前取得微調鎖定,並嘗試在 EvtRequestCancel 內取得相同的微調鎖定,則相同的線程會嘗試取得相同的微調鎖定兩次,導致死結。
  • 不過,因為 WdfRequestMarkCancelableEx 永遠不會呼叫 EvtRequestCancel,所以不會發生此案例。 如果要求已經取消, WdfRequestMarkCancelableEx傳回STATUS_CANCELLED。 如果您的驅動程式在呼叫 WdfRequestMarkCancelableEx 之前取得微調鎖定 (,這會在 WdfRequestMarkCancelable (Ex 之前將 IRQL 設定為 DISPATCH_LEVEL) PASSIVE_LEVEL) ,則會在 WdfRequestMarkCancelableEx 傳回之前呼叫 EvtRequestCancel 回呼函式。 因此,即使 EvtRequestCancel 回呼函式使用相同的微調鎖定,也不會發生死結。

啟用取消之後處理要求

驅動程式呼叫 WdfRequestMarkCancelable 以啟用取消之後,除非驅動程式呼叫 WdfRequestUnmarkCancelable,否則要求仍可取消,而驅動程式擁有要求物件。

如果驅動程式已呼叫 WdfRequestMarkCancelable,而且驅動程式的 EvtRequestCancel 回呼函式尚未執行並呼叫 WdfRequestComplete,則驅動程式必須先呼叫 WdfRequestUnmarkCancelable,再呼叫 EvtRequestCancel 回呼函式以外的 WdfRequestComplete

如果驅動程式呼叫 WdfRequestForwardToIoQueue 以將要求轉送至不同的佇列,則適用下列規則:

  • 當驅動程式將其轉送至不同的佇列時,無法取消 I/O 要求。

    一般而言,您的驅動程式不應該呼叫 WdfRequestMarkCancelable 來啟用取消要求,再呼叫 WdfRequestForwardToIoQueue。 如果驅動程式確實將要求設為可取消,它必須呼叫 WdfRequestUnmarkCancelable 才能停用取消,再呼叫 WdfRequestForwardToIoQueue

  • 當要求位於第二個佇列中時,架構會擁有它,而且可以在不通知驅動程序的情況下取消它。

    如果驅動程式需要取消通知 (,讓它可以在呼叫 WdfRequestForwardToIoQueue) 之前解除分配它可能配置的任何資源,驅動程式應該註冊 EvtIoCanceledOnQueue 回呼函式,而且應該使用要求特定的內容記憶體來儲存要求資源的相關信息。

  • 在架構從第二個佇列中清除要求並傳遞至驅動程序之後,驅動程式可以呼叫 WdfRequestMarkCancelable 來啟用取消。
如需 WdfRequestMarkCancelable 的詳細資訊,請參閱 取消 I/O 要求

範例

下列程式代碼範例顯示兩個回呼函式的一部分:

  • EvtIoRead 回呼函式,可執行要求特定工作 (,例如建立子佇列以傳送至 I/O 目標) ,然後啟用已接收 I/O 要求的取消。
  • 取消 I/O 要求的 EvtRequestCancel 回呼函式。
驅動程式必須使用架構的 自動同步處理
VOID
MyEvtIoRead(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  Length
    )
{
...
    // Perform request-specific work here
    // (such as creating subrequests 
    // to send to an I/O target). 
...
    WdfRequestMarkCancelable(
                             Request,
                             MyEvtRequestCancel
                             );
    }
...
}
VOID
MyEvtRequestCancel(
    IN WDFREQUEST  Request
    )
{
    // Remove request-specific work here, because
    // we don't want the work to be done if the
    // request was canceled.

    WdfRequestComplete(
                       Request,
                       STATUS_CANCELLED
                       );
}

規格需求

需求
目標平台 Universal
最低 KMDF 版本 1.0
最低UMDF版本 2.0
標頭 wdfrequest.h (包含 Wdf.h)
程式庫 Wdf01000.sys (KMDF) ;WUDFx02000.dll (UMDF)
IRQL <=DISPATCH_LEVEL
DDI 合規性規則 DeferredRequestCompleted (kmdf) DriverCreate (kmdf) EvtIoStopCancel (kmdf) InvalidReqAccess (kmdf) InvalidReqAccessLocal (kmdf) KmdfIrql (kmdf) KmdfIrql2 (kmdf) 、 KmdfIrqlExplicit (kmdf ) , MarkCancOnCancReqLocal (kmdf) ReqIsCancOnCancReq (kmdf) ReqMarkCancelableSend (kmdf ) 、 ReqNotCanceledLocal (kmdf) RequestCompleted (kmdf) RequestCompletedLocal (kmdf)

另請參閱

EvtRequestCancel

WdfRequestComplete

WdfRequestForwardToIoQueue

WdfRequestMarkCancelableEx

WdfRequestUnmarkCancelable