PRINTER_STATUS_OFFLINE condition not detected by GetPrinter or FindFirstPrinterChangeNotification
Posted on 2004-09-04
I have written a small printer monitor that updates a list of connected printers with the status information of the printer. The application uses a seperate thread that executes the FindFirstPrinterChangeNotification and FindNextPrinterChangeNotification calls to get printer change notifications. The problem I am having is that when a printer is set to offline, although a notification is being generated and picked up by the monitoring thread, the PRINTER_NOTIFY_INFO_DATA.NotifyData.awData = 0 for Type = PRINTER_NOTIFY_TYPE and Field = PRINTER_NOTIFY_FIELD_STATUS instead of having the 0x80 bit set (PRINTER_STATUS_OFFLINE). A call to GetPrinter ( hPrinter, 2, pBuf ...) returns a PRINT_INFO_2 structure that has the Status field also set to 0.
When the code first runs it initialises by calling the GetPrinter API call for each connected printer and sets the status for each printer based on the value of the Status field in the PRINT_INFO_2 structure.
The code works fine for other notifications such as pausing the printer - the status field has the 0x01 bit set.
Here is some simple sample code. When compiled this app takes a printer name on the command line in the form \\server\printername. It then prints out the current status value of the printer. To test: connect the test machine to a network printer. Make sure the printer is functioning correctly. Run the application - a status of 0 should be printed. Now pause the printer by righ clicking the printer and select pause printing. Run the application again - a status of 1 should be printed. Set printing to resume and then set the printer to Use Offline. Run the application again. A status of 128 (0x80) should be reported but instead it reports 0.
int main(int argc, char* argv)
HANDLE hPrinter ;
PRINTER_DEFAULTS pd ;
PRINTER_INFO_2 * pBuf ;
DWORD dwBytesNeeded ;
memset ( &pd, 0, sizeof ( pd ) ) ;
pd.DesiredAccess = PRINTER_ALL_ACCESS ;
if ( OpenPrinter ( argv, &hPrinter, &pd ) )
GetPrinter ( hPrinter, 2, NULL, 0, &dwBytesNeeded ) ;
if ( GetLastError ( ) == ERROR_INSUFFICIENT_BUFFER )
if ( ( pBuf = (PRINTER_INFO_2 * ) malloc ( dwBytesNeeded ) ) )
if ( GetPrinter ( hPrinter, 2, ( LPBYTE ) pBuf, dwBytesNeeded, &dwBytesNeeded ) )
printf ( "Status for printer %s is [%d]\n", argv, pBuf->Status ) ;
printf ( "Error: [%ld]\n", GetLastError ( ) ) ;
free ( pBuf ) ;
ClosePrinter ( hPrinter ) ;