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
)
70 DWORD dwErrorCode
= 0xFFFFFFFF;
73 PSPOOLSS_PRINT_PROVIDER pPrintProvider
;
80 if (cbBuf
&& !pPrinterEnum
)
82 dwErrorCode
= ERROR_INVALID_USER_BUFFER
;
86 // At the beginning, we have the full buffer available.
88 pCallBuffer
= pPrinterEnum
;
90 // Loop through all Print Providers.
91 for (pEntry
= PrintProviderList
.Flink
; pEntry
!= &PrintProviderList
; pEntry
= pEntry
->Flink
)
93 pPrintProvider
= CONTAINING_RECORD(pEntry
, SPOOLSS_PRINT_PROVIDER
, Entry
);
95 // Call the EnumPrinters function of this Print Provider.
96 pPrintProvider
->PrintProvider
.fpEnumPrinters(Flags
, Name
, Level
, pCallBuffer
, cbCallBuffer
, &cbNeeded
, &dwReturned
);
98 // Add the returned counts to the total values.
99 *pcbNeeded
+= cbNeeded
;
100 *pcReturned
+= dwReturned
;
102 // Reduce the available buffer size for the next call without risking an underflow.
103 if (cbNeeded
< cbCallBuffer
)
104 cbCallBuffer
-= cbNeeded
;
108 // Advance the buffer if the caller provided it.
110 pCallBuffer
+= cbNeeded
;
112 // dwErrorCode shall not be overwritten if a previous EnumPrinters call already succeeded.
113 if (dwErrorCode
!= ERROR_SUCCESS
)
114 dwErrorCode
= GetLastError();
118 SetLastError(dwErrorCode
);
119 return (dwErrorCode
== ERROR_SUCCESS
);
123 GetPrinterDriverW(HANDLE hPrinter
, PWSTR pEnvironment
, DWORD Level
, PBYTE pDriverInfo
, DWORD cbBuf
, PDWORD pcbNeeded
)
125 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
130 SetLastError(ERROR_INVALID_PARAMETER
);
134 return pHandle
->pPrintProvider
->PrintProvider
.fpGetPrinterDriver(pHandle
->hPrinter
, pEnvironment
, Level
, pDriverInfo
, cbBuf
, pcbNeeded
);
138 GetPrinterW(HANDLE hPrinter
, DWORD Level
, PBYTE pPrinter
, DWORD cbBuf
, PDWORD pcbNeeded
)
140 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
145 SetLastError(ERROR_INVALID_PARAMETER
);
149 return pHandle
->pPrintProvider
->PrintProvider
.fpGetPrinter(pHandle
->hPrinter
, Level
, pPrinter
, cbBuf
, pcbNeeded
);
153 OpenPrinterW(PWSTR pPrinterName
, PHANDLE phPrinter
, PPRINTER_DEFAULTSW pDefault
)
156 DWORD dwErrorCode
= ERROR_INVALID_PRINTER_NAME
;
159 PSPOOLSS_PRINTER_HANDLE pHandle
;
160 PSPOOLSS_PRINT_PROVIDER pPrintProvider
;
163 if (!pPrinterName
|| !phPrinter
)
165 dwErrorCode
= ERROR_INVALID_PARAMETER
;
169 // Loop through all Print Providers to find one able to open this Printer.
170 for (pEntry
= PrintProviderList
.Flink
; pEntry
!= &PrintProviderList
; pEntry
= pEntry
->Flink
)
172 pPrintProvider
= CONTAINING_RECORD(pEntry
, SPOOLSS_PRINT_PROVIDER
, Entry
);
174 bReturnValue
= pPrintProvider
->PrintProvider
.fpOpenPrinter(pPrinterName
, &hPrinter
, pDefault
);
175 if (bReturnValue
== ROUTER_SUCCESS
)
177 // This Print Provider has opened this Printer.
178 // Store this information and return a handle.
179 pHandle
= DllAllocSplMem(sizeof(SPOOLSS_PRINTER_HANDLE
));
182 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
183 dwErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
187 pHandle
->pPrintProvider
= pPrintProvider
;
188 pHandle
->hPrinter
= hPrinter
;
189 *phPrinter
= (HANDLE
)pHandle
;
191 dwErrorCode
= ERROR_SUCCESS
;
194 else if (bReturnValue
== ROUTER_STOP_ROUTING
)
196 ERR("A Print Provider returned ROUTER_STOP_ROUTING for Printer \"%S\"!\n", pPrinterName
);
197 dwErrorCode
= GetLastError();
202 // 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.
203 if (dwErrorCode
== ERROR_INVALID_NAME
)
204 dwErrorCode
= ERROR_INVALID_PRINTER_NAME
;
207 SetLastError(dwErrorCode
);
208 return (dwErrorCode
== ERROR_SUCCESS
);
212 ReadPrinter(HANDLE hPrinter
, PVOID pBuf
, DWORD cbBuf
, PDWORD pNoBytesRead
)
214 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
219 SetLastError(ERROR_INVALID_PARAMETER
);
223 return pHandle
->pPrintProvider
->PrintProvider
.fpReadPrinter(pHandle
->hPrinter
, pBuf
, cbBuf
, pNoBytesRead
);
227 StartDocPrinterW(HANDLE hPrinter
, DWORD Level
, PBYTE pDocInfo
)
229 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
234 SetLastError(ERROR_INVALID_PARAMETER
);
238 return pHandle
->pPrintProvider
->PrintProvider
.fpStartDocPrinter(pHandle
->hPrinter
, Level
, pDocInfo
);
242 StartPagePrinter(HANDLE hPrinter
)
244 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
249 SetLastError(ERROR_INVALID_PARAMETER
);
253 return pHandle
->pPrintProvider
->PrintProvider
.fpStartPagePrinter(pHandle
->hPrinter
);
257 WritePrinter(HANDLE hPrinter
, PVOID pBuf
, DWORD cbBuf
, PDWORD pcWritten
)
259 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
264 SetLastError(ERROR_INVALID_PARAMETER
);
268 return pHandle
->pPrintProvider
->PrintProvider
.fpWritePrinter(pHandle
->hPrinter
, pBuf
, cbBuf
, pcWritten
);
272 XcvDataW(HANDLE hXcv
, PCWSTR pszDataName
, PBYTE pInputData
, DWORD cbInputData
, PBYTE pOutputData
, DWORD cbOutputData
, PDWORD pcbOutputNeeded
, PDWORD pdwStatus
)
274 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hXcv
;
279 SetLastError(ERROR_INVALID_PARAMETER
);
283 return pHandle
->pPrintProvider
->PrintProvider
.fpXcvData(pHandle
->hPrinter
, pszDataName
, pInputData
, cbInputData
, pOutputData
, cbOutputData
, pcbOutputNeeded
, pdwStatus
);