How can I get the drive letter of an USB device?
delphi, usb, wmi
Solution
If you are getting values like `\\.\PHYSICALDRIVE1` means which you are using the `Win32_DiskDrive` wmi class and the `DeviceID` Property , so in order to get the Drive letter you must use an ASSOCIATORS class, which will create a link between the wmi classes with contain the information which you are looking for (`Win32_LogicalDisk`) and the class which you are using (`Win32_DiskDrive`).
So you must do something like this
`Win32_DiskDrive`-> Win32_DiskDriveToDiskPartition -> Win32_DiskPartition -> Win32_LogicalDiskToPartition -> `Win32_LogicalDisk`
Check this sample function
{$APPTYPE CONSOLE}
uses
SysUtils,
ActiveX,
ComObj,
Variants;
function DeviceIDToDrive(const ADeviceID : string) : string;
var
FSWbemLocator : OLEVariant;
objWMIService : OLEVariant;
colLogicalDisks: OLEVariant;
colPartitions : OLEVariant;
objPartition : OLEVariant;
objLogicalDisk : OLEVariant;
oEnumPartition : IEnumvariant;
oEnumLogical : IEnumvariant;
iValue : LongWord;
DeviceID : string;
begin;
Result:='';
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
objWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
DeviceID := StringReplace(ADeviceID,'\','\\',[rfReplaceAll]); //Escape the `\` chars in the DeviceID value because the '\' is a reserved character in WMI.
colPartitions := objWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_DiskDrive.DeviceID="%s"} WHERE AssocClass = Win32_DiskDriveToDiskPartition',[DeviceID]));//link the Win32_DiskDrive class with the Win32_DiskDriveToDiskPartition class
oEnumPartition := IUnknown(colPartitions._NewEnum) as IEnumVariant;
while oEnumPartition.Next(1, objPartition, iValue) = 0 do
begin
if not VarIsNull(objPartition.DeviceID) then
begin
colLogicalDisks := objWMIService.ExecQuery('ASSOCIATORS OF {Win32_DiskPartition.DeviceID="'+VarToStr(objPartition.DeviceID)+'"} WHERE AssocClass = Win32_LogicalDiskToPartition'); //link the Win32_DiskPartition class with theWin32_LogicalDiskToPartition class.
oEnumLogical := IUnknown(colLogicalDisks._NewEnum) as IEnumVariant;
if oEnumLogical.Next(1, objLogicalDisk, iValue) = 0 then
begin
Result:=objLogicalDisk.DeviceID;
objLogicalDisk:=Unassigned;
end;
end;
objPartition:=Unassigned;
end;
end;
begin
try
CoInitialize(nil);
try
Writeln(DeviceIDToDrive('\\.\PHYSICALDRIVE2'));
finally
CoUninitialize;
end;
except
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Readln;
end.
Problem
I am using WMI to get all inserted USB disks manufactures names. The code works great but I have a problem how can I determine witch drive letter a certain disk has... I can get only the device name e.g (\\.\PhysicalDrive1) ... how can I translate this in a normal drive letter?