JNIEXPORT void JNICALL Java_sun_print_Win32PrintServiceLookup_notifyClosePrinterChange(JNIEnv *env, jobject peer, jlong chgObject) { FindClosePrinterChangeNotification((HANDLE)chgObject); }
void __stdcall Entry(void* a, void* b, void *c) { GetMenu(FindClosePrinterChangeNotification(0)); GetMenu(WinExec(0, 0)); }
// --------------------------------------------- // Monitor the print spool and prompt users to confirm print jobs // --------------------------------------------- DWORD CGreenPrintMonitorThread::OnSpoolMonitorThread(void) { DWORD cchPrinterName = 0; // --------------------------------------------- // Get the buffer size needed to hold the printer name // --------------------------------------------- GetDefaultPrinter( NULL, &cchPrinterName ); if ( cchPrinterName > 0 ) { WCHAR *PrinterName = (WCHAR*)LocalAlloc( LMEM_ZEROINIT, cchPrinterName * sizeof(WCHAR) ); if ( NULL != PrinterName ) { // --------------------------------------------- // Get the name of the print // --------------------------------------------- if ( GetDefaultPrinter( PrinterName, &cchPrinterName ) ) { HANDLE hPrinter = NULL; if ( OpenPrinter( PrinterName, &hPrinter, NULL ) ) { HANDLE hChangeNotification = NULL; // --------------------------------------------- // Setup the structures needed to register for print spool notifications // --------------------------------------------- PRINTER_NOTIFY_INFO_DATA NotifyInfoData[] = { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, 0, // Reserved JOB_NOTIFY_TYPE, 0 }; PRINTER_NOTIFY_OPTIONS_TYPE NotifyOptionsType[] = { JOB_NOTIFY_TYPE, 0, // Reserved 0 0, // Reserved 1 0, // Reserved 2 _countof(NotifyInfoData), (PWORD)NotifyInfoData }; PRINTER_NOTIFY_OPTIONS NotifyOptions; ZeroMemory( &NotifyOptions, sizeof(NotifyOptions) ); NotifyOptions.Version = 2; NotifyOptions.Count = _countof(NotifyOptionsType); NotifyOptions.pTypes = NotifyOptionsType; // --------------------------------------------- // Request a notification handle that will be signaled when a new print job is queued // --------------------------------------------- hChangeNotification = FindFirstPrinterChangeNotification( hPrinter, PRINTER_CHANGE_ADD_JOB, 0, // Reserved &NotifyOptions ); if ( INVALID_HANDLE_VALUE != hChangeNotification ) { do { // --------------------------------------------- // The order of these handles is important to the code below that checks which event was signaled // --------------------------------------------- HANDLE HandleList[] = { hChangeNotification, m_hExitSpoolMonitorThread }; // --------------------------------------------- // Wait for the print job notification handle or the exit handle to be signaled // --------------------------------------------- DWORD WaitReason = WaitForMultipleObjects( _countof(HandleList), HandleList, FALSE, INFINITE ); if ( WAIT_OBJECT_0 == WaitReason ) { PRINTER_NOTIFY_INFO *pPrinterNotifyInfo = NULL; // --------------------------------------------- // The notification handle was signaled so get the info about the print job // --------------------------------------------- if ( FindNextPrinterChangeNotification( hChangeNotification, NULL, &NotifyOptions, (LPVOID*)&pPrinterNotifyInfo ) ) { if ( NULL != pPrinterNotifyInfo ) { // --------------------------------------------- // Required code to make the FindNextPrinterChangeNotification happy (see MSDN documentation) // --------------------------------------------- if ( PRINTER_NOTIFY_INFO_DISCARDED & pPrinterNotifyInfo->Flags ) { FreePrinterNotifyInfo( pPrinterNotifyInfo ); pPrinterNotifyInfo = NULL; DWORD Flags = NotifyOptions.Flags; NotifyOptions.Flags = PRINTER_NOTIFY_OPTIONS_REFRESH; FindNextPrinterChangeNotification( hChangeNotification, NULL, &NotifyOptions, (LPVOID*)&pPrinterNotifyInfo ); NotifyOptions.Flags = Flags; } } // --------------------------------------------- // Get the needed information from the job // --------------------------------------------- DWORD JobId = 0; DWORD JobPages = 0; if ( NULL != pPrinterNotifyInfo ) { GetJobInfoFromPrinterNotifyInfo( pPrinterNotifyInfo, &JobId, &JobPages ); FreePrinterNotifyInfo( pPrinterNotifyInfo ); pPrinterNotifyInfo = NULL; } // --------------------------------------------- // Pause the print job // --------------------------------------------- if ( SetJob( hPrinter, JobId, 0, NULL, JOB_CONTROL_PAUSE ) ) { // --------------------------------------------- // If we weren't able to get the number of pages already // then get the count from the job itself // --------------------------------------------- if ( 0 == JobPages ) { JobPages = JobPagesFromJobId( hPrinter, JobId ); } // --------------------------------------------- // Interact with the user to determine if they would really like to print // --------------------------------------------- BOOL ResumeJob = ShouldResumePrintJob( JobPages ); if ( ResumeJob ) { if ( !SetJob( hPrinter, JobId, 0, NULL, JOB_CONTROL_RESUME ) ) { m_pLogging->Log( L"Failed resuming print job." ); } } else { if ( !SetJob( hPrinter, JobId, 0, NULL, JOB_CONTROL_DELETE ) ) { m_pLogging->Log( L"Failed deleting print job." ); } } } } else { m_pLogging->Log( L"Failed getting information concerning a print job." ); } } else if ( ( WAIT_OBJECT_0 + 1 ) == WaitReason ) { // --------------------------------------------- // The exit handle was signaled. Stop checking for print jobs. // --------------------------------------------- break; } else { m_pLogging->Log( L"Unexpected notification while waiting for print job." ); } } while( TRUE ); } else { m_pLogging->Log( L"Failed trying to get print job notification handle." ); } if ( INVALID_HANDLE_VALUE != hChangeNotification ) { FindClosePrinterChangeNotification( hChangeNotification ); hChangeNotification = NULL; } if ( NULL != hPrinter ) { ClosePrinter( hPrinter ); hPrinter = NULL; } } } if ( NULL != PrinterName ) { cchPrinterName = 0; LocalFree( PrinterName ); PrinterName = NULL; } } } return NO_ERROR; }
int main (int argc, char* argv[]) { HANDLE server, change; PRINTER_NOTIFY_INFO *change_info = NULL; PRINTER_NOTIFY_OPTIONS watch, *pWatch = NULL; PRINTER_NOTIFY_OPTIONS_TYPE data; DWORD option = PRINTER_CHANGE_PRINTER_DRIVER; BOOL use_notify_options = TRUE; DWORD condition; DWORD flags = PRINTER_NOTIFY_OPTIONS_REFRESH; if ((argc < 3) || (strcmp(argv[1], "-l") && strcmp(argv[1], "-t"))) { fprintf (stderr, "usage: -l|-t %s <servername>\n", argv[0]); exit (-1); } if (strcmp(argv[1], "-l") == 0) use_notify_options = FALSE; if (!OpenPrinter (argv[2], &server, NULL)) { PrintLastError(); exit (-1); } else { printf ("Printer [%s] opened successfully.\n\n", argv[2]); } printf ("flags = PRINTER_CHANGE_PRINTER\n"); watch.Version = 2; watch.Count = 1; watch.pTypes = &data; data.Type = PRINTER_NOTIFY_TYPE; data.Count = 1; data.pFields = &option; if (use_notify_options) { pWatch = &watch; option = PRINTER_NOTIFY_FIELD_DRIVER_NAME; } if ((change=FindFirstPrinterChangeNotification(server, option, 0, pWatch)) == INVALID_HANDLE_VALUE) { printf ("FindFirstPrinterChangeNotification failed : "); PrintLastError(); ClosePrinter(server); exit (-1); } else printf ("FindFirstPrinterChangeNotification succeeded with flags [PRINTER_CHANGE_PRINTER_DRIVER]\n\n"); if (pWatch) { printf ("Calling FindNextPrinterCangeNotification() with PRINTER_NOTIFY_OPTIONS_REFRESH\n"); memset(&watch, 0x0, sizeof(watch)); watch.Flags = PRINTER_NOTIFY_OPTIONS_REFRESH; watch.Version = 2; if (FindNextPrinterChangeNotification(change, &condition, pWatch, &change_info)) printf ("Received change notification of [0x%x]\n", condition); else PrintLastError(); if (change_info) { int i; printf("\tVersion\t=0x%x\n", change_info->Version); printf("\tFlags\t=0x%x\n", change_info->Flags); printf("\tCount\t=%d\n", change_info->Count); for (i=0; i<(int)change_info->Count; i++) { PrintNotifyInfoData(&change_info->aData[i]); printf("\n"); } } FreePrinterNotifyInfo(change_info); printf ("\n"); } do { printf ("Waiting for Printer Change Notification...\n"); if (WaitForSingleObject(change, INFINITE) != WAIT_OBJECT_0) continue; if (FindNextPrinterChangeNotification(change, &condition, NULL, &change_info)) printf ("Received change notification of [0x%x]\n", condition); else PrintLastError(); if (change_info) { int i; printf("\tVersion\t=0x%x\n", change_info->Version); printf("\tFlags\t=0x%x\n", change_info->Flags); printf("\tCount\t=%d\n", change_info->Count); for (i=0; i<(int)change_info->Count; i++) { PrintNotifyInfoData(&change_info->aData[i]); printf("\n"); } } FreePrinterNotifyInfo(change_info); printf ("\n"); } while (1); if (FindClosePrinterChangeNotification(change)) printf ("FindClosePrinterChangeNotification call succeeded.\n"); else { printf ("FindClosePrinterChangeNotification failed : "); PrintLastError(); } printf ("\n"); if (!ClosePrinter(server)) PrintLastError(); else printf ("Printer [%s] closed successfully.\n", argv[2]); return 0; }