Solved

GetPrinter function fails to retrieves the printer information.

Posted on 2008-10-14
8
1,225 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
  • 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

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

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

726 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