2 * PROJECT: ReactOS Spooler Router
3 * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
4 * PURPOSE: Functions related to Printers and printing
5 * COPYRIGHT: Copyright 2015-2017 Colin Finck <colin@reactos.org>
12 ClosePrinter(HANDLE hPrinter
)
15 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
20 SetLastError(ERROR_INVALID_PARAMETER
);
24 // FIXME: Call FindClosePrinterChangeNotification for all created change notifications (according to MSDN).
26 // Call CloseHandle of the Print Provider.
27 bReturnValue
= pHandle
->pPrintProvider
->PrintProvider
.fpClosePrinter(pHandle
->hPrinter
);
29 // Free our handle information.
30 DllFreeSplMem(pHandle
);
36 EndDocPrinter(HANDLE hPrinter
)
38 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
43 SetLastError(ERROR_INVALID_PARAMETER
);
47 return pHandle
->pPrintProvider
->PrintProvider
.fpEndDocPrinter(pHandle
->hPrinter
);
51 EndPagePrinter(HANDLE hPrinter
)
53 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
58 SetLastError(ERROR_INVALID_PARAMETER
);
62 return pHandle
->pPrintProvider
->PrintProvider
.fpEndPagePrinter(pHandle
->hPrinter
);
66 EnumPrintersW(DWORD Flags
, PWSTR Name
, DWORD Level
, PBYTE pPrinterEnum
, DWORD cbBuf
, PDWORD pcbNeeded
, PDWORD pcReturned
)
71 DWORD dwErrorCode
= 0xFFFFFFFF;
74 PSPOOLSS_PRINT_PROVIDER pPrintProvider
;
81 if (cbBuf
&& !pPrinterEnum
)
83 dwErrorCode
= ERROR_INVALID_USER_BUFFER
;
87 // At the beginning, we have the full buffer available.
89 pCallBuffer
= pPrinterEnum
;
91 // Loop through all Print Providers.
92 for (pEntry
= PrintProviderList
.Flink
; pEntry
!= &PrintProviderList
; pEntry
= pEntry
->Flink
)
94 pPrintProvider
= CONTAINING_RECORD(pEntry
, SPOOLSS_PRINT_PROVIDER
, Entry
);
96 // Call the EnumPrinters function of this Print Provider.
97 bReturnValue
= pPrintProvider
->PrintProvider
.fpEnumPrinters(Flags
, Name
, Level
, pCallBuffer
, cbCallBuffer
, &cbNeeded
, &dwReturned
);
99 // Add the returned counts to the total values.
100 *pcbNeeded
+= cbNeeded
;
101 *pcReturned
+= dwReturned
;
103 // Reduce the available buffer size for the next call without risking an underflow.
104 if (cbNeeded
< cbCallBuffer
)
105 cbCallBuffer
-= cbNeeded
;
109 // Advance the buffer if the caller provided it.
111 pCallBuffer
+= cbNeeded
;
113 // dwErrorCode shall not be overwritten if a previous EnumPrinters call already succeeded.
114 if (dwErrorCode
!= ERROR_SUCCESS
)
115 dwErrorCode
= GetLastError();
119 SetLastError(dwErrorCode
);
120 return (dwErrorCode
== ERROR_SUCCESS
);
124 GetPrinterDriverW(HANDLE hPrinter
, PWSTR pEnvironment
, DWORD Level
, PBYTE pDriverInfo
, DWORD cbBuf
, PDWORD pcbNeeded
)
126 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
131 SetLastError(ERROR_INVALID_PARAMETER
);
135 return pHandle
->pPrintProvider
->PrintProvider
.fpGetPrinterDriver(pHandle
->hPrinter
, pEnvironment
, Level
, pDriverInfo
, cbBuf
, pcbNeeded
);
139 GetPrinterW(HANDLE hPrinter
, DWORD Level
, PBYTE pPrinter
, DWORD cbBuf
, PDWORD pcbNeeded
)
141 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
146 SetLastError(ERROR_INVALID_PARAMETER
);
150 return pHandle
->pPrintProvider
->PrintProvider
.fpGetPrinter(pHandle
->hPrinter
, Level
, pPrinter
, cbBuf
, pcbNeeded
);
154 OpenPrinterW(PWSTR pPrinterName
, PHANDLE phPrinter
, PPRINTER_DEFAULTSW pDefault
)
157 DWORD dwErrorCode
= ERROR_INVALID_PRINTER_NAME
;
160 PSPOOLSS_PRINTER_HANDLE pHandle
;
161 PSPOOLSS_PRINT_PROVIDER pPrintProvider
;
164 if (!pPrinterName
|| !phPrinter
)
166 dwErrorCode
= ERROR_INVALID_PARAMETER
;
170 // Loop through all Print Providers to find one able to open this Printer.
171 for (pEntry
= PrintProviderList
.Flink
; pEntry
!= &PrintProviderList
; pEntry
= pEntry
->Flink
)
173 pPrintProvider
= CONTAINING_RECORD(pEntry
, SPOOLSS_PRINT_PROVIDER
, Entry
);
175 bReturnValue
= pPrintProvider
->PrintProvider
.fpOpenPrinter(pPrinterName
, &hPrinter
, pDefault
);
176 if (bReturnValue
== ROUTER_SUCCESS
)
178 // This Print Provider has opened this Printer.
179 // Store this information and return a handle.
180 pHandle
= DllAllocSplMem(sizeof(SPOOLSS_PRINTER_HANDLE
));
183 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
184 dwErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
188 pHandle
->pPrintProvider
= pPrintProvider
;
189 pHandle
->hPrinter
= hPrinter
;
190 *phPrinter
= (HANDLE
)pHandle
;
192 dwErrorCode
= ERROR_SUCCESS
;
195 else if (bReturnValue
== ROUTER_STOP_ROUTING
)
197 ERR("A Print Provider returned ROUTER_STOP_ROUTING for Printer \"%S\"!\n", pPrinterName
);
198 dwErrorCode
= GetLastError();
203 // ERROR_INVALID_NAME by the Print Provider is translated to ERROR_INVALID_PRINTER_NAME here, but not in other APIs as far as I know.
204 if (dwErrorCode
== ERROR_INVALID_NAME
)
205 dwErrorCode
= ERROR_INVALID_PRINTER_NAME
;
208 SetLastError(dwErrorCode
);
209 return (dwErrorCode
== ERROR_SUCCESS
);
213 ReadPrinter(HANDLE hPrinter
, PVOID pBuf
, DWORD cbBuf
, PDWORD pNoBytesRead
)
215 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
220 SetLastError(ERROR_INVALID_PARAMETER
);
224 return pHandle
->pPrintProvider
->PrintProvider
.fpReadPrinter(pHandle
->hPrinter
, pBuf
, cbBuf
, pNoBytesRead
);
228 StartDocPrinterW(HANDLE hPrinter
, DWORD Level
, PBYTE pDocInfo
)
230 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
235 SetLastError(ERROR_INVALID_PARAMETER
);
239 return pHandle
->pPrintProvider
->PrintProvider
.fpStartDocPrinter(pHandle
->hPrinter
, Level
, pDocInfo
);
243 StartPagePrinter(HANDLE hPrinter
)
245 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
250 SetLastError(ERROR_INVALID_PARAMETER
);
254 return pHandle
->pPrintProvider
->PrintProvider
.fpStartPagePrinter(pHandle
->hPrinter
);
258 WritePrinter(HANDLE hPrinter
, PVOID pBuf
, DWORD cbBuf
, PDWORD pcWritten
)
260 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
265 SetLastError(ERROR_INVALID_PARAMETER
);
269 return pHandle
->pPrintProvider
->PrintProvider
.fpWritePrinter(pHandle
->hPrinter
, pBuf
, cbBuf
, pcWritten
);
273 XcvDataW(HANDLE hXcv
, PCWSTR pszDataName
, PBYTE pInputData
, DWORD cbInputData
, PBYTE pOutputData
, DWORD cbOutputData
, PDWORD pcbOutputNeeded
, PDWORD pdwStatus
)
275 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hXcv
;
280 SetLastError(ERROR_INVALID_PARAMETER
);
284 return pHandle
->pPrintProvider
->PrintProvider
.fpXcvData(pHandle
->hPrinter
, pszDataName
, pInputData
, cbInputData
, pOutputData
, cbOutputData
, pcbOutputNeeded
, pdwStatus
);