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>
11 static PCWSTR _pwszDatatypes
[] = {
18 * @name ClosePrintProcessor
20 * Closes a Print Processor Handle that has previously been opened through OpenPrintProcessor.
22 * @param hPrintProcessor
23 * The return value of a previous successful OpenPrintProcessor call.
26 * TRUE if the Print Processor Handle was successfully closed, FALSE otherwise.
27 * A more specific error code can be obtained through GetLastError.
30 ClosePrintProcessor(HANDLE hPrintProcessor
)
33 PWINPRINT_HANDLE pHandle
;
35 TRACE("ClosePrintProcessor(%p)\n", hPrintProcessor
);
40 dwErrorCode
= ERROR_INVALID_HANDLE
;
44 pHandle
= (PWINPRINT_HANDLE
)hPrintProcessor
;
46 // Free all structure fields for which memory has been allocated.
47 if (pHandle
->pwszDatatype
)
48 DllFreeSplStr(pHandle
->pwszDatatype
);
50 if (pHandle
->pwszDocumentName
)
51 DllFreeSplStr(pHandle
->pwszDocumentName
);
53 if (pHandle
->pwszOutputFile
)
54 DllFreeSplStr(pHandle
->pwszOutputFile
);
56 if (pHandle
->pwszPrinterPort
)
57 DllFreeSplStr(pHandle
->pwszPrinterPort
);
59 // Finally free the WINSPOOL_HANDLE structure itself.
60 DllFreeSplMem(pHandle
);
61 dwErrorCode
= ERROR_SUCCESS
;
64 SetLastError(dwErrorCode
);
65 return (dwErrorCode
== ERROR_SUCCESS
);
69 ControlPrintProcessor(HANDLE hPrintProcessor
, DWORD Command
)
71 TRACE("ControlPrintProcessor(%p, %lu)\n", hPrintProcessor
, Command
);
78 * @name EnumPrintProcessorDatatypesW
80 * Obtains an array of all datatypes supported by this Print Processor.
83 * Server Name. Ignored here, because every caller of EnumPrintProcessorDatatypesW is interested in this Print Processor's information.
85 * @param pPrintProcessorName
86 * Print Processor Name. Ignored here, because every caller of EnumPrintProcessorDatatypesW is interested in this Print Processor's information.
89 * The level of the structure supplied through pDatatypes. This must be 1.
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.
96 * Size of the buffer you supplied for pDatatypes, in bytes.
99 * Pointer to a variable that receives the required size of the buffer for pDatatypes, in bytes.
100 * This parameter mustn't be NULL!
103 * Pointer to a variable that receives the number of elements of the DATATYPES_INFO_1W array.
104 * This parameter mustn't be NULL!
107 * TRUE if we successfully copied the array into pDatatypes, FALSE otherwise.
108 * A more specific error code can be obtained through GetLastError.
111 EnumPrintProcessorDatatypesW(PWSTR pName
, PWSTR pPrintProcessorName
, DWORD Level
, PBYTE pDatatypes
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
114 DWORD dwDatatypeCount
= 0;
116 DWORD dwOffsets
[_countof(_pwszDatatypes
)];
117 PCWSTR
* pCurrentDatatype
;
118 PDWORD pCurrentOffset
= dwOffsets
;
120 TRACE("EnumPrintProcessorDatatypesW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName
, pPrintProcessorName
, Level
, pDatatypes
, cbBuf
, pcbNeeded
, pcReturned
);
123 if (Level
!= 1 || !pcbNeeded
|| !pcReturned
)
125 dwErrorCode
= ERROR_INVALID_PARAMETER
;
129 // Count the required buffer size and the number of datatypes.
133 for (pCurrentDatatype
= _pwszDatatypes
; *pCurrentDatatype
; pCurrentDatatype
++)
135 cbDatatype
= (wcslen(*pCurrentDatatype
) + 1) * sizeof(WCHAR
);
136 *pcbNeeded
+= sizeof(DATATYPES_INFO_1W
) + cbDatatype
;
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
);
145 // Check if the supplied buffer is large enough.
146 if (cbBuf
< *pcbNeeded
)
148 dwErrorCode
= ERROR_INSUFFICIENT_BUFFER
;
152 // Check if a buffer was supplied at all.
155 dwErrorCode
= ERROR_INVALID_PARAMETER
;
159 // Copy over all datatypes.
160 *pCurrentOffset
= MAXDWORD
;
161 PackStrings(_pwszDatatypes
, pDatatypes
, dwOffsets
, &pDatatypes
[*pcbNeeded
]);
163 *pcReturned
= dwDatatypeCount
;
164 dwErrorCode
= ERROR_SUCCESS
;
167 SetLastError(dwErrorCode
);
168 return (dwErrorCode
== ERROR_SUCCESS
);
173 GetPrintProcessorCapabilities(PWSTR pValueName
, DWORD dwAttributes
, PBYTE pData
, DWORD nSize
, PDWORD pcbNeeded
)
175 TRACE("GetPrintProcessorCapabilities(%S, %lu, %p, %lu, %p)\n", pValueName
, dwAttributes
, pData
, nSize
, pcbNeeded
);
182 * @name OpenPrintProcessor
184 * Prepares this Print Processor for processing a document.
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.
189 * @param pPrintProcessorOpenData
190 * Pointer to a PRINTPROCESSOROPENDATA structure containing details about the print job to be processed.
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.
197 OpenPrintProcessor(PWSTR pPrinterName
, PPRINTPROCESSOROPENDATA pPrintProcessorOpenData
)
200 HANDLE hReturnValue
= NULL
;
201 PWINPRINT_HANDLE pHandle
= NULL
;
203 TRACE("OpenPrintProcessor(%S, %p)\n", pPrinterName
, pPrintProcessorOpenData
);
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
)
209 dwErrorCode
= ERROR_INVALID_PARAMETER
;
213 // Create a new WINPRINT_HANDLE structure and fill the relevant fields.
214 pHandle
= DllAllocSplMem(sizeof(WINPRINT_HANDLE
));
216 // Check what datatype was given.
217 if (wcsicmp(pPrintProcessorOpenData
->pDatatype
, L
"RAW") == 0)
219 pHandle
->Datatype
= RAW
;
223 dwErrorCode
= ERROR_INVALID_DATATYPE
;
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
);
234 // We were successful! Return the handle and don't let the cleanup routine free it.
235 dwErrorCode
= ERROR_SUCCESS
;
236 hReturnValue
= pHandle
;
241 DllFreeSplMem(pHandle
);
243 SetLastError(dwErrorCode
);
248 * @name PrintDocumentOnPrintProcessor
250 * Prints a document on this Print Processor after a handle for the document has been opened through OpenPrintProcessor.
252 * @param hPrintProcessor
253 * The return value of a previous successful OpenPrintProcessor call.
255 * @param pDocumentName
256 * String in the format "Printer, Job N" describing the spooled job that is to be processed.
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.
263 PrintDocumentOnPrintProcessor(HANDLE hPrintProcessor
, PWSTR pDocumentName
)
266 PWINPRINT_HANDLE pHandle
;
268 TRACE("PrintDocumentOnPrintProcessor(%p, %S)\n", hPrintProcessor
, pDocumentName
);
271 if (!hPrintProcessor
)
273 dwErrorCode
= ERROR_INVALID_HANDLE
;
277 pHandle
= (PWINPRINT_HANDLE
)hPrintProcessor
;
279 // Call the corresponding Print function for the datatype.
280 if (pHandle
->Datatype
== RAW
)
281 dwErrorCode
= PrintRawJob(pHandle
, pDocumentName
);
284 SetLastError(dwErrorCode
);
285 return (dwErrorCode
== ERROR_SUCCESS
);