请问WinNT/2000/XP下如何获得BIOS信息,非得用VXD吗?不要告诉我用下面的代码,这些在WinNT/2000/XP不管用的。
with Memo1.Lines do 
begin 
Add('MainBoardBiosName:'+^I+string(Pchar(Ptr($FE061)))); 
Add('MainBoardBiosCopyRight:'+^I+string(Pchar(Ptr($FE091)))); 
Add('MainBoardBiosDate:'+^I+string(Pchar(Ptr($FFFF5)))); 
Add('MainBoardBiosSerialNo:'+^I+string(Pchar(Ptr($FEC71)))); 
end;

解决方案 »

  1.   

    不知道用Director是不是可以?
    这是我多猜的!其实帮你UP一下!
      

  2.   

    一个例子:
    (******************************************************************************* 
    *                                                                              * 
    * BIOS Help - read ROM BIOS on Windows 95/98/SE/ME/NT/2K/XP                    * 
    *                                                                              * 
    * Copyright (C) 2001, Nico Bendlin ([email protected])                           * 
    *                                                                              * 
    * Compiler: Delphi 4.03/5.01/6.00                                              * 
    * Version: 1.03, 2001-09-02                                                    * 
    *                                                                              * 
    *******************************************************************************) { postum scriptum: sorry for the bad english, i wrote it in a hurry } 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 {############################################################################### 
    #                                                                              # 
    #                             GENERIC METHOD                                   # 
    #                                                                              # 
    # Create an temporary folder, save an 16bit COM program (RomDump.com) into it, # 
    # execute program redirected to an file (Rom.dmp, RomDump.com simply dumps the # 
    # memory range F000:0000-F000:FFFF to STDOUT), read dump file into the buffer, # 
    # and finally cleanup all temporary files and directories.                     # 
    #                                                                              # 
    # (the function RomDumpCode is x86 specific, which i wrote to generate 16-bit  # 
    #  code with the help of the 23-bit Delphi compiler, never try to execute the  # 
    #  pseudo-code in your program! it will not work in 32-bit protected mode)     # 
    #                                                                              # 
    ###############################################################################} { *INTERNAL* - Pseudo 16-bit code } 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; 
      

  3.   


    { *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; {############################################################################### 
    #                                                                              # 
    #                           DIRECT METHOD (Win9x)                              # 
    #                                                                              # 
    # Due to the fact that Windows 95/98/ME maps the BIOS into every Win32 process # 
    # for read access it is very simple to fill the buffer from memory.            # 
    #                                                                              # 
    ###############################################################################} 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; {############################################################################### 
    #                                                                              # 
    #                       PHYSICAL MEMORY METHOD (WinNT)                         # 
    #                                                                              # 
    # On Windows NT the ROM BIOS is only available through the named kernel object # 
    # '\Device\PhysicalMemory'. Because it is impossible to open kernel objects in # 
    # user mode with standard Win32 API functions we make use of NT's nativeAPI in # 
    # NtDll.dll ("NT-Layer") namely ZwOpenSection.                                 # 
    #                                                                              # 
    # (note: mostly there are two versions of every function ZwXxx and NtXxx. The  # 
      

  4.   

    #  only difference in kernel mode is that the NtXxx version works in conside-  # 
    #  ration to security while ZwXxx not. But in user mode both work like NtXxx.) # 
    #                                                                              # 
    # At first the section is opened with ZwOpenSection. Normally we would proceed # 
    # ZwMapViewOfSection, ZwUnmapViewOfSection, and NtClose. But the functions are # 
    # more complex and there is no needing for it. With the handle (because we are # 
    # in the "very simple" user mode =) we now use MapViewOfFile, UnmapViewOfFile, # 
    # and CloseHandle to map an memory window (the ROM BIOS) into our process.     # 
    #                                                                              # 
    # Due to the fact that ZwOpenSection returns NT error-codes in case of failure # 
    # we have to translate it to an Win32 error-code (RtlNtStatusToDosError).      # 
    # All NT specific functions are dynamically loaded -- because the applications # 
    # should start on Win9x systems =)                                             # 
    #                                                                              # 
    ###############################################################################} { 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; 
    {############################################################################### 
    #                                                                              # 
    #                               ReadRomBios                                    # 
    #                                                                              # 
    ###############################################################################} 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; {############################################################################### 
    #                                                                              # 
    #     Utilities to simplify the access to data as generic standard types       # 
    #                                                                              # 
    ###############################################################################} function GetRomBiosBuffer(const Dump: TRomBiosDump; Address: Pointer; 
      var Buffer; BufferSize: Cardinal): Cardinal; 
    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; 
      

  5.   

    VXD只能在Win9X里用,要通用用WDM,嵌入ASM
      

  6.   

    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; 
    这几个函数怎么使用啊?
      

  7.   

    如果你试着去理解上面代码的意思,很容易知道怎么使用你自己代码中的String(Pchar(Ptr($FE061)))什么意思?意思是将内存地址$FE061中的内容转化为字符串,因为计算机启动后会将相关BIOS信息复制到内存中,Win9x下可以直接获得相关内容!而NT下需要打开内核对象,把文件视图映射到进程地址空间!在16位系统下,上面的代码是动态生成了一个COM文件(文件内容用嵌入ASM写成)去获得相关信息,并将信息保存在一个临时文件中!所以可以看出得到相关信息用上面的
    var
      RBD: TRomBiosDump;GetRomBiosString(RBD, Ptr($FE061));即可当然你可能有一点不是很清楚,上面的地址只是针对Award的BIOS芯片而言如果是AMI的,地址不一样BIOS 序列号:$FF478
    BIOS 日期:$FFFF5
    BIOS copyright:$FE0CB还有其它如Phoenix BIOS ,自己用上面的方法导出全部BIOS信息分析得出
      

  8.   

    var
      RBD: TRomBiosDump;
      Str: String;ReadRomBios(RBD, rrbmAutomatic)
    Str:=GetRomBiosString(RBD, Ptr($FE061));