+++ /dev/null
-/*
- * PROJECT: ReactOS Local Spooler
- * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
- * PURPOSE: Implementation of the Thread that actually performs the printing process
- * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
- */
-
-#include "precomp.h"
-
-DWORD WINAPI
-PrintingThreadProc(PLOCAL_JOB pJob)
-{
- const DWORD cchMaxJobIdDigits = 5; // Job ID is limited to 5 decimal digits, see IS_VALID_JOB_ID
- const WCHAR wszJobAppendix[] = L", Job ";
- const DWORD cchJobAppendix = _countof(wszJobAppendix) - 1;
- const WCHAR wszPortAppendix[] = L", Port";
-
- DWORD cchPortName;
- DWORD cchPrinterName;
- DWORD dwErrorCode;
- HANDLE hPrintProcessor = NULL;
- PLOCAL_PRINT_PROCESSOR pPrintProcessor = pJob->pPrintProcessor;
- PRINTPROCESSOROPENDATA OpenData;
- PWSTR pwszPrinterAndJob = NULL;
- PWSTR pwszPrinterPort = NULL;
- PWSTR pwszSPLFile = NULL;
-
- TRACE("PrintingThreadProc(%p)\n", pJob);
-
- // Prepare the pPrinterName parameter.
- // This is the string for LocalOpenPrinter to open a port (e.g. "LPT1:, Port").
- cchPortName = wcslen(pJob->pPrinter->pPort->pwszName);
- pwszPrinterPort = DllAllocSplMem(cchPortName * sizeof(WCHAR) + sizeof(wszPortAppendix));
- if (!pwszPrinterPort)
- {
- dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
- ERR("DllAllocSplMem failed!\n");
- goto Cleanup;
- }
-
- CopyMemory(pwszPrinterPort, pJob->pPrinter->pPort->pwszName, cchPortName * sizeof(WCHAR));
- CopyMemory(&pwszPrinterPort[cchPortName], wszPortAppendix, sizeof(wszPortAppendix));
-
- // Prepare the pPrintProcessorOpenData parameter.
- OpenData.JobId = pJob->dwJobID;
- OpenData.pDatatype = pJob->pwszDatatype;
- OpenData.pDevMode = pJob->pDevMode;
- OpenData.pDocumentName = pJob->pwszDocumentName;
- OpenData.pOutputFile = NULL;
- OpenData.pParameters = pJob->pwszPrintProcessorParameters;
- OpenData.pPrinterName = pJob->pPrinter->pwszPrinterName;
-
- // Associate our job to the port. The next port handle created through LocalOpenPrinter will pick this up.
- // LocalStartDocPrinter needs this information to call StartDocPort of the Print Monitor, but as the parameters
- // for LocalOpenPrinter and LocalStartDocPrinter are fixed, we can only pass over the information this way.
- pJob->pPrinter->pPort->pNextJobToProcess = pJob;
-
- // Open a handle to the Print Processor.
- hPrintProcessor = pPrintProcessor->pfnOpenPrintProcessor(pwszPrinterPort, &OpenData);
- if (!hPrintProcessor)
- {
- dwErrorCode = GetLastError();
- ERR("OpenPrintProcessor failed with error %lu!\n", dwErrorCode);
- goto Cleanup;
- }
-
- // Let other functions use the Print Processor as well while it's opened.
- pJob->hPrintProcessor = hPrintProcessor;
-
- // Prepare the pDocumentName parameter.
- cchPrinterName = wcslen(OpenData.pPrinterName);
- pwszPrinterAndJob = DllAllocSplMem((cchPrinterName + cchJobAppendix + cchMaxJobIdDigits + 1) * sizeof(WCHAR));
- if (!pwszPrinterAndJob)
- {
- dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
- ERR("DllAllocSplMem failed!\n");
- goto Cleanup;
- }
-
- CopyMemory(pwszPrinterAndJob, OpenData.pPrinterName, cchPrinterName * sizeof(WCHAR));
- CopyMemory(&pwszPrinterAndJob[cchPrinterName], wszJobAppendix, cchJobAppendix * sizeof(WCHAR));
- _ultow(OpenData.JobId, &pwszPrinterAndJob[cchPrinterName + cchJobAppendix], 10);
-
- // Printing starts here.
- pJob->dwStatus |= JOB_STATUS_PRINTING;
-
- // Print the document.
- // Note that pJob is freed after this function, so we may not access it anymore.
- if (!pPrintProcessor->pfnPrintDocumentOnPrintProcessor(hPrintProcessor, pwszPrinterAndJob))
- {
- dwErrorCode = GetLastError();
- ERR("PrintDocumentOnPrintProcessor failed with error %lu!\n", dwErrorCode);
- goto Cleanup;
- }
-
- // Close the Print Processor.
- pPrintProcessor->pfnClosePrintProcessor(hPrintProcessor);
- hPrintProcessor = NULL;
-
- // Delete the spool file.
- pwszSPLFile = DllAllocSplMem(GetJobFilePath(L"SPL", 0, NULL));
- if (!pwszSPLFile)
- {
- dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
- ERR("DllAllocSplMem failed!\n");
- goto Cleanup;
- }
-
- GetJobFilePath(L"SPL", OpenData.JobId, pwszSPLFile);
- DeleteFileW(pwszSPLFile);
-
- // We were successful!
- dwErrorCode = ERROR_SUCCESS;
-
-Cleanup:
- if (hPrintProcessor)
- pPrintProcessor->pfnClosePrintProcessor(hPrintProcessor);
-
- if (pwszPrinterPort)
- DllFreeSplMem(pwszPrinterPort);
-
- if (pwszPrinterAndJob)
- DllFreeSplMem(pwszPrinterAndJob);
-
- if (pwszSPLFile)
- DllFreeSplMem(pwszSPLFile);
-
- return dwErrorCode;
-}