Printer WaitForSingleObject problems

The code below is SUPPOSED to wait until the print spooler has a job submitted to it. Unfortunately, it always returns IMMEDIATELY from the WaitForSingleObject without waiting for a job! All above this point doesn't error (have stripped out error checking!
/////////////////////////////////////////////////
DWORD needed, returned;
HANDLE printer = 0;
BOOL didit;
PRINTER_INFO_1 printers[255];
PRINTER_DEFAULTS pdefaults;
DWORD event;
HANDLE changenotify;

EnumPrinters((DWORD)PRINTER_ENUM_NAME,(LPTSTR)"Windows 95 Local Print Provider",
            (DWORD)1,(LPBYTE)printers,sizeof(PRINTER_INFO_1)*255,
            &needed,&returned);
pdefaults.pDatatype = NULL;
pdefaults.pDevMode = NULL;
pdefaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
OpenPrinter(printers[0].pName,(LPHANDLE)&printer,(LPPRINTER_DEFAULTS)&pdefaults);
// Now let's see if we can wait for a job!
changenotify = FindFirstPrinterChangeNotification(printer,PRINTER_CHANGE_ALL,0,NULL);
event = WaitForSingleObject(changenotify,INFINITE);
MessageBox("Wait Completed","Wait");
if(event==WAIT_FAILED)
{
      char buff[50];
/////////////////////////////////////////////////////////////////////////////////////
      wsprintf(buff,"failed...%d",GetLastError()); // **HERE IS WHERE IT ALWAYS FAILS!! ** With the informative error code 6!!!
////////////////////////////////////////////////////////////////////////////////////
      MessageBox(buff);
}
else if(event == PRINTER_CHANGE_JOB)
{
      MessageBox("Yippee Printer change job signalled\n","Mwuhahaha");
}
else
{
      sprintf(buff,"Hmmm....wait returned %d",event);
      EditBox->SetText(buff);
}
nmsltdAsked:
Who is Participating?
 
NickRepinCommented:
You cannot use FindFirstPrinterChange... in Windows95 (see comments above). This function just does nothing and returns 0 (not INVALID_HANDLE_VALUE!!!).

That is output of my little test program (code see below):

*** EnumPrinters() 1 0 Needed:396 Returned: 5
pDesc: HP LaserJet 4P,HP LaserJet 4P,
pName: HP LaserJet 4P
pComment:
*** OpenPrinter() 1 0 Handle:0x005105a8
*** ChangeNotify() 1 78 Handle:0x00000000
*** WaitForSingleObject() 0 6 Handle:ffffffff


//**************************************
// Here is test program
//**************************************

#include <iostream.h>
#include <windows.h>

// Compile as BCC32 -WM <filename>
void main(int argc,char* argv[])
{
   if(argc<2) return;

   BOOL r;
   DWORD needed, returned;
   PRINTER_INFO_1 printers[255];
   cout<<"*** EnumPrinters() ";
   r=EnumPrinters(PRINTER_ENUM_NAME,argv[1],1,LPBYTE(&printers[0]),sizeof(printers),
      &needed,&returned);
   cout<<r<<' '<<GetLastError()<<" Needed:"<<needed<<" Returned: "<<returned<<endl;
   if(!r) return;
   cout<<"pDesc: "<<printers[0].pDescription<<endl<<"pName: "<<printers[0].pName<<endl<<
      "pComment: "<<printers[0].pComment<<endl;

   HANDLE printer = 0;
   PRINTER_DEFAULTS pdefaults;
   pdefaults.pDatatype = NULL;
   pdefaults.pDevMode = NULL;
   pdefaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
   cout<<"*** OpenPrinter() ";
   r=OpenPrinter(printers[0].pName,&printer,&pdefaults);
   cout<<r<<' '<<GetLastError()<<" Handle:"<<hex<<printer<<endl;
   if(!r) return;

   cout<<"*** ChangeNotify() ";
   HANDLE changenotify=FindFirstPrinterChangeNotification(printer,PRINTER_CHANGE_ALL,0,NULL);
   cout<<(changenotify!=INVALID_HANDLE_VALUE)<<' '<<GetLastError()<<" Handle:"<<hex<<
      changenotify<<endl;
   if(changenotify==INVALID_HANDLE_VALUE) return;

   cout<<"*** WaitForSingleObject() ";
   DWORD event=WaitForSingleObject(changenotify,INFINITE);
   cout<<(event!=WAIT_FAILED)<<' '<<GetLastError()<<" Handle:"<<hex<<event<<endl;
   if(event==WAIT_FAILED) return;

   cout<<"Wait success: "<<event<<endl;
}
0
 
NickRepinCommented:
What is error code (returned by GetLastError) printed in follow statement?

if(event==WAIT_FAILED) { wsprintf(buff,"failed...%d",GetLastError());
0
 
nmsltdAuthor Commented:
Edited text of question
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
NickRepinCommented:
Error code 6 mean 'Invalid handle'
Did you check changenotyfy variable after calling FindFirstPrinterChangeNotification() to make sure it is not equal INVALID_HANDLE_VALUE? If so, invoke GetLastError() immediately after this call and check error code.

Also, is OpenPrinter() return TRUE?
0
 
NickRepinCommented:
I'm not sure you can set these values to NULL:
  pdefaults.pDatatype = NULL;
  pdefaults.pDevMode = NULL;

May be, better try this:
OpenPrinter(printers[0].pName,(LPHANDLE)&printer,NULL);




0
 
NickRepinCommented:
If it works, please let me know to turn comments into answer.
0
 
amartin030297Commented:
also make sure your linking to the multi-threaded libraries, because by default (msvc 4.x and 5.x) they are single-threaded..

0
 
nmsltdAuthor Commented:
In response to above comments:
Yes I do check for INVALID_HANDLE_VALUE (it's ok).
OpenPrinter does indeed return TRUE.

According to the Borland C++ V5 helpdoc on open printer:
".....or obtain a handle to a print server to call WaitForPrinterChange. To do so, it should call OpenPrinter with pPrinterName set to the name of the server and should specify a server access mask value such as SERVER_ALL_ACCESS. The pDatatype and pDevMode members of the PRINTER_DEFAULTS data structure should be set to NULL. The handle returned by such a call may be passed to the ClosePrinter or WaitForPrinterChange function.

So (allegedly) you can set these values to NULL.

I am linking multithreading libraries.

I have tried OpenPrinter(printers[0].pName,(LPHANDLE)&printer,NULL);
Still doesn't work! :(

My only thoughts on the matter reading the above snippet from the helpdoc is that it says "print server". Is there a difference between a printer returned from EnumPrinters and a print server, or a print provider? I have found no real explanation of the terminology in any documentation (oh for a decent book on windows printer programming - are there any???)
Hope this clarifies the problem!
0
 
NickRepinCommented:
http://www.microsoft.com/win32dev/guidelns/apidiffs.htm DECLARES:

Printer change notification

Printer change notification print spooler functions are not supported on Windows 95 nor on Windows 95 OSR 2. The following functions are not supported:

FindClosePrinterChangeNotification

FindFirstPrinterChangeNotification

FindNextPrinterChangeNotification

WaitForPrinterChange
0
 
NickRepinCommented:
FindFirstPrinterChangeNotification() works fine for NT, but not for Windows95!
0
 
nmsltdAuthor Commented:
100% Correct! I discovered this myself at 1:30 this afternoon!
Great minds think alike, eh Nick?! Now all I have to figure out is how I'm going to implement FindFirstPrinterChangeNotification on win95 & the project's home and dry :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.