I am using a getJobs function I found to get current print jobs in my printer (not print device). So far I can tell how many print jobs are in the queue of my virtual printer, and I have the information from JOB_INFO_ strucs to mess with, but I am trying to use SetJob() to delete the job from the print queue (after storing the information I want). With this I get an error:
0xC0000005: Access violation reading location 0x00002012.
My question is, what exactly am I doing wrong? I've tried putting 0 as level and NULL for pJob, then I do not get an error but the print job is still in the queue. I can't seem to find anyone else that has examples with explenations.
BOOL getJobs(LPTSTR printerName) {
HANDLE hPrinter; //Printer handle variable
DWORD dwNeeded, dwReturned, i; //Mem needed, jobs found, variable for loop
JOB_INFO_1 *pJobInfo; // pointer to structure
//Find printer handle
if (!OpenPrinter(printerName, &hPrinter, NULL)) {
return FALSE;
}
//Get amount of memory needed
if (!EnumJobs(hPrinter, 0, 0xFFFFFFFF, 1, NULL, 0, &dwNeeded, &dwReturned)) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
ClosePrinter(hPrinter);
return FALSE;
}
}
//Allocate the memory, if you cant end function
if ((pJobInfo = (JOB_INFO_1 *)malloc(dwNeeded)) == NULL) {
ClosePrinter(hPrinter);
return FALSE;
}
//Get job info struc
if (!EnumJobs(hPrinter, 0, 0xFFFFFFFF, 1, (LPBYTE)pJobInfo, dwNeeded, &dwNeeded, &dwReturned)) {
ClosePrinter(hPrinter);
free(pJobInfo);
return FALSE;
}
//If there are printjobs, get document name and data type. put into docinfo1 struc and return true
if (dwReturned > 0){
docinfo1.pDocName = pJobInfo[1].pDocument;
docinfo1.pDatatype = pJobInfo[1].pDatatype;
SetJob(hPrinter, pJobInfo[1].JobId, 2, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
ClosePrinter(hPrinter);
free(pJobInfo);
return TRUE;
}
//No print jobs, Free memory and finish up :>
ClosePrinter(hPrinter);
free(pJobInfo);
return FALSE;
}
Help is much appreciated.
EDIT: The issue ended up being a simple mistake in where I told SetJob the wrong struct type.
Aside from specifying a JOB_INFO_2
struct when you're actually passing a JOB_INFO_1
struct (as was pointed out in comments), you're also trying to use the second element of pJobInfo[]
, which may not even exist:
SetJob(hPrinter, pJobInfo[1].JobId, 2, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
Change it to:
SetJob(hPrinter, pJobInfo[0].JobId, 1, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
Or better yet, do this because all you need to delete a print job is the job ID:
SetJob(hPrinter, pJobInfo[0].JobId, 0, NULL, JOB_CONTROL_DELETE);