WdfRequestUnmarkCancelable 函式 (wdfrequest.h)
[適用於 KMDF 和 UMDF]
WdfRequestUnmarkCancelable 方法會停用取消指定的 I/O 要求。
語法
NTSTATUS WdfRequestUnmarkCancelable(
[in] WDFREQUEST Request
);
參數
[in] Request
架構要求物件的句柄。
傳回值
如果作業成功,WdfRequestUnmarkCancelable 會傳回STATUS_SUCCESS。 否則,此方法可能會傳回下列其中一個值:
傳回碼 | 描述 |
---|---|
|
輸入參數無效,或要求尚未取消。 |
|
驅動程式不擁有要求。 |
|
要求已取消。 |
此方法也可能 傳回其他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) |