|
@@ -33,142 +33,6 @@ implementation
|
|
|
uses
|
|
|
CmnFunc2, FileClass;
|
|
|
|
|
|
-function GetVXDVersionInfo(const Filename: String;
|
|
|
- var VersionInfo: TVSFixedFileInfo): Boolean;
|
|
|
-{ Gets the version info from a VXD file. Returns True if successful.
|
|
|
- Note: The code in this function is based on the code in the MS KB article
|
|
|
- Q201685.
|
|
|
- Known issue: This function fails if the version resource has a name
|
|
|
- (TVXDVersionResource.cName <> $FF). It's rare, but such VXDs do exist --
|
|
|
- see Windows 98's MSGAME.VXD for example. Given that as of 2007 Windows 9x
|
|
|
- is mostly obsolete, I don't plan on fixing this. }
|
|
|
-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: Byte;
|
|
|
- wID: Word;
|
|
|
- cName: Byte;
|
|
|
- wOrdinal: Word;
|
|
|
- wFlags: Word;
|
|
|
- dwResSize: DWORD;
|
|
|
- end;
|
|
|
-var
|
|
|
- F: TFile;
|
|
|
- DosHeader: packed record
|
|
|
- Sig: Word;
|
|
|
- Other: array[0..57] of Byte;
|
|
|
- VXDHeaderOffset: DWORD;
|
|
|
- end;
|
|
|
- VXDHeader: TImageVXDHeader;
|
|
|
- VXDVersionRes: TVXDVersionResource;
|
|
|
- RootNode: packed record
|
|
|
- cbNode: Word;
|
|
|
- cbData: Word;
|
|
|
- szKey: array[0..15] of AnsiChar; { should always be 'VS_VERSION_INFO'#0 }
|
|
|
- Value: TVSFixedFileInfo;
|
|
|
- end;
|
|
|
-begin
|
|
|
- Result := False;
|
|
|
- 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
|
|
|
- (DosHeader.Sig <> IMAGE_DOS_SIGNATURE) or
|
|
|
- (DosHeader.VXDHeaderOffset = 0) then
|
|
|
- Exit;
|
|
|
-
|
|
|
- { VXD header }
|
|
|
- F.Seek(DosHeader.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 (VXDVersionRes.cType <> $FF) or
|
|
|
- (VXDVersionRes.wID <> 16) or { RT_VERSION? }
|
|
|
- (VXDVersionRes.cName <> $FF) then
|
|
|
- Exit; { we don't support non-ordinal types/names (see "Known issue") }
|
|
|
- if Cardinal(VXDVersionRes.dwResSize) < Cardinal(SizeOf(RootNode)) then
|
|
|
- Exit; { sanity check }
|
|
|
- F.ReadBuffer(RootNode, SizeOf(RootNode));
|
|
|
- if (RootNode.cbNode >= SizeOf(RootNode)) and
|
|
|
- (RootNode.cbData >= SizeOf(RootNode.Value)) and
|
|
|
- (RootNode.Value.dwSignature = VS_FFI_SIGNATURE) then begin
|
|
|
- VersionInfo := RootNode.Value;
|
|
|
- Result := True;
|
|
|
- end;
|
|
|
- finally
|
|
|
- F.Free;
|
|
|
- end;
|
|
|
- except
|
|
|
- { don't propagate exceptions }
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
function GetVersionInfo(const Filename: String;
|
|
|
var VersionInfo: TVSFixedFileInfo): Boolean;
|
|
|
var
|
|
@@ -193,9 +57,6 @@ begin
|
|
|
finally
|
|
|
FreeMem(VersionBuf);
|
|
|
end;
|
|
|
- end else begin
|
|
|
- { Windows' version APIs don't support VXDs, so use our own code to handle them }
|
|
|
- Result := GetVXDVersionInfo(Filename, VersionInfo);
|
|
|
end;
|
|
|
end;
|
|
|
|