Get Main Hard Drive Serial - Delphi

DarkCoderSc personal avatar
DarkCoderSc

Jean-Pierre LESUEUR

uses
  System.SysUtils, Winapi.Windows;

// ...

type
  STORAGE_QUERY_TYPE = (
    PropertyStandardQuery = 0,
    PropertyExistsQuery,
    PropertyMaskQuery,
    PropertyQueryMaxDefined
  );
  TStorageQueryType = STORAGE_QUERY_TYPE;

  STORAGE_PROPERTY_ID = (
    StorageDeviceProperty = 0,
    StorageAdapterProperty
  );
  TStoragePropertyID = STORAGE_PROPERTY_ID;

  STORAGE_PROPERTY_QUERY = record
    PropertyId           : STORAGE_PROPERTY_ID;
    QueryType            : STORAGE_QUERY_TYPE;
    AdditionalParameters : array[0..9] of AnsiChar;
  end;
  TStoragePropertyQuery = STORAGE_PROPERTY_QUERY;

  STORAGE_BUS_TYPE = (
    BusTypeUnknown = 0,
    BusTypeScsi,
    BusTypeAtapi,
    BusTypeAta,
    BusType1394,
    BusTypeSsa,
    BusTypeFibre,
    BusTypeUsb,
    BusTypeRAID,
    BusTypeiScsi,
    BusTypeSas,
    BusTypeSata,
    BusTypeMaxReserved = $7F
  );
  TStorageBusType = STORAGE_BUS_TYPE;

  STORAGE_DEVICE_DESCRIPTOR = record
    Version               : DWORD;
    Size                  : DWORD;
    DeviceType            : Byte;
    DeviceTypeModifier    : Byte;
    RemovableMedia        : Boolean;
    CommandQueueing       : Boolean;
    VendorIdOffset        : DWORD;
    ProductIdOffset       : DWORD;
    ProductRevisionOffset : DWORD;
    SerialNumberOffset    : DWORD;
    BusType               : STORAGE_BUS_TYPE;
    RawPropertiesLength   : DWORD;
    RawDeviceProperties   : array[0..0] of AnsiChar;
  end;
  TStorageDeviceDescriptor = STORAGE_DEVICE_DESCRIPTOR;
  PStorageDeviceDescriptor = ^TStorageDeviceDescriptor;

  STORAGE_DESCRIPTOR_HEADER = record
    Version : DWORD;
    Size    : DWORD;
  end;
  TStorageDescriptorHeader = STORAGE_DESCRIPTOR_HEADER;
  PStorageDescriptorHeader = ^TStorageDescriptorHeader;

// ...

function GetHardDriveSerial() : String;
begin
  result := '';
  ///

  var hFile := CreateFileW('\\.\PhysicalDrive0', 0, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  if hFile = INVALID_HANDLE_VALUE then
    raise EWindowsException.Create('CreateFileW');
  try
    var AStoragePropertyQuery : TStoragePropertyQuery;
    ZeroMemory(@AStoragePropertyQuery, SizeOf(TStoragePropertyQuery));

    AStoragePropertyQuery.PropertyId := StorageDeviceProperty;
    AStoragePropertyQuery.QueryType := PropertyStandardQuery;

    var AStorageDescriptorHeader : TStorageDescriptorHeader;
    var ABytesReturned : DWORD;

    if not DeviceIoControl(
      hFile,
      IOCTL_STORAGE_QUERY_PROPERTY,
      @AStoragePropertyQuery,
      SizeOf(TStoragePropertyQuery),
      @AStorageDescriptorHeader,
      SizeOf(TStorageDescriptorHeader),
      ABytesReturned,
      nil
    ) then
      raise EWindowsException.Create('DeviceIoControl(1)');

    var pBuffer : Pointer;
    GetMem(pBuffer, AStorageDescriptorHeader.Size);
    try
      if not DeviceIoControl(
        hFile,
        IOCTL_STORAGE_QUERY_PROPERTY,
        @AStoragePropertyQuery,
        SizeOf(TStoragePropertyQuery),
        pBuffer,
        AStorageDescriptorHeader.Size,
        ABytesReturned,
        nil
      ) then
        raise EWindowsException.Create('DeviceIoControl(2)');

     ///
     result := String(PAnsiChar(NativeUInt(pBuffer) + PStorageDeviceDescriptor(pBuffer)^.SerialNumberOffset));
    finally
      FreeMem(pBuffer, AStorageDescriptorHeader.Size);
    end;
  finally
    CloseHandle(hFile);
  end;
end;

// ...

WriteLn(GetHardDriveSerial);

Implemented By Technique

Featured Windows API


Created

April 13, 2025

Last Revised

April 13, 2025