What is passing through to the screen is the actual binary/hex data.
That is why the screeen has the little characters and the linefeeds.

        Can you provide that portion of the code, so we can see what you are
trying to do?

Wags ;)

-----Original Message-----
From: Gary Hawkins [mailto:[EMAIL PROTECTED]]
Sent: Sunday, December 08, 2002 02:55
To: [EMAIL PROTECTED]
Subject: File version info



This is an effort to write filever.exe in Perl.  Filever extracts file
version information and is available in the later Windows resource kits I
think, or maybe as early as NT4.  In verbose mode it prints info like this:

D:\>filever.exe /v c:\windows\system32\kernel32.dll
--a-- W32i   DLL ENU      5.1.2600.0 shp    926,720 08-23-2001 kernel32.dll
        Language        0x0409 (English (United States))
        CharSet         0x04b0 Unicode
        OleSelfRegister Disabled
        CompanyName     Microsoft Corporation
        FileDescription Windows NT BASE API Client DLL
        InternalName    kernel32
        OriginalFilenam kernel32
        ProductName     Microsoft« Windows« Operating System
        ProductVersion  5.1.2600.0
        FileVersion     5.1.2600.0 (xpclient.010817-1148)
        LegalCopyright  ¬ 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

I want to do the same thing with Perl so my script can use the information
without having to rely on an external exe, and I don't want to use AdminMisc
(I forget why right now, maybe pride or something even dummer).

The script below prints:

c:\windows\system32\kernel32.dll

î♥4     VS_VERSION_INFO ╜♦∩¦

♣       (

♣       (
?               ♦♦☻                                     Ω☻
StringFileInfo  ¦☻
040904B0        L▬
CompanyName     Microsoft Corporation   f▼
FileDescription Windows NT BASE API Client DLL  d"
FileVersion     5.1.2600.0 (xpclient.010817-1148)       2
InternalName    kernel32        Ç.
LegalCopyright  ¬ Microsoft Corporation. All rights reserved.   :
OriginalFilename        kernel32        j%
ProductName     Microsoft« Windows« Operating System    :♂
ProductVersion  5.1.2600.0      D
VarFileInfo     $♦      Translation             ♦¦♦FE2X

[Screen capture if that doesn't make any sense:
http://www.eskimo.com/~ghawk/images/filever.gif]

Now, most everything in there is relatively easy to clean up.  The problem
area is the information between VS_VERSION_INFO and StringFileInfo that if
translated to hex will become the numbers shown by filever.exe in the
VS_FIXEDFILEINFO section.  So if you do a match between the two bookends and
then unpack("h*", $&), you get a hex string with all of the data.  In an
ideal world.  It works fine on some files.  Drop the first ten bytes and
then from that point some of them need to be reversed but it is accurate.

Here's the problem:  With that particular dll the VS_VERSION_INFO contains
"00050001:0a280000".  Somehow, when the pattern match sees 0a (really a0
because it has to be reversed later, or possibly 000A (a Unicode linefeed,
since the \000's are still in there at that point), it interprets that as
'\n', and the screen print does too, as you can see above.  I want it all on
one line or least be able to match past those.

I tried $/ = "", $/ = "xyz", and $* = 1 to no avail.

Is there someone out there, some Unicode guru or anybody who can help clear
up what's wrong here?

My Perl version is v5.6.1 built for MSWin32-x86-multi-thread.

Thanks!

Gary

#!perl.exe

use Win32::API;
#use utf8; # no effect

if (! $ARGV[0]) { 
        print "\n\tFilename arg needed.\n\n"; 
        exit; 
} else {
        $filename = $ARGV[0];
}

if ($filename && $filename =~ /\*/) { # for *.* etc wildcards
        $filenameprefix = $filename;
        $filenameprefix =~ s/(.*)\\.*/$1\\/;
        @filenames = `dir /b $filename`; # readdir later maybe
} else {
        $filenames[0] = $filename;
}

chomp @filenames;

for (@filenames) {
        s/^(.*)/$filenameprefix$1/; # reassemble full path

        $pBlock = "";

        print "\n\n$_\t\n\n";

        $GetFileVersionInfoSize = 
                new Win32::API(
                        "version.dll", 
                        "GetFileVersionInfoSizeA", 
                        ['P', 'P'], 
                        'N'
        );

        if (    $GetFileVersionInfoSize->Call(
                        $_, 
                        $lpHandle
                )
                ) {
                $lpBufferSize   = 
                        $GetFileVersionInfoSize->Call(
                                $_, 
                                $lpHandle
                        );
        } else {
                print "Apparently 16-bit\n";
                next;
        }

        $GetFileVersionInfo = new Win32::API(
                        "version.dll", 
                        "GetFileVersionInfoA", 
                        ['P', 'N', 'N', 'P'], 
                        'I'
        );

        $pBlock = "#" x $lpBufferSize;

        if (    $GetFileVersionInfo->Call(
                        $_, 
                        0, 
                        $lpBufferSize, 
                        $pBlock
                )
                ) {
                $one_or_zero_ignored = 
                        $GetFileVersionInfo->Call(
                                $_, 
                                0, 
                                $lpBufferSize, 
                                $pBlock
                        ); # merely to get $pBlock
        } 

        $lplpBuffer = "X" x 32;
        $puLen = 16;

        $VerQueryValue = new Win32::API(
                        "version.dll", 
                        "VerQueryValueA", 
                        ['P', 'P' , 'P', 'P'], 
                        'N'
        );

        if (! $VerQueryValue->Call(
                        $pBlock, 
                        $lpSubBlock, 
                        $lplpBuffer, 
                        $puLen
                )
                ) { 
                print Win32::FormatMessage(Win32::GetLastError); 
        }

        #print "$pBlock\n"; next; # raw output, or...
        $pBlock =~ s/\#*$//; # excess buffer erase
        $pBlock =~ s/\001\000/\n/g; # 001 smiley face, \000 space
        $pBlock =~ s/\000\000\000/\t/g; # mo pretty
        $pBlock =~ s/\000//g; # human-readable
        print "$pBlock\n";
}

__END__


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


**********************************************************
This message contains information that is confidential
and proprietary to FedEx Freight or its affiliates.
It is intended only for the recipient named and for
the express purpose(s) described therein.
Any other use is prohibited.
****************************************************************


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to