How To Call Win32 Spooler Enumeration APIs ProperlyLast reviewed: November 18, 1996Article ID: Q158828 |
The information in this article applies to:
SUMMARYProper 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 INFORMATIONThe 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
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |