Developing Drivers with the Windows Driver Foundation (Pro Developer)
In UMDF, the framework maintains a set of framework objects, and the driver creates a callback object that corresponds to each framework object for which the driver requires an event callback. The callback objects expose callback interfaces that are defined by the framework.
UMDF drivers use the following types of objects:
Driver-created file | I/O completion parameters |
Base object | I/O target |
Driver | Memory |
Device | USB device |
File | USB I/O target |
I/O request | USB interface |
I/O queue |
UMDF objects and interfaces are based on the COM programming pattern. UMDF uses only the query-interface and reference-counting features of COM; it does not depend on the entire COM infrastructure and runtime library.
Chapter 18, "An Introduction to COM," provides information about COM.
UMDF Naming Conventions
UMDF follows naming conventions for the interfaces that it implements and the callback interfaces that it defines.
UMDF interface names The UMDF-implemented interfaces are named:
-
IWDFObject[Description]
where:
-
Object specifies the UMDF object that exposes the interface.
-
Description is additional information that indicates which aspect of the object it acts on.
For example, framework device objects expose the IWDFDevice interface, which supports methods that manipulate a framework device object. Framework I/O target objects expose the IWDFIoTarget and IWDFIoTargetStateManagement interfaces.
UMDF method names Methods in UMDF interfaces are named:
-
ActionQualifier
where:
-
Action is a verb that indicates the action that the function performs.
-
Qualifier specifies the object or data that is the target of the action.
For example, the IWDFDevice interface includes the CreateIoQueue and ConfigureRequestDispatching methods.
UMDF property names UMDF properties are named:
-
{Set|Get}Data
-
{Assign|Retrieve}Data
where:
-
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 properties without failure. Functions with Assign and Retrieve in their names can fail and return an HRESULT that contains a status value.
For example, IWDFDevice::GetPnpState and IWDFDevice::SetPnpState set and return the value of individual Plug and Play characteristics for a device object.
UMDF event callback interface names Event callback interfaces for UMDF objects are generally named:
-
IObjectCallbackDescription
where:
-
Object identifies the object type.
-
Description indicates what the interface does.
For example, the IQueueCallbackWrite interface is implemented on a queue callback object. It supports a method that the framework calls in response to a write request.
The IPnpCallbackXxx interfaces are an exception. Although these interfaces have Pnp in their names, they are implemented on device objects. They support methods that respond to Plug and Play events.
UMDF methods within the callback interfaces are named:
-
OnEvent
where:
-
Event indicates the event for which the framework invokes the callback method.
For example, the framework calls the IQueueCallbackWrite::OnWrite method when a write request arrives for the device object. The IPnpCallback::OnD0Entry method is called when the device enters the working power state.
UMDF Framework Objects and Interfaces
Table 5-1 lists the interfaces that the framework implements on each type of object.
Type of object | Object description | Interfaces | Interface description |
---|---|---|---|
Base object | Represents a generic base object for the driver to use as required. | IWDFObject | Supports actions common to all objects, such as locking, deletion, and managing the context area. |
Device | Represents a device object. A driver typically has one device object for each device that it controls. Inherits from IWDFObject. | IWDFDevice | Provides device-specific information and creates device-specific objects. |
IWDFFileHandleTargetFactory | Creates an I/O target object based on a file handle. | ||
IWDFUsbTargetFactory | Creates a USB I/O target device object. | ||
Driver | Represents the driver object itself. Every driver has one driver object. Inherits from IWDFObject. | IWDFDriver | Creates driver child objects and provides version information. |
File | Represents a framework file object that was opened by the CreateFile function, through which applications can access the device. Inherits from IWDFObject. | IWDFFile | Returns information about the file and device that are associated with a file handle. |
Driver-created file | Represents a framework file object that the driver created. Inherits from IWDFFile. | IWDFDriverCreatedFile | Closes a driver-created file. |
I/O queue | Represents an I/O queue, which controls the flow of I/O in the driver. A driver can have any number of I/O queues. Inherits from IWDFObject. | IWDFIoQueue | Configures, manages, and retrieves requests and information from a queue. |
I/O request | Represents a request for device I/O. Inherits from IWDFObject. | IWDFIoRequest | Formats, sends, cancels, and returns information about an I/O request. |
I/O request completion information | Represents the completion information for an I/O request. | IWDFRequestCompletionParams | Returns status, number of bytes, and request type for a completed I/O request. |
I/O request completion parameters | Exposes the parameters returned in a completed I/O request. Inherits from IWDF-RequestCompletionParams. | IWDFIoRequestCompletionParams | Returns buffers for read, write, and device I/O control requests. |
I/O target | Represents the next-lower driver in the device stack, to which the driver sends I/O requests. Inherits from IWDFObject. | IWDFIoTarget | Formats and cancels I/O requests and returns information about the target file. |
IWDFIoTargetStateManagement | Monitors and controls the state of an I/O target. | ||
Memory | Represents memory that the driver uses, typically an input or output buffer that is associated with an I/O request. Inherits from IWDFObject. | IWDFMemory | Copies data to and from a memory buffer and returns information about the buffer. |
Property store | Represents an object through which a driver can maintain persistent data in the registry between driver loads and unloads. | IWDFNamedPropertyStore | Enables a driver to query and set information in the registry. |
USB interface | Represents an interface on a USB device. Inherits from IWDFObject. | IWDFUsbInterface | Returns information about and selects a setting for a USB interface. |
USB target device | Represents a USB device object that is an I/O target. Inherits from IWDFIoTarget. | IWDFUsbTargetDevice | Formats requests for and returns information about a USB target device. |
USB target pipe | Represents a USB pipe that is an I/O target. Inherits from IWDFIoTarget. | IWDFUsbTargetPipe | Manages and returns information about a USB pipe. |
USB I/O request completion parameters | Exposes the parameters returned in a completed I/O request to a USB target. Inherits from IWDFRequestCompletionParams. | IWDFUsbRequestCompletionParams | Returns request type and buffers for USB read, write, and device I/O control requests. |
UMDF Driver Callback Objects and Interfaces
A UMDF driver assigns a callback object to each framework object whose events the driver is interested in and implements callback interfaces for those events on the callback object. Every UMDF driver must implement one driver callback object for the driver itself and one device callback object for each device that it supports. Most drivers also implement a queue callback object for each queue.
The driver must implement the IUnknown interface for each callback object. The driver can do this in any of several ways. The UMDF Echo, Skeleton, and USB samples include the Comsup.h header file, which implements IUnknown in the CUnknown base class. In your own driver, you can include Comsup.h and list CUnknown as a base class when you declare the driver's classes.
Chapter 13, "UMDF Driver Template," provides details about how to use the Skeleton sample as a template for your own driver development.
Table 5-2 lists the possible callback interfaces that a driver can implement.
Type of object | Callback interfaces | Description of interface |
---|---|---|
All objects | IObjectCleanup | Provides processing that is required before an object is disposed, typically releasing any circular references. |
Driver | IDriverEntry | Provides the main entry point from the framework into the driver and methods to initialize the driver and add its devices. This object is required for all drivers. Unlike other callback interfaces, the driver does not register IDriverEntry with any particular object. Instead, the framework requests this interface from the driver's CoClass object when it loads the driver. |
Device | IPnpCallback | Handles device stop, removal, and power state changes. |
IPnpCallbackHardware | Provides hardware-related operations before device power-up and after device power-down. | |
IPnpCallbackSelfManagedIo | Enables the driver to perform actions when the framework starts and stops I/O processing at specific Plug and Play and power management state transitions. | |
File | IFileCallbackCleanup | Handles cleanup requests for file objects on a specific device, typically so that the driver can cancel any outstanding I/O requests for the file before it is closed. |
IFileCallbackClose | Receives close notifications for file objects on a specific device so that the driver can release file-specific resources. | |
I/O queue | IQueueCallbackCreate | Handles file create requests. |
IQueueCallbackDefaultIoHandler | Handles create, device I/O control, read, and write requests for which no other interface has been implemented. | |
IQueueCallbackDeviceIoControl | Handles device I/O control requests. | |
IQueueCallbackIoResume | Resumes processing an I/O request after its queue has been stopped. | |
IQueueCallbackIoStop | Stops processing an I/O request because its queue is stopping. | |
IQueueCallbackStateChange | Notifies the driver when the state of a queue changes. | |
IQueueCallbackRead | Handles read requests. | |
IQueueCallbackWrite | Handles write requests. | |
I/O request | IImpersonateCallback | Performs tasks while the driver impersonates the client that issued the I/O request. |
IRequestCallbackCancel | Performs tasks after an I/O request is canceled. | |
IRequestCallbackRequestCompletion | Performs tasks when an I/O request is completed. |
When an event occurs, the framework calls methods on the appropriate callback interfaces so that the driver can respond to the events that are associated with the request. For example, if the driver has configured a queue for read requests, the framework calls methods in the queue callback object's IQueueCallbackRead interface when it receives such a request.
Tip | Framework objects and callback objects are not required to correspond on a one-to-one basis. The driver can do whatever makes the most sense for the callback and the driver. For example, consider I/O cancellation and completion callbacks. You can implement these interfaces on whichever callback object seems most appropriate. If your driver has a queue that also manages continuous reads on an interrupt pipe, then it might make sense to implement the cancellation and completion callback interfaces on the queue. Likewise, if your driver allocates a context area for each request to track the state of the request, then you could create a callback object instead and implement the I/O cancellation and completion callback interfaces on the callback object. |
UMDF Example: Objects and Callback Interfaces
Figure 5-1 shows the primary callback interfaces that the Fx2_Driver sample implements for the driver and device objects. IUnknown-which all COM objects must support-is not shown, nor are the objects and callback interfaces that support the driver's I/O queues.
As the figure shows, the framework implements a driver object and a device object, and the Fx2_Driver sample creates a driver callback object and a device callback object. The framework driver object uses the driver callback object's IDriverEntry interface, and the driver callback object, in turn, uses the IWDFDriver interface on the framework driver object.
The framework device object exposes the IWDFDevice and IWDFDeviceInitialize interfaces, which the device callback object uses. The device callback object also implements the IPnpCallbackHardware and IPnpCallback interfaces, which the framework device object uses.
Категории