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 if (valuenameW
) 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 if (keynameW
) HeapFree(GetProcessHeap(), 0, keynameW
);
93 if (valuenameW
) 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 if (keynameW
) 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
= &((PPRINTER_ENUM_VALUESW
) pEnumValues
)[dwIndex
];
224 if (dwBufSize
< ppev
->cbValueName
)
225 dwBufSize
= ppev
->cbValueName
;
227 if ( dwBufSize
< ppev
->cbData
&&
228 (ppev
->dwType
== REG_SZ
|| ppev
->dwType
== REG_EXPAND_SZ
|| ppev
->dwType
== REG_MULTI_SZ
))
229 dwBufSize
= ppev
->cbData
;
232 FIXME ("Largest Unicode name or value is %i bytes\n", dwBufSize
);
234 pBuffer
= HeapAlloc (hHeap
, 0, dwBufSize
);
237 ERR ("Failed to allocate %i bytes from process heap\n", dwBufSize
);
238 return ERROR_OUTOFMEMORY
;
241 for (dwIndex
= 0; dwIndex
< *pnEnumValues
; ++dwIndex
)
243 PPRINTER_ENUM_VALUESW ppev
=
244 &((PPRINTER_ENUM_VALUESW
) pEnumValues
)[dwIndex
];
246 len
= WideCharToMultiByte (CP_ACP
, 0, ppev
->pValueName
,
247 ppev
->cbValueName
/ sizeof (WCHAR
), pBuffer
, dwBufSize
, NULL
,
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 ());
258 memcpy (ppev
->pValueName
, pBuffer
, len
);
260 TRACE ("Converted '%s' from Unicode to ASCII\n", pBuffer
);
262 if (ppev
->dwType
!= REG_SZ
&& ppev
->dwType
!= REG_EXPAND_SZ
&&
263 ppev
->dwType
!= REG_MULTI_SZ
)
266 len
= WideCharToMultiByte (CP_ACP
, 0, (LPWSTR
) ppev
->pData
,
267 ppev
->cbData
/ sizeof (WCHAR
), pBuffer
, dwBufSize
, NULL
, NULL
);
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 ());
277 memcpy (ppev
->pData
, pBuffer
, len
);
279 TRACE ("Converted '%s' from Unicode to ASCII\n", pBuffer
);
280 TRACE (" (only first string of REG_MULTI_SZ printed)\n");
283 if (HeapFree (hHeap
, 0, pBuffer
) == 0)
285 ret
= GetLastError ();
286 ERR ("HeapFree failed with code %i\n", ret
);
290 return ERROR_SUCCESS
;
294 EnumPrinterDataExW(HANDLE hPrinter
, PCWSTR pKeyName
, PBYTE pEnumValues
, DWORD cbEnumValues
, PDWORD pcbEnumValues
, PDWORD pnEnumValues
)
296 TRACE("EnumPrinterDataExW(%p, %S, %p, %lu, %p, %p)\n", hPrinter
, pKeyName
, pEnumValues
, cbEnumValues
, pcbEnumValues
, pnEnumValues
);
298 return ERROR_NOT_SUPPORTED
;
302 EnumPrinterDataW(HANDLE hPrinter
, DWORD dwIndex
, PWSTR pValueName
, DWORD cbValueName
, PDWORD pcbValueName
, PDWORD pType
, PBYTE pData
, DWORD cbData
, PDWORD pcbData
)
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
;
310 EnumPrinterKeyA(HANDLE hPrinter
, PCSTR pKeyName
, PSTR pSubkey
, DWORD cbSubkey
, PDWORD pcbSubkey
)
312 TRACE("EnumPrinterKeyA(%p, %s, %s, %lu, %p)\n", hPrinter
, pKeyName
, pSubkey
, cbSubkey
, pcbSubkey
);
314 return ERROR_NOT_SUPPORTED
;
318 EnumPrinterKeyW(HANDLE hPrinter
, PCWSTR pKeyName
, PWSTR pSubkey
, DWORD cbSubkey
, PDWORD pcbSubkey
)
320 TRACE("EnumPrinterKeyW(%p, %S, %S, %lu, %p)\n", hPrinter
, pKeyName
, pSubkey
, cbSubkey
, pcbSubkey
);
322 return ERROR_NOT_SUPPORTED
;
326 GetPrinterDataA(HANDLE hPrinter
, LPSTR pValueName
, LPDWORD pType
, LPBYTE pData
, DWORD nSize
, LPDWORD pcbNeeded
)
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
);
333 GetPrinterDataExA(HANDLE hPrinter
, LPCSTR pKeyName
, LPCSTR pValueName
, LPDWORD pType
, LPBYTE pData
, DWORD nSize
, LPDWORD pcbNeeded
)
339 POSVERSIONINFOEXA pInfoA
;
340 POSVERSIONINFOEXW pInfoW
;
341 PVOID pUnicodeData
= NULL
;
342 PWSTR pwszKeyName
= NULL
;
343 PWSTR pwszValueName
= NULL
;
345 TRACE("GetPrinterDataExA(%p, %s, %s, %p, %p, %lu, %p)\n", hPrinter
, pKeyName
, pValueName
, pType
, pData
, nSize
, pcbNeeded
);
349 // Convert pKeyName to a Unicode string pwszKeyName
350 cch
= strlen(pKeyName
);
352 pwszKeyName
= HeapAlloc(hProcessHeap
, 0, (cch
+ 1) * sizeof(WCHAR
));
355 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
356 ERR("HeapAlloc failed!\n");
360 MultiByteToWideChar(CP_ACP
, 0, pKeyName
, -1, pwszKeyName
, cch
+ 1);
365 // Convert pValueName to a Unicode string pwszValueName
366 cch
= strlen(pValueName
);
368 pwszValueName
= HeapAlloc(hProcessHeap
, 0, (cch
+ 1) * sizeof(WCHAR
));
371 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
372 ERR("HeapAlloc failed!\n");
376 MultiByteToWideChar(CP_ACP
, 0, pValueName
, -1, pwszValueName
, cch
+ 1);
379 // We need the data type information, even if no pData was passed.
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
);
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
)
391 // Save the needed buffer size for the Unicode data. We may alter *pcbNeeded for an ANSI buffer size.
392 cbUnicodeData
= *pcbNeeded
;
394 if (*pType
== REG_SZ
|| *pType
== REG_MULTI_SZ
|| *pType
== REG_EXPAND_SZ
)
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
);
400 else if (*pType
== REG_NONE
)
402 if (cbUnicodeData
== sizeof(OSVERSIONINFOW
) && wcsicmp(pwszValueName
, SPLREG_OS_VERSION
) == 0)
404 // This is a Unicode OSVERSIONINFOW structure that needs to be converted to an ANSI OSVERSIONINFOA.
405 *pcbNeeded
= sizeof(OSVERSIONINFOA
);
407 else if (cbUnicodeData
== sizeof(OSVERSIONINFOEXW
) && wcsicmp(pwszValueName
, SPLREG_OS_VERSIONEX
) == 0)
409 // This is a Unicode OSVERSIONINFOEXW structure that needs to be converted to an ANSI OSVERSIONINFOEXA.
410 *pcbNeeded
= sizeof(OSVERSIONINFOEXA
);
414 // Other REG_NONE value, nothing to do.
419 // Check if the supplied buffer is large enough for the ANSI data.
420 if (nSize
< *pcbNeeded
)
422 dwReturnValue
= ERROR_MORE_DATA
;
426 // Allocate a temporary buffer for the Unicode data.
427 pUnicodeData
= HeapAlloc(hProcessHeap
, 0, cbUnicodeData
);
430 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
431 ERR("HeapAlloc failed!\n");
435 if (dwReturnValue
== ERROR_SUCCESS
)
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
);
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
)
450 if (*pType
== REG_SZ
|| *pType
== REG_MULTI_SZ
|| *pType
== REG_EXPAND_SZ
)
452 // Convert the Unicode string to ANSI.
453 WideCharToMultiByte(CP_ACP
, 0, (PWSTR
)pUnicodeData
, -1, (PSTR
)pData
, *pcbNeeded
, NULL
, NULL
);
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
);
467 if (cbUnicodeData
== sizeof(OSVERSIONINFOW
))
469 pInfoA
->dwOSVersionInfoSize
= sizeof(OSVERSIONINFOA
);
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
;
484 HeapFree(hProcessHeap
, 0, pwszKeyName
);
487 HeapFree(hProcessHeap
, 0, pwszValueName
);
490 HeapFree(hProcessHeap
, 0, pUnicodeData
);
492 return dwReturnValue
;
496 GetPrinterDataExW(HANDLE hPrinter
, LPCWSTR pKeyName
, LPCWSTR pValueName
, LPDWORD pType
, LPBYTE pData
, DWORD nSize
, LPDWORD pcbNeeded
)
498 const WCHAR wszEmptyString
[] = L
"";
502 DWORD dwType
= REG_NONE
;
503 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
505 TRACE("GetPrinterDataExW(%p, %S, %S, %p, %p, %lu, %p)\n", hPrinter
, pKeyName
, pValueName
, pType
, pData
, nSize
, pcbNeeded
);
509 return ERROR_INVALID_HANDLE
;
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.
514 pKeyName
= wszEmptyString
;
519 if (!pData
&& !nSize
)
525 dwErrorCode
= _RpcGetPrinterDataEx(pHandle
->hPrinter
, pKeyName
, pValueName
, pType
, pData
, nSize
, pcbNeeded
);
527 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
529 dwErrorCode
= RpcExceptionCode();
537 GetPrinterDataW(HANDLE hPrinter
, LPWSTR pValueName
, LPDWORD pType
, LPBYTE pData
, DWORD nSize
, LPDWORD pcbNeeded
)
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
);
544 SetPrinterDataA(HANDLE hPrinter
, PSTR pValueName
, DWORD Type
, PBYTE pData
, DWORD cbData
)
546 TRACE("SetPrinterDataA(%p, %s, %lu, %p, %lu)\n", hPrinter
, pValueName
, Type
, pData
, cbData
);
547 return SetPrinterDataExA(hPrinter
, "PrinterDriverData", pValueName
, Type
, pData
, cbData
);
551 SetPrinterDataExA(HANDLE hPrinter
, LPCSTR pKeyName
, LPCSTR pValueName
, DWORD Type
, LPBYTE pData
, DWORD cbData
)
555 PWSTR pwszKeyName
= NULL
;
556 PWSTR pwszValueName
= NULL
;
557 PWSTR pUnicodeData
= NULL
;
559 TRACE("SetPrinterDataExA(%p, %s, %s, %lu, %p, %lu)\n", hPrinter
, pKeyName
, pValueName
, Type
, pData
, cbData
);
563 // Convert pKeyName to a Unicode string pwszKeyName
564 cch
= strlen(pKeyName
);
566 pwszKeyName
= HeapAlloc(hProcessHeap
, 0, (cch
+ 1) * sizeof(WCHAR
));
569 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
570 ERR("HeapAlloc failed!\n");
574 MultiByteToWideChar(CP_ACP
, 0, pKeyName
, -1, pwszKeyName
, cch
+ 1);
579 // Convert pValueName to a Unicode string pwszValueName
580 cch
= strlen(pValueName
);
582 pwszValueName
= HeapAlloc(hProcessHeap
, 0, (cch
+ 1) * sizeof(WCHAR
));
585 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
586 ERR("HeapAlloc failed!\n");
590 MultiByteToWideChar(CP_ACP
, 0, pValueName
, -1, pwszValueName
, cch
+ 1);
593 if (Type
== REG_SZ
|| Type
== REG_MULTI_SZ
|| Type
== REG_EXPAND_SZ
)
595 // Convert pData to a Unicode string pUnicodeData.
596 pUnicodeData
= HeapAlloc(hProcessHeap
, 0, cbData
* sizeof(WCHAR
));
599 dwReturnValue
= ERROR_NOT_ENOUGH_MEMORY
;
600 ERR("HeapAlloc failed!\n");
604 MultiByteToWideChar(CP_ACP
, 0, (PCSTR
)pData
, -1, pUnicodeData
, cbData
);
606 pData
= (PBYTE
)pUnicodeData
;
607 cbData
*= sizeof(WCHAR
);
610 dwReturnValue
= SetPrinterDataExW(hPrinter
, pwszKeyName
, pwszValueName
, Type
, pData
, cbData
);
614 HeapFree(hProcessHeap
, 0, pwszKeyName
);
617 HeapFree(hProcessHeap
, 0, pwszValueName
);
620 HeapFree(hProcessHeap
, 0, pUnicodeData
);
622 return dwReturnValue
;
626 SetPrinterDataExW(HANDLE hPrinter
, LPCWSTR pKeyName
, LPCWSTR pValueName
, DWORD Type
, LPBYTE pData
, DWORD cbData
)
628 const WCHAR wszEmptyString
[] = L
"";
631 PSPOOLER_HANDLE pHandle
= (PSPOOLER_HANDLE
)hPrinter
;
633 TRACE("SetPrinterDataExW(%p, %S, %S, %lu, %p, %lu)\n", hPrinter
, pKeyName
, pValueName
, Type
, pData
, cbData
);
637 return ERROR_INVALID_HANDLE
;
640 pKeyName
= wszEmptyString
;
645 dwErrorCode
= _RpcSetPrinterDataEx(pHandle
->hPrinter
, pKeyName
, pValueName
, Type
, pData
, cbData
);
647 RpcExcept(EXCEPTION_EXECUTE_HANDLER
)
649 dwErrorCode
= RpcExceptionCode();
657 SetPrinterDataW(HANDLE hPrinter
, PWSTR pValueName
, DWORD Type
, PBYTE pData
, DWORD cbData
)
659 TRACE("SetPrinterDataW(%p, %S, %lu, %p, %lu)\n", hPrinter
, pValueName
, Type
, pData
, cbData
);
660 return SetPrinterDataExW(hPrinter
, L
"PrinterDriverData", pValueName
, Type
, pData
, cbData
);