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
12 _RpcAbortPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
13 {
14     UNIMPLEMENTED;
15     return ERROR_INVALID_FUNCTION;
16 }
17 
18 DWORD
19 _RpcAddPrinter(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_PRINTER_HANDLE* pHandle)
20 {
21     UNIMPLEMENTED;
22     return ERROR_INVALID_FUNCTION;
23 }
24 
25 DWORD
26 _RpcAddPrinterEx(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo, WINSPOOL_PRINTER_HANDLE* pHandle)
27 {
28     UNIMPLEMENTED;
29     return ERROR_INVALID_FUNCTION;
30 }
31 
32 DWORD
33 _RpcClosePrinter(WINSPOOL_PRINTER_HANDLE* phPrinter)
34 {
35     DWORD dwErrorCode;
36 
37     dwErrorCode = RpcImpersonateClient(NULL);
38     if (dwErrorCode != ERROR_SUCCESS)
39     {
40         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
41         return dwErrorCode;
42     }
43 
44     if (ClosePrinter(*phPrinter))
45         *phPrinter = NULL;
46     else
47         dwErrorCode = GetLastError();
48 
49     RpcRevertToSelf();
50     return dwErrorCode;
51 }
52 
53 DWORD
54 _RpcDeletePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
55 {
56     UNIMPLEMENTED;
57     return ERROR_INVALID_FUNCTION;
58 }
59 
60 DWORD
61 _RpcEndDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
62 {
63     DWORD dwErrorCode;
64 
65     dwErrorCode = RpcImpersonateClient(NULL);
66     if (dwErrorCode != ERROR_SUCCESS)
67     {
68         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
69         return dwErrorCode;
70     }
71 
72     if (!EndDocPrinter(hPrinter))
73         dwErrorCode = GetLastError();
74 
75     RpcRevertToSelf();
76     return dwErrorCode;
77 }
78 
79 DWORD
80 _RpcEndPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
81 {
82     DWORD dwErrorCode;
83 
84     dwErrorCode = RpcImpersonateClient(NULL);
85     if (dwErrorCode != ERROR_SUCCESS)
86     {
87         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
88         return dwErrorCode;
89     }
90 
91     if (!EndPagePrinter(hPrinter))
92         dwErrorCode = GetLastError();
93 
94     RpcRevertToSelf();
95     return dwErrorCode;
96 }
97 
98 DWORD
99 _RpcEnumPrinters(DWORD Flags, WINSPOOL_HANDLE Name, DWORD Level, BYTE* pPrinterEnum, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
100 {
101     DWORD dwErrorCode;
102     PBYTE pPrinterEnumAligned;
103 
104     dwErrorCode = RpcImpersonateClient(NULL);
105     if (dwErrorCode != ERROR_SUCCESS)
106     {
107         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
108         return dwErrorCode;
109     }
110 
111     pPrinterEnumAligned = AlignRpcPtr(pPrinterEnum, &cbBuf);
112 
113     if (EnumPrintersW(Flags, Name, Level, pPrinterEnumAligned, cbBuf, pcbNeeded, pcReturned))
114     {
115         // Replace absolute pointer addresses in the output by relative offsets.
116         ASSERT(Level <= 9);
117         MarshallDownStructuresArray(pPrinterEnumAligned, *pcReturned, pPrinterInfoMarshalling[Level]->pInfo, pPrinterInfoMarshalling[Level]->cbStructureSize, TRUE);
118     }
119     else
120     {
121         dwErrorCode = GetLastError();
122     }
123 
124     RpcRevertToSelf();
125     UndoAlignRpcPtr(pPrinterEnum, pPrinterEnumAligned, cbBuf, pcbNeeded);
126 
127     return dwErrorCode;
128 }
129 
130 DWORD
131 _RpcFlushPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten, DWORD cSleep)
132 {
133     UNIMPLEMENTED;
134     return ERROR_INVALID_FUNCTION;
135 }
136 
137 DWORD
138 _RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pPrinter, DWORD cbBuf, DWORD* pcbNeeded)
139 {
140     DWORD dwErrorCode;
141     PBYTE pPrinterAligned;
142 
143     dwErrorCode = RpcImpersonateClient(NULL);
144     if (dwErrorCode != ERROR_SUCCESS)
145     {
146         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
147         return dwErrorCode;
148     }
149 
150     pPrinterAligned = AlignRpcPtr(pPrinter, &cbBuf);
151 
152     if (GetPrinterW(hPrinter, Level, pPrinterAligned, cbBuf, pcbNeeded))
153     {
154         // Replace absolute pointer addresses in the output by relative offsets.
155         ASSERT(Level <= 9);
156         MarshallDownStructure(pPrinterAligned, pPrinterInfoMarshalling[Level]->pInfo, pPrinterInfoMarshalling[Level]->cbStructureSize, TRUE);
157     }
158     else
159     {
160         dwErrorCode = GetLastError();
161     }
162 
163     RpcRevertToSelf();
164     UndoAlignRpcPtr(pPrinter, pPrinterAligned, cbBuf, pcbNeeded);
165 
166     return dwErrorCode;
167 }
168 
169 DWORD
170 _RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* phPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired)
171 {
172     DWORD dwErrorCode;
173     PRINTER_DEFAULTSW Default;
174 
175     dwErrorCode = RpcImpersonateClient(NULL);
176     if (dwErrorCode != ERROR_SUCCESS)
177     {
178         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
179         return dwErrorCode;
180     }
181 
182     Default.DesiredAccess = AccessRequired;
183     Default.pDatatype = pDatatype;
184     Default.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
185 
186     if (!OpenPrinterW(pPrinterName, phPrinter, &Default))
187         dwErrorCode = GetLastError();
188 
189     RpcRevertToSelf();
190     return dwErrorCode;
191 }
192 
193 DWORD
194 _RpcOpenPrinterEx(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* pHandle, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo)
195 {
196     UNIMPLEMENTED;
197     return ERROR_INVALID_FUNCTION;
198 }
199 
200 DWORD
201 _RpcReadPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcNoBytesRead)
202 {
203     DWORD dwErrorCode;
204 
205     dwErrorCode = RpcImpersonateClient(NULL);
206     if (dwErrorCode != ERROR_SUCCESS)
207     {
208         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
209         return dwErrorCode;
210     }
211 
212     if (!ReadPrinter(hPrinter, pBuf, cbBuf, pcNoBytesRead))
213         dwErrorCode = GetLastError();
214 
215     RpcRevertToSelf();
216     return dwErrorCode;
217 }
218 
219 DWORD
220 _RpcResetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer)
221 {
222     UNIMPLEMENTED;
223     return ERROR_INVALID_FUNCTION;
224 }
225 
226 DWORD
227 _RpcResetPrinterEx(VOID)
228 {
229     UNIMPLEMENTED;
230     return ERROR_INVALID_FUNCTION;
231 }
232 
233 DWORD
234 _RpcSeekPrinter(VOID)
235 {
236     UNIMPLEMENTED;
237     return ERROR_INVALID_FUNCTION;
238 }
239 
240 DWORD
241 _RpcSetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, DWORD Command)
242 {
243     UNIMPLEMENTED;
244     return ERROR_INVALID_FUNCTION;
245 }
246 
247 DWORD
248 _RpcStartDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_DOC_INFO_CONTAINER* pDocInfoContainer, DWORD* pJobId)
249 {
250     DWORD dwErrorCode;
251 
252     dwErrorCode = RpcImpersonateClient(NULL);
253     if (dwErrorCode != ERROR_SUCCESS)
254     {
255         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
256         return dwErrorCode;
257     }
258 
259     *pJobId = StartDocPrinterW(hPrinter, pDocInfoContainer->Level, (PBYTE)pDocInfoContainer->DocInfo.pDocInfo1);
260     dwErrorCode = GetLastError();
261 
262     RpcRevertToSelf();
263     return dwErrorCode;
264 }
265 
266 DWORD
267 _RpcStartPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
268 {
269     DWORD dwErrorCode;
270 
271     dwErrorCode = RpcImpersonateClient(NULL);
272     if (dwErrorCode != ERROR_SUCCESS)
273     {
274         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
275         return dwErrorCode;
276     }
277 
278     if (!StartPagePrinter(hPrinter))
279         dwErrorCode = GetLastError();
280 
281     RpcRevertToSelf();
282     return dwErrorCode;
283 }
284 
285 DWORD
286 _RpcWritePrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten)
287 {
288     DWORD dwErrorCode;
289 
290     dwErrorCode = RpcImpersonateClient(NULL);
291     if (dwErrorCode != ERROR_SUCCESS)
292     {
293         ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
294         return dwErrorCode;
295     }
296 
297     if (!WritePrinter(hPrinter, pBuf, cbBuf, pcWritten))
298         dwErrorCode = GetLastError();
299 
300     RpcRevertToSelf();
301     return dwErrorCode;
302 }
303