⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 verinfo.pas

📁 源代码
💻 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 + -