10. Windows Kernel
The I/O manager in the Windows
kernel creates IRPs to represent the requests and presents them to the
target driver by calling the driver at a designated entry point. If the
target of the request is a User Mode WDF Driver, however, the I/O
manager cannot call the driver or the UMDF directly because these
components run a user mode process, and kernel mode components cannot be
called back to user mode. Therefore, the I/O manager does not present
the request directly to the User Mode Driver. Instead, the I/O manager
presents the request to a kernel mode component called the reflector.
10.1. Reflector
The reflector is a Kernel Mode
WDM Filter Driver that represents the User Mode Driver in the Kernel
Mode Driver stack. The reflector passes the I/O request to the User Mode
Driver host process.
The reflector
manages communication between the kernel mode components and the User
Mode Driver host process. It monitors the driver host process to ensure
that it responds properly to messages and completes critical operations
in a timely manner, thus helping to prevent driver and application
hangs. The reflector also sends messages to the driver manager as
required.
The reflector is supplied
by Microsoft and is added as the top driver in the Kernel Mode Driver
stack during installation of the User Mode Driver.
10.2. Driver Host Process
The driver host process is the user mode process in which the User Mode Driver runs. It includes the following components:
The User Mode WDF Driver is an in-process COM component that controls the hardware from user mode.
The
UMDF exposes the User Mode DDI. The UMDF is a dynamic-link library
(DLL) of COM-style objects that support the presentation, flow, and
management of I/O, Plug and Play, and power management requests to the
driver.
The
run-time environment dispatches I/O requests, loads the driver,
constructs and destroys the user mode device stack, manages a user mode
thread pool, and handles messages from the reflector and the driver
manager.
The driver host process is
separate from the application process and the driver manager. It runs in
the security credentials of a LocalService account, although it is not a
Windows service. The driver host process contains the user mode device
stack for the device. The device stack is visible to all applications
across the system. Each instance of a device has its own device stack.
Currently, each instance has a separate driver host process, too. The
driver host process is a child process of the driver manager.
10.3. Driver Manager
The driver manager creates
and shuts down the driver host process and maintains status information
about it. It also responds to messages from the reflector. The driver
manager runs as a Windows service is started during installation of the
first device that is managed by a User Mode WDF Driver. The driver
manager must be running all the time that any device controlled by a
User Mode WDF Driver is installed on the system.
2.11. Tools for Development and Testing
The WDF has some outstanding
tools to aid in the testing of drivers. We will cover those in the
following discussion. Thoroughly testing a driver is nearly as complex
as writing one for two main reasons:
Observing the point of
error can be difficult. In many cases, a driver error is not apparent
until long after it has actually occurred. If a Kernel Mode Driver uses a
DDI incorrectly, the system might not crash until another driver
attempts to perform an action based on the first driver’s error.
Subtle,
condition-dependent errors and related code paths are difficult to
exercise. Drivers that work correctly under normal circumstances can
have subtle errors that occur only under exceptional situations, such
as when another driver, lower in the stack, fails an I/O request.
Too often, testing becomes a
hit-or-miss, trial-and-error affair. To help remedy the situation, WDF
has several testing and tracing features that make it easier for driver
writers to find problems early in the development cycle. We will cover
these features in more detail in the subsequent discussion. These
features include the following:
In addition, WDF includes
PREfast and Static Driver Verifier (SDV). PREfast and SDV are both
compile-time code verification tools that are provided with the Windows
Driver Kit (WDK). PREfast analyzes code on a function-by-function basis,
looking for a wide variety of common logic and usage errors. SDV
applies knowledge about system internals to Kernel Mode Driver
verification.
11.1. PREfast for Drivers
PREfast for Drivers (PFD), an
extension of PREfast, is a compile-time static verification tool that
detects errors missed by the compiler and by conventional run-time
testing. It detects common coding errors in C and C++ programs, and is
designed to detect errors in Kernel Mode Driver code. You can run PFD
very early in the development cycle—as soon as the code compiles
correctly. PFD is integrated into the Windows 7 build environments in
the Windows Driver Kit (WDK) as well as into Windows Automated Code
Review (known as OACR). PFD supports a large vocabulary of annotations
beyond those supported for generic PREfast, including annotations for
IRQLs, resource-object leaks, memory leaks, and stricter type checking.
PREfast for Drivers
examines each function in the code independently, looking for common
errors and unwise coding practices. PFD runs quickly, even on large
drivers, and generates a report that identifies the line of driver code
with the suspected error.
PREfast for Drivers runs on Windows XP and later versions of Windows and is designed to analyze code written for X86-based and X64-based platforms. It can analyze C and C++ source files for drivers in any driver model, including managed code.
You should use PREfast for
Drivers in conjunction with Driver Verifier, Static Driver Verifier, and
the checked build of Windows to ensure that your driver code is safe
and reliable.
The following new features for PFD are in Windows 7:
PFD now supports a broader range of expressions for analysis, such as const, member names, and side effect-free C expressions.
PFD now has better annotation error checking.
PFD now has improved defect detection, including “banned API” checking.
PFD
now generates warnings that help you prepare to analyze a driver with
Static Driver Verifier (SDV). SDV requires drivers to have declarations
that define the role of the driver-supplied callback functions. PFD will
indicate when you need to add these role type declarations to the drive
code.
PFD
is now integrated into the build environments and OACR in the WDK. When
you build your driver using the WDK build environments, PFD runs
automatically in the background and presents an easy-to-read view for
any potential defects it finds.
For Windows 7, all
Microsoft drivers that ship with the operating system and all WDK
samples have been verified with PFD, and identified defects have been
fixed. In addition, the WDK public headers are now annotated to enable
PFD to better find code defects. The following functionality aids in
finding code defects.
Because PFD annotations
are not in public header files, driver writers can take advantage of
these checks by simply running PFD on their drivers. Adding PFD
annotations to your driver code will give you deeper analysis.
Windows headers for drivers now provide a comprehensive set of examples of how to annotate your functions.
11.2. Static Driver Verification (SDV)
Static Driver Verifier
(SDV) is a static verification tool that runs at compile time. It
explores paths in the driver code by symbolically executing the source
code, making the fewest possible assumptions about the state of the
operating system and the initial state of the driver. As a result, SDV
can exercise code in paths that are missed in traditional testing.
SDV includes a set of rules that
defines proper interaction between a driver and the operating system
kernel. During verification, SDV examines every applicable branch of the
driver code and the library code that it uses, and tries to prove that
the driver violates the rules. If SDV fails to prove a violation, it
reports that the driver complies with the rules and passes the
verification.
11.3. Frameworks Verifier
WDF includes an
internal driver verifier that provides framework-specific features that
are not currently available in the driver verifier (Verifier.exe). The
frameworks verifier provides extensive tracing messages that supply
detailed information about activities within the framework. It tracks
references to each WDF object and builds a trace that can be sent to the
debugger.
In kernel mode, the
frameworks verifier checks lock acquisition and hierarchies, and ensures
that calls to the framework occur at the correct IRQL. It also verifies
correct I/O cancellation and queue usage. It can also simulate
low-memory and out-of-memory conditions and test a driver’s response to
these situations to determine whether the driver responds properly
without crashing, hanging, or failing to unload.
In user mode, the frameworks
verifier checks for correct use of parameters, validates configurations,
and correct responses to events.
11.4. Trace Logging
Both the KMDF and UMDF support integrated internal trace logging. The following discussions cover this internal trace logging.
The KMDF includes an
internal trace logger called the in-flight recorder (IFR), which is
based on the Windows Software Trace Preprocessor (WPP). The IFR provides
a recent history of events (currently, about the last 100 trace events)
on a per-driver-instance basis. The trace logs track the progress of
IRPs through the framework and the corresponding requests through a
driver. Each WDF driver has its own log.
Kernel Mode Drivers can use
Event Tracing for Windows (ETW) and WPP software tracing to generate a
trace log that contains information about
both the driver and the KMDF. Driver-level tracing provides information
about events in the driver code. Internal WDF tracing provides
information about events internal to WDF that might affect driver
activities. A driver developer can choose whether to implement
driver-level tracing, but internal WDF tracing is always available.
Driver writers can use
the software tracing tools provided with the WDK to view the IFR logs
during interactive debugging. These logs can also be made available as
part of a mini dump for inspection after a crash. The typical saved IFR
log file is small (10K to 20K bytes) and written in a binary form that
humans cannot read.
The User Mode Driver
components supplied by Microsoft start trace sessions that record their
activities and note such events as driver hangs, timeouts, and failures.
The log files from these sessions can be sent as input to Windows Error
Reporting (WER). Vendor-supplied User Mode WDRF Drivers can use ETW to
generate a trace log of driver events.
11.5. Debugger Extensions
WDF also includes
several debugger extensions that can dump internal trace records. These
extensions are specialized commands that run in the context of the
WinDbg debugger. These extensions are packaged in two DLLs: WudfExt.dll
contains the UMDF extensions, and WdfKd.dll contains the KMDF
extensions. The information they provide can help locate the exact point
in I/O processing at which an error occurred and can often give a clue
to faulty assumptions or unexpected behavior.
The two sets of
debugger extensions are provided for WDF. As mentioned, one set supports
user mode debuggers, and the other supports kernel mode debuggers.
11.6. Serviceability and Versioning
To improve driver
serviceability, WDF includes versioning and side-by-side support.
Versioning allows a driver binary to run with the same major version of
WDF with which it was built. Side-by-side support enables the
simultaneous use of two or more major versions of WDF by two or more
drivers.
Serviceability is a common
problem for drivers. When Microsoft releases a new version of Windows,
driver vendors must test their drivers to ensure that they operate
properly on the new release. Any driver that uses undocumented features,
or that uses documented features in a nonstandard way, is likely to
encounter compatibility problems from one release to the next. Even
drivers that follow the rules might be affected by subtle changes
between versions of Windows.
Drivers that use the
frameworks, however, are less susceptible to such problems. Microsoft is
responsible for testing the frameworks on each new version of the
operating system and ensuring that drivers built with older versions
maintain consistent behavior from one release to the next.
In addition, the versioning
support in WDF helps to prevent compatibility problems. The frameworks
have major and minor version numbers, which are recorded in the driver
binaries. In general, a WDF driver runs against the latest available
minor version of the major version against which it was compiled, so
that it can benefit from bug fixes in the new version.
A WDF driver can use a newer
minor version, but not an older minor version, than the one against
which it was built. Multiple WDF drivers can use a single WDF library.
They can also run side by side using different major versions of the
framework.