how to get vendor id and product id of a plugged usb device on windows

后端 未结 3 1192
执笔经年
执笔经年 2020-12-09 06:49

I am using Qt on windows platform.

i want to get and display vendor id and product id of a plugged usb device from my local system.

Below is my full source c

相关标签:
3条回答
  • 2020-12-09 07:12

    After this line:

    SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;
    

    Add this:

    DWORD dwDetDataSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
    pDetData = (_SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc (dwDetDataSize);
    pDetData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
    

    After this line:

    qDebug ()<<pDetData->DevicePath;
    

    Add this:

    free(pDetData);
    

    But eventually you're going to have to read the docs for SetupDiGetDeviceInterfaceDetail(). Do it, there are lots of functions that work like this, with pointers to variable-size structs.

    -------- Edited to add: --------

    You're really going about this the wrong way. I see you're following the advice you got here, and it's taken you down the wrong path. idVendor and idProduct can only be found in the USB_DEVICE_DESCRIPTOR (MSDN).

    It looks like you already know how to get the device handle (using CreateFile()). After that, you call WinUsb_Initialize() (MSDN). That gets you a WINUSB_INTERFACE_HANDLE.

    Once you have that handle, you want to call WinUsb_GetDescriptor() (MSDN), with the DescriptorType set to URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE. I can't test code now, but it will look something like this:

    USB_DEVICE_DESCRIPTOR udd;
    memset(&udd, 0, sizeof(udd));
    ULONG LengthTransferred = 0;
    
    WinUsb_GetDescriptor(
        winusb_interface_handle, // returned by WinUsbInitialize
        URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE,
        0,     // not sure if we need this
        0x409, // not sure if we need this
        &udd,
        sizeof(udd),
        &LengthTransferred);
    

    After that, udd->idVendor and udd->idProduct should have what you want.

    Microsoft used to supply sample code for all this in the DDK, and probably still does, but I don't have access to one.

    ---------- Edited to add: ----------

    Daniel K writes that the code should really be:

    USB_DEVICE_DESCRIPTOR udd;
    memset(&udd, 0, sizeof(udd));
    ULONG LengthTransferred = 0;
    
    WinUsb_GetDescriptor(
        winusb_interface_handle,    // returned by WinUsbInitialize
        USB_DEVICE_DESCRIPTOR_TYPE, // Daniel K's suggestion
        0,
        0x409,     // asks for English
        &udd,
        sizeof(udd),
        &LengthTransferred);
    

    See the comments for further details.

    0 讨论(0)
  • 2020-12-09 07:15

    An alternative is to obtain the hardwareID which includes the VID and PID.

    Call SetupDiGetDeviceRegistryProperty with SPDRP_HARDWAREID like so:

    wchar_t *hardwareID;
    
    // First get requiredLength
    SetupDiGetDeviceRegistryProperty(deviceInfoList, &deviceInfoData, SPDRP_HARDWAREID, NULL, NULL, 0, &requiredLength);
    
    hardwareID = (wchar_t*)(new char[requiredLength]());
    
    // Second call to populate hardwareID
    SetupDiGetDeviceRegistryProperty(deviceInfoList, &deviceInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)hardwareID, requiredLength, NULL);
    
    // Display the string
    qDebug() << "hardwareID =" << QString::fromWCharArray(hardwareID);
    

    This will give you a string like USB\ROOT_HUB20&VID1002&PID4396&REV0000 which you can parse.

    *Note: not all devices will have a VID and PID, such as non-USB devices.

    0 讨论(0)
  • 2020-12-09 07:16

    You are enumerating the device "interface". Interfaces do not have a VID or PID - device instances do. I am not sure whether you are enumerating the interfaces to narrow down the devices you are interested in, for because it's an error.

    If you just enumerate the device instances, then you can call SetupDiGetDeviceProperty with DEVPKEY_Device_HardwareIds and then grep the resulting hardware id for the VID and PID.

    If you are using the device interfaces on purpose, then you need to call SetupDiGetDeviceInterfaceDetail once with a NULL PSP_DEVICE_INTERFACE_DETAIL parameter and a valid requiredSize pointer to get the required size of memory to allocate, allocate that memory and then call the function again. In that call, the last parameter is a SP_DEVINFO_DATA structure, which once retrieved, you can use in the call to SetupDiGetDeviceProperty as I mentioned above.

    0 讨论(0)
提交回复
热议问题