信息
您所需的主题如下所示。但此主题未包含在此库中。

WdfRequestMarkCancelable 方法

The WdfRequestMarkCancelable method enables cancellation of a specified I/O request.

语法

VOID WdfRequestMarkCancelable(
  [in]  WDFREQUEST Request,
  [in]  PFN_WDF_REQUEST_CANCEL EvtRequestCancel
);

参数

Request [in]

A handle to a framework request object.

EvtRequestCancel [in]

A pointer to a driver-defined EvtRequestCancel callback function, which the framework calls if it cancels the I/O request.

返回值

None.

A bug check occurs if the driver supplies an invalid object handle.

评论

After your driver has received an I/O request from the framework, the driver can call WdfRequestMarkCancelable or WdfRequestMarkCancelableEx (beginning with KMDF version 1.9) to make the request cancelable.

If your driver uses the framework's automatic synchronization, the driver can call either WdfRequestMarkCancelable or WdfRequestMarkCancelableEx.

If the driver does not use automatic synchronization, it must call WdfRequestMarkCancelableEx instead of WdfRequestMarkCancelable, for the following reasons.

  • WdfRequestMarkCancelable can call the driver's EvtRequestCancel callback function before returning, if the specified request has already been canceled. A typical driver locking scheme involves acquiring a spinlock before calling WdfRequestMarkCancelable and acquiring the same spinlock inside the EvtRequestCancel callback function. If a driver thread calls WdfRequestMarkCancelable with the spinlock held, and if WdfRequestMarkCancelable calls the EvtRequestCancel callback function, the same thread attempts to acquire the same spinlock twice, causing a deadlock.

  • On the other hand, WdfRequestMarkCancelableEx never calls the driver's EvtRequestCancel callback function before returning. If the request has already been canceled, WdfRequestMarkCancelableEx just returns STATUS_CANCELLED, and the EvtRequestCancel callback function is not called. If your driver acquires a spinlock (which sets the IRQL to DISPATCH_LEVEL) before calling WdfRequestMarkCancelableEx and releases the spinlock (which sets the IRQL to PASSIVE_LEVEL) after WdfRequestMarkCancelableEx returns, the EvtRequestCancel callback function will not be called before the spinlock is released. Therefore, a deadlock does not occur even if the EvtRequestCancel callback function uses the same spinlock.

When calling WdfRequestMarkCancelable, your driver must specify an EvtRequestCancel callback function. The framework calls the callback function if the I/O manager or another driver is attempting to cancel the I/O request. If your driver can cancel the request, it must:

  1. Finish or stop processing the request, along with subrequests that it might have created.

  2. Call WdfRequestComplete, specifying a status value of STATUS_CANCELLED.

After a driver calls WdfRequestMarkCancelable to enable canceling, the request remains cancelable while the driver owns the request object, unless the driver calls WdfRequestUnmarkCancelable.

If a driver has called WdfRequestMarkCancelable, and if the driver's EvtRequestCancel callback function has not executed and called WdfRequestComplete, the driver must call WdfRequestUnmarkCancelable before it calls WdfRequestComplete outside of the EvtRequestCancel callback function.

If the driver calls WdfRequestForwardToIoQueue to forward the request to a different queue, the following rules apply:

  • I/O requests cannot be cancelable when your driver forwards them to a different queue.

    Generally, your driver should not call WdfRequestMarkCancelable to enable canceling the request before calling WdfRequestForwardToIoQueue. If the driver does make the request cancelable, it must call WdfRequestUnmarkCancelable to disable cancellation before calling WdfRequestForwardToIoQueue.

  • While the request is in the second queue, the framework owns it and can cancel it without notifying the driver.

    If the driver requires cancellation notification (so that it can deallocate any resources that it might have allocated before calling WdfRequestForwardToIoQueue), the driver should register an EvtIoCanceledOnQueue callback function, and it should use request-specific context memory to store information about the request's resources.

  • After the framework has dequeued the request from the second queue and delivered it to the driver, the driver can call WdfRequestMarkCancelable to enable canceling.

For more information about WdfRequestMarkCancelable, see Canceling I/O Requests

示例

The following code example shows parts of two callback functions:

  • An EvtIoRead callback function that performs request-specific work (such as creating subrequests to send to an I/O target), then enables cancellation of the received I/O request.

  • An EvtRequestCancel callback function that cancels an I/O request.

The driver must use the framework's automatic synchronization.

VOID
MyEvtIoRead(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  Length
    )
{
...
    // Perform request-specific work here
    // (such as creating subrequests 
    // to send to an I/O target). 
...
    WdfRequestMarkCancelable(
                             Request,
                             EchoEvtRequestCancel
                             );
    }
...
}
VOID
MyEvtRequestCancel(
    IN WDFREQUEST  Request
    )
{
    // Remove request-specific work here, because
    // we don't want the work to be done if the
    // request was canceled.

    WdfRequestComplete(
                       Request,
                       STATUS_CANCELLED
                       );
}

要求

版本

Available in version 1.0 and later versions of KMDF.

标头

Wdfrequest.h (包括Wdf.h)

Wdf<MajorVersionNumber>000.sys (see Framework Library Versions.)

IRQL

<=DISPATCH_LEVEL

另请参见

WdfRequestComplete
WdfRequestForwardToIoQueue
WdfRequestMarkCancelableEx
WdfRequestUnmarkCancelable
EvtRequestCancel

 

 

社区附加资源

显示:
© 2014 Microsoft