我在几台计算机上测试了这段代码,它可以工作:
MBR 磁盘:
磁盘签名/标识符是一个 4 字节(长字)数字,在第一次创建主引导记录/分区表时随机生成并存储在字节偏移 1B8(十六进制)或 440(十进制)到 1BB(十六进制)或 443 (dec) 在 MBR 磁盘扇区 (0) 中。因此,在任何 MBR 磁盘上,您都可以直接从该位置读取它:
const
// Max number of drives assuming primary/secondary, master/slave topology
MAX_IDE_DRIVES = 16;
var
i: Integer;
RawMBR: array[0..511] of Byte;
btsIO: DWORD;
hDevice: THandle;
s: string;
begin
s := '';
for i := 0 to MAX_IDE_DRIVES - 1 do
begin
hDevice := CreateFile(PChar('\\.\PHYSICALDRIVE' + IntToStr(i)), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hDevice <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(hDevice, 0, nil, FILE_BEGIN); //MBR starts in sector 0
if not ReadFile(hDevice, RawMBR[0], 512, btsIO, nil) then
begin
CloseHandle(hDevice);
Continue;
end;
CloseHandle(hDevice);
s := s + 'Disk ' + IntToStr(i) + ' = ' + IntToHex(RawMBR[443], 2) + ' ' +
IntToHex(RawMBR[442], 2) + ' ' + IntToHex(RawMBR[441], 2) +
' ' + IntToHex(RawMBR[440], 2) + #13#10;
end;
end;
ShowMessage(s);
end;
GPT 磁盘:
磁盘签名/标识符是第一次创建 GPT 时随机生成的 16 字节 (GUID) 数字,并存储在GPT 磁盘扇区 (1)。因此,在任何 GPT 磁盘上,您都可以直接从该位置读取它:
const
// Max number of drives assuming primary/secondary, master/slave topology
MAX_IDE_DRIVES = 16;
var
i: Integer;
RawMBR: array[0..511] of Byte;
btsIO: DWORD;
hDevice: THandle;
s: string;
begin
s := '';
for i := 0 to MAX_IDE_DRIVES - 1 do
begin
hDevice := CreateFile(PChar('\\.\PHYSICALDRIVE' + IntToStr(i)), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hDevice <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(hDevice, 512, nil, FILE_BEGIN); //GPT starts in sector 1
if not ReadFile(hDevice, RawMBR[0], 512, btsIO, nil) then
begin
CloseHandle(hDevice);
Continue;
end;
CloseHandle(hDevice);
s := s + 'Disk ' + IntToStr(i) + ' = ' + IntToHex(RawMBR[59], 2) +
' ' + IntToHex(RawMBR[58], 2) + ' ' + IntToHex(RawMBR[57], 2) +
' ' + IntToHex(RawMBR[56], 2) + ' - ' + IntToHex(RawMBR[61], 2) +
' ' + IntToHex(RawMBR[60], 2) + ' - ' + IntToHex(RawMBR[63], 2) +
' ' + IntToHex(RawMBR[62], 2) + ' - ' + IntToHex(RawMBR[64], 2) +
' ' + IntToHex(RawMBR[65], 2) + ' - ' + IntToHex(RawMBR[66], 2) +
' ' + IntToHex(RawMBR[67], 2) + ' ' + IntToHex(RawMBR[68], 2) +
' ' + IntToHex(RawMBR[69], 2) + ' ' + IntToHex(RawMBR[70], 2) +
' ' + IntToHex(RawMBR[71], 2) +
#13#10;
end;
end;
ShowMessage(s);
end;
好的,现在让我们将它们组合起来:
procedure TForm1.Button1Click(Sender: TObject);
const
// Max number of drives assuming primary/secondary, master/slave topology
MAX_IDE_DRIVES = 16;
var
i: Integer;
DiskType: Byte;
RawMBR: array[0..511] of Byte;
btsIO: DWORD;
hDevice: THandle;
s: string;
begin
s := '';
for i := 0 to MAX_IDE_DRIVES - 1 do
begin
hDevice := CreateFile(PChar('\\.\PHYSICALDRIVE' + IntToStr(i)), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hDevice <> INVALID_HANDLE_VALUE then
begin
SetFilePointer(hDevice, 512, nil, FILE_BEGIN); //sector 1 for GPT
if not ReadFile(hDevice, RawMBR[0], 512, btsIO, nil) then
begin
CloseHandle(hDevice);
Continue;
end;
if (IntToHex(RawMBR[0], 2) + IntToHex(RawMBR[1], 2) +
IntToHex(RawMBR[2], 2) + IntToHex(RawMBR[3], 2) +
IntToHex(RawMBR[4], 2) + IntToHex(RawMBR[5], 2) +
IntToHex(RawMBR[6], 2) + IntToHex(RawMBR[7], 2)) =
'4546492050415254' then //EFI PART
DiskType := 1 //GPT
else
begin
DiskType := 0; //MBR
SetFilePointer(hDevice, 0, nil, FILE_BEGIN); //sector 0 for MBR
if not ReadFile(hDevice, RawMBR[0], 512, btsIO, nil) then
begin
CloseHandle(hDevice);
Continue;
end;
end;
CloseHandle(hDevice);
if DiskType = 0 then
s := s + 'Disk ' + IntToStr(i) + ' = ' + IntToHex(RawMBR[443], 2) + ' ' +
IntToHex(RawMBR[442], 2) + ' ' + IntToHex(RawMBR[441], 2) +
' ' + IntToHex(RawMBR[440], 2) + #13#10
else
s := s + 'Disk ' + IntToStr(i) + ' = ' + IntToHex(RawMBR[59], 2) +
' ' + IntToHex(RawMBR[58], 2) + ' ' + IntToHex(RawMBR[57], 2) +
' ' + IntToHex(RawMBR[56], 2) + ' - ' + IntToHex(RawMBR[61], 2) +
' ' + IntToHex(RawMBR[60], 2) + ' - ' + IntToHex(RawMBR[63], 2) +
' ' + IntToHex(RawMBR[62], 2) + ' - ' + IntToHex(RawMBR[64], 2) +
' ' + IntToHex(RawMBR[65], 2) + ' - ' + IntToHex(RawMBR[66], 2) +
' ' + IntToHex(RawMBR[67], 2) + ' ' + IntToHex(RawMBR[68], 2) +
' ' + IntToHex(RawMBR[69], 2) + ' ' + IntToHex(RawMBR[70], 2) +
' ' + IntToHex(RawMBR[71], 2) +
#13#10;
end;
end;
ShowMessage(s);
end;
此代码需要提升权限才能访问磁盘。