ReactOS 0.4.15-dev-7958-gcd0bb1a
printerdrivers.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Local Spooler
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Functions for printer driver information
5 * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
6 * Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7 */
8
9#include "precomp.h"
10#include <strsafe.h>
11
12typedef struct {
20
21static const WCHAR backslashW[] = {'\\',0};
22static const WCHAR configuration_fileW[] = {'C','o','n','f','i','g','u','r','a','t','i','o','n',' ','F','i','l','e',0};
23static const WCHAR datatypeW[] = {'D','a','t','a','t','y','p','e',0};
24static const WCHAR data_fileW[] = {'D','a','t','a',' ','F','i','l','e',0};
25static const WCHAR dependent_filesW[] = {'D','e','p','e','n','d','e','n','t',' ','F','i','l','e','s',0};
26static const WCHAR driverW[] = {'D','r','i','v','e','r',0};
27static const WCHAR emptyW[] = {0};
28static const WCHAR fmt_driversW[] = { 'S','y','s','t','e','m','\\',
29 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
30 'c','o','n','t','r','o','l','\\',
31 'P','r','i','n','t','\\',
32 'E','n','v','i','r','o','n','m','e','n','t','s','\\',
33 '%','s','\\','D','r','i','v','e','r','s','%','s',0 };
34static const WCHAR monitorW[] = {'M','o','n','i','t','o','r',0};
35static const WCHAR previous_namesW[] = {'P','r','e','v','i','o','u','s',' ','N','a','m','e','s',0};
36
37static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
38
39static const WCHAR spoolW[] = {'\\','s','p','o','o','l',0};
40static const WCHAR driversW[] = {'\\','d','r','i','v','e','r','s','\\',0};
41static const WCHAR ia64_envnameW[] = {'W','i','n','d','o','w','s',' ','I','A','6','4',0};
42static const WCHAR ia64_subdirW[] = {'i','a','6','4',0};
43static const WCHAR version3_regpathW[] = {'\\','V','e','r','s','i','o','n','-','3',0};
44static const WCHAR version3_subdirW[] = {'\\','3',0};
45static const WCHAR version0_regpathW[] = {'\\','V','e','r','s','i','o','n','-','0',0};
46static const WCHAR version0_subdirW[] = {'\\','0',0};
47static const WCHAR help_fileW[] = {'H','e','l','p',' ','F','i','l','e',0};
48static const WCHAR x64_envnameW[] = {'W','i','n','d','o','w','s',' ','x','6','4',0};
49static const WCHAR x64_subdirW[] = {'x','6','4',0};
50static const WCHAR x86_envnameW[] = {'W','i','n','d','o','w','s',' ','N','T',' ','x','8','6',0};
51static const WCHAR x86_subdirW[] = {'w','3','2','x','8','6',0};
52static const WCHAR win40_envnameW[] = {'W','i','n','d','o','w','s',' ','4','.','0',0};
53static const WCHAR win40_subdirW[] = {'w','i','n','4','0',0};
54
56
58
60
62
64
65static const DWORD di_sizeof[] = {0, sizeof(DRIVER_INFO_1W), sizeof(DRIVER_INFO_2W),
66 sizeof(DRIVER_INFO_3W), sizeof(DRIVER_INFO_4W),
67 sizeof(DRIVER_INFO_5W), sizeof(DRIVER_INFO_6W),
68 0, sizeof(DRIVER_INFO_8W)};
69
71
75
76BOOL
78{
79 WCHAR szSysDir[MAX_PATH];
80 DWORD cbBuf;
81
83 return TRUE;
84
85 if (!GetSystemDirectoryW(szSysDir, _countof(szSysDir)))
86 {
87 ERR("GetSystemDirectoryW failed\n");
88 return FALSE;
89 }
90
92 StringCbCatW(wszLocalSplFile, sizeof(wszLocalSplFile), L"\\localspl.dll");
93
95 StringCbCatW(wszPrintUiFile, sizeof(wszPrintUiFile), L"\\printui.dll");
96
97 if (!LocalGetPrinterDriverDirectory(NULL, (PWSTR)wszCurrentEnvironment, 1, (PBYTE)szSysDir, (DWORD)sizeof(szSysDir), &cbBuf))
98 {
99 ERR("LocalGetPrinterDriverDirectory failed\n");
100 return FALSE;
101 }
102
103 StringCbCopyW(wszDriverPath, sizeof(wszDriverPath), szSysDir);
106
107 // HAX! need to get it from the Reg Key L"Driver"!
108 StringCbCatW(wszDriverPath, sizeof(wszDriverPath), L"UniDrv.dll");
109
110 FIXME("DriverPath : %S\n",wszDriverPath);
111
112 return TRUE;
113}
114
115// Local Constants
119};
120
123 FIELD_OFFSET(DRIVER_INFO_2W, pEnvironment),
124 FIELD_OFFSET(DRIVER_INFO_2W, pDriverPath),
125 FIELD_OFFSET(DRIVER_INFO_2W, pDataFile),
126 FIELD_OFFSET(DRIVER_INFO_2W, pConfigFile),
128};
129
132 FIELD_OFFSET(DRIVER_INFO_3W, pEnvironment),
133 FIELD_OFFSET(DRIVER_INFO_3W, pDriverPath),
134 FIELD_OFFSET(DRIVER_INFO_3W, pDataFile),
135 FIELD_OFFSET(DRIVER_INFO_3W, pConfigFile),
136 FIELD_OFFSET(DRIVER_INFO_3W, pHelpFile),
137 FIELD_OFFSET(DRIVER_INFO_3W, pDependentFiles),
138 FIELD_OFFSET(DRIVER_INFO_3W, pMonitorName),
139 FIELD_OFFSET(DRIVER_INFO_3W, pDefaultDataType),
141};
142
145 FIELD_OFFSET(DRIVER_INFO_4W, pEnvironment),
146 FIELD_OFFSET(DRIVER_INFO_4W, pDriverPath),
147 FIELD_OFFSET(DRIVER_INFO_4W, pDataFile),
148 FIELD_OFFSET(DRIVER_INFO_4W, pConfigFile),
149 FIELD_OFFSET(DRIVER_INFO_4W, pHelpFile),
150 FIELD_OFFSET(DRIVER_INFO_4W, pDependentFiles),
151 FIELD_OFFSET(DRIVER_INFO_4W, pMonitorName),
152 FIELD_OFFSET(DRIVER_INFO_4W, pDefaultDataType),
153 FIELD_OFFSET(DRIVER_INFO_4W, pszzPreviousNames),
155};
156
159 FIELD_OFFSET(DRIVER_INFO_5W, pEnvironment),
160 FIELD_OFFSET(DRIVER_INFO_5W, pDriverPath),
161 FIELD_OFFSET(DRIVER_INFO_5W, pDataFile),
162 FIELD_OFFSET(DRIVER_INFO_5W, pConfigFile),
164};
165
168 FIELD_OFFSET(DRIVER_INFO_6W, pEnvironment),
169 FIELD_OFFSET(DRIVER_INFO_6W, pDriverPath),
170 FIELD_OFFSET(DRIVER_INFO_6W, pDataFile),
171 FIELD_OFFSET(DRIVER_INFO_6W, pConfigFile),
172 FIELD_OFFSET(DRIVER_INFO_6W, pHelpFile),
173 FIELD_OFFSET(DRIVER_INFO_6W, pDependentFiles),
174 FIELD_OFFSET(DRIVER_INFO_6W, pMonitorName),
175 FIELD_OFFSET(DRIVER_INFO_6W, pDefaultDataType),
176 FIELD_OFFSET(DRIVER_INFO_6W, pszzPreviousNames),
177 FIELD_OFFSET(DRIVER_INFO_6W, pszMfgName),
178 FIELD_OFFSET(DRIVER_INFO_6W, pszOEMUrl),
179 FIELD_OFFSET(DRIVER_INFO_6W, pszHardwareID),
180 FIELD_OFFSET(DRIVER_INFO_6W, pszProvider),
182};
183
186 FIELD_OFFSET(DRIVER_INFO_8W, pEnvironment),
187 FIELD_OFFSET(DRIVER_INFO_8W, pDriverPath),
188 FIELD_OFFSET(DRIVER_INFO_8W, pDataFile),
189 FIELD_OFFSET(DRIVER_INFO_8W, pConfigFile),
190 FIELD_OFFSET(DRIVER_INFO_8W, pHelpFile),
191 FIELD_OFFSET(DRIVER_INFO_8W, pDependentFiles),
192 FIELD_OFFSET(DRIVER_INFO_8W, pMonitorName),
193 FIELD_OFFSET(DRIVER_INFO_8W, pDefaultDataType),
194 FIELD_OFFSET(DRIVER_INFO_8W, pszzPreviousNames),
195 FIELD_OFFSET(DRIVER_INFO_8W, pszMfgName),
196 FIELD_OFFSET(DRIVER_INFO_8W, pszOEMUrl),
197 FIELD_OFFSET(DRIVER_INFO_8W, pszHardwareID),
198 FIELD_OFFSET(DRIVER_INFO_8W, pszProvider),
199 FIELD_OFFSET(DRIVER_INFO_8W, pszPrintProcessor),
200 FIELD_OFFSET(DRIVER_INFO_8W, pszVendorSetup),
201 FIELD_OFFSET(DRIVER_INFO_8W, pszzColorProfiles),
202 FIELD_OFFSET(DRIVER_INFO_8W, pszInfPath),
203 FIELD_OFFSET(DRIVER_INFO_8W, pszzCoreDriverDependencies),
205};
206
207static void
209{
210 while (*pString)
211 {
212 if (*pString == '|')
213 *pString = '\0';
214 pString++;
215 }
216}
217
218static void
220{
221 DWORD n;
222 PCWSTR pwszStrings[1];
223
224 /* This value is only here to send something, I have not verified if it is actually correct */
225 pwszStrings[0] = pPrinter->pwszPrinterDriver;
226
227 // Calculate the string lengths.
228 if (!ppDriverInfo)
229 {
230 for (n = 0; n < _countof(pwszStrings); ++n)
231 {
232 *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
233 }
234
235 *pcbNeeded += sizeof(DRIVER_INFO_1W);
236 return;
237 }
238
239 // Finally copy the structure and advance to the next one in the output buffer.
240 *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo1Offsets, *ppDriverInfoEnd);
241 (*ppDriverInfo)++;
242}
243
244static void
246{
247 DWORD n;
248 PCWSTR pwszStrings[5];
249
250 pwszStrings[0] = pPrinter->pwszPrinterDriver; // pName
251 pwszStrings[1] = wszCurrentEnvironment; // pEnvironment
252 pwszStrings[2] = wszDriverPath; // pDriverPath
253 pwszStrings[3] = wszLocalSplFile; // pDataFile
254 pwszStrings[4] = wszPrintUiFile; // pConfigFile
255
256 // Calculate the string lengths.
257 if (!ppDriverInfo)
258 {
259 for (n = 0; n < _countof(pwszStrings); ++n)
260 {
261 if (pwszStrings[n])
262 {
263 *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
264 }
265 }
266
267 *pcbNeeded += sizeof(DRIVER_INFO_2W);
268 return;
269 }
270
271 (*ppDriverInfo)->cVersion = 3;
272
273 // Finally copy the structure and advance to the next one in the output buffer.
274 *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo2Offsets, *ppDriverInfoEnd);
275 (*ppDriverInfo)++;
276}
277
278static void
280{
281 DWORD n;
282 PCWSTR pwszStrings[9];
283
284 pwszStrings[0] = pPrinter->pwszPrinterDriver; // pName
285 pwszStrings[1] = wszCurrentEnvironment; // pEnvironment
286 pwszStrings[2] = wszDriverPath; // pDriverPath
287 pwszStrings[3] = wszLocalSplFile; // pDataFile
288 pwszStrings[4] = wszPrintUiFile; // pConfigFile
289 pwszStrings[5] = L""; // pHelpFile
290 pwszStrings[6] = L"localspl.dll|printui.dll|"; // pDependentFiles, | is separator and terminator!
291 pwszStrings[7] = NULL;
292 if (pPrinter->pPort && pPrinter->pPort->pPrintMonitor)
293 {
294 pwszStrings[7] = pPrinter->pPort->pPrintMonitor->pwszName;
295 }
296 pwszStrings[8] = pPrinter->pwszDefaultDatatype;
297
298
299 // Calculate the string lengths.
300 if (!ppDriverInfo)
301 {
302 for (n = 0; n < _countof(pwszStrings); ++n)
303 {
304 if (pwszStrings[n])
305 {
306 *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
307 }
308 }
309
310 *pcbNeeded += sizeof(DRIVER_INFO_3W);
311 return;
312 }
313
314 (*ppDriverInfo)->cVersion = 3;
315
316 // Finally copy the structure and advance to the next one in the output buffer.
317 *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo3Offsets, *ppDriverInfoEnd);
318 ToMultiSz((*ppDriverInfo)->pDependentFiles);
319 (*ppDriverInfo)++;
320}
321
322static void
324{
325 DWORD n;
326 PCWSTR pwszStrings[10];
327
328 pwszStrings[0] = pPrinter->pwszPrinterDriver; // pName
329 pwszStrings[1] = wszCurrentEnvironment; // pEnvironment
330 pwszStrings[2] = wszDriverPath; // pDriverPath
331 pwszStrings[3] = wszLocalSplFile; // pDataFile
332 pwszStrings[4] = wszPrintUiFile; // pConfigFile
333 pwszStrings[5] = L""; // pHelpFile
334 pwszStrings[6] = L"localspl.dll|printui.dll|"; // pDependentFiles, | is separator and terminator!
335 pwszStrings[7] = NULL;
336 if (pPrinter->pPort && pPrinter->pPort->pPrintMonitor)
337 {
338 pwszStrings[7] = pPrinter->pPort->pPrintMonitor->pwszName;
339 }
340 pwszStrings[8] = pPrinter->pwszDefaultDatatype;
341 pwszStrings[9] = NULL; // pszzPreviousNames
342
343 // Calculate the string lengths.
344 if (!ppDriverInfo)
345 {
346 for (n = 0; n < _countof(pwszStrings); ++n)
347 {
348 if (pwszStrings[n])
349 {
350 *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
351 }
352 }
353
354 *pcbNeeded += sizeof(DRIVER_INFO_4W);
355 return;
356 }
357
358 (*ppDriverInfo)->cVersion = 3;
359
360 // Finally copy the structure and advance to the next one in the output buffer.
361 *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo4Offsets, *ppDriverInfoEnd);
362 ToMultiSz((*ppDriverInfo)->pDependentFiles);
363 (*ppDriverInfo)++;
364}
365
366static void
368{
369 DWORD n;
370 PCWSTR pwszStrings[5];
371
372 pwszStrings[0] = pPrinter->pwszPrinterDriver; // pName
373 pwszStrings[1] = wszCurrentEnvironment; // pEnvironment
374 pwszStrings[2] = wszDriverPath; // pDriverPath UniDrv.dll
375 pwszStrings[3] = wszLocalSplFile; // pDataFile.ppd
376 pwszStrings[4] = wszPrintUiFile; // pConfigFile UniDrvUI.dll
377
378 // Calculate the string lengths.
379 if (!ppDriverInfo)
380 {
381 for (n = 0; n < _countof(pwszStrings); ++n)
382 {
383 if (pwszStrings[n])
384 {
385 *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
386 }
387 }
388
389 *pcbNeeded += sizeof(DRIVER_INFO_5W);
390 return;
391 }
392
393 (*ppDriverInfo)->cVersion = 3;
394 // Driver attributes, like UMPD/KMPD.
395 (*ppDriverInfo)->dwDriverAttributes = 0; // UMPD/KMPD, So where are they?
396 // Number of times the configuration file for this driver has been upgraded or downgraded since the last spooler restart.
397 (*ppDriverInfo)->dwConfigVersion = 1;
398 // Number of times the driver file for this driver has been upgraded or downgraded since the last spooler restart.
399 (*ppDriverInfo)->dwDriverVersion = 1;
400
401 // Finally copy the structure and advance to the next one in the output buffer.
402 *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo5Offsets, *ppDriverInfoEnd);
403 (*ppDriverInfo)++;
404}
405
406
407static void
409{
410 DWORD n;
411 PCWSTR pwszStrings[14];
412
414
415 pwszStrings[0] = pPrinter->pwszPrinterDriver; // pName
416 pwszStrings[1] = wszCurrentEnvironment; // pEnvironment
417 pwszStrings[2] = wszDriverPath; // pDriverPath
418 pwszStrings[3] = wszLocalSplFile; // pDataFile
419 pwszStrings[4] = wszPrintUiFile; // pConfigFile
420 pwszStrings[5] = L""; // pHelpFile
421 pwszStrings[6] = L"localspl.dll|printui.dll|"; // pDependentFiles, | is separator and terminator!
422 pwszStrings[7] = NULL;
423 if (pPrinter->pPort && pPrinter->pPort->pPrintMonitor)
424 {
425 pwszStrings[7] = pPrinter->pPort->pPrintMonitor->pwszName;
426 }
427 pwszStrings[8] = pPrinter->pwszDefaultDatatype;
428 pwszStrings[9] = NULL; // pszzPreviousNames
429 pwszStrings[10] = NULL; // pszMfgName
430 pwszStrings[11] = NULL; // pszOEMUrl
431 pwszStrings[12] = NULL; // pszHardwareID
432 pwszStrings[13] = wszScratchPad;
433
434 // Calculate the string lengths.
435 if (!ppDriverInfo)
436 {
437 for (n = 0; n < _countof(pwszStrings); ++n)
438 {
439 if (pwszStrings[n])
440 {
441 *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
442 }
443 }
444
445 *pcbNeeded += sizeof(DRIVER_INFO_6W);
446 return;
447 }
448
449 (*ppDriverInfo)->cVersion = 3;
450
451 // Finally copy the structure and advance to the next one in the output buffer.
452 *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo6Offsets, *ppDriverInfoEnd);
453 ToMultiSz((*ppDriverInfo)->pDependentFiles);
454 (*ppDriverInfo)++;
455}
456
457static void
459{
460 DWORD n;
461 PCWSTR pwszStrings[19];
462
464
465 pwszStrings[0] = pPrinter->pwszPrinterDriver; // pName
466 pwszStrings[1] = wszCurrentEnvironment; // pEnvironment
467 pwszStrings[2] = wszDriverPath; // pDriverPath
468 pwszStrings[3] = wszLocalSplFile; // pDataFile
469 pwszStrings[4] = wszPrintUiFile; // pConfigFile
470 pwszStrings[5] = L""; // pHelpFile
471 pwszStrings[6] = L"localspl.dll|printui.dll|"; // pDependentFiles, | is separator and terminator!
472 pwszStrings[7] = NULL;
473 if (pPrinter->pPort && pPrinter->pPort->pPrintMonitor)
474 {
475 pwszStrings[7] = pPrinter->pPort->pPrintMonitor->pwszName;
476 }
477 pwszStrings[8] = pPrinter->pwszDefaultDatatype;
478 pwszStrings[9] = NULL; // pszzPreviousNames
479 pwszStrings[10] = NULL; // pszMfgName
480 pwszStrings[11] = NULL; // pszOEMUrl
481 pwszStrings[12] = NULL; // pszHardwareID
482 pwszStrings[13] = wszScratchPad;
483 pwszStrings[14] = NULL;
484 if ( pPrinter->pPrintProcessor )
485 {
486 pwszStrings[14] = pPrinter->pPrintProcessor->pwszName;
487 }
488 pwszStrings[15] = NULL; // pszVendorSetup
489 pwszStrings[16] = NULL; // pszzColorProfiles
490 pwszStrings[17] = NULL; // pszInfPath
491 pwszStrings[18] = NULL; // pszzCoreDriverDependencies
492
493 // Calculate the string lengths.
494 if (!ppDriverInfo)
495 {
496 for (n = 0; n < _countof(pwszStrings); ++n)
497 {
498 if (pwszStrings[n])
499 {
500 *pcbNeeded += (wcslen(pwszStrings[n]) + 1) * sizeof(WCHAR);
501 }
502 }
503
504 *pcbNeeded += sizeof(DRIVER_INFO_8W);
505 return;
506 }
507
508 (*ppDriverInfo)->cVersion = 3;
509
510 // Finally copy the structure and advance to the next one in the output buffer.
511 *ppDriverInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppDriverInfo), dwDriverInfo8Offsets, *ppDriverInfoEnd);
512 ToMultiSz((*ppDriverInfo)->pDependentFiles);
513 (*ppDriverInfo)++;
514}
515
517
519 NULL,
526 NULL,
528};
529
530BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
531{
532 DWORD dwErrorCode;
533 PBYTE pEnd = &pDriverInfo[cbBuf];
534 PLOCAL_HANDLE pHandle;
535 PLOCAL_PRINTER_HANDLE pPrinterHandle;
536
537 TRACE("LocalGetPrinterDriver(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
538
539 // Check if this is a printer handle.
540 pHandle = (PLOCAL_HANDLE)hPrinter;
541 if (pHandle->HandleType != HandleType_Printer)
542 {
543 dwErrorCode = ERROR_INVALID_HANDLE;
544 goto Cleanup;
545 }
546
547 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
548
549 // Only support 8 levels and not 7
550 if (Level < 1 || Level == 7 || Level > 8)
551 {
552 // The caller supplied an invalid level.
553 dwErrorCode = ERROR_INVALID_LEVEL;
554 goto Cleanup;
555 }
556
557 // Count the required buffer size.
558 *pcbNeeded = 0;
559
561
562 // Check if the supplied buffer is large enough.
563 if (cbBuf < *pcbNeeded)
564 {
565 ERR("Insuffisient Buffer size\n");
566 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
567 goto Cleanup;
568 }
569
570 // Copy over the information.
571 pEnd = &pDriverInfo[*pcbNeeded];
572
573 pfnPrinterDriverLevels[Level](pPrinterHandle->pPrinter, &pDriverInfo, &pEnd, NULL);
574
575 dwErrorCode = ERROR_SUCCESS;
576
577Cleanup:
578 SetLastError(dwErrorCode);
579 return (dwErrorCode == ERROR_SUCCESS);
580}
581
583 HANDLE hPrinter,
584 LPWSTR pEnvironment,
585 DWORD Level,
586 LPBYTE pDriverInfo,
587 DWORD cbBuf,
589 DWORD dwClientMajorVersion,
590 DWORD dwClientMinorVersion,
591 PDWORD pdwServerMajorVersion,
592 PDWORD pdwServerMinorVersion )
593{
594 FIXME("LocalGetPrinterDriverEx(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion);
596 return LocalGetPrinterDriver( hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded );
597}
598
600LocalEnumPrinterDrivers(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
601{
602 DWORD dwErrorCode;
603 PSKIPLIST_NODE pNode;
604 PBYTE pEnd;
605 PLOCAL_PRINTER pPrinter;
606
607 FIXME("LocalEnumPrinterDrivers(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, pcReturned);
608
609 // Only support 8 levels and not 7
610 if (Level < 1 || Level == 7 || Level > 8)
611 {
612 // The caller supplied an invalid level.
613 dwErrorCode = ERROR_INVALID_LEVEL;
614 goto Cleanup;
615 }
616
617 // Count the required buffer size.
618 *pcbNeeded = 0;
619
620 // Count the required buffer size and the number of printers.
621 for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
622 {
623 pPrinter = (PLOCAL_PRINTER)pNode->Element;
624
626 }
627
628 // Check if the supplied buffer is large enough.
629 if (cbBuf < *pcbNeeded)
630 {
631 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
632 goto Cleanup;
633 }
634
635 // Copy over the Printer information.
636 pEnd = &pDriverInfo[*pcbNeeded];
637
638 for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
639 {
640 pPrinter = (PLOCAL_PRINTER)pNode->Element;
641
642 pfnPrinterDriverLevels[Level](pPrinter, &pDriverInfo, &pEnd, NULL);
643 (*pcReturned)++;
644 }
645
646 dwErrorCode = ERROR_SUCCESS;
647
648Cleanup:
649 SetLastError(dwErrorCode);
650 return (dwErrorCode == ERROR_SUCCESS);
651}
652
653/******************************************************************
654 * Return the number of bytes for an multi_sz string.
655 * The result includes all \0s
656 * (specifically the extra \0, that is needed as multi_sz terminator).
657 */
658static int multi_sz_lenW(const WCHAR *str)
659{
660 const WCHAR *ptr = str;
661 if (!str) return 0;
662 do
663 {
664 ptr += lstrlenW(ptr) + 1;
665 } while (*ptr);
666
667 return (ptr - str + 1) * sizeof(WCHAR);
668}
669
670
671/******************************************************************
672 * validate_envW [internal]
673 *
674 * validate the user-supplied printing-environment
675 *
676 * PARAMS
677 * env [I] PTR to Environment-String or NULL
678 *
679 * RETURNS
680 * Success: PTR to printenv_t
681 * Failure: NULL and ERROR_INVALID_ENVIRONMENT
682 *
683 * NOTES
684 * An empty string is handled the same way as NULL.
685 *
686 */
688{
690 unsigned int i;
691
692 TRACE("(%s)\n", debugstr_w(env));
693 if (env && env[0])
694 {
695 for (i = 0; i < ARRAYSIZE(all_printenv); i++)
696 {
697 if (lstrcmpiW(env, all_printenv[i]->envname) == 0)
698 {
700 break;
701 }
702 }
703 if (result == NULL)
704 {
705 FIXME("unsupported Environment: %s\n", debugstr_w(env));
707 }
708 /* on win9x, only "Windows 4.0" is allowed, but we ignore this */
709 }
710 else
711 {
712 result = (GetVersion() & 0x80000000) ? &env_win40 : &env_x86;
713 }
714
715 TRACE("=> using %p: %s\n", result, debugstr_w(result ? result->envname : NULL));
716 return result;
717}
718
719/*****************************************************************************
720 * open_driver_reg [internal]
721 *
722 * opens the registry for the printer drivers depending on the given input
723 * variable pEnvironment
724 *
725 * RETURNS:
726 * Success: the opened hkey
727 * Failure: NULL
728 */
730{
731 HKEY retval = NULL;
733 const PRINTENV_T * env;
734
735 TRACE("(%s)\n", debugstr_w(pEnvironment));
736
737 env = validate_envW(pEnvironment);
738 if (!env) return NULL;
739
741 (lstrlenW(env->envname) + lstrlenW(env->versionregpath)) * sizeof(WCHAR));
742
743 if (buffer)
744 {
745 wsprintfW(buffer, fmt_driversW, env->envname, env->versionregpath);
748 }
749 return retval;
750}
751
752
753/******************************************************************************
754 * LocalGetPrintProcessorDirectory [exported through PRINTPROVIDOR]
755 *
756 * Return the PATH for the Print-Processors
757 *
758 * PARAMS
759 * pName [I] Servername or NULL (this computer)
760 * pEnvironment [I] Printing-Environment or NULL (Default)
761 * level [I] Structure-Level (must be 1)
762 * pPPInfo [O] PTR to Buffer that receives the Result
763 * cbBuf [I] Size of Buffer at pPPInfo
764 * pcbNeeded [O] PTR to DWORD that receives the size in Bytes used / required for pPPInfo
765 *
766 * RETURNS
767 * Success: TRUE
768 * Failure: FALSE and in pcbNeeded the Bytes required for pPPInfo, if cbBuf is too small
769 *
770 * Native Values returned in pPPInfo on Success for this computer:
771 *| NT(Windows x64): "%winsysdir%\\spool\\PRTPROCS\\x64"
772 *| NT(Windows NT x86): "%winsysdir%\\spool\\PRTPROCS\\w32x86"
773 *| NT(Windows 4.0): "%winsysdir%\\spool\\PRTPROCS\\win40"
774 *
775 * "%winsysdir%" is the Value from GetSystemDirectoryW()
776 *
777 */
779{
780 DWORD needed;
781 const PRINTENV_T * env = NULL;
782 WCHAR * const dir = (WCHAR *)pDriverDirectory;
783
784 FIXME("LocalGetPrinterDriverDirectory(%S, %S, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded);
785
786 if (pName != NULL && pName[0])
787 {
788 FIXME("server %s not supported\n", debugstr_w(pName));
790 return FALSE;
791 }
792
793 env = validate_envW(pEnvironment);
794 if (!env) return FALSE; /* pEnvironment invalid or unsupported */
795
796 /* GetSystemDirectoryW returns number of WCHAR including the '\0' */
797 needed = GetSystemDirectoryW(NULL, 0);
798 /* add the Size for the Subdirectories */
799 needed += lstrlenW(spoolW);
800 needed += lstrlenW(driversW);
801 needed += lstrlenW(env->subdir);
802 needed *= sizeof(WCHAR); /* return-value is size in Bytes */
803
804 *pcbNeeded = needed;
805
806 if (needed > cbBuf)
807 {
809 return FALSE;
810 }
811
812 if (dir == NULL)
813 {
814 /* ERROR_INVALID_USER_BUFFER is NT, ERROR_INVALID_PARAMETER is win9x */
816 return FALSE;
817 }
818
819 GetSystemDirectoryW( dir, cbBuf / sizeof(WCHAR) );
820 /* add the Subdirectories */
821 lstrcatW( dir, spoolW );
825 lstrcatW( dir, env->subdir );
827
828 FIXME( "=> %s\n", debugstr_w( dir ) );
829 return TRUE;
830}
831
832/******************************************************************
833 * apd_copyfile [internal]
834 *
835 * Copy a file from the driverdirectory to the versioned directory
836 *
837 * RETURNS
838 * Success: TRUE
839 * Failure: FALSE
840 *
841 */
842static BOOL apd_copyfile( WCHAR *pathname, WCHAR *file_part, apd_data_t *apd )
843{
844 WCHAR *srcname;
845 BOOL res;
846
847 apd->src[apd->srclen] = '\0';
848 apd->dst[apd->dstlen] = '\0';
849
850 if (!pathname || !pathname[0]) {
851 /* nothing to copy */
852 return TRUE;
853 }
854
856 srcname = pathname;
857 else
858 {
859 srcname = apd->src;
860 lstrcatW( srcname, file_part );
861 }
862 lstrcatW( apd->dst, file_part );
863
864 FIXME("%s => %s\n", debugstr_w(srcname), debugstr_w(apd->dst));
865
866 /* FIXME: handle APD_COPY_NEW_FILES */
867 res = CopyFileW(srcname, apd->dst, FALSE);
868 FIXME("got %d with %u\n", res, GetLastError());
869
870 return apd->lazy || res;
871}
872
873/******************************************************************
874 * driver_load [internal]
875 *
876 * load a driver user interface dll
877 *
878 * On failure, NULL is returned
879 *
880 */
881
882static HMODULE driver_load(const PRINTENV_T * env, LPWSTR dllname)
883{
885 HMODULE hui;
886 DWORD len;
887
888 FIXME("(%p, %s)\n", env, debugstr_w(dllname));
889
890 /* build the driverdir */
891 len = sizeof(fullname) - (lstrlenW(env->versionsubdir) + 1 + lstrlenW(dllname) + 1) * sizeof(WCHAR);
892
894 {
895 /* Should never fail */
897 return NULL;
898 }
899
900 lstrcatW(fullname, env->versionsubdir);
902 lstrcatW(fullname, dllname);
903
904 hui = LoadLibraryW(fullname);
905 FIXME("%p: LoadLibrary(%s) %d\n", hui, debugstr_w(fullname), GetLastError());
906
907 return hui;
908}
909
910static inline WCHAR *get_file_part( WCHAR *name )
911{
912 WCHAR *ptr = wcsrchr( name, '\\' );
913 if (ptr) return ptr + 1;
914 return name;
915}
916
917/******************************************************************************
918 * myAddPrinterDriverEx [internal]
919 *
920 * Install a Printer Driver with the Option to upgrade / downgrade the Files
921 * and a special mode with lazy error checking.
922 *
923 */
924BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags, BOOL lazy)
925{
926 const PRINTENV_T *env;
927 apd_data_t apd;
929 BOOL (WINAPI *pDrvDriverEvent)(DWORD, DWORD, LPBYTE, LPARAM);
930 HMODULE hui;
931 WCHAR *file;
932 HKEY hroot;
933 HKEY hdrv;
934 DWORD disposition;
935 DWORD len;
936 LONG lres;
937 BOOL res;
938
939 /* we need to set all entries in the Registry, independent from the Level of
940 DRIVER_INFO, that the caller supplied */
941
942 ZeroMemory(&di, sizeof(di));
943 if (pDriverInfo && (level < ARRAYSIZE(di_sizeof)))
944 {
945 memcpy(&di, pDriverInfo, di_sizeof[level]);
946 }
947
948 /* dump the most used infos */
949 FIXME("%p: .cVersion : 0x%x/%d\n", pDriverInfo, di.cVersion, di.cVersion);
950 FIXME("%p: .pName : %s\n", di.pName, debugstr_w(di.pName));
951 FIXME("%p: .pEnvironment: %s\n", di.pEnvironment, debugstr_w(di.pEnvironment));
952 FIXME("%p: .pDriverPath : %s\n", di.pDriverPath, debugstr_w(di.pDriverPath));
953 FIXME("%p: .pDataFile : %s\n", di.pDataFile, debugstr_w(di.pDataFile));
954 FIXME("%p: .pConfigFile : %s\n", di.pConfigFile, debugstr_w(di.pConfigFile));
955 FIXME("%p: .pHelpFile : %s\n", di.pHelpFile, debugstr_w(di.pHelpFile));
956 /* dump only the first of the additional Files */
957 FIXME("%p: .pDependentFiles: %s\n", di.pDependentFiles, debugstr_w(di.pDependentFiles));
958
959
960 /* check environment */
962 if (env == NULL) return FALSE; /* ERROR_INVALID_ENVIRONMENT */
963
964 /* fill the copy-data / get the driverdir */
965 len = sizeof(apd.src) - sizeof(version3_subdirW) - sizeof(WCHAR);
966 if (!LocalGetPrinterDriverDirectory(NULL, (LPWSTR) env->envname, 1, (LPBYTE) apd.src, len, &len))
967 {
968 /* Should never fail */
969 return FALSE;
970 }
971 memcpy(apd.dst, apd.src, len);
972 lstrcatW(apd.src, backslashW);
973 apd.srclen = lstrlenW(apd.src);
974 lstrcatW(apd.dst, env->versionsubdir);
975 lstrcatW(apd.dst, backslashW);
976 apd.dstlen = lstrlenW(apd.dst);
977 apd.copyflags = dwFileCopyFlags;
978 apd.lazy = lazy;
981
982 hroot = open_driver_reg(env->envname);
983 if (!hroot)
984 {
985 ERR("Can't create Drivers key\n");
986 return FALSE;
987 }
988
989 /* Fill the Registry for the Driver */
990 if ((lres = RegCreateKeyExW(hroot, di.pName, 0, NULL, REG_OPTION_NON_VOLATILE,
992 &hdrv, &disposition)) != ERROR_SUCCESS)
993 {
994 ERR("can't create driver %s: %u\n", debugstr_w(di.pName), lres);
995 RegCloseKey(hroot);
996 SetLastError(lres);
997 return FALSE;
998 }
999 RegCloseKey(hroot);
1000
1001 /* Verified with the Adobe PS Driver, that w2k does not use di.Version */
1002 RegSetValueExW(hdrv, versionW, 0, REG_DWORD, (const BYTE*) &env->driverversion,
1003 sizeof(DWORD));
1004
1006 RegSetValueExW( hdrv, driverW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
1007 apd_copyfile( di.pDriverPath, file, &apd );
1008
1010 RegSetValueExW( hdrv, data_fileW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
1011 apd_copyfile( di.pDataFile, file, &apd );
1012
1014 RegSetValueExW( hdrv, configuration_fileW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
1015 apd_copyfile( di.pConfigFile, file, &apd );
1016
1017 /* settings for level 3 */
1018 if (di.pHelpFile)
1019 {
1021 RegSetValueExW( hdrv, help_fileW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
1022 apd_copyfile( di.pHelpFile, file, &apd );
1023 }
1024 else
1025 RegSetValueExW( hdrv, help_fileW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW) );
1026
1027 if (di.pDependentFiles && *di.pDependentFiles)
1028 {
1029 WCHAR *reg, *reg_ptr, *in_ptr;
1030 reg = reg_ptr = HeapAlloc( GetProcessHeap(), 0, multi_sz_lenW( di.pDependentFiles ) );
1031
1032 for (in_ptr = di.pDependentFiles; *in_ptr; in_ptr += lstrlenW( in_ptr ) + 1)
1033 {
1034 file = get_file_part( in_ptr );
1035 len = lstrlenW( file ) + 1;
1036 memcpy( reg_ptr, file, len * sizeof(WCHAR) );
1037 reg_ptr += len;
1038 apd_copyfile( in_ptr, file, &apd );
1039 }
1040 *reg_ptr = 0;
1041
1042 RegSetValueExW( hdrv, dependent_filesW, 0, REG_MULTI_SZ, (LPBYTE)reg, (reg_ptr - reg + 1) * sizeof(WCHAR) );
1043 HeapFree( GetProcessHeap(), 0, reg );
1044 }
1045 else
1046 RegSetValueExW(hdrv, dependent_filesW, 0, REG_MULTI_SZ, (const BYTE*)emptyW, sizeof(emptyW));
1047
1048 /* The language-Monitor was already copied by the caller to "%SystemRoot%\system32" */
1049 if (di.pMonitorName)
1051 (lstrlenW(di.pMonitorName)+1)* sizeof(WCHAR));
1052 else
1053 RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW));
1054
1055 if (di.pDefaultDataType)
1057 (lstrlenW(di.pDefaultDataType)+1)* sizeof(WCHAR));
1058 else
1059 RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW));
1060
1061 /* settings for level 4 */
1062 if (di.pszzPreviousNames)
1065 else
1066 RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (const BYTE*)emptyW, sizeof(emptyW));
1067
1068 if (level > 5) FIXME("level %u for Driver %s is incomplete\n", level, debugstr_w(di.pName));
1069
1070 RegCloseKey(hdrv);
1071
1072 //
1073 // Locate driver and send the event.
1074 //
1075
1076 hui = driver_load(env, di.pConfigFile);
1077
1078 pDrvDriverEvent = (void *)GetProcAddress(hui, "DrvDriverEvent");
1079
1080 if (hui && pDrvDriverEvent)
1081 {
1082 /* Support for DrvDriverEvent is optional */
1083 TRACE("DRIVER_EVENT_INITIALIZE for %s (%s)\n", debugstr_w(di.pName), debugstr_w(di.pConfigFile));
1084 /* MSDN: level for DRIVER_INFO is 1 to 3 */
1085 res = pDrvDriverEvent(DRIVER_EVENT_INITIALIZE, 3, (LPBYTE) &di, 0);
1086 TRACE("got %d from DRIVER_EVENT_INITIALIZE\n", res);
1087 }
1088 FreeLibrary(hui);
1089
1090 FIXME("=> TRUE with %u\n", GetLastError());
1091 return TRUE;
1092}
1093
1094/******************************************************************************
1095 * AddPrinterDriverEx [exported through PRINTPROVIDOR]
1096 *
1097 * Install a Printer Driver with the Option to upgrade / downgrade the Files
1098 *
1099 * PARAMS
1100 * pName [I] Servername or NULL (local Computer)
1101 * level [I] Level for the supplied DRIVER_INFO_*W struct
1102 * pDriverInfo [I] PTR to DRIVER_INFO_*W struct with the Driver Parameter
1103 * dwFileCopyFlags [I] How to Copy / Upgrade / Downgrade the needed Files
1104 *
1105 * RESULTS
1106 * Success: TRUE
1107 * Failure: FALSE
1108 *
1109 */
1111{
1112 LONG lres;
1113
1114 TRACE("(%s, %d, %p, 0x%x)\n", debugstr_w(pName), level, pDriverInfo, dwFileCopyFlags);
1115
1117
1118 if (lres)
1119 {
1120 FIXME("server %s not supported\n", debugstr_w(pName));
1122 return FALSE;
1123 }
1124
1125 if ((dwFileCopyFlags & ~APD_COPY_FROM_DIRECTORY) != APD_COPY_ALL_FILES)
1126 {
1127 TRACE("Flags 0x%x ignored (using APD_COPY_ALL_FILES)\n", dwFileCopyFlags & ~APD_COPY_FROM_DIRECTORY);
1128 }
1129
1130 return myAddPrinterDriverEx(level, pDriverInfo, dwFileCopyFlags, TRUE);
1131}
1132
1134{
1135 LONG lres;
1136
1137 TRACE("(%s, %d, %p, 0x%x)\n", debugstr_w(pName), level, pDriverInfo);
1138
1140
1141 if (lres)
1142 {
1143 FIXME("server %s not supported\n", debugstr_w(pName));
1145 return FALSE;
1146 }
1147
1148 // Should be APD_COPY_NEW_FILES. Cheap wine.
1149
1150 return myAddPrinterDriverEx(level, pDriverInfo, APD_COPY_NEW_FILES, TRUE);
1151}
unsigned int dir
Definition: maze.c:112
PBYTE WINAPI PackStrings(PCWSTR *pSource, PBYTE pDest, const DWORD *DestOffsets, PBYTE pEnd)
Definition: tools.c:39
static int multi_sz_lenW(const WCHAR *str)
const WCHAR wszCurrentEnvironment[]
Definition: prtprocenv.h:11
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define wcsrchr
Definition: compat.h:16
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define LoadLibraryW(x)
Definition: compat.h:747
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxString * pString
GLint level
Definition: gl.h:1546
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLenum GLenum dst
Definition: glext.h:6340
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static int reg
Definition: i386-dis.c:1290
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
if(dx< 0)
Definition: linetemp.h:194
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char pathname[512]
Definition: util.h:13
static PVOID ptr
Definition: dispmode.c:27
static LPSTR pName
Definition: security.c:75
const char * fullname
Definition: shader.c:1766
#define BOOL
Definition: nt_native.h:43
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define KEY_WRITE
Definition: nt_native.h:1031
#define DWORD
Definition: nt_native.h:44
#define MAXDWORD
struct _DRIVER_INFO_2W DRIVER_INFO_2W
Definition: ntgdi.h:86
#define L(x)
Definition: ntvdm.h:50
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
static const WCHAR previous_namesW[]
static void _LocalGetPrinterDriverLevel5(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_5W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
static PRINTENV_T env_win40
static const DWORD di_sizeof[]
static WCHAR wszDriverPath[MAX_PATH]
static PPRINTENV_T all_printenv[]
static const WCHAR version3_regpathW[]
BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags, BOOL lazy)
static PRINTENV_T env_ia64
static const WCHAR datatypeW[]
BOOL WINAPI LocalAddPrinterDriver(LPWSTR pName, DWORD level, LPBYTE pDriverInfo)
BOOL WINAPI LocalAddPrinterDriverEx(LPWSTR pName, DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags)
static DWORD dwDriverInfo2Offsets[]
static PRINTENV_T env_x86
static const PLocalPrinterDriverLevelFunc pfnPrinterDriverLevels[]
static const WCHAR help_fileW[]
static WCHAR * get_file_part(WCHAR *name)
static WCHAR wszLocalSplFile[MAX_PATH]
static void _LocalGetPrinterDriverLevel6(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_6W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
static const WCHAR data_fileW[]
static const WCHAR ia64_envnameW[]
HKEY open_driver_reg(LPCWSTR pEnvironment)
static const WCHAR driverW[]
static const WCHAR configuration_fileW[]
static const WCHAR win40_envnameW[]
static void _LocalGetPrinterDriverLevel1(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_1W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
static const WCHAR fmt_driversW[]
static HMODULE driver_load(const PRINTENV_T *env, LPWSTR dllname)
static const WCHAR dependent_filesW[]
static const WCHAR monitorW[]
static BOOL apd_copyfile(WCHAR *pathname, WCHAR *file_part, apd_data_t *apd)
static DWORD dwDriverInfo5Offsets[]
static const WCHAR version3_subdirW[]
static const WCHAR x64_subdirW[]
static const WCHAR spoolW[]
static WCHAR wszScratchPad[MAX_PATH]
static const WCHAR versionW[]
static DWORD dwDriverInfo4Offsets[]
static const WCHAR ia64_subdirW[]
static const WCHAR emptyW[]
static WCHAR wszPrintUiFile[MAX_PATH]
static DWORD dwDriverInfo3Offsets[]
BOOL InitializePrinterDrivers(VOID)
static void _LocalGetPrinterDriverLevel4(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_4W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
static PRINTENV_T env_x64
static DWORD dwDriverInfo6Offsets[]
static const WCHAR backslashW[]
static DWORD dwDriverInfo8Offsets[]
static void _LocalGetPrinterDriverLevel3(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_3W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
static const WCHAR x86_envnameW[]
static DWORD dwDriverInfo1Offsets[]
static const WCHAR x64_envnameW[]
static const WCHAR driversW[]
BOOL WINAPI LocalGetPrinterDriverDirectory(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded)
BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
void(* PLocalPrinterDriverLevelFunc)(PLOCAL_PRINTER, PVOID, PBYTE *, PDWORD)
static const WCHAR version0_regpathW[]
static void ToMultiSz(LPWSTR pString)
static void _LocalGetPrinterDriverLevel2(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_2W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
PPRINTENV_T validate_envW(LPCWSTR env)
static void _LocalGetPrinterDriverLevel8(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_8W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
BOOL WINAPI LocalGetPrinterDriverEx(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded, DWORD dwClientMajorVersion, DWORD dwClientMinorVersion, PDWORD pdwServerMajorVersion, PDWORD pdwServerMinorVersion)
static const WCHAR x86_subdirW[]
BOOL WINAPI LocalEnumPrinterDrivers(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
static const WCHAR win40_subdirW[]
static const WCHAR version0_subdirW[]
#define DRIVER_EVENT_INITIALIZE
Definition: winddiui.h:97
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
const WCHAR * str
#define REG_DWORD
Definition: sdbapi.c:596
#define _countof(array)
Definition: sndvol32.h:68
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
DWORD cVersion
Definition: winspool.h:537
LPWSTR pDependentFiles
Definition: winspool.h:544
LPWSTR pDataFile
Definition: winspool.h:541
LPWSTR pEnvironment
Definition: winspool.h:539
LPWSTR pDriverPath
Definition: winspool.h:540
LPWSTR pDefaultDataType
Definition: winspool.h:546
LPWSTR pMonitorName
Definition: winspool.h:545
LPWSTR pConfigFile
Definition: winspool.h:542
LPWSTR pszzPreviousNames
Definition: winspool.h:547
LPWSTR pHelpFile
Definition: winspool.h:543
LPWSTR pName
Definition: winspool.h:538
enum _LOCAL_HANDLE::@5124 HandleType
PVOID pSpecificHandle
Definition: precomp.h:208
PLOCAL_PRINT_MONITOR pPrintMonitor
Definition: precomp.h:91
PLOCAL_PRINTER pPrinter
Definition: precomp.h:171
PWSTR pwszDefaultDatatype
Definition: precomp.h:126
PLOCAL_PORT pPort
Definition: precomp.h:129
PWSTR pwszPrinterDriver
Definition: precomp.h:124
PLOCAL_PRINT_PROCESSOR pPrintProcessor
Definition: precomp.h:128
struct _SKIPLIST_NODE * Next[SKIPLIST_LEVELS]
Definition: skiplist.h:30
PVOID Element
Definition: skiplist.h:31
SKIPLIST_NODE Head
Definition: skiplist.h:37
WCHAR src[MAX_PATH+MAX_PATH]
DWORD copyflags
WCHAR dst[MAX_PATH+MAX_PATH]
Definition: fci.c:127
Definition: name.c:39
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
void * PVOID
Definition: typedefs.h:50
uint32_t * LPDWORD
Definition: typedefs.h:59
PCWSTR wszPrintProviderInfo[3]
Definition: main.c:27
LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
Definition: tools.c:89
struct _LOCAL_PRINTER * PLOCAL_PRINTER
Definition: precomp.h:62
struct _LOCAL_PRINTER_HANDLE * PLOCAL_PRINTER_HANDLE
Definition: precomp.h:63
struct _LOCAL_HANDLE * PLOCAL_HANDLE
Definition: precomp.h:56
SKIPLIST PrinterList
Definition: printers.c:11
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3828
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define ERROR_INVALID_ENVIRONMENT
Definition: winerror.h:1112
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
struct _DRIVER_INFO_6W DRIVER_INFO_6W
struct _DRIVER_INFO_1W DRIVER_INFO_1W
struct _DRIVER_INFO_5W DRIVER_INFO_5W
struct _DRIVER_INFO_4W DRIVER_INFO_4W
struct _DRIVER_INFO_3W DRIVER_INFO_3W
#define APD_COPY_NEW_FILES
Definition: winspool.h:606
#define APD_COPY_ALL_FILES
Definition: winspool.h:605
struct _DRIVER_INFO_8W DRIVER_INFO_8W
#define APD_COPY_FROM_DIRECTORY
Definition: winspool.h:607
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193