3. KMDF Driver Structure and Concepts
KMDF drivers are object-oriented, event-driven
drivers that link dynamically with the Kernel Mode Driver Framework at
run time. This discussion provides a brief overview of KMDF concepts.
The KMDF object model defines object types to
represent common driver constructs. Each object exports methods
(functions) and properties (data) that drivers can access and is
associated with object-specific events, which drivers can support by
providing event callbacks. The objects themselves are opaque to the
driver. KMDF and the driver instantiate the objects that are required
to service the device. The driver provides callbacks for the events for
which the KMDF defaults do not suit its device and calls methods on the
object to get and set properties and perform any additional actions.
Thus, a KMDF driver consists of a DriverEntry
function, callback routines for events that affect the driver or its
devices, and whatever utility functions the driver requires.
All KMDF drivers create a WDFDRIVER object to represent the driver and a WDFDEVICE object to represent each device that the driver supports. Most drivers also create one or more WDFQUEUE
objects to represent the driver’s I/O queues. KMDF places I/O requests
into the queues until the driver is ready to handle them.
Drivers can create additional objects as their
device hardware and driver features require. KMDF objects are organized
hierarchically, with the WDFDRIVER object as the root. The object hierarchy defines the object’s lifetime—each object is deleted when its parent is deleted.
All KMDF objects are created in the same way, by
using KMDF-defined initialization functions and an object creation
method. Any KMDF object has one or more driver-defined object context
areas, in which the driver can store data that is specific to that
particular instance of the object.
The following discussions provide more information
on object creation and context areas and on I/O queues and requests,
which are fundamental to KMDF drivers.
3.1. Object Creation
To create a KMDF object, a driver follows these steps:
1. | Initialize the configuration structure for the object, if one exists.
|
2. | Initialize the attributes structure for the object, if necessary.
|
3. | Call the creation method to create the object.
|
The object configuration structure and the object
attributes structure supply basic information about the object and how
the driver uses it. All object types have the same attributes
structure, but the configuration structure for each type of object is
different and some objects do not have one.
The configuration structure holds pointers to
object-specific information, such as the driver’s event callback
functions for the object. The driver fills in this structure and then
passes it to the framework when it calls the object creation method.
The framework uses the information from the configuration structure to
initialize the object. For example, the WDFDRIVER object contains a pointer to the driver’s EvtDriverDeviceAdd callback function, which KMDF invokes when a Plug and Play add-device event occurs.
KMDF defines functions named WDF_Object_Config_INIT to initialize the configuration structures, where Object
represents the name of the object type. Not all object types have
configuration structures or the corresponding initialization functions.
The object attributes structure (WDF_OBJECT_ATTRIBUTES) specifies attributes that are common to all objects:
Callbacks to handle object cleanup and destruction.
The interrupt request level (IRQL) at which the objects’ callback functions are invoked and its locks are held.
An object context area.
Information about the context area, such as its size and type.
KMDF defines the following for use in initializing object attributes:
WDF_OBJECT_ATTRIBUTES_INIT
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE
WDF_OBJECT_ATTIBUTES_SET_CONTEXT_TYPE
The WDF_OBJECT_ATTRIBUTES_INIT
function sets values for synchronization and execution level, which
determine which of the driver’s callbacks KMDF invokes concurrently and
the highest IRQL at which they can be called. The two context-type
initialization macros set information about the object’s context area,
which is described in the next section.
Although attributes can apply to any type of object,
the defaults are typically acceptable for objects for which the driver
does not define a context area. To accept the defaults, a driver
specifies WDF_NO_OBJECT_ATTRIBUTES, in which WDK defines a NULL.
After initializing the object’s configuration
structure and attributes, the driver creates an instance of the object
by calling the creation method for the object type with pointer to the
attributes structure and any other object-type-specific parameters.
Creation methods are all named WdfObjectCreate, where Object
indicates the type of object. The creation method returns a handle to
the created object. The driver subsequently uses the handle to refer to
the object.