Una aproximación al problema a bajo nivel puede ser leer directamente la unidad física, para extraer la tabla de particiones, donde encontraremos el tamaño en sectores de cada una. En este ejemplo muestro como hacerlo asumiendo que el tamaño de un sector es 512 bytes:
Código Delphi
[-]
uses
Windows, SysUtils;
type
PARTITION_ENTRY = record
Boot_Flag: BYTE; CHS_Begin: array [1..2] of BYTE;
_Type: BYTE; CHS_End: array [1..2] of BYTE;
LBA: DWORD; NumberOfSectors: DWORD; end;
PPARTITION_ENTRY = ^PARTITION_ENTRY;
function GetSizeOfPhysicalDisk(Name: String): UINT64;
var
hFile: Cardinal;
MBR: PByteArray;
BytesRead: Cardinal;
PE: array [0..4] of PARTITION_ENTRY;
i: integer;
Sectors: DWORD;
begin
Sectors:= 0;
GetMem(MBR,$0200);
hFile:= CreateFile(PChar(Name), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
if hFile <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
ReadFile(hFile, MBR^, 512, BytesRead, nil);
CopyMemory(@PE, Pointer(DWORD(MBR)+446), 16*4);
for i:=0 to 3 do inc(Sectors, PE[i].NumberOfSectors);
CloseHandle(hFile);
end;
FreeMem(MBR);
Result:= (UINT64(Sectors)-1) * 512;
end;
Un ejemplo de uso:
Código Delphi
[-]
var
TotalSize: UINT64;
begin
TotalSize:= GetSizeOfPhysicalDisk('\\.\PhysicalDrive0');
end.
Saludos.