4

When using SetupDiGetDeviceInterfaceDetail to retrieve a SP_DEVICE_INTERFACE_DETAIL_DATA relating to a connected USB device, a string called DevicePath is returned.

The string being returned is formatted like the following example:

\?\usb#vid_abcd&pid_1234#000000000#{xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

Question : Is the formatting/syntax of this string documented anywhere and / or known to be dependable across all versions of Windows XP/Vista/7/8?

I am experimenting with code to extract the VID and PID values from this string in order to identify the device being referred to, and would like to know if this is a robust way to retrieve the VID and PID values.

Preston
  • 2,543
  • 1
  • 17
  • 26
user3099783
  • 51
  • 1
  • 2
  • I've been using this format for years. I'm not sure where this is documented, but I can say that it has been reliable for me in production code. I've added some tags to get more visibility from developers that might know. – Preston Dec 14 '13 at 19:32
  • What API are you using to access your USB device, such as WinUSB or libusb? These have APIs you can use to target devices by their IDs, or get descriptors to look at the values that come up from the device itself. – Preston Dec 14 '13 at 20:07
  • Thanks for the response. I use functions of setupapi.dll such as SetupDiEnumDeviceInterfaces to retrieve the path of the USB device. I then use CreateFile, WriteFile, ReadFile, and so on to communicate with that device. – user3099783 Dec 15 '13 at 14:14

3 Answers3

3

While you may find it easy to just parse the device path to get this information, technically it is illegal because device paths in Windows are supposed to be opaque.

Take a look at the usbview sample to see the right way to do this.

TripShock
  • 4,081
  • 5
  • 30
  • 39
  • That usbview link is to a private microsoft page. Is there any public information available? – user23573 Sep 04 '15 at 10:03
  • @BogdanWilli I've updated the link to point to the new Github page instead. – TripShock Sep 04 '15 at 13:33
  • thanks a lot!. I've found also [Uwe Sieber's page](http://www.uwe-sieber.de/usbtreeview_e.html). He's perhaps the original author. – user23573 Sep 05 '15 at 08:52
  • @TripShock Can you please link to an official document where it says device paths within Windows are supposed to be opaque? As pointed out by *user23573*'s answer below, usbview is parsing the device path too. – Code Doggo May 20 '20 at 18:34
  • @CodeDoggo https://learn.microsoft.com/en-us/windows-hardware/drivers/install/device-identification-strings "Device identification strings should not be parsed. They are meant only for string comparisons and should be treated as opaque strings." – Jamie Aug 17 '21 at 19:29
2

That particular string is not documented, so a safer choice would be to use the Hardware IDs of the USB device. These are documented by Microsoft in a page entitled Standard USB Identifiers, which says:

When a new USB device is plugged in, the system-supplied USB hub driver composes the following device ID by using information extracted from the device's device descriptor:

USB\VID_v(4)&PID_d(4)&REV_r(4)

Where:

  • v(4) is the 4-digit vendor code that the USB committee assigns to the vendor.
  • d(4) is the 4-digit product code that the vendor assigns to the device.
  • r(4) is the revision code.

For more context, see the MSDN page entitled Device Identification Strings.

David Grayson
  • 84,103
  • 24
  • 152
  • 189
2

Unlike TripShock I believe that you can parse device paths and is perfectly legal to do so.

  1. Microsoft has published documentation about the device paths as David Grayson points out in his answer.

  2. Code published by microsoft does it exactly this way. (usbview)

Probably there is no single "official" way of how to do this. IMHO the robustness of this method across Windows 7, 8, 8.1 and 10 should be ok, but I would not bet for all eternity.

One of the most valuable sources for USB stuff is the usbview example which is now published by Microsoft. This is probably the "most official" it will ever get, given that Microsoft publishes this code.

Uwe Sieber seems to be the original author of usbview. In file enum.c starting at line 470, the VID, PID, SUBSYS and RevID values are extracted like this:

    ULONG   ven, dev, subsys, rev;
    ven = dev = subsys = rev = 0;

    if (sscanf_s(DevProps->DeviceId,
               "PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x",
               &ven, &dev, &subsys, &rev) != 4)
    {
        OOPS();
    }

    hcInfo->VendorID = ven;
    hcInfo->DeviceID = dev;
    hcInfo->SubSysID = subsys;
    hcInfo->Revision = rev;
    hcInfo->UsbDeviceProperties = DevProps;
Community
  • 1
  • 1
user23573
  • 2,479
  • 1
  • 17
  • 36