Device objects are fundamental to the Windows Plug and Play (PnP) architecture. They represent physical devices, logical devices, or device functions within the system and are the primary means by which the kernel and drivers interact with hardware.
What is a Device Object?
A device object, represented by the `DEVICE_OBJECT` structure, is a kernel object that encapsulates information about a device. This information includes:
- Pointers to driver routines.
- Device characteristics (e.g., removable media, bus type).
- The device's state.
- Links to related objects, such as device extension and functional device objects (FDOs).
Device Object Hierarchy
Device objects are typically organized in a hierarchy that mirrors the physical and logical structure of the system's hardware. This hierarchy is managed by the PnP manager.
Types of Device Objects:
- Physical Device Object (PDO): Represents a physical device on a bus. For example, a PDO might represent a USB flash drive or a PCI network card.
- Functional Device Object (FDO): Represents a device's functionality. A driver creates an FDO to manage a device's operations. For a single physical device, there might be multiple FDOs stacked on top of each other, each representing a different layer of functionality (e.g., a storage driver, a file system driver).
- Filter Device Object (Filter DO): Used by filter drivers to intercept I/O requests and potentially modify them or perform additional actions before passing them up or down the stack.
- Control Device Object (CDO): Represents a control interface that is not directly tied to a physical device, often used by system components.
These device objects are linked together to form a "device stack," where I/O requests travel down the stack to the PDO and then up the stack for processing.
Note: Understanding the device stack is crucial for debugging and developing drivers, as it dictates the flow of control and data.
Creating and Managing Device Objects
Driver writers are responsible for creating and managing device objects. Key routines include:
IoCreateDevice: Used by a driver to create a device object.IoDeleteDevice: Used by a driver to delete a device object.IoGetDeviceObjectPointer: Used to obtain a pointer to a device object.
// Example of creating a device object
NTSTATUS CreateDevice(
_In PIRP Irp,
_In PDEVICE_OBJECT Pdo
)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS status;
// Create a device object for this device.
status = IoCreateDevice(
DriverObject, // Pointer to driver object created in DriverEntry
sizeof(MY_DEVICE_EXTENSION), // Size of the device extension
NULL, // Device name (NULL for PDOs usually)
FILE_DEVICE_UNKNOWN, // Device characteristics
0, // Exclusive, if the device is exclusive
FALSE, // CreateExclusive, if the device is exclusive
&DeviceObject // Pointer to the created device object
);
if (!NT_SUCCESS(status)) {
return status;
}
// ... initialize device extension and other properties ...
return status;
}
Device Extension
Each device object can have an associated device extension, which is a block of memory allocated by the system. Drivers use the device extension to store private information relevant to the device object, such as device-specific data, state variables, and pointers to other data structures.
Device Object Properties
Device objects have numerous properties that control their behavior and how they are managed by the PnP manager and the operating system. These include flags like:
DO_BUFFERED_IO: Indicates that I/O buffers should be buffered.DO_DIRECT_IO: Indicates that I/O should use direct I/O.DO_POWER_INRUSH: For devices that require power inrush.
Tip: Correctly setting device object flags is essential for efficient and correct I/O handling.
Interaction with the PnP Manager
The PnP manager uses device objects to enumerate hardware, manage device installation, track device states (e.g., present, absent, stopped, started), and arbitrate resource requests. Drivers must handle PnP IRPs (I/O Request Packets) to respond to PnP manager requests, such as surprise removal or device power state changes.
Important: Properly handling PnP IRPs is critical for a stable and reliable driver. Failure to do so can lead to system instability or device malfunction.
In summary, device objects are the core components that enable drivers to interface with hardware in the Windows operating system, forming the backbone of the Plug and Play system.