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 值

如果驱动程序提供无效的对象句柄,则会发生 bug 检查。

注解

如果驱动程序以前调用 WdfRequestMarkCancelable 或 WdfRequestMarkCancelable 以启用请求取消,则驱动程序可以调用 WdfRequestUnmarkCancelable 来禁用取消 I/O 请求。

如果 WdfRequestUnmarkCancelable 返回STATUS_CANCELLED以外的值,则不会为请求调用驱动程序的 EvtRequestCancel 回调函数。

如果驱动程序以前名为 WdfRequestMarkCancelableWdfRequestMarkCancelableEx,则驱动程序的 EvtRequestCancel 回调函数可以使用 status 参数 STATUS_CANCELLED 调用 WdfRequestCompleteEvtRequestCancel 回调函数不必调用 WdfRequestUnmarkCancelable。 如果驱动程序在其 EvtRequestCancel 回调函数外部调用 WdfRequestComplete,则驱动程序必须首先调用 WdfRequestUnmarkCancelable

但是,在 EvtRequestCancel 调用 WdfRequestComplete 后,驱动程序不得调用 WdfRequestUnmarkCancelable 在以下示例部分中,该示例存储请求句柄的本地副本,然后在 EvtRequestCancel 回调函数调用 WdfRequestComplete 时清除该副本。 如果已清除请求句柄的本地副本,驱动程序不会调用 WdfRequestUnmarkCancelable 。 此示例使用框架的 自动同步 来同步回调函数。

请注意,调用 WdfObjectReference 以添加对请求对象的附加引用不会使驱动程序在驱动程序的 EvtRequestCancel 回调函数调用 WdfRequestComplete 之后调用 WdfRequestUnmarkCancelable

如果 WdfRequestUnmarkCancelable 返回STATUS_CANCELLED,然后 EvtRequestCancel 完成请求,则驱动程序随后不得使用请求对象。

如果 WdfRequestUnmarkCancelable 返回STATUS_CANCELLED,则驱动程序在框架调用 EvtRequestCancel 之前不得完成请求。 否则,框架可能会使用无效请求调用驱动程序的 EvtRequestCancel 。 有关相关代码示例,请参阅 IWDFIoRequest::UnmarkCancelable

有关 WdfRequestUnmarkCancelable 的详细信息,请参阅 取消 I/O 请求

示例

下面的代码示例提供了 ECHO 示例驱动程序包含的 EvtIoReadEvtRequestCancelEvtTimerFunc 回调函数的简化版本。 此示例演示如何在使用框架自动同步的驱动程序中调用 WdfRequestMarkCancelable、WdfRequestUnmarkCancelableWdfRequestComplete (ECHO 示例使用设备级 synchronization.)

如果驱动程序不使用框架的自动同步,请参阅 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)
Library 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) ReqIsCancOnCancCancReq (kmdf) ReqMarkCancelableSend (kmdf) ReqNotCanceledLocal (kmdf)

另请参阅

EvtRequestCancel

WdfRequestComplete

WdfRequestMarkCancelable

WdfRequestMarkCancelableEx