Developing Drivers with the Windows Driver Foundation (Pro Developer)
KMDF defines a larger set of objects than UMDF defines, because kernel-mode drivers have access to additional resources and can perform certain operations, such as handling interrupts, that user-mode drivers cannot perform. In addition to the object types that UMDF supports, KMDF also includes the following types of objects:
Collection | String |
DPC | Timer |
Interrupt | WMI |
Lookaside list | Work item |
Registry key | |
Several objects for DMA: DMA enabler, DMA transaction, and common buffer | Several objects for hardware resources: resource range list, resource list, and resource requirements list |
KMDF does not support a named property store; instead, KMDF drivers manage persistent data by using registry key objects.
From the driver's perspective, WDF objects are opaque and the driver never directly accesses the underlying structure. Instead, a KMDF driver refers to an object by using a handle. The driver passes the handle as a parameter to the object's methods, and KMDF passes the handle as a parameter to event callbacks.
KMDF Object Types
For KMDF drivers, the framework creates objects for which the driver supplies callback function pointers. KMDF drivers do not require callback objects. Table 5-3 lists all of the KMDF object types.
Object | Type | Description |
---|---|---|
Child list | WDFCHILDLIST | Represents a list of the child devices that the bus driver enumerates for a parent device. |
Collection | WDFCOLLECTION | Describes a list of similar objects, such as resources or the devices for which a filter driver filters requests. |
Device | WDFDEVICE | Represents an instance of a device. A driver typically has one WDFDEVICE object for each device that it controls. |
DMA common buffer | WDFCOMMONBUFFER | Represents a buffer that can be accessed by both the device and the driver to perform DMA. |
DMA enabler | WDFDMAENABLER | Enables DMA use by a device. A driver that handles device I/O operations has one WDFDMAENABLER object for each DMA channel within the device. |
DMA transaction | WDFDMATRANSACTION | Represents a single DMA transaction. |
DPC | WDFDPC | Represents a DPC. |
Driver | WDFDRIVER | Represents the driver itself and maintains information about the driver, such as its entry points. Every driver has one WDFDRIVER object. |
File | WDFFILEOBJECT | Represents a file object through which external drivers or applications can access the device. |
Generic object | WDFOBJECT | Represents a generic object for the driver to use as required. |
I/O queue | WDFQUEUE | Represents an I/O queue. A driver can have any number of WDFQUEUE objects. |
I/O request | WDFREQUEST | Represents a request for device I/O. |
I/O target | WDFIOTARGET | Represents a device stack to which the driver is forwarding an I/O request. A driver can have any number of WDFIOTARGET objects. |
Interrupt | WDFINTERRUPT | Represents a device's interrupt object. Any driver that handles device interrupts has one WDFINTERRUPT object for each IRQ or message-signaled interrupt (MSI) that the device can trigger. |
Lookaside list | WDFLOOKASIDE | Represents a dynamically sized list of identical buffers that are allocated from either paged or nonpaged pool. |
Memory | WDFMEMORY | Represents memory that the driver uses, typically an input or output buffer that is associated with an I/O request. |
Registry key | WDFKEY | Represents a registry key. |
Resource list | WDFCMRESLIST | Represents the list of resources that have actually been assigned to the device. |
Resource range list | WDFIORESLIST | Represents a possible configuration for a device. |
Resource requirements list | WDFIORESREQLIST | Represents a set of I/O resource lists, which comprises all possible configurations for the device. Each element of the list is a WDFIORESLIST object. |
String | WDFSTRING | Represents a counted Unicode string. |
Synchronization: spin lock | WDFSPINLOCK | Represents a spin lock, which synchronizes access to data DISPATCH_LEVEL. |
Synchronization: wait lock | WDFWAITLOCK | Represents a wait lock, which synchronizes access to data at PASSIVE_LEVEL. |
Timer | WDFTIMER | Represents a timer that fires either once or periodically and causes a callback routine to run. |
USB device | WDFUSBDEVICE | Represents a USB device. |
USB interface | WDFUSBINTERFACE | Represents an interface on a USB device. |
USB pipe | WDFUSBPIPE | Represents a configured pipe in a USB interface's setting. |
WMI instance | WDFWMIINSTANCE | Represents an individual WMI data block that is associated with a particular provider. |
WMI provider | WDFWMIPROVIDER | Represents the schema for WMI data blocks that the driver provides. |
Work item | WDFWORKITEM | Represents a work item, which runs in a system thread at PASSIVE_LEVEL. |
Note Framework objects are unique to the framework. Framework objects are not managed by the Windows object manager and cannot be manipulated by using the system's ObXxx functions. Only the framework and its drivers can create and operate on framework objects. Framework objects are also unique to the driver that created them and should not be shared between two different framework drivers.
KMDF Naming Conventions
KMDF follows a set of naming conventions for the methods, properties, and events that its objects support.
KMDF method names KMDF methods are named:
-
WdfObjectOperation
where:
-
Object specifies the KMDF object on which the method operates.
-
Operation indicates what the method does.
For example, the WdfDeviceCreate method creates a framework device object.
KMDF property names KMDF properties are named:
-
WdfObject{Set|Get}Data
-
WdfObject{Assign|Retrieve}Data
where:
-
Object specifies the KMDF object on which the function operates.
-
Data specifies the field that the function reads or writes.
Some properties can be read and written without failure, but other properties can sometimes fail. Functions with Set and Get in their names read and write fields without failure. The Set functions return VOID, and the Get functions typically return the value of the field. Functions with Assign and Retrieve in their names can fail and return an NTSTATUS value.
For example, the WDFINTERRUPT object represents the interrupt object for a device. Each interrupt object is described by a set of characteristics that indicate the type of interrupt-message signaled or IRQ based-and provide additional information about the interrupt. The WdfInterruptGetInfo method returns this information. A corresponding method to set the value is not available, because the driver initializes this information when it creates the object and cannot change it later.
KMDF event callback function names In header files and documentation, the placeholders for KMDF event callback functions are named:
-
EvtObjectDescription
where:
-
Object specifies the KMDF object on which the function operates.
-
Description indicates what triggers the callback.
Most of the sample drivers name callback functions by replacing or prepending Evt with the name of the driver. For example, the Osrusbfx2 driver's callback function names typically start with OsrFxEvt. Conforming to a similar convention in your own drivers is a good idea, because it improves code readability and makes clear the purpose of each function, when it is called, and who calls it.
A driver registers callbacks only for the events that are important to its operation. When the event occurs, the framework invokes the callback, passing as a parameter a handle to the object for which the callback is registered. For example, if a device can be ejected, its driver registers an EvtDeviceEject callback, which performs device-specific operations upon ejection. When the PnP manager sends an IRP_MN_EJECT request for the device, KMDF calls the EvtDeviceEject routine with a handle to the device object.
Note KMDF events are not related to the kernel-dispatcher events that Windows provides as synchronization mechanisms. A driver cannot create, manipulate, or wait on a KMDF event; a KMDF event is simply a function. For time-related waits, KMDF provides timer objects.
Категории