+BOOL WINAPI
+LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
+{
+ DWORD dwErrorCode;
+ PBYTE pEnd = &pStart[cbBuf];
+ PLOCAL_HANDLE pHandle;
+ PLOCAL_JOB pJob;
+ PSKIPLIST_NODE pFirstJobNode;
+ PSKIPLIST_NODE pNode;
+ PLOCAL_PRINTER_HANDLE pPrinterHandle;
+
+ // Check if this is a printer handle.
+ pHandle = (PLOCAL_HANDLE)hPrinter;
+ if (pHandle->HandleType != Printer)
+ {
+ dwErrorCode = ERROR_INVALID_HANDLE;
+ goto Cleanup;
+ }
+
+ pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
+
+ // Check the level.
+ if (Level > 2)
+ {
+ dwErrorCode = ERROR_INVALID_LEVEL;
+ goto Cleanup;
+ }
+
+ // Begin counting.
+ *pcbNeeded = 0;
+ *pcReturned = 0;
+
+ // Lookup the node of the first job requested by the caller in the Printer's Job List.
+ pFirstJobNode = LookupNodeByIndexSkiplist(&pPrinterHandle->pPrinter->JobList, FirstJob);
+
+ // Count the required buffer size and the number of jobs.
+ pNode = pFirstJobNode;
+
+ while (*pcReturned < NoJobs && pNode)
+ {
+ pJob = (PLOCAL_JOB)pNode->Element;
+
+ // The function behaves differently for each level.
+ if (Level == 1)
+ _LocalGetJobLevel1(pPrinterHandle, pJob, NULL, NULL, 0, pcbNeeded);
+ else if (Level == 2)
+ _LocalGetJobLevel2(pPrinterHandle, pJob, NULL, NULL, 0, pcbNeeded);
+
+ // We stop either when there are no more jobs in the list or when the caller didn't request more, whatever comes first.
+ *pcReturned++;
+ pNode = pNode->Next[0];
+ }
+
+ // Check if the supplied buffer is large enough.
+ if (cbBuf < *pcbNeeded)
+ {
+ dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
+ goto Cleanup;
+ }
+
+ // Begin counting again and also empty the given buffer.
+ *pcbNeeded = 0;
+ *pcReturned = 0;
+ ZeroMemory(pStart, cbBuf);
+
+ // Now call the same functions again to copy the actual data for each job into the buffer.
+ pNode = pFirstJobNode;
+
+ while (*pcReturned < NoJobs && pNode)
+ {
+ pJob = (PLOCAL_JOB)pNode->Element;
+
+ // The function behaves differently for each level.
+ if (Level == 1)
+ dwErrorCode = _LocalGetJobLevel1(pPrinterHandle, pJob, &pStart, &pEnd, cbBuf, pcbNeeded);
+ else if (Level == 2)
+ dwErrorCode = _LocalGetJobLevel2(pPrinterHandle, pJob, &pStart, &pEnd, cbBuf, pcbNeeded);
+
+ if (dwErrorCode != ERROR_SUCCESS)
+ goto Cleanup;
+
+ // We stop either when there are no more jobs in the list or when the caller didn't request more, whatever comes first.
+ *pcReturned++;
+ pNode = pNode->Next[0];
+ }
+
+ dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
+}
+