[WINSPOOL] Add Implementation of EnumPrintersA (#2273)

This commit is contained in:
Doug Lyons 2020-01-31 11:42:55 -06:00 committed by GitHub
parent fcc4347898
commit e8b177825b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -8,6 +8,7 @@
#include "precomp.h" #include "precomp.h"
#include <marshalling/printers.h> #include <marshalling/printers.h>
#include <marshalling/printerdrivers.h> #include <marshalling/printerdrivers.h>
#include <strsafe.h>
// Local Constants // Local Constants
@ -386,8 +387,451 @@ Cleanup:
BOOL WINAPI 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)
{ {
BOOL bReturnValue = FALSE;
DWORD cch;
PWSTR pwszName = NULL;
PSTR pszPrinterName = NULL;
PSTR pszServerName = NULL;
PSTR pszDescription = NULL;
PSTR pszName = NULL;
PSTR pszComment = NULL;
PSTR pszShareName = NULL;
PSTR pszPortName = NULL;
PSTR pszDriverName = NULL;
PSTR pszLocation = NULL;
PSTR pszSepFile = NULL;
PSTR pszPrintProcessor = NULL;
PSTR pszDatatype = NULL;
PSTR pszParameters = NULL;
DWORD i;
PPRINTER_INFO_1W ppi1w = NULL;
PPRINTER_INFO_1A ppi1a = NULL;
PPRINTER_INFO_2W ppi2w = NULL;
PPRINTER_INFO_2A ppi2a = NULL;
PPRINTER_INFO_4W ppi4w = NULL;
PPRINTER_INFO_4A ppi4a = NULL;
PPRINTER_INFO_5W ppi5w = NULL;
PPRINTER_INFO_5A ppi5a = NULL;
TRACE("EnumPrintersA(%lu, %s, %lu, %p, %lu, %p, %p)\n", Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned); TRACE("EnumPrintersA(%lu, %s, %lu, %p, %lu, %p, %p)\n", Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
return FALSE;
// Check for invalid levels here for early error return. MSDN says that only 1, 2, 4, and 5 are allowable.
if (Level != 1 && Level != 2 && Level != 4 && Level != 5)
{
SetLastError(ERROR_INVALID_LEVEL);
ERR("Invalid Level!\n");
goto Cleanup;
}
if (Name)
{
// Convert pName to a Unicode string pwszName.
cch = strlen(Name);
pwszName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
if (!pwszName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
MultiByteToWideChar(CP_ACP, 0, Name, -1, pwszName, cch + 1);
}
/* Ref: https://stackoverflow.com/questions/41147180/why-enumprintersa-and-enumprintersw-request-the-same-amount-of-memory */
bReturnValue = EnumPrintersW(Flags, pwszName, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
HeapFree(hProcessHeap, 0, pwszName);
TRACE("*pcReturned is '%d' and bReturnValue is '%d' and GetLastError is '%ld'.\n", *pcReturned, bReturnValue, GetLastError());
/* We are mapping multiple different pointers to the same pPrinterEnum pointer here so that */
/* we can do in-place conversion. We read the Unicode response from the EnumPrintersW and */
/* then we write back the ANSI conversion into the same buffer for our EnumPrintersA output */
/* mapping to pPrinterEnum for Unicode (w) characters for Levels 1, 2, 4, and 5 */
ppi1w = (PPRINTER_INFO_1W)pPrinterEnum;
ppi2w = (PPRINTER_INFO_2W)pPrinterEnum;
ppi4w = (PPRINTER_INFO_4W)pPrinterEnum;
ppi5w = (PPRINTER_INFO_5W)pPrinterEnum;
/* mapping to pPrinterEnum for ANSI (a) characters for Levels 1, 2, 4, and 5 */
ppi1a = (PPRINTER_INFO_1A)pPrinterEnum;
ppi2a = (PPRINTER_INFO_2A)pPrinterEnum;
ppi4a = (PPRINTER_INFO_4A)pPrinterEnum;
ppi5a = (PPRINTER_INFO_5A)pPrinterEnum;
for (i = 0; i < *pcReturned; i++)
{
switch (Level)
{
case 1:
{
if (ppi1w[i].pDescription)
{
// Convert Unicode pDescription to a ANSI string pszDescription.
cch = wcslen(ppi1w[i].pDescription);
pszDescription = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszDescription)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi1w[i].pDescription, -1, pszDescription, cch + 1, NULL, NULL);
StringCchCopyA(ppi1a[i].pDescription, cch + 1, pszDescription);
HeapFree(hProcessHeap, 0, pszDescription);
}
if (ppi1w[i].pName)
{
// Convert Unicode pName to a ANSI string pszName.
cch = wcslen(ppi1w[i].pName);
pszName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi1w[i].pName, -1, pszName, cch + 1, NULL, NULL);
StringCchCopyA(ppi1a[i].pName, cch + 1, pszName);
HeapFree(hProcessHeap, 0, pszName);
}
if (ppi1w[i].pComment)
{
// Convert Unicode pComment to a ANSI string pszComment.
cch = wcslen(ppi1w[i].pComment);
pszComment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszComment)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi1w[i].pComment, -1, pszComment, cch + 1, NULL, NULL);
StringCchCopyA(ppi1a[i].pComment, cch + 1, pszComment);
HeapFree(hProcessHeap, 0, pszComment);
}
break;
}
case 2:
{
if (ppi2w[i].pServerName)
{
// Convert Unicode pServerName to a ANSI string pszServerName.
cch = wcslen(ppi2w[i].pServerName);
pszServerName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszServerName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pServerName, -1, pszServerName, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pServerName, cch + 1, pszServerName);
HeapFree(hProcessHeap, 0, pszServerName);
}
if (ppi2w[i].pPrinterName)
{
// Convert Unicode pPrinterName to a ANSI string pszPrinterName.
cch = wcslen(ppi2w[i].pPrinterName);
pszPrinterName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszPrinterName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pPrinterName, -1, pszPrinterName, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pPrinterName, cch + 1, pszPrinterName);
HeapFree(hProcessHeap, 0, pszPrinterName);
}
if (ppi2w[i].pShareName)
{
// Convert Unicode pShareName to a ANSI string pszShareName.
cch = wcslen(ppi2w[i].pShareName);
pszShareName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszShareName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pShareName, -1, pszShareName, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pShareName, cch + 1, pszShareName);
HeapFree(hProcessHeap, 0, pszShareName);
}
if (ppi2w[i].pPortName)
{
// Convert Unicode pPortName to a ANSI string pszPortName.
cch = wcslen(ppi2w[i].pPortName);
pszPortName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszPortName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pPortName, -1, pszPortName, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pPortName, cch + 1, pszPortName);
HeapFree(hProcessHeap, 0, pszPortName);
}
if (ppi2w[i].pDriverName)
{
// Convert Unicode pDriverName to a ANSI string pszDriverName.
cch = wcslen(ppi2w[i].pDriverName);
pszDriverName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszDriverName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pDriverName, -1, pszDriverName, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pDriverName, cch + 1, pszDriverName);
HeapFree(hProcessHeap, 0, pszDriverName);
}
if (ppi2w[i].pComment)
{
// Convert Unicode pComment to a ANSI string pszComment.
cch = wcslen(ppi2w[i].pComment);
pszComment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszComment)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pComment, -1, pszComment, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pComment, cch + 1, pszComment);
HeapFree(hProcessHeap, 0, pszComment);
}
if (ppi2w[i].pLocation)
{
// Convert Unicode pLocation to a ANSI string pszLocation.
cch = wcslen(ppi2w[i].pLocation);
pszLocation = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszLocation)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pLocation, -1, pszLocation, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pLocation, cch + 1, pszLocation);
HeapFree(hProcessHeap, 0, pszLocation);
}
if (ppi2w[i].pSepFile)
{
// Convert Unicode pSepFile to a ANSI string pszSepFile.
cch = wcslen(ppi2w[i].pSepFile);
pszSepFile = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszSepFile)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pSepFile, -1, pszSepFile, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pSepFile, cch + 1, pszSepFile);
HeapFree(hProcessHeap, 0, pszSepFile);
}
if (ppi2w[i].pPrintProcessor)
{
// Convert Unicode pPrintProcessor to a ANSI string pszPrintProcessor.
cch = wcslen(ppi2w[i].pPrintProcessor);
pszPrintProcessor = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszPrintProcessor)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pPrintProcessor, -1, pszPrintProcessor, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pPrintProcessor, cch + 1, pszPrintProcessor);
HeapFree(hProcessHeap, 0, pszPrintProcessor);
}
if (ppi2w[i].pDatatype)
{
// Convert Unicode pDatatype to a ANSI string pszDatatype.
cch = wcslen(ppi2w[i].pDatatype);
pszDatatype = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszDatatype)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pDatatype, -1, pszDatatype, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pDatatype, cch + 1, pszDatatype);
HeapFree(hProcessHeap, 0, pszDatatype);
}
if (ppi2w[i].pParameters)
{
// Convert Unicode pParameters to a ANSI string pszParameters.
cch = wcslen(ppi2w[i].pParameters);
pszParameters = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszParameters)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi2w[i].pParameters, -1, pszParameters, cch + 1, NULL, NULL);
StringCchCopyA(ppi2a[i].pParameters, cch + 1, pszParameters);
HeapFree(hProcessHeap, 0, pszParameters);
}
break;
}
case 4:
{
if (ppi4w[i].pPrinterName)
{
// Convert Unicode pPrinterName to a ANSI string pszPrinterName.
cch = wcslen(ppi4w[i].pPrinterName);
pszPrinterName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszPrinterName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi4w[i].pPrinterName, -1, pszPrinterName, cch + 1, NULL, NULL);
StringCchCopyA(ppi4a[i].pPrinterName, cch + 1, pszPrinterName);
HeapFree(hProcessHeap, 0, pszPrinterName);
}
if (ppi4w[i].pServerName)
{
// Convert Unicode pServerName to a ANSI string pszServerName.
cch = wcslen(ppi4w[i].pServerName);
pszServerName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszServerName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi4w[i].pServerName, -1, pszServerName, cch + 1, NULL, NULL);
StringCchCopyA(ppi4a[i].pServerName, cch + 1, pszServerName);
HeapFree(hProcessHeap, 0, pszServerName);
}
break;
}
case 5:
{
if (ppi5w[i].pPrinterName)
{
// Convert Unicode pPrinterName to a ANSI string pszPrinterName.
cch = wcslen(ppi5w[i].pPrinterName);
pszPrinterName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszPrinterName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi5w[i].pPrinterName, -1, pszPrinterName, cch + 1, NULL, NULL);
StringCchCopyA(ppi5a[i].pPrinterName, cch + 1, pszPrinterName);
HeapFree(hProcessHeap, 0, pszPrinterName);
}
if (ppi5w[i].pPortName)
{
// Convert Unicode pPortName to a ANSI string pszPortName.
cch = wcslen(ppi5w[i].pPortName);
pszPortName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR));
if (!pszPortName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
ERR("HeapAlloc failed!\n");
goto Cleanup;
}
WideCharToMultiByte(CP_ACP, 0, ppi5w[i].pPortName, -1, pszPortName, cch + 1, NULL, NULL);
StringCchCopyA(ppi5a[i].pPortName, cch + 1, pszPortName);
HeapFree(hProcessHeap, 0, pszPortName);
}
break;
}
} // switch
} // for
Cleanup:
return bReturnValue;
} }
BOOL WINAPI BOOL WINAPI