如何获取电脑的机器码呀?怎样获取网卡的物理地址?

解决方案 »

  1.   

    function LanCardID: string;//获取网卡物理地址
    var guid: TGUID;
        i: integer;
    begin
       result := '';
       CoCreateGUID(guid);
       for i := Low(guid.D4)+2 to High(guid.D4) do
       begin
          result := result + IntToHex(guid.D4[i],2);
       end;
    end;
      

  2.   

    *      这个模块是用来获取CPU、硬盘序列号,CPU的*
    *                                              *
    *   速率、显示器的刷新率网卡的MAC地址等信息    *Unit HardInfo;interfaceuses 
       Windows,SysUtils,Nb30;const
       ID_BIT = $200000; // EFLAGS ID bittype 
       TCPUID = array[1..4] of Longint;
       TVendor = array [0..11] of char;
       
       function IsCPUID_Available : Boolean; register;       //判断CPU序列号是否可用函数
       function GetCPUID: TCPUID; assembler; register;       //获取CPU序列号函数
       function GetCPUVendor: TVendor; assembler; register;  //获取CPU生产厂家函数
       function GetCPUInfo: string;                          //CPU序列号(格式化成字符串)
       function GetCPUSpeed: Double;                         //获取CPU速度函数
       function GetDisplayFrequency: Integer;                //获取显示器刷新率
       function GetIdeSerialNumber: pchar;                   //获取IDE硬盘序列号函数
       function MonthMaxDay(year,month:integer):Integer;     //获取某年某月的最大天数
       function GetAdapterMac(ANo:Integer):String;implementation   function IsCPUID_Available : Boolean; register;
       asm
        PUSHFD {direct access to flags no possible, only via stack}
        POP EAX {flags to EAX}
        MOV EDX,EAX {save current flags}
        XOR EAX,ID_BIT {not ID bit}
        PUSH EAX {onto stack}
        POPFD {from stack to flags, with not ID bit}
        PUSHFD {back to stack}
        POP EAX {get back to EAX}
        XOR EAX,EDX {check if ID bit affected}
        JZ @exit {no, CPUID not availavle}
        MOV AL,True {Result=True}
        @exit:
      end;  function GetCPUID: TCPUID; assembler; register;
        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;   function GetCPUVendor : TVendor; assembler; register;
      //获取CPU生产厂家函数
      //调用方法:EDIT.TEXT:='Current CPU Vendor:'+GetCPUVendor;
        asm
          PUSH EBX {Save affected register}
          PUSH EDI
          MOV EDI,EAX {@Result (TVendor)}
          MOV EAX,0
          DW $A20F {CPUID Command}
          MOV EAX,EBX
          XCHG EBX,ECX {save ECX result}
          MOV ECX,4
          @1:
          STOSB
          SHR EAX,8
          LOOP @1
          MOV EAX,EDX
          MOV ECX,4
          @2:
          STOSB
          SHR EAX,8
          LOOP @2
          MOV EAX,EBX
          MOV ECX,4
          @3:
          STOSB
          SHR EAX,8
          LOOP @3
          POP EDI {Restore registers}
          POP EBX
        end;  function GetCPUInfo: string;
      var
        CPUID: TCPUID;
            I: Integer;
            S: TVendor;
      begin
        for I:=Low(CPUID) to High(CPUID) do CPUID[I]:=-1;
        if IsCPUID_Available then
          begin
             CPUID:= GetCPUID;
             S:=GetCPUVendor;
             Result:= IntToHex(CPUID[1], 8)
                     +'-'+ IntToHex(CPUID[2], 8)
                     +'-'+ IntToHex(CPUID[3], 8)
                     +'-'+ IntToHex(CPUID[4], 8);
          end
        else Result:='CPUID not available';
      end;  
     function GetCPUSpeed: Double;
     //获取CPU速率函数
     //调用方法:EDIT.TEXT:='Current CPU Speed:'+floattostr(GetCPUSpeed)+'MHz';
     const
      DelayTime = 500; // 时间单位是毫秒
     var
      TimerHi, TimerLo: DWORD;
      PriorityClass, Priority: Integer;
     begin
         PriorityClass := GetPriorityClass(GetCurrentProcess);
         Priority := GetThreadPriority(GetCurrentThread);
         SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
         SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
         Sleep(10);
         asm
            dw 310Fh // rdtsc
            mov TimerLo, eax
            mov TimerHi, edx
         end;
         Sleep(DelayTime);
         asm
            dw 310Fh // rdtsc 
            sub eax, TimerLo 
            sbb edx, TimerHi
            mov TimerLo, eax
            mov TimerHi, edx
         end;     SetThreadPriority(GetCurrentThread, Priority);
         SetPriorityClass(GetCurrentProcess, PriorityClass);
         Result := TimerLo / (1000.0 * DelayTime);
     end; function GetDisplayFrequency: Integer;
     // 这个函数返回的显示刷新率是以Hz为单位的
     //调用方法:EDIT.TEXT:='Current DisplayFrequency:'+inttostr(GetDisplayFrequency)+' Hz';
     var
        DeviceMode: TDeviceMode;
     begin
       EnumDisplaySettings(nil, Cardinal(-1), DeviceMode);
       Result := DeviceMode.dmDisplayFrequency;
     end;
      

  3.   


      function GetIdeSerialNumber : pchar;
      //获取第一个IDE硬盘的序列号
      //调用方法:EDIT.TEXT:='HardDriver SerialNumber:'+strpas(GetIdeSerialNumber);
      const IDENTIFY_BUFFER_SIZE = 512;
      type
       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;
      TSendCmdInParams = packed record
        // Buffer size in bytes
        cBufferSize  : DWORD;
        // Structure with drive register values.
        irDriveRegs  : TIDERegs;
        // Physical drive number to send command to (0,1,2,3).
        bDriveNumber : BYTE;
        bReserved    : Array[0..2] of Byte;
        dwReserved   : Array[0..3] of DWORD;
        bBuffer      : Array[0..0] of Byte;  // Input buffer.
      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
        // 驱动器返回的错误代码,无错则返回0
        bDriverError : Byte;
        // IDE出错寄存器的内容,只有当bDriverError 为 SMART_IDE_ERROR 时有效
        bIDEStatus   : Byte;
        bReserved    : Array[0..1] of Byte;
        dwReserved   : Array[0..1] of DWORD;
      end;
      TSendCmdOutParams = packed record
        // bBuffer的大小
        cBufferSize  : DWORD;
        // 驱动器状态
        DriverStatus : TDriverStatus;
        // 用于保存从驱动器读出的数据的缓冲区,实际长度由cBufferSize决定
        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
            // 提示! 改变名称可适用于其它驱动器,如第二个驱动器: '\\.\PhysicalDrive1\'
            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;
          // Set up data structures for IDENTIFY command.
          with SCIP do begin
            cBufferSize  := IDENTIFY_BUFFER_SIZE;
      //      bDriveNumber := 0;
            with irDriveRegs do begin
              bSectorCountReg  := 1;
              bSectorNumberReg := 1;
      //      if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0
      //      else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
              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;
        // 更多关于 S.M.A.R.T. ioctl 的信息可查看:
        // http://www.microsoft.com/hwdev/download/respec/iocltapi.rtf
        // MSDN库中也有一些简单的例子
        // Windows Development -> Win32 Device Driver Kit ->
        // SAMPLE: SmartApp.exe Accesses SMART stats in IDE drives
        // 还可以查看 http://www.mtgroup.ru/~alexk
        // IdeInfo.zip - 一个简单的使用了S.M.A.R.T. Ioctl API的Delphi应用程序
        // 注意:
        // WinNT/Win2000 - 你必须拥有对硬盘的读/写访问权限
        // Win98
        // SMARTVSD.VXD 必须安装到 \windows\system\iosubsys
        // (不要忘记在复制后重新启动系统)
      end;  function MonthMaxDay(Year,Month:Integer) : Integer ;    //获取某年某月最大天数
      begin
        Case Month of
           1,3,5,7,8,10,12:  Result:=31;  //如是1、3、5、7、8、10、12则最大为31天
           2: if (Year mod 4=0) and (Year mod 100<>0) or (Year mod 400=0) then Result:=29
              else Result:=28;    //如是闰年2月则29天,否则2月最大为28天
           else Result:=30;       //其它的4、6、9、11则最大天数为30天
        end;
      end;  
      function GetAdapterMac(ANo:Integer):String;
      //获取网卡的MAC地址
      var
         Ncb:TNcb;
         Adapter:TAdapterStatus;
         Lanaenum:TLanaenum;
         IntIdx:Integer; //
         cRc:Char;
         StrTemp:String;
      begin
        Result:='';
        Try
           ZeroMemory(@Ncb,SizeOf(Ncb));
           Ncb.ncb_command:=Chr(NCbenum);
           NetBios(@NCb);
           Ncb.ncb_buffer:=@Lanaenum; //再处理enum命令
           Ncb.ncb_length:=SizeOf(Lanaenum);
           cRc:=NetBios(@Ncb);
           if Ord(cRc)<>0 then exit;
           ZeroMemory(@Ncb,SizeOf(Ncb)); //适配器清零
           Ncb.ncb_command:=Chr(NcbReset);
           Ncb.ncb_lana_num:=Lanaenum.lana[aNo];
           cRc:=NetBios(@Ncb);
           if Ord(cRc)<>0 then exit;
           //得到适配器状态
           ZeroMemory(@Ncb,SizeOf(Ncb));
           Ncb.ncb_command:=Chr(NcbAstat);
           Ncb.ncb_lana_num:=Lanaenum.lana[aNo];
           StrPcopy(Ncb.ncb_callname,'*');
           Ncb.ncb_buffer:=@Adapter;
           Ncb.ncb_length:=SizeOf(Adapter);
           NetBios(@Ncb);
           //将mac地址转换成字符串输出
           StrTemp:='';
           For IntIdx:=0 to 5 do
           StrTemp:=StrTemp+IntToHex(Integer(Adapter.adapter_address[intIdx]),2);
           Result:=StrTemp;
        finally
        end;
    end;end.