Author Topic: Finding drive letter assigned by Windows to a USB MSD Device from VID/PID  (Read 20658 times)

egovind

  • Member
  • ***
  • Posts: 14
I've been looking for a way to find the drive letter assigned by windows to my device which implements a USB MSD + HID composite class. The most promising solution I've come across was http://stackoverflow.com/questions/17371578/find-usb-drive-letter-from-vid-pid-needed-for-xp-and-higher on stackoverflow. But that does not quite work for me. (The PNPDeviceID returned by the Query on Win32_DiskDrive and that returned by the "Device" class are different.)

Finally, I settled on an indirect way by finding the Drive letter from a "Model" query on Win32_DiskDrive which happens to be the string in the "Product ID" field from the InquiryResponse of the MSD. Like this:

Code: [Select]
            foreach (ManagementObject drive in new ManagementObjectSearcher("SELECT DeviceID FROM Win32_DiskDrive WHERE Model LIKE" + "\"%" + model + "%\"").Get())
            {
                // associate physical disks with partitions
                ManagementObject partition = new ManagementObjectSearcher(System.String.Format("associators of {{Win32_DiskDrive.DeviceID='{0}'}} where AssocClass = Win32_DiskDriveToDiskPartition", drive["DeviceID"])).First();

                if (partition != null)
                {
                    // associate partitions with logical disks (drive letter volumes)
                    ManagementObject logical = new ManagementObjectSearcher(System.String.Format("associators of {{Win32_DiskPartition.DeviceID='{0}'}} where AssocClass = Win32_LogicalDiskToPartition", partition["DeviceID"])).First();

                    if (logical != null)
                    {
                        // finally find the logical disk entry to determine the volume name
                        ManagementObject volume = new ManagementObjectSearcher(System.String.Format("select Name from Win32_LogicalDisk where Name='{0}'", logical["Name"])).First(); // FreeSpace, Size,
                        foreach (PropertyData usb in volume.Properties)
                        {
                            if (usb.Value != null && usb.Value.ToString() != "")
                            {
                                Debug.Write("WMI Search Successful! The Drive Letter is: ");
                                Debug.Write(usb.Value + "\r\n");
                                drive_path = usb.Value.ToString();
                            }
                        }
                    }
                }


Was wondering if any one here knows of a more direct way of getting the drive letter from the VID/PID ?

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Finding drive letter assigned by Windows to a USB MSD Device from VID/PID
« Reply #1 on: December 06, 2013, 10:32:28 am »
This is a frequently asked question where the responses always seem to be complicated and not always 100% useful. Yours looks like a good one, thanks for posting it.

I have links to other options here, scroll to the bottom:

http://www.lvr.com/mass_storage_faq.htm

egovind

  • Member
  • ***
  • Posts: 14
Re: Finding drive letter assigned by Windows to a USB MSD Device from VID/PID
« Reply #2 on: December 06, 2013, 11:22:45 am »
Thanks for the links, guess I should stick to the current solution then, it seems to be the least complicated..

egovind

  • Member
  • ***
  • Posts: 14
Re: Finding drive letter assigned by Windows to a USB MSD Device from VID/PID
« Reply #3 on: December 08, 2013, 09:22:28 pm »
I got a reply to my post on this in stackoverflow that seems to work. So I'm cross posting that here:

Code: [Select]
         public void FindPath()
         {
             string Entity = "";
             List<string> USBobjects = new List<string>();
             foreach (ManagementObject entity in new ManagementObjectSearcher("select * from Win32_USBHub Where DeviceID Like '%VID_XXXX&PID_YYYY%'").Get())
             {
                 Entity = entity["DeviceID"].ToString();
                 foreach (ManagementObject controller in entity.GetRelated("Win32_USBController"))
                 {
                     foreach (ManagementObject obj in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_USBController.DeviceID='" + controller["PNPDeviceID"].ToString() + "'}").Get())
                     {
                         if (obj.ToString().Contains("DeviceID"))
                             USBobjects.Add(obj["DeviceID"].ToString());

                     }
                 }

             }

             int VidPidposition = USBobjects.IndexOf(Entity);
             for (int i = VidPidposition; i <= USBobjects.Count; i++)
             {
                 if (USBobjects[i].Contains("USBSTOR"))
                 {
                     Secondentity = USBobjects[i];
                     break;
                 }

             }
         }

         public void GetDriveLetter()
         {
             foreach (ManagementObject drive in new ManagementObjectSearcher("select * from Win32_DiskDrive").Get())
             {
                 if (drive["PNPDeviceID"].ToString() == Secondentity)
                 {
                     foreach (ManagementObject o in drive.GetRelated("Win32_DiskPartition"))
                     {
                         foreach (ManagementObject i in o.GetRelated("Win32_LogicalDisk"))
                         {
                             Console.WriteLine("Disk: " + i["Name"].ToString());
                         }
                     }
                 }
             }
         }

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Finding drive letter assigned by Windows to a USB MSD Device from VID/PID
« Reply #4 on: December 08, 2013, 10:54:52 pm »
Looks good, thanks for posting!