using SetJob function in printspooler API

0

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.

c++
printing
print-spooler-api
asked on Stack Overflow Apr 25, 2017 by ashmont • edited May 10, 2017 by ashmont

1 Answer

3

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);
answered on Stack Overflow Apr 25, 2017 by Carey Gregory

User contributions licensed under CC BY-SA 3.0