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