ReactOS 0.4.15-dev-8348-gc1b9bb5
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
11AdvancedSetupDialog(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
27AdvancedDocumentPropertiesA(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
35AdvancedDocumentPropertiesW(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
43DeletePrinterDataA(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
67DeletePrinterDataExA(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
99DeletePrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName)
100{
101 TRACE("DeletePrinterDataExW(%p, %S, %S)\n", hPrinter, pKeyName, pValueName);
103 return ERROR_NOT_SUPPORTED;
104}
105
107DeletePrinterDataW(HANDLE hPrinter, PWSTR pValueName)
108{
109 TRACE("DeletePrinterDataW(%p, %S)\n", hPrinter, pValueName);
111 return ERROR_NOT_SUPPORTED;
112}
113
115DeletePrinterKeyA(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
138DeletePrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName)
139{
140 TRACE("DeletePrinterKeyW(%p, %S)\n", hPrinter, pKeyName);
142 return ERROR_NOT_SUPPORTED;
143}
144
146EnumPrinterDataA(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
154EnumPrinterDataExA(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;
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 {
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
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
294EnumPrinterDataExW(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
302EnumPrinterDataW(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
310EnumPrinterKeyA(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
318EnumPrinterKeyW(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
482Cleanup:
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
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)
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 }
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
544SetPrinterDataA(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
551SetPrinterDataExA(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
612Cleanup:
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
626SetPrinterDataExW(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)
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 }
652
653 return dwErrorCode;
654}
655
657SetPrinterDataW(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}
Type
Definition: Type.h:7
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
HWND hWnd
Definition: settings.c:17
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
DWORD WINAPI DeletePrinterDataW(HANDLE hPrinter, PWSTR pValueName)
Definition: printerdata.c:26
DWORD WINAPI EnumPrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues)
Definition: printerdata.c:56
DWORD WINAPI DeletePrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName)
Definition: printerdata.c:11
DWORD WINAPI SetPrinterDataW(HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
Definition: printerdata.c:146
DWORD WINAPI DeletePrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName)
Definition: printerdata.c:41
DWORD WINAPI SetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
Definition: printerdata.c:128
DWORD WINAPI GetPrinterDataW(HANDLE hPrinter, LPWSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:119
DWORD WINAPI EnumPrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName, PWSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey)
Definition: printerdata.c:86
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
DWORD WINAPI GetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:101
DWORD _RpcSetPrinterDataEx(WINSPOOL_PRINTER_HANDLE hPrinter, const WCHAR *pKeyName, const WCHAR *pValueName, DWORD Type, BYTE *pData, DWORD cbData)
Definition: printerdata.c:84
DWORD _RpcGetPrinterDataEx(WINSPOOL_PRINTER_HANDLE hPrinter, const WCHAR *pKeyName, const WCHAR *pValueName, DWORD *pType, BYTE *pData, DWORD nSize, DWORD *pcbNeeded)
Definition: printerdata.c:59
LONG WINAPI AdvancedSetupDialog(HWND hWnd, INT Unknown, PDEVMODEA pDevModeInput, PDEVMODEA pDevModeOutput)
Definition: printerdata.c:11
LONG WINAPI AdvancedDocumentPropertiesA(HWND hWnd, HANDLE hPrinter, PSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput)
Definition: printerdata.c:27
DWORD WINAPI GetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:333
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
DWORD WINAPI SetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
Definition: printerdata.c:551
DWORD WINAPI DeletePrinterKeyA(HANDLE hPrinter, PCSTR pKeyName)
Definition: printerdata.c:115
DWORD WINAPI DeletePrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PCSTR pValueName)
Definition: printerdata.c:67
DWORD WINAPI GetPrinterDataA(HANDLE hPrinter, LPSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
Definition: printerdata.c:326
DWORD WINAPI EnumPrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues)
Definition: printerdata.c:154
DWORD WINAPI EnumPrinterKeyA(HANDLE hPrinter, PCSTR pKeyName, PSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey)
Definition: printerdata.c:310
LONG WINAPI AdvancedDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, PWSTR pDeviceName, PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput)
Definition: printerdata.c:35
DWORD WINAPI DeletePrinterDataA(HANDLE hPrinter, PSTR pValueName)
Definition: printerdata.c:43
DWORD WINAPI SetPrinterDataA(HANDLE hPrinter, PSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
Definition: printerdata.c:544
#define UNIMPLEMENTED
Definition: debug.h:118
ULONG DummyData
Definition: cmdata.c:18
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define wcsicmp
Definition: compat.h:15
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
GLenum GLsizei len
Definition: glext.h:6722
@ Unknown
Definition: i8042prt.h:114
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
HANDLE hProcessHeap
Definition: kbswitch.c:37
#define REG_SZ
Definition: layer.c:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define REG_NONE
Definition: nt_native.h:1492
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#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
PVOID pBuffer
#define RpcEndExcept
Definition: rpc.h:128
#define RpcTryExcept
Definition: rpc.h:126
#define RpcExcept(expr)
Definition: rpc.h:127
#define RpcExceptionCode()
Definition: rpc.h:132
#define TRACE(s)
Definition: solgame.cpp:4
ULONG dwMajorVersion
Definition: rtltypes.h:256
ULONG dwMinorVersion
Definition: rtltypes.h:257
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:255
ULONG dwBuildNumber
Definition: rtltypes.h:258
USHORT wServicePackMajor
Definition: rtltypes.h:261
CHAR szCSDVersion[128]
Definition: rtltypes.h:260
USHORT wSuiteMask
Definition: rtltypes.h:263
UCHAR wProductType
Definition: rtltypes.h:264
USHORT wServicePackMinor
Definition: rtltypes.h:262
ULONG dwPlatformId
Definition: rtltypes.h:259
WCHAR szCSDVersion[128]
Definition: rtltypes.h:274
ULONG dwMajorVersion
Definition: rtltypes.h:270
ULONG dwMinorVersion
Definition: rtltypes.h:271
USHORT wServicePackMinor
Definition: rtltypes.h:276
ULONG dwPlatformId
Definition: rtltypes.h:273
UCHAR wProductType
Definition: rtltypes.h:278
USHORT wSuiteMask
Definition: rtltypes.h:277
ULONG dwBuildNumber
Definition: rtltypes.h:272
USHORT wServicePackMajor
Definition: rtltypes.h:275
HANDLE hPrinter
Definition: precomp.h:50
BYTE dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1565
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
_In_z_ PCWSTR pwszValueName
Definition: ntuser.h:42
int ret
struct _SPOOLER_HANDLE * PSPOOLER_HANDLE
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CopyMemory
Definition: winbase.h:1710
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2084
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4950
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3828
#define WINAPI
Definition: msvc.h:6
WINBOOL WINAPI OpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefault)
Definition: printers.c:2582
#define SPLREG_OS_VERSIONEX
Definition: winspool.h:1356
struct _PRINTER_ENUM_VALUESW * PPRINTER_ENUM_VALUESW
#define SPLREG_OS_VERSION
Definition: winspool.h:1355
WINBOOL WINAPI ClosePrinter(HANDLE hPrinter)
Definition: printers.c:176
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
struct _OSVERSIONINFOA OSVERSIONINFOA
struct _OSVERSIONINFOEXW * POSVERSIONINFOEXW
struct _OSVERSIONINFOEXA OSVERSIONINFOEXA
struct _OSVERSIONINFOEXA * POSVERSIONINFOEXA
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__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