📄 verinfo.pas
字号:
unit VerInfo;
{
Inno Setup
Copyright (C) 1997-2004 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Version info functions
$jrsoftware: issrc/Projects/VerInfo.pas,v 1.7 2004/02/28 18:32:08 jr Exp $
}
interface
uses
Windows, SysUtils;
{$I VERSION.INC}
type
TFileVersionNumbers = record
MS, LS: DWORD;
end;
function GetVersionInfo(const Filename: String;
var VersionInfo: TVSFixedFileInfo): Boolean;
function GetVersionNumbers(const Filename: String;
var VersionNumbers: TFileVersionNumbers): Boolean;
implementation
uses
CmnFunc2, FileClass;
function GetVXDVersionRes(const Filename: String): Pointer;
{ Gets the version info resource from a VXD file, suitable for passing to
VerQueryValue. Returns a allocated pointer on success (free it using FreeMem),
or nil on failure.
Note: The code in this function is based on the code in the MS KB article
Q201685. }
const
IMAGE_DOS_SIGNATURE = $5A4D; { MZ }
IMAGE_VXD_SIGNATURE = $454C; { LE }
type
PImageVXDHeader = ^TImageVXDHeader;
TImageVXDHeader = packed record
e32_magic: Word; // Magic number
e32_border: Byte; // The byte ordering for the VXD
e32_worder: Byte; // The word ordering for the VXD
e32_level: DWORD; // The EXE format level for now = 0
e32_cpu: Word; // The CPU type
e32_os: Word; // The OS type
e32_ver: DWORD; // Module version
e32_mflags: DWORD; // Module flags
e32_mpages: DWORD; // Module # pages
e32_startobj: DWORD; // Object # for instruction pointer
e32_eip: DWORD; // Extended instruction pointer
e32_stackobj: DWORD; // Object # for stack pointer
e32_esp: DWORD; // Extended stack pointer
e32_pagesize: DWORD; // VXD page size
e32_lastpagesize: DWORD; // Last page size in VXD
e32_fixupsize: DWORD; // Fixup section size
e32_fixupsum: DWORD; // Fixup section checksum
e32_ldrsize: DWORD; // Loader section size
e32_ldrsum: DWORD; // Loader section checksum
e32_objtab: DWORD; // Object table offset
e32_objcnt: DWORD; // Number of objects in module
e32_objmap: DWORD; // Object page map offset
e32_itermap: DWORD; // Object iterated data map offset
e32_rsrctab: DWORD; // Offset of Resource Table
e32_rsrccnt: DWORD; // Number of resource entries
e32_restab: DWORD; // Offset of resident name table
e32_enttab: DWORD; // Offset of Entry Table
e32_dirtab: DWORD; // Offset of Module Directive Table
e32_dircnt: DWORD; // Number of module directives
e32_fpagetab: DWORD; // Offset of Fixup Page Table
e32_frectab: DWORD; // Offset of Fixup Record Table
e32_impmod: DWORD; // Offset of Import Module Name Table
e32_impmodcnt: DWORD; // Number of entries in Import Module Name Table
e32_impproc: DWORD; // Offset of Import Procedure Name Table
e32_pagesum: DWORD; // Offset of Per-Page Checksum Table
e32_datapage: DWORD; // Offset of Enumerated Data Pages
e32_preload: DWORD; // Number of preload pages
e32_nrestab: DWORD; // Offset of Non-resident Names Table
e32_cbnrestab: DWORD; // Size of Non-resident Name Table
e32_nressum: DWORD; // Non-resident Name Table Checksum
e32_autodata: DWORD; // Object # for automatic data object
e32_debuginfo: DWORD; // Offset of the debugging information
e32_debuglen: DWORD; // The length of the debugging info. in bytes
e32_instpreload: DWORD; // Number of instance pages in preload section of VXD file
e32_instdemand: DWORD; // Number of instance pages in demand load section of VXD file
e32_heapsize: DWORD; // Size of heap - for 16-bit apps
e32_res3: array[0..11] of Byte; // Reserved words
e32_winresoff: DWORD;
e32_winreslen: DWORD;
e32_devid: Word; // Device ID for VxD
e32_ddkver: Word; // DDK version for VxD
end;
PVXDVersionResource = ^TVXDVersionResource;
TVXDVersionResource = packed record
cType: Char;
wID: Word;
cName: Char;
wOrdinal: Word;
wFlags: Word;
dwResSize: DWORD;
end;
var
F: TFile;
DosHeader: array[0..63] of Byte;
VXDHeaderOffset: Cardinal;
VXDHeader: TImageVXDHeader;
VXDVersionRes: TVXDVersionResource;
Data: Pointer;
begin
Result := nil;
try
if not NewFileExists(Filename) then
Exit;
F := TFile.Create(Filename, fdOpenExisting, faRead, fsRead);
try
{ DOS header }
if (F.Read(DosHeader, SizeOf(DosHeader)) <> SizeOf(DosHeader)) or
(Word((@DosHeader)^) <> IMAGE_DOS_SIGNATURE) then
Exit;
{ VXD header }
VXDHeaderOffset := DWORD(Pointer(Cardinal(@DosHeader) + 60)^);
F.Seek(VXDHeaderOffset);
if (F.Read(VXDHeader, SizeOf(VXDHeader)) <> SizeOf(VXDHeader)) or
(DWORD(Pointer(@VXDHeader)^) <> IMAGE_VXD_SIGNATURE) then
Exit;
if Cardinal(VXDHeader.e32_winreslen) <= Cardinal(SizeOf(VXDVersionRes)) then
Exit; { sanity check }
{ Resource }
F.Seek(VXDHeader.e32_winresoff);
F.ReadBuffer(VXDVersionRes, SizeOf(VXDVersionRes));
if Cardinal(VXDVersionRes.dwResSize) > Cardinal($100000) then
Exit; { sanity check }
GetMem(Data, VXDVersionRes.dwResSize);
try
F.ReadBuffer(Data^, VXDVersionRes.dwResSize);
except
FreeMem(Data);
raise;
end;
Result := Data;
finally
F.Free;
end;
except
{ don't propogate exceptions }
end;
end;
function GetVersionInfo(const Filename: String;
var VersionInfo: TVSFixedFileInfo): Boolean;
var
VersionSize: Integer;
VersionHandle: DWORD;
VersionBuf: PChar;
VerInfo: PVSFixedFileInfo;
VerInfoSize: UINT;
begin
Result := False;
VersionSize := GetFileVersionInfoSize(PChar(Filename), VersionHandle);
if VersionSize > 0 then begin
GetMem(VersionBuf, VersionSize);
try
if GetFileVersionInfo(PChar(Filename), VersionHandle, VersionSize, VersionBuf) then begin
if VerQueryValue(VersionBuf, '\', Pointer(VerInfo), VerInfoSize) then begin
VersionInfo := VerInfo^;
Result := True;
end;
end;
finally
FreeMem(VersionBuf);
end;
end
else if Win32Platform <> VER_PLATFORM_WIN32_WINDOWS then begin
{ NT's version APIs don't support VXDs, so use our own code to handle them }
VersionBuf := GetVXDVersionRes(Filename);
if Assigned(VersionBuf) then begin
try
if VerQueryValue(VersionBuf, '\', Pointer(VerInfo), VerInfoSize) then begin
VersionInfo := VerInfo^;
Result := True;
end;
finally
FreeMem(VersionBuf);
end;
end;
end;
end;
function GetVersionNumbers(const Filename: String;
var VersionNumbers: TFileVersionNumbers): Boolean;
var
VerInfo: TVSFixedFileInfo;
begin
Result := GetVersionInfo(Filename, VerInfo);
if Result then begin
VersionNumbers.MS := VerInfo.dwFileVersionMS;
VersionNumbers.LS := VerInfo.dwFileVersionLS;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -