1 /*
2  * PROJECT:     ReactOS Print Spooler Service
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Functions related to Printers and printing
5  * COPYRIGHT:   Copyright 2015-2018 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 #include <marshalling/printers.h>
10 
11 DWORD
_RpcAbortPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)12 _RpcAbortPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
13 {
14     DWORD dwErrorCode;
15 
16     dwErrorCode = RpcImpersonateClient(NULL);
17     if (dwErrorCode != ERROR_SUCCESS)
18     {
19         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
20         return dwErrorCode;
21     }
22 
23     if (!AbortPrinter(hPrinter))
24         dwErrorCode = GetLastError();
25 
26     RpcRevertToSelf();
27     return dwErrorCode;
28 }
29 
30 DWORD
_RpcAddPrinter(WINSPOOL_HANDLE pName,WINSPOOL_PRINTER_CONTAINER * pPrinterContainer,WINSPOOL_DEVMODE_CONTAINER * pDevModeContainer,WINSPOOL_SECURITY_CONTAINER * pSecurityContainer,WINSPOOL_PRINTER_HANDLE * pHandle)31 _RpcAddPrinter(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_PRINTER_HANDLE* pHandle)
32 {
33     UNIMPLEMENTED;
34     return ERROR_INVALID_FUNCTION;
35 }
36 
37 DWORD
_RpcAddPrinterEx(WINSPOOL_HANDLE pName,WINSPOOL_PRINTER_CONTAINER * pPrinterContainer,WINSPOOL_DEVMODE_CONTAINER * pDevModeContainer,WINSPOOL_SECURITY_CONTAINER * pSecurityContainer,WINSPOOL_SPLCLIENT_CONTAINER * pClientInfo,WINSPOOL_PRINTER_HANDLE * pHandle)38 _RpcAddPrinterEx(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo, WINSPOOL_PRINTER_HANDLE* pHandle)
39 {
40     UNIMPLEMENTED;
41     return ERROR_INVALID_FUNCTION;
42 }
43 
44 DWORD
_RpcClosePrinter(WINSPOOL_PRINTER_HANDLE * phPrinter)45 _RpcClosePrinter(WINSPOOL_PRINTER_HANDLE* phPrinter)
46 {
47     DWORD dwErrorCode;
48 
49     dwErrorCode = RpcImpersonateClient(NULL);
50     if (dwErrorCode != ERROR_SUCCESS)
51     {
52         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
53         return dwErrorCode;
54     }
55 
56     if (ClosePrinter(*phPrinter))
57         *phPrinter = NULL;
58     else
59         dwErrorCode = GetLastError();
60 
61     RpcRevertToSelf();
62     return dwErrorCode;
63 }
64 
65 DWORD
_RpcDeletePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)66 _RpcDeletePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
67 {
68     DWORD dwErrorCode;
69 
70     dwErrorCode = RpcImpersonateClient(NULL);
71     if (dwErrorCode != ERROR_SUCCESS)
72     {
73         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
74         return dwErrorCode;
75     }
76 
77     if (!DeletePrinter(hPrinter))
78         dwErrorCode = GetLastError();
79 
80     RpcRevertToSelf();
81     return dwErrorCode;
82 }
83 
84 DWORD
_RpcEndDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)85 _RpcEndDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
86 {
87     DWORD dwErrorCode;
88 
89     dwErrorCode = RpcImpersonateClient(NULL);
90     if (dwErrorCode != ERROR_SUCCESS)
91     {
92         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
93         return dwErrorCode;
94     }
95 
96     if (!EndDocPrinter(hPrinter))
97         dwErrorCode = GetLastError();
98 
99     RpcRevertToSelf();
100     return dwErrorCode;
101 }
102 
103 DWORD
_RpcEndPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)104 _RpcEndPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
105 {
106     DWORD dwErrorCode;
107 
108     dwErrorCode = RpcImpersonateClient(NULL);
109     if (dwErrorCode != ERROR_SUCCESS)
110     {
111         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
112         return dwErrorCode;
113     }
114 
115     if (!EndPagePrinter(hPrinter))
116         dwErrorCode = GetLastError();
117 
118     RpcRevertToSelf();
119     return dwErrorCode;
120 }
121 
122 DWORD
_RpcEnumPrinters(DWORD Flags,WINSPOOL_HANDLE Name,DWORD Level,BYTE * pPrinterEnum,DWORD cbBuf,DWORD * pcbNeeded,DWORD * pcReturned)123 _RpcEnumPrinters(DWORD Flags, WINSPOOL_HANDLE Name, DWORD Level, BYTE* pPrinterEnum, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
124 {
125     DWORD dwErrorCode;
126     PBYTE pPrinterEnumAligned;
127 
128     dwErrorCode = RpcImpersonateClient(NULL);
129     if (dwErrorCode != ERROR_SUCCESS)
130     {
131         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
132         return dwErrorCode;
133     }
134 
135     pPrinterEnumAligned = AlignRpcPtr(pPrinterEnum, &cbBuf);
136 
137     if (EnumPrintersW(Flags, Name, Level, pPrinterEnumAligned, cbBuf, pcbNeeded, pcReturned))
138     {
139         // Replace absolute pointer addresses in the output by relative offsets.
140         ASSERT(Level <= 9);
141         MarshallDownStructuresArray(pPrinterEnumAligned, *pcReturned, pPrinterInfoMarshalling[Level]->pInfo, pPrinterInfoMarshalling[Level]->cbStructureSize, TRUE);
142     }
143     else
144     {
145         dwErrorCode = GetLastError();
146     }
147 
148     RpcRevertToSelf();
149     UndoAlignRpcPtr(pPrinterEnum, pPrinterEnumAligned, cbBuf, pcbNeeded);
150 
151     return dwErrorCode;
152 }
153 
154 DWORD
_RpcFlushPrinter(WINSPOOL_PRINTER_HANDLE hPrinter,BYTE * pBuf,DWORD cbBuf,DWORD * pcWritten,DWORD cSleep)155 _RpcFlushPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten, DWORD cSleep)
156 {
157     UNIMPLEMENTED;
158     return ERROR_INVALID_FUNCTION;
159 }
160 
161 DWORD
_RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter,DWORD Level,BYTE * pPrinter,DWORD cbBuf,DWORD * pcbNeeded)162 _RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pPrinter, DWORD cbBuf, DWORD* pcbNeeded)
163 {
164     DWORD dwErrorCode;
165     PBYTE pPrinterAligned;
166 
167     dwErrorCode = RpcImpersonateClient(NULL);
168     if (dwErrorCode != ERROR_SUCCESS)
169     {
170         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
171         return dwErrorCode;
172     }
173 
174     pPrinterAligned = AlignRpcPtr(pPrinter, &cbBuf);
175 
176     if (GetPrinterW(hPrinter, Level, pPrinterAligned, cbBuf, pcbNeeded))
177     {
178         // Replace absolute pointer addresses in the output by relative offsets.
179         ASSERT(Level <= 9);
180         MarshallDownStructure(pPrinterAligned, pPrinterInfoMarshalling[Level]->pInfo, pPrinterInfoMarshalling[Level]->cbStructureSize, TRUE);
181     }
182     else
183     {
184         dwErrorCode = GetLastError();
185     }
186 
187     RpcRevertToSelf();
188     UndoAlignRpcPtr(pPrinter, pPrinterAligned, cbBuf, pcbNeeded);
189 
190     return dwErrorCode;
191 }
192 
193 DWORD
_RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName,WINSPOOL_PRINTER_HANDLE * phPrinter,WCHAR * pDatatype,WINSPOOL_DEVMODE_CONTAINER * pDevModeContainer,DWORD AccessRequired)194 _RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* phPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired)
195 {
196     DWORD dwErrorCode;
197     PRINTER_DEFAULTSW Default;
198 
199     dwErrorCode = RpcImpersonateClient(NULL);
200     if (dwErrorCode != ERROR_SUCCESS)
201     {
202         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
203         return dwErrorCode;
204     }
205 
206     Default.DesiredAccess = AccessRequired;
207     Default.pDatatype = pDatatype;
208     Default.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
209 
210     if (!OpenPrinterW(pPrinterName, phPrinter, &Default))
211         dwErrorCode = GetLastError();
212 
213     RpcRevertToSelf();
214     return dwErrorCode;
215 }
216 
217 DWORD
_RpcOpenPrinterEx(WINSPOOL_HANDLE pPrinterName,WINSPOOL_PRINTER_HANDLE * pHandle,WCHAR * pDatatype,WINSPOOL_DEVMODE_CONTAINER * pDevModeContainer,DWORD AccessRequired,WINSPOOL_SPLCLIENT_CONTAINER * pClientInfo)218 _RpcOpenPrinterEx(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* pHandle, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo)
219 {
220     UNIMPLEMENTED;
221     return ERROR_INVALID_FUNCTION;
222 }
223 
224 DWORD
_RpcReadPrinter(WINSPOOL_PRINTER_HANDLE hPrinter,BYTE * pBuf,DWORD cbBuf,DWORD * pcNoBytesRead)225 _RpcReadPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcNoBytesRead)
226 {
227     DWORD dwErrorCode;
228 
229     dwErrorCode = RpcImpersonateClient(NULL);
230     if (dwErrorCode != ERROR_SUCCESS)
231     {
232         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
233         return dwErrorCode;
234     }
235 
236     if (!ReadPrinter(hPrinter, pBuf, cbBuf, pcNoBytesRead))
237         dwErrorCode = GetLastError();
238 
239     RpcRevertToSelf();
240     return dwErrorCode;
241 }
242 
243 DWORD
_RpcResetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter,WCHAR * pDatatype,WINSPOOL_DEVMODE_CONTAINER * pDevModeContainer)244 _RpcResetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer)
245 {
246     UNIMPLEMENTED;
247     return ERROR_INVALID_FUNCTION;
248 }
249 
250 DWORD
_RpcResetPrinterEx(WINSPOOL_PRINTER_HANDLE hPrinter,WCHAR * pDatatype,WINSPOOL_DEVMODE_CONTAINER * pDevModeContainer,DWORD dwFlags)251 _RpcResetPrinterEx(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD dwFlags)
252 {
253     DWORD dwErrorCode;
254     PRINTER_DEFAULTSW pdw;
255 
256     if (pDatatype)
257     {
258         pdw.pDatatype = pDatatype;
259     }
260     else
261     {
262         pdw.pDatatype = dwFlags & RESETPRINTERDEFAULTDATATYPE ? (PWSTR)-1 : NULL;
263     }
264 
265     if (pDevModeContainer->pDevMode)
266     {
267         pdw.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
268         // Fixme : Need to check DevMode before forward call, by copy devmode.c from WinSpool.
269         //         Local SV!SplIsValidDevmode((PDW)pDevModeContainer->pDevMode, pDevModeContainer->cbBuf)
270     }
271     else
272     {
273         pdw.pDevMode = dwFlags & RESETPRINTERDEFAULTDEVMODE ? (PDEVMODEW)-1 : NULL;
274 
275     }
276     pdw.DesiredAccess = 0;
277 
278     dwErrorCode = RpcImpersonateClient(NULL);
279     if (dwErrorCode != ERROR_SUCCESS)
280     {
281         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
282         return dwErrorCode;
283     }
284 
285     if (!ResetPrinterW(hPrinter, &pdw))
286         dwErrorCode = GetLastError();
287 
288     RpcRevertToSelf();
289     return dwErrorCode;
290 }
291 
292 DWORD
_RpcSeekPrinter(WINSPOOL_PRINTER_HANDLE hPrinter,LARGE_INTEGER liDistanceToMove,PLARGE_INTEGER pliNewPointer,DWORD dwMoveMethod,BOOL bWrite)293 _RpcSeekPrinter( WINSPOOL_PRINTER_HANDLE hPrinter, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER pliNewPointer, DWORD dwMoveMethod, BOOL bWrite )
294 {
295     DWORD dwErrorCode;
296 
297     dwErrorCode = RpcImpersonateClient(NULL);
298     if (dwErrorCode != ERROR_SUCCESS)
299     {
300         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
301         return dwErrorCode;
302     }
303 
304     if (!SeekPrinter(hPrinter, liDistanceToMove, pliNewPointer, dwMoveMethod, bWrite))
305         dwErrorCode = GetLastError();
306 
307     RpcRevertToSelf();
308     return dwErrorCode;
309 }
310 
311 DWORD
_RpcSetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter,WINSPOOL_PRINTER_CONTAINER * pPrinterContainer,WINSPOOL_DEVMODE_CONTAINER * pDevModeContainer,WINSPOOL_SECURITY_CONTAINER * pSecurityContainer,DWORD Command)312 _RpcSetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, DWORD Command)
313 {
314     UNIMPLEMENTED;
315     return ERROR_INVALID_FUNCTION;
316 }
317 
318 DWORD
_RpcStartDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter,WINSPOOL_DOC_INFO_CONTAINER * pDocInfoContainer,DWORD * pJobId)319 _RpcStartDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_DOC_INFO_CONTAINER* pDocInfoContainer, DWORD* pJobId)
320 {
321     DWORD dwErrorCode;
322 
323     dwErrorCode = RpcImpersonateClient(NULL);
324     if (dwErrorCode != ERROR_SUCCESS)
325     {
326         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
327         return dwErrorCode;
328     }
329 
330     *pJobId = StartDocPrinterW(hPrinter, pDocInfoContainer->Level, (PBYTE)pDocInfoContainer->DocInfo.pDocInfo1);
331     dwErrorCode = GetLastError();
332 
333     RpcRevertToSelf();
334     return dwErrorCode;
335 }
336 
337 DWORD
_RpcStartPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)338 _RpcStartPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
339 {
340     DWORD dwErrorCode;
341 
342     dwErrorCode = RpcImpersonateClient(NULL);
343     if (dwErrorCode != ERROR_SUCCESS)
344     {
345         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
346         return dwErrorCode;
347     }
348 
349     if (!StartPagePrinter(hPrinter))
350         dwErrorCode = GetLastError();
351 
352     RpcRevertToSelf();
353     return dwErrorCode;
354 }
355 
356 DWORD
_RpcWritePrinter(WINSPOOL_PRINTER_HANDLE hPrinter,BYTE * pBuf,DWORD cbBuf,DWORD * pcWritten)357 _RpcWritePrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten)
358 {
359     DWORD dwErrorCode;
360 
361     dwErrorCode = RpcImpersonateClient(NULL);
362     if (dwErrorCode != ERROR_SUCCESS)
363     {
364         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
365         return dwErrorCode;
366     }
367 
368     if (!WritePrinter(hPrinter, pBuf, cbBuf, pcWritten))
369         dwErrorCode = GetLastError();
370 
371     RpcRevertToSelf();
372     return dwErrorCode;
373 }
374