共用方式為


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 值。

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

言論

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

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

如果先前呼叫的驅動程式 WdfRequestMarkCancelableWdfRequestMarkCancelableEx,則驅動程式的 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 要求

例子

下列程式代碼範例提供簡化版本的 EvtIoReadEvtRequestCancelEvtTimerFunc 回呼函式,ECHO 範例驅動程式 所包含的回呼函式。 此範例示範如何在使用架構 自動同步處理的驅動程式中呼叫 WdfRequestMarkCancelableWdfRequestUnmarkCancelableWdfRequestComplete。 (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), MarkCancOnCancReqLocalReqIsCancOnCancReq(kmdf)ReqMarkCancelableSend(kmdf)ReqNotCanceledLocal(kmdf)

另請參閱

EvtRequestCancel

WdfRequestComplete

WdfRequestMarkCancelable

WdfRequestMarkCancelableEx