如何得到硬盘物理序号

    技术2022-05-11  91

     

    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:/windows/system/的smartvsd.vxd//copy to c:/windows/system/iosubsys//reboot your computer and ok//2000 and nt do not need得到硬盘物理序号:

    uses hdid;

    hdsn:=trim(GetIdeDiskSerialNumber);

     


    最新回复(0)