ADD: Determine USB drive (Windows)

This commit is contained in:
Alexander Koblov 2019-07-09 17:55:44 +00:00
commit bd7deabcbd
2 changed files with 69 additions and 0 deletions

View file

@ -542,6 +542,7 @@ begin
begin
case DriveType of
dtFloppy: ; // Don't retrieve, it's slow.
dtFlash,
dtHardDisk:
begin
DriveLabel := mbGetVolumeLabel(Path, True);
@ -552,6 +553,11 @@ begin
else
DriveLabel := mbGetVolumeLabel(Path, True);
end;
if DriveType in [dtFlash, dtHardDisk] then
begin
if mbDriveUsb(DriveLetter) then
DriveType:= dtRemovableUsb;
end;
end;
end;
end;

View file

@ -76,6 +76,7 @@ procedure mbWaitLabelChange(const sDrv: String; const sCurLabel: String);
@param(sDrv String specifying the root directory of a drive)
}
procedure mbCloseCD(const sDrv: String);
function mbDriveUsb(Drive: AnsiChar): Boolean;
procedure mbDriveUnlock(const sDrv: String);
{en
Get remote file name by local file name
@ -415,6 +416,68 @@ begin
mciSendCommandA(OpenParms.wDeviceID, MCI_CLOSE, MCI_OPEN_TYPE or MCI_OPEN_ELEMENT, DWORD_PTR(@OpenParms));
end;
const
// STORAGE_BUS_TYPE
BusTypeUnknown = $00;
BusTypeUsb = $07;
// dwIoControlCode
IOCTL_STORAGE_QUERY_PROPERTY = $2D1400;
type
STORAGE_PROPERTY_QUERY = record
PropertyId: DWORD;
QueryType: DWORD;
AdditionalParameters: array[0..0] of Byte;
end;
STORAGE_DEVICE_DESCRIPTOR = record
Version: DWORD;
Size: DWORD;
DeviceType: Byte;
DeviceTypeModifier: Byte;
RemovableMedia: Boolean;
CommandQueueing: Boolean;
VendorIdOffset: DWORD;
ProductIdOffset: DWORD;
ProductRevisionOffset: DWORD;
SerialNumberOffset: DWORD;
BusType: DWORD;
RawPropertiesLength: DWORD;
RawDeviceProperties: array[0..0] of Byte;
end;
function mbDriveUsb(Drive: AnsiChar): Boolean;
var
Dummy: DWORD;
Handle: THandle;
Query: STORAGE_PROPERTY_QUERY;
BusType: DWORD = BusTypeUnknown;
Descr: STORAGE_DEVICE_DESCRIPTOR;
VolumePath: UnicodeString = '\\.\X:';
begin
VolumePath[5] := WideChar(Drive);
Handle := CreateFileW(PWideChar(VolumePath), 0,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0);
if (Handle <> INVALID_HANDLE_VALUE) then
begin
ZeroMemory(@Query, SizeOf(STORAGE_PROPERTY_QUERY));
if (DeviceIoControl(Handle, IOCTL_STORAGE_QUERY_PROPERTY,
@Query, SizeOf(STORAGE_PROPERTY_QUERY),
@Descr, SizeOf(STORAGE_DEVICE_DESCRIPTOR),
@Dummy, nil)) then
begin
BusType := Descr.BusType;
end;
CloseHandle(Handle);
end;
Result := (BusType = BusTypeUsb);
end;
function IsWow64: BOOL;
const
Wow64Process: TDuplicates = dupIgnore;