8. WMI Requests (Kernel Mode Drivers Only)
A
Windows Management Instrumentation (WMI) request triggers callbacks
that the driver registered for any current WMI events. In its WMI
callbacks, the driver might call WMI methods on the device object to
create and manipulate WMI instances of to change its status as a WMI
provider. After the WMI callbacks have returned, the framework completes
or forwards the request, as appropriate, on the driver’s behalf. Only
the KMDF supports WMI.
To understand how an I/O request flows through a WDF driver, consider the following scenario:
A user mode process requests a read from a device.
At the time of the request, the device is in a low-power state.
The driver has configured a power-managed queue to accept read requests.
The request is processed by the WDF function driver as follows:
The
IRP dispatcher inspects the IRP and directs it to the I/O package. The
I/O package creates a WDF request object to represent the IRP, adds the
WDF request object to the queue, and checks the current device power
state. Because the device is in a low-power state, the I/O package calls
the Plug and Play/power management package to put the device in the
fully powered working state so that it can perform the read operation.
The
Plug and Play/power management package returns the device to the
working state by taking default actions and calling the appropriate
power management callbacks implemented by the driver.
When
the device has successfully reentered the working state, the framework
dispatches the read request to the driver. If the driver has configured
manual dispatching, the driver calls a method on the queue to get a
request. Otherwise, the framework dispatches the request either
immediately or when the driver has completed the previous request,
depending on the queue’s configuration.
If the driver can satisfy the request, it does; if it cannot, it sends the request to an I/O target.
9. Driver Frameworks
The
WDF driver model is implemented through the KMDF, which supports Kernel
Mode Driver development, and the UMDF, which supports User Mode Driver
development. The frameworks provide the basic driver infrastructure and
perform the following services for WDF Drivers:
Define WDF objects that drivers can instantiate.
Manage object lifetimes.
Expose a basic set of DDIs that drivers call to manipulate the objects.
Provide
a common implementation of features that drivers typically require,
such as Plug and Play, power management, synchronization, I/O queues,
and access to the registry.
Manage the flow of I/O requests and Plug and Play and power notifications from the operating system to the driver.
Instead of calling the
operating system directly, drivers interact with the appropriate
framework for most services. The frameworks manage most of the
interactions with the operating system on behalf of the driver. In
effect, the frameworks shield driver developers from the details of the
operating system.
The frameworks implement the
WDF I/O model, object model, and Plug and Play and power management
support. Each framework receives I/O requests, calls the driver to
handle events according to the driver’s configuration, and applies
defaults otherwise. Both frameworks provide intelligent defaults for
common operations so that drivers do not require large amounts of
potentially buggy “boilerplate” code.
The frameworks support
common features required for all device classes. Device-class-specific
extensions can also be added. For example, the initial release of the
KMDF supports extensions specifically for USB devices. As new features
are added to the operating system, and as new device classes are
supported, features that are common to all device classes will be added
to the base set of DDIs in the frameworks. Extensions will provide
features that are required by one or more specific device classes, but
not by every device class. The extensions are intended to replace the
miniport models common with WDM.
9.1. Kernel Mode Framework
For
Kernel Mode Drivers, the KMDF does not replace WDM; instead, it
provides a skeletal WDM implementation. In effect, the driver developer
configures the skeletal driver to work with a particular device by
creating objects and providing event-based callback routines.
The KMDF is a reentrant library
that can be shared by multiple drivers. Drivers are dynamically bound
with the library at load time, and multiple versions of the library can
be used by multiple drivers simultaneously.
The KMDF currently supports creation of the following types of Kernel Mode Drivers:
Function drivers for Plug and Play devices.
Filter drivers for Plug and Play devices.
Bus drivers for Plug and Play device stacks.
Control device drivers for legacy (NT 4.0-style) devices that are not part of a Plug and Play stack.
Currently, the KMDF does not support bus filter drivers.
WDF provides certain
methods and callbacks specifically for bus drivers, others specifically
for function and filter drivers, and still others for control device
drivers.
The KMDF identifies a
function driver, control device driver, or a bus driver based on the
methods that the driver calls and the callbacks that the driver
supports. For example, the bus driver for a device typically supports
callbacks to enumerate the children of the device and to supply a list
of the hardware resources that the device requires. A function driver
for a device typically supports callbacks to manage power to its device.
A filter driver
explicitly identifies itself as such before creating a device object.
The KMDF uses this information when passing I/O requests to the driver. A
filter driver registers for only the I/O requests it chooses to filter;
the KMDF passes all other requests to the next lower driver. (For a
function or bus driver, WDF fails other requests.) By contrast, a WDM
filter driver must accept all I/O requests that could be targeted to its
device, pass those it does not filter to a lower driver, and act on the
remaining subset. A WDM filter driver requires logic to inspect and
forward many types of requests; a WDF filter driver has no such code
because it receives only the requests it is interested in.
When an application sends an I/O request to a Kernel Mode WDF Driver, the request travels through the components shown in Figure 2.
As the figure shows, the following components are involved in handling an I/O request to a Kernel Mode WDF Driver:
Application— The application is a user mode process that issues I/O requests through the Win32 API.
Win32 API— In response to the application’s I/O request, the Win32 API calls I/O routines in the Windows kernel.
Windows kernel—
The I/O manager in the Windows kernel creates an IRP to represent the
request and presents it to the target driver by calling the driver at a
designated entry point. For Kernel Mode WDF Drivers, the KMDF registers
the entry points, in effect intercepting the request on behalf of the
driver.
KMDF— The KMDF.
9.2. User Mode Framework
The
UMDF implements a subset of the KMDF functionality, including support
for Plug and Play, power management, and asynchronous I/O. Drivers that
run in user mode have access only to the user address space and
therefore pose low risk to system stability. User Mode Drivers cannot
handle interrupts, perform DMA, or use kernel mode resources such as
nonpaged pool.
Using the UMDF, developers can
create drivers for any protocol or serial-bus based device. Although
these drivers run in user mode, they use the standard Plug and Play
installation mechanism and the same I/O model as Kernel Mode WDF
Drivers. Figure 3 shows the components involved in transmitting an I/O request from an application to a User Mode WDF Driver.
Figure 3 includes the following components, described according to the typical flow of an I/O request:
Application— The application is a user mode process that issues I/O requests through the Win32 API.
Win32 API— In response to the application’s I/O request, the Win32 API calls I/O routines in the Windows kernel.