Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1751
  • Last Modified:

OpenPrinter()gives me Access Violation!!!

I'm trying to code an printer log app. My printer is connected to an NT server. I'm using a funktion called FindFirstPrinterChangeNotification and before I can use this funktion I need a handle to my printer. I use the OpenPrinter funktion to get this handle but in return I get 0 wich indicates an error. When I check LastErrorCode the number is 87. My call to OpenPrinter is: BOOL bResult = OpenPrinter(PrinterName ,PrintHandle,&PrinterDefault); where PrinterName is "\\\\server\\printername" and PrinterDefault.DesiredAccess = PRINTER_ALL_ACCESS the rest of the struct is set to NULL. In my debug windows I get this message:
First-chance exception in PrinterLog.exe (WINSPOOL.DRV): 0xC0000005: Access Violation.

Can anybody give me a hint off what is wrong? Nikolaj Christoffersen
0
nc
Asked:
nc
  • 6
  • 2
1 Solution
 
nietodCommented:
I can give you a hint.  error 87 is caused by a bad parameter.  
0
 
nietodCommented:
I see the problem.  You are passing the handle, not a pointer to the handle.
0
 
nietodCommented:
Try

BOOL bResult = OpenPrinter(PrinterName,&PrintHandle,&PrinterDefault)

with a & before the handle.
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!

 
ncAuthor Commented:
>> I can give you a hint.  error 87 is caused by a bad parameter.
You are right the error 87 is a bad parameter but it dosn't solve my Access Violation error and the return value is still 0. Using & before the handle donsn't do anything either. My handle is declared as LPHANDLE if I want to use the & I ned to declare my handle as HANDLE.
0
 
nietodCommented:
I suspect the problem is in how you pass pointers to this procedure.  You declared the PrintHandle as LPHANDLE with is very unusual!  It can be done that way, but it is much harder so you are probably doing it incorrectly.  However, you are probably handling the last parameter PrinterDefault incorrectly as well.   I'll post some code.
0
 
nietodCommented:
When you see a parameter of type LPxxxxx it means window is expecting that the paramamter it gets is a pointer to a xxxxx type that it can access and alter.  It doesn't want to access the pointer, in the end it wants to access the xxxx that it points to.

All three parameter to OpenPrinter() are this way.  

Parameter 1:  Should be a pointer to a string.  This  is easy to do in C++ and you probably got it right.  It could be something like

char PrinterName[] = "\\\\server\\printername";
or
char * PrinterName = "\\\\server\\printername";

Eihter will work because the in both cases PrinterName will be a pointer to a string.  (It doesn't look like it in the first case, but it is).

Parameter 2:  Should point to a HANDLE.  Windows will change the value in the handle.
Thus you have several options.  You could do

HANDLE PrintHandle;

then pass &PrintHandle;  which passes a pointer to the handle that you declared

or you could do  

HANDLE PrintHandle;
LPHANDLE PrintHandlePtr = &PrintHandle;

then pass PrintHandlePtr (no &).  This passes a pointer to PrintHandle.  In either case windows will change PrintHandle.  You CANNOT do

LPHANDLE PrintHandle;

then pass PrintHandle.  Windows will try to change what PrintHandle points to. But you never made it point to anything so it will be poiting to a random location in memory.  This will cause a crash.


0
 
nietodCommented:
Parameter 3:  Must point to a PRINTER_DEFAULTS structure.  Again you can do this several ways.  Thea easiest is

PRINTER_DEFAULTS PrintDefault;

Then pass &PrintDefault.  Or you could do

PRINTER_DEFAULTS PrintDefault;
LPPRINTER_DEFAULTS PrinterDefaultPtr = &PrintDefault;

and then pass PrinterDefaultPtr.  Again, you cannot do

LPPRINTER_DEFAULTS PrintDefault and then pass PrintDefault.  Windows will dereference this pointer and you never made it point to a PRINTER_DEFAULTS for it.

Here is the simplist example.

char * PrinterName = "\\\\server\\printername";
HANDLE PrintHandle;
PRINTER_DEFAULTS PrintDefault;

BOOL bResult = OpenPrinter(PrinterName,&PrintHandle,&PrintDefault);

If this doesn't help, post your code.
0
 
ncAuthor Commented:
Thank you.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now