@@ -13,7 +13,8 @@ interface
1313uses
1414 System.Classes,
1515 PE.Image,
16- PE.Resources;
16+ PE.Resources,
17+ PE.Resources.VersionInfo;
1718
1819{ Values for Windows PE. }
1920
@@ -77,8 +78,7 @@ interface
7778type
7879 TWindowsResourceTree = class
7980 private
80- function FindResourceInternal (lpType, lpName: PChar; Language: word;
81- Depth: cardinal): TResourceTreeNode;
81+ function FindResourceInternal (lpType, lpName: PChar; Language: word; Depth: cardinal): TResourceTreeNode;
8282 protected
8383 FResourceTree: TResourceTree;
8484 public
@@ -101,8 +101,16 @@ TWindowsResourceTree = class
101101 function RemoveResource (lpType, lpName: PChar; Language: word): Boolean;
102102 end ;
103103
104- function IsIntResource (lpszType: PChar): Boolean;
105- function GetIntResource (lpszType: PChar): word;
104+ function IsIntResource (lpszType: PChar): Boolean; inline;
105+ function GetIntResource (lpszType: PChar): word; inline;
106+ function MakeIntResource (wInteger: uint16): PChar; inline;
107+
108+ // See Windows GetFileVersionInfo function.
109+ // Find RT_VERSION raw data or nil if failed.
110+ // Don't Free returned stream because it's part of ResourceTree.
111+ function PeGetFileVersionInfo (img: TPEImage): TMemoryStream;
112+
113+ function PeVerQueryValueFixed (stream: TStream; out value : VS_FIXEDFILEINFO): Boolean;
106114
107115implementation
108116
@@ -119,6 +127,11 @@ function GetIntResource(lpszType: PChar): word; // inline;
119127 Result := NativeUInt(lpszType) and $FFFF;
120128end ;
121129
130+ function MakeIntResource (wInteger: uint16): PChar;
131+ begin
132+ Result := PChar(wInteger);
133+ end ;
134+
122135constructor TWindowsResourceTree.Create(ResourceTree: TResourceTree);
123136begin
124137 FResourceTree := ResourceTree;
@@ -241,4 +254,54 @@ procedure TWindowsResourceTree.UpdateResource(lpType, lpName: PChar;
241254 nLang.UpdateData(lpData, cbData);
242255end ;
243256
257+ function PeGetFileVersionInfo (img: TPEImage): TMemoryStream;
258+ var
259+ rt: TWindowsResourceTree;
260+ versionBranch: TResourceTreeBranchNode;
261+ versionLeaf: TResourceTreeLeafNode;
262+ begin
263+ rt := TWindowsResourceTree.Create(img.ResourceTree);
264+ try
265+ versionBranch := rt.FindResource(MakeIntResource(RT_VERSION));
266+ if assigned(versionBranch) and versionBranch.IsBranch and (versionBranch.Children.Count > 0 ) then
267+ begin
268+ versionBranch := TResourceTreeBranchNode(versionBranch.Children.First.K);
269+ if assigned(versionBranch) and versionBranch.IsBranch and (versionBranch.Children.Count > 0 ) then
270+ begin
271+ versionLeaf := TResourceTreeLeafNode(versionBranch.Children.First.K);
272+ if assigned(versionLeaf) and versionLeaf.IsLeaf then
273+ begin
274+ exit(versionLeaf.Data);
275+ end ;
276+ end ;
277+ end ;
278+ exit(nil );
279+ finally
280+ rt.Free;
281+ end ;
282+ end ;
283+
284+ function PeVerQueryValueFixed (stream: TStream; out value : VS_FIXEDFILEINFO): Boolean;
285+ var
286+ verInfo: TPEVersionInfo;
287+ block: TBlock;
288+ begin
289+ verInfo := TPEVersionInfo.Create;
290+ try
291+ verInfo.LoadFromStream(stream);
292+
293+ if assigned(verInfo.Root) then
294+ for block in verInfo.Root.Children do
295+ if block.ClassType = TBlockVersionInfo then
296+ begin
297+ value := TBlockVersionInfo(block).FixedInfo;
298+ exit(True);
299+ end ;
300+
301+ exit(False);
302+ finally
303+ verInfo.Free;
304+ end ;
305+ end ;
306+
244307end .
0 commit comments