Windows I/O is
The thread or process that issued the request cancels it or exits.
A system Plug and Play or power event such as hibernation occurs.
The device is being, or has been, removed.
The actions that a driver takes to stop processing an I/O request depend on the reason for suspension or cancellation. Usually, the driver can either cancel the request or complete it with an error. In some situations, the system might request that a driver suspend (that is, temporarily pause) processing; the system notifies the driver later when to resume processing.
To provide a good
The actions that WDF takes to cancel an I/O request depend on whether the request has already been delivered to the target driver:
If the request has never been delivered-either because the framework has not yet queued it or because it is still in a queue, the framework cancels or suspends it automatically without
If the original I/O request has been canceled, the framework completes the request with a cancellation status.
If the request has been delivered but the driver forwards it to a different queue, the framework automatically cancels the request without notifying the driver.
KMDF drivers can receive notification by registering an EvtIoCanceledOnQueue callback for the queue.
UMDF drivers cannot receive this type of notification.
If the request has been delivered and is owned by the driver, the framework does not cancel it.
However, if the driver explicitly marks the request cancelable and registers a cancellation callback, the framework notifies the driver that the request was canceled. In its callback, the driver should complete the request or should arrange for it to complete quickly.
To mark a request cancelable or uncancelable:
A UMDF driver calls the request object's IWDFIoRequest::MarkCancelable or IWDFIoRequest::UnmarkCancelable method.
A KMDF driver calls WdfRequestMarkCancelable or WdfRequestUnmarkCancelable .
When a driver marks a request cancelable, it
Drivers must not leave requests in the noncancelable state for long periods of time. A driver should mark a request cancelable and register an I/O cancellation callback if either of the following conditions is true:
The request involves a long-
The request might never succeed, for example, if the request is waiting for synchronous input.
The I/O cancel callback must perform any
UMDF drivers complete the request with ERROR_OPERATION_ABORTED if the request was canceled before it completed successfully or S_OK if it completed successfully despite the cancellation.
KMDF drivers complete the request with STATUS_CANCELLED if the request was canceled before it completed successfully or STATUS_SUCCESS if it completed succssfully despite the cancellation.
Requests that a driver has
To properly implement request cancellation, you must pay careful attention to race conditions between the code in the normal request completion path and the code in the request cancellation
Chapter 10, "Synchronization," includes more information on synchronization techniques for request cancellation.
|
|
When a driver marks a request as cancelable, it gives up ownership of the request to the cancel routine, which could run at any time and complete the request. The driver routine that completes the request must regain ownership before it can complete the request or forward it to another queue. The unmark-cancelable
|
|
KMDF
KMDF provides a way for a driver to determine whether a request has been canceled even if the driver has not marked it cancelable. If the driver does not mark a request cancelable, it can call
WdfRequestIsCanceled
to determine whether the I/O manager or original requester has attempted to cancel the request. A driver that processes data on a periodic basis might use this method. For example, a driver involved in image processing might complete a transfer request in small
Chapter 9, "I/O Targets," includes information about canceling I/O requests that your driver sent to an I/O target.
Table 8-15 summarizes the framework actions when a request is canceled.
|
When cancellation occurs … |
The framework … |
|---|---|
|
Before the request has ever been delivered to the driver |
Cancels the request. No driver code is required, and no notification is sent to the driver. |
|
While the request is in a queue but after it has been delivered to the driver, which could occur if the driver receives an I/O request and then requeues it |
Cancels the request. No driver code is required, and no notification is sent to the driver.
If a KMDF driver has registered an
EvtIoCanceledOnQueue
callback for the queue, invokes this callback, and then cancels the request;
|
|
While the driver owns the request |
If the driver has marked the request cancelable, calls the cancel callback that the driver registered for the request. If the driver has not marked the request cancelable, does nothing. The driver can call WdfRequestIsCanceled to find out whether the request has been canceled. (KMDF only) |
| Tip |
Chapter 24, "Static Driver Verifier," describes how to annotate your driver's callback functions so that SDV can analyze compliance with KMDF rules for request completion and request cancellation. |
When the device transitions to a low-power state-often because the user has
A driver can implement an I/O stop callback to be notified in case of such power changes:
UMDF notifies the driver of the
KMDF notifies the driver of the impending power change by calling the EvtIoStop callback for each such request.
Each call includes flags that
Complete the request.
Requeue the request.
Ignore the notification if the current request will complete in a
Acknowledge the notification but continue to hold the request. (KMDF only)
If the queue is stopping because the device is being removed, the driver should complete the request as soon as possible. After the framework calls the I/O stop callbacks, device removal processing blocks until all driver-owned requests are complete.
Drivers should implement the I/O stop callback for any request that might take a long time to complete or that might not complete. For example, if your driver forwards requests to an I/O target, those requests could