[WINSPOOL] GetPrinterDriverA(): Refactor failure handling (#2832)

* [WINSPOOL] GetPrinterDriverA(): Refactor failure handling

Addendum to d90beaeed2.
This commit is contained in:
Serge Gautherie 2020-05-26 20:21:25 +02:00 committed by GitHub
parent 8fde48b5d7
commit 4b1ae54046
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 253 additions and 129 deletions

View file

@ -42,7 +42,7 @@ SPOOLER_HANDLE, *PSPOOLER_HANDLE;
extern HANDLE hProcessHeap; extern HANDLE hProcessHeap;
// utils.c // utils.c
extern BOOL UnicodeToAnsiInPlace(PWSTR pwszField); DWORD UnicodeToAnsiInPlace(PWSTR pwszField);
// devmode.c // devmode.c
extern void RosConvertAnsiDevModeToUnicodeDevmode(PDEVMODEA pDevModeInput, PDEVMODEW pDevModeOutput); extern void RosConvertAnsiDevModeToUnicodeDevmode(PDEVMODEA pDevModeInput, PDEVMODEW pDevModeOutput);

View file

@ -472,7 +472,6 @@ BOOL WINAPI
EnumPrintersA(DWORD Flags, PSTR Name, DWORD Level, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned) EnumPrintersA(DWORD Flags, PSTR Name, DWORD Level, PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
{ {
DWORD dwErrorCode; DWORD dwErrorCode;
BOOL bResult;
DWORD cch; DWORD cch;
PWSTR pwszName = NULL; PWSTR pwszName = NULL;
PSTR pszPrinterName = NULL; PSTR pszPrinterName = NULL;
@ -525,8 +524,7 @@ EnumPrintersA(DWORD Flags, PSTR Name, DWORD Level, PBYTE pPrinterEnum, DWORD cbB
} }
/* Ref: https://stackoverflow.com/questions/41147180/why-enumprintersa-and-enumprintersw-request-the-same-amount-of-memory */ /* Ref: https://stackoverflow.com/questions/41147180/why-enumprintersa-and-enumprintersw-request-the-same-amount-of-memory */
bResult = EnumPrintersW(Flags, pwszName, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned); if (!EnumPrintersW(Flags, pwszName, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned))
if (!bResult)
{ {
dwErrorCode = GetLastError(); dwErrorCode = GetLastError();
goto Cleanup; goto Cleanup;
@ -1118,7 +1116,6 @@ BOOL WINAPI
GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded) GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded)
{ {
DWORD dwErrorCode; DWORD dwErrorCode;
BOOL bResult;
PPRINTER_INFO_1A ppi1a = (PPRINTER_INFO_1A)pPrinter; PPRINTER_INFO_1A ppi1a = (PPRINTER_INFO_1A)pPrinter;
PPRINTER_INFO_1W ppi1w = (PPRINTER_INFO_1W)pPrinter; PPRINTER_INFO_1W ppi1w = (PPRINTER_INFO_1W)pPrinter;
PPRINTER_INFO_2A ppi2a = (PPRINTER_INFO_2A)pPrinter; PPRINTER_INFO_2A ppi2a = (PPRINTER_INFO_2A)pPrinter;
@ -1141,8 +1138,7 @@ GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD
goto Cleanup; goto Cleanup;
} }
bResult = GetPrinterW(hPrinter, Level, pPrinter, cbBuf, pcbNeeded); if (!GetPrinterW(hPrinter, Level, pPrinter, cbBuf, pcbNeeded))
if (!bResult)
{ {
dwErrorCode = GetLastError(); dwErrorCode = GetLastError();
goto Cleanup; goto Cleanup;
@ -1580,6 +1576,7 @@ 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)
{ {
DWORD dwErrorCode;
/* /*
* We are mapping multiple different pointers to the same pDriverInfo pointer here so that * We are mapping multiple different pointers to the same pDriverInfo pointer here so that
* we can use the same incoming pointer for different Levels * we can use the same incoming pointer for different Levels
@ -1591,7 +1588,6 @@ GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriv
PDRIVER_INFO_5W pdi5w = (PDRIVER_INFO_5W)pDriverInfo; PDRIVER_INFO_5W pdi5w = (PDRIVER_INFO_5W)pDriverInfo;
PDRIVER_INFO_6W pdi6w = (PDRIVER_INFO_6W)pDriverInfo; PDRIVER_INFO_6W pdi6w = (PDRIVER_INFO_6W)pDriverInfo;
BOOL bReturnValue = FALSE;
DWORD cch; DWORD cch;
PWSTR pwszEnvironment = NULL; PWSTR pwszEnvironment = NULL;
@ -1600,9 +1596,9 @@ GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriv
// Check for invalid levels here for early error return. Should be 1-6. // Check for invalid levels here for early error return. Should be 1-6.
if (Level < 1 || Level > 6) if (Level < 1 || Level > 6)
{ {
SetLastError(ERROR_INVALID_LEVEL); dwErrorCode = ERROR_INVALID_LEVEL;
ERR("Invalid Level!\n"); ERR("Invalid Level!\n");
goto Exit; goto Cleanup;
} }
if (pEnvironment) if (pEnvironment)
@ -1613,26 +1609,18 @@ GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriv
pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
if (!pwszEnvironment) if (!pwszEnvironment)
{ {
SetLastError(ERROR_NOT_ENOUGH_MEMORY); dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
ERR("HeapAlloc failed!\n"); ERR("HeapAlloc failed!\n");
goto Exit; goto Cleanup;
} }
MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1); MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1);
} }
bReturnValue = GetPrinterDriverW(hPrinter, pwszEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); if (!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); dwErrorCode = GetLastError();
} goto Cleanup;
if (!bReturnValue)
{
TRACE("GetPrinterDriverW failed!\n");
goto Exit;
} }
// Do Unicode to ANSI conversions for strings based on Level // Do Unicode to ANSI conversions for strings based on Level
@ -1640,170 +1628,307 @@ GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriv
{ {
case 1: case 1:
{ {
if (!UnicodeToAnsiInPlace(pdi1w->pName)) dwErrorCode = UnicodeToAnsiInPlace(pdi1w->pName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
break; break;
} }
case 2: case 2:
{ {
if (!UnicodeToAnsiInPlace(pdi2w->pName)) dwErrorCode = UnicodeToAnsiInPlace(pdi2w->pName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi2w->pEnvironment)) dwErrorCode = UnicodeToAnsiInPlace(pdi2w->pEnvironment);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi2w->pDriverPath)) dwErrorCode = UnicodeToAnsiInPlace(pdi2w->pDriverPath);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi2w->pDataFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi2w->pDataFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi2w->pConfigFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi2w->pConfigFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
break; break;
} }
case 3: case 3:
{ {
if (!UnicodeToAnsiInPlace(pdi3w->pName)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi3w->pEnvironment)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pEnvironment);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi3w->pDriverPath)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pDriverPath);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi3w->pDataFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pDataFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi3w->pConfigFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pConfigFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi3w->pHelpFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pHelpFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi3w->pDependentFiles)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pDependentFiles);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi3w->pMonitorName)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pMonitorName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi3w->pDefaultDataType)) dwErrorCode = UnicodeToAnsiInPlace(pdi3w->pDefaultDataType);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
break; break;
} }
case 4: case 4:
{ {
if (!UnicodeToAnsiInPlace(pdi4w->pName)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pEnvironment)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pEnvironment);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pDriverPath)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pDriverPath);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pDataFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pDataFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pConfigFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pConfigFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pHelpFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pHelpFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pDependentFiles)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pDependentFiles);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pMonitorName)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pMonitorName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pDefaultDataType)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pDefaultDataType);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi4w->pszzPreviousNames)) dwErrorCode = UnicodeToAnsiInPlace(pdi4w->pszzPreviousNames);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
break; break;
} }
case 5: case 5:
{ {
if (!UnicodeToAnsiInPlace(pdi5w->pName)) dwErrorCode = UnicodeToAnsiInPlace(pdi5w->pName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi5w->pEnvironment)) dwErrorCode = UnicodeToAnsiInPlace(pdi5w->pEnvironment);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi5w->pDriverPath)) dwErrorCode = UnicodeToAnsiInPlace(pdi5w->pDriverPath);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi5w->pDataFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi5w->pDataFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi5w->pConfigFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi5w->pConfigFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
break; break;
} }
case 6: case 6:
{ {
if (!UnicodeToAnsiInPlace(pdi6w->pName)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pEnvironment)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pEnvironment);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pDriverPath)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pDriverPath);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pDataFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pDataFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pConfigFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pConfigFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pHelpFile)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pHelpFile);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pDependentFiles)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pDependentFiles);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pMonitorName)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pMonitorName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pDefaultDataType)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pDefaultDataType);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pszzPreviousNames)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pszzPreviousNames);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pszMfgName)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pszMfgName);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pszOEMUrl)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pszOEMUrl);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pszHardwareID)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pszHardwareID);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
if (!UnicodeToAnsiInPlace(pdi6w->pszProvider)) dwErrorCode = UnicodeToAnsiInPlace(pdi6w->pszProvider);
goto Exit; if (dwErrorCode != ERROR_SUCCESS)
{
goto Cleanup;
}
} }
} }
bReturnValue = TRUE; dwErrorCode = ERROR_SUCCESS;
Exit: Cleanup:
if (pwszEnvironment)
{
HeapFree(hProcessHeap, 0, pwszEnvironment);
}
return bReturnValue; SetLastError(dwErrorCode);
return (dwErrorCode == ERROR_SUCCESS);
} }
BOOL WINAPI BOOL WINAPI

View file

@ -7,16 +7,16 @@
#include "precomp.h" #include "precomp.h"
BOOL UnicodeToAnsiInPlace(PWSTR pwszField) /*
* Converts an incoming Unicode string to an ANSI string.
* 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 returns an error code.
*/
// TODO: It seems that many of the functions involving printing could use this.
DWORD 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; PSTR pszTemp;
DWORD cch; DWORD cch;
@ -29,21 +29,20 @@ BOOL UnicodeToAnsiInPlace(PWSTR pwszField)
if (!pwszField) if (!pwszField)
{ {
return TRUE; return ERROR_SUCCESS;
} }
cch = wcslen(pwszField); cch = wcslen(pwszField);
if (cch == 0) if (cch == 0)
{ {
return TRUE; return ERROR_SUCCESS;
} }
pszTemp = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); pszTemp = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszField) if (!pszTemp)
{ {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n"); ERR("HeapAlloc failed!\n");
return FALSE; // indicates a failure to be handled by caller return ERROR_NOT_ENOUGH_MEMORY;
} }
WideCharToMultiByte(CP_ACP, 0, pwszField, -1, pszTemp, cch + 1, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, pwszField, -1, pszTemp, cch + 1, NULL, NULL);
@ -51,5 +50,5 @@ BOOL UnicodeToAnsiInPlace(PWSTR pwszField)
HeapFree(hProcessHeap, 0, pszTemp); HeapFree(hProcessHeap, 0, pszTemp);
return TRUE; return ERROR_SUCCESS;
} }