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