delphi如何读取硬件信息如CPU、硬盘、主板、网卡等序列号.

解决方案 »

  1.   

    转来的,取硬盘序列号
    function GetIdeDiskSerialNumber : String; 
    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 for future use.  Must be zero. 
     end; 
     IDEREGS   = TIDERegs; 
     PIDERegs  = ^TIDERegs;  TSendCmdInParams = packed record 
       cBufferSize  : DWORD;                // Buffer size in bytes 
       irDriveRegs  : TIDERegs;             // Structure with drive register values. 
       bDriveNumber : Byte;                 // Physical drive number to send command to (0,1,2,3). 
       bReserved    : Array[0..2] of Byte;  // Reserved for future expansion. 
       dwReserved   : Array[0..3] of DWORD; // For future use. 
       bBuffer      : Array[0..0] of Byte;  // Input buffer. 
     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; 
    var 
     hDevice : THandle; 
     cbBytesReturned : DWORD; 
     pInData : PSendCmdInParams; 
     pOutData : Pointer; // PSendCmdInParams; 
     Buffer : Array[0..BufferSize-1] of Byte; 
     srbControl : TSrbIoControl absolute Buffer;  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; 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 := PChar(@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; 
      

  2.   

    还是转来的,取CPU序列号:
    type
      TCPUID = array[1..4] of Longint;function GetCPUID: TCPUID; assembler; register; //得到CPU序列号
    asm
     PUSH    EBX         {Save affected register}
     PUSH    EDI
     MOV     EDI,EAX     {@Resukt}
     MOV     EAX,1
     DW      $A20F       {CPUID Command}
     STOSD               {CPUID[1]}
     MOV     EAX,EBX
     STOSD               {CPUID[2]}
     MOV     EAX,ECX
     STOSD               {CPUID[3]}
     MOV     EAX,EDX
     STOSD               {CPUID[4]}
     POP     EDI         {Restore registers}
     POP     EBX
    end;procedure TForm1.BitBtn1Click(Sender: TObject);
    var
      mCPUID: TCPUID;
    begin
      mCPUID := GetCPUID;
      ShowMessage(IntToHex(mCPUID[1], 8) + ';' + IntToHex(mCPUID[2], 8) + ';' + IntToHex(mCPUID[3], 8) + ';' + IntToHex(mCPUID[4], 8));
    end;
      

  3.   

    CPU序列号:不同CPU序列号取法不同(Pentium/P2/P3/P4),不是所有的CPU都有序列号,而且同一型号的CPU序列号相同
    硬盘序列号:有些硬盘没有序列号,或无法正确读取(人为或系统等因素造成)
    网卡序列号:局限性太大,并且可以通过修改注册表的方式,修改网卡序列号
    主板序列号:和BIOS厂商和操作系统的不同,取法不同,比如Award BIOS中主板序列号的位置是固定的,在Phoenix BIOS中主板序列号的位置不固定
      

  4.   

    去网上下载DiskID32.dll,有例程可以参考!