Win32::API use Pointer to struct

P

Peter Arnhold

Hi,
how can I correctly 'unpack' $SessionInfo?:

use Win32::API;

my $WTSOpenServer = new Win32::API("wtsapi32.dll", "WTSOpenServer",[P],N);
my $hServer = $WTSOpenServer->Call('');
my $SessionInfo = pack 'L4', 0;
my $Count = pack 'C', 0;

my $WTSEnumerateSessions = new Win32::API(
'wtsapi32.dll', 'WTSEnumerateSessions',[qw(N N N P P)],'I'
);
$WTSEnumerateSessions->Call($hServer,0,1,$SessionInfo,$Count);

print unpack('C', $Count), "\n"; # 2 - OK, system and console
print unpack 'H*', $SessionInfo; # not realy struct _WTS_SESSION_INFO??

THX,
Peter
 
R

Rainer Weikusat

Peter Arnhold said:
how can I correctly 'unpack' $SessionInfo?:

use Win32::API;

my $WTSOpenServer = new Win32::API("wtsapi32.dll", "WTSOpenServer",[P],N);
my $hServer = $WTSOpenServer->Call('');
my $SessionInfo = pack 'L4', 0;
my $Count = pack 'C', 0;

my $WTSEnumerateSessions = new Win32::API(
'wtsapi32.dll', 'WTSEnumerateSessions',[qw(N N N P P)],'I'
);
$WTSEnumerateSessions->Call($hServer,0,1,$SessionInfo,$Count);

Judgeging from

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383833(v=vs.85).aspx

and the Win32::API documentation, the sizes of the buffers you are
passing are wrong: The second should be four bytes (DWORD), not 1, and
the first would need to be large enough to accommodate the number of
structures which will be returned, however this is supposed to be
determined. According to

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383864(v=vs.85).aspx

the 'bare' size of such a structure should be 12 bytes, not 16 and 16
(4 times 4 bytes) is certainly to small to hold two structures.
 
P

Peter Arnhold

Am 06.09.2012 23:08, schrieb Rainer Weikusat:
Peter Arnhold said:
how can I correctly 'unpack' $SessionInfo?:

use Win32::API;

my $WTSOpenServer = new Win32::API("wtsapi32.dll", "WTSOpenServer",[P],N);
my $hServer = $WTSOpenServer->Call('');
my $SessionInfo = pack 'L4', 0;
my $Count = pack 'C', 0;

my $WTSEnumerateSessions = new Win32::API(
'wtsapi32.dll', 'WTSEnumerateSessions',[qw(N N N P P)],'I'
);
$WTSEnumerateSessions->Call($hServer,0,1,$SessionInfo,$Count);

Judgeging from

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383833(v=vs.85).aspx

and the Win32::API documentation, the sizes of the buffers you are
passing are wrong: The second should be four bytes (DWORD), not 1, and
the first would need to be large enough to accommodate the number of
structures which will be returned, however this is supposed to be
determined. According to

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383864(v=vs.85).aspx

the 'bare' size of such a structure should be 12 bytes, not 16 and 16
(4 times 4 bytes) is certainly to small to hold two structures.

ACK. Bad example. I know this msdn sites. I followed your advice but no other
result. $Count is 2 - correct, $SessionInfo is still no _WTS_SESSION_INFO.
 
P

Peter Arnhold

Am 07.09.2012 11:23, schrieb Heinrich Mislik:
Can't you use Win32::API::Struct? Much easier than using pack/unpack.

But how?
I found out this, triggered by Rainer's thoughts:

$WTSEnumerateSessions->Call($hServer,0,1,$SessionInfo,$Count);
$Count = unpack 'I', $Count;
$SessionInfo = unpack 'P'.(12 x $Count), $SessionInfo;

foreach my $pos ( 0 .. $Count-1 ) {
my($id,$p,$state) = unpack '@'.($pos*12).' LLL', $SessionInfo;
print "$id => $state => ", unpack('p', pack('L', $p)), "\n";
}

0 => 4 => Services
2 => 0 => Console

This is not really nice but works. No idea how to handle $SessionInfo by
Win32::API::Struct. Too much Win32 ;-)


Gruß,
Peter
 
R

Rainer Weikusat

Rainer Weikusat said:
Peter Arnhold said:
how can I correctly 'unpack' $SessionInfo?:

use Win32::API;

my $WTSOpenServer = new Win32::API("wtsapi32.dll", "WTSOpenServer",[P],N);
my $hServer = $WTSOpenServer->Call('');
my $SessionInfo = pack 'L4', 0;
my $Count = pack 'C', 0;

my $WTSEnumerateSessions = new Win32::API(
'wtsapi32.dll', 'WTSEnumerateSessions',[qw(N N N P P)],'I'
);
$WTSEnumerateSessions->Call($hServer,0,1,$SessionInfo,$Count);
[...]

and the first would need to be large enough to accommodate the number of
structures which will be returned, however this is supposed to be
determined.

To have this explicitly: I misread this. The second argument needs to
be a pointer to a pointer where the address of the structure array is
supposed to be stored. This can then be unpacked in the way Peter
showed in his posting in the other subthread.
 
R

Rainer Weikusat

[...]
foreach my $pos ( 0 .. $Count-1 ) {
my($id,$p,$state) = unpack '@'.($pos*12).' LLL', $SessionInfo;
print "$id => $state => ", unpack('p', pack('L', $p)), "\n";
}

0 => 4 => Services
2 => 0 => Console

This is not really nice but works.

Based on some experiments with 'manually' created structures of this
form, it should be possible to use LpL for unpacking such a structure
directly:
 
P

Peter Arnhold

Am 07.09.2012 12:47, schrieb Rainer Weikusat:
[...]
foreach my $pos ( 0 .. $Count-1 ) {
my($id,$p,$state) = unpack '@'.($pos*12).' LLL', $SessionInfo;
print "$id => $state => ", unpack('p', pack('L', $p)), "\n";
}

0 => 4 => Services
2 => 0 => Console

This is not really nice but works.

Based on some experiments with 'manually' created structures of this
form, it should be possible to use LpL for unpacking such a structure
directly:

--------------
$string = 'Elfriede';
$struct = pack('LpL', 4, $string, 5);
($id, $name, $state) = unpack('LpL', $struct);
print("$id, $name, $state\n");

Of course yes. THX.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top