Developing Drivers with the Windows Driver Foundation: WDF Fundamentals
What Is WDF?
WDF provides a unified driver model for a large range of device types. The most important features of the model include:
Support for both user-mode and kernel-mode drivers.
The core of the model can be used by either type of driver.
A well-designed object model.
WDF drivers interact with objects through a robust and consistent programming interface.
An object hierarchy that simplifies object lifetime management and synchronization of I/O requests.
An I/O model in which the frameworks handle interactions with the operating system.
The frameworks also manage the flow of I/O requests, including responding to Plug and Play and power events.
A Plug and Play and power management implementation that provides robust state management and intelligent default processing for state transitions.
WDF drivers handle only those state transitions that are relevant to their device.
The framework provides a set of objects that represent various fundamental Windows and driver-related constructs, such as device, driver, I/O request, queue, and so on. WDF drivers use the framework objects to implement the various aspects of driver functionality. For example, when a WDF driver requires a queue to manage I/O requests, it creates a framework queue object.
Each object exposes a programming interface that the WDF driver uses to access object properties or direct the object to perform tasks. Each object also supports one or more events, which are raised in response to occurrences such as a system state change or the arrival of an I/O request. Events allow the framework to notify a WDF driver that something interesting has occurred and pass control to the WDF driver to handle the event. For example, a framework queue object raises an event to notify the WDF driver that an I/O request is ready to be processed.
Some framework objects are created by the framework and passed to the WDF driver. Other framework objects are created as the WDF driver needs them. As the developer, your job is to assemble the appropriate objects in a structure that supports the requirements of the device. The structure controls how the framework routes I/O through the WDF driver and how that driver interacts with the operating system and the device. The details of the structure vary, depending on the particular requirements of the device, but all WDF drivers are constructed from the same basic pieces.
Some framework objects are permanent or very long lived. For example, when a device is plugged in, a typical WDF driver creates a device object to represent the device and one or more queue objects to manage I/O requests. These objects usually persist for the lifetime of the device. Some objects are transient; they serve a specific short-term purpose and are destroyed as soon as that purpose is achieved. For example, a WDF driver could create an I/O request object to issue a single I/O request and then destroy it after the request is completed.
The framework provides default processing for all events, so WDF drivers are not required to handle any of them. However, depending solely on the framework’s default event processing leads to a functional, but relatively uninteresting driver. To provide the necessary device-specific support, WDF drivers must handle at least some events.
To override the framework’s default event handling, a WDF driver must explicitly register a callback. The framework invokes the callback to notify the WDF driver that the event has occurred and allow the driver to do any necessary processing. This opt-in event model is a key aspect of WDF. The framework provides intelligent default processing for all events—if the default processing for an event is adequate, WDF drivers do not need to register a callback. WDF drivers register callbacks for only those events for which the framework’s default processing is not sufficient. All other events are handled by the framework, without any driver intervention.