windows - 如何枚举所有连接的 USB 设备的设备路径?

Posted

技术标签:

【中文标题】windows - 如何枚举所有连接的 USB 设备的设备路径?【英文标题】:windows - How to enumerate all connected USB devices' device path? 【发布时间】:2012-12-05 08:02:10 【问题描述】:

我正在尝试使用 SetupDi 函数枚举所有连接的 USB 设备的设备路径。设备路径是 CreateFile() 中使用的路径,因此我可以与设备通信。

但是,SetupDiGetDeviceInterface 需要接口 GUID,但我并不是专门寻找特定接口(所有连接的 USB 除外)。这部分已被注释为 /* ??? */ 在下面的源代码中。

尝试的解决方案:

我尝试提供 GUID_DEVCLASS_UNKNOWN = 0x4d36e97e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18;但这引发了“不再有接口”错误。

我也尝试将 deviceInfoData.ClassGuid 提供给 SetupDiGetDeviceInterface,但我得到与上面相同的错误,“没有更多接口”。

问题:

是否有涵盖所有 USB 设备的通用接口类? (HID、通用等)

或者是否有其他功能可以为我提供设备路径? (由 SetupDiGetDeviceInterfaceDetail 返回的 SP_DEVICE_INTERFACE_DETAIL_DATA 结构的插入)。

来源:

HDEVINFO deviceInfoList
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
DWORD requiredLength = 0;
char *hardwareID = 0;

// Retrieve a list of all present devices
deviceInfoList = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES);

if (deviceInfoList == INVALID_HANDLE_VALUE) 
    SetupDiDestroyDeviceInfoList(deviceInfoList);
    return false;


// Iterate over the list
for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoList, i, &deviceInfoData); i++) 
    if (deviceInterfaceDetailData) LocalFree(deviceInterfaceDetailData);

    requiredLength = 0;

    SetupDiGetDeviceRegistryProperty(deviceInfoList, &deviceInfoData, SPDRP_HARDWAREID, &DataT, NULL, 0, &requiredLength);

    if (requiredLength <= 0) 
        SetupDiDestroyDeviceInfoList(deviceInfoList);
        return false;
    

    hardwareID = new char[requiredLength]();

    SetupDiGetDeviceRegistryProperty(deviceInfoList, &deviceInfoData, SPDRP_HARDWAREID, &DataT, (PBYTE)hardwareID, requiredLength, NULL);

    // Parse hardwareID for vendor ID and product ID

    delete hardwareID;
    hardwareID = 0;

    deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);

    // Requires an interface GUID, for which I have none to specify
    if (!SetupDiEnumDeviceInterfaces(deviceInfoList, &deviceInfoData, /* ??? */, 0, &deviceInterfaceData)) 
        SetupDiDestroyDeviceInfoList(deviceInfoList);
        return false;
    

    if (!SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInterfaceData, NULL, 0, &requiredLength, NULL)) 
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && requiredLength > 0) 
            deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);

            if (!deviceInterfaceDetailData) 
                SetupDiDestroyDeviceInfoList(deviceInfoList);
                return false;
            
         else 
            SetupDiDestroyDeviceInfoList(deviceInfoList);
            return false;
        
    

    deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    if (!SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInterfaceData, deviceInterfaceDetailData, requiredLength, NULL, &deviceInfoData)) 
        SetupDiDestroyDeviceInfoList(deviceInfoList);
        return false;
    

    SetupDiDestroyDeviceInfoList(deviceInfoList);

    // deviceInterfaceDetailData->DevicePath yields the device path

【问题讨论】:

我尝试了答案中给出的代码,但得到了Please select a valid target machine for deployment from the project property page。它构建但我无法运行它。你有同样的问题吗?我在 Windows 7 上使用 VS 2015 和 WDK 10 【参考方案1】:

MSDN 表示有一个通用 USB 设备接口类,名为 GUID_DEVINTERFACE_USB_DEVICE,GUID 为 A5DCBF10-6530-11D2-901F-00C04FB951ED

系统提供的 USB 集线器驱动程序注册 GUID_DEVINTERFACE_USB_DEVICE 实例,以通知系统和应用程序存在连接到 USB 集线器的 USB 设备。

Here's a code example 似乎可以使用 DEVINTERFACE_USB_DEVICE GUID 执行您想做的事情。

【讨论】:

刚刚试了一下,这正是我想要的!谢谢! 未来读者注意事项:要非常小心,您使用的是设备 interface 类 GUID 而不是设备 setup 类,它们不是一样。 See this article for more details. 该 GUID 在 usbiodef.h 中定义。不要忘记事先#include &lt;initguid.h&gt; 以避免链接器错误 这段代码给了我对 `__imp_SetupDiGetClassDevsA' 的未定义引用和其他未定义引用的错误。查找之后,似乎我需要使用我的链接器来链接一些库,我这样做了,它说它找不到这些库。我做错了什么?我使用 Code::Blocks

以上是关于windows - 如何枚举所有连接的 USB 设备的设备路径?的主要内容,如果未能解决你的问题,请参考以下文章

Windows 10 - 清除 USB 枚举/驱动程序垃圾

苹果笔记本无法识别usb设备

usb 枚举流程

我怎么将我的E2手机连接模式设为 USB net

获取连接的 USB 设备列表

USB枚举过程