How To Call Win32 Spooler Enumeration APIs Properly

Last reviewed: November 18, 1996
Article ID: Q158828
The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API) for Windows NT and Win95, version 4.00

SUMMARY

Proper use of the Win32 Spooler Enumeration APIs requires two calls to the desired function. These APIs generally fill out an array of structures. However, the structures usually include pointers to strings or to other data. This extraneous data must also be stored in the return memory, so the strings and other data are appended to the array. Therefore, simply declaring an array of such structures on the stack would not set aside enough memory to hold all of the information the API returns.

MORE INFORMATION

The Enumeration APIs that behave this way include: EnumForms(), EnumJobs(), EnumMonitors(), EnumPorts(), EnumPrinterDrivers(), EnumPrinters(), and EnumPrintProcessors(). Also, GetJob(), GetPrinter(), and DocumentProperties() require the same treatment. In each case, proper usage requires an initial call to the function to determine the necessary buffer size, and a subsequent call that passes in a pointer to a dynamically- allocated buffer of sufficient size. The code below, from a console application, demonstrates this approach using the EnumJobs() API:

   BOOL ListJobsForPrinter( LPTSTR szPrinterName )
   {
     HANDLE         hPrinter;
     DWORD          dwNeeded, dwReturned, i;
     JOB_INFO_1     *pJobInfo;

     // You need a printer handle, open the printer
     if( ! OpenPrinter( szPrinterName, &hPrinter, NULL ) )
       return FALSE;

     // First you call EnumJobs() to find out how much memory you need
     if( ! EnumJobs( hPrinter, 0, 0xFFFFFFFF, 1, NULL, 0, &dwNeeded,
                     &dwReturned ) )
     {
       // It should have failed, but if it failed for any reason other
       // than "not enough memory", you should bail out
       if( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
       {
         ClosePrinter( hPrinter );
         return FALSE;
       }
     }
     // Allocate enough memory for the JOB_INFO_1 structures plus
     // the extra data - dwNeeded from the previous call tells you
     // the total size needed
     if( (pJobInfo = (JOB_INFO_1 *)malloc( dwNeeded )) == NULL )
     {
       ClosePrinter( hPrinter );
       return FALSE;
     }
     // Call EnumJobs() again and let it fill out our structures
     if( ! EnumJobs( hPrinter, 0, 0xFFFFFFFF, 1, (LPBYTE)pJobInfo,
                     dwNeeded, &dwNeeded, &dwReturned ) )
     {
       ClosePrinter( hPrinter );
       free( pJobInfo );
       return FALSE;
     }
     // You're done with the printer handle, close it
     ClosePrinter( hPrinter );

     // dwReturned tells how many jobs there are
     // Here, you'll simply display the number of jobs found
     printf( "%d jobs\n", dwReturned );
     // It's easy to loop through the jobs and access each one
     for(i=0;i<dwReturned;i++)
     {
       // pJobInfo[i] is a JOB_INFO_1 struct for that job
       // so here you could do whatever you want for each job
       printf( "[%d] [%s]\n", pJobInfo[i].JobId, pJobInfo[i].pDocument );
     }

     // Clean up
     free( pJobInfo );
     return TRUE;
   }


KBCategory: kbprint kbhowto
KBSubcategory: GdiPrn
Additional reference words: 4.00 kbdsd



THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: November 18, 1996
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.