Revert "[SHELL32] SHChangeNotify: Use tree for CDirectoryList (#6784)" (#6800)
[reactos.git] / win32ss / printing / base / spoolsv / printerdrivers.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 Printer Drivers
5 * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org)
6 */
7
8 #include "precomp.h"
9 #include "marshalling/printerdrivers.h"
10
11 DWORD
12 _RpcAddPrinterDriver(WINSPOOL_HANDLE pName, WINSPOOL_DRIVER_CONTAINER* pDriverContainer)
13 {
14 DWORD dwErrorCode;
15 PBYTE pDriverInfo = NULL;
16
17 switch ( pDriverContainer->Level )
18 {
19 case 8:
20 {
21 WINSPOOL_DRIVER_INFO_8 *pdi = pDriverContainer->DriverInfo.Level8;
22 PDRIVER_INFO_8W pdi8w = DllAllocSplMem(sizeof(DRIVER_INFO_8W));
23 pDriverInfo = (PBYTE)pdi8w;
24
25 pdi8w->pszPrintProcessor = pdi->pPrintProcessor;
26 pdi8w->pszVendorSetup = pdi->pVendorSetup;
27 pdi8w->pszzColorProfiles = pdi->pszzColorProfiles;
28 pdi8w->pszInfPath = pdi->pInfPath;
29 pdi8w->pszzCoreDriverDependencies = pdi->pszzCoreDriverDependencies;
30 pdi8w->ftMinInboxDriverVerDate = pdi->ftMinInboxDriverVerDate;
31 pdi8w->dwlMinInboxDriverVerVersion = pdi->dwlMinInboxDriverVerVersion;
32 }
33 case 6:
34 {
35 WINSPOOL_DRIVER_INFO_6 *pdi = pDriverContainer->DriverInfo.Level6;
36 PDRIVER_INFO_6W pdi6w;
37
38 if ( pDriverInfo == NULL )
39 {
40 pdi6w = DllAllocSplMem(sizeof(DRIVER_INFO_6W));
41 pDriverInfo = (PBYTE)pdi6w;
42 }
43 else
44 {
45 pdi6w = (PDRIVER_INFO_6W)pDriverInfo;
46 }
47
48 pdi6w->pszMfgName = pdi->pMfgName;
49 pdi6w->pszOEMUrl = pdi->pOEMUrl;
50 pdi6w->pszHardwareID = pdi->pHardwareID;
51 pdi6w->pszProvider = pdi->pProvider;
52 pdi6w->ftDriverDate = pdi->ftDriverDate;
53 pdi6w->dwlDriverVersion = pdi->dwlDriverVersion;
54 }
55 case 4:
56 {
57 WINSPOOL_DRIVER_INFO_4 *pdi = pDriverContainer->DriverInfo.Level4;
58 PDRIVER_INFO_4W pdi4w;
59
60 if ( pDriverInfo == NULL )
61 {
62 pdi4w = DllAllocSplMem(sizeof(DRIVER_INFO_4W));
63 pDriverInfo = (PBYTE)pdi4w;
64 }
65 else
66 {
67 pdi4w = (PDRIVER_INFO_4W)pDriverInfo;
68 }
69
70 pdi4w->pszzPreviousNames = pdi->pszzPreviousNames;
71 }
72 case 3:
73 {
74 WINSPOOL_DRIVER_INFO_3 *pdi = pDriverContainer->DriverInfo.Level3;
75 PDRIVER_INFO_3W pdi3w;
76
77 if ( pDriverInfo == NULL )
78 {
79 pdi3w = DllAllocSplMem(sizeof(DRIVER_INFO_3W));
80 pDriverInfo = (PBYTE)pdi3w;
81 }
82 else
83 {
84 pdi3w = (PDRIVER_INFO_3W)pDriverInfo;
85 }
86
87 pdi3w->pHelpFile = pdi->pHelpFile;
88 pdi3w->pDependentFiles = pdi->pDependentFiles;
89 pdi3w->pMonitorName = pdi->pMonitorName;
90 pdi3w->pDefaultDataType = pdi->pDefaultDataType;
91 pdi3w->pDependentFiles = pdi->pDependentFiles;
92 }
93 case 2:
94 {
95 WINSPOOL_DRIVER_INFO_2 *pdi = pDriverContainer->DriverInfo.Level2;
96 PDRIVER_INFO_2W pdi2w;
97
98 if ( pDriverInfo == NULL )
99 {
100 pdi2w = DllAllocSplMem(sizeof(DRIVER_INFO_2W));
101 pDriverInfo = (PBYTE)pdi2w;
102 }
103 else
104 {
105 pdi2w = (PDRIVER_INFO_2W)pDriverInfo;
106 }
107
108 pdi2w->pName = pdi->pName;
109 pdi2w->pEnvironment = pdi->pEnvironment;
110 pdi2w->pDriverPath = pdi->pDriverPath;
111 pdi2w->pDataFile = pdi->pDataFile;
112 pdi2w->pConfigFile = pdi->pConfigFile;
113 }
114 break;
115 //
116 // At this point pDriverInfo is null.
117 //
118 default:
119 return ERROR_INVALID_LEVEL;
120 }
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 if (!AddPrinterDriverW( pName, pDriverContainer->Level, pDriverInfo ))
130 dwErrorCode = GetLastError();
131
132 if ( pDriverInfo ) DllFreeSplMem( pDriverInfo );
133
134 RpcRevertToSelf();
135 return dwErrorCode;
136 }
137
138 DWORD
139 _RpcAddPrinterDriverEx(WINSPOOL_HANDLE pName, WINSPOOL_DRIVER_CONTAINER* pDriverContainer, DWORD dwFileCopyFlags)
140 {
141 DWORD dwErrorCode;
142 PBYTE pDriverInfo = NULL;
143
144 switch ( pDriverContainer->Level )
145 {
146 case 8:
147 {
148 WINSPOOL_DRIVER_INFO_8 *pdi = pDriverContainer->DriverInfo.Level8;
149 PDRIVER_INFO_8W pdi8w = DllAllocSplMem(sizeof(DRIVER_INFO_8W));
150 pDriverInfo = (PBYTE)pdi8w;
151
152 pdi8w->pszPrintProcessor = pdi->pPrintProcessor;
153 pdi8w->pszVendorSetup = pdi->pVendorSetup;
154 pdi8w->pszzColorProfiles = pdi->pszzColorProfiles;
155 pdi8w->pszInfPath = pdi->pInfPath;
156 pdi8w->pszzCoreDriverDependencies = pdi->pszzCoreDriverDependencies;
157 pdi8w->ftMinInboxDriverVerDate = pdi->ftMinInboxDriverVerDate;
158 pdi8w->dwlMinInboxDriverVerVersion = pdi->dwlMinInboxDriverVerVersion;
159 }
160 case 6:
161 {
162 WINSPOOL_DRIVER_INFO_6 *pdi = pDriverContainer->DriverInfo.Level6;
163 PDRIVER_INFO_6W pdi6w;
164
165 if ( pDriverInfo == NULL )
166 {
167 pdi6w = DllAllocSplMem(sizeof(DRIVER_INFO_6W));
168 pDriverInfo = (PBYTE)pdi6w;
169 }
170 else
171 {
172 pdi6w = (PDRIVER_INFO_6W)pDriverInfo;
173 }
174
175 pdi6w->pszMfgName = pdi->pMfgName;
176 pdi6w->pszOEMUrl = pdi->pOEMUrl;
177 pdi6w->pszHardwareID = pdi->pHardwareID;
178 pdi6w->pszProvider = pdi->pProvider;
179 pdi6w->ftDriverDate = pdi->ftDriverDate;
180 pdi6w->dwlDriverVersion = pdi->dwlDriverVersion;
181 }
182 case 4:
183 {
184 WINSPOOL_DRIVER_INFO_4 *pdi = pDriverContainer->DriverInfo.Level4;
185 PDRIVER_INFO_4W pdi4w;
186
187 if ( pDriverInfo == NULL )
188 {
189 pdi4w = DllAllocSplMem(sizeof(DRIVER_INFO_4W));
190 pDriverInfo = (PBYTE)pdi4w;
191 }
192 else
193 {
194 pdi4w = (PDRIVER_INFO_4W)pDriverInfo;
195 }
196
197 pdi4w->pszzPreviousNames = pdi->pszzPreviousNames;
198 }
199 case 3:
200 {
201 WINSPOOL_DRIVER_INFO_3 *pdi = pDriverContainer->DriverInfo.Level3;
202 PDRIVER_INFO_3W pdi3w;
203
204 if ( pDriverInfo == NULL )
205 {
206 pdi3w = DllAllocSplMem(sizeof(DRIVER_INFO_3W));
207 pDriverInfo = (PBYTE)pdi3w;
208 }
209 else
210 {
211 pdi3w = (PDRIVER_INFO_3W)pDriverInfo;
212 }
213
214 pdi3w->pHelpFile = pdi->pHelpFile;
215 pdi3w->pDependentFiles = pdi->pDependentFiles;
216 pdi3w->pMonitorName = pdi->pMonitorName;
217 pdi3w->pDefaultDataType = pdi->pDefaultDataType;
218 pdi3w->pDependentFiles = pdi->pDependentFiles;
219 }
220 case 2:
221 {
222 WINSPOOL_DRIVER_INFO_2 *pdi = pDriverContainer->DriverInfo.Level2;
223 PDRIVER_INFO_2W pdi2w;
224
225 if ( pDriverInfo == NULL )
226 {
227 pdi2w = DllAllocSplMem(sizeof(DRIVER_INFO_2W));
228 pDriverInfo = (PBYTE)pdi2w;
229 }
230 else
231 {
232 pdi2w = (PDRIVER_INFO_2W)pDriverInfo;
233 }
234
235 pdi2w->pName = pdi->pName;
236 pdi2w->pEnvironment = pdi->pEnvironment;
237 pdi2w->pDriverPath = pdi->pDriverPath;
238 pdi2w->pDataFile = pdi->pDataFile;
239 pdi2w->pConfigFile = pdi->pConfigFile;
240 }
241 break;
242 //
243 // At this point pDriverInfo is null.
244 //
245 default:
246 return ERROR_INVALID_LEVEL;
247 }
248
249 dwErrorCode = RpcImpersonateClient(NULL);
250 if (dwErrorCode != ERROR_SUCCESS)
251 {
252 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
253 return dwErrorCode;
254 }
255
256 if (!AddPrinterDriverExW( pName, pDriverContainer->Level, pDriverInfo, dwFileCopyFlags ))
257 dwErrorCode = GetLastError();
258
259 if ( pDriverInfo ) DllFreeSplMem( pDriverInfo );
260
261 RpcRevertToSelf();
262 return dwErrorCode;
263 }
264
265 DWORD
266 _RpcDeletePrinterDriver(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, WCHAR* pDriverName)
267 {
268 DWORD dwErrorCode;
269
270 dwErrorCode = RpcImpersonateClient(NULL);
271 if (dwErrorCode != ERROR_SUCCESS)
272 {
273 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
274 return dwErrorCode;
275 }
276
277 if (!DeletePrinterDriverW(pName, pEnvironment, pDriverName))
278 dwErrorCode = GetLastError();
279
280 RpcRevertToSelf();
281 return dwErrorCode;
282 }
283
284 DWORD
285 _RpcDeletePrinterDriverEx(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, WCHAR* pDriverName, DWORD dwDeleteFlag, DWORD dwVersionNum)
286 {
287 DWORD dwErrorCode;
288
289 dwErrorCode = RpcImpersonateClient(NULL);
290 if (dwErrorCode != ERROR_SUCCESS)
291 {
292 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
293 return dwErrorCode;
294 }
295
296 if (!DeletePrinterDriverExW(pName, pEnvironment, pDriverName, dwDeleteFlag, dwVersionNum))
297 dwErrorCode = GetLastError();
298
299 RpcRevertToSelf();
300 return dwErrorCode;
301 }
302
303 DWORD
304 _RpcEnumPrinterDrivers(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, DWORD Level, BYTE* pDrivers, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned)
305 {
306 DWORD dwErrorCode;
307 PBYTE pPrinterDriversEnumAligned;
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 pPrinterDriversEnumAligned = AlignRpcPtr(pDrivers, &cbBuf);
317
318 if (EnumPrinterDriversW(pName, pEnvironment, Level, pPrinterDriversEnumAligned, cbBuf, pcbNeeded, pcReturned))
319 {
320 // Replace absolute pointer addresses in the output by relative offsets.
321 ASSERT(Level <= 6 || Level == 8);
322 MarshallDownStructuresArray(pPrinterDriversEnumAligned, *pcReturned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
323 }
324 else
325 {
326 dwErrorCode = GetLastError();
327 }
328
329 RpcRevertToSelf();
330 UndoAlignRpcPtr(pDrivers, pPrinterDriversEnumAligned, cbBuf, pcbNeeded);
331
332 return dwErrorCode;
333 }
334
335 DWORD
336 _RpcGetPrinterDriver(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWORD Level, BYTE* pDriver, DWORD cbBuf, DWORD* pcbNeeded)
337 {
338 DWORD dwErrorCode;
339 PBYTE pDriverAligned;
340
341 TRACE("_RpcGetPrinterDriver(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded);
342
343 dwErrorCode = RpcImpersonateClient(NULL);
344 if (dwErrorCode != ERROR_SUCCESS)
345 {
346 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
347 return dwErrorCode;
348 }
349
350 pDriverAligned = AlignRpcPtr(pDriver, &cbBuf);
351
352 if (GetPrinterDriverW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded))
353 {
354 // Replace relative offset addresses in the output by absolute pointers.
355 ASSERT(Level <= 6 || Level == 8);
356 MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
357 }
358 else
359 {
360 dwErrorCode = GetLastError();
361 }
362
363 RpcRevertToSelf();
364 UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded);
365
366 return dwErrorCode;
367 }
368
369 BOOL WINAPI YGetPrinterDriver2(
370 HANDLE hPrinter,
371 LPWSTR pEnvironment,
372 DWORD Level,
373 LPBYTE pDriver,
374 DWORD cbBuf,
375 LPDWORD pcbNeeded,
376 DWORD dwClientMajorVersion,
377 DWORD dwClientMinorVersion,
378 PDWORD pdwServerMajorVersion,
379 PDWORD pdwServerMinorVersion,
380 BOOL bRPC ) // Seems that all Y fuctions have this.
381 {
382 DWORD dwErrorCode;
383 PBYTE pDriverAligned;
384
385 FIXME("_Rpc(Y)GetPrinterDriver2(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion);
386
387 if ( bRPC )
388 {
389 dwErrorCode = RpcImpersonateClient(NULL);
390 if (dwErrorCode != ERROR_SUCCESS)
391 {
392 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
393 return dwErrorCode;
394 }
395 }
396
397 pDriverAligned = AlignRpcPtr(pDriver, &cbBuf);
398
399 if (GetPrinterDriverExW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion))
400 {
401 // Replace relative offset addresses in the output by absolute pointers.
402 ASSERT(Level <= 6 || Level == 8);
403 MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
404 }
405 else
406 {
407 dwErrorCode = GetLastError();
408 }
409
410 if ( bRPC ) RpcRevertToSelf();
411 UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded);
412
413 return dwErrorCode;
414 }
415
416 DWORD
417 _RpcGetPrinterDriver2(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWORD Level, BYTE* pDriver, DWORD cbBuf, DWORD* pcbNeeded, DWORD dwClientMajorVersion, DWORD dwClientMinorVersion, DWORD* pdwServerMaxVersion, DWORD* pdwServerMinVersion)
418 {
419 DWORD dwErrorCode;
420 PBYTE pDriverAligned;
421
422 FIXME("_RpcGetPrinterDriver2(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMaxVersion, pdwServerMinVersion);
423
424 dwErrorCode = RpcImpersonateClient(NULL);
425 if (dwErrorCode != ERROR_SUCCESS)
426 {
427 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
428 return dwErrorCode;
429 }
430
431 pDriverAligned = AlignRpcPtr(pDriver, &cbBuf);
432
433 if (GetPrinterDriverExW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMaxVersion, pdwServerMinVersion))
434 {
435 // Replace relative offset addresses in the output by absolute pointers.
436 ASSERT(Level <= 6 || Level == 8);
437 MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE);
438 }
439 else
440 {
441 dwErrorCode = GetLastError();
442 }
443
444 RpcRevertToSelf();
445 UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded);
446
447 return dwErrorCode;
448 }
449
450 DWORD
451 _RpcGetPrinterDriverDirectory(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, DWORD Level, BYTE* pDriverDirectory, DWORD cbBuf, DWORD* pcbNeeded)
452 {
453 DWORD dwErrorCode;
454
455 dwErrorCode = RpcImpersonateClient(NULL);
456 if (dwErrorCode != ERROR_SUCCESS)
457 {
458 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode);
459 return dwErrorCode;
460 }
461
462 if (!GetPrinterDriverDirectoryW(pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded))
463 dwErrorCode = GetLastError();
464
465 RpcRevertToSelf();
466 return dwErrorCode;
467 }