PORTS Forum
Ports and Interfaces => USB => Topic started by: egovind on December 06, 2013, 06:12:10 am
-
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 (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:
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 ?
-
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
-
Thanks for the links, guess I should stick to the current solution then, it seems to be the least complicated..
-
I got a reply to my post on this in stackoverflow that seems to work. So I'm cross posting that here:
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());
}
}
}
}
}
-
Looks good, thanks for posting!