Front page | perl.beginners |
Postings from December 2002
Re: Scalar reference, pointer to pointer meaning
Thread Previous
|
Thread Next
From:
Gary Hawkins
Date:
December 29, 2002 08:01
Subject:
Re: Scalar reference, pointer to pointer meaning
Message ID:
001f01c2af53$a7fe9160$0201a8c0@garyha1
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: ghawk@eskimo.com [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
Thread Previous
|
Thread Next