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 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
)
73 PSPOOLSS_PRINT_PROVIDER pPrintProvider
;
77 if ((cbBuf
&& !pPrinterEnum
) || !pcbNeeded
|| !pcReturned
)
79 SetLastError(ERROR_INVALID_PARAMETER
);
87 // At the beginning, we have the full buffer available.
89 pCallBuffer
= pPrinterEnum
;
91 // Loop through all Print Provider.
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
;
118 GetPrinterDriverW(HANDLE hPrinter
, PWSTR pEnvironment
, DWORD Level
, PBYTE pDriverInfo
, DWORD cbBuf
, PDWORD pcbNeeded
)
120 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
125 SetLastError(ERROR_INVALID_PARAMETER
);
129 return pHandle
->pPrintProvider
->PrintProvider
.fpGetPrinterDriver(pHandle
->hPrinter
, pEnvironment
, Level
, pDriverInfo
, cbBuf
, pcbNeeded
);
133 GetPrinterW(HANDLE hPrinter
, DWORD Level
, PBYTE pPrinter
, DWORD cbBuf
, PDWORD pcbNeeded
)
135 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
140 SetLastError(ERROR_INVALID_PARAMETER
);
144 return pHandle
->pPrintProvider
->PrintProvider
.fpGetPrinter(pHandle
->hPrinter
, Level
, pPrinter
, cbBuf
, pcbNeeded
);
148 OpenPrinterW(PWSTR pPrinterName
, PHANDLE phPrinter
, PPRINTER_DEFAULTSW pDefault
)
153 PSPOOLSS_PRINTER_HANDLE pHandle
;
154 PSPOOLSS_PRINT_PROVIDER pPrintProvider
;
157 if (!pPrinterName
|| !phPrinter
)
159 SetLastError(ERROR_INVALID_PARAMETER
);
163 // Loop through all Print Providers to find one able to open this Printer.
164 for (pEntry
= PrintProviderList
.Flink
; pEntry
!= &PrintProviderList
; pEntry
= pEntry
->Flink
)
166 pPrintProvider
= CONTAINING_RECORD(pEntry
, SPOOLSS_PRINT_PROVIDER
, Entry
);
168 bReturnValue
= pPrintProvider
->PrintProvider
.fpOpenPrinter(pPrinterName
, &hPrinter
, pDefault
);
169 if (bReturnValue
== ROUTER_SUCCESS
)
171 // This Print Provider has opened this Printer.
172 // Store this information and return a handle.
173 pHandle
= DllAllocSplMem(sizeof(SPOOLSS_PRINTER_HANDLE
));
176 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
177 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
181 pHandle
->pPrintProvider
= pPrintProvider
;
182 pHandle
->hPrinter
= hPrinter
;
183 *phPrinter
= (HANDLE
)pHandle
;
185 SetLastError(ERROR_SUCCESS
);
188 else if (bReturnValue
== ROUTER_STOP_ROUTING
)
190 ERR("A Print Provider returned ROUTER_STOP_ROUTING for Printer \"%S\"!\n", pPrinterName
);
195 // We found no Print Provider able to open this Printer.
200 ReadPrinter(HANDLE hPrinter
, PVOID pBuf
, DWORD cbBuf
, PDWORD pNoBytesRead
)
202 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
207 SetLastError(ERROR_INVALID_PARAMETER
);
211 return pHandle
->pPrintProvider
->PrintProvider
.fpReadPrinter(pHandle
->hPrinter
, pBuf
, cbBuf
, pNoBytesRead
);
215 StartDocPrinterW(HANDLE hPrinter
, DWORD Level
, PBYTE pDocInfo
)
217 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
222 SetLastError(ERROR_INVALID_PARAMETER
);
226 return pHandle
->pPrintProvider
->PrintProvider
.fpStartDocPrinter(pHandle
->hPrinter
, Level
, pDocInfo
);
230 StartPagePrinter(HANDLE hPrinter
)
232 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
237 SetLastError(ERROR_INVALID_PARAMETER
);
241 return pHandle
->pPrintProvider
->PrintProvider
.fpStartPagePrinter(pHandle
->hPrinter
);
245 WritePrinter(HANDLE hPrinter
, PVOID pBuf
, DWORD cbBuf
, PDWORD pcWritten
)
247 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hPrinter
;
252 SetLastError(ERROR_INVALID_PARAMETER
);
256 return pHandle
->pPrintProvider
->PrintProvider
.fpWritePrinter(pHandle
->hPrinter
, pBuf
, cbBuf
, pcWritten
);
260 XcvDataW(HANDLE hXcv
, PCWSTR pszDataName
, PBYTE pInputData
, DWORD cbInputData
, PBYTE pOutputData
, DWORD cbOutputData
, PDWORD pcbOutputNeeded
, PDWORD pdwStatus
)
262 PSPOOLSS_PRINTER_HANDLE pHandle
= (PSPOOLSS_PRINTER_HANDLE
)hXcv
;
267 SetLastError(ERROR_INVALID_PARAMETER
);
271 return pHandle
->pPrintProvider
->PrintProvider
.fpXcvData(pHandle
->hPrinter
, pszDataName
, pInputData
, cbInputData
, pOutputData
, cbOutputData
, pcbOutputNeeded
, pdwStatus
);