This documentation provides a comprehensive overview of the Plug and Play (PnP) subsystem in Windows, focusing on the development and behavior of PnP drivers. Understanding PnP is crucial for creating device drivers that integrate seamlessly with the Windows operating system, allowing for dynamic detection, configuration, and management of hardware devices.
Plug and Play (PnP) is a standardized interface that enables hardware devices to be automatically detected and configured by the operating system when they are connected. This eliminates the need for manual installation and resource allocation in most cases. PnP drivers are the software components responsible for interacting with the PnP manager to facilitate this process.
Key benefits of PnP include:
Several fundamental concepts underpin the PnP mechanism in Windows:
The process by which the PnP manager discovers and identifies devices attached to the system. This is typically handled by bus drivers.
Each PnP device has a unique identifier (e.g., Hardware ID, Compatible ID) that the PnP manager uses to find the appropriate driver.
Assigning hardware resources (like I/O port addresses, interrupts, DMA channels) and loading the correct driver for a device.
The PnP manager arbitrates resource requests from multiple devices to ensure no conflicts occur.
The PnP manager controls the lifecycle of a device, initiating its start-up sequence and gracefully shutting it down when necessary.
The PnP architecture involves several key components working together:
The central component responsible for managing the PnP process. It communicates with bus drivers and device drivers to enumerate, identify, and configure devices.
Drivers that manage specific hardware buses (e.g., PCI, USB, I2C). They are responsible for enumerating devices present on their bus.
Optional drivers that sit above or below function drivers in the device stack. They can intercept and modify I/O requests for various purposes, such as logging, security, or adding functionality.
Drivers that provide the primary functionality for a device. They interact directly with the hardware and expose an interface to the operating system and applications.
PnP drivers are structured using a layered model:
Represents a physical device. Bus drivers create PDOs for devices they detect on their bus.
Represents the functional aspect of a device. A function driver creates an FDO for its device.
An FDO is typically attached to a PDO, forming a device stack.
A stack of device objects, starting with the PDO at the bottom and potentially including filter driver objects and the FDO at the top. I/O requests travel up and down this stack.
Effective management of hardware resources is a cornerstone of PnP. Drivers communicate their needs and receive assigned resources through the PnP manager.
These include memory-mapped I/O ranges, I/O port addresses, interrupts, and DMA channels.
Data structures used to describe the type and range of a hardware resource.
Drivers typically request resources by handling the IRP_MN_QUERY_RESOURCE_REQUIREMENTS and IRP_MN_FILTER_RESOURCE_REQUIREMENTS IRPs.
Example of requesting resources:
NTSTATUS DriverDispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
PIO_STACK_LOCATION irpStack;
irpStack = IoGetCurrentIrpStackLocation(Irp);
switch (irpStack->MinorFunction) {
// ... other PnP minor functions ...
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
// Handle request for device resources
// This typically involves querying child devices or the bus driver
break;
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
// Filter or modify resource requirements
break;
case IRP_MN_ASSIGN_RESOURCES:
// Resources have been assigned by the PnP manager
// Driver should claim and configure hardware based on these resources
break;
// ...
}
// ... default handling ...
}
The PnP manager organizes all devices in a hierarchical tree structure, reflecting the bus topology of the system. Each node in the tree represents a device and has a parent-child relationship based on the bus connections.
PnP drivers communicate with the PnP manager and other drivers using I/O Request Packets (IRPs). The most common PnP IRPs include:
IRP_MN_START_DEVICE: Initiates the device startup process.IRP_MN_STOP_DEVICE: Shuts down the device gracefully.IRP_MN_QUERY_REMOVE_DEVICE: Checks if the device can be removed.IRP_MN_REMOVE_DEVICE: Removes the device from the system.IRP_MN_QUERY_CAPABILITIES: Retrieves device capabilities.IRP_MN_RESOURCES_CHANGED: Notifies the driver that resources have changed.Properly handling these IRPs is essential for a stable and responsive PnP driver.