WEB开发网
开发学院软件开发Delphi 如何得到硬盘物理序号 阅读

如何得到硬盘物理序号

 2006-02-04 13:30:07 来源:WEB开发网   
核心提示:unit hdid;interfaceuses Windows, Controls,SysUtils,Forms; //, Graphics, Dialogs, Classes, Messages,StdCtrls;type TSrbIoControl = packed record HeaderLength

unit hdid;

interface

uses
  Windows, Controls,SysUtils,Forms;
  //, Graphics, Dialogs, Classes, Messages,StdCtrls;
type
  TSrbIoControl = packed record
   HeaderLength : ULONG;
   Signature   : Array[0..7] of Char;
   Timeout    : ULONG;
   ControlCode  : ULONG;
   ReturnCode  : ULONG;
   Length    : ULONG;
  end;
  SRB_IO_CONTROL = TSrbIoControl;
  PSrbIoControl = ^TSrbIoControl;

  TIDERegs = packed record
   bFeaturesReg   : Byte; // Used for specifying SMART "commands".
   bSectorCountReg  : Byte; // IDE sector count register
   bSectorNumberReg : Byte; // IDE sector number register
   bCylLowReg    : Byte; // IDE low order cylinder value
   bCylHighReg    : Byte; // IDE high order cylinder value
   bDriveHeadReg   : Byte; // IDE drive/head register
   bCommandReg    : Byte; // Actual IDE command.
   bReserved     : Byte; // reserved.  Must be zero.
  end;
  IDEREGS  = TIDERegs;
  PIDERegs  = ^TIDERegs;

  TSendCmdInParams = packed record
   cBufferSize  : DWord;
   irDriveRegs  : TIDERegs;
   bDriveNumber : Byte;
   bReserved   : Array[0..2] of Byte;
   dwReserved  : Array[0..3] of DWORD;
   bBuffer    : Array[0..0] of Byte;
  end;
  SENDCMDINPARAMS  = TSendCmdInParams;
  PSendCmdInParams  = ^TSendCmdInParams;

  TIdSector = packed record
   wGenConfig         : Word;
   wNumCyls          : Word;
   wReserved          : Word;
   wNumHeads          : Word;
   wBytesPerTrack       : Word;
   wBytesPerSector       : Word;
   wSectorsPerTrack      : Word;
   wVendorUnique        : Array[0..2] of Word;
   sSerialNumber        : Array[0..19] of Char;
   wBufferType         : Word;
   wBufferSize         : Word;
   wECCSize          : Word;
   sFirmwareRev        : Array[0..7] of Char;
   sModelNumber        : Array[0..39] of Char;
   wMoreVendorUnique      : Word;
   wDoubleWordIO        : Word;
   wCapabilities        : Word;
   wReserved1         : Word;
   wPIOTiming         : Word;
   wDMATiming         : Word;
   wBS             : Word;
   wNumCurrentCyls       : Word;
   wNumCurrentHeads      : Word;
   wNumCurrentSectorsPerTrack : Word;
   ulCurrentSectorCapacity   : ULONG;
   wMultSectorStuff      : Word;
   ulTotalAddressableSectors  : ULONG;
   wSingleWordDMA       : Word;
   wMultiWordDMA        : Word;
   bReserved          : Array[0..127] of Byte;
  end;
  PIdSector = ^TIdSector;

const
  IDE_ID_FUNCTION = $EC;
  IDENTIFY_BUFFER_SIZE    = 512;
  DFP_RECEIVE_DRIVE_DATA     = $0007c088;
  IOCTL_SCSI_MINipORT      = $0004d008;
  IOCTL_SCSI_MINIPORT_IDENTIFY  = $001b0501;
  DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;
  BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize;
  W9xBufferSize = IDENTIFY_BUFFER_SIZE+16;
type
  Thdidform = class(TForm)
  PRivate
   { Private declarations }
  public

   { Public declarations }
  end;

var
  hdidform: Thdidform;
  function GetIdeDiskSerialNumber : String;

implementation

{$R *.DFM}
procedure ChangeByteOrder( var Data; Size : Integer );
  var ptr : PChar;
    i : Integer;
    c : Char;
  begin
   ptr := @Data;
   for i := 0 to (Size shr 1)-1 do
   begin
    c := ptr^;
    ptr^ := (ptr+1)^;
    (ptr+1)^ := c;
    Inc(ptr,2);
   end;
  end;

function GetIdeDiskSerialNumber : String;

var
  hDevice : THandle;
  cbBytesReturned : DWORD;
  pInData : PSendCmdInParams;
  pOutData : Pointer; // PSendCmdOutParams
  Buffer : Array[0..BufferSize-1] of Byte;
  srbControl : TSrbIoControl absolute Buffer;
begin
  Result := ';
  FillChar(Buffer,BufferSize,#0);
  if Win32Platform=VER_PLATFORM_WIN32_NT then
   begin // Windows NT, Windows 2000
    // Get SCSI port handle
    hDevice := CreateFile( '\.Scsi0:',
     GENERIC_READ or GENERIC_WRITE,
     FILE_SHARE_READ or FILE_SHARE_WRITE,
     nil, OPEN_EXISTING, 0, 0 );
    if hDevice=INVALID_HANDLE_VALUE then Exit;
    try
     srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
     System.Move('SCSIDISK',srbControl.Signature,8);
     srbControl.Timeout    := 2;
     srbControl.Length    := DataSize;
     srbControl.ControlCode  := IOCTL_SCSI_MINIPORT_IDENTIFY;
     pInData := PSendCmdInParams(PChar(@Buffer)
          +SizeOf(SRB_IO_CONTROL));
     pOutData := pInData;
     with pInData^ do
     begin
      cBufferSize  := IDENTIFY_BUFFER_SIZE;
      bDriveNumber := 0;
      with irDriveRegs do
      begin
       bFeaturesReg   := 0;
       bSectorCountReg  := 1;
       bSectorNumberReg := 1;
       bCylLowReg    := 0;
       bCylHighReg    := 0;
       bDriveHeadReg   := $A0;
       bCommandReg    := IDE_ID_FUNCTION;
      end;
     end;
     if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT,
      @Buffer, BufferSize, @Buffer, BufferSize,
      cbBytesReturned, nil ) then Exit;
    finally
     CloseHandle(hDevice);
    end;
   end
  else
   begin // Windows 95 OSR2, Windows 98
    hDevice := CreateFile( '\.SMARTVSD', 0, 0, nil,
     CREATE_NEW, 0, 0 );
    if hDevice=INVALID_HANDLE_VALUE then Exit;
    try
     pInData := PSendCmdInParams(@Buffer);
     pOutData := @pInData^.bBuffer;
     with pInData^ do
     begin
      cBufferSize  := IDENTIFY_BUFFER_SIZE;
      bDriveNumber := 0;
      with irDriveRegs do
      begin
       bFeaturesReg   := 0;
       bSectorCountReg  := 1;
       bSectorNumberReg := 1;
       bCylLowReg    := 0;
       bCylHighReg    := 0;
       bDriveHeadReg   := $A0;
       bCommandReg    := IDE_ID_FUNCTION;
      end;
     end;
     if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA,
      pInData, SizeOf(TSendCmdInParams)-1, pOutData,
      W9xBufferSize, cbBytesReturned, nil ) then Exit;
    finally
     CloseHandle(hDevice);
    end;
   end;
   with PIdSector(PChar(pOutData)+16)^ do
   begin
    ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
    SetString(Result,sSerialNumber,SizeOf(sSerialNumber));
   end;
end;

END.

//win98要 c:windowssystem的smartvsd.vxd
//copy to c:windowssystemiosubsys
//reboot your computer and ok
//2000 and nt do not need
得到硬盘物理序号:

uses hdid;

hdsn:=trim(GetIdeDiskSerialNumber);

Tags:如何 得到 硬盘

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接