https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e8b177825b0f4478428603...
commit e8b177825b0f44784286032d6ec64606c7b0a718 Author: Doug Lyons douglyons@douglyons.com AuthorDate: Fri Jan 31 11:42:55 2020 -0600 Commit: GitHub noreply@github.com CommitDate: Fri Jan 31 18:42:55 2020 +0100
[WINSPOOL] Add Implementation of EnumPrintersA (#2273) --- win32ss/printing/base/winspool/printers.c | 446 +++++++++++++++++++++++++++++- 1 file changed, 445 insertions(+), 1 deletion(-)
diff --git a/win32ss/printing/base/winspool/printers.c b/win32ss/printing/base/winspool/printers.c index 3d029144d51..a3ee6e69673 100644 --- a/win32ss/printing/base/winspool/printers.c +++ b/win32ss/printing/base/winspool/printers.c @@ -8,6 +8,7 @@ #include "precomp.h" #include <marshalling/printers.h> #include <marshalling/printerdrivers.h> +#include <strsafe.h>
// Local Constants
@@ -386,8 +387,451 @@ Cleanup: BOOL WINAPI 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); - 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-enumprint... */ + 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