2 * PROJECT: ReactOS Standard Print Processor
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Main functions
5 * COPYRIGHT: Copyright 2015-2017 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;
115 DWORD dwOffsets
[_countof(_pwszDatatypes
)];
116 PCWSTR
* pCurrentDatatype
;
117 PDWORD pCurrentOffset
= dwOffsets
;
119 TRACE("EnumPrintProcessorDatatypesW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName
, pPrintProcessorName
, Level
, pDatatypes
, cbBuf
, pcbNeeded
, pcReturned
);
122 if (Level
!= 1 || !pcbNeeded
|| !pcReturned
)
125 // Count the required buffer size and the number of datatypes.
129 for (pCurrentDatatype
= _pwszDatatypes
; *pCurrentDatatype
; pCurrentDatatype
++)
131 cbDatatype
= (wcslen(*pCurrentDatatype
) + 1) * sizeof(WCHAR
);
132 *pcbNeeded
+= sizeof(DATATYPES_INFO_1W
) + cbDatatype
;
134 // Also calculate the offset in the output buffer of the pointer to this datatype string.
135 *pCurrentOffset
= dwDatatypeCount
* sizeof(DATATYPES_INFO_1W
) + FIELD_OFFSET(DATATYPES_INFO_1W
, pName
);
141 // Check if the supplied buffer is large enough.
142 if (cbBuf
< *pcbNeeded
)
144 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
148 // Check if a buffer was supplied at all.
151 SetLastError(ERROR_INVALID_PARAMETER
);
155 // Copy over all datatypes.
156 *pCurrentOffset
= MAXDWORD
;
157 PackStrings(_pwszDatatypes
, pDatatypes
, dwOffsets
, &pDatatypes
[*pcbNeeded
]);
159 *pcReturned
= dwDatatypeCount
;
165 GetPrintProcessorCapabilities(PWSTR pValueName
, DWORD dwAttributes
, PBYTE pData
, DWORD nSize
, PDWORD pcbNeeded
)
167 TRACE("GetPrintProcessorCapabilities(%S, %lu, %p, %lu, %p)\n", pValueName
, dwAttributes
, pData
, nSize
, pcbNeeded
);
174 * @name OpenPrintProcessor
176 * Prepares this Print Processor for processing a document.
178 * @param pPrinterName
179 * String in the format "\\COMPUTERNAME\Port:, Port" that is passed to OpenPrinterW for writing to the Print Monitor on the specified port.
181 * @param pPrintProcessorOpenData
182 * Pointer to a PRINTPROCESSOROPENDATA structure containing details about the print job to be processed.
185 * 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.
186 * A more specific error code can be obtained through GetLastError.
189 OpenPrintProcessor(PWSTR pPrinterName
, PPRINTPROCESSOROPENDATA pPrintProcessorOpenData
)
192 HANDLE hReturnValue
= NULL
;
193 PWINPRINT_HANDLE pHandle
= NULL
;
195 TRACE("OpenPrintProcessor(%S, %p)\n", pPrinterName
, pPrintProcessorOpenData
);
198 // This time a datatype needs to be given. We can't fall back to a default here.
199 if (!pPrintProcessorOpenData
|| !pPrintProcessorOpenData
->pDatatype
|| !*pPrintProcessorOpenData
->pDatatype
)
201 dwErrorCode
= ERROR_INVALID_PARAMETER
;
205 // Create a new WINPRINT_HANDLE structure and fill the relevant fields.
206 pHandle
= DllAllocSplMem(sizeof(WINPRINT_HANDLE
));
208 // Check what datatype was given.
209 if (wcsicmp(pPrintProcessorOpenData
->pDatatype
, L
"RAW") == 0)
211 pHandle
->Datatype
= RAW
;
215 dwErrorCode
= ERROR_INVALID_DATATYPE
;
219 // Fill the relevant fields.
220 pHandle
->dwJobID
= pPrintProcessorOpenData
->JobId
;
221 pHandle
->pwszDatatype
= AllocSplStr(pPrintProcessorOpenData
->pDatatype
);
222 pHandle
->pwszDocumentName
= AllocSplStr(pPrintProcessorOpenData
->pDocumentName
);
223 pHandle
->pwszOutputFile
= AllocSplStr(pPrintProcessorOpenData
->pOutputFile
);
224 pHandle
->pwszPrinterPort
= AllocSplStr(pPrinterName
);
226 // We were successful! Return the handle and don't let the cleanup routine free it.
227 dwErrorCode
= ERROR_SUCCESS
;
228 hReturnValue
= pHandle
;
233 DllFreeSplMem(pHandle
);
235 SetLastError(dwErrorCode
);
240 * @name PrintDocumentOnPrintProcessor
242 * Prints a document on this Print Processor after a handle for the document has been opened through OpenPrintProcessor.
244 * @param hPrintProcessor
245 * The return value of a previous successful OpenPrintProcessor call.
247 * @param pDocumentName
248 * String in the format "Printer, Job N" describing the spooled job that is to be processed.
251 * TRUE if the document was successfully processed by this Print Processor, FALSE otherwise.
252 * A more specific error code can be obtained through GetLastError.
255 PrintDocumentOnPrintProcessor(HANDLE hPrintProcessor
, PWSTR pDocumentName
)
258 PWINPRINT_HANDLE pHandle
;
260 TRACE("PrintDocumentOnPrintProcessor(%p, %S)\n", hPrintProcessor
, pDocumentName
);
263 if (!hPrintProcessor
)
265 dwErrorCode
= ERROR_INVALID_HANDLE
;
269 pHandle
= (PWINPRINT_HANDLE
)hPrintProcessor
;
271 // Call the corresponding Print function for the datatype.
272 if (pHandle
->Datatype
== RAW
)
273 dwErrorCode
= PrintRawJob(pHandle
, pDocumentName
);
276 SetLastError(dwErrorCode
);
277 return (dwErrorCode
== ERROR_SUCCESS
);