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)
11 AdvancedSetupDialog(HWND hWnd
, INT Unknown
, PDEVMODEA pDevModeInput
, PDEVMODEA pDevModeOutput
)
16 TRACE("AdvancedSetupDialog(%p, %d, %p, %p)\n", hWnd
, Unknown
, pDevModeOutput
, pDevModeInput
);
18 if ( OpenPrinterA( (LPSTR
)pDevModeInput
->dmDeviceName
, &hPrinter
, NULL
) )
20 Ret
= AdvancedDocumentPropertiesA( hWnd
, hPrinter
, (PSTR
)pDevModeInput
->dmDeviceName
, pDevModeOutput
, pDevModeInput
);
21 ClosePrinter(hPrinter
);
27 AdvancedDocumentPropertiesA(HWND hWnd
, HANDLE hPrinter
, PSTR pDeviceName
, PDEVMODEA pDevModeOutput
, PDEVMODEA pDevModeInput
)
29 TRACE("AdvancedDocumentPropertiesA(%p, %p, %s, %p, %p)\n", hWnd
, hPrinter
, pDeviceName
, pDevModeOutput
, pDevModeInput
);
35 AdvancedDocumentPropertiesW(HWND hWnd
, HANDLE hPrinter
, PWSTR pDeviceName
, PDEVMODEW pDevModeOutput
, PDEVMODEW pDevModeInput
)
37 TRACE("AdvancedDocumentPropertiesW(%p, %p, %S, %p, %p)\n", hWnd
, hPrinter
, pDeviceName
, pDevModeOutput
, pDevModeInput
);
43 DeletePrinterDataA(HANDLE hPrinter
, PSTR pValueName
)
45 LPWSTR valuenameW
= NULL
;
49 TRACE("DeletePrinterDataA(%p, %s)\n", hPrinter
, pValueName
);
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
);
58 res
= DeletePrinterDataW( hPrinter
, valuenameW
);
60 HeapFree(GetProcessHeap(), 0, valuenameW
);
67 DeletePrinterDataExA(HANDLE hPrinter
, PCSTR pKeyName
, PCSTR pValueName
)
69 LPWSTR keynameW
= NULL
;
70 LPWSTR valuenameW
= NULL
;
74 TRACE("DeletePrinterDataExA(%p, %s, %s)\n", hPrinter
, pKeyName
, pValueName
);
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
);
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
);
90 res
= DeletePrinterDataExW( hPrinter
, keynameW
, valuenameW
);
92 HeapFree(GetProcessHeap(), 0, keynameW
);
93 HeapFree(GetProcessHeap(), 0, valuenameW
);
99 DeletePrinterDataExW(HANDLE hPrinter
, PCWSTR pKeyName
, PCWSTR pValueName
)
101 TRACE("DeletePrinterDataExW(%p, %S, %S)\n", hPrinter
, pKeyName
, pValueName
);
103 return ERROR_NOT_SUPPORTED
;
107 DeletePrinterDataW(HANDLE hPrinter
, PWSTR pValueName
)
109 TRACE("DeletePrinterDataW(%p, %S)\n", hPrinter
, pValueName
);
111 return ERROR_NOT_SUPPORTED
;
115 DeletePrinterKeyA(HANDLE hPrinter
, PCSTR pKeyName
)
117 LPWSTR keynameW
= NULL
;
121 TRACE("DeletePrinterKeyA(%p, %s)\n", hPrinter
, pKeyName
);
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
);
130 res
= DeletePrinterKeyW( hPrinter
, keynameW
);
132 HeapFree(GetProcessHeap(), 0, keynameW
);
138 DeletePrinterKeyW(HANDLE hPrinter
, PCWSTR pKeyName
)
140 TRACE("DeletePrinterKeyW(%p, %S)\n", hPrinter
, pKeyName
);
142 return ERROR_NOT_SUPPORTED
;
146 EnumPrinterDataA(HANDLE hPrinter
, DWORD dwIndex
, PSTR pValueName
, DWORD cbValueName
, PDWORD pcbValueName
, PDWORD pType
, PBYTE pData
, DWORD cbData
, PDWORD pcbData
)
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
;
154 EnumPrinterDataExA(HANDLE hPrinter
, PCSTR pKeyName
, PBYTE pEnumValues
, DWORD cbEnumValues
, PDWORD pcbEnumValues
, PDWORD pnEnumValues
)
158 DWORD ret
, dwIndex
, dwBufSize
;
162 TRACE("EnumPrinterDataExA(%p, %s, %p, %lu, %p, %p)\n", hPrinter
, pKeyName
, pEnumValues
, cbEnumValues
, pcbEnumValues
, pnEnumValues
);
164 if (pKeyName
== NULL
|| *pKeyName
== 0)
165 return ERROR_INVALID_PARAMETER
;
167 len
= MultiByteToWideChar (CP_ACP
, 0, pKeyName
, -1, NULL
, 0);
170 ret
= GetLastError ();
171 ERR ("MultiByteToWideChar failed with code %i\n", ret
);
175 hHeap
= GetProcessHeap ();
178 ERR ("GetProcessHeap failed\n");
179 return ERROR_OUTOFMEMORY
;
182 pKeyNameW
= HeapAlloc (hHeap
, 0, len
* sizeof (WCHAR
));
183 if (pKeyNameW
== NULL
)
185 ERR ("Failed to allocate %i bytes from process heap\n",
186 (LONG
)(len
* sizeof (WCHAR
)));
187 return ERROR_OUTOFMEMORY
;
190 if (MultiByteToWideChar (CP_ACP
, 0, pKeyName
, -1, pKeyNameW
, len
) == 0)
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 ());
199 ret
= EnumPrinterDataExW (hPrinter
, pKeyNameW
, pEnumValues
, cbEnumValues
, pcbEnumValues
, pnEnumValues
);
201 if (ret
!= ERROR_SUCCESS
)
203 if (HeapFree (hHeap
, 0, pKeyNameW
) == 0)
204 WARN ("HeapFree failed with code %i\n", GetLastError ());
205 TRACE ("EnumPrinterDataExW returned %i\n", ret
);
209 if (HeapFree (hHeap
, 0, pKeyNameW
) == 0)
211 ret
= GetLastError ();
212 ERR ("HeapFree failed with code %i\n", ret
);
216 if (*pnEnumValues
== 0) /* empty key */
217 return ERROR_SUCCESS
;
220 for (dwIndex
= 0; dwIndex
< *pnEnumValues
; ++dwIndex
)
222 PPRINTER_ENUM_VALUESW ppev
=
223 &((PPRINTER_ENUM_VALUESW
) pEnumValues
)[dwIndex
];
225 if (dwBufSize
< ppev
->cbValueName
)
226 dwBufSize
= ppev
->cbValueName
;
228 if (dwBufSize
< ppev
->cbData
&& (ppev
->dwType
== REG_SZ
||
229 ppev
->dwType
== REG_EXPAND_SZ
|| ppev
->dwType
== REG_MULTI_SZ
))
230 dwBufSize
= ppev
->cbData
;
233 TRACE ("Largest Unicode name or value is %i bytes\n", dwBufSize
);
235 pBuffer
= HeapAlloc (hHeap
, 0, dwBufSize
);
238 ERR ("Failed to allocate %i bytes from process heap\n", dwBufSize
);
239 return ERROR_OUTOFMEMORY
;
242 for (dwIndex
= 0; dwIndex
< *pnEnumValues
; ++dwIndex
)
244 PPRINTER_ENUM_VALUESW ppev
=
245 &((PPRINTER_ENUM_VALUESW
) pEnumValues
)[dwIndex
];
247 len
= WideCharToMultiByte (CP_ACP
, 0, ppev
->pValueName
,
248 ppev
->cbValueName
/ sizeof (WCHAR
), pBuffer
, dwBufSize
, NULL
,
252 ret
= GetLastError ();
253 ERR ("WideCharToMultiByte failed with code %i\n", ret
);
254 if (HeapFree (hHeap
, 0, pBuffer
) == 0)
255 WARN ("HeapFree failed with code %i\n", GetLastError ());
259 memcpy (ppev
->pValueName
, pBuffer
, len
);
261 TRACE ("Converted '%s' from Unicode to ASCII\n", pBuffer
);
263 if (ppev
->dwType
!= REG_SZ
&& ppev
->dwType
!= REG_EXPAND_SZ
&&
264 ppev
->dwType
!= REG_MULTI_SZ
)
267 len
= WideCharToMultiByte (CP_ACP
, 0, (LPWSTR
) ppev
->pData
,
268 ppev
->cbData
/ sizeof (WCHAR
), pBuffer
, dwBufSize
, NULL
, NULL
);
271 ret
= GetLastError ();
272 ERR ("WideCharToMultiByte failed with code %i\n", ret
);
273 if (HeapFree (hHeap
, 0, pBuffer
) == 0)
274 WARN ("HeapFree failed with code %i\n", GetLastError ());
278 memcpy (ppev
->pData
, pBuffer
, len
);
280 TRACE ("Converted '%s' from Unicode to ASCII\n", pBuffer
);
281 TRACE (" (only first string of REG_MULTI_SZ printed)\n");
284 if (HeapFree (hHeap
, 0, pBuffer
) == 0)
286 ret
= GetLastError ();
287 ERR ("HeapFree failed with code %i\n", ret
);
291 return ERROR_SUCCESS
;
295 EnumPrinterDataExW(HANDLE hPrinter
, PCWSTR pKeyName
, PBYTE pEnumValues
, DWORD cbEnumValues
, PDWORD pcbEnumValues
, PDWORD pnEnumValues
)
297 TRACE("EnumPrinterDataExW(%p, %S, %p, %lu, %p, %p)\n", hPrinter
, pKeyName
, pEnumValues
, cbEnumValues
, pcbEnumValues
, pnEnumValues
);
299 return ERROR_NOT_SUPPORTED
;
303 EnumPrinterDataW(HANDLE hPrinter
, DWORD dwIndex
, PWSTR pValueName
, DWORD cbValueName
, PDWORD pcbValueName
, PDWORD pType
, PBYTE pData
, DWORD cbData
, PDWORD pcbData
)
305 TRACE("EnumPrinterDataW(%p, %lu, %S, %lu, %p, %p, %p, %lu, %p)\n", hPrinter
, dwIndex
, pValueName
, cbValueName
, pcbValueName
, pType
, pData
, cbData
, pcbData
);
307 return ERROR_NOT_SUPPORTED
;
311 EnumPrinterKeyA(HANDLE hPrinter
, PCSTR pKeyName
, PSTR pSubkey
, DWORD cbSubkey
, PDWORD pcbSubkey
)
313 TRACE("EnumPrinterKeyA(%p, %s, %s, %lu, %p)\n", hPrinter
, pKeyName
, pSubkey
, cbSubkey
, pcbSubkey
);
315 return ERROR_NOT_SUPPORTED
;
319 EnumPrinterKeyW(HANDLE hPrinter
, PCWSTR pKeyName
, PWSTR pSubkey
, DWORD cbSubkey
, PDWORD pcbSubkey
)
321 TRACE("EnumPrinterKeyW(%p, %S, %S, %lu, %p)\n", hPrinter
, pKeyName
, pSubkey
, cbSubkey
, pcbSubkey
);
323 return ERROR_NOT_SUPPORTED
;
327 GetPrinterDataA(HANDLE hPrinter
, LPSTR pValueName
, LPDWORD pType
, LPBYTE pData
, DWORD nSize
, LPDWORD pcbNeeded
)
329 TRACE("GetPrinterDataA(%p, %s, %p, %p, %lu, %p)\n", hPrinter
, pValueName
, pType
, pData
, nSize
, pcbNeeded
);
330 return GetPrinterDataExA(hPrinter
, "PrinterDriverData", pValueName
, pType
, pData
, nSize
, pcbNeeded
);
334 GetPrinterDataExA(HANDLE hPrinter
, LPCSTR pKeyName
, LPCSTR pValueName
, LPDWORD pType
, LPBYTE pData
, DWORD nSize
, LPDWORD pcbNeeded
)
340 POSVERSIONINFOEXA pInfoA
;
341 POSVERSIONINFOEXW pInfoW
;
342 PVOID pUnicodeData
= NULL
;
343 PWSTR pwszKeyName
= NULL
;
344 PWSTR pwszValueName
= NULL
;
346 TRACE("GetPrinterDataExA(%p, %s, %s, %p, %p, %lu, %p)\n", hPrinter
, pKeyName
, pValueName
, pType
, pData
, nSize
, pcbNeeded
);
350 // Convert pKeyName to a Unicode string pwszKeyName
351 cch
= strlen(pKeyName
);
353 pwszKeyName
= HeapAlloc(hProcessHeap
, 0, (cch
+ 1) * sizeof(WCHAR
));
356 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
357 ERR("HeapAlloc failed!\n");
361 MultiByteToWideChar(CP_ACP
, 0, pKeyName
, -1, pwszKeyName
, cch
+ 1);
366 // Convert pValueName to a Unicode string pwszValueName
367 cch
= strlen(pValueName
);
369 pwszValueName
= HeapAlloc(hProcessHeap
, 0, (cch
+ 1) * sizeof(WCHAR
));
372 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
373 ERR("HeapAlloc failed!\n");
377 MultiByteToWideChar(CP_ACP
, 0, pValueName
, -1, pwszValueName
, cch
+ 1);
380 // We need the data type information, even if no pData was passed.
384 // Call GetPrinterDataExW for the first time.
385 // 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.
386 dwReturnValue
= GetPrinterDataExW(hPrinter
, pwszKeyName
, pwszValueName
, pType
, pData
, nSize
, pcbNeeded
);
388 // If a critical error occurred, just return it. We cannot do anything else in this case.
389 if (dwReturnValue
!= ERROR_SUCCESS
&& dwReturnValue
!= ERROR_MORE_DATA
)
392 // Save the needed buffer size for the Unicode data. We may alter *pcbNeeded for an ANSI buffer size.
393 cbUnicodeData
= *pcbNeeded
;
395 if (*pType
== REG_SZ
|| *pType
== REG_MULTI_SZ
|| *pType
== REG_EXPAND_SZ
)
397 // This is a string that needs to be converted from Unicode to ANSI.
398 // Output the required buffer size for the ANSI string.
399 *pcbNeeded
/= sizeof(WCHAR
);
401 else if (*pType
== REG_NONE
)
403 if (cbUnicodeData
== sizeof(OSVERSIONINFOW
) && wcsicmp(pwszValueName
, SPLREG_OS_VERSION
) == 0)
405 // This is a Unicode OSVERSIONINFOW structure that needs to be converted to an ANSI OSVERSIONINFOA.
406 *pcbNeeded
= sizeof(OSVERSIONINFOA
);
408 else if (cbUnicodeData
== sizeof(OSVERSIONINFOEXW
) && wcsicmp(pwszValueName
, SPLREG_OS_VERSIONEX
) == 0)
410 // This is a Unicode OSVERSIONINFOEXW structure that needs to be converted to an ANSI OSVERSIONINFOEXA.
411 *pcbNeeded
= sizeof(OSVERSIONINFOEXA
);
415 // Other REG_NONE value, nothing to do.
420 // Check if the supplied buffer is large enough for the ANSI data.
421 if (nSize
< *pcbNeeded
)
423 dwReturnValue
= ERROR_MORE_DATA
;
427 // Allocate a temporary buffer for the Unicode data.
428 pUnicodeData
= HeapAlloc(hProcessHeap
, 0, cbUnicodeData
);
431 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
432 ERR("HeapAlloc failed!\n");
436 if (dwReturnValue
== ERROR_SUCCESS
)
438 // ERROR_SUCCESS: The buffer is large enough for the ANSI and the Unicode string,
439 // so the Unicode string has been copied into pData. Copy it to pUnicodeData.
440 CopyMemory(pUnicodeData
, pData
, cbUnicodeData
);
444 // ERROR_MORE_DATA: The buffer is large enough for the ANSI string, but not for the Unicode string.
445 // We have to call GetPrinterDataExW again with the temporary buffer.
446 dwReturnValue
= GetPrinterDataExW(hPrinter
, pwszKeyName
, pwszValueName
, NULL
, (PBYTE
)pUnicodeData
, cbUnicodeData
, &cbUnicodeData
);
447 if (dwReturnValue
!= ERROR_SUCCESS
)
451 if (*pType
== REG_SZ
|| *pType
== REG_MULTI_SZ
|| *pType
== REG_EXPAND_SZ
)
453 // Convert the Unicode string to ANSI.
454 WideCharToMultiByte(CP_ACP
, 0, (PWSTR
)pUnicodeData
, -1, (PSTR
)pData
, *pcbNeeded
, NULL
, NULL
);
458 // This is a REG_NONE with either OSVERSIONINFOW or OSVERSIONINFOEXW.
459 // Copy the fields and convert the Unicode CSD Version string to ANSI.
460 pInfoW
= (POSVERSIONINFOEXW
)pUnicodeData
;
461 pInfoA
= (POSVERSIONINFOEXA
)pData
;
462 pInfoA
->dwMajorVersion
= pInfoW
->dwMajorVersion
;
463 pInfoA
->dwMinorVersion
= pInfoW
->dwMinorVersion
;
464 pInfoA
->dwBuildNumber
= pInfoW
->dwBuildNumber
;
465 pInfoA
->dwPlatformId
= pInfoW
->dwPlatformId
;
466 WideCharToMultiByte(CP_ACP
, 0, pInfoW
->szCSDVersion
, -1, pInfoA
->szCSDVersion
, sizeof(pInfoA
->szCSDVersion
), NULL
, NULL
);
468 if (cbUnicodeData
== sizeof(OSVERSIONINFOW
))
470 pInfoA
->dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
474 pInfoA
->dwOSVersionInfoSize
= sizeof(OSVERSIONINFOEXA
);
475 pInfoA
->wServicePackMajor
= pInfoW
->wServicePackMajor
;
476 pInfoA
->wServicePackMinor
= pInfoW
->wServicePackMinor
;
477 pInfoA
->wSuiteMask
= pInfoW
->wSuiteMask
;
478 pInfoA
->wProductType
= pInfoW
->wProductType
;
479 pInfoA
->wReserved
= pInfoW
->wReserved
;
485 HeapFree(hProcessHeap
, 0, pwszKeyName
);
488 HeapFree(hProcessHeap
, 0, pwszValueName
);
491 HeapFree(hProcessHeap
, 0, pUnicodeData
);
493 return dwReturnValue
;
497 GetPrinterDataExW(HANDLE hPrinter
, LPCWSTR pKeyName
, LPCWSTR pValueName
, LPDWORD pType
, LPBYTE pData
, DWORD nSize
, LPDWORD pcbNeeded
)
499 const WCHAR wszEmptyString
[] = L
"";
503 DWORD dwType
= REG_NONE
;
504 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
506 TRACE("GetPrinterDataExW(%p, %S, %S, %p, %p, %lu, %p)\n", hPrinter
, pKeyName
, pValueName
, pType
, pData
, nSize
, pcbNeeded
);
510 return ERROR_INVALID_HANDLE
;
512 // Yes, instead of declaring these pointers unique in the IDL file (and perfectly accepting NULL pointers this way),
513 // Windows does it differently for GetPrinterDataExW and points them to empty variables.
515 pKeyName
= wszEmptyString
;
520 if (!pData
&& !nSize
)
526 dwErrorCode
= _RpcGetPrinterDataEx(pHandle
->hPrinter
, pKeyName
, pValueName
, pType
, pData
, nSize
, pcbNeeded
);
528 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
530 dwErrorCode
= RpcExceptionCode();
538 GetPrinterDataW(HANDLE hPrinter
, LPWSTR pValueName
, LPDWORD pType
, LPBYTE pData
, DWORD nSize
, LPDWORD pcbNeeded
)
540 TRACE("GetPrinterDataW(%p, %S, %p, %p, %lu, %p)\n", hPrinter
, pValueName
, pType
, pData
, nSize
, pcbNeeded
);
541 return GetPrinterDataExW(hPrinter
, L
"PrinterDriverData", pValueName
, pType
, pData
, nSize
, pcbNeeded
);
545 SetPrinterDataA(HANDLE hPrinter
, PSTR pValueName
, DWORD Type
, PBYTE pData
, DWORD cbData
)
547 TRACE("SetPrinterDataA(%p, %s, %lu, %p, %lu)\n", hPrinter
, pValueName
, Type
, pData
, cbData
);
548 return SetPrinterDataExA(hPrinter
, "PrinterDriverData", pValueName
, Type
, pData
, cbData
);
552 SetPrinterDataExA(HANDLE hPrinter
, LPCSTR pKeyName
, LPCSTR pValueName
, DWORD Type
, LPBYTE pData
, DWORD cbData
)
556 PWSTR pwszKeyName
= NULL
;
557 PWSTR pwszValueName
= NULL
;
558 PWSTR pUnicodeData
= NULL
;
560 TRACE("SetPrinterDataExA(%p, %s, %s, %lu, %p, %lu)\n", hPrinter
, pKeyName
, pValueName
, Type
, pData
, cbData
);
564 // Convert pKeyName to a Unicode string pwszKeyName
565 cch
= strlen(pKeyName
);
567 pwszKeyName
= HeapAlloc(hProcessHeap
, 0, (cch
+ 1) * sizeof(WCHAR
));
570 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
571 ERR("HeapAlloc failed!\n");
575 MultiByteToWideChar(CP_ACP
, 0, pKeyName
, -1, pwszKeyName
, cch
+ 1);
580 // Convert pValueName to a Unicode string pwszValueName
581 cch
= strlen(pValueName
);
583 pwszValueName
= HeapAlloc(hProcessHeap
, 0, (cch
+ 1) * sizeof(WCHAR
));
586 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
587 ERR("HeapAlloc failed!\n");
591 MultiByteToWideChar(CP_ACP
, 0, pValueName
, -1, pwszValueName
, cch
+ 1);
594 if (Type
== REG_SZ
|| Type
== REG_MULTI_SZ
|| Type
== REG_EXPAND_SZ
)
596 // Convert pData to a Unicode string pUnicodeData.
597 pUnicodeData
= HeapAlloc(hProcessHeap
, 0, cbData
* sizeof(WCHAR
));
600 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
601 ERR("HeapAlloc failed!\n");
605 MultiByteToWideChar(CP_ACP
, 0, (PCSTR
)pData
, -1, pUnicodeData
, cbData
);
607 pData
= (PBYTE
)pUnicodeData
;
608 cbData
*= sizeof(WCHAR
);
611 dwReturnValue
= SetPrinterDataExW(hPrinter
, pwszKeyName
, pwszValueName
, Type
, pData
, cbData
);
615 HeapFree(hProcessHeap
, 0, pwszKeyName
);
618 HeapFree(hProcessHeap
, 0, pwszValueName
);
621 HeapFree(hProcessHeap
, 0, pUnicodeData
);
623 return dwReturnValue
;
627 SetPrinterDataExW(HANDLE hPrinter
, LPCWSTR pKeyName
, LPCWSTR pValueName
, DWORD Type
, LPBYTE pData
, DWORD cbData
)
629 const WCHAR wszEmptyString
[] = L
"";
632 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
634 TRACE("SetPrinterDataExW(%p, %S, %S, %lu, %p, %lu)\n", hPrinter
, pKeyName
, pValueName
, Type
, pData
, cbData
);
638 return ERROR_INVALID_HANDLE
;
641 pKeyName
= wszEmptyString
;
646 dwErrorCode
= _RpcSetPrinterDataEx(pHandle
->hPrinter
, pKeyName
, pValueName
, Type
, pData
, cbData
);
648 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
650 dwErrorCode
= RpcExceptionCode();
658 SetPrinterDataW(HANDLE hPrinter
, PWSTR pValueName
, DWORD Type
, PBYTE pData
, DWORD cbData
)
660 TRACE("SetPrinterDataW(%p, %S, %lu, %p, %lu)\n", hPrinter
, pValueName
, Type
, pData
, cbData
);
661 return SetPrinterDataExW(hPrinter
, L
"PrinterDriverData", pValueName
, Type
, pData
, cbData
);