7771d732fc2d8df91ec15d7716af0a8ffe83d2c2
[reactos.git] / reactos / win32ss / printing / providers / localspl / printingthread.c
1 /*
2 * PROJECT: ReactOS Local Spooler
3 * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
4 * PURPOSE: Implementation of the Thread that actually performs the printing process
5 * COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 DWORD WINAPI
11 PrintingThreadProc(PLOCAL_JOB pJob)
12 {
13 const DWORD cchMaxJobIdDigits = 5; // Job ID is limited to 5 decimal digits, see IS_VALID_JOB_ID
14 const WCHAR wszJobAppendix[] = L", Job ";
15 const DWORD cchJobAppendix = _countof(wszJobAppendix) - 1;
16 const WCHAR wszPortAppendix[] = L", Port";
17
18 DWORD cchPortName;
19 DWORD cchPrinterName;
20 DWORD dwErrorCode;
21 HANDLE hPrintProcessor = NULL;
22 PLOCAL_PRINT_PROCESSOR pPrintProcessor = pJob->pPrintProcessor;
23 PRINTPROCESSOROPENDATA OpenData;
24 PWSTR pwszPrinterAndJob = NULL;
25 PWSTR pwszPrinterPort = NULL;
26 PWSTR pwszSPLFile = NULL;
27
28 // Prepare the pPrinterName parameter.
29 // This is the string for LocalOpenPrinter to open a port (e.g. "LPT1:, Port").
30 cchPortName = wcslen(pJob->pPrinter->pPort->pwszName);
31 pwszPrinterPort = DllAllocSplMem(cchPortName * sizeof(WCHAR) + sizeof(wszPortAppendix));
32 if (!pwszPrinterPort)
33 {
34 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
35 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
36 goto Cleanup;
37 }
38
39 CopyMemory(pwszPrinterPort, pJob->pPrinter->pPort->pwszName, cchPortName * sizeof(WCHAR));
40 CopyMemory(&pwszPrinterPort[cchPortName], wszPortAppendix, sizeof(wszPortAppendix));
41
42 // Prepare the pPrintProcessorOpenData parameter.
43 OpenData.JobId = pJob->dwJobID;
44 OpenData.pDatatype = pJob->pwszDatatype;
45 OpenData.pDevMode = pJob->pDevMode;
46 OpenData.pDocumentName = pJob->pwszDocumentName;
47 OpenData.pOutputFile = NULL;
48 OpenData.pParameters = pJob->pwszPrintProcessorParameters;
49 OpenData.pPrinterName = pJob->pPrinter->pwszPrinterName;
50
51 // Open a handle to the Print Processor.
52 hPrintProcessor = pPrintProcessor->pfnOpenPrintProcessor(pwszPrinterPort, &OpenData);
53 if (!hPrintProcessor)
54 {
55 dwErrorCode = GetLastError();
56 ERR("OpenPrintProcessor failed with error %lu!\n", dwErrorCode);
57 goto Cleanup;
58 }
59
60 // Let other functions use the Print Processor as well while it's opened.
61 pJob->hPrintProcessor = hPrintProcessor;
62
63 // Prepare the pDocumentName parameter.
64 cchPrinterName = wcslen(OpenData.pPrinterName);
65 pwszPrinterAndJob = DllAllocSplMem((cchPrinterName + cchJobAppendix + cchMaxJobIdDigits + 1) * sizeof(WCHAR));
66 if (!pwszPrinterAndJob)
67 {
68 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
69 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
70 goto Cleanup;
71 }
72
73 CopyMemory(pwszPrinterAndJob, OpenData.pPrinterName, cchPrinterName * sizeof(WCHAR));
74 CopyMemory(&pwszPrinterAndJob[cchPrinterName], wszJobAppendix, cchJobAppendix * sizeof(WCHAR));
75 _ultow(OpenData.JobId, &pwszPrinterAndJob[cchPrinterName + cchJobAppendix], 10);
76
77 // Print the document.
78 // Note that pJob is freed after this function, so we may not access it anymore.
79 if (!pPrintProcessor->pfnPrintDocumentOnPrintProcessor(hPrintProcessor, pwszPrinterAndJob))
80 {
81 dwErrorCode = GetLastError();
82 ERR("PrintDocumentOnPrintProcessor failed with error %lu!\n", dwErrorCode);
83 goto Cleanup;
84 }
85
86 // Close the Print Processor.
87 pPrintProcessor->pfnClosePrintProcessor(hPrintProcessor);
88 hPrintProcessor = NULL;
89
90 // Delete the spool file.
91 pwszSPLFile = DllAllocSplMem(GetJobFilePath(L"SPL", 0, NULL));
92 if (!pwszSPLFile)
93 {
94 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
95 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
96 goto Cleanup;
97 }
98
99 GetJobFilePath(L"SPL", OpenData.JobId, pwszSPLFile);
100 DeleteFileW(pwszSPLFile);
101
102 // We were successful!
103 dwErrorCode = ERROR_SUCCESS;
104
105 Cleanup:
106 if (hPrintProcessor)
107 pPrintProcessor->pfnClosePrintProcessor(hPrintProcessor);
108
109 if (pwszPrinterPort)
110 DllFreeSplMem(pwszPrinterPort);
111
112 if (pwszPrinterAndJob)
113 DllFreeSplMem(pwszPrinterAndJob);
114
115 if (pwszSPLFile)
116 DllFreeSplMem(pwszSPLFile);
117
118 return dwErrorCode;
119 }