Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / win32ss / printing / base / spoolsv / printers.c
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-2017 Colin Finck (colin@reactos.org)
6 */
7
8 #include "precomp.h"
9
10 static void
11 _MarshallDownPrinterInfo(PBYTE* ppPrinterInfo, DWORD Level)
12 {
13 // Replace absolute pointer addresses in the output by relative offsets.
14 if (Level == 0)
15 {
16 PPRINTER_INFO_STRESS pPrinterInfo0 = (PPRINTER_INFO_STRESS)(*ppPrinterInfo);
17
18 pPrinterInfo0->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo0->pPrinterName - (ULONG_PTR)pPrinterInfo0);
19
20 if (pPrinterInfo0->pServerName)
21 pPrinterInfo0->pServerName = (PWSTR)((ULONG_PTR)pPrinterInfo0->pServerName - (ULONG_PTR)pPrinterInfo0);
22
23 *ppPrinterInfo += sizeof(PRINTER_INFO_STRESS);
24 }
25 else if (Level == 1)
26 {
27 PPRINTER_INFO_1W pPrinterInfo1 = (PPRINTER_INFO_1W)(*ppPrinterInfo);
28
29 pPrinterInfo1->pName = (PWSTR)((ULONG_PTR)pPrinterInfo1->pName - (ULONG_PTR)pPrinterInfo1);
30 pPrinterInfo1->pDescription = (PWSTR)((ULONG_PTR)pPrinterInfo1->pDescription - (ULONG_PTR)pPrinterInfo1);
31 pPrinterInfo1->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo1->pComment - (ULONG_PTR)pPrinterInfo1);
32
33 *ppPrinterInfo += sizeof(PRINTER_INFO_1W);
34 }
35 else if (Level == 2)
36 {
37 PPRINTER_INFO_2W pPrinterInfo2 = (PPRINTER_INFO_2W)(*ppPrinterInfo);
38
39 pPrinterInfo2->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPrinterName - (ULONG_PTR)pPrinterInfo2);
40 pPrinterInfo2->pShareName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pShareName - (ULONG_PTR)pPrinterInfo2);
41 pPrinterInfo2->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPortName - (ULONG_PTR)pPrinterInfo2);
42 pPrinterInfo2->pDriverName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pDriverName - (ULONG_PTR)pPrinterInfo2);
43 pPrinterInfo2->pComment = (PWSTR)((ULONG_PTR)pPrinterInfo2->pComment - (ULONG_PTR)pPrinterInfo2);
44 pPrinterInfo2->pLocation = (PWSTR)((ULONG_PTR)pPrinterInfo2->pLocation - (ULONG_PTR)pPrinterInfo2);
45 pPrinterInfo2->pDevMode = (PDEVMODEW)((ULONG_PTR)pPrinterInfo2->pDevMode - (ULONG_PTR)pPrinterInfo2);
46 pPrinterInfo2->pSepFile = (PWSTR)((ULONG_PTR)pPrinterInfo2->pSepFile - (ULONG_PTR)pPrinterInfo2);
47 pPrinterInfo2->pPrintProcessor = (PWSTR)((ULONG_PTR)pPrinterInfo2->pPrintProcessor - (ULONG_PTR)pPrinterInfo2);
48 pPrinterInfo2->pDatatype = (PWSTR)((ULONG_PTR)pPrinterInfo2->pDatatype - (ULONG_PTR)pPrinterInfo2);
49 pPrinterInfo2->pParameters = (PWSTR)((ULONG_PTR)pPrinterInfo2->pParameters - (ULONG_PTR)pPrinterInfo2);
50
51 if (pPrinterInfo2->pServerName)
52 pPrinterInfo2->pServerName = (PWSTR)((ULONG_PTR)pPrinterInfo2->pServerName - (ULONG_PTR)pPrinterInfo2);
53
54 if (pPrinterInfo2->pSecurityDescriptor)
55 pPrinterInfo2->pSecurityDescriptor = (PSECURITY_DESCRIPTOR)((ULONG_PTR)pPrinterInfo2->pSecurityDescriptor - (ULONG_PTR)pPrinterInfo2);
56
57 *ppPrinterInfo += sizeof(PRINTER_INFO_2W);
58 }
59 else if (Level == 3)
60 {
61 PPRINTER_INFO_3 pPrinterInfo3 = (PPRINTER_INFO_3)(*ppPrinterInfo);
62
63 pPrinterInfo3->pSecurityDescriptor = (PSECURITY_DESCRIPTOR)((ULONG_PTR)pPrinterInfo3->pSecurityDescriptor - (ULONG_PTR)pPrinterInfo3);
64
65 *ppPrinterInfo += sizeof(PRINTER_INFO_3);
66 }
67 else if (Level == 4)
68 {
69 PPRINTER_INFO_4W pPrinterInfo4 = (PPRINTER_INFO_4W)(*ppPrinterInfo);
70
71 pPrinterInfo4->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo4->pPrinterName - (ULONG_PTR)pPrinterInfo4);
72
73 if (pPrinterInfo4->pServerName)
74 pPrinterInfo4->pServerName = (PWSTR)((ULONG_PTR)pPrinterInfo4->pServerName - (ULONG_PTR)pPrinterInfo4);
75
76 *ppPrinterInfo += sizeof(PRINTER_INFO_4W);
77 }
78 else if (Level == 5)
79 {
80 PPRINTER_INFO_5W pPrinterInfo5 = (PPRINTER_INFO_5W)(*ppPrinterInfo);
81
82 pPrinterInfo5->pPrinterName = (PWSTR)((ULONG_PTR)pPrinterInfo5->pPrinterName - (ULONG_PTR)pPrinterInfo5);
83 pPrinterInfo5->pPortName = (PWSTR)((ULONG_PTR)pPrinterInfo5->pPortName - (ULONG_PTR)pPrinterInfo5);
84
85 *ppPrinterInfo += sizeof(PRINTER_INFO_5W);
86 }
87 else if (Level == 6)
88 {
89 *ppPrinterInfo += sizeof(PRINTER_INFO_6);
90 }
91 else if (Level == 7)
92 {
93 PPRINTER_INFO_7W pPrinterInfo7 = (PPRINTER_INFO_7W)(*ppPrinterInfo);
94
95 if (pPrinterInfo7->pszObjectGUID)
96 pPrinterInfo7->pszObjectGUID = (PWSTR)((ULONG_PTR)pPrinterInfo7->pszObjectGUID - (ULONG_PTR)pPrinterInfo7);
97
98 *ppPrinterInfo += sizeof(PRINTER_INFO_7W);
99 }
100 else if (Level == 8)
101 {
102 PPRINTER_INFO_8W pPrinterInfo8 = (PPRINTER_INFO_8W)(*ppPrinterInfo);
103
104 pPrinterInfo8->pDevMode = (PDEVMODEW)((ULONG_PTR)pPrinterInfo8->pDevMode - (ULONG_PTR)pPrinterInfo8);
105
106 *ppPrinterInfo += sizeof(PRINTER_INFO_8W);
107 }
108 else if (Level == 9)
109 {
110 PPRINTER_INFO_9W pPrinterInfo9 = (PPRINTER_INFO_9W)(*ppPrinterInfo);
111
112 pPrinterInfo9->pDevMode = (PDEVMODEW)((ULONG_PTR)pPrinterInfo9->pDevMode - (ULONG_PTR)pPrinterInfo9);
113
114 *ppPrinterInfo += sizeof(PRINTER_INFO_9W);
115 }
116 }
117
118 DWORD
119 _RpcAbortPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
120 {
121 UNIMPLEMENTED;
122 return ERROR_INVALID_FUNCTION;
123 }
124
125 DWORD
126 _RpcAddPrinter(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_PRINTER_HANDLE* pHandle)
127 {
128 UNIMPLEMENTED;
129 return ERROR_INVALID_FUNCTION;
130 }
131
132 DWORD
133 _RpcAddPrinterEx(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo, WINSPOOL_PRINTER_HANDLE* pHandle)
134 {
135 UNIMPLEMENTED;
136 return ERROR_INVALID_FUNCTION;
137 }
138
139 DWORD
140 _RpcClosePrinter(WINSPOOL_PRINTER_HANDLE* phPrinter)
141 {
142 DWORD dwErrorCode;
143
144 dwErrorCode = RpcImpersonateClient(NULL);
145 if (dwErrorCode != ERROR_SUCCESS)
146 {
147 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
148 return dwErrorCode;
149 }
150
151 if (ClosePrinter(*phPrinter))
152 *phPrinter = NULL;
153 else
154 dwErrorCode = GetLastError();
155
156 RpcRevertToSelf();
157 return dwErrorCode;
158 }
159
160 DWORD
161 _RpcDeletePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
162 {
163 UNIMPLEMENTED;
164 return ERROR_INVALID_FUNCTION;
165 }
166
167 DWORD
168 _RpcEndDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
169 {
170 DWORD dwErrorCode;
171
172 dwErrorCode = RpcImpersonateClient(NULL);
173 if (dwErrorCode != ERROR_SUCCESS)
174 {
175 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
176 return dwErrorCode;
177 }
178
179 if (!EndDocPrinter(hPrinter))
180 dwErrorCode = GetLastError();
181
182 RpcRevertToSelf();
183 return dwErrorCode;
184 }
185
186 DWORD
187 _RpcEndPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
188 {
189 DWORD dwErrorCode;
190
191 dwErrorCode = RpcImpersonateClient(NULL);
192 if (dwErrorCode != ERROR_SUCCESS)
193 {
194 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
195 return dwErrorCode;
196 }
197
198 if (!EndPagePrinter(hPrinter))
199 dwErrorCode = GetLastError();
200
201 RpcRevertToSelf();
202 return dwErrorCode;
203 }
204
205 DWORD
206 _RpcEnumPrinters(DWORD Flags, WINSPOOL_HANDLE Name, DWORD Level, BYTE* pPrinterEnum, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
207 {
208 DWORD dwErrorCode;
209 PBYTE pPrinterEnumAligned;
210
211 dwErrorCode = RpcImpersonateClient(NULL);
212 if (dwErrorCode != ERROR_SUCCESS)
213 {
214 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
215 return dwErrorCode;
216 }
217
218 pPrinterEnumAligned = AlignRpcPtr(pPrinterEnum, &cbBuf);
219
220 if (EnumPrintersW(Flags, Name, Level, pPrinterEnumAligned, cbBuf, pcbNeeded, pcReturned))
221 {
222 DWORD i;
223 PBYTE p = pPrinterEnumAligned;
224
225 for (i = 0; i < *pcReturned; i++)
226 _MarshallDownPrinterInfo(&p, Level);
227 }
228 else
229 {
230 dwErrorCode = GetLastError();
231 }
232
233 RpcRevertToSelf();
234 UndoAlignRpcPtr(pPrinterEnum, pPrinterEnumAligned, cbBuf, pcbNeeded);
235
236 return dwErrorCode;
237 }
238
239 DWORD
240 _RpcFlushPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten, DWORD cSleep)
241 {
242 UNIMPLEMENTED;
243 return ERROR_INVALID_FUNCTION;
244 }
245
246 DWORD
247 _RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pPrinter, DWORD cbBuf, DWORD* pcbNeeded)
248 {
249 DWORD dwErrorCode;
250 PBYTE pPrinterAligned;
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 pPrinterAligned = AlignRpcPtr(pPrinter, &cbBuf);
260
261 if (GetPrinterW(hPrinter, Level, pPrinterAligned, cbBuf, pcbNeeded))
262 {
263 PBYTE p = pPrinterAligned;
264 _MarshallDownPrinterInfo(&p, Level);
265 }
266 else
267 {
268 dwErrorCode = GetLastError();
269 }
270
271 RpcRevertToSelf();
272 UndoAlignRpcPtr(pPrinter, pPrinterAligned, cbBuf, pcbNeeded);
273
274 return dwErrorCode;
275 }
276
277 DWORD
278 _RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* phPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired)
279 {
280 DWORD dwErrorCode;
281 PRINTER_DEFAULTSW Default;
282
283 dwErrorCode = RpcImpersonateClient(NULL);
284 if (dwErrorCode != ERROR_SUCCESS)
285 {
286 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
287 return dwErrorCode;
288 }
289
290 Default.DesiredAccess = AccessRequired;
291 Default.pDatatype = pDatatype;
292 Default.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
293
294 if (!OpenPrinterW(pPrinterName, phPrinter, &Default))
295 dwErrorCode = GetLastError();
296
297 RpcRevertToSelf();
298 return dwErrorCode;
299 }
300
301 DWORD
302 _RpcOpenPrinterEx(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* pHandle, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo)
303 {
304 UNIMPLEMENTED;
305 return ERROR_INVALID_FUNCTION;
306 }
307
308 DWORD
309 _RpcReadPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcNoBytesRead)
310 {
311 DWORD dwErrorCode;
312
313 dwErrorCode = RpcImpersonateClient(NULL);
314 if (dwErrorCode != ERROR_SUCCESS)
315 {
316 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
317 return dwErrorCode;
318 }
319
320 if (!ReadPrinter(hPrinter, pBuf, cbBuf, pcNoBytesRead))
321 dwErrorCode = GetLastError();
322
323 RpcRevertToSelf();
324 return dwErrorCode;
325 }
326
327 DWORD
328 _RpcResetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer)
329 {
330 UNIMPLEMENTED;
331 return ERROR_INVALID_FUNCTION;
332 }
333
334 DWORD
335 _RpcResetPrinterEx()
336 {
337 UNIMPLEMENTED;
338 return ERROR_INVALID_FUNCTION;
339 }
340
341 DWORD
342 _RpcSeekPrinter()
343 {
344 UNIMPLEMENTED;
345 return ERROR_INVALID_FUNCTION;
346 }
347
348 DWORD
349 _RpcSetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, DWORD Command)
350 {
351 UNIMPLEMENTED;
352 return ERROR_INVALID_FUNCTION;
353 }
354
355 DWORD
356 _RpcStartDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_DOC_INFO_CONTAINER* pDocInfoContainer, DWORD* pJobId)
357 {
358 DWORD dwErrorCode;
359
360 dwErrorCode = RpcImpersonateClient(NULL);
361 if (dwErrorCode != ERROR_SUCCESS)
362 {
363 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
364 return dwErrorCode;
365 }
366
367 *pJobId = StartDocPrinterW(hPrinter, pDocInfoContainer->Level, (PBYTE)pDocInfoContainer->DocInfo.pDocInfo1);
368 dwErrorCode = GetLastError();
369
370 RpcRevertToSelf();
371 return dwErrorCode;
372 }
373
374 DWORD
375 _RpcStartPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
376 {
377 DWORD dwErrorCode;
378
379 dwErrorCode = RpcImpersonateClient(NULL);
380 if (dwErrorCode != ERROR_SUCCESS)
381 {
382 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
383 return dwErrorCode;
384 }
385
386 if (!StartPagePrinter(hPrinter))
387 dwErrorCode = GetLastError();
388
389 RpcRevertToSelf();
390 return dwErrorCode;
391 }
392
393 DWORD
394 _RpcWritePrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten)
395 {
396 DWORD dwErrorCode;
397
398 dwErrorCode = RpcImpersonateClient(NULL);
399 if (dwErrorCode != ERROR_SUCCESS)
400 {
401 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
402 return dwErrorCode;
403 }
404
405 if (!WritePrinter(hPrinter, pBuf, cbBuf, pcWritten))
406 dwErrorCode = GetLastError();
407
408 RpcRevertToSelf();
409 return dwErrorCode;
410 }