2012-12-18 107 views
12

我正在尝试使用SetupDi函数来枚举所有连接的USB设备的设备路径。设备路径是CreateFile()中使用的路径,所以我可以与设备进行通信。windows - 如何枚举所有连接的USB设备的设备路径?

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

尝试的解决方案:

我试图提供GUID_DEVCLASS_UNKNOWN = {0x4d36e97e,0xe325,0x11ce,{为0xBF,0xc1,0x08时,0×00,0x2B访问,0xe1,0×03,为0x18}};但是这抛出了“没有更多接口”的错误。

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

问题:

是否有一个通用的接口类,这将覆盖所有的USB设备? (HID,通用等)

或者是否有替代功能,它会给我的设备路径? (由SetupDiGetDeviceInterfaceDetail返回的Instance的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 
} 
+0

我尝试了答案中给出的代码,但是我得到了'请从项目属性页面中选择一个有效的目标机器进行部署。它建立,但我不能运行它。你有没有同样的问题?我在Windows 7上使用VS 2015和WDK 10 – lads

回答

16

MSDN说,有一个名为GUID_DEVINTERFACE_USB_DEVICE与GUID {A5DCBF10-6530-11D2-901F-00C04FB951ED}一个通用的USB设备接口类:

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

Here's a code example似乎正在使用DEVINTERFACE_USB_DEVICE GUID做你想做的事情。

+0

刚刚尝试过,这正是我一直在寻找的!谢谢! – Daniel

+0

对未来读者的注意事项:要小心使用设备**接口**类GUID而不是设备**设置**类,它们不是同一件事。 [有关更多详细信息,请参阅此文章。](https://docs.microsoft.com/en-us/windows-hardware/drivers/install/setup-classes-versus-interface-classes) – jrh