The PnP Manager sends this request to determine certain relationships among devices. The following types of drivers handle this request:
The PnP Manager sends this IRP to gather information about devices with a relationship to the specified device.
The PnP Manager queries a device's BusRelations (child devices) when the device is enumerated and at other times while the device is active, such as when a driver calls IoInvalidateDeviceRelations to indicate that a child device has arrived or departed.
The PnP Manager queries a device's RemovalRelations before it removes a device's drivers or ejects the device and it queries for EjectionRelations before it ejects a device.
The PnP Manager queries a device's TargetDeviceRelation when a driver or user-mode application registers for PnP notification of an EventCategoryTargetDeviceChange on the device. The PnP Manager queries for the device that is associated with a particular file object. This is the only PnP IRP that has a valid file object parameter. A driver can query a device stack for TargetDeviceRelation.
For BusRelations, RemovalRelations, and EjectionRelations requests, the PnP Manager sends the IRP at IRQL = PASSIVE_LEVEL in the context of a system thread.
For TargetDeviceRelation requests, the PnP Manager sends the IRP at IRQL = PASSIVE_LEVEL in an arbitrary thread context.
The Parameters.QueryDeviceRelations.Type member of the IO_STACK_LOCATION structure specifies the type of relations being queried. Possible values include BusRelations, EjectionRelations, RemovalRelations, and TargetDeviceRelation. PowerRelations is not used.
Irp->FileObject points to a valid file object only if Parameters.QueryDeviceRelations.Type is TargetDeviceRelation.
Returned in the I/O status block.
A driver sets Irp->IoStatus.Status to STATUS_SUCCESS or to a failure status such as STATUS_INSUFFICIENT_RESOURCES.
On success, a driver sets Irp->IoStatus.Information to a PDEVICE_RELATIONS pointer that points to the requested relations information. The DEVICE_RELATIONS structure is defined as follows:
typedef struct _DEVICE_RELATIONS {
ULONG Count;
PDEVICE_OBJECT Objects[1]; // variable length
} DEVICE_RELATIONS, *PDEVICE_RELATIONS;
If a driver returns relations in response to this IRP, it allocates a DEVICE_RELATIONS structure from paged memory containing a count and the appropriate number of device object pointers. The PnP Manager frees the structure when it is no longer needed. If a driver replaces a DEVICE_RELATIONS structure allocated by another driver, it must free the previous structure.
A driver must reference the PDO of any device that it reports in this IRP (ObReferenceObject). The PnP Manager removes the reference when appropriate.
A function or filter driver should be prepared to handle this IRP for a device any time after its AddDevice routine has completed for the device. Bus drivers should be prepared to handle a query for BusRelations immediately after a device is enumerated.
See Plug and Play for the general rules for handling Plug and Play Minor IRPs.
The following subsections describe the specific actions for handling the various queries.
When the PnP Manager queries for the bus relations (child devices) of an adapter or controller, the bus driver must return a list of pointers to the PDOs of any devices physically present on the bus. The bus driver reports all devices, regardless of whether they have been started. The bus driver might need to power up its bus device to determine which children are present.
The bus driver that responds to this IRP is the function driver for the bus adapter or controller, not the parent bus driver for the bus that the adapter or controller is connected to. Function drivers for non-bus devices do not handle this query. Such drivers just pass the IRP to the next lower driver. (See the following figure.) Filter drivers typically do not handle this query.

Drivers Handling a Query For Bus Relations
In the example shown in the figure, the PnP Manager sends an IRP_MN_QUERY_DEVICE_RELATIONS for BusRelations to the drivers for the USB hub device. The PnP Manager is requesting a list of the hub device's children.
The USB hub bus driver:
For each child device, the bus driver references the PDO and puts a pointer to the PDO in the DEVICE_RELATIONS structure.
There are two PDOs in this example, one for the joystick device and one for the keyboard device.
The bus driver should check whether another driver already created a DEVICE_RELATIONS structure for this IRP. If so, the bus driver must add to the existing information.
If there is no child device present on the bus, the driver sets the count to zero in the DEVICE_RELATIONS structure and returns success.
If there are one or more bus filter drivers in the device stack, such drivers might handle the IRP on its way down to the bus driver and/or on the IRP's way back up the device stack (if there are IoCompletion routines). According to the PnP IRP rules, such a driver can add PDOs to the IRP on its way down the stack and/or modify the relations list on the IRP's way back up the stack (in IoCompletion routines).
A driver returns pointers to PDOs of any devices that might be physically removed from the system when the specified device is ejected. Do not report the PDOs of children of the device; the PnP Manager always requests that child devices be removed before their parent device.
The PnP Manager sends an IRP_MN_EJECT IRP to a device being ejected. The driver for such a device also receive a remove IRP. The device's ejection relations receive an IRP_MN_REMOVE_DEVICE IRP (not an IRP_MN_EJECT IRP).
Only a parent bus driver can respond to an EjectionRelations query for one of its child devices. Function and filter drivers must pass it to the next lower driver in the device stack. If a bus driver receives this IRP as the function driver for its adapter or controller, the bus driver is performing the tasks of a function driver and must pass the IRP to the next lower driver.
Reserved.
A driver returns pointers to PDOs of any devices whose drivers must be removed when the drivers for the specified device are removed. Do not report the PDOs of children of the device; the PnP Manager already requests removal of child devices before removing a device.
The order in which removal relations are removed is undefined. Removal relations at the same level in the device tree can be removed in any order.
Any driver in the device stack can handle this type of relations query. A function or filter driver handles the IRP before passing it to the next lower driver. A bus driver handles the IRP and then completes it.
A parent bus driver must handle this type of relations query for its child devices. The bus driver references the child device's PDO with ObReferenceObject and returns a pointer to the PDO in the DEVICE_RELATIONS structure. There is only one PDO pointer in the structure for this relation type. The PnP Manager removes the reference to the PDO when the driver or application unregisters for notification on the device.
Only a parent bus driver responds to a TargetDeviceRelation query. Function and filter drivers must pass it to the next lower driver in the device stack. If a bus driver receives this IRP as the function driver for its adapter or controller, the bus driver is performing the tasks of a function driver and must pass the IRP to the next lower driver.
If a driver is not in a PDO-based stack, the driver sends a new target-device-relation query IRP to the device object associated with the file handle on which the driver performs I/O.
Drivers must not send this IRP to request BusRelations. Drivers are not restricted from sending this IRP for RemovalRelations or EjectionRelations, but it is not likely that a driver would do so.
Drivers can query a device stack for TargetDeviceRelation. See Handling IRPs for information on sending IRPs. The following steps apply specifically to this IRP:
If a driver sent this IRP to get the PDO to report in response to an IRP_MN_QUERY_DEVICE_RELATIONS for TargetDeviceRelation that the driver received, then the driver reports the PDO and frees the returned relations structure when the IRP completes. If a driver initiated this IRP for another reason, the driver frees the relations structure when the IRP completes and dereferences the PDO when it is no longer needed.
IoInvalidateDeviceRelations, IRP_MN_EJECT, IRP_MN_REMOVE_DEVICE, IoRegisterPlugPlayNotification, ObReferenceObject