Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

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

Posted on 2007-11-20
3
Medium Priority
?
441 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 2000 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: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying 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 shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
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…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…

596 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