How To Call Win32 Spooler Enumeration APIs Properly

Article translations Article translations
Article ID: 158828 - View products that this article applies to.
This article was previously published under Q158828
Expand all | Collapse all

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;
 }
				

Properties

Article ID: 158828 - Last Review: November 21, 2006 - Revision: 2.3
APPLIES TO
  • Microsoft Win32 Application Programming Interface, when used with:
    • Microsoft Windows NT Server 4.0 Standard Edition
    • Microsoft Windows NT Workstation 4.0 Developer Edition
    • Microsoft Windows 95
Keywords: 
kbfaq kbhowto KB158828

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com