mirror of
https://github.com/reactos/reactos.git
synced 2025-04-30 11:08:51 +00:00
[WINSPOOL] Implement GetPrinterDriverA and a helper function UnicodeToAnsiInPlace (#2317)
This commit is contained in:
parent
3ef235e7cb
commit
d90beaeed2
4 changed files with 284 additions and 4 deletions
|
@ -17,6 +17,7 @@ list(APPEND SOURCE
|
||||||
printers.c
|
printers.c
|
||||||
printprocessors.c
|
printprocessors.c
|
||||||
printproviders.c
|
printproviders.c
|
||||||
|
utils.c
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/winspool_c.c)
|
${CMAKE_CURRENT_BINARY_DIR}/winspool_c.c)
|
||||||
|
|
||||||
add_library(winspool MODULE
|
add_library(winspool MODULE
|
||||||
|
|
|
@ -40,4 +40,7 @@ SPOOLER_HANDLE, *PSPOOLER_HANDLE;
|
||||||
// main.c
|
// main.c
|
||||||
extern HANDLE hProcessHeap;
|
extern HANDLE hProcessHeap;
|
||||||
|
|
||||||
|
// utils.c
|
||||||
|
extern BOOL UnicodeToAnsiInPlace(PWSTR pwszField);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1491,9 +1491,230 @@ Cleanup:
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
|
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;
|
* We are mapping multiple different pointers to the same pDriverInfo pointer here so that
|
||||||
return FALSE;
|
* 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
|
BOOL WINAPI
|
||||||
|
|
55
win32ss/printing/base/winspool/utils.c
Normal file
55
win32ss/printing/base/winspool/utils.c
Normal file
|
@ -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@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;
|
||||||
|
}
|
Loading…
Reference in a new issue