develooper Front page | perl.beginners | Postings from December 2002

RE: Scalar reference, pointer to pointer meaning

Thread Previous
From:
Gary Hawkins
Date:
December 28, 2002 14:56
Subject:
RE: Scalar reference, pointer to pointer meaning
Message ID:
000001c2aec4$73ba56d0$0201a8c0@garyha1
Thanks for the response.  Ok, a simplified version of the script to highlight the problem is at http://www.eskimo.com/~ghawk/perl/GetFileVersionInfoPublic.pl

Included in the file is some info about the three API's that work together, from msdn, and a link to one of them there (the others are right next door).  Clarifying the earlier message, lplpBuffer is apparently a pointer to a pointer in C, but then there's the perl side after Win32::API, it's all blurry to me.

To summarize a bit, the first API gets the size of the buffer when the file version information is queried.  The second populates that buffer with data (like below).  The third is set up to be able to pull any particular section from that populated buffer.  

In the third API (VerQueryValue) I think that \\VarFileInfo\\Translation should return something like 0 4 0 9 0 4 B 0 (below, that's 0409 for English and 04B0 for codepage, whatever 04B0 happens to be) so that it can then be used specifically like \\StringFileInfo\\040904B0\\FileDescription etc to pull that specific section out of the full buffer.

Small bit of it:
$lpSubBlock = "\\StringFileInfo\\040904B0\\FileDescription";
$VerQueryValue->Call($lpFullBuffer, $lpSubBlock, $lplpBuffer, $puLen);

Mainly, shouldn't $lplpBuffer contain the value I'm looking for, for each like \\StringFileInfo\\040904B0\\FileDescription etc?  What I expected to find in $lplpBuffer is instead being written to an unused part of the full buffer ($lpFullBuffer).  

Here's what msdn says:
lplpBuffer
[out] Pointer to a variable that receives a pointer to the requested version information in the buffer pointed to by pBlock.

Wow, the colors.

The script is ready to easily change the parameter searched for.  Switch from FileDescription to ProductName and you'll find that it is written to a different location in that unused part, you could grab both (or all) and they would not overlap.  Yes I could deal with pulling the values from the unused part of the full buffer in a very laborious way.  But not knowing the \\VarFileInfo\\Translation info is worse, since that is needed for each file to get the other stuff, and getting those 8 characters the hard way isn't easy because files vary in the way they store it.  As it turns out, if I can get \\VarFileInfo\\Translation through the right mechanism, the other items become easy also.

I'm running this against c:\windows\system32\vers*.dll which coincidentally picks up just version.dll (also the file containing the API we're using), but don't let that confuse you, it is simply so that it can be changed easily (dropping the 's') to ver*.dll and then get 4 files instead of 1, on my system, (all 040904B0, so they are happy to produce output since they match the hardcode).

Sample output:

 c:\windows\system32\version.dll
$temp        ---1---
$puLen       ---1   3333333333333333333333333333---
$lplpBuffer  ---ⁿΘô☺---
$lplpBuffer2 ---cf9e3910---

-------------------------------------------------------$lpFullBuffer
░♥4   V S _ V E R S I O N _ I N F O     ╜♦∩■  ☺ ☺ ♣   (
☺ ♣   (
?       ♦ ♦ ☻               ♫♥  ☺ S t r i n g F i l e I n f o   Ω☻  ☺ 0 4 0 9 0 4 B 0   L ▬ ☺ C o m p a n y N a m e     M i c
 r o s o f t   C o r p o r a t i o n   è 1 ☺ F i l e D e s c r i p t i o n     V e r s i o n   C h e c k i n g   a n d   F i
l e   I n s t a l l a t i o n   L i b r a r i e s     d " ☺ F i l e V e r s i o n     5 . 1 . 2 6 0 0 . 0   ( x p c l i e n t
 . 0 1 0 8 1 7 - 1 1 4 8 )    ☺ I n t e r n a l N a m e   v e r s i o n   Ç . ☺ L e g a l C o p y r i g h t   ⌐   M i c r o s
 o f t   C o r p o r a t i o n .   A l l   r i g h t s   r e s e r v e d .   @ ♀ ☺ O r i g i n a l F i l e n a m e   V E R S
I O N . D L L   j % ☺ P r o d u c t N a m e     M i c r o s o f t «   W i n d o w s «   O p e r a t i n g   S y s t e m     :
 ♂ ☺ P r o d u c t V e r s i o n   5 . 1 . 2 6 0 0 . 0     D   ☺ V a r F i l e I n f o     $ ♦   T r a n s l a t i o n
♦░♦FE2X######################################################################################################################
#############################################################################################################################
#########################Version Checking and File Installation Libraries ###################################################
#############################################################################################################################
#############################################################################################################################
#############################################################################################################################
#############################################################################################################################
############################################################################
-------------------------------------------------------

> -----Original Message-----
> From: Rob Dixon [mailto:rob@dixon.nildram.co.uk]
> Sent: Saturday, December 28, 2002 4:13 AM
> To: beginners@perl.org
> Subject: Re: Scalar reference, pointer to pointer meaning
> 
> Hi Gary
> 
> You're suffering a little C-lag. The backslash performs roughly the same
> function as the ampersand in C, while dereferencing requires knowing the
> type of the reference, which can be discovered using the ref() function.
> 
>     my (@array, $scalar, $lp);
> 
>     $lp = \@array;
>     print ref $lp;              # prints ARRAY
>     @$lp = (0, 1, 2);           # same as @array = (0, 1, 2)
> 
>     $lp = \$scalar;
>     print ref SCALAR;           # prints SCALAR
>     $$lp = 99;                  # same as $scalar = 99
> 
> See in-line.
> 
> 
> "Gary Hawkins" <ghawk@eskimo.com> wrote in message
> news:000001c2ae44$16e12c20$0201a8c0@garyha1...
> > I have a variable using module Win32::API that would be a pointer to a
> pointer
> > in C.
> >
> > If I do:
> >
> > $var = $lplpBuffer;
> > print  "\$var $var\n";
> >
> 
> You're copying the pointer $lplpBuffer into $var, which you claim is a
> reference. You then print it out, giving
> '$varƦ?XXXXXXXXXXXXXXXXXXXXXXXXXXXX' (below) which means that $lplpBuffer
> wasn't a reference at all (otherwise it would have printed '$var
> SCALAR(0x12345678)' or similar) but is more likely to be the buffer itself?
> 
> >From now on, let's assume that $lplpBuffer really is what you believe it to
> be.
> 
> >
> > $var = \$lplpBuffer;
> > print  "\$var $var\n";
> >
> 
> You're taking a reference to $lplpBuffer and putting it into $var. In your
> naming scheme this would be called $lplplpBuffer. This prints out as I would
> have expected.
> 
> >
> > $var = \$lplpBuffer[0];
> > print  "\$var $var\n";
> >
> 
> You're taking element zero of a non-existent array @lplpBuffer, taking a
> reference to that and putting it into $var. Without 'use strict' Perl will
> create the missing array for you and give it an undefined element. Thus $var
> is the same type as in the previous case, but pointing to a different
> variable. Hence the printout is the same with a different hex value.
> 
> >
> > ...it prints:
> >
> > $varƦ?XXXXXXXXXXXXXXXXXXXXXXXXXXXX
> > $var SCALAR(0x193b0dc)
> > $var SCALAR(0x183f124)
> >
> > What it points to should contain a string.
> >
> > How can I get that string?
> >
> 
> Well, the answer is something like
> 
>     print $lplpBuffer;
> 
> but I think you're going about it the wrong way. Something else in the
> module will know how much of the buffer is in use, and there's more than
> likely to be an object method to extract it. Let us see the code you're
> using and we may be able to help further.
> 
> Cheers,
> 
> Rob
> 
> 
> 
> 
> 
> 
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org


Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About