WdfRequestUnmarkCancelable 函式 (wdfrequest.h)
[適用於 KMDF 和 UMDF]
WdfRequestUnmarkCancelable 方法會停用指定 I/O 要求的取消。
語法
NTSTATUS WdfRequestUnmarkCancelable(
[in] WDFREQUEST Request
);
參數
[in] Request
架構要求物件的句柄。
傳回值
如果作業成功,WdfRequestUnmarkCancelable 會傳回STATUS_SUCCESS。 否則,這個方法可能會傳回下列其中一個值:
傳回碼 | Description |
---|---|
|
輸入參數無效,或要求尚未取消。 |
|
驅動程式沒有擁有要求。 |
|
要求已取消。 |
這個方法也可能傳回其他 NTSTATUS值。
如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。
備註
如果驅動程式先前稱為 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx 來啟用取消要求,則驅動程式可以呼叫 WdfRequestUnmarkCancelable 來停用取消 I/O 要求。
如果 WdfRequestUnmarkCancelable 傳回STATUS_CANCELLED以外的值,將不會針對要求呼叫驅動程式的 EvtRequestCancel 回呼函式。
如果驅動程式先前稱為 WdfRequestMarkCancelable 或 WdfRequestMarkCancelableEx,驅動程式的 EvtRequestCancel 回呼函式可以使用 status 參數 STATUS_CANCELLED 呼叫 WdfRequestComplete。 EvtRequestCancel 回呼函式不需要呼叫 WdfRequestUnmarkCancelable。 如果驅動程式在其 EvtRequestCancel 回呼函式之外呼叫 WdfRequestComplete,驅動程式必須先呼叫 WdfRequestUnmarkCancelable。
不過,驅動程式在 EvtRequestCancel 呼叫 WdfRequestComplete 之後,不得呼叫 WdfRequestUnmarkCancelable。 在下列 Example 區段中,此範例會儲存要求句柄的本地副本,然後在 EvtRequestCancel 回呼函式呼叫 WdfRequestComplete 時將其清除。 如果已清除要求句柄的本地副本,驅動程式不會呼叫 WdfRequestUnmarkCancelable 。 此範例會使用架構的 自動同步 處理來同步處理回呼函式。
請注意,在驅動程式的 EvtRequestCancel 回呼函式呼叫 WdfRequestCancel 函式呼叫 WdfRequestCancelable 之後,呼叫 WdfObjectReference 以新增要求對象的額外參考。
如果 WdfRequestUnmarkCancelable 傳回STATUS_CANCELLED,然後 EvtRequestCancel 完成要求,則驅動程式後續不得使用要求物件。
如果 WdfRequestUnmarkCancelable 傳回STATUS_CANCELLED,則驅動程式在架構呼叫 EvtRequestCancel 之前,不得完成要求。 否則,架構可能會以無效的要求呼叫驅動程式的 EvtRequestCancel 。 如需相關程式代碼範例,請參閱 IWDFIoRequest::UnmarkCancelable。
如需 WdfRequestUnmarkCancelable 的詳細資訊,請參閱 取消 I/O 要求。
範例
下列程式代碼範例提供 ECHO 範例驅動程式包含之 EvtIoRead、EvtRequestCancel 和 EvtTimerFunc 回呼函式的簡化版本。 此範例示範如何在使用架構的自動同步處理驅動程式中呼叫 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;
}
規格需求
需求 | 值 |
---|---|
目標平台 | Universal |
最低 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 (kmdf) 、 ReqIsCancOnCancReq (kmdf) 、 ReqMarkCancelableSend (kmdf) , ReqNotCanceledLocal (kmdf) |