https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e8b177825b0f447842860…
commit e8b177825b0f44784286032d6ec64606c7b0a718
Author: Doug Lyons <douglyons(a)douglyons.com>
AuthorDate: Fri Jan 31 11:42:55 2020 -0600
Commit: GitHub <noreply(a)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-enumprin…
*/
+ 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