Developing Drivers with the Windows Driver Foundation (Pro Developer)

I/O Model

When Windows sends an I/O request to a WDF driver, the framework receives the request and handles the mechanics of dispatching, queuing, completing, and canceling requests on behalf of its drivers. When an I/O request arrives, the framework determines whether it should handle the request itself or invoke a callback to let the WDF driver handle the request. If the WDF driver is to handle the request, the framework packages the data into a framework request object and passes the object to the driver.

The framework keeps track of every I/O request. Because the framework is aware of all active requests, it can call the appropriate callbacks when an I/O request is canceled, the system's power state changes, the device is removed, and so forth.

A WDF driver manages the flow of I/O requests by creating one or more queue objects and configuring each object for:

WDF drivers register queue callbacks to receive requests, and the queue object dispatches requests by invoking the appropriate callback. A WDF driver can configure a queue object to dispatch requests in one of the following three ways:

Plug and Play and power management events can affect the state of I/O queues. The framework provides integrated Plug and Play and power management support for I/O request queues, and it integrates queuing with request cancellation. A WDF driver can configure a queue so that the framework starts, stops, or resumes queuing as appropriate in response to Plug and Play or power events. WDF drivers can also explicitly start, stop, resume, and purge queues, as required.

I/O Request Cancellation

Because Windows I/O is inherently asynchronous, canceled I/O requests are often difficult to handle correctly. A driver must cope with several potential race conditions that require one or more locks. WDM drivers must manage the necessary locks by themselves, and the required code is typically scattered among several driver routines. The framework provides default handling for I/O request cancellation by managing the locks for the I/O queues and by canceling queued requests without requiring driver intervention. WDF drivers that use the WDF defaults typically require little if any cancellation code.

With WDF, when an I/O request is canceled:

Chapter 8, "I/O Flow and Dispatching," discusses I/O.

I/O Targets

WDF drivers must sometimes send I/O requests to other drivers. For example:

WDF drivers send requests to an I/O target, which is a framework object that represents the driver that is to receive the request. The default I/O target for a WDF driver is the next lower driver in the device stack. However, I/O targets can also represent another driver in the same stack or a driver in an entirely different stack. WDF drivers can send a request to an I/O target synchronously or asynchronously. They can also specify a time-out value for either type of request to limit how long the framework will wait before canceling the request.

I/O target objects support a programming interface that WDF drivers use for purposes such as tracking the state of the target, formatting requests in a target-specific way, obtaining information about the target, and receiving notification if the target is removed. I/O target objects also track queued and sent requests, and they can cancel outstanding requests if changes occur in the state of the target device or the WDF driver that sent the request.

Chapter 9, "I/O Targets," discusses I/O target objects.

How to Handle Nonfatal Errors

WDF drivers call WDF methods for many different purposes. Many of these function calls can fail:

You must be scrupulous about checking return values for errors to ensure that they are handled properly. However, only WDF functions that return a status value can fail. All other functions are guaranteed to simply return a value of the appropriate type, although that return value could be NULL in some cases.

Sometimes the WDF driver itself detects errors. However, only those callbacks that return a status value must be concerned with returning errors. In that case, the callback reports nonfatal errors to the framework by returning the appropriate status value.

Tip 

The PREfast static analysis tool flags any instances where you failed to check a return status. Chapter 23, "PREfast for Drivers," provides details.

Reporting UMDF Errors

The HRESULT type supports multiple success and failure codes:

Chapter 18, "An Introduction to COM," discusses HRESULT values in detail.

Reporting KMDF Errors

The NTSTATUS type also supports multiple success and failure codes:

 Note  The Windows-defined NTSTATUS values are in Ntstatus.h, which is included with the WDK. It is also possible to define custom NTSTATUS values to handle scenarios that are not covered in Ntstatus.h. In general, custom values are used only in circumstances where both components can be expected to understand the value. Several custom NTSTATUS values are used to communicate status between a KMDF driver and the framework. If you complete an I/O request with a custom KMDF NTSTATUS value, KMDF remaps the custom error code to a well-known NTSTATUS value, which is then returned to the originator of the request.

Inside Out 

The KMDF custom NTSTATUS values are defined in %wdk%\inc\wdf\kmdf\VersionNumber\Wdfstatus.h.

Категории