在windows 98下我用Pchar(Ptr($FEC71))取得主板的serial No,但这在windows2000下是绝对不行的, 请问如何在windows 2000下取得主板序列号???

解决方案 »

  1.   

    可以用以下控件:
    MiTeC System Information Component Package   version 7.62 2421KB 
    http://www.mitec.d2.cz/Downloads/MSI.zip
      

  2.   

    转贴:
    两个单元:在98/me/2000/xp测试通过。
    biosHelp.pas:
    unit BiosHelp;
    {$ALIGN ON}
    {$MINENUMSIZE 4}
    interface
    uses
      Windows;
    type
      PRomBiosDump = ^TRomBiosDump;
      TRomBiosDump = array [$000F0000..$000FFFFF] of Byte;
    type
      TReadRomBiosMethod = (
        rrbmAutomatic, { Autodetect OS type and use proper method }
        rrbmGeneric,   { Use 16-bit COM program to dump the BIOS  }
        rrbmMemory,    { Read from memory (Win9x)                 }
        rrbmPhysical   { Read from physical memory object (WinNT) }
      );
    function ReadRomBios(var Dump: TRomBiosDump; Method: TReadRomBiosMethod;
      Timeout: DWORD = INFINITE): Boolean;
    function GetRomBiosBuffer(const Dump: TRomBiosDump; Address: Pointer;
      var Buffer; BufferSize: Cardinal): Cardinal;
    function GetRomBiosString(const Dump: TRomBiosDump; Address: Pointer): string;
    function GetRomBiosLongLong(const Dump: TRomBiosDump; Address: Pointer):
    LONGLONG;
    function GetRomBiosDWord(const Dump: TRomBiosDump; Address: Pointer): DWORD;
    function GetRomBiosWord(const Dump: TRomBiosDump; Address: Pointer): Word;
    function GetRomBiosByte(const Dump: TRomBiosDump; Address: Pointer): Byte;
    implementation
    type
      PRomDumpCodeInfo = ^TRomDumpCodeInfo;
      TRomDumpCodeInfo = (rdciStart, rdciEnd, rdciSize);
    function _RomDumpCode(Info: TRomDumpCodeInfo): Pointer;
    var
      CodeStart: Pointer;
      CodeEnd: Pointer;
    begin
      asm
              JMP     @@End          { *BEGIN* 16-bit code  }
              { -- never use it in your program! -- }
              { COM which writes ROM-BIOS to StdOut }
      @@Start:
              { Dump F000:0000-F000:FFFE }
              XOR     eDX, eDX  // DS = 0xF000   ; Data segment
              MOV     DH, 0F0h
              MOV     DS, eDX
              XOR     eDX, eDX  // DX = 0x0000   ; Data offset
              XOR     eCX, eCX  // CX = 0xFFFF   ; Data length
              DEC     eCX
              XOR     eBX, eBX  // BX = 0x0001   ; STDOUT (file handle)
              INC     eBX
              MOV     AH, 40h   // DosCall(0x40) ; INT21, DOS_WRITE_TO_HANDLE
              INT     21h
              JC      @@Exit    // On error exit ; AL = Error code
              { Dump F000:FFFF }
              XOR     eDX, eDX  // DS = 0xF000   ; Data segment
              MOV     DH, 0F0h
              MOV     DS, eDX
              XOR     eDX, eDX  // DX = 0xFFFF   ; Data offset
              DEC     eDX
              XOR     eCX, eCX  // CX = 0x0001   ; Data length
              INC     eCX
              MOV     eBX, eCX  // BX = 0x0001   ; STDOUT (file handle)
              MOV     AH, 40h   // DosCall(0x40) ; INT21, DOS_WRITE_TO_HANDLE
              INT     21h
              JC      @@Exit    // On error exit ; AL = Error code
              MOV     AL, 0     // no error      ; AL = 0
      @@Exit:
              MOV     AH, 4Ch   // DosCall(0x4C) ; INT21, DOS_TERMINATE_EXE
              INT     21h
      @@End:
              { *END* 16-bit code  }          MOV     CodeStart, OFFSET @@Start
              MOV     CodeEnd, OFFSET @@End
      end;
      case Info of
        rdciStart:
          Result := CodeStart;
        rdciEnd:
          Result := CodeEnd;
        rdciSize:
          Result := Pointer(Cardinal(CodeEnd) - Cardinal(CodeStart));
      else
        Result := nil;
      end;
    end;{ *INTERNAL* - Save 16-bit code to file }function _RomDumpCodeToFile(const Filename: string): Boolean;
    var
      ComFile: THandle;
      Size: Cardinal;
    begin
      Result := False;
      ComFile := CreateFile(PChar(Filename), GENERIC_WRITE, FILE_SHARE_READ, nil,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
      if ComFile <> INVALID_HANDLE_VALUE then
      try
        Result := WriteFile(ComFile, _RomDumpCode(rdciStart)^,
          Cardinal(_RomDumpCode(rdciSize)), Size, nil) and
          (Size = Cardinal(_RomDumpCode(rdciSize)));
        if not Result then
          DeleteFile(PChar(Filename));
      finally
        CloseHandle(ComFile);
      end;
    end;{ *INTERNAL* - Execute 16-bit code redirected to file }function _RomDumpCodeExecute(const Com, Dmp: string; Timeout: DWORD): Boolean;
    var
      ComSpec: string;
      si: TStartupInfo;
      pi: TProcessInformation;
    begin
      Result := False;
      SetLength(ComSpec, MAX_PATH);
      SetLength(ComSpec,
        GetEnvironmentVariable('ComSpec', PChar(@ComSpec[1]), MAX_PATH));
      if Length(ComSpec) > 0 then
      begin
        FillChar(si, SizeOf(TStartupInfo), 0);
        si.cb := SizeOf(TStartupInfo);
        si.dwFlags := STARTF_USESHOWWINDOW;
        si.wShowWindow := SW_HIDE;
        if CreateProcess(nil, PChar(ComSpec + ' /C ' + Com + ' > ' + Dmp),
          nil, nil, False, CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP, nil,
          nil, si, pi) then
        try
          Result := WaitForSingleObject(pi.hProcess, Timeout) <> WAIT_TIMEOUT;
        finally
          CloseHandle(pi.hProcess);
          CloseHandle(pi.hThread);
        end;
      end;
    end;function DirectoryExists(const Dir: string): Boolean;
    var
      Attr: DWORD;
    begin
      Attr := GetFileAttributes(PChar(Dir));
      Result := (Attr <> $FFFFFFFF) and
        (Attr and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY);
    end;{ Get BIOS dump the generic way }function ReadRomBios16(var Buffer: TRomBiosDump; Timeout: DWORD): Boolean;
    const
      TempSub = '~RomDmp';
      ComName = 'RomDump.com';
      DmpName = 'Rom.dmp';
    var
      TempPath: string;
      TempDir: string;
      TempIdx: Integer;
      TempIdxStr: string;
      ComFile: string;
      DmpFile: string;
      DmpHandle: THandle;
      Written: DWORD;
    begin
      Result := False;
      SetLength(TempPath, MAX_PATH);
      SetLength(TempPath, GetTempPath(MAX_PATH, PChar(@TempPath[1])));
      if Length(TempPath) > 0 then
      begin
        if (TempPath[Length(TempPath)] <> '\') then
          TempPath := TempPath + '\';
        TempIdx := 0;
        repeat
          Inc(TempIdx);
          Str(TempIdx, TempIdxStr);
          TempDir := TempPath + TempSub + TempIdxStr;
        until not DirectoryExists(TempDir);
        if CreateDirectory(PChar(TempDir), nil) then
        try
          TempDir := TempDir + '\';
          ComFile := TempDir + ComName;
          DmpFile := TempDir + DmpName;
          if _RomDumpCodeToFile(ComFile) then
          try
            if _RomDumpCodeExecute(ComFile, DmpFile, Timeout) then
            begin
              DmpHandle := CreateFile(PChar(DmpFile), GENERIC_READ,
                FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
              if DmpHandle <> INVALID_HANDLE_VALUE then
              try
                FillChar(Buffer, SizeOf(TRomBiosDump), 0);
                Result := ReadFile(DmpHandle, Buffer, SizeOf(TRomBiosDump),
                  Written, nil) and (Written = SizeOf(TRomBiosDump));
              finally
                CloseHandle(DmpHandle);
              end;
            end;
          finally
            DeleteFile(PChar(DmpFile));
            DeleteFile(PChar(ComFile));
          end;
        finally
          RemoveDirectory(PChar(TempDir));
        end;
      end;
    end;
      

  3.   


    function ReadRomBios9x(var Buffer: TRomBiosDump): Boolean;
    begin
      Result := False;
      try
        FillChar(Buffer, SizeOf(TRomBiosDump), 0);
        Move(Pointer(Low(TRomBiosDump))^, Buffer, SizeOf(TRomBiosDump));
        Result := True;
      except
        // ignore exceptions
      end
    end;{ For more information see Windows 2000/XP DDK  }
    { It works on Windows NT 4.0 too, use NtDll.dll }
    type
      NTSTATUS = Integer;const
      STATUS_SUCCESS        = NTSTATUS(0);
      STATUS_INVALID_HANDLE = NTSTATUS($C0000008);
      STATUS_ACCESS_DENIED  = NTSTATUS($C0000022);type
      PUnicodeString = ^TUnicodeString;
      TUnicodeString = packed record
        Length: Word;
        MaximumLength: Word;
        Buffer: PWideChar;
      end;const
      OBJ_INHERIT          = $00000002;
      OBJ_PERMANENT        = $00000010;
      OBJ_EXCLUSIVE        = $00000020;
      OBJ_CASE_INSENSITIVE = $00000040;
      OBJ_OPENIF           = $00000080;
      OBJ_OPENLINK         = $00000100;
      OBJ_KERNEL_HANDLE    = $00000200;
      OBJ_VALID_ATTRIBUTES = $000003F2;type
      PObjectAttributes = ^TObjectAttributes;
      TObjectAttributes = record
        Length: ULONG;
        RootDirectory: THandle;
        ObjectName: PUnicodeString;
        Attributes: ULONG;
        SecurityDescriptor: PSecurityDescriptor;
        SecurityQualityOfService: PSecurityQualityOfService;
      end;const
      ObjectPhysicalMemoryDeviceName = '\Device\PhysicalMemory';
      ObjectPhysicalMemoryName: TUnicodeString = (
        Length: Length(ObjectPhysicalMemoryDeviceName) * 2;
        MaximumLength: Length(ObjectPhysicalMemoryDeviceName) * 2 + 2;
        Buffer: ObjectPhysicalMemoryDeviceName;
      );
      ObjectPhysicalMemoryAccessMask: ACCESS_MASK = SECTION_MAP_READ;
      ObjectPhysicalMemoryAttributes: TObjectAttributes =(
        Length: SizeOf(TObjectAttributes);
        RootDirectory: 0;
        ObjectName: @ObjectPhysicalMemoryName;
        Attributes: OBJ_CASE_INSENSITIVE;
        SecurityDescriptor: nil;
        SecurityQualityOfService: nil;
      );type
      TFNZwOpenSection = function(out SectionHandle: THandle;
        DesiredAccess: ACCESS_MASK; ObjectAttributes: PObjectAttributes): NTSTATUS;
    stdcall;
      TFNRtlNtStatusToDosError = function(Status: NTSTATUS): DWORD; stdcall;const
      ntdll = 'ntdll.dll';var
      ZwOpenSection: TFNZwOpenSection;
      RtlNtStatusToDosError: TFNRtlNtStatusToDosError;function ReadRomBiosNt(var Buffer: TRomBiosDump; Timeout: DWORD): Boolean;
    var
      NtLayer: HMODULE;
      Status: NTSTATUS;
      Section: THandle;
      View: Pointer;
    begin
      Result := False;
      NtLayer := GetModuleHandle(ntdll);
      if NtLayer = 0 then
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED)
      else
      begin
        if not Assigned(ZwOpenSection) then
          ZwOpenSection := GetProcAddress(NtLayer, 'ZwOpenSection');
        if not Assigned(RtlNtStatusToDosError) then
          RtlNtStatusToDosError := GetProcAddress(NtLayer,
    'RtlNtStatusToDosError');
        if not (Assigned(ZwOpenSection) and Assigned(RtlNtStatusToDosError)) then
          SetLastError(ERROR_CALL_NOT_IMPLEMENTED)
        else
        begin
          Status := ZwOpenSection(Section, ObjectPhysicalMemoryAccessMask,
            @ObjectPhysicalMemoryAttributes);
          case Status of
            STATUS_SUCCESS:
              try
                View := MapViewOfFile(Section, ObjectPhysicalMemoryAccessMask, 0,
                  Low(TRomBiosDump), SizeOf(TRomBiosDump));
                if Assigned(View) then
                try
                  FillChar(Buffer, SizeOf(TRomBiosDump), 0);
                  Move(View^, Buffer, SizeOf(TRomBiosDump));
                  Result := True;
                finally
                  UnmapViewOfFile(View);
                end;
              finally
                CloseHandle(Section);
              end;
            STATUS_ACCESS_DENIED:
              Result := ReadRomBios16(Buffer, Timeout);
          else
            SetLastError(RtlNtStatusToDosError(Status))
          end;
        end;
      end;
    end;
    function ReadRomBios(var Dump: TRomBiosDump; Method: TReadRomBiosMethod;
      Timeout: DWORD = INFINITE): Boolean;
    begin
      Result := False;
      case Method of
        rrbmAutomatic:
          if (Integer(GetVersion) < 0) then
          try
            Result := ReadRomBios9x(Dump);
          except
            Result := ReadRomBios16(Dump, Timeout);
          end
          else
            Result := ReadRomBiosNt(Dump, Timeout);
        rrbmGeneric:
          Result := ReadRomBios16(Dump, Timeout);
        rrbmMemory:
          Result := ReadRomBios9x(Dump);
        rrbmPhysical:
          Result := ReadRomBiosNt(Dump, Timeout);
      else
        SetLastError(ERROR_INVALID_PARAMETER);
      end;
    end;function GetRomBiosBuffer(const Dump: TRomBiosDump; Address: Pointer;
      var Buffer; BufferSize: Cardinal): Cardinal;
      //Dump就是 ReadRomBios 读出来的数组,
    //Address就是起始的读取的地址,BufferSize就是你要读取的大小。
    begin
      Result := 0;
      if (Cardinal(Address) >= Low(TRomBiosDump)) and
        (Cardinal(Address) <= High(TRomBiosDump)) then
      begin
        Result := BufferSize;
        if (Cardinal(Address) + BufferSize > High(TRomBiosDump)) then
          Result := High(TRomBiosDump) - Cardinal(Address) + 1;
        Move(Dump[Cardinal(Address)], Buffer, Result);
      end;
    end;function GetRomBiosString(const Dump: TRomBiosDump; Address: Pointer): string;
    begin
      Result := '';
      if (Cardinal(Address) >= Low(TRomBiosDump)) and
        (Cardinal(Address) <= High(TRomBiosDump)) then
        Result := string(PChar(@Dump[Cardinal(Address)]));
    end;function GetRomBiosLongLong(const Dump: TRomBiosDump; Address: Pointer):
    LONGLONG;
    type
      PLongLong = ^LONGLONG;
    begin
      Result := 0;
      if (Cardinal(Address) >= Low(TRomBiosDump)) and
        (Cardinal(Address) <= High(TRomBiosDump) - SizeOf(LONGLONG) + 1) then
        Result := PLongLong(@Dump[Cardinal(Address)])^;
    end;function GetRomBiosDWord(const Dump: TRomBiosDump; Address: Pointer): DWORD;
    begin
      Result := 0;
      if (Cardinal(Address) >= Low(TRomBiosDump)) and
        (Cardinal(Address) <= High(TRomBiosDump) - SizeOf(DWORD) + 1) then
        Result := PDWORD(@Dump[Cardinal(Address)])^;
    end;function GetRomBiosWord(const Dump: TRomBiosDump; Address: Pointer): Word;
    begin
      Result := 0;
      if (Cardinal(Address) >= Low(TRomBiosDump)) and
        (Cardinal(Address) <= High(TRomBiosDump) - SizeOf(Word) + 1) then
        Result := PWord(@Dump[Cardinal(Address)])^;
    end;function GetRomBiosByte(const Dump: TRomBiosDump; Address: Pointer): Byte;
    begin
      Result := 0;
      if (Cardinal(Address) >= Low(TRomBiosDump)) and
        (Cardinal(Address) <= High(TRomBiosDump) - SizeOf(Byte) + 1) then
        Result := PByte(@Dump[Cardinal(Address)])^;
    end;end.对bioshelp调用单元:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Edit2: TEdit;
        Edit3: TEdit;
        Edit4: TEdit;
        Edit5: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementationuses bioshelp;
    {$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
    var
      RBD: TRomBiosDump;
    begin
      if ReadRomBios(RBD, rrbmAutomatic) then
      begin
        edit1.Text := GetRomBiosString(RBD, Ptr($ffff5));  // bios date
        edit2.Text := GetRomBiosString(RBD, Ptr($ffa68)); // bios name
        edit3.Text := GetRomBiosString(RBD, Ptr($fe061));  // bios version
        edit4.Text := GetRomBiosString(RBD, Ptr($FEC71));  // bios serial number
        edit5.Text := GetRomBiosString(RBD, Ptr($fe091));  // bios copyringht
      end
    end;
    end.
      

  4.   

    http://expert.csdn.net/Expert/topic/1404/1404676.xml
      

  5.   

    看看下面的控件吧取所有电脑硬件的序列号码:
    http://www.csdn.net/cnshare/soft/15/15890.shtm
    mac地址只要不是人为改,应该是全世界唯一的。
    不过这个版本只能在delphi6.0下使用。