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 # # 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;
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.
========================================== 4、获取BIOS日期信息
{--------------------------------------------------------------------------} {获取BIOS的日期信息,估计可能在2000下适用,但是可能需要获取权限} function GetBiosDate1: String; var Buffer: Array[0..8] Of Char; N: DWORD; begin ReadProcessMemory(GetCurrentProcess, Ptr($FFFF5), @Buffer, 8, N); Buffer[8] := #0; result := StrPas(Buffer) end;
function GetBiosDate2: String; begin result := string(pchar(ptr($FFFF5))); end; 上一页 [1] [2] |