type
TDiskExtent = record
DiskNumber: Cardinal;
StartingOffset: Int64;
ExtentLength: Int64;
end;
TVolumeDiskExtents = record
NumberOfDiskExtents: Cardinal;
Extents: array[0..0] of TDiskExtent;
end;
PVolumeDiskExtents = ^TVolumeDiskExtents;
...
const
METHOD_BUFFERED = 0;
FILE_ANY_ACCESS = 0;
IOCTL_VOLUME_BASE = DWORD('V');
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = ((IOCTL_VOLUME_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or (0 shl 2) or METHOD_BUFFERED);
...
function GetLD(Drive: Char):Cardinal;
var
Buffer : String;
begin
Buffer := Format('\\.\%s:', [Drive]);
Result := CreateFile(PChar(Buffer), 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
end;
function GetPhysicalDiskNumber(Drive: Char):Byte;
var
LD : DWORD;
DiskExtents : PVolumeDiskExtents;
DiskExtent : TDiskExtent;
BytesReturned : Cardinal;
begin
Result := MAXBYTE;
LD := GetLD(Drive);
if LD = INVALID_HANDLE_VALUE then exit;
try
DiskExtents := AllocMem(Max_Path);
DeviceIOControl(LD, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil, 0, DiskExtents, Max_Path, BytesReturned, nil);
if DiskExtents^.NumberOfDiskExtents > 0 then
begin
DiskExtent := DiskExtents^.Extents[0];
Result := DiskExtent.DiskNumber;
end;
finally
CloseHandle(LD);
end;
end;
Источник:
https://www.experts-exchange.com/questions/2413489... (я код немного подправил)