Device Objects


When the PnP manager finds a device that the driver controls, it notifies the framework. The framework, in turn, calls the driver so that the driver can create and initialize the data structures that are required to manage the device. The most important of these is the device object.

The device object represents the driver's role in managing the device. It contains status information and is the driver's target for I/O requests that are directed to the device. Windows directs requests to the device object, not to the driver.

The device object contains device-specific information that the driver uses while handling I/O requests and managing the device. The device object also supports the callbacks that the driver implements to respond to device-related events.

Types of Device Objects

The function driver, bus driver, and any filter drivers for a device respond to many of the same events and handle many of the same requests. However, not all events or requests apply to all types of drivers. Bus drivers, for instance, respond to some events that do not affect function drivers and in some cases require access to different device properties and other device information. Consequently, WDF defines types of device objects that correspond to each type of driver.

WDF defines the following types of device objects:

  • Filter device objects (filter DOs)

    A filter driver creates a filter DO for each of its devices. Filter DOs "filter"-or modify-one or more types of I/O requests that are targeted at the device.

  • Functional device objects (FDOs)

    A function driver creates an FDO for each of its devices. The FDO represents the primary driver for the device.

  • Physical device objects (PDOs)

    A bus driver creates a PDO for each device that is attached to its bus. The PDO represents the device in relationship to its bus.

    UMDF drivers cannot create PDOs.

  • Control device objects

    Any KMDF driver can create a control device object, which represents a legacy non-Plug and Play device or a control interface through which a Plug and Play driver receives so-called "sideband" I/O requests. Control device objects are not part of the Plug and Play device stack.

    UMDF drivers cannot create control device objects.

Although this book focuses primarily on how to write function and filter drivers, you should be familiar with all of the driver types and device objects. The following sections provide a brief overview of each type.

Filter Drivers and Filter Device Objects

Filter drivers do not typically perform device I/O themselves; instead, they modify or record a request that another driver satisfies. Device-specific data encryption and decryption are commonly implemented in a filter driver. A filter driver receives one or more types of I/O requests that are targeted at its device, takes some action based on the request, and then typically passes the request to the next driver in the stack.

A filter driver adds a filter DO to the device stack. A driver notifies the framework that it is a filter driver when its device is added to the system, so that the framework can set the appropriate defaults.

Most filter drivers are not "interested" in every request. For example, a filter driver might filter only create or read requests. A filter driver sets up queues for the types of requests that it filters. The framework dispatches only those request types to the driver and passes all other requests down the device stack. The filter driver never receives them and so does not require code that inspects them or passes them down the stack.

Some types of devices can also have bus filter drivers, which perform complex, low-level tasks for a bus. Bus filter drivers are rare, and WDF does not support their development.

Function Drivers and Functional Device Objects

Function drivers are the primary drivers for their devices. A function driver communicates with its device to perform I/O and typically manages power policy for its device by determining, for instance, when the device is idle and can be powered down to conserve energy. In the Plug and Play device stack, a function driver exposes an FDO. When a driver creates a device object, both frameworks create an FDO by default unless the driver specifies otherwise.

 KMDF  Kernel-mode function drivers often have additional requirements that do not apply to user-mode function drivers. For example, a kernel-mode function driver that controls a device that supports wake signals must implement callback functions that enable and disable such signals. The WdfFdoInitXxx and WdfFdoXxx DDIs define a set of methods, events, and properties that apply to a KMDF driver's FDOs during initialization and operation.

By using the FDO interfaces, a driver can:

  • Register event callbacks that are related to resource allocation for its device.

  • Retrieve properties of its physical device.

Most of the sample drivers create an FDO. The KMDF KbFiltr, Toaster Filter, and Firefly drivers do not create an FDO.

Bus Drivers and Physical Device Objects (KMDF)

 KMDF  A bus driver manages a parent device that enumerates one or more child devices. The parent device could be a PCI adapter, a USB hub, or a similar device into which a user can plug various other devices. The parent device could also be a multifunction device that enumerates fixed child devices whose functions require different types of drivers, such as a sound card that has an audio port and a game port. This book refers to all such parent devices as "buses" and to their drivers as bus drivers.

The important distinction between a bus driver and any other type of driver is that the bus driver manages hardware that is not at the end of a devnode. A bus driver is thus responsible for two kinds of tasks:

  • Handling I/O requests that are directed to the bus itself.

  • Enumerating the child devices and reporting their hardware requirements and status.

In the Plug and Play device stack, a bus driver typically creates at least two device objects: an FDO for its role as the function driver for the bus itself and a PDO for each child device that is attached to the bus.

The framework defines methods, events, and properties that are specific to PDOs, just as it does for FDOs. By using the WdfPdoInitXxx and WdfPdoXxx methods, a driver can:

  • Register event callbacks that report the hardware resources that its children require.

  • Register event callbacks that are related to device locking and ejection.

  • Register event callbacks that perform bus-level operations so that its child devices can trigger a wake signal.

  • Assign Plug and Play, compatible, and instance IDs to its child devices.

  • Notify the system of relationships among its child devices so that the PnP manager can coordinate their removal and ejection.

  • Notify the system that a child device has been ejected or unexpectedly removed.

  • Retrieve and update the bus address of a child device.

To indicate that it is a bus driver, a KMDF driver calls one or more of the PDO initialization methods before creating its device object.

Raw Devices

In rare cases, a bus driver might control a raw device. A raw device is driven directly by a bus driver and PDO, without an FDO. A bus driver can indicate that a PDO is "raw capable," which means that the device can start and clients can access it even without a function driver. For example, the SCSI, IDE, and other storage bus drivers create a PDO for each device that they find on the bus, and they mark these PDOs as raw capable. For standard devices such as disks and CD-ROMs, the system loads the function driver and the function driver controls the device. However, if no function driver exists for the device, the system starts the device as a raw device. The storage stack supports "storage pass-through" commands with which a client can directly issue SCSI requests to a raw device. Not all buses support such pass-through commands, but those that do generally mark their PDOs as raw capable.

If the driver indicates that it controls a raw device, the framework assumes that the driver is the power policy manager for the device. The driver can change this setting by calling WdfDeviceInitSetPowerPolicyOwnership, but another driver must manage power for the device.

Enumeration Models

The framework supports both static and dynamic models for enumerating child devices. A driver that performs static enumeration detects and reports child devices during system initialization and has a limited ability to report subsequent configuration changes. If the status of child devices rarely changes, the bus driver should use the static model. Static enumeration is thus appropriate for most multifunction devices.

The dynamic enumeration model supports drivers that can detect and report changes to the number and type of devices that are connected to the bus while the system is running. Bus drivers must use dynamic enumeration if the number or types of devices that are connected to the parent device depend on the system's configuration. Some of these devices might be permanently connected to the system, and some might be plugged in and unplugged while the system is running. The dynamic model supports drivers for devices such as IEEE 1394 controllers, where the status of child devices might change at any time.

The framework handles most of the details of enumeration for bus drivers, including the following:

  • Reporting child devices to the system.

  • Coordinating scans to find child devices.

  • Maintaining a list of child devices.

The sample KbFiltr, Osrusbfx2/EnumSwitches, and Toaster Bus drivers create PDOs and demonstrate static and dynamic enumeration of child devices.

Legacy Device Drivers and Control Device Objects (KMDF)

 KMDF  In addition to Plug and Play function, bus, and filter drivers, the framework supports the development of drivers for legacy devices, which are not controlled by a Plug and Play lifetime model. Such drivers create control device objects, which are not part of the Plug and Play device stack. The I/O manager delivers requests to the control device object without sending them down a device stack.

Plug and Play drivers can also use control device objects to implement control interfaces that operate independently of the device stack. An application can send requests directly to the control device object, thus bypassing any filtering that other drivers in the stack perform.

For example, a filter driver that is installed beneath another filter driver in the device stack can create a control device object to ensure that it receives all of the IOCTLs that are targeted at the underlying device. A driver that operates in a device stack with a port or class driver that does not allow custom IOCTLs might create a control device object so that it can receive such requests.

A control device object typically has a queue and the driver can forward requests from that queue to a Plug and Play device object by using an I/O target.

Because control device objects are not part of the Plug and Play device stack, the driver must notify the framework when their initialization is complete by calling WdfControlFinishInitializing. In addition, the driver itself must delete the device object when the device has been removed because only the driver knows how to control the lifetime of the object.

The NdisProt, NonPnP, and Toaster Filter sample drivers create control device objects.

Tip 

Chapter 24, "Static Driver Verifier," describes how to annotate your driver's callback functions so that SDV can analyze compliance with KMDF rules that require calling WdfControlFinishInitializing for a control device object and specify that a control device object that the driver created is disposed of at the correct point.

WDF Drivers, Driver Types, and Device Object Types

The typical Plug and Play device has one function driver and one bus driver, but can have any number of filter drivers. The function driver is the primary driver for the device. The bus driver enumerates the device and any other devices that are attached to a particular bus or controller. The filter drivers modify one or more I/O request types for the device stack.

 UMDF  A UMDF driver creates a single device object for each device that it controls. It can act as a filter driver or as a function driver for a device. UMDF does not currently support bus drivers.

 KMDF  A KMDF function driver or filter driver typically creates a single device object for each device that it controls. A KMDF bus driver typically is the function driver for its device and the bus driver for the devices that its device enumerates, so it creates an FDO for its device and a PDO for each enumerated device. For example, a USB hub driver acts as the function driver for the hub itself and the bus driver for each USB device that is attached to the hub. Thus, it creates an FDO for the hub and a PDO for each attached USB device. After the bus driver enumerates the PDOs, the PnP manager loads the function driver for each attached USB device, and the function driver then creates an FDO for the device.

Any KMDF driver can also create one or more control device objects, though few drivers use this feature.

 Note  Windows directs requests to specific device objects, not to drivers. Some types of requests apply only to FDOs or filter DOs, whereas others apply only to PDOs. For this reason, certain callbacks apply only to FDOs or filter DOs and others apply only to PDOs.

A driver that creates more than one type of device object-such as a bus driver that creates an FDO and one or more PDOs-typically must implement some FDO-only callbacks and some PDO-only callbacks, particularly for Plug and Play and power management features.

This book refers to those callbacks as FDO specific or PDO specific, just as WDF itself does, rather than as callbacks for function drivers or bus drivers.

Device Properties

Every device object contains information about the properties of the device. The framework sets default values for the properties based on information that it requests from both the system and the bus driver. The driver can change some of these values when it initializes and creates the device object. Table 6-2 lists the device properties that WDF supports.

Table 6-2: Device Properties
Open table as spreadsheet

Property

Description

Supporting framework

Alignment requirement

The device's address alignment requirement for memory transfer operations.

KMDF

Default child list

The default child list that the framework creates for an FDO (FDO only).

KMDF, for FDO only

Default I/O queue

The I/O queue that receives the device's I/O requests unless the driver creates additional I/O queues.

UMDF (through INF) and KMDF

Device characteristics

A set of device characteristics that are stored as flags. A driver can set all of these characteristics as a group or can set some characteristics individually.

UMDF; KMDF

Device instance ID

A string that represents the instance ID for the device.

UMDF; KMDF

Device name

Name of the Down device object (UMDF) or of the device object that the driver creates (KMDF). Clients can use the KMDF device object name to open the device, but clients cannot use the UMDF device name.

UMDF; KMDF

Device state

The operational state of a Plug and Play device.

UMDF; KMDF

Filter

A Boolean value that indicates whether the device object represents a filter driver.

UMDF; KMDF

Default I/O target

The next-lower driver in the device stack to which the driver forwards I/O requests.

UMDF; KMDF

Parent

The FDO of the parent bus for an enumerated child device object (PDO only).

KMDF, for PDO only

Plug and Play capabilities

The Plug and Play features of the device, such as locking, surprise removal, and related capabilities.

UMDF; KMDF

Plug and Play state

The current state of the framework's Plug and Play state machine.

KMDF

Power capabilities

The power management features of the device, including the intermediate power states, the states from which it can trigger a wake signal, and related capabilities.

KMDF

Power policy ownership

A Boolean value that indicates whether the device object owns power policy for the device.

UMDF; KMDF

Power policy state

The current state of the framework's power policy state machine.

KMDF

Power state

The current state of the framework's power management state machine.

KMDF

Synchronization model (also called locking constraint)

The level at which the framework calls certain object callbacks concurrently.

UMDF; KMDF

Neither UMDF nor KMDF exposes all of the properties that the Windows I/O manager stores for a device. However, both UMDF and KMDF drivers can call outside the framework to query for the value of many such properties. A KMDF driver calls the kernel-mode IoGetDeviceProperty function, and a UMDF driver calls SetupDiXxx functions.

Chapter 14, "Beyond the Frameworks," describes how to call outside the frameworks and includes a UMDF example that calls SetupDiXxx functions to query for a device property.

 Tip  See "Using Device Installation Functions" on MSDN for more information about SetupDiXxx functions-online at http://go.microsoft.com/fwlink/?LinkId=82107.

Device Object Initialization

The device object maintains information about the device and supports callbacks for device-related events, such as Plug and Play and power management requests. Both frameworks implement functions that a driver calls to initialize such data for the device object:

  • UMDF provides the methods in the IWDFDeviceInitialize interface. The framework passes a pointer to this interface as a parameter to the IDriverEntry::OnDeviceAdd method.

  • KMDF provides the WdfDeviceInitXxx functions. The EvtDriverDeviceAdd callback receives a pointer to a WDFDEVICE_INIT structure that the WdfDeviceInitXxx functions fill in.

A driver calls the device object initialization functions before it creates the device object, as part of its add-device event callback.

By using these functions, a driver can initialize the Plug and Play capabilities of the device and the concurrency model that is used with the I/O event callbacks for the device object, among other items. Because kernel-mode drivers have greater access to device hardware than user-mode drivers and can support additional features, the device objects of KMDF drivers typically require more initialization than those of UMDF drivers.




Developing Drivers with the Microsoft Windows Driver Foundation
Developing Drivers with the Windows Driver Foundation (Pro Developer)
ISBN: 0735623740
EAN: 2147483647
Year: 2007
Pages: 224

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net