https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d90beaeed268639854868…
commit d90beaeed26863985486874aaa2a1c3422fd6d9f
Author: Doug Lyons <douglyons(a)douglyons.com>
AuthorDate: Wed Feb 12 12:52:34 2020 -0600
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Feb 12 19:52:34 2020 +0100
[WINSPOOL] Implement GetPrinterDriverA and a helper function UnicodeToAnsiInPlace
(#2317)
---
win32ss/printing/base/winspool/CMakeLists.txt | 1 +
win32ss/printing/base/winspool/precomp.h | 3 +
win32ss/printing/base/winspool/printers.c | 229 +++++++++++++++++++++++++-
win32ss/printing/base/winspool/utils.c | 55 +++++++
4 files changed, 284 insertions(+), 4 deletions(-)
diff --git a/win32ss/printing/base/winspool/CMakeLists.txt
b/win32ss/printing/base/winspool/CMakeLists.txt
index 9081819dd24..34c30263522 100644
--- a/win32ss/printing/base/winspool/CMakeLists.txt
+++ b/win32ss/printing/base/winspool/CMakeLists.txt
@@ -17,6 +17,7 @@ list(APPEND SOURCE
printers.c
printprocessors.c
printproviders.c
+ utils.c
${CMAKE_CURRENT_BINARY_DIR}/winspool_c.c)
add_library(winspool MODULE
diff --git a/win32ss/printing/base/winspool/precomp.h
b/win32ss/printing/base/winspool/precomp.h
index 033b38d1b4c..2c8fe18bbd9 100644
--- a/win32ss/printing/base/winspool/precomp.h
+++ b/win32ss/printing/base/winspool/precomp.h
@@ -40,4 +40,7 @@ SPOOLER_HANDLE, *PSPOOLER_HANDLE;
// main.c
extern HANDLE hProcessHeap;
+// utils.c
+extern BOOL UnicodeToAnsiInPlace(PWSTR pwszField);
+
#endif
diff --git a/win32ss/printing/base/winspool/printers.c
b/win32ss/printing/base/winspool/printers.c
index e8a6da62db7..f6616068442 100644
--- a/win32ss/printing/base/winspool/printers.c
+++ b/win32ss/printing/base/winspool/printers.c
@@ -1490,10 +1490,231 @@ Cleanup:
BOOL WINAPI
GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo,
DWORD cbBuf, LPDWORD pcbNeeded)
-{
- ERR("GetPrinterDriverA(%p, %s, %lu, %p, %lu, %p)\n", hPrinter,
pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
- if (pcbNeeded) *pcbNeeded = 0;
- return FALSE;
+{
+ /*
+ * We are mapping multiple different pointers to the same pDriverInfo pointer here so
that
+ * we can use the same incoming pointer for different Levels
+ */
+ PDRIVER_INFO_1W pdi1w = (PDRIVER_INFO_1W)pDriverInfo;
+ PDRIVER_INFO_2W pdi2w = (PDRIVER_INFO_2W)pDriverInfo;
+ PDRIVER_INFO_3W pdi3w = (PDRIVER_INFO_3W)pDriverInfo;
+ PDRIVER_INFO_4W pdi4w = (PDRIVER_INFO_4W)pDriverInfo;
+ PDRIVER_INFO_5W pdi5w = (PDRIVER_INFO_5W)pDriverInfo;
+ PDRIVER_INFO_6W pdi6w = (PDRIVER_INFO_6W)pDriverInfo;
+
+ BOOL bReturnValue = FALSE;
+ DWORD cch;
+ PWSTR pwszEnvironment = NULL;
+
+ TRACE("GetPrinterDriverA(%p, %s, %lu, %p, %lu, %p)\n", hPrinter,
pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
+
+ // Check for invalid levels here for early error return. Should be 1-6.
+ if (Level < 1 || Level > 6)
+ {
+ SetLastError(ERROR_INVALID_LEVEL);
+ ERR("Invalid Level!\n");
+ goto Exit;
+ }
+
+ if (pEnvironment)
+ {
+ // Convert pEnvironment to a Unicode string pwszEnvironment.
+ cch = strlen(pEnvironment);
+
+ pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
+ if (!pwszEnvironment)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ ERR("HeapAlloc failed!\n");
+ goto Exit;
+ }
+
+ MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1);
+ }
+
+ bReturnValue = GetPrinterDriverW(hPrinter, pwszEnvironment, Level, pDriverInfo,
cbBuf, pcbNeeded);
+ TRACE("*pcbNeeded is '%d' and bReturnValue is '%d' and
GetLastError is '%ld'.\n", *pcbNeeded, bReturnValue, GetLastError());
+
+ if (pwszEnvironment)
+ {
+ HeapFree(hProcessHeap, 0, pwszEnvironment);
+ }
+
+ if (!bReturnValue)
+ {
+ TRACE("GetPrinterDriverW failed!\n");
+ goto Exit;
+ }
+
+ // Do Unicode to ANSI conversions for strings based on Level
+ switch (Level)
+ {
+ case 1:
+ {
+ if (!UnicodeToAnsiInPlace(pdi1w->pName))
+ goto Exit;
+
+ break;
+ }
+
+ case 2:
+ {
+ if (!UnicodeToAnsiInPlace(pdi2w->pName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi2w->pEnvironment))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi2w->pDriverPath))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi2w->pDataFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi2w->pConfigFile))
+ goto Exit;
+
+ break;
+ }
+
+ case 3:
+ {
+ if (!UnicodeToAnsiInPlace(pdi3w->pName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi3w->pEnvironment))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi3w->pDriverPath))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi3w->pDataFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi3w->pConfigFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi3w->pHelpFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi3w->pDependentFiles))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi3w->pMonitorName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi3w->pDefaultDataType))
+ goto Exit;
+
+ break;
+ }
+
+ case 4:
+ {
+ if (!UnicodeToAnsiInPlace(pdi4w->pName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pEnvironment))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pDriverPath))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pDataFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pConfigFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pHelpFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pDependentFiles))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pMonitorName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pDefaultDataType))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi4w->pszzPreviousNames))
+ goto Exit;
+
+ break;
+ }
+
+ case 5:
+ {
+ if (!UnicodeToAnsiInPlace(pdi5w->pName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi5w->pEnvironment))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi5w->pDriverPath))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi5w->pDataFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi5w->pConfigFile))
+ goto Exit;
+
+ break;
+ }
+
+ case 6:
+ {
+ if (!UnicodeToAnsiInPlace(pdi6w->pName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pEnvironment))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pDriverPath))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pDataFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pConfigFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pHelpFile))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pDependentFiles))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pMonitorName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pDefaultDataType))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pszzPreviousNames))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pszMfgName))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pszOEMUrl))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pszHardwareID))
+ goto Exit;
+
+ if (!UnicodeToAnsiInPlace(pdi6w->pszProvider))
+ goto Exit;
+ }
+ }
+
+ bReturnValue = TRUE;
+
+Exit:
+
+ return bReturnValue;
}
BOOL WINAPI
diff --git a/win32ss/printing/base/winspool/utils.c
b/win32ss/printing/base/winspool/utils.c
new file mode 100644
index 00000000000..0ba5e274a5d
--- /dev/null
+++ b/win32ss/printing/base/winspool/utils.c
@@ -0,0 +1,55 @@
+/*
+* PROJECT: ReactOS Spooler API
+* LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+* PURPOSE: Utility Functions related to Print Processors
+* COPYRIGHT: Copyright 2020 Doug Lyons (douglyons(a)douglyons.com)
+*/
+
+#include <strsafe.h>
+
+BOOL UnicodeToAnsiInPlace(PWSTR pwszField)
+{
+ /*
+ * This converts an incoming Unicode string to an ANSI string.
+ * It returns FALSE on failure, otherwise it returns TRUE.
+ * It is only useful for "in-place" conversions where the ANSI string goes
+ * back into the same place where the Unicode string came into this function.
+ * It seems that many of the functions involving printing can use this.
+ */
+
+ PSTR pszTemp;
+ DWORD cch;
+
+ /*
+ * Map the incoming Unicode pwszField string to an ANSI one here so that we can do
+ * in-place conversion. We read the Unicode input and then we write back the ANSI
+ * conversion into the same buffer for use with our GetPrinterDriverA function
+ */
+ PSTR pszField = (PSTR)pwszField;
+
+ if (!pwszField)
+ {
+ return TRUE;
+ }
+
+ cch = wcslen(pwszField);
+ if (cch == 0)
+ {
+ return TRUE;
+ }
+
+ pszTemp = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
+ if (!pszField)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ ERR("HeapAlloc failed!\n");
+ return FALSE; // indicates a failure to be handled by caller
+ }
+
+ WideCharToMultiByte(CP_ACP, 0, pwszField, -1, pszTemp, cch + 1, NULL, NULL);
+ StringCchCopyA(pszField, cch + 1, pszTemp);
+
+ HeapFree(hProcessHeap, 0, pszTemp);
+
+ return TRUE;
+}