Get parent device

I have two USB device IDs for example. USB\VID_E4F1&PID_0661\00000115FA9CE7750000000000000000


How can I verify that device # 2 is a direct descendant of device # 1 (physically they are part of the same USB-composite device)?

In real life scenarios, many of them will be connected to a single USB controller. Moreover, it is possible that they will be of the same manufacturer and model. So I cannot check VID, PID and use Win32_USBControllerDevice

WMI query to check that they are connected to the same USB controller. I need to somehow check for the parent-child relationship, not just the fact that they are connected to the same controller.

If it matters, I only need to support Windows 8+.


source to share

3 answers

The PnP Configuration Manager API is your friend here:



If you can use the new WinRT API, you should take a look at the class PnpObject

and namespace.

Here's some sample code:

var propertiesToQuery = new List<string>() { 

var id1 = @"USB\VID_E4F1&PID_0661\00000115FA9CE7750000000000000000";

var device1 = await PnpObject.FindAllAsync(PnpObjectType.Device, 
                                            "System.Devices.DeviceInstanceId:=\"" + id1 + "\"");

var id2 = @"USB\VID_E4F1&PID_0661&MI_00\7&B5A5DDF&0&0000";

var device2 = await PnpObject.FindAllAsync(PnpObjectType.Device, 
                                            "System.Devices.DeviceInstanceId:=\"" + id2 + "\"");

var parent1 = device1.Properties["System.Devices.Parent"] as string;
var parent2 = device2.Properties["System.Devices.Parent"] as string;

if (parent1 && parent1 == id2)
    WriteLine("Device 2 is parent of device 1");

if (parent2 && parent2 == id1)
    WriteLine("Device 11 is parent of device 2");

var child_ids = device1.Properties["System.Devices.Children"] as string[];

if (child_ids != null){
    foreach (var id in child_ids)
        if (id == id2){
            WriteLine("Device 2 is child of device 1")

 child_ids = device2.Properties["System.Devices.Children"] as string[];

if (child_ids != null){
    foreach (var id in child_ids)
        if (id == id1){
            WriteLine("Device 1 is child of device 2")


If that's not enough, you can try going up or down the parent / child path.

You can also look at the property System.Devices.LocationPaths

(which is an array of strings) and check if it is a prefix of another.



Continuing on Harry Johnston's excellent answer:

Once called, CM_Locate_DevNode

you can get the ID of the parent device instance with a single function call:

#include <propkey.h>

// Get the Parent Device Property
wchar_t propBuf[MAX_DEVICE_ID_LEN] = {};
ULONG propBufSize = sizeof(propBuf);
CONFIGRET cres = CM_Get_DevNode_Property(devInst, (DEVPROPKEY*)&PKEY_Devices_Parent, &propType, (BYTE*)propBuf, &propBufSize, 0);
if (cres == CR_SUCCESS) {
    // propBuf now contains the Parent System Device ID!




All Articles