[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 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 DWORD i;
141 PBYTE p = pPrinterEnum;
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 EnumPrintersW(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
151 dwErrorCode = GetLastError();
152
153 if (dwErrorCode == ERROR_SUCCESS)
154 {
155 // Replace absolute pointer addresses in the output by relative offsets.
156 for (i = 0; i < *pcReturned; i++)
157 {
158 _MarshallDownPrinterInfo(p, Level);
159
160 if (Level == 1)
161 p += sizeof(PRINTER_INFO_1W);
162 else if (Level == 2)
163 p += sizeof(PRINTER_INFO_2W);
164 }
165 }
166
167 RpcRevertToSelf();
168 return dwErrorCode;
169 }
170
171 DWORD
172 _RpcFlushPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten, DWORD cSleep)
173 {
174 UNIMPLEMENTED;
175 return ERROR_INVALID_FUNCTION;
176 }
177
178 DWORD
179 _RpcGetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pPrinter, DWORD cbBuf, DWORD* pcbNeeded)
180 {
181 UNIMPLEMENTED;
182 return ERROR_INVALID_FUNCTION;
183 }
184
185 DWORD
186 _RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* phPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired)
187 {
188 DWORD dwErrorCode;
189 PRINTER_DEFAULTSW Default;
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 Default.DesiredAccess = AccessRequired;
199 Default.pDatatype = pDatatype;
200 Default.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
201
202 OpenPrinterW(pPrinterName, phPrinter, &Default);
203 dwErrorCode = GetLastError();
204
205 RpcRevertToSelf();
206 return dwErrorCode;
207 }
208
209 DWORD
210 _RpcOpenPrinterEx(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* pHandle, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, DWORD AccessRequired, WINSPOOL_SPLCLIENT_CONTAINER* pClientInfo)
211 {
212 UNIMPLEMENTED;
213 return ERROR_INVALID_FUNCTION;
214 }
215
216 DWORD
217 _RpcReadPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcNoBytesRead)
218 {
219 DWORD dwErrorCode;
220
221 dwErrorCode = RpcImpersonateClient(NULL);
222 if (dwErrorCode != ERROR_SUCCESS)
223 {
224 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
225 return dwErrorCode;
226 }
227
228 ReadPrinter(hPrinter, pBuf, cbBuf, pcNoBytesRead);
229 dwErrorCode = GetLastError();
230
231 RpcRevertToSelf();
232 return dwErrorCode;
233 }
234
235 DWORD
236 _RpcResetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pDatatype, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer)
237 {
238 UNIMPLEMENTED;
239 return ERROR_INVALID_FUNCTION;
240 }
241
242 DWORD
243 _RpcResetPrinterEx()
244 {
245 UNIMPLEMENTED;
246 return ERROR_INVALID_FUNCTION;
247 }
248
249 DWORD
250 _RpcSeekPrinter()
251 {
252 UNIMPLEMENTED;
253 return ERROR_INVALID_FUNCTION;
254 }
255
256 DWORD
257 _RpcSetPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, DWORD Command)
258 {
259 UNIMPLEMENTED;
260 return ERROR_INVALID_FUNCTION;
261 }
262
263 DWORD
264 _RpcStartDocPrinter(WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_DOC_INFO_CONTAINER* pDocInfoContainer, DWORD* pJobId)
265 {
266 DWORD dwErrorCode;
267
268 dwErrorCode = RpcImpersonateClient(NULL);
269 if (dwErrorCode != ERROR_SUCCESS)
270 {
271 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
272 return dwErrorCode;
273 }
274
275 *pJobId = StartDocPrinterW(hPrinter, pDocInfoContainer->Level, (PBYTE)pDocInfoContainer->DocInfo.pDocInfo1);
276 dwErrorCode = GetLastError();
277
278 RpcRevertToSelf();
279 return dwErrorCode;
280 }
281
282 DWORD
283 _RpcStartPagePrinter(WINSPOOL_PRINTER_HANDLE hPrinter)
284 {
285 DWORD dwErrorCode;
286
287 dwErrorCode = RpcImpersonateClient(NULL);
288 if (dwErrorCode != ERROR_SUCCESS)
289 {
290 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
291 return dwErrorCode;
292 }
293
294 StartPagePrinter(hPrinter);
295 dwErrorCode = GetLastError();
296
297 RpcRevertToSelf();
298 return dwErrorCode;
299 }
300
301 DWORD
302 _RpcWritePrinter(WINSPOOL_PRINTER_HANDLE hPrinter, BYTE* pBuf, DWORD cbBuf, DWORD* pcWritten)
303 {
304 DWORD dwErrorCode;
305
306 dwErrorCode = RpcImpersonateClient(NULL);
307 if (dwErrorCode != ERROR_SUCCESS)
308 {
309 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
310 return dwErrorCode;
311 }
312
313 WritePrinter(hPrinter, pBuf, cbBuf, pcWritten);
314 dwErrorCode = GetLastError();
315
316 RpcRevertToSelf();
317 return dwErrorCode;
318 }