2012-12-18 69 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