I have a USB device that enumerates with a different interface, VID, PID and serial number when commanded to do so, and I'd like to keep track of the physical device after this change occurs. My thought was to track it by its hub and port location.
The Win32_PnPSignedDriver class has a "Location" field that seemed perfect (e.g. Port_#0001.Hub_#0010
), but it only contains the location of the device when the driver was first loaded. Plugging the hardware into a different port does not update that field.
However, the information is available somewhere because there is a "Location information" field under the "Details" tab when viewing the device via the Device Manager. Can this information be retrieve through WMI queries or some other method? Is there a better approach to solving this problem?
EDIT: I know this sounds like a strange scenario. The microcontroller in these devices contains a ROM that enumerates as a CDC device (i.e. serial port) and allows programming. During manufacturing, it would be beneficial to track a device as it changes between the manufacturer's ROM (unique VID/PID/serial number) and my custom firmware interface (different VID/PID/serial number).
A better Idea will be to use the Unique serial number of the USB device.
The "Location information" under device manager is the exact same string you've gotten through WMI.
Have you considered that when the device is plugged into a different port, instead of updating the metadata with the new location, Windows creates a new driver instance and new metadata. Try filtering the
Win32_PnPDevice
object instances for just those that are currently plugged in, and I think you'll find the current location information.For example, if I move my USB mouse to a different port, there's a copy of the mouse associated with the old port still listed under Device Manager, it's just hidden by default. See http://oreilly.com/pub/h/3105 for instructions to view these disconnected devices. Or run the following from an elevated administrator command prompt:
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 ths 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 it's code:
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:
Did you try SetupDi? You can use the SetupDi class of API function to get the information from DeviceManager.
As best as I can tell, correlating a USB device with a physical port is not possible in Windows. Please feel free to prove me wrong.