Using VerQueryValue for file version information on Windows > What I expected to find in $lplpBuffer is instead being > written to an unused part of the full buffer ($lpFullBuffer). Got it. Prints like so: c:\windows\system32\version.dll CompanyName Microsoft Corporation FileDescription Version Checking and File Installation Libraries InternalName version OriginalFilename VERSION.DLL ProductName Microsoft« Windows« Operating System ProductVersion 5.1.2600.0 FileVersion 5.1.2600.0 (xpclient.010817-1148) LegalCopyright ⌐ Microsoft Corporation. All rights reserved. Needed unpack as pointer, see 'perl -f pack'. Not perfect or the best it can be yet, but it works... #!perl.exe
# Script to grab file information in Windows, not covering VS_FIXEDFILEINFO here # # Do... GetFileVersonInfoPublic.pl c:\windows\system32\vers*.dll ...for example # # email: [EMAIL PROTECTED] [Gary Hawkins] use Win32::API; &GetListOfFiles; &ProcessEachFile; # sends filename(s) to &GetFileVersionAPI exit; ############################# sub GetFileVersionAPI ############################# { $dwHandle = 0; $puLen = "M" x 8; # ? $lplpBuffer = "X" x 32; $lpdwHandle = ""; # [out] Pointer to a variable that the function sets to zero. $GetFileVersionInfoSize = new Win32::API("version.dll", "GetFileVersionInfoSizeA", 'PP', N); $GetFileVersionInfo = new Win32::API("version.dll", "GetFileVersionInfoA", 'PNNP', N); $VerQueryValue = new Win32::API("version.dll", "VerQueryValueA", 'PPPP', N); if ($dwBufferSize = $GetFileVersionInfoSize->Call($filename, $lpdwHandle)) { # continue } else { print "No version info.\n"; return; } $lpFullBuffer = "#" x $dwBufferSize; $GetFileVersionInfo->Call($filename, $dwHandle, $dwBufferSize, $lpFullBuffer); # populate $lpFullBuffer ### Just get lang and codepage, like 040904B0 or 040904E4 $lpSubBlock = "\\VarFileInfo\\Translation"; if ($VerQueryValue->Call($lpFullBuffer, $lpSubBlock, $lplpBuffer, $puLen)) { $LangCode = unpack("p*", $lplpBuffer); $LangCode = unpack("h*", $LangCode); $LangCode =~ s#^(....)(....).*#$2$1#; $LangCode = reverse uc($LangCode); #print "\$LangCode ---$LangCode---\n"; } ### Now each one @pattern = ("CompanyName", "FileDescription", "InternalName", "OriginalFilename", "ProductName", "ProductVersion", "FileVersion", "LegalCopyright", "LegalTrademarks", "SpecialBuild", "PrivateBuild", "Comments"); foreach $p (@pattern) { $lpSubBlock = "\\StringFileInfo\\$LangCode\\$p"; if ($VerValue = $VerQueryValue->Call($lpFullBuffer, $lpSubBlock, $lplpBuffer, $puLen)) { $lplpBuffer = unpack("p*", $lplpBuffer); substr($p, length($p)) = " " x (16 - length($p)); # make fixed width print "\t$p $lplpBuffer\n"; } else { print "\t$p\t ", Win32::FormatMessage(Win32::GetLastError); } #&PrintFullBuffer; } } ################## sub GetListOfFiles ################## { $filename = $ARGV[0]; if ($filename && $filename =~ /\*/) { $filenameprefix = $filename; $filenameprefix =~ s#(.*)\\.*#$1\\#; @filenames = `dir /b $filename`; } else { push @filenames, $filename; } chomp @filenames; } #################### sub ProcessEachFile #################### { foreach $filename (@filenames) { $filename =~ s#^(.*)#$filenameprefix$1#; print "\n $filename\n"; &GetFileVersionAPI; } } ##################### sub PrintFullBuffer ##################### { print " -------------------------------------------------------\$lpFullBuffer $lpFullBuffer ------------------------------------------------------- "; } __END__ ========================================================== >filever.exe /v c:\windows\system32\vers*.dll ========================================================== --a-- W32i DLL ENU 5.1.2600.0 shp 16,384 08-23-2001 version.dll Language 0x0409 (English (United States)) <== 0409 CharSet 0x04b0 Unicode <== 04b0 OleSelfRegister Disabled ...together make 040904b0 used above CompanyName Microsoft Corporation FileDescription Version Checking and File Installation Libraries InternalName version OriginalFilenam VERSION.DLL ProductName Microsoft<edit out unicode> Windows<edit out unicode> Operating System ProductVersion 5.1.2600.0 FileVersion 5.1.2600.0 (xpclient.010817-1148) LegalCopyright <edit out unicode> Microsoft Corporation. All rights reserved. VS_FIXEDFILEINFO: Signature: feef04bd Struc Ver: 00010000 FileVer: 00050001:0a280000 (5.1:2600.0) ProdVer: 00050001:0a280000 (5.1:2600.0) FlagMask: 0000003f Flags: 00000000 OS: 00040004 NT Win32 FileType: 00000002 Dll SubType: 00000000 FileDate: 00000000:00000000