我在多台电脑上测试过这段代码并且它能正常工作:
MBR磁盘:
磁盘签名/标识符是一个4字节(长整型)的数字,当主引导记录/分区表第一次创建时随机生成,并存储于MBR磁盘扇区(0)的1B8(十六进制)或440(十进制)至1BB(十六进制)或443(十进制)字节偏移处。因此,在任何MBR磁盘上,您都可以直接从该位置读取它:
const
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);
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磁盘:
磁盘签名/标识符是一个16字节(GUID)的数字,在创建GPT时随机生成,并存储在GPT磁盘扇区的字节偏移量038(十六进制)或56(十进制)到047(十六进制)或71(十进制)之间的位置(1)。因此,在任何GPT磁盘上,您都可以直接从该位置读取它:
const
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);
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;
Ok, now let's combine them:
procedure TForm1.Button1Click(Sender: TObject);
const
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);
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
DiskType := 1
else
begin
DiskType := 0;
SetFilePointer(hDevice, 0, nil, FILE_BEGIN);
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;
这段代码需要提升权限才能访问磁盘。