Solved

GetPrinter function fails to retrieves the printer information.

Posted on 2008-10-14
8
1,249 Views
Last Modified: 2013-12-14
Hi

 When I am trying to print the reports the GetPrinter function fails to retrieves the printer information.

First I am trying to get the printer handle for the specified printer using OpenPrinter function. .

HANDLE hPrinter = 0;
OpenPrinter ((LPTSTR)(LPCTSTR)strPrinterAddress, &hPrinter, NULL);

This function gets succeed. Using this printer handle I am trying to access the specified printer informations using the GetPrinter function.

GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded);
if(!dwNeeded)
{
  DWORD dwError = ::GetLastError();
  ClosePrinter( hPrinter );
   return 0;
}

Even using GetLastError() function I am not able retrieve error message. This function is not failing all the times. When I am trying to print out of 10 times, 6 times the printing is succeed. Only 4 times its getting failed. Please help me shoot out this problem.

Thanks
Gokul
0
Comment
Question by:iSOFT_India
[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
  • 4
  • 2
8 Comments
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22716474
You'd better go in with a sufficiently sized buffer:

char buffer[16*1024] = { 0 };
int rc = GetPrinter(hPrinter, 2, buffer, sizeof(buffer), &dwNeeded);
if(rc == FALSE)
{
   DWORD dwError = ::GetLastError();
   ClosePrinter( hPrinter );
   return 0;
}
PRINTER_INFO_2  pi2 = { 0 };
memcpy(&pi2, buffer, sizeof(pi2));


0
 

Author Comment

by:iSOFT_India
ID: 22718335
Hi
  First I am getting required size for the printer information in dwNeeded.
After that allocating the required buffer size and getting the printer information.
The below snippet is used retrieve the printer information.
Here I am trying to get the information of a network shared printer.


// get the printer handle
HANDLE hPrinter = 0;
if(OpenPrinter ((LPTSTR)(LPCTSTR)strPrinterAddress, &hPrinter, NULL))
{
      return 0;
}

//Allocate memory for pointer to printer structure
BYTE *pbPrinters;
DWORD dwBuf;
DWORD dwNeeded;
DWORD dwLevel = 2;      

//code added and modified by Smita B. for iAssist 436486 - Begins
GetPrinter(hPrinter, dwLevel, NULL, 0, &dwNeeded);

//Allocate the memory for the buffer
pbPrinters = new BYTE[ ++dwNeeded ];
 if( pbPrinters == NULL )
{
      return 0;
}
dwBuf = (DWORD)(dwNeeded - 1);

//Get the printer structure
if (!GetPrinter(hPrinter, dwLevel, pbPrinters, dwBuf, &dwNeeded))
{
        ClosePrinter( hPrinter );
         delete [] pbPrinters;
         return 0;            
}



Thanks
Gokul
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22719287
Did you still have problems?

The code looks ok, though you should check the return value of the first call to GetPrinter. In case it is zero, the GetLastError should point out the issue.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:iSOFT_India
ID: 22720374

Hi
In the first call of GetPrinter function I am checking the variable dwNeeded. System is not returning any error code. I have formatted the error code and printing the error message in the log file.
 
if(!dwNeeded)
{
DWORD dwError = ::GetLastError();
LPVOID lpMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | RMAT_MESSAGE_FROM_SYSTEM,
NULL, dwError, MAKELANGID(LANG_NEUTRAL, LANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0,NULL );
CString strMessage = (LPTSTR)lpMsgBuf;
FILE *fp = fopen("C:\\log.txt","a+");
fprintf(fp,"\n Error Occurred - %s ", strMessage );
fclose(fp);
 
 ClosePrinter( hPrinter );
  return 0;
}

in that log file it printed as
 
Error Occurred -

Thanks
Gokul
 
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
ID: 22722079
>>>> In the first call of GetPrinter function I am checking the variable dwNeeded.
First, in the code you posted, you didn't initialize the dwNeeded and you didn't check for return code of GetPrinter. The missing initialization may result to arbitrary values in dwNeeded in case the call to GetPrinter failed for any reason. So, the correct code would be

 
  //Allocate memory for pointer to printer structure
  BYTE *pbPrinters = NULL;
  DWORD dwBuf = 0;
  DWORD dwNeeded = 0;
  DWORD dwLevel = 2;      

  if (GetPrinter(hPrinter, dwLevel, NULL, NULL, &dwNeeded) == 0)
  {
     DWORD dwError = ::GetLastError();
     LPVOID lpMsgBuf;
     FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |    
                                FORMAT_MESSAGE_FROM_SYSTEM,
                                NULL, dwError,
                                MAKELANGID(LANG_NEUTRAL, LANG_DEFAULT),
                                (LPTSTR) &lpMsgBuf, 0,NULL );
     CString strMessage = (LPTSTR)lpMsgBuf;
     FILE *fp = fopen("C:\\log.txt","a+");
     fprintf(fp,"\n Error Occurred - %s ", strMessage );
     fclose(fp);
     ClosePrinter( hPrinter );
     return FALSE;
   
  }

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 22722109
Note, you showed different code in your comments. It makes not much sense to post code different to that which actually caused the errors. It is a good chance that the errors were in the original code but not in the code posted.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

In our object-oriented world the class is a minimal unit, a brick for constructing our applications. It is an abstraction and we know well how to use it. In well-designed software we are not usually interested in knowing how objects look in memory. …
Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.

632 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