[LOCALSPL] [SPOOLSV] [WINSPOOL]
[reactos.git] / reactos / win32ss / printing / base / spoolsv / printers.c
1 /*
2 * PROJECT: ReactOS Print Spooler Service
3 * LICENSE: GNU GPLv2 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>
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
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 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 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 EnumPrintersW(Flags, Name, Level, pPrinterEnumAligned, cbBuf, pcbNeeded, pcReturned);
220 dwErrorCode = GetLastError();
221
222 if (dwErrorCode == ERROR_SUCCESS)
223 {
224 DWORD i;
225 PBYTE p = pPrinterEnumAligned;
226
227 for (i = 0; i < *pcReturned; i++)
228 _MarshallDownPrinterInfo(&p, Level);
229 }
230
231 RpcRevertToSelf();
232 UndoAlignRpcPtr(pPrinterEnum, pPrinterEnumAligned, cbBuf, pcbNeeded);
233
234 return dwErrorCode;
235 }
236
237 DWORD
238 _RpcFlushPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten, DWORD cSleep)
239 {
240 UNIMPLEMENTED;
241 return ERROR_INVALID_FUNCTION;
242 }
243
244 DWORD
245 _RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pPrinter, DWORD cbBuf, DWORD* pcbNeeded)
246 {
247 DWORD dwErrorCode;
248 PBYTE pPrinterAligned;
249
250 dwErrorCode = RpcImpersonateClient(NULL);
251 if (dwErrorCode != ERROR_SUCCESS)
252 {
253 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
254 return dwErrorCode;
255 }
256
257 pPrinterAligned = AlignRpcPtr(pPrinter, &cbBuf);
258 GetPrinterW(hPrinter, Level, pPrinterAligned, cbBuf, pcbNeeded);
259 dwErrorCode = GetLastError();
260
261 if (dwErrorCode == ERROR_SUCCESS)
262 {
263 PBYTE p = pPrinterAligned;
264 _MarshallDownPrinterInfo(&p, Level);
265 }
266
267 RpcRevertToSelf();
268 UndoAlignRpcPtr(pPrinter, pPrinterAligned, cbBuf, pcbNeeded);
269
270 return dwErrorCode;
271 }
272
273 DWORD
274 _RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* phPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired)
275 {
276 DWORD dwErrorCode;
277 PRINTER_DEFAULTSW Default;
278
279 dwErrorCode = RpcImpersonateClient(NULL);
280 if (dwErrorCode != ERROR_SUCCESS)
281 {
282 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
283 return dwErrorCode;
284 }
285
286 Default.DesiredAccess = AccessRequired;
287 Default.pDatatype = pDatatype;
288 Default.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
289
290 OpenPrinterW(pPrinterName, phPrinter, &Default);
291 dwErrorCode = GetLastError();
292
293 RpcRevertToSelf();
294 return dwErrorCode;
295 }
296
297 DWORD
298 _RpcOpenPrinterEx(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* pHandle, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo)
299 {
300 UNIMPLEMENTED;
301 return ERROR_INVALID_FUNCTION;
302 }
303
304 DWORD
305 _RpcReadPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcNoBytesRead)
306 {
307 DWORD dwErrorCode;
308
309 dwErrorCode = RpcImpersonateClient(NULL);
310 if (dwErrorCode != ERROR_SUCCESS)
311 {
312 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
313 return dwErrorCode;
314 }
315
316 ReadPrinter(hPrinter, pBuf, cbBuf, pcNoBytesRead);
317 dwErrorCode = GetLastError();
318
319 RpcRevertToSelf();
320 return dwErrorCode;
321 }
322
323 DWORD
324 _RpcResetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer)
325 {
326 UNIMPLEMENTED;
327 return ERROR_INVALID_FUNCTION;
328 }
329
330 DWORD
331 _RpcResetPrinterEx()
332 {
333 UNIMPLEMENTED;
334 return ERROR_INVALID_FUNCTION;
335 }
336
337 DWORD
338 _RpcSeekPrinter()
339 {
340 UNIMPLEMENTED;
341 return ERROR_INVALID_FUNCTION;
342 }
343
344 DWORD
345 _RpcSetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, DWORD Command)
346 {
347 UNIMPLEMENTED;
348 return ERROR_INVALID_FUNCTION;
349 }
350
351 DWORD
352 _RpcStartDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_DOC_INFO_CONTAINER* pDocInfoContainer, DWORD* pJobId)
353 {
354 DWORD dwErrorCode;
355
356 dwErrorCode = RpcImpersonateClient(NULL);
357 if (dwErrorCode != ERROR_SUCCESS)
358 {
359 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
360 return dwErrorCode;
361 }
362
363 *pJobId = StartDocPrinterW(hPrinter, pDocInfoContainer->Level, (PBYTE)pDocInfoContainer->DocInfo.pDocInfo1);
364 dwErrorCode = GetLastError();
365
366 RpcRevertToSelf();
367 return dwErrorCode;
368 }
369
370 DWORD
371 _RpcStartPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
372 {
373 DWORD dwErrorCode;
374
375 dwErrorCode = RpcImpersonateClient(NULL);
376 if (dwErrorCode != ERROR_SUCCESS)
377 {
378 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
379 return dwErrorCode;
380 }
381
382 StartPagePrinter(hPrinter);
383 dwErrorCode = GetLastError();
384
385 RpcRevertToSelf();
386 return dwErrorCode;
387 }
388
389 DWORD
390 _RpcWritePrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten)
391 {
392 DWORD dwErrorCode;
393
394 dwErrorCode = RpcImpersonateClient(NULL);
395 if (dwErrorCode != ERROR_SUCCESS)
396 {
397 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
398 return dwErrorCode;
399 }
400
401 WritePrinter(hPrinter, pBuf, cbBuf, pcWritten);
402 dwErrorCode = GetLastError();
403
404 RpcRevertToSelf();
405 return dwErrorCode;
406 }