title: How to have the drive letter, with the device ID on Windows7
body: <p>I am a beginner in programming, so don't be rude ^^.. </p>
  
  <p>I'm developing a programme which will use to manage mass storage device. On Windows Xp and Windows 7.</p>
  
  <p>I' have already done the XP's manager. And for it, i used this function : <a href="https://stackoverflow.com/questions/1187241/drive-letter-to-device-instance-id">Drive Letter to Device Instance ID</a></p>
  
  <p>I've try to understand what's this function was doing.. But in vain.. As i told you, i m a beginner, and i did'nt found one single tutorial about it.</p>
  
  <p>So, here's my problem : I've used this function for Windows XP as you can see : </p>
  
  <pre><code>int _tmain(int argc, _TCHAR* argv[])
  {
      //char id_voulue[TAILLE_MAX2]= "USBSTOR\DISK&amp;VEN_KINGSTON&amp;PROD_READER__MICSD/M2&amp;REV_0200\AA00000000135539&amp;1";
      WCHAR cDrive;
      LPSTR dev_ID = "USBSTOR\\DISK&amp;VEN_GENERIC-&amp;PROD_COMPACT_FLASH&amp;REV_1.01\\9&amp;19571B1B&amp;0&amp;058F63646476&amp;1"/*USBSTOR\\DISK&amp;VEN_KINGSTON&amp;PROD_READER_____SD/MS&amp;REV_0200\\AA00000000135539&amp;0"*/;
      int code_erreur = 0;
  
      //id_voulue[strlen(id_voulue) - 1] = 0x00;
  
      //dev_ID = id_voulue; 
  
  
      if(!GetAllRemovableDisks())
      {
          code_erreur = -1 ;
      }
  
      cDrive = GetSpecificDrive(dev_ID);
  
      printf("L'ID est : %s \n", dev_ID);
  
      printf("La lettre correspondante est : %c \n", cDrive);
  
  
      puts("\n\n");
      system("pause");
      return 0;
  }
  
  
  //                My functions 
  
  
  struct tagDrives
  {
      WCHAR letter;
      WCHAR volume[BUFFER_SIZE];
  }g_drives[26];
  
  
  BOOL GetAllRemovableDisks()
  {
      WCHAR caDrive[4];
      WCHAR volume[BUFFER_SIZE];
      int nLoopIndex;
      DWORD dwDriveMask;
      UINT g_count;
  
      caDrive[0] = 'A';
      caDrive[1] = ':';
      caDrive[2] = '\\';
      caDrive[3] = 0;
  
      g_count = 0;
  
      // Get all drives in the system.
      dwDriveMask = GetLogicalDrives();
  
      if(dwDriveMask == 0)
      {
          puts("Error - GetLogicalDrives failed\n");
          return FALSE;
      }
  
      // Loop for all drives (MAX_DRIVES = 26)
  
      for(nLoopIndex = 0; nLoopIndex&lt; MAX_DRIVES; nLoopIndex++)
      {
          // if a drive is present,
          if(dwDriveMask &amp; 1)
          {
              caDrive[0] = 'A' + nLoopIndex;
  
              // If a drive is removable
              if(GetDriveType(caDrive) == DRIVE_REMOVABLE)
              {
                  //Get its volume info and store it in the global variable.
                  if(GetVolumeNameForVolumeMountPoint(caDrive, volume, BUFFER_SIZE))
                  {
                      g_drives[g_count].letter = caDrive[0];
                      wcscpy(g_drives[g_count].volume, volume);
                      g_count ++;
                  }
              }
          }
          dwDriveMask &gt;&gt;= 1;
      }
  
      // success if atleast one removable drive is found.
      if(g_count == 0)
      {
          return FALSE;
      }
      else
      {
          return TRUE;
      }
  }
  
  WCHAR GetSpecificDrive(LPSTR lpDevID)
  {
      HDEVINFO hDevInfo;
      GUID guid;
      BYTE buffer[BUFFER_SIZE];
      DWORD dwRequiredSize ;
      WCHAR buf[BUFFER_SIZE];
      DEVINST devInstParent;
      DWORD dwIndex;
      WCHAR volume[BUFFER_SIZE];
      UINT nLength,nLoopIndex,g_count;
      g_count = 26;
      SP_DEVICE_INTERFACE_DATA devInterfaceData;
      SP_DEVINFO_DATA devInfoData;
      PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetail;
  
      if(!lpDevID)
      {
          return 0;
      }
  
      // GUID_DEVINTERFACE_VOLUME is interface Guid for Volume class devices.
      guid = GUID_DEVINTERFACE_VOLUME;
  
  
      // Get device Information handle for Volume interface
      hDevInfo = SetupDiGetClassDevs(&amp;guid, NULL, NULL,
      DIGCF_DEVICEINTERFACE |
      DIGCF_PRESENT);
  
      if(hDevInfo == INVALID_HANDLE_VALUE)
      {
          puts("Error - SetupDiGetClassDevs failed\n");
          return 0;
      }
  
      // Loop until device interfaces are found.
      for(dwIndex = 0; ;dwIndex ++)
      {
          ZeroMemory(&amp;devInterfaceData, sizeof(devInterfaceData));
          devInterfaceData.cbSize = sizeof(devInterfaceData);
  
          // Get device Interface data.
  
          if(!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &amp;guid, dwIndex,&amp;devInterfaceData))
          {
              break;
          }
  
          ZeroMemory(&amp;devInfoData, sizeof(devInfoData));
          devInfoData.cbSize = sizeof(devInfoData);
  
          pDevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer;
          pDevDetail-&gt;cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  
          // Get device interface detail data to get
          // Device Instance from SP_DEVINFO_DATA and
          // Device Path from SP_DEVICE_INTERFACE_DETAIL_DATA
  
          SetupDiGetDeviceInterfaceDetail(hDevInfo,
          &amp;devInterfaceData,
          pDevDetail, // SP_DEVICE_INTERFACE_DETAIL_DATA
          BUFFER_SIZE,
          &amp;dwRequiredSize,
          &amp;devInfoData); // SP_DEVINFO_DATA
  
          // Get the device instance of parent. This points to USBSTOR.
          CM_Get_Parent(&amp;devInstParent,devInfoData.DevInst, 0);
          CM_Get_Device_ID(devInstParent, buf, BUFFER_SIZE,0);
          // Get the device instance of grand parent. This points to USB root.
          CM_Get_Parent(&amp;devInstParent,devInstParent, 0);
          // Get the device ID of the USB root.
          //CM_Get_Device_ID(devInstParent, buf, BUFFER_SIZE,0);
  
          // If USB root device matches with the input device ID, it is the target
          //device.
  
          if( buf != NULL &amp;&amp; compare(lpDevID,buf)==0)
          {
              // Append \ to the DevicePath of SP_DEVICE_INTERFACE_DETAIL_DATA
              if(lpDevID[50] == buf[50] &amp;&amp; lpDevID[55] == buf[55] &amp;&amp; lpDevID[60] == buf[60])
              {
                  nLength = wcslen(pDevDetail-&gt;DevicePath);
                  pDevDetail-&gt;DevicePath[nLength] = '\\';
                  pDevDetail-&gt;DevicePath[nLength] = '\\';
                  pDevDetail-&gt;DevicePath[nLength+1] = 0;
  
                  // Get Volume mount point for the device path.
                  if(GetVolumeNameForVolumeMountPoint(pDevDetail-&gt;DevicePath, volume, BUFFER_SIZE))
                  {
                      for(nLoopIndex=0; nLoopIndex&lt; g_count; nLoopIndex++)
                      {
                          // Compare volume mount point with the one stored earlier.
                          // If both match, return the corresponding drive letter.
  
                          if(wcscmp(g_drives[nLoopIndex].volume, volume)==0)
                          {
                              SetupDiDestroyDeviceInfoList(hDevInfo);
                              return g_drives[nLoopIndex].letter;
                          }
  
                      }
                  }
              }
          }
      }
  
      SetupDiDestroyDeviceInfoList(hDevInfo);
      puts("Error - No drives found in GetSpecificDrives\n");
      return 0;
  }
  
  UINT compare(LPSTR lpDevID,WCHAR* buf)
  {
      UINT nombre_caractere1, 
           confirmation = 0, 
           i = 0;
      nombre_caractere1 = strlen(lpDevID);
  
          for(i=1 ; i &lt;= nombre_caractere1 ; i++)
          {
              if(lpDevID[i]==buf[i])
              {
                  confirmation += 1;
              }
  
          }
  
          if(confirmation == nombre_caractere1)
          {
              return 0;
          }
          else
          {
              return -1;
          }
  }
  </code></pre>
  
  <p>So this code work fine on XP, but no on Windows Seven.. It seems like if we don't start at the right place in the register base. During my comparaison, I can see that my variable "buf" is "HTREE\ROOT\0", at the second loop, "buf" = "ACPI\PNP0A08\0", and until the end, i see again "buf" = "HTREE\ROOT\0"..</p>
  
  <p>Can someone explain to me what's going on ? I've really tried to understand. I've been a lot on msdn, but maybe i m stupid, because i don't got it.</p>