1385aab0e3058ebc371e43c0ed73f7887a831a50
[reactos.git] / reactos / win32ss / printing / processors / winprint / main.c
1 /*
2 * PROJECT: ReactOS Standard Print Processor
3 * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
4 * PURPOSE: Main functions
5 * COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 // Local Constants
11 static PCWSTR _pwszDatatypes[] = {
12 L"RAW",
13 0
14 };
15
16
17 /**
18 * @name ClosePrintProcessor
19 *
20 * Closes a Print Processor Handle that has previously been opened through OpenPrintProcessor.
21 *
22 * @param hPrintProcessor
23 * The return value of a previous successful OpenPrintProcessor call.
24 *
25 * @return
26 * TRUE if the Print Processor Handle was successfully closed, FALSE otherwise.
27 * A more specific error code can be obtained through GetLastError.
28 */
29 BOOL WINAPI
30 ClosePrintProcessor(HANDLE hPrintProcessor)
31 {
32 DWORD dwErrorCode;
33 PWINPRINT_HANDLE pHandle;
34
35 TRACE("ClosePrintProcessor(%p)\n", hPrintProcessor);
36
37 // Sanity checks
38 if (!hPrintProcessor)
39 {
40 dwErrorCode = ERROR_INVALID_HANDLE;
41 goto Cleanup;
42 }
43
44 pHandle = (PWINPRINT_HANDLE)hPrintProcessor;
45
46 // Free all structure fields for which memory has been allocated.
47 if (pHandle->pwszDatatype)
48 DllFreeSplStr(pHandle->pwszDatatype);
49
50 if (pHandle->pwszDocumentName)
51 DllFreeSplStr(pHandle->pwszDocumentName);
52
53 if (pHandle->pwszOutputFile)
54 DllFreeSplStr(pHandle->pwszOutputFile);
55
56 if (pHandle->pwszPrinterPort)
57 DllFreeSplStr(pHandle->pwszPrinterPort);
58
59 // Finally free the WINSPOOL_HANDLE structure itself.
60 DllFreeSplMem(pHandle);
61 dwErrorCode = ERROR_SUCCESS;
62
63 Cleanup:
64 SetLastError(dwErrorCode);
65 return (dwErrorCode == ERROR_SUCCESS);
66 }
67
68 BOOL WINAPI
69 ControlPrintProcessor(HANDLE hPrintProcessor, DWORD Command)
70 {
71 TRACE("ControlPrintProcessor(%p, %lu)\n", hPrintProcessor, Command);
72
73 UNIMPLEMENTED;
74 return FALSE;
75 }
76
77 /**
78 * @name EnumPrintProcessorDatatypesW
79 *
80 * Obtains an array of all datatypes supported by this Print Processor.
81 *
82 * @param pName
83 * Server Name. Ignored here, because every caller of EnumPrintProcessorDatatypesW is interested in this Print Processor's information.
84 *
85 * @param pPrintProcessorName
86 * Print Processor Name. Ignored here, because every caller of EnumPrintProcessorDatatypesW is interested in this Print Processor's information.
87 *
88 * @param Level
89 * The level of the structure supplied through pDatatypes. This must be 1.
90 *
91 * @param pDatatypes
92 * Pointer to the buffer that receives an array of DATATYPES_INFO_1W structures.
93 * Can be NULL if you just want to know the required size of the buffer.
94 *
95 * @param cbBuf
96 * Size of the buffer you supplied for pDatatypes, in bytes.
97 *
98 * @param pcbNeeded
99 * Pointer to a variable that receives the required size of the buffer for pDatatypes, in bytes.
100 * This parameter mustn't be NULL!
101 *
102 * @param pcReturned
103 * Pointer to a variable that receives the number of elements of the DATATYPES_INFO_1W array.
104 * This parameter mustn't be NULL!
105 *
106 * @return
107 * TRUE if we successfully copied the array into pDatatypes, FALSE otherwise.
108 * A more specific error code can be obtained through GetLastError.
109 */
110 BOOL WINAPI
111 EnumPrintProcessorDatatypesW(PWSTR pName, PWSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
112 {
113 DWORD cbDatatype;
114 DWORD dwDatatypeCount = 0;
115 DWORD dwErrorCode;
116 DWORD dwOffsets[_countof(_pwszDatatypes)];
117 PCWSTR* pCurrentDatatype;
118 PDWORD pCurrentOffset = dwOffsets;
119
120 TRACE("EnumPrintProcessorDatatypesW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
121
122 // Sanity checks
123 if (Level != 1 || !pcbNeeded || !pcReturned)
124 {
125 dwErrorCode = ERROR_INVALID_PARAMETER;
126 goto Cleanup;
127 }
128
129 // Count the required buffer size and the number of datatypes.
130 *pcbNeeded = 0;
131 *pcReturned = 0;
132
133 for (pCurrentDatatype = _pwszDatatypes; *pCurrentDatatype; pCurrentDatatype++)
134 {
135 cbDatatype = (wcslen(*pCurrentDatatype) + 1) * sizeof(WCHAR);
136 *pcbNeeded += sizeof(DATATYPES_INFO_1W) + cbDatatype;
137
138 // Also calculate the offset in the output buffer of the pointer to this datatype string.
139 *pCurrentOffset = dwDatatypeCount * sizeof(DATATYPES_INFO_1W) + FIELD_OFFSET(DATATYPES_INFO_1W, pName);
140
141 dwDatatypeCount++;
142 pCurrentOffset++;
143 }
144
145 // Check if the supplied buffer is large enough.
146 if (cbBuf < *pcbNeeded)
147 {
148 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
149 goto Cleanup;
150 }
151
152 // Check if a buffer was supplied at all.
153 if (!pDatatypes)
154 {
155 dwErrorCode = ERROR_INVALID_PARAMETER;
156 goto Cleanup;
157 }
158
159 // Copy over all datatypes.
160 *pCurrentOffset = MAXDWORD;
161 PackStrings(_pwszDatatypes, pDatatypes, dwOffsets, &pDatatypes[*pcbNeeded]);
162
163 *pcReturned = dwDatatypeCount;
164 dwErrorCode = ERROR_SUCCESS;
165
166 Cleanup:
167 SetLastError(dwErrorCode);
168 return (dwErrorCode == ERROR_SUCCESS);
169 }
170
171
172 DWORD WINAPI
173 GetPrintProcessorCapabilities(PWSTR pValueName, DWORD dwAttributes, PBYTE pData, DWORD nSize, PDWORD pcbNeeded)
174 {
175 TRACE("GetPrintProcessorCapabilities(%S, %lu, %p, %lu, %p)\n", pValueName, dwAttributes, pData, nSize, pcbNeeded);
176
177 UNIMPLEMENTED;
178 return 0;
179 }
180
181 /**
182 * @name OpenPrintProcessor
183 *
184 * Prepares this Print Processor for processing a document.
185 *
186 * @param pPrinterName
187 * String in the format "\\COMPUTERNAME\Port:, Port" that is passed to OpenPrinterW for writing to the Print Monitor on the specified port.
188 *
189 * @param pPrintProcessorOpenData
190 * Pointer to a PRINTPROCESSOROPENDATA structure containing details about the print job to be processed.
191 *
192 * @return
193 * A Print Processor handle on success or NULL in case of a failure. This handle has to be passed to PrintDocumentOnPrintProcessor to do the actual processing.
194 * A more specific error code can be obtained through GetLastError.
195 */
196 HANDLE WINAPI
197 OpenPrintProcessor(PWSTR pPrinterName, PPRINTPROCESSOROPENDATA pPrintProcessorOpenData)
198 {
199 DWORD dwErrorCode;
200 HANDLE hReturnValue = NULL;
201 PWINPRINT_HANDLE pHandle = NULL;
202
203 TRACE("OpenPrintProcessor(%S, %p)\n", pPrinterName, pPrintProcessorOpenData);
204
205 // Sanity checks
206 // This time a datatype needs to be given. We can't fall back to a default here.
207 if (!pPrintProcessorOpenData || !pPrintProcessorOpenData->pDatatype || !*pPrintProcessorOpenData->pDatatype)
208 {
209 dwErrorCode = ERROR_INVALID_PARAMETER;
210 goto Cleanup;
211 }
212
213 // Create a new WINPRINT_HANDLE structure and fill the relevant fields.
214 pHandle = DllAllocSplMem(sizeof(WINPRINT_HANDLE));
215
216 // Check what datatype was given.
217 if (wcsicmp(pPrintProcessorOpenData->pDatatype, L"RAW") == 0)
218 {
219 pHandle->Datatype = RAW;
220 }
221 else
222 {
223 dwErrorCode = ERROR_INVALID_DATATYPE;
224 goto Cleanup;
225 }
226
227 // Fill the relevant fields.
228 pHandle->dwJobID = pPrintProcessorOpenData->JobId;
229 pHandle->pwszDatatype = AllocSplStr(pPrintProcessorOpenData->pDatatype);
230 pHandle->pwszDocumentName = AllocSplStr(pPrintProcessorOpenData->pDocumentName);
231 pHandle->pwszOutputFile = AllocSplStr(pPrintProcessorOpenData->pOutputFile);
232 pHandle->pwszPrinterPort = AllocSplStr(pPrinterName);
233
234 // We were successful! Return the handle and don't let the cleanup routine free it.
235 dwErrorCode = ERROR_SUCCESS;
236 hReturnValue = pHandle;
237 pHandle = NULL;
238
239 Cleanup:
240 if (pHandle)
241 DllFreeSplMem(pHandle);
242
243 SetLastError(dwErrorCode);
244 return hReturnValue;
245 }
246
247 /**
248 * @name PrintDocumentOnPrintProcessor
249 *
250 * Prints a document on this Print Processor after a handle for the document has been opened through OpenPrintProcessor.
251 *
252 * @param hPrintProcessor
253 * The return value of a previous successful OpenPrintProcessor call.
254 *
255 * @param pDocumentName
256 * String in the format "Printer, Job N" describing the spooled job that is to be processed.
257 *
258 * @return
259 * TRUE if the document was successfully processed by this Print Processor, FALSE otherwise.
260 * A more specific error code can be obtained through GetLastError.
261 */
262 BOOL WINAPI
263 PrintDocumentOnPrintProcessor(HANDLE hPrintProcessor, PWSTR pDocumentName)
264 {
265 DWORD dwErrorCode;
266 PWINPRINT_HANDLE pHandle;
267
268 TRACE("PrintDocumentOnPrintProcessor(%p, %S)\n", hPrintProcessor, pDocumentName);
269
270 // Sanity checks
271 if (!hPrintProcessor)
272 {
273 dwErrorCode = ERROR_INVALID_HANDLE;
274 goto Cleanup;
275 }
276
277 pHandle = (PWINPRINT_HANDLE)hPrintProcessor;
278
279 // Call the corresponding Print function for the datatype.
280 if (pHandle->Datatype == RAW)
281 dwErrorCode = PrintRawJob(pHandle, pDocumentName);
282
283 Cleanup:
284 SetLastError(dwErrorCode);
285 return (dwErrorCode == ERROR_SUCCESS);
286 }