Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I tested this code on several computers and it works:</p> <p>MBR disks:</p> <p>The Disk Signature/Identifier is a 4-byte (longword) number that is randomly generated when the Master Boot Record/Partition Table is first created and stored at byte offset 1B8 (hex) or 440 (dec) through 1BB (hex) or 443 (dec) in the MBR disk sector (0). So, on any MBR disks you can read it directly from that location:</p> <pre><code>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 &lt;&gt; 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; </code></pre> <p>GPT Disks:</p> <p>The Disk Signature/Identifier is a 16-byte (GUID) number that is randomly generated when the GPT is first created and stored at byte offset 038 (hex) or 56 (dec) through 047 (hex) or 71 (dec) in the GPT disk sector (1). So, on any GPT disks you can read it directly from that location:</p> <pre><code>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 &lt;&gt; 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; </code></pre> <p>Ok, now let's combine them:</p> <pre><code>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 &lt;&gt; 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; </code></pre> <p>This code requires elevated privileges to gain access to the disks.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload