Solved

How do I intercept a print job in another process (using Visual C++ 6.0)?

Posted on 2007-11-20
3
419 Views
Last Modified: 2013-12-04
I am writing a program in C++ that need to spy on all processes running in windows xp.
The program need to monitor the printing activities of these processes.

How can I hook or intercept a print job in another process?
0
Comment
Question by:shavit
  • 2
3 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 20323422
he easiest way is IMHO to use "FindNextPrinterChangeNotification()" (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_0tym.asp and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_390y.asp)- there is a "JOB_NOTIFY_TYPE" that has information about "JOB_NOTIFY_FIELD_TOTAL_PAGES" that will tell you how many pages are about to be printed. For a code sample, see http://nienie.com/~masapico/api_FindFirstPrinterChangeNotification.html - I hope your Japanese isn't as rusty as mine :o)

BTW, here's the code:

here's the code:

void DoPrtNotify()
{
     HANDLE hPrinter = INVALID_HANDLE_VALUE;
     HANDLE hNotify;
     BOOL b;
     PRINTER_NOTIFY_INFO *p;
     DWORD i;
     char *pBuf;
     DWORD *adwData;

     PRINTER_NOTIFY_OPTIONS no;
     PRINTER_NOTIFY_OPTIONS_TYPE not[2];
     WORD pnf[100], jnf[100];
     DWORD ChangeReason;

     no.Version = 2;
     no.Count = 2;
     no.pTypes = not;

     i = 0;
     pnf[i++] = PRINTER_NOTIFY_FIELD_SERVER_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_SHARE_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PORT_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_DRIVER_NAME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_COMMENT;
     pnf[i++] = PRINTER_NOTIFY_FIELD_LOCATION;
     pnf[i++] = PRINTER_NOTIFY_FIELD_SEPFILE;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PARAMETERS;
     pnf[i++] = PRINTER_NOTIFY_FIELD_DATATYPE;
     pnf[i++] = PRINTER_NOTIFY_FIELD_ATTRIBUTES;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PRIORITY;
     pnf[i++] = PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY;
     pnf[i++] = PRINTER_NOTIFY_FIELD_START_TIME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_UNTIL_TIME;
     pnf[i++] = PRINTER_NOTIFY_FIELD_STATUS_STRING;
     pnf[i++] = PRINTER_NOTIFY_FIELD_CJOBS;
     pnf[i++] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;
     pnf[i++] = PRINTER_NOTIFY_FIELD_TOTAL_PAGES;
     pnf[i++] = PRINTER_NOTIFY_FIELD_PAGES_PRINTED;
     pnf[i++] = PRINTER_NOTIFY_FIELD_TOTAL_BYTES;
     pnf[i++] = PRINTER_NOTIFY_FIELD_BYTES_PRINTED;

     not[0].Type = PRINTER_NOTIFY_TYPE;
     not[0].Count = i;
     not[0].pFields = pnf;

     i=0;
     jnf[i++] = JOB_NOTIFY_FIELD_PRINTER_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_MACHINE_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_PORT_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_USER_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_NOTIFY_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_DATATYPE;
     jnf[i++] = JOB_NOTIFY_FIELD_PRINT_PROCESSOR;
     jnf[i++] = JOB_NOTIFY_FIELD_PARAMETERS;
     jnf[i++] = JOB_NOTIFY_FIELD_DRIVER_NAME;
     jnf[i++] = JOB_NOTIFY_FIELD_STATUS_STRING;
     jnf[i++] = JOB_NOTIFY_FIELD_DOCUMENT;
     jnf[i++] = JOB_NOTIFY_FIELD_PRIORITY;
     jnf[i++] = JOB_NOTIFY_FIELD_POSITION;
     jnf[i++] = JOB_NOTIFY_FIELD_START_TIME;
     jnf[i++] = JOB_NOTIFY_FIELD_UNTIL_TIME;
     jnf[i++] = JOB_NOTIFY_FIELD_TIME;
     jnf[i++] = JOB_NOTIFY_FIELD_TOTAL_PAGES;
     jnf[i++] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
     jnf[i++] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
     jnf[i++] = JOB_NOTIFY_FIELD_BYTES_PRINTED;

     not[1].Type = JOB_NOTIFY_TYPE;
     not[1].Count = 20;
     not[1].pFields = jnf;


     b = OpenPrinter(
          "\\\\ringo\\ringoprt",
          &hPrinter,
          NULL);

     if(!b) {
          printf("printer can not open(%d)\n", GetLastError());
          return;
     }

     hNotify = FindFirstPrinterChangeNotification(
          hPrinter,
          PRINTER_CHANGE_ALL,
          0,
          &no);

     if(hNotify == INVALID_HANDLE_VALUE) {
          printf("find first fail(%d)\n", GetLastError());
          ClosePrinter(hPrinter);
          return;
     }

     for(;;) {

          WaitForSingleObject(hNotify, INFINITE);

          no.Flags = 0;

          b = FindNextPrinterChangeNotification(
               hNotify,
               &ChangeReason,
               &no,
               &p);

          if(!b) printf("find next error(%d)\n", GetLastError());

          printf("\nCxg-6...\n");
          printf("\tJmR: ");

          if(ChangeReason & PRINTER_CHANGE_ADD_PRINTER) printf("v
^G     A ");
          if(ChangeReason & PRINTER_CHANGE_SET_PRINTER) printf("v
^L]hOX " );
          if(ChangeReason & PRINTER_CHANGE_DELETE_PRINTER) printf("v
^m ");
          if(ChangeReason & PRINTER_CHANGE_FAILED_CONNECTION_PRINTER) printf("Z18s ");
          if(ChangeReason & PRINTER_CHANGE_ADD_JOB) printf("WuG     A ");
          if(ChangeReason & PRINTER_CHANGE_SET_JOB) printf("Wu]hOX ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_JOB) printf("Wum ");
          if(ChangeReason & PRINTER_CHANGE_WRITE_JOB) printf("Wu+] ");
          if(ChangeReason & PRINTER_CHANGE_ADD_FORM) printf("tH[G     A ");
          if(ChangeReason & PRINTER_CHANGE_SET_FORM) printf("tH[]hOX ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_FORM) printf("tH[m ");
          if(ChangeReason & PRINTER_CHANGE_ADD_PORT) printf("|[gG     A ");
          if(ChangeReason & PRINTER_CHANGE_CONFIGURE_PORT) printf("|[g]hOX ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_PORT) printf("|[gm ");
          if(ChangeReason & PRINTER_CHANGE_ADD_PRINT_PROCESSOR) printf("v
gvZbTG     A ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_PRINT_PROCESSOR) printf("v
gvZbTm ");
          if(ChangeReason & PRINTER_CHANGE_ADD_PRINTER_DRIVER) printf("h     CoG     A ");
          if(ChangeReason & PRINTER_CHANGE_SET_PRINTER_DRIVER) printf("h     Co]hOX ");
          if(ChangeReason & PRINTER_CHANGE_DELETE_PRINTER_DRIVER) printf("h     Com ");
          if(ChangeReason & PRINTER_CHANGE_TIMEOUT) printf("^CAEg ");
          printf("\n");

          if(p != NULL) {
               for(i=0; i<p->Count; i++) {
                    pBuf = p->aData[i].NotifyData.Data.pBuf;
                    adwData = p->aData[i].NotifyData.adwData;

                    switch(p->aData[i].Type) {
                    case PRINTER_NOTIFY_TYPE:
                         printf("\tv
^Jm(no.%d)...", i);
                         switch(p->aData[i].Field) {
                         case PRINTER_NOTIFY_FIELD_SERVER_NAME:
                              printf("T[o<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_PRINTER_NAME:
                              printf("v
^<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_SHARE_NAME:
                              printf(" $L<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_PORT_NAME:
                              printf("|[g<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_DRIVER_NAME:
                              printf("h     Co<F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_COMMENT:
                              printf("v
^L`>F%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_LOCATION:
                              printf("]uj
:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_DEVMODE:
                              // DEVMODE structure
                              break;
                         case PRINTER_NOTIFY_FIELD_SEPFILE:
                              printf(" fXht@C <:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR:
                              printf("v
gvZbT<:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_PARAMETERS:
                              printf("v
gvZbTLp     [^:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_DATATYPE:
                              printf("f[^Lm^:%s\n", pBuf);
                              break;
                         case PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR:
                              // SECURITY_DESCRIPTOR
                              break;
                         case PRINTER_NOTIFY_FIELD_ATTRIBUTES:
                              printf("v
^LsT:\n");
                              if(PRINTER_ATTRIBUTE_QUEUED & adwData[0]) printf("\t\tL[\n");
                              if(PRINTER_ATTRIBUTE_DIRECT & adwData[0]) printf("\t\tv
^I<Zf[^pi\n");
                              if(PRINTER_ATTRIBUTE_DEFAULT & adwData[0]) printf("\t\tftH g\n");
                              if(PRINTER_ATTRIBUTE_SHARED & adwData[0]) printf("\t\t $L7i\n");
                              if(PRINTER_ATTRIBUTE_NETWORK & adwData[0]) printf("\t\tlbg[N\n");
                              if(PRINTER_ATTRIBUTE_HIDDEN & adwData[0]) printf("\t\t     B5v
^\n");
                              if(PRINTER_ATTRIBUTE_LOCAL & adwData[0]) printf("\t\t[J v
^\n");
                              if(PRINTER_ATTRIBUTE_ENABLE_DEVQ & adwData[0]) printf("\t\tjv5H"hLgp[/7i\n");
                              if(PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS & adwData[0]) printf("\t\ts| chLgpc7\n");
                              if(PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST & adwData[0]) printf("\t\tXv[ 3j=hLgpE     Is|7i\n");
                              if(PRINTER_ATTRIBUTE_WORK_OFFLINE & adwData[0]) printf("\t\tIt     Cs|\n");
                              if(PRINTER_ATTRIBUTE_ENABLE_BIDI & adwData[0]) printf("\t\tenable BIDI(?)\n");
                              if(PRINTER_ATTRIBUTE_RAW_ONLY & adwData[0]) printf("\t\t<Zf[^ML]\n");
                              break;
                         case PRINTER_NOTIFY_FIELD_PRIORITY:
                              printf(" ;]LDfxF%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY:
                              printf("ftH gLDfx:%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_START_TIME:
                              printf("p     B\FHi
Jn
TF%02d:%02d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case PRINTER_NOTIFY_FIELD_UNTIL_TIME:
                              printf("ps     B\IHi
TF%02d:%02d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case PRINTER_NOTIFY_FIELD_STATUS:
                              if(adwData[0] & PRINTER_STATUS_PAUSED) printf("jb~ ");
                              if(adwData[0] & PRINTER_STATUS_ERROR) printf("G     [ ");
                              if(adwData[0] & PRINTER_STATUS_PENDING_DELETION) printf("pending_deletion ");
                              if(adwData[0] & PRINTER_STATUS_PAPER_JAM) printf(" l\h ");
                              if(adwData[0] & PRINTER_STATUS_PAPER_OUT) printf("ro ");
                              if(adwData[0] & PRINTER_STATUS_MANUAL_FEED) printf("manual_feed ");
                              if(adwData[0] & PRINTER_STATUS_PAPER_PROBLEM) printf("Lbh ");
                              if(adwData[0] & PRINTER_STATUS_OFFLINE) printf("It     C ");
                              if(adwData[0] & PRINTER_STATUS_IO_ACTIVE) printf("io_active ");
                              if(adwData[0] & PRINTER_STATUS_BUSY) printf("busy ");
                              if(adwData[0] & PRINTER_STATUS_PRINTING) printf("s| ");
                              if(adwData[0] & PRINTER_STATUS_OUTPUT_BIN_FULL) printf("output_bin_full ");
                              if(adwData[0] & PRINTER_STATUS_NOT_AVAILABLE) printf("not_available ");
                              if(adwData[0] & PRINTER_STATUS_WAITING) printf("R @ ");
                              if(adwData[0] & PRINTER_STATUS_PROCESSING) printf(" ");
                              if(adwData[0] & PRINTER_STATUS_INITIALIZING) printf("    
z     ; ");
                              if(adwData[0] & PRINTER_STATUS_WARMING_UP) printf("warming_up ");
                              if(adwData[0] & PRINTER_STATUS_TONER_LOW) printf("gi[*-H" ");
                              if(adwData[0] & PRINTER_STATUS_NO_TONER) printf("gi[*3" ");
                              if(adwData[0] & PRINTER_STATUS_PAGE_PUNT) printf("page_punt ");
                              if(adwData[0] & PRINTER_STATUS_USER_INTERVENTION) printf("user_intervention ");
                              if(adwData[0] & PRINTER_STATUS_OUT_OF_MEMORY) printf("out_of_memory ");
                              if(adwData[0] & PRINTER_STATUS_DOOR_OPEN) printf("door_open ");
                              if(adwData[0] & PRINTER_STATUS_SERVER_UNKNOWN) printf("server_unknown ");
                              if(adwData[0] & PRINTER_STATUS_POWER_SAVE) printf("power_save ");
                                   
                              break;
                         case PRINTER_NOTIFY_FIELD_STATUS_STRING:
                              printf("sTF%d\n", pBuf);
                         case PRINTER_NOTIFY_FIELD_CJOBS:
                              printf("L[I=_gj=WuL:%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_AVERAGE_PPM:
                              printf("Py[W =hL= Os|
T:%d*\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_TOTAL_PAGES:
                              printf("y[WF%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_PAGES_PRINTED:
                              printf("s|y[WF%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_TOTAL_BYTES:
                              printf("oCgF%d\n", adwData[0]);
                              break;
                         case PRINTER_NOTIFY_FIELD_BYTES_PRINTED:
                              printf("s|oCgF%d\n", adwData[0]);
                              break;
                         }
                         break;
                    case JOB_NOTIFY_TYPE:
                         printf("\tWuJm(no.%d, id:%d)...", i, p->aData[i].Id);
                         switch(p->aData[i].Field) {
                         case JOB_NOTIFY_FIELD_PRINTER_NAME:
                              printf("v
^<F%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_MACHINE_NAME:
                              printf("Wul, 3}V<F%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_PORT_NAME:
                              printf("|[gF%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_USER_NAME:
                              printf("Wul, 3[U<F%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_NOTIFY_NAME:
                              printf("Jmf[UF%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_DATATYPE:
                              printf("f[^Lm^:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_PRINT_PROCESSOR:
                              printf("v
gvZbT<:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_PARAMETERS:
                              printf("v
gvZbTVLp     [^:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_DRIVER_NAME:
                              printf("h     Co<:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_DEVMODE:
                              // DEVMODE
                              break;
                         case JOB_NOTIFY_FIELD_STATUS:
                              printf("WuLsT(flag):");
                              if(adwData[0] & JOB_STATUS_PAUSED) printf("jb~ ");
                              if(adwData[0] & JOB_STATUS_ERROR) printf("G     [ ");
                              if(adwData[0] & JOB_STATUS_DELETING) printf("m ");
                              if(adwData[0] & JOB_STATUS_SPOOLING) printf("Xv[  ");
                              if(adwData[0] & JOB_STATUS_PRINTING) printf("s| ");
                              if(adwData[0] & JOB_STATUS_OFFLINE) printf("It     C ");
                              if(adwData[0] & JOB_STATUS_PAPEROUT) printf("oM ");
                              if(adwData[0] & JOB_STATUS_PRINTED) printf("s|I9 ");
                              if(adwData[0] & JOB_STATUS_DELETED) printf("mI9 ");
                              if(adwData[0] & JOB_STATUS_BLOCKED_DEVQ) printf("blocked_dev_queue ");
                              if(adwData[0] & JOB_STATUS_USER_INTERVENTION) printf("user_intervention ");
                              if(adwData[0] & JOB_STATUS_RESTART) printf("
X^[g ");
                              printf("\n");
                              break;
                         case JOB_NOTIFY_FIELD_STATUS_STRING:
                              printf("WuLsT(msg):%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_DOCUMENT:
                              printf("hLg<:%s\n", pBuf);
                              break;
                         case JOB_NOTIFY_FIELD_PRIORITY:
                              printf("Dfx:%d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_POSITION:
                              printf("T:%d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_SUBMITTED:
                              //SYSTEMTIME
                              break;
                         case JOB_NOTIFY_FIELD_START_TIME:
                              printf("s|
Jn
T: %d:%d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case JOB_NOTIFY_FIELD_UNTIL_TIME:
                              printf("s|I9
T: %d:%d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case JOB_NOTIFY_FIELD_TIME:
                              printf(" o     _
T: %d: %d\n", adwData[0]/60, adwData[0]%60);
                              break;
                         case JOB_NOTIFY_FIELD_TOTAL_PAGES:
                              printf("s|: %d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_PAGES_PRINTED:
                              printf("s|: %d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_TOTAL_BYTES:
                              printf("oCg: %d\n", adwData[0]);
                              break;
                         case JOB_NOTIFY_FIELD_BYTES_PRINTED:
                              printf("s|oCg: %d\n", adwData[0]);
                              break;
                         }
                         break;
                    }
               }
               b = FreePrinterNotifyInfo(p);
               if(!b) printf("free error:%d\n", GetLastError());
          }
     }
     if(hPrinter!=INVALID_HANDLE_VALUE) {
          ClosePrinter(hPrinter);
          FindClosePrinterChangeNotification(hNotify);
     }
}
0
 

Author Comment

by:shavit
ID: 20337100
how can this be used to redirect to job to another printer?
0
 

Author Comment

by:shavit
ID: 20345337
is it possible to get the print job id or handle from FindNextPrinterChangeNotification?
0

Featured Post

Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question