ReactOS  0.4.15-dev-1150-g593bcce
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 
12 typedef struct {
19 } apd_data_t;
20 
21 static const WCHAR backslashW[] = {'\\',0};
22 static const WCHAR configuration_fileW[] = {'C','o','n','f','i','g','u','r','a','t','i','o','n',' ','F','i','l','e',0};
23 static const WCHAR datatypeW[] = {'D','a','t','a','t','y','p','e',0};
24 static const WCHAR data_fileW[] = {'D','a','t','a',' ','F','i','l','e',0};
25 static const WCHAR dependent_filesW[] = {'D','e','p','e','n','d','e','n','t',' ','F','i','l','e','s',0};
26 static const WCHAR driverW[] = {'D','r','i','v','e','r',0};
27 static const WCHAR emptyW[] = {0};
28 static 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 };
34 static const WCHAR monitorW[] = {'M','o','n','i','t','o','r',0};
35 static const WCHAR previous_namesW[] = {'P','r','e','v','i','o','u','s',' ','N','a','m','e','s',0};
36 
37 static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
38 
39 static const WCHAR spoolW[] = {'\\','s','p','o','o','l',0};
40 static const WCHAR driversW[] = {'\\','d','r','i','v','e','r','s','\\',0};
41 static const WCHAR ia64_envnameW[] = {'W','i','n','d','o','w','s',' ','I','A','6','4',0};
42 static const WCHAR ia64_subdirW[] = {'i','a','6','4',0};
43 static const WCHAR version3_regpathW[] = {'\\','V','e','r','s','i','o','n','-','3',0};
44 static const WCHAR version3_subdirW[] = {'\\','3',0};
45 static const WCHAR version0_regpathW[] = {'\\','V','e','r','s','i','o','n','-','0',0};
46 static const WCHAR version0_subdirW[] = {'\\','0',0};
47 static const WCHAR help_fileW[] = {'H','e','l','p',' ','F','i','l','e',0};
48 static const WCHAR x64_envnameW[] = {'W','i','n','d','o','w','s',' ','x','6','4',0};
49 static const WCHAR x64_subdirW[] = {'x','6','4',0};
50 static const WCHAR x86_envnameW[] = {'W','i','n','d','o','w','s',' ','N','T',' ','x','8','6',0};
51 static const WCHAR x86_subdirW[] = {'w','3','2','x','8','6',0};
52 static const WCHAR win40_envnameW[] = {'W','i','n','d','o','w','s',' ','4','.','0',0};
53 static const WCHAR win40_subdirW[] = {'w','i','n','4','0',0};
54 
56 
58 
60 
62 
64 
65 static 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 
76 BOOL
78 {
79  WCHAR szSysDir[MAX_PATH];
80  DWORD cbBuf;
81 
82  if (wszLocalSplFile[0] && wszPrintUiFile[0])
83  return TRUE;
84 
85  if (!GetSystemDirectoryW(szSysDir, _countof(szSysDir)))
86  {
87  ERR("GetSystemDirectoryW failed\n");
88  return FALSE;
89  }
90 
91  StringCbCopyW(wszLocalSplFile, sizeof(wszLocalSplFile), szSysDir);
92  StringCbCatW(wszLocalSplFile, sizeof(wszLocalSplFile), L"\\localspl.dll");
93 
94  StringCbCopyW(wszPrintUiFile, sizeof(wszPrintUiFile), szSysDir);
95  StringCbCatW(wszPrintUiFile, sizeof(wszPrintUiFile), L"\\printui.dll");
96 
97  if (!LocalGetPrinterDriverDirectory( NULL, (PWSTR)wszCurrentEnvironment, 1, (PBYTE)szSysDir, cbBuf, &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
118  MAXDWORD
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),
127  MAXDWORD
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),
140  MAXDWORD
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),
154  MAXDWORD
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),
163  MAXDWORD
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),
181  MAXDWORD
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),
204  MAXDWORD
205 };
206 
207 static void
209 {
210  while (*pString)
211  {
212  if (*pString == '|')
213  *pString = '\0';
214  pString++;
215  }
216 }
217 
218 static 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 
244 static 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 
278 static 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 
322 static 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 
366 static 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 
407 static void
409 {
410  DWORD n;
411  PCWSTR pwszStrings[14];
412 
413  StringCbCopyW(wszScratchPad, sizeof(wszPrintProviderInfo[1]), wszPrintProviderInfo[1]); // Provider Name
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 
457 static void
459 {
460  DWORD n;
461  PCWSTR pwszStrings[19];
462 
463  StringCbCopyW(wszScratchPad, sizeof(wszPrintProviderInfo[1]), wszPrintProviderInfo[1]); // Provider Name
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 
530 BOOL 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 
577 Cleanup:
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 
599 BOOL WINAPI
600 LocalEnumPrinterDrivers(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 
648 Cleanup:
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  */
658 static 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  {
699  result = all_printenv[i];
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;
732  LPWSTR buffer;
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 
740  buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(fmt_driversW) +
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 );
823  lstrcatW( dir, driversW );
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  */
842 static 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 
882 static 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 
893  if (!LocalGetPrinterDriverDirectory(NULL, (LPWSTR) env->envname, 1, (LPBYTE) fullname, len, &len))
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 
910 static 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  */
924 BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags, BOOL lazy)
925 {
926  const PRINTENV_T *env;
927  apd_data_t apd;
928  DRIVER_INFO_8W di;
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;
979  CreateDirectoryW(apd.src, NULL);
980  CreateDirectoryW(apd.dst, NULL);
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 
1005  file = get_file_part( di.pDriverPath );
1006  RegSetValueExW( hdrv, driverW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
1007  apd_copyfile( di.pDriverPath, file, &apd );
1008 
1009  file = get_file_part( di.pDataFile );
1010  RegSetValueExW( hdrv, data_fileW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
1011  apd_copyfile( di.pDataFile, file, &apd );
1012 
1013  file = get_file_part( di.pConfigFile );
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  {
1020  file = get_file_part( di.pHelpFile );
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 }
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
LPWSTR pDriverPath
Definition: winspool.h:540
HKEY open_driver_reg(LPCWSTR pEnvironment)
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static void _LocalGetPrinterDriverLevel4(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_4W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
const uint16_t * PCWSTR
Definition: typedefs.h:57
GLint level
Definition: gl.h:1546
static const WCHAR versionW[]
static const WCHAR data_fileW[]
PCWSTR wszPrintProviderInfo[3]
Definition: main.c:27
static const PLocalPrinterDriverLevelFunc pfnPrinterDriverLevels[]
BOOL WINAPI LocalAddPrinterDriver(LPWSTR pName, DWORD level, LPBYTE pDriverInfo)
static void _LocalGetPrinterDriverLevel5(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_5W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
static BOOL apd_copyfile(WCHAR *pathname, WCHAR *file_part, apd_data_t *apd)
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static WCHAR wszPrintUiFile[MAX_PATH]
#define ERROR_SUCCESS
Definition: deptool.c:10
static const WCHAR datatypeW[]
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static DWORD dwDriverInfo3Offsets[]
static const WCHAR fmt_driversW[]
enum _LOCAL_HANDLE::@4264 HandleType
#define TRUE
Definition: types.h:120
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
static DWORD dwDriverInfo8Offsets[]
SKIPLIST_NODE Head
Definition: skiplist.h:37
uint16_t * PWSTR
Definition: typedefs.h:56
struct _DRIVER_INFO_3W DRIVER_INFO_3W
#define DRIVER_EVENT_INITIALIZE
Definition: winddiui.h:97
PWSTR pwszPrinterDriver
Definition: precomp.h:124
char pathname[512]
Definition: util.h:13
void(* PLocalPrinterDriverLevelFunc)(PLOCAL_PRINTER, PVOID, PBYTE *, PDWORD)
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
static DWORD dwDriverInfo2Offsets[]
static void _LocalGetPrinterDriverLevel1(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_1W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
GLdouble n
Definition: glext.h:7729
PLOCAL_PRINT_MONITOR pPrintMonitor
Definition: precomp.h:91
BOOL WINAPI LocalGetPrinterDriverDirectory(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded)
static const WCHAR previous_namesW[]
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
#define ZeroMemory
Definition: winbase.h:1648
GLuint buffer
Definition: glext.h:5915
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
static const WCHAR configuration_fileW[]
LPWSTR pEnvironment
Definition: winspool.h:539
static WCHAR wszDriverPath[MAX_PATH]
static const WCHAR backslashW[]
static const WCHAR ia64_subdirW[]
static void _LocalGetPrinterDriverLevel2(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_2W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
DWORD copyflags
#define lstrlenW
Definition: compat.h:498
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
#define APD_COPY_FROM_DIRECTORY
Definition: winspool.h:607
static DWORD dwDriverInfo4Offsets[]
static PRINTENV_T env_x86
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
DWORD WINAPI GetVersion(VOID)
Definition: version.c:22
LPWSTR pDefaultDataType
Definition: winspool.h:546
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:1091
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static void _LocalGetPrinterDriverLevel8(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_8W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
static PRINTENV_T env_x64
static const WCHAR emptyW[]
static const WCHAR x86_subdirW[]
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
const WCHAR wszCurrentEnvironment[]
Definition: prtprocenv.h:11
#define APD_COPY_ALL_FILES
Definition: winspool.h:605
struct _LOCAL_HANDLE * PLOCAL_HANDLE
Definition: precomp.h:56
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
LPWSTR pMonitorName
Definition: winspool.h:545
static const WCHAR driverW[]
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static const DWORD di_sizeof[]
static DWORD dwDriverInfo1Offsets[]
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define debugstr_w
Definition: kernel32.h:32
#define APD_COPY_NEW_FILES
Definition: winspool.h:606
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR ia64_envnameW[]
const WCHAR * str
struct _DRIVER_INFO_6W DRIVER_INFO_6W
PLOCAL_PRINT_PROCESSOR pPrintProcessor
Definition: precomp.h:128
#define LoadLibraryW(x)
Definition: compat.h:495
smooth NULL
Definition: ftsmooth.c:416
PVOID pSpecificHandle
Definition: precomp.h:208
#define MAXDWORD
LONG_PTR LPARAM
Definition: windef.h:208
unsigned int dir
Definition: maze.c:112
void * PVOID
Definition: retypes.h:9
static const WCHAR win40_subdirW[]
BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
static WCHAR wszScratchPad[MAX_PATH]
WCHAR dst[MAX_PATH+MAX_PATH]
static PPRINTENV_T all_printenv[]
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
static const WCHAR x64_envnameW[]
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:4895
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:496
static LPSTR pName
Definition: security.c:75
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static void ToMultiSz(LPWSTR pString)
BOOL WINAPI LocalAddPrinterDriverEx(LPWSTR pName, DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags)
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
static PRINTENV_T env_win40
PBYTE WINAPI PackStrings(PCWSTR *pSource, PBYTE pDest, const DWORD *DestOffsets, PBYTE pEnd)
Definition: tools.c:39
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
static const WCHAR version3_subdirW[]
LPWSTR pDependentFiles
Definition: winspool.h:544
#define _countof(array)
Definition: sndvol32.h:68
static const WCHAR help_fileW[]
struct _DRIVER_INFO_1W DRIVER_INFO_1W
#define MAX_PATH
Definition: compat.h:34
static const WCHAR spoolW[]
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
struct _SKIPLIST_NODE * Next[SKIPLIST_LEVELS]
Definition: skiplist.h:30
SKIPLIST PrinterList
Definition: printers.c:11
static int multi_sz_lenW(const WCHAR *str)
struct _DRIVER_INFO_2W DRIVER_INFO_2W
Definition: ntgdi.h:86
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:500
PPRINTENV_T validate_envW(LPCWSTR env)
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 version0_regpathW[]
static HMODULE driver_load(const PRINTENV_T *env, LPWSTR dllname)
const char * fullname
Definition: shader.c:1766
PWSTR pwszDefaultDatatype
Definition: precomp.h:126
static const WCHAR L[]
Definition: oid.c:1250
static const WCHAR version0_subdirW[]
static void _LocalGetPrinterDriverLevel6(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_6W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
static WCHAR wszLocalSplFile[MAX_PATH]
static PRINTENV_T env_ia64
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1199
WCHAR src[MAX_PATH+MAX_PATH]
GLenum src
Definition: glext.h:6340
#define wcsrchr
Definition: compat.h:16
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned char BYTE
Definition: xxhash.c:193
LPWSTR pszzPreviousNames
Definition: winspool.h:547
struct _LOCAL_PRINTER * PLOCAL_PRINTER
Definition: precomp.h:62
#define ERR(fmt,...)
Definition: debug.h:110
DWORD cVersion
Definition: winspool.h:537
static const WCHAR driversW[]
struct _DRIVER_INFO_4W DRIVER_INFO_4W
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags, BOOL lazy)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
static DWORD dwDriverInfo6Offsets[]
LPWSTR pName
Definition: winspool.h:538
GLenum GLenum dst
Definition: glext.h:6340
LPWSTR pDataFile
Definition: winspool.h:541
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
PVOID Element
Definition: skiplist.h:31
LPWSTR pHelpFile
Definition: winspool.h:543
static int reg
Definition: i386-dis.c:1275
DWORD * PDWORD
Definition: pedump.c:68
BOOL WINAPI LocalEnumPrinterDrivers(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:168
static DWORD dwDriverInfo5Offsets[]
static const WCHAR monitorW[]
Definition: name.c:38
GLuint res
Definition: glext.h:9613
static WCHAR * get_file_part(WCHAR *name)
uint32_t * LPDWORD
Definition: typedefs.h:59
LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
Definition: tools.c:89
static const WCHAR x86_envnameW[]
#define GetProcAddress(x, y)
Definition: compat.h:501
struct _LOCAL_PRINTER_HANDLE * PLOCAL_PRINTER_HANDLE
Definition: precomp.h:63
static const WCHAR dependent_filesW[]
BOOL InitializePrinterDrivers(VOID)
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
WCHAR * LPWSTR
Definition: xmlstorage.h:184
PLOCAL_PRINTER pPrinter
Definition: precomp.h:171
static void _LocalGetPrinterDriverLevel3(PLOCAL_PRINTER pPrinter, PDRIVER_INFO_3W *ppDriverInfo, PBYTE *ppDriverInfoEnd, PDWORD pcbNeeded)
PLOCAL_PORT pPort
Definition: precomp.h:129
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
GLuint64EXT * result
Definition: glext.h:11304
static const WCHAR version3_regpathW[]
#define REG_DWORD
Definition: sdbapi.c:596
static const WCHAR x64_subdirW[]
BYTE * PBYTE
Definition: pedump.c:66
struct _DRIVER_INFO_8W DRIVER_INFO_8W
static const WCHAR win40_envnameW[]
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:483
LPWSTR pConfigFile
Definition: winspool.h:542
#define ERROR_INVALID_ENVIRONMENT
Definition: winerror.h:1112
struct _DRIVER_INFO_5W DRIVER_INFO_5W
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
Definition: fci.c:126
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define REG_SZ
Definition: layer.c:22
GLuint const GLchar * name
Definition: glext.h:6031