WdfRequestUnmarkCancelable 函式 (wdfrequest.h)

[適用於 KMDF 和 UMDF]

WdfRequestUnmarkCancelable 方法會停用取消指定的 I/O 要求。

語法

NTSTATUS WdfRequestUnmarkCancelable(
  [in] WDFREQUEST Request
);

參數

[in] Request

架構要求物件的句柄。

傳回值

如果作業成功,WdfRequestUnmarkCancelable 會傳回STATUS_SUCCESS。 否則,此方法可能會傳回下列其中一個值:

傳回碼 描述
STATUS_INVALID_PARAMETER
輸入參數無效,或要求尚未取消。
STATUS_INVALID_DEVICE_REQUEST
驅動程式不擁有要求。
STATUS_CANCELLED
要求已取消。
 

此方法也可能 傳回其他NTSTATUS 值。

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

言論

如果驅動程式先前呼叫 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx,則驅動程式可以呼叫 WdfRequestUnmarkCancelable 來停用取消 I/O 要求。

如果 WdfRequestUnmarkCancelable 傳回STATUS_CANCELLED以外的值,則不會針對要求呼叫驅動程式的 EvtRequestCancel 回呼函式。

如果先前呼叫的驅動程式 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx,則驅動程式的 EvtRequestCancel 回呼函式可以呼叫 WdfRequestComplete,且具有 STATUS_CANCELLED Status 参数。 EvtRequestCancel 回呼函式不需要呼叫 WdfRequestUnmarkCancelable。 如果驅動程式在其 EvtRequestCancel 回呼函式之外呼叫 WdfRequestComplete,驅動程式必須先呼叫 WdfRequestUnmarkCancelable。

不過,在 EvtRequestCancel 呼叫 WdfRequestComplete之後,驅動程式不得呼叫 WdfRequestUnmarkCancelable。 在下列範例區段中,此範例會儲存要求句柄的本地副本,然後在 EvtRequestCancel 回呼函式呼叫 WdfRequestComplete時將其清除。 如果已清除要求句柄的本機複本,驅動程式不會呼叫 WdfRequestUnmarkCancelable。 此範例會使用架構 自動同步處理 來同步處理回呼函式。

請注意,呼叫 WdfObjectReference 新增要求對象的額外參考,並不會 不 讓驅動程式呼叫 WdfRequestUnmarkCancelable 驅動程式 EvtRequestCancel 回呼函式 WdfRequestComplete。

如果 WdfRequestUnmarkCancelable 傳回STATUS_CANCELLED,然後 EvtRequestCancel 完成要求,則驅動程式不得後續使用要求物件。

如果 WdfRequestUnmarkCancelable 傳回STATUS_CANCELLED,則驅動程式在架構呼叫 EvtRequestCancel之前,不得完成要求。 否則,架構可能會以無效的要求呼叫驅動程式的 EvtRequestCancel。 如需相關的程式代碼範例,請參閱 IWDFIoRequest::UnmarkCancelable。

如需 WdfRequestUnmarkCancelable的詳細資訊,請參閱 取消 I/O 要求。

例子

下列程式代碼範例提供簡化版本的 EvtIoRead、EvtRequestCancel 和 EvtTimerFunc 回呼函式,ECHO 範例驅動程式 所包含的回呼函式。 此範例示範如何在使用架構 自動同步處理的驅動程式中呼叫 WdfRequestMarkCancelable、WdfRequestUnmarkCancelable和 WdfRequestComplete。 (ECHO 範例使用裝置層級同步處理。)

如果您的驅動程式未使用架構的自動同步處理,請參閱 IWDFIoRequest::UnmarkCancelable上的兩個範例。 針對UMDF驅動程式撰寫時,這些範例會示範可用來管理取消回呼與另一個呼叫 unmark 例程之 線程之間的同步處理。

VOID
  EchoEvtIoRead(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  Length
    )
{
    PQUEUE_CONTEXT queueContext = QueueGetContext(Queue);

    // Prepare for read operation here.
    // (See the Echo sample driver for details.) 
 ...
    // Enable cancellation.
    WdfRequestMarkCancelable(
                             Request,
                             EchoEvtRequestCancel
                             );

    // Save the request handle. We'll clear it after
    // we call WdfRequestComplete.
    queueContext->CurrentRequest = Request;
    return
}


VOID
 EchoEvtRequestCancel(
    IN WDFREQUEST  Request
    )
{
    PQUEUE_CONTEXT queueContext = 
        QueueGetContext(WdfRequestGetIoQueue(Request));

    WdfRequestComplete(
                       Request,
                       STATUS_CANCELLED,
     );
    // Clear the request handle so EchEvtTimerFunc will
    // know that we called WdfRequestComplete.
    queueContext->CurrentRequest = NULL;

    return;
}


VOID
  EchoEvtTimerFunc(
    IN WDFTIMER  Timer
    )
{
    NTSTATUS  Status;
    WDFREQUEST  Request;
    WDFQUEUE  queue;
    PQUEUE_CONTEXT  queueContext;

    // Retrieve our saved copy of the request handle.
    queue = WdfTimerGetParentObject(Timer);
    queueContext = QueueGetContext(queue);
    Request = queueContext->CurrentRequest;

    // We cannot call WdfRequestUnmarkCancelable
    // after a request completes, so check here to see
    // if EchoEvtRequestCancel cleared our saved
    // request handle. 
    if( Request != NULL ) {
        Status = WdfRequestUnmarkCancelable(Request);
        if(Status != STATUS_CANCELLED) {
            queueContext->CurrentRequest = NULL;
            Status = queueContext->CurrentStatus;
            WdfRequestComplete(
                               Request,
                               Status
                               );
        }
    }

    return;
}

要求

要求 價值
目標平臺 普遍
最低 KMDF 版本 1.0
最低 UMDF 版本 2.0
標頭 wdfrequest.h (包括 Wdf.h)
連結庫 Wdf01000.sys (KMDF):WUDFx02000.dll (UMDF)
IRQL <=DISPATCH_LEVEL
DDI 合規性規則 CompleteCanceledReq(kmdf),DeferredRequestCompleted(kmdf),DriverCreate(kmdf),EvtIoStopCancel(kmdf),InvalidReqAccess(kmdf),InvalidReqAccessLocal(kmdf),KmdfIrql(kmdf) ), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MarkCancOnCancReqLocal, ReqIsCancOnCancReq(kmdf),ReqMarkCancelableSend(kmdf),ReqNotCanceledLocal(kmdf)

另請參閱

EvtRequestCancel

WdfRequestComplete

WdfRequestMarkCancelable

WdfRequestMarkCancelableEx