现在的位置: 首页 > 综合 > 正文

DELPHI 硬件信息 收集程序

2013年10月21日 ⁄ 综合 ⁄ 共 12785字 ⁄ 字号 评论关闭
  1. {***********************************************
  2. *                                              *
  3. *                                              *
  4. *      这个模块是用来获取CPU、硬盘序列号,CPU的  *
  5. *                                              *
  6. *   速率、显示器的刷新率网卡的MAC地址等信息       *
  7. *                                              *
  8. *                                              *
  9. *                                          *
  10. *************************************************}
  11. Unit UnitHardInfo;
  12. interface
  13. uses 
  14.    Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   Forms,   Dialogs,   
  15.       StdCtrls,   ExtCtrls,NB30,WinSock,Registry;
  16. const
  17.    ID_BIT = $200000// EFLAGS ID bit
  18. type 
  19.    TCPUID = array[1..4of Longint;
  20.    TVendor = array [0..11of char;
  21.    
  22.    function IsCPUID_Available : Boolean; register;       //判断CPU序列号是否可用函数
  23.    function GetCPUID: TCPUID; assembler; register;       //获取CPU序列号函数
  24.    function GetCPUVendor: TVendor; assembler; register;  //获取CPU生产厂家函数
  25.    function GetCPUInfo: string;                          //CPU序列号(格式化成字符串)
  26.    function GetCPUSpeed: Double;                         //获取CPU速度函数
  27.    function GetDisplayFrequency: Integer;                //获取显示器刷新率
  28.    function GetMemoryTotalSize  : DWORD;  //获取内存总量
  29.    function Getmac:string;
  30.    function GetHostName:string;
  31.    function NameToIP(Name:string):string;
  32.    function GetDiskSize : string;
  33.    function GetCPUName : string ;
  34. type  
          PASTAT   =   ^TASTAT;
          TASTAT   =   record
              adapter:   TAdapterStatus;
              name_buf:   TNameBuffer;
      end;
  35. implementation 
  36.   function IsCPUID_Available : Boolean; register;
  37.    asm
  38.     PUSHFD {direct access to flags no possible, only via stack}
  39.     POP EAX {flags to EAX}
  40.     MOV EDX,EAX {save current flags}
  41.     XOR EAX,ID_BIT {not ID bit}
  42.     PUSH EAX {onto stack}
  43.     POPFD {from stack to flags, with not ID bit}
  44.     PUSHFD {back to stack}
  45.     POP EAX {get back to EAX}
  46.     XOR EAX,EDX {check if ID bit affected}
  47.     JZ @exit {no, CPUID not availavle}
  48.     MOV AL,True {Result=True}
  49.     @exit:
  50.   end;
  51.   function GetCPUID: TCPUID; assembler; register;
  52.     asm
  53.     PUSH    EBX         {Save affected register}
  54.     PUSH    EDI
  55.     MOV     EDI,EAX     {@Resukt}
  56.     MOV     EAX,1
  57.     DW      $A20F       {CPUID Command}
  58.     STOSD                {CPUID[1]}
  59.     MOV     EAX,EBX
  60.     STOSD               {CPUID[2]}
  61.     MOV     EAX,ECX
  62.     STOSD               {CPUID[3]}
  63.     MOV     EAX,EDX
  64.     STOSD               {CPUID[4]}
  65.     POP     EDI         {Restore registers}
  66.     POP     EBX
  67.     end
  68.   function GetCPUVendor : TVendor; assembler; register;
  69.   //获取CPU生产厂家函数
  70.   //调用方法:EDIT.TEXT:='Current CPU Vendor:'+GetCPUVendor;
  71.     asm
  72.       PUSH EBX {Save affected register}
  73.       PUSH EDI
  74.       MOV EDI,EAX {@Result (TVendor)}
  75.       MOV EAX,0
  76.       DW $A20F {CPUID Command}
  77.       MOV EAX,EBX
  78.       XCHG EBX,ECX {save ECX result}
  79.       MOV ECX,4
  80.       @1:
  81.       STOSB
  82.       SHR EAX,8
  83.       LOOP @1
  84.       MOV EAX,EDX
  85.       MOV ECX,4
  86.       @2:
  87.       STOSB
  88.       SHR EAX,8
  89.       LOOP @2
  90.       MOV EAX,EBX
  91.       MOV ECX,4
  92.       @3:
  93.       STOSB
  94.       SHR EAX,8
  95.       LOOP @3
  96.       POP EDI {Restore registers}
  97.       POP EBX
  98.     end;
  99.   function GetCPUInfo: string;
  100.   var
  101.     CPUID: TCPUID;
  102.         I: Integer;
  103.         S: TVendor;
  104.   begin
  105.     for I:=Low(CPUID) to High(CPUID) do CPUID[I]:=-1;
  106.     if IsCPUID_Available then
  107.       begin
  108.          CPUID:= GetCPUID;
  109.          S:=GetCPUVendor;
  110.          Result:= IntToHex(CPUID[1], 8)
  111.                  +'-'+ IntToHex(CPUID[2], 8)
  112.                  +'-'+ IntToHex(CPUID[3], 8)
  113.                  +'-'+ IntToHex(CPUID[4], 8);
  114.       end
  115.     else Result:='CPUID not available';
  116.   end;
  117.  function GetCPUSpeed: Double;
  118.  //获取CPU速率函数
  119.  //调用方法:EDIT.TEXT:='Current CPU Speed:'+floattostr(GetCPUSpeed)+'MHz';
  120.  const
  121.   DelayTime = 500// 时间单位是毫秒
  122.  var
  123.   TimerHi, TimerLo: DWORD;
  124.   PriorityClass, Priority: Integer;
  125.  begin
  126.      PriorityClass := GetPriorityClass(GetCurrentProcess);
  127.      Priority := GetThreadPriority(GetCurrentThread);
  128.      SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
  129.      SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
  130.      Sleep(10);
  131.      asm
  132.         dw 310Fh // rdtsc
  133.         mov TimerLo, eax
  134.         mov TimerHi, edx
  135.      end;
  136.      Sleep(DelayTime);
  137.      asm
  138.         dw 310Fh // rdtsc 
  139.         sub eax, TimerLo 
  140.         sbb edx, TimerHi
  141.         mov TimerLo, eax
  142.         mov TimerHi, edx
  143.      end;
  144.      SetThreadPriority(GetCurrentThread, Priority);
  145.      SetPriorityClass(GetCurrentProcess, PriorityClass);
  146.      Result := TimerLo / (1000.0 * DelayTime);
  147.  end;
  148.  function GetDisplayFrequency: Integer;
  149.  // 这个函数返回的显示刷新率是以Hz为单位的
  150.  //调用方法:EDIT.TEXT:='Current DisplayFrequency:'+inttostr(GetDisplayFrequency)+' Hz';
  151.  var
  152.     DeviceMode: TDeviceMode;
  153.  begin
  154.    EnumDisplaySettings(nil, Cardinal(-1), DeviceMode);
  155.    Result := DeviceMode.dmDisplayFrequency;
  156.  end;
  157.   function  GetMemoryTotalSize : DWORD;  //获取内存总量
  158.   var
  159.   msMemory : TMemoryStatus;
  160.   iPhysicsMemoryTotalSize : DWORD ;
  161.   begin
  162.    msMemory.dwLength := SizeOf(msMemory);
  163.    GlobalMemoryStatus(msMemory);
  164.    iPhysicsMemoryTotalSize := msMemory.dwTotalPhys;
  165.    Result := iPhysicsMemoryTotalSize ;
  166.   end;
  167.   type   
  168.       PASTAT =^TASTAT;
  169.       TASTAT = record
  170.           adapter:TAdapterStatus;
  171.           name_buf:TNameBuffer;   
  172.   end;   
  173.   function   Getmac:string;   
  174.   var   
  175.       ncb   :   TNCB;   
  176.       s:string;   
  177.       adapt   :   TASTAT;   
  178.       lanaEnum   :   TLanaEnum;   
  179.       i,   j,   m   :   integer;
  180.       strPart,   strMac   :   string;   
  181.   begin
  182.   FillChar(ncb,   SizeOf(TNCB),   0);   
  183.       ncb.ncb_command   :=   Char(NCBEnum);   
  184.       ncb.ncb_buffer   :=   PChar(@lanaEnum);   
  185.       ncb.ncb_length   :=   SizeOf(TLanaEnum);
  186.       s:=Netbios(@ncb);
  187.       for   i   :=   0   to   integer(lanaEnum.length)-1   do
  188.       begin   
  189.           FillChar(ncb,   SizeOf(TNCB),   0);   
  190.           ncb.ncb_command   :=   Char(NCBReset);   
  191.           ncb.ncb_lana_num   :=   lanaEnum.lana[i];   
  192.           Netbios(@ncb);   
  193.           Netbios(@ncb);   
  194.           FillChar(ncb,   SizeOf(TNCB),   0);   
  195.           ncb.ncb_command   :=   Chr(NCBAstat);   
  196.           ncb.ncb_lana_num   :=   lanaEnum.lana[i];   
  197.           ncb.ncb_callname   :=   '*';
  198.           ncb.ncb_buffer   :=   PChar(@adapt);   
  199.           ncb.ncb_length   :=   SizeOf(TASTAT);   
  200.           m:=0;   
  201.           if   (Win32Platform   =   VER_PLATFORM_WIN32_NT)   then   
  202.           m:=1;   
  203.           if   m=1   then   
  204.           begin   
  205.           if   Netbios(@ncb)   =   Chr(0)   then   
  206.               strMac   :=   '';   
  207.               for   j   :=   0   to   5   do   
  208.               begin   
  209.                   strPart   :=   IntToHex(integer(adapt.adapter.adapter_address[j]),   2);   
  210.                   strMac   :=   strMac   +   strPart   +   '-';   
  211.               end;   
  212.               SetLength(strMac,   Length(strMac)-1);   
  213.           end;   
  214.       if   m=0   then   
  215.           if   Netbios(@ncb)   <>   Chr(0)   then   
  216.           begin   
  217.               strMac   :=   '';   
  218.               for   j   :=   0   to   5   do   
  219.               begin   
  220.                   strPart   :=   IntToHex(integer(adapt.adapter.adapter_address[j]),   2);   
  221.                   strMac   :=   strMac   +   strPart   +   '-';   
  222.               end;   
  223.               SetLength(strMac,   Length(strMac)-1);   
  224.           end;   
  225.       end;   
  226.   result:=strmac;   
  227.   end;   
  228.   function GetHostName:String;
  229.   var
  230.     ComputerName: array[0..MAX_COMPUTERNAME_LENGTH+1of char;
  231.     Size: Cardinal;
  232.     begin
  233.     result:='';
  234.     Size := MAX_COMPUTERNAME_LENGTH+1;
  235.     GetComputerName(ComputerName, Size);
  236.     Result:=StrPas(ComputerName);
  237.   end;
  238.   function NameToIP(Name:string):String;
  239.   var
  240.     WSAData: TWSAData;
  241.     HostEnt: PHostEnt;
  242.     begin
  243.     result:='';
  244.     WSAStartup(2, WSAData);
  245.     HostEnt := GetHostByName(PChar(Name));
  246.     if HostEnt <> nil then
  247.     begin
  248.     with HostEnt^ do
  249.     result:= Format('%d.%d.%d.%d',[Byte(h_addr^[0]), Byte(h_addr^[1]),Byte(h_addr^[2]), Byte(h_addr^[3])]);
  250.     end;
  251.     WSACleanup;
  252.     end;
  253.    function GetDiskSize : string;
  254.    var Available,Total,Free:Int64;
  255.        AvailableT,TotalT:real;
  256.        Drive:Char;
  257.          const GB=1024*1024*1024;
  258.    begin
  259.       AvailableT:=0;
  260.       TotalT:=0;
  261.     for Drive:='C' to 'Z' do
  262.     if GetDriveType(Pchar(Drive+':/'))=DRIVE_FIXED then
  263.         begin
  264.           GetDiskFreeSpaceEx(PChar(Drive+':/'),Available,Total,@Free);
  265.           AvailableT:=AvailableT+Available;
  266.           TotalT:=TotalT+Total;
  267.         end;
  268.     Result := Format('%.2fGB',[TotalT/GB]);
  269.    end ;
  270.   function GetCPUName : string ;
  271.   var
  272.      myreg:TRegistry;
  273.      CPUInfo : string ;
  274.   begin
  275.      myreg:=TRegistry.Create;
  276.      myreg.RootKey:=HKEY_LOCAL_MACHINE;
  277.      if   myreg.OpenKey('Hardware/Description/System/CentralProcessor/0',truethen     begin
  278.        if   myreg.ValueExists('ProcessorNameString')   then begin
  279.             CPUInfo :=  myreg.ReadString('ProcessorNameString') ;
  280.              myreg.CloseKey;
  281.        end else CPUInfo := 'UnKnow';
  282.      end;
  283.     Result := CPUInfo ;
  284.    end ;
  285. function   GetIdeSerialNumber:   pchar;     //获取硬盘的出厂系列号;  
         
    const   IDENTIFY_BUFFER_SIZE   =   512;  
     
    type  
            TIDERegs  
    =   packed   record  
                bFeaturesReg:   BYTE;  
                bSectorCountReg:   BYTE;  
                bSectorNumberReg:   BYTE;  
                bCylLowReg:   BYTE;  
                bCylHighReg:   BYTE;  
                bDriveHeadReg:   BYTE;
                bCommandReg:   BYTE;  
                bReserved:   BYTE;  
         
    end;  
          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;  
          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:   DWORD;  
              wMultSectorStuff:   Word;  
              ulTotalAddressableSectors:   DWORD;  
              wSingleWordDMA:   Word;  
              wMultiWordDMA:   Word;  
              bReserved:  
    array[0..127]   of   BYTE;  
         
    end;  
          PIdSector  
    =   ^TIdSector;  
          TDriverStatus  
    =   packed   record  
              bDriverError:   Byte;  
              bIDEStatus:   Byte;  
              bReserved:  
    array[0..1]   of   Byte;  
              dwReserved:  
    array[0..1]   of   DWORD;  
         
    end;  
          TSendCmdOutParams  
    =   packed   record  
              cBufferSize:   DWORD;  
              DriverStatus:   TDriverStatus;  
              bBuffer:  
    array[0..0]   of   BYTE;  
         
    end;  
     
    var  
          hDevice:   Thandle;  
          cbBytesReturned:   DWORD;  
          SCIP:   TSendCmdInParams;  
          aIdOutCmd:  
    array[0..(SizeOf(TSendCmdOutParams)   +   IDENTIFY_BUFFER_SIZE-1)-1]   of   Byte;  
          IdOutCmd:   TSendCmdOutParams   absolute   aIdOutCmd;  
     
    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   :
    =   '';  
     
    if   SysUtils.Win32Platform   =   VER_PLATFORM_WIN32_NT   then   begin   //   Windows   NT,   Windows   2000  
      hDevice   :
    =   CreateFile('//./PhysicalDrive0',   GENERIC_READ   or   GENERIC_WRITE,  
      FILE_SHARE_READ  
    or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,   0,   0);  
     
    end   else   //   Version   Windows   95   OSR2,   Windows   98  
      hDevice   :
    =   CreateFile('//./SMARTVSD',   0,   0,   nil,   CREATE_NEW,   0,   0);  
     
    if   hDevice   =   INVALID_HANDLE_VALUE   then   Exit;  
      try  
      FillChar(SCIP,   SizeOf(TSendCmdInParams)  
    -   1,   #0);  
      FillChar(aIdOutCmd,   SizeOf(aIdOutCmd),   #
    0);  
      cbBytesReturned   :
    =   0;  
     
    with   SCIP   do   begin  
      cBufferSize   :
    =   IDENTIFY_BUFFER_SIZE;  
     
    with   irDriveRegs   do   begin  
      bSectorCountReg   :
    =   1;  
      bSectorNumberReg   :
    =   1;  
      bDriveHeadReg   :
    =   $A0;  
      bCommandReg   :
    =   $EC;  
     
    end;  
     
    end;  
     
    if   not   DeviceIoControl(hDevice,   $0007C088,   @SCIP,   SizeOf(TSendCmdInParams)   -   1,  
      @aIdOutCmd,   SizeOf(aIdOutCmd),   cbBytesReturned,  
    nil)   then   Exit;  
      finally  
      CloseHandle(hDevice);  
     
    end;  
     
    with   PIdSector(@IdOutCmd.bBuffer)^   do   begin  
      ChangeByteOrder(sSerialNumber,   SizeOf(sSerialNumber));  
      (Pchar(@sSerialNumber)  
    +   SizeOf(sSerialNumber))^:=   #0;  
      Result   :
    =   Pchar(@sSerialNumber);  
     
    end;  
     
    end;
  286. end.

抱歉!评论已关闭.