windows - 如何使用 Delphi 7 检索 Windows 中所有磁盘的磁盘签名?

标签 windows delphi delphi-7 signature disk

在 Windows >= XP 上使用 Delphi 7,如何从计算机中检索每个磁盘的磁盘签名?最好不使用 WMI 或 Diskpart。

如果可能的话,也要快..

谢谢。

稍后编辑:

Documentation: http://pcsupport.about.com/od/termsd/g/disk-signature.htm
MBR disks: http://diddy.boot-land.net/firadisk/files/signature.htm
GPT disks: http://thestarman.pcministry.com/asm/mbr/GPT.htm

How to get it with DiskPart (method found on Google when searching "disk signature"):
Diskpart >> list disk >> select disk [n] >>
detail disk >> Disk ID: 0E35445B for MBR disks
and GUID: 55FD03F2-6B11-49DF-8167-D30B94A4509D for GPT Disks

最佳答案

您可以使用 DeviceIoControlIOCTL_DISK_GET_DRIVE_LAYOUT_EX获取您需要的信息。

program DiskSignatureGuid;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

type
  TDriveLayoutInformationMbr = record
    Signature: DWORD;
  end;

  TDriveLayoutInformationGpt = record
    DiskId: TGuid;
    StartingUsableOffset: Int64;
    UsableLength: Int64;
    MaxPartitionCount: DWORD;
  end;

  TPartitionInformationMbr = record
    PartitionType: Byte;
    BootIndicator: Boolean;
    RecognizedPartition: Boolean;
    HiddenSectors: DWORD;
  end;

  TPartitionInformationGpt = record
    PartitionType: TGuid;
    PartitionId: TGuid;
    Attributes: Int64;
    Name: array [0..35] of WideChar;
  end;

  TPartitionInformationEx = record
    PartitionStyle: Integer;
    StartingOffset: Int64;
    PartitionLength: Int64;
    PartitionNumber: DWORD;
    RewritePartition: Boolean;
    case Integer of
      0: (Mbr: TPartitionInformationMbr);
      1: (Gpt: TPartitionInformationGpt);
  end;

  TDriveLayoutInformationEx = record
    PartitionStyle: DWORD;
    PartitionCount: DWORD;
    DriveLayoutInformation: record
      case Integer of
      0: (Mbr: TDriveLayoutInformationMbr);
      1: (Gpt: TDriveLayoutInformationGpt);
    end;
    PartitionEntry: array [0..15] of TPartitionInformationGpt;
    //hard-coded maximum of 16 partitions
  end;

const
  PARTITION_STYLE_MBR = 0;
  PARTITION_STYLE_GPT = 1;
  PARTITION_STYLE_RAW = 2;

const
  IOCTL_DISK_GET_DRIVE_LAYOUT_EX = $00070050;

procedure Main;
const
  // Max number of drives assuming primary/secondary, master/slave topology
  MAX_IDE_DRIVES = 16;
var
  i: Integer;
  Drive: string;
  hDevice: THandle;
  DriveLayoutInfo: TDriveLayoutInformationEx;
  BytesReturned: DWORD;
begin
  for i := 0 to MAX_IDE_DRIVES - 1 do
  begin
    Drive := '\\.\PHYSICALDRIVE' + IntToStr(i);
    hDevice := CreateFile(PChar(Drive), 0, FILE_SHARE_READ or FILE_SHARE_WRITE,
      nil, OPEN_EXISTING, 0, 0);
    if hDevice <> INVALID_HANDLE_VALUE then
    begin
      if DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
        @DriveLayoutInfo, SizeOf(DriveLayoutInfo), BytesReturned, nil) then
      begin
        case DriveLayoutInfo.PartitionStyle of
        PARTITION_STYLE_MBR:
          Writeln(Drive + ', MBR, ' +
            IntToHex(DriveLayoutInfo.DriveLayoutInformation.Mbr.Signature, 8));
        PARTITION_STYLE_GPT:
          Writeln(Drive + ', GPT, ' +
            GUIDToString(DriveLayoutInfo.DriveLayoutInformation.Gpt.DiskId));
        PARTITION_STYLE_RAW:
          Writeln(Drive + ', RAW');
        end;
      end;
      CloseHandle(hDevice);
    end;
  end;
end;

begin
  Main;
  Readln;
end.

请注意,由于 0 已传递给 CreateFiledwDesiredAccess 参数,因此不需要提升权限。这在 documentation 中得到了解释,尽管有些含糊不清。 :

Direct access to the disk or to a volume is restricted ... The following requirements must be met for such a call to succeed:

  • The caller must have administrative privileges.
  • The dwCreationDisposition parameter must have the OPEN_EXISTINGflag.
  • When opening a volume or floppy disk, the dwShareMode parameter must have the FILE_SHARE_WRITEflag.

Note The dwDesiredAccess parameter can be zero, allowing the application to query device attributes without accessing a device. This is useful for an application to determine the size of a floppy disk drive and the formats it supports without requiring a floppy disk in a drive, for instance. It can also be used for reading statistics without requiring higher-level data read/write permission.

关于windows - 如何使用 Delphi 7 检索 Windows 中所有磁盘的磁盘签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17110543/

相关文章:

Delphi7、dbExpress和Master Detail关系

delphi - 向同一台计算机上的多个客户端发送多播消息

delphi - 在 Firemonkey 中打印时客户端的格式设置发生变化

delphi - 如何使用WinSpool API设置纸张尺寸?

multithreading - 在 Delphi 中的每个内核中运行线程

windows - 函数返回不同的结果

windows - 如何在表格中心模仿[Ctrl+鼠标左键]或打开另一个程序并输入一个词?

windows - REBASE.EXE 的替代品是什么?

python - 从 Ubuntu 迁移到 Windows——恢复 Vim+Python 工作流程

c - 在基准测试中强制串行执行 __rdtsc()