08-12-2015 03:38 PM - edited 08-12-2015 03:38 PM
Let's make it as simple as possible. In your parameters set the minimum size of pPrinter to be cbBuf (select from the pulldown)
08-12-2015 04:10 PM
OK, I think I can duplicate what you're seeing, with the snippet below. For any level other than 3, GetLastError returns error 124, "The system call level is not correct." No idea what that means. With level set to 3, the first call returns error 122, "The data area passed to a system call is too small." which makes sense, and the second call succeeds. If your setup matches this, then I would say that you have properly configured the function calls from the LabVIEW side, and you need to figure out what parameters you need to set to OpenPrinter/AddPrinter to get the right system level, whatever that is.
08-12-2015 04:42 PM
@DB_IQ wrote:
I understand the function needs to be run twice. But should it not return a non-zero answer for the first run?
The first call will "fail" despite giving us exactly what we want (the size) and this is expected. This is a quite common idiom in Windows API programming.
08-12-2015 05:20 PM
@Darin.K wrote:
Let's make it as simple as possible. In your parameters set the minimum size of pPrinter to be cbBuf (select from the pulldown)
What kind of node is that for GetPrinterA? I am using Call Library Function Node.
08-12-2015 05:23 PM - edited 08-12-2015 05:27 PM
@nathand wrote:
OK, I think I can duplicate what you're seeing, with the snippet below. For any level other than 3, GetLastError returns error 124, "The system call level is not correct." No idea what that means. With level set to 3, the first call returns error 122, "The data area passed to a system call is too small." which makes sense, and the second call succeeds. If your setup matches this, then I would say that you have properly configured the function calls from the LabVIEW side, and you need to figure out what parameters you need to set to OpenPrinter/AddPrinter to get the right system level, whatever that is.
Both this sample and the sample Darin posted are almost exactly what my process is doing.
But for me, the return on the second GetPrinter is still 0.
My pcbNeeded for the first printer was 4544, but the pPrinter pointer returned an empty array out of the second GetPrinterA.
I am testing my default printer, which is a network printer.
I downreved my VI, attached, to 2012. Hopefully it works for you.
Thank you both.
08-12-2015 05:49 PM
Try my code. It's a "snippet", meaning you can drag it directly onto a block diagram (or you might need to drag it to the desktop first, and then drag from there into a block diagram) and run it. Does it work for you? Compare the call library function configuration to yours.
I can't test your code properly without seeing how you're calling GetPrinter or AddPrinter to get the handle in the first place. One detail I noticed is that you should configure the Minimum Size of pPrinter to be cbBuf (in the call library configuration setup).
You might notice in my code I added a call to GetLastError so you can see what error occurred; you can look up the error codes on MSDN.
08-12-2015 06:14 PM
You did not follow my advice to set the minimum size of pPrinter to cpBuf in the parameters tab. (BTW I show names in the CLFN). You either have to initiliaze an array with sufficient size or use the minimum size setting.
08-13-2015 09:42 AM
Ah, I see. I overlooked that with my multitasking.
I made that correction and everything works now.
Both my VI and the snippet VI appear to work.
Thank you very much. Now onto the next problem!
08-13-2015 11:17 AM
So my problem is solved but I have one last question:
Now that I have an array of pPrinter as an ouput, how can I parse it?
The typedef of this variable in MSDN is a pretty complex structure.
https://msdn.microsoft.com/en-us/library/windows/desktop/dd162845(v=vs.85).aspx
I am specifically interested in getting the number of jobs cJobs.
If I can do this, I can do pretty much everything I need to do with this driver/dll.
08-13-2015 01:02 PM
Fortunately, that value looks relatively easy to retrieve. Create a cluster that matches the _PRINTER_INFO_2 structure. All the pointer types (LP* and PSECURITY_DESCRIPTOR) are 32-bit or 64-bit values depending on whether you're using 32- or 64-bit LabVIEW. Convert the array of bytes to a string, then use "unflatten from string" to unflatten that string into the cluster, then unbundle cJobs. You will probably need to set the unflatten endianness input to little-endian. If you expect to run this code on both 32- and 64-bit LabVIEW, then you will need two cases, one for each pointer size, and select the appropriate one.