Extracting USB PID VID from DevicePath

7.2k views Asked by At

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.

3

There are 3 answers

5
TripShock On

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.

0
David Grayson On

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.

1
user23573 On

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;