title: windows - How to enumerate all connected USB devices' device path?
body: <p>I'm trying to use the SetupDi functions to enumerate all connected USB devices' device path. The device path is the path used in CreateFile() so I can communicate with the device.</p>
  
  <p>However, <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff551015%28v=vs.85%29.aspx" rel="noreferrer">SetupDiGetDeviceInterface</a> requires an interface GUID but I'm not specifically looking for a particular interface (other than all connected USBs). This part has been commented as /* ??? */ in the source below.</p>
  
  <p><strong>Attempted Solutions:</strong></p>
  
  <p>I've tried to supply GUID_DEVCLASS_UNKNOWN = {0x4d36e97e, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}; but this threw a "no more interfaces" error.</p>
  
  <p>I've also tried to supply deviceInfoData.ClassGuid into SetupDiGetDeviceInterface but I get the same error as above, "no more interfaces".</p>
  
  <p><strong>Questions:</strong></p>
  
  <p>Is there a general interface class which will cover all USB devices? (HID, generic, etc.)</p>
  
  <p>Or is there an alternate function which will give me the path to the device? (Instread of the SP_DEVICE_INTERFACE_DETAIL_DATA structure returned by SetupDiGetDeviceInterfaceDetail).</p>
  
  <p><strong>Source:</strong></p>
  
  <pre><code>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, &amp;deviceInfoData); i++) {
      if (deviceInterfaceDetailData) LocalFree(deviceInterfaceDetailData);
  
      requiredLength = 0;
  
      SetupDiGetDeviceRegistryProperty(deviceInfoList, &amp;deviceInfoData, SPDRP_HARDWAREID, &amp;DataT, NULL, 0, &amp;requiredLength);
  
      if (requiredLength &lt;= 0) {
          SetupDiDestroyDeviceInfoList(deviceInfoList);
          return false;
      }
  
      hardwareID = new char[requiredLength]();
  
      SetupDiGetDeviceRegistryProperty(deviceInfoList, &amp;deviceInfoData, SPDRP_HARDWAREID, &amp;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, &amp;deviceInfoData, /* ??? */, 0, &amp;deviceInterfaceData)) {
          SetupDiDestroyDeviceInfoList(deviceInfoList);
          return false;
      }
  
      if (!SetupDiGetDeviceInterfaceDetail(deviceInfoList, &amp;deviceInterfaceData, NULL, 0, &amp;requiredLength, NULL)) {
          if (GetLastError() == ERROR_INSUFFICIENT_BUFFER &amp;&amp; requiredLength &gt; 0) {
              deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);
  
              if (!deviceInterfaceDetailData) {
                  SetupDiDestroyDeviceInfoList(deviceInfoList);
                  return false;
              }
          } else {
              SetupDiDestroyDeviceInfoList(deviceInfoList);
              return false;
          }
      }
  
      deviceInterfaceDetailData-&gt;cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  
      if (!SetupDiGetDeviceInterfaceDetail(deviceInfoList, &amp;deviceInterfaceData, deviceInterfaceDetailData, requiredLength, NULL, &amp;deviceInfoData)) {
          SetupDiDestroyDeviceInfoList(deviceInfoList);
          return false;
      }
  
      SetupDiDestroyDeviceInfoList(deviceInfoList);
  
      // deviceInterfaceDetailData-&gt;DevicePath yields the device path
  }
  </code></pre>