I know it's been awhile since any activity on this answer, but I am working on a project that requires a similar functionality to this as well, and I can tell you it is indeed possible. As far as I can tell, it does require the DDK and PInvoke
, there's no C# or WMI interface for this information. It requires opening the low-level USB root hub devices and directly sending driver IOCTL commands to them.
The good news is, Microsoft provides an example C++ application that completely enumerates all USB devices and shows exactly which ports they are connected to. That application is the USBView sample application.
I think you will find if you compile and run this application, you'll see that it shows you exactly where your device is plugged in, and if you plug any device into that port, it shows up in the same place. Perhaps it might be easier if you create an unmanaged C++ DLL that provides a few calls your C# application can use to get the information it needs.
It has this to say about the EnumerateHubPorts()
function in its code:
Given an handle to an open hub and the number of downstream ports on
the hub, send the hub an IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX
request for each downstream port of the hub to get info about the
device (if any) attached to each port.
To give an idea about everything this requires (everything must be enumerated starting at the top, even if you're only interested in one port), here are the comments listed at the top of the enum.c
file in the code:
/*
This source file contains the routines which enumerate the USB bus
and populate the TreeView control.
The enumeration process goes like this:
(1) Enumerate Host Controllers and Root Hubs
EnumerateHostControllers()
EnumerateHostController()
Host controllers currently have symbolic link names of the form HCDx,
where x starts at 0. Use CreateFile() to open each host controller
symbolic link. Create a node in the TreeView to represent each host
controller.
GetRootHubName()
After a host controller has been opened, send the host controller an
IOCTL_USB_GET_ROOT_HUB_NAME request to get the symbolic link name of
the root hub that is part of the host controller.
(2) Enumerate Hubs (Root Hubs and External Hubs)
EnumerateHub()
Given the name of a hub, use CreateFile() to map the hub. Send the
hub an IOCTL_USB_GET_NODE_INFORMATION request to get info about the
hub, such as the number of downstream ports. Create a node in the
TreeView to represent each hub.
(3) Enumerate Downstream Ports
EnumerateHubPorts()
Given an handle to an open hub and the number of downstream ports on
the hub, send the hub an IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX
request for each downstream port of the hub to get info about the
device (if any) attached to each port. If there is a device attached
to a port, send the hub an IOCTL_USB_GET_NODE_CONNECTION_NAME request
to get the symbolic link name of the hub attached to the downstream
port. If there is a hub attached to the downstream port, recurse to
step (2).
GetAllStringDescriptors()
GetConfigDescriptor()
Create a node in the TreeView to represent each hub port
and attached device.
*/
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB
. I'll write up an answer once I verify it. – WolfenbargerSetupDiGetDeviceRegistryProperty
– Pattypatulous