ReactOS  0.4.15-dev-1184-g23e04ae
printerdata.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Spooler API
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Functions related to Printer Configuration Data
5  * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
11 AdvancedSetupDialog(HWND hWnd, INT Unknown, PDEVMODEA pDevModeInput, PDEVMODEA pDevModeOutput)
12 {
13  HANDLE hPrinter;
14  LONG Ret = -1;
15 
16  TRACE("AdvancedSetupDialog(%p, %d, %p, %p)\n", hWnd, Unknown, pDevModeOutput, pDevModeInput);
17 
18  if ( OpenPrinterA( (LPSTR)pDevModeInput->dmDeviceName, &hPrinter, NULL ) )
19  {
20  Ret = AdvancedDocumentPropertiesA( hWnd, hPrinter, (PSTR)pDevModeInput->dmDeviceName, pDevModeOutput, pDevModeInput );
21  ClosePrinter(hPrinter);
22  }
23  return Ret;
24 }
25 
27 AdvancedDocumentPropertiesA(HWND hWnd, HANDLE hPrinter, PSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput)
28 {
29  TRACE("AdvancedDocumentPropertiesA(%p, %p, %s, %p, %p)\n", hWnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput);
31  return 0;
32 }
33 
35 AdvancedDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, PWSTR pDeviceName, PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput)
36 {
37  TRACE("AdvancedDocumentPropertiesW(%p, %p, %S, %p, %p)\n", hWnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput);
39  return 0;
40 }
41 
43 DeletePrinterDataA(HANDLE hPrinter, PSTR pValueName)
44 {
45  LPWSTR valuenameW = NULL;
46  INT len;
47  DWORD res;
48 
49  TRACE("DeletePrinterDataA(%p, %s)\n", hPrinter, pValueName);
50 
51  if (pValueName)
52  {
53  len = MultiByteToWideChar(CP_ACP, 0, pValueName, -1, NULL, 0);
54  valuenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
55  MultiByteToWideChar(CP_ACP, 0, pValueName, -1, valuenameW, len);
56  }
57 
58  res = DeletePrinterDataW( hPrinter, valuenameW );
59 
60  if (valuenameW) HeapFree(GetProcessHeap(), 0, valuenameW);
61 
62  return res;
63 
64 }
65 
67 DeletePrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PCSTR pValueName)
68 {
69  LPWSTR keynameW = NULL;
70  LPWSTR valuenameW = NULL;
71  INT len;
72  DWORD res;
73 
74  TRACE("DeletePrinterDataExA(%p, %s, %s)\n", hPrinter, pKeyName, pValueName);
75 
76  if (pKeyName)
77  {
78  len = MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, NULL, 0);
79  keynameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
80  MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, keynameW, len);
81  }
82 
83  if (pValueName)
84  {
85  len = MultiByteToWideChar(CP_ACP, 0, pValueName, -1, NULL, 0);
86  valuenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
87  MultiByteToWideChar(CP_ACP, 0, pValueName, -1, valuenameW, len);
88  }
89 
90  res = DeletePrinterDataExW( hPrinter, keynameW, valuenameW );
91 
92  if (keynameW) HeapFree(GetProcessHeap(), 0, keynameW);
93  if (valuenameW) HeapFree(GetProcessHeap(), 0, valuenameW);
94 
95  return res;
96 }
97 
99 DeletePrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName)
100 {
101  TRACE("DeletePrinterDataExW(%p, %S, %S)\n", hPrinter, pKeyName, pValueName);
103  return ERROR_NOT_SUPPORTED;
104 }
105 
107 DeletePrinterDataW(HANDLE hPrinter, PWSTR pValueName)
108 {
109  TRACE("DeletePrinterDataW(%p, %S)\n", hPrinter, pValueName);
111  return ERROR_NOT_SUPPORTED;
112 }
113 
115 DeletePrinterKeyA(HANDLE hPrinter, PCSTR pKeyName)
116 {
117  LPWSTR keynameW = NULL;
118  INT len;
119  DWORD res;
120 
121  TRACE("DeletePrinterKeyA(%p, %s)\n", hPrinter, pKeyName);
122 
123  if (pKeyName)
124  {
125  len = MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, NULL, 0);
126  keynameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
127  MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, keynameW, len);
128  }
129 
130  res = DeletePrinterKeyW( hPrinter, keynameW );
131 
132  if (keynameW) HeapFree(GetProcessHeap(), 0, keynameW);
133 
134  return res;
135 }
136 
138 DeletePrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName)
139 {
140  TRACE("DeletePrinterKeyW(%p, %S)\n", hPrinter, pKeyName);
142  return ERROR_NOT_SUPPORTED;
143 }
144 
146 EnumPrinterDataA(HANDLE hPrinter, DWORD dwIndex, PSTR pValueName, DWORD cbValueName, PDWORD pcbValueName, PDWORD pType, PBYTE pData, DWORD cbData, PDWORD pcbData)
147 {
148  TRACE("EnumPrinterDataA(%p, %lu, %s, %lu, %p, %p, %p, %lu, %p)\n", hPrinter, dwIndex, pValueName, cbValueName, pcbValueName, pType, pData, cbData, pcbData);
150  return ERROR_NOT_SUPPORTED;
151 }
152 
154 EnumPrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues)
155 {
156  INT len;
157  LPWSTR pKeyNameW;
158  DWORD ret, dwIndex, dwBufSize;
159  HANDLE hHeap;
160  LPSTR pBuffer;
161 
162  TRACE("EnumPrinterDataExA(%p, %s, %p, %lu, %p, %p)\n", hPrinter, pKeyName, pEnumValues, cbEnumValues, pcbEnumValues, pnEnumValues);
163 
164  if (pKeyName == NULL || *pKeyName == 0)
166 
167  len = MultiByteToWideChar (CP_ACP, 0, pKeyName, -1, NULL, 0);
168  if (len == 0)
169  {
170  ret = GetLastError ();
171  ERR ("MultiByteToWideChar failed with code %i\n", ret);
172  return ret;
173  }
174 
175  hHeap = GetProcessHeap ();
176  if (hHeap == NULL)
177  {
178  ERR ("GetProcessHeap failed\n");
179  return ERROR_OUTOFMEMORY;
180  }
181 
182  pKeyNameW = HeapAlloc (hHeap, 0, len * sizeof (WCHAR));
183  if (pKeyNameW == NULL)
184  {
185  ERR ("Failed to allocate %i bytes from process heap\n",
186  (LONG)(len * sizeof (WCHAR)));
187  return ERROR_OUTOFMEMORY;
188  }
189 
190  if (MultiByteToWideChar (CP_ACP, 0, pKeyName, -1, pKeyNameW, len) == 0)
191  {
192  ret = GetLastError ();
193  ERR ("MultiByteToWideChar failed with code %i\n", ret);
194  if (HeapFree (hHeap, 0, pKeyNameW) == 0)
195  WARN ("HeapFree failed with code %i\n", GetLastError ());
196  return ret;
197  }
198 
199  ret = EnumPrinterDataExW (hPrinter, pKeyNameW, pEnumValues, cbEnumValues, pcbEnumValues, pnEnumValues);
200 
201  if (ret != ERROR_SUCCESS)
202  {
203  if (HeapFree (hHeap, 0, pKeyNameW) == 0)
204  WARN ("HeapFree failed with code %i\n", GetLastError ());
205  TRACE ("EnumPrinterDataExW returned %i\n", ret);
206  return ret;
207  }
208 
209  if (HeapFree (hHeap, 0, pKeyNameW) == 0)
210  {
211  ret = GetLastError ();
212  ERR ("HeapFree failed with code %i\n", ret);
213  return ret;
214  }
215 
216  if (*pnEnumValues == 0) /* empty key */
217  return ERROR_SUCCESS;
218 
219  dwBufSize = 0;
220  for (dwIndex = 0; dwIndex < *pnEnumValues; ++dwIndex)
221  {
222  PPRINTER_ENUM_VALUESW ppev = &((PPRINTER_ENUM_VALUESW) pEnumValues)[dwIndex];
223 
224  if (dwBufSize < ppev->cbValueName)
225  dwBufSize = ppev->cbValueName;
226 
227  if ( dwBufSize < ppev->cbData &&
228  (ppev->dwType == REG_SZ || ppev->dwType == REG_EXPAND_SZ || ppev->dwType == REG_MULTI_SZ))
229  dwBufSize = ppev->cbData;
230  }
231 
232  FIXME ("Largest Unicode name or value is %i bytes\n", dwBufSize);
233 
234  pBuffer = HeapAlloc (hHeap, 0, dwBufSize);
235  if (pBuffer == NULL)
236  {
237  ERR ("Failed to allocate %i bytes from process heap\n", dwBufSize);
238  return ERROR_OUTOFMEMORY;
239  }
240 
241  for (dwIndex = 0; dwIndex < *pnEnumValues; ++dwIndex)
242  {
243  PPRINTER_ENUM_VALUESW ppev =
244  &((PPRINTER_ENUM_VALUESW) pEnumValues)[dwIndex];
245 
247  ppev->cbValueName / sizeof (WCHAR), pBuffer, dwBufSize, NULL,
248  NULL);
249  if (len == 0)
250  {
251  ret = GetLastError ();
252  ERR ("WideCharToMultiByte failed with code %i\n", ret);
253  if (HeapFree (hHeap, 0, pBuffer) == 0)
254  WARN ("HeapFree failed with code %i\n", GetLastError ());
255  return ret;
256  }
257 
258  memcpy (ppev->pValueName, pBuffer, len);
259 
260  TRACE ("Converted '%s' from Unicode to ASCII\n", pBuffer);
261 
262  if (ppev->dwType != REG_SZ && ppev->dwType != REG_EXPAND_SZ &&
263  ppev->dwType != REG_MULTI_SZ)
264  continue;
265 
266  len = WideCharToMultiByte (CP_ACP, 0, (LPWSTR) ppev->pData,
267  ppev->cbData / sizeof (WCHAR), pBuffer, dwBufSize, NULL, NULL);
268  if (len == 0)
269  {
270  ret = GetLastError ();
271  ERR ("WideCharToMultiByte failed with code %i\n", ret);
272  if (HeapFree (hHeap, 0, pBuffer) == 0)
273  WARN ("HeapFree failed with code %i\n", GetLastError ());
274  return ret;
275  }
276 
277  memcpy (ppev->pData, pBuffer, len);
278 
279  TRACE ("Converted '%s' from Unicode to ASCII\n", pBuffer);
280  TRACE (" (only first string of REG_MULTI_SZ printed)\n");
281  }
282 
283  if (HeapFree (hHeap, 0, pBuffer) == 0)
284  {
285  ret = GetLastError ();
286  ERR ("HeapFree failed with code %i\n", ret);
287  return ret;
288  }
289 
290  return ERROR_SUCCESS;
291 }
292 
294 EnumPrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues)
295 {
296  TRACE("EnumPrinterDataExW(%p, %S, %p, %lu, %p, %p)\n", hPrinter, pKeyName, pEnumValues, cbEnumValues, pcbEnumValues, pnEnumValues);
298  return ERROR_NOT_SUPPORTED;
299 }
300 
302 EnumPrinterDataW(HANDLE hPrinter, DWORD dwIndex, PWSTR pValueName, DWORD cbValueName, PDWORD pcbValueName, PDWORD pType, PBYTE pData, DWORD cbData, PDWORD pcbData)
303 {
304  TRACE("EnumPrinterDataW(%p, %lu, %S, %lu, %p, %p, %p, %lu, %p)\n", hPrinter, dwIndex, pValueName, cbValueName, pcbValueName, pType, pData, cbData, pcbData);
306  return ERROR_NOT_SUPPORTED;
307 }
308 
310 EnumPrinterKeyA(HANDLE hPrinter, PCSTR pKeyName, PSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey)
311 {
312  TRACE("EnumPrinterKeyA(%p, %s, %s, %lu, %p)\n", hPrinter, pKeyName, pSubkey, cbSubkey, pcbSubkey);
314  return ERROR_NOT_SUPPORTED;
315 }
316 
318 EnumPrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName, PWSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey)
319 {
320  TRACE("EnumPrinterKeyW(%p, %S, %S, %lu, %p)\n", hPrinter, pKeyName, pSubkey, cbSubkey, pcbSubkey);
322  return ERROR_NOT_SUPPORTED;
323 }
324 
327 {
328  TRACE("GetPrinterDataA(%p, %s, %p, %p, %lu, %p)\n", hPrinter, pValueName, pType, pData, nSize, pcbNeeded);
329  return GetPrinterDataExA(hPrinter, "PrinterDriverData", pValueName, pType, pData, nSize, pcbNeeded);
330 }
331 
334 {
335  DWORD cbUnicodeData;
336  DWORD cch;
337  DWORD dwReturnValue;
338  DWORD dwType;
339  POSVERSIONINFOEXA pInfoA;
340  POSVERSIONINFOEXW pInfoW;
341  PVOID pUnicodeData = NULL;
342  PWSTR pwszKeyName = NULL;
344 
345  TRACE("GetPrinterDataExA(%p, %s, %s, %p, %p, %lu, %p)\n", hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded);
346 
347  if (pKeyName)
348  {
349  // Convert pKeyName to a Unicode string pwszKeyName
350  cch = strlen(pKeyName);
351 
352  pwszKeyName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
353  if (!pwszKeyName)
354  {
355  dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
356  ERR("HeapAlloc failed!\n");
357  goto Cleanup;
358  }
359 
360  MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, pwszKeyName, cch + 1);
361  }
362 
363  if (pValueName)
364  {
365  // Convert pValueName to a Unicode string pwszValueName
366  cch = strlen(pValueName);
367 
368  pwszValueName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
369  if (!pwszValueName)
370  {
371  dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
372  ERR("HeapAlloc failed!\n");
373  goto Cleanup;
374  }
375 
376  MultiByteToWideChar(CP_ACP, 0, pValueName, -1, pwszValueName, cch + 1);
377  }
378 
379  // We need the data type information, even if no pData was passed.
380  if (!pType)
381  pType = &dwType;
382 
383  // Call GetPrinterDataExW for the first time.
384  // If we're lucky, the supplied buffer is already large enough and we don't need to do the expensive RPC call a second time.
385  dwReturnValue = GetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, pType, pData, nSize, pcbNeeded);
386 
387  // If a critical error occurred, just return it. We cannot do anything else in this case.
388  if (dwReturnValue != ERROR_SUCCESS && dwReturnValue != ERROR_MORE_DATA)
389  goto Cleanup;
390 
391  // Save the needed buffer size for the Unicode data. We may alter *pcbNeeded for an ANSI buffer size.
392  cbUnicodeData = *pcbNeeded;
393 
394  if (*pType == REG_SZ || *pType == REG_MULTI_SZ || *pType == REG_EXPAND_SZ)
395  {
396  // This is a string that needs to be converted from Unicode to ANSI.
397  // Output the required buffer size for the ANSI string.
398  *pcbNeeded /= sizeof(WCHAR);
399  }
400  else if (*pType == REG_NONE)
401  {
402  if (cbUnicodeData == sizeof(OSVERSIONINFOW) && wcsicmp(pwszValueName, SPLREG_OS_VERSION) == 0)
403  {
404  // This is a Unicode OSVERSIONINFOW structure that needs to be converted to an ANSI OSVERSIONINFOA.
405  *pcbNeeded = sizeof(OSVERSIONINFOA);
406  }
407  else if (cbUnicodeData == sizeof(OSVERSIONINFOEXW) && wcsicmp(pwszValueName, SPLREG_OS_VERSIONEX) == 0)
408  {
409  // This is a Unicode OSVERSIONINFOEXW structure that needs to be converted to an ANSI OSVERSIONINFOEXA.
410  *pcbNeeded = sizeof(OSVERSIONINFOEXA);
411  }
412  else
413  {
414  // Other REG_NONE value, nothing to do.
415  goto Cleanup;
416  }
417  }
418 
419  // Check if the supplied buffer is large enough for the ANSI data.
420  if (nSize < *pcbNeeded)
421  {
422  dwReturnValue = ERROR_MORE_DATA;
423  goto Cleanup;
424  }
425 
426  // Allocate a temporary buffer for the Unicode data.
427  pUnicodeData = HeapAlloc(hProcessHeap, 0, cbUnicodeData);
428  if (!pUnicodeData)
429  {
430  dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
431  ERR("HeapAlloc failed!\n");
432  goto Cleanup;
433  }
434 
435  if (dwReturnValue == ERROR_SUCCESS)
436  {
437  // ERROR_SUCCESS: The buffer is large enough for the ANSI and the Unicode string,
438  // so the Unicode string has been copied into pData. Copy it to pUnicodeData.
439  CopyMemory(pUnicodeData, pData, cbUnicodeData);
440  }
441  else
442  {
443  // ERROR_MORE_DATA: The buffer is large enough for the ANSI string, but not for the Unicode string.
444  // We have to call GetPrinterDataExW again with the temporary buffer.
445  dwReturnValue = GetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, NULL, (PBYTE)pUnicodeData, cbUnicodeData, &cbUnicodeData);
446  if (dwReturnValue != ERROR_SUCCESS)
447  goto Cleanup;
448  }
449 
450  if (*pType == REG_SZ || *pType == REG_MULTI_SZ || *pType == REG_EXPAND_SZ)
451  {
452  // Convert the Unicode string to ANSI.
453  WideCharToMultiByte(CP_ACP, 0, (PWSTR)pUnicodeData, -1, (PSTR)pData, *pcbNeeded, NULL, NULL);
454  }
455  else
456  {
457  // This is a REG_NONE with either OSVERSIONINFOW or OSVERSIONINFOEXW.
458  // Copy the fields and convert the Unicode CSD Version string to ANSI.
459  pInfoW = (POSVERSIONINFOEXW)pUnicodeData;
460  pInfoA = (POSVERSIONINFOEXA)pData;
461  pInfoA->dwMajorVersion = pInfoW->dwMajorVersion;
462  pInfoA->dwMinorVersion = pInfoW->dwMinorVersion;
463  pInfoA->dwBuildNumber = pInfoW->dwBuildNumber;
464  pInfoA->dwPlatformId = pInfoW->dwPlatformId;
465  WideCharToMultiByte(CP_ACP, 0, pInfoW->szCSDVersion, -1, pInfoA->szCSDVersion, sizeof(pInfoA->szCSDVersion), NULL, NULL);
466 
467  if (cbUnicodeData == sizeof(OSVERSIONINFOW))
468  {
469  pInfoA->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
470  }
471  else
472  {
473  pInfoA->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
474  pInfoA->wServicePackMajor = pInfoW->wServicePackMajor;
475  pInfoA->wServicePackMinor = pInfoW->wServicePackMinor;
476  pInfoA->wSuiteMask = pInfoW->wSuiteMask;
477  pInfoA->wProductType = pInfoW->wProductType;
478  pInfoA->wReserved = pInfoW->wReserved;
479  }
480  }
481 
482 Cleanup:
483  if (pwszKeyName)
484  HeapFree(hProcessHeap, 0, pwszKeyName);
485 
486  if (pwszValueName)
488 
489  if (pUnicodeData)
490  HeapFree(hProcessHeap, 0, pUnicodeData);
491 
492  return dwReturnValue;
493 }
494 
497 {
498  const WCHAR wszEmptyString[] = L"";
499 
500  BYTE DummyData;
501  DWORD dwErrorCode;
502  DWORD dwType = REG_NONE;
503  PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
504 
505  TRACE("GetPrinterDataExW(%p, %S, %S, %p, %p, %lu, %p)\n", hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded);
506 
507  // Sanity checks
508  if (!pHandle)
509  return ERROR_INVALID_HANDLE;
510 
511  // Yes, instead of declaring these pointers unique in the IDL file (and perfectly accepting NULL pointers this way),
512  // Windows does it differently for GetPrinterDataExW and points them to empty variables.
513  if (!pKeyName)
514  pKeyName = wszEmptyString;
515 
516  if (!pType)
517  pType = &dwType;
518 
519  if (!pData && !nSize)
520  pData = &DummyData;
521 
522  // Do the RPC call
524  {
525  dwErrorCode = _RpcGetPrinterDataEx(pHandle->hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded);
526  }
528  {
529  dwErrorCode = RpcExceptionCode();
530  }
531  RpcEndExcept;
532 
533  return dwErrorCode;
534 }
535 
538 {
539  TRACE("GetPrinterDataW(%p, %S, %p, %p, %lu, %p)\n", hPrinter, pValueName, pType, pData, nSize, pcbNeeded);
540  return GetPrinterDataExW(hPrinter, L"PrinterDriverData", pValueName, pType, pData, nSize, pcbNeeded);
541 }
542 
544 SetPrinterDataA(HANDLE hPrinter, PSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
545 {
546  TRACE("SetPrinterDataA(%p, %s, %lu, %p, %lu)\n", hPrinter, pValueName, Type, pData, cbData);
547  return SetPrinterDataExA(hPrinter, "PrinterDriverData", pValueName, Type, pData, cbData);
548 }
549 
551 SetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
552 {
553  DWORD cch;
554  DWORD dwReturnValue;
555  PWSTR pwszKeyName = NULL;
557  PWSTR pUnicodeData = NULL;
558 
559  TRACE("SetPrinterDataExA(%p, %s, %s, %lu, %p, %lu)\n", hPrinter, pKeyName, pValueName, Type, pData, cbData);
560 
561  if (pKeyName)
562  {
563  // Convert pKeyName to a Unicode string pwszKeyName
564  cch = strlen(pKeyName);
565 
566  pwszKeyName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
567  if (!pwszKeyName)
568  {
569  dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
570  ERR("HeapAlloc failed!\n");
571  goto Cleanup;
572  }
573 
574  MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, pwszKeyName, cch + 1);
575  }
576 
577  if (pValueName)
578  {
579  // Convert pValueName to a Unicode string pwszValueName
580  cch = strlen(pValueName);
581 
582  pwszValueName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
583  if (!pwszValueName)
584  {
585  dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
586  ERR("HeapAlloc failed!\n");
587  goto Cleanup;
588  }
589 
590  MultiByteToWideChar(CP_ACP, 0, pValueName, -1, pwszValueName, cch + 1);
591  }
592 
593  if (Type == REG_SZ || Type == REG_MULTI_SZ || Type == REG_EXPAND_SZ)
594  {
595  // Convert pData to a Unicode string pUnicodeData.
596  pUnicodeData = HeapAlloc(hProcessHeap, 0, cbData * sizeof(WCHAR));
597  if (!pUnicodeData)
598  {
599  dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
600  ERR("HeapAlloc failed!\n");
601  goto Cleanup;
602  }
603 
604  MultiByteToWideChar(CP_ACP, 0, (PCSTR)pData, -1, pUnicodeData, cbData);
605 
606  pData = (PBYTE)pUnicodeData;
607  cbData *= sizeof(WCHAR);
608  }
609 
610  dwReturnValue = SetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, Type, pData, cbData);
611 
612 Cleanup:
613  if (pwszKeyName)
614  HeapFree(hProcessHeap, 0, pwszKeyName);
615 
616  if (pwszValueName)
618 
619  if (pUnicodeData)
620  HeapFree(hProcessHeap, 0, pUnicodeData);
621 
622  return dwReturnValue;
623 }
624 
626 SetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
627 {
628  const WCHAR wszEmptyString[] = L"";
629 
630  DWORD dwErrorCode;
631  PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
632 
633  TRACE("SetPrinterDataExW(%p, %S, %S, %lu, %p, %lu)\n", hPrinter, pKeyName, pValueName, Type, pData, cbData);
634 
635  // Sanity checks
636  if (!pHandle)
637  return ERROR_INVALID_HANDLE;
638 
639  if (!pKeyName)
640  pKeyName = wszEmptyString;
641 
642  // Do the RPC call
644  {
645  dwErrorCode = _RpcSetPrinterDataEx(pHandle->hPrinter, pKeyName, pValueName, Type, pData, cbData);
646  }
648  {
649  dwErrorCode = RpcExceptionCode();
650  }
651  RpcEndExcept;
652 
653  return dwErrorCode;
654 }
655 
657 SetPrinterDataW(HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
658 {
659  TRACE("SetPrinterDataW(%p, %S, %lu, %p, %lu)\n", hPrinter, pValueName, Type, pData, cbData);
660  return SetPrinterDataExW(hPrinter, L"PrinterDriverData", pValueName, Type, pData, cbData);
661 }
DWORD WINAPI EnumPrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues)
Definition: printerdata.c:154
ULONG dwBuildNumber
Definition: rtltypes.h:272
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
UCHAR wProductType
Definition: rtltypes.h:278
DWORD WINAPI DeletePrinterDataW(HANDLE hPrinter, PWSTR pValueName)
Definition: printerdata.c:26
const uint16_t * PCWSTR
Definition: typedefs.h:57
DWORD WINAPI SetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
Definition: printerdata.c:128
#define RpcEndExcept
Definition: rpc.h:128
ULONG DummyData
Definition: cmdata.c:18
Type
Definition: Type.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
USHORT wSuiteMask
Definition: rtltypes.h:263
#define WideCharToMultiByte
Definition: compat.h:111
ULONG dwPlatformId
Definition: rtltypes.h:273
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
struct _OSVERSIONINFOEXW * POSVERSIONINFOEXW
ULONG dwMinorVersion
Definition: rtltypes.h:271
uint16_t * PWSTR
Definition: typedefs.h:56
DWORD _RpcSetPrinterDataEx(WINSPOOL_PRINTER_HANDLE hPrinter, const WCHAR *pKeyName, const WCHAR *pValueName, DWORD Type, BYTE *pData, DWORD cbData)
Definition: printerdata.c:84
#define CP_ACP
Definition: compat.h:109
#define WARN(fmt,...)
Definition: debug.h:112
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2037
HWND hWnd
Definition: settings.c:17
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
char * LPSTR
Definition: xmlstorage.h:182
USHORT wSuiteMask
Definition: rtltypes.h:277
int32_t INT
Definition: typedefs.h:58
ULONG dwMajorVersion
Definition: rtltypes.h:256
ULONG dwMajorVersion
Definition: rtltypes.h:270
LONG WINAPI AdvancedDocumentPropertiesA(HWND hWnd, HANDLE hPrinter, PSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput)
Definition: printerdata.c:27
unsigned char * LPBYTE
Definition: typedefs.h:53
DWORD WINAPI GetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:101
DWORD WINAPI EnumPrinterKeyA(HANDLE hPrinter, PCSTR pKeyName, PSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey)
Definition: printerdata.c:310
DWORD WINAPI DeletePrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PCSTR pValueName)
Definition: printerdata.c:67
long LONG
Definition: pedump.c:60
#define REG_MULTI_SZ
Definition: nt_native.h:1501
USHORT wServicePackMinor
Definition: rtltypes.h:262
#define FIXME(fmt,...)
Definition: debug.h:111
#define RpcTryExcept
Definition: rpc.h:126
DWORD WINAPI DeletePrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName)
Definition: printerdata.c:41
WINBOOL WINAPI ClosePrinter(HANDLE hPrinter)
Definition: printers.c:176
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:201
smooth NULL
Definition: ftsmooth.c:416
PVOID pBuffer
DWORD WINAPI EnumPrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName, PWSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey)
Definition: printerdata.c:86
WINBOOL WINAPI OpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefault)
Definition: printers.c:2553
const char * LPCSTR
Definition: xmlstorage.h:183
DWORD WINAPI DeletePrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName)
Definition: printerdata.c:11
struct _OSVERSIONINFOEXA OSVERSIONINFOEXA
struct _PRINTER_ENUM_VALUESW * PPRINTER_ENUM_VALUESW
ULONG dwMinorVersion
Definition: rtltypes.h:257
#define RpcExceptionCode()
Definition: rpc.h:132
#define TRACE(s)
Definition: solgame.cpp:4
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:255
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD WINAPI GetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:333
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_z_ PCWSTR pwszValueName
Definition: ntuser.h:36
#define WINAPI
Definition: msvc.h:6
DWORD WINAPI SetPrinterDataA(HANDLE hPrinter, PSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
Definition: printerdata.c:544
DWORD WINAPI SetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
Definition: printerdata.c:551
#define CopyMemory
Definition: winbase.h:1646
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI DeletePrinterKeyA(HANDLE hPrinter, PCSTR pKeyName)
Definition: printerdata.c:115
#define wcsicmp
Definition: compat.h:15
int ret
DWORD WINAPI EnumPrinterDataW(HANDLE hPrinter, DWORD dwIndex, PWSTR pValueName, DWORD cbValueName, PDWORD pcbValueName, PDWORD pType, PBYTE pData, DWORD cbData, PDWORD pcbData)
Definition: printerdata.c:71
static const WCHAR L[]
Definition: oid.c:1250
USHORT wServicePackMajor
Definition: rtltypes.h:261
WCHAR szCSDVersion[128]
Definition: rtltypes.h:274
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
static const WCHAR Cleanup[]
Definition: register.c:80
CHAR szCSDVersion[128]
Definition: rtltypes.h:260
DWORD WINAPI GetPrinterDataA(HANDLE hPrinter, LPSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:326
#define ERROR_MORE_DATA
Definition: dderror.h:13
unsigned char BYTE
Definition: xxhash.c:193
#define ERR(fmt,...)
Definition: debug.h:110
DWORD _RpcGetPrinterDataEx(WINSPOOL_PRINTER_HANDLE hPrinter, const WCHAR *pKeyName, const WCHAR *pValueName, DWORD *pType, BYTE *pData, DWORD nSize, DWORD *pcbNeeded)
Definition: printerdata.c:59
struct _OSVERSIONINFOA OSVERSIONINFOA
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
signed char * PSTR
Definition: retypes.h:7
USHORT wServicePackMajor
Definition: rtltypes.h:275
#define SPLREG_OS_VERSIONEX
Definition: winspool.h:1356
struct _OSVERSIONINFOEXA * POSVERSIONINFOEXA
BYTE dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1564
DWORD * PDWORD
Definition: pedump.c:68
#define SPLREG_OS_VERSION
Definition: winspool.h:1355
#define MultiByteToWideChar
Definition: compat.h:110
LONG WINAPI AdvancedSetupDialog(HWND hWnd, INT Unknown, PDEVMODEA pDevModeInput, PDEVMODEA pDevModeOutput)
Definition: printerdata.c:11
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
ULONG dwPlatformId
Definition: rtltypes.h:259
GLuint res
Definition: glext.h:9613
uint32_t * LPDWORD
Definition: typedefs.h:59
DWORD WINAPI GetPrinterDataW(HANDLE hPrinter, LPWSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:119
#define UNIMPLEMENTED
Definition: debug.h:115
UCHAR wProductType
Definition: rtltypes.h:264
const char * PCSTR
Definition: typedefs.h:52
#define REG_NONE
Definition: nt_native.h:1492
WCHAR * LPWSTR
Definition: xmlstorage.h:184
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
DWORD WINAPI SetPrinterDataW(HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
Definition: printerdata.c:146
DWORD WINAPI EnumPrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues)
Definition: printerdata.c:56
BYTE * PBYTE
Definition: pedump.c:66
struct _SPOOLER_HANDLE * PSPOOLER_HANDLE
ULONG dwBuildNumber
Definition: rtltypes.h:258
#define HeapFree(x, y, z)
Definition: compat.h:483
USHORT wServicePackMinor
Definition: rtltypes.h:276
DWORD WINAPI DeletePrinterDataA(HANDLE hPrinter, PSTR pValueName)
Definition: printerdata.c:43
#define RpcExcept(expr)
Definition: rpc.h:127
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4949
HANDLE hProcessHeap
Definition: kbswitch.c:25
DWORD WINAPI EnumPrinterDataA(HANDLE hPrinter, DWORD dwIndex, PSTR pValueName, DWORD cbValueName, PDWORD pcbValueName, PDWORD pType, PBYTE pData, DWORD cbData, PDWORD pcbData)
Definition: printerdata.c:146
HANDLE hPrinter
Definition: precomp.h:50
#define REG_SZ
Definition: layer.c:22
LONG WINAPI AdvancedDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, PWSTR pDeviceName, PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput)
Definition: printerdata.c:35