Solved

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

Posted on 2007-11-20
3
434 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
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…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…

729 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