From: "Edson Alvarenga (EDB)" <[EMAIL PROTECTED]>

I've almost deleted the mail without reading. Please include what module 
do you have problems with in the subject!

> I'm writing a script file in order to get the print queues, but
> when I call the function EnumJobsA at the first time in order to
> know what is the size that I need to allocate for the buffer the
> function return the value 538976288 and when I try to alloc ate
> this value in a buffer variable the system abbend the script and
> return the error message "Out of memory!". 

If you'd print the 

        unpack( 'H*', $pcbSizeRequired)

you would find out that it consists of the four spaces. That is the value was 
not changed ... because the call failed. There are several more problems with your 
code.
See below.

> ---- this is my script file ---------------------------------------------------------
> 
> use Win32::API;
> use strict;
> 
> my $printer_name = 'nt_xerox';
> my $OpenPrinter;
> $OpenPrinter ||= Win32::API->new( 'winspool.drv','OpenPrinter',
>                  [qw( P L P )],'N') or return;
> my $printer_handle = ' ' x 4;

It's better to use

        my $printer_handle = "\0" x 4

It's easier to see that the call failed and did not modify the value.

> $OpenPrinter->Call( $printer_name, $printer_handle, undef);

You should check the result and print the error message if necessary:

        $OpenPrinter->Call( $printer_name, $printer_handle, undef)
         or die Win32::FormatMessage(Win32::GetLastError());


> my ($pcbSizeRequired, $pcbBytesReturned, $pl_bytes_needed, $sizeof_ji1_struct,
>     $info_structs, $ji1structs, $long, $EnumJobs);
>       
> $pcbSizeRequired  = ' ' x 4; # Reserve space for LONG
> $pcbBytesReturned = ' ' x 4; # Reserve space for LONG
> 
> $EnumJobs ||= Win32::API->new('winspool.drv','EnumJobsA',[qw( L P P P P P P P 
>)],'L'); 

You have the types wrong. If the MSDN says a parameters is DWORD you should use L and 
not P.

        $EnumJobs ||= Win32::API->new('winspool.drv','EnumJobsA',[qw( L L L L P L P P 
)],'L'); 

> $EnumJobs->Call($printer_name, 0, 255, 1, $info_structs, 1, $pcbSizeRequired, 
>                 $pcbBytesReturned ); 

Again you should test for errors.

Plus there are two errors in that statement. First you should pass the handle you got 
from 
OpenPrinter, not the printer name. Second you pass a NULL pointer to the buffer, but 
claim that the buffer's 1 byte long. Even though it's unlikely there will only be one 
byte
of data for the printer, it's better to pass 0.

        unless ($EnumJobs->Call($printer_handle, 0, 255, 1, $info_structs, 0, 
                        $pcbSizeRequired, $pcbBytesReturned )) {
                my $error = Win32::GetLastError();
                die Win32::FormatMessage($error)." ($error)\n" unless $error = 122; 
                #ignore the expected "data area too small error"
        }

As you can see we want to ignore the error that the buffer was too small.

> $pl_bytes_needed = unpack('L',$pcbSizeRequired);
> print "Bytes Needed=$pl_bytes_needed\n\n";

To make it easier here is the whole script after all my changes :

#perl
use Win32::API;
use strict;

my $printer_name = 'HP LaserJet 4050 Series PCL';
my $OpenPrinter;
$OpenPrinter ||= Win32::API->new( 'winspool.drv','OpenPrinter',
                 [qw( P P P )],'N') or return;
my $printer_handle = "\0" x 4;
$OpenPrinter->Call( $printer_name, $printer_handle, undef)
 or die Win32::FormatMessage(Win32::GetLastError());

$printer_handle = unpack('L',$printer_handle);

my ($pcbSizeRequired, $pcbBytesReturned, $pl_bytes_needed, $sizeof_ji1_struct,
    $info_structs, $ji1structs, $long, $EnumJobs);
        
$pcbSizeRequired  = "\0" x 4; # Reserve space for LONG
$pcbBytesReturned = "\0" x 4; # Reserve space for LONG

$EnumJobs ||= Win32::API->new('winspool.drv','EnumJobsA',[qw( L L L L P L P P )],'L'); 

unless ($EnumJobs->Call($printer_handle, 0, 255, 1, $info_structs, 0, 
$pcbSizeRequired, $pcbBytesReturned )) {
        my $error = Win32::GetLastError();
        die Win32::FormatMessage($error)." ($error)\n" unless $error = 122; 
        #ignore the expected "data area too small error"
}

$pl_bytes_needed = unpack('L',$pcbSizeRequired);
print "Bytes Needed=$pl_bytes_needed\n\n";

$info_structs = "\0" x $pl_bytes_needed;

$EnumJobs->Call($printer_handle, 0, 255, 1, $info_structs, $pl_bytes_needed, 
$pcbSizeRequired, 
$pcbBytesReturned )
        or die Win32::FormatMessage(Win32::GetLastError());

print "INFO: $info_structs\n";
__END__

I'm too lazy to parse the $info_struct ;-)

HTH, Jenda

=========== [EMAIL PROTECTED] == http://Jenda.Krynicky.cz ==========
There is a reason for living. There must be. I've seen it somewhere.
It's just that in the mess on my table ... and in my brain.
I can't find it.
                                        --- me

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

Reply via email to