[LOCALSPL]
[reactos.git] / reactos / win32ss / printing / base / spoolss / printers.c
index 2bbf698..51e3f87 100644 (file)
@@ -2,7 +2,7 @@
  * PROJECT:     ReactOS Spooler Router
  * LICENSE:     GNU LGPL v2.1 or any later version as published by the Free Software Foundation
  * PURPOSE:     Functions related to Printers and printing
- * COPYRIGHT:   Copyright 2015 Colin Finck <colin@reactos.org>
+ * COPYRIGHT:   Copyright 2015-2017 Colin Finck <colin@reactos.org>
  */
 
 #include "precomp.h"
@@ -68,27 +68,27 @@ EnumPrintersW(DWORD Flags, PWSTR Name, DWORD Level, PBYTE pPrinterEnum, DWORD cb
     BOOL bReturnValue;
     DWORD cbCallBuffer;
     DWORD cbNeeded;
+    DWORD dwErrorCode = 0xFFFFFFFF;
     DWORD dwReturned;
     PBYTE pCallBuffer;
     PSPOOLSS_PRINT_PROVIDER pPrintProvider;
     PLIST_ENTRY pEntry;
 
-    // Sanity checks.
-    if ((cbBuf && !pPrinterEnum) || !pcbNeeded || !pcReturned)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
     // Begin counting.
     *pcbNeeded = 0;
     *pcReturned = 0;
 
+    if (cbBuf && !pPrinterEnum)
+    {
+        dwErrorCode = ERROR_INVALID_USER_BUFFER;
+        goto Cleanup;
+    }
+
     // At the beginning, we have the full buffer available.
     cbCallBuffer = cbBuf;
     pCallBuffer = pPrinterEnum;
 
-    // Loop through all Print Provider.
+    // Loop through all Print Providers.
     for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
     {
         pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
@@ -109,9 +109,15 @@ EnumPrintersW(DWORD Flags, PWSTR Name, DWORD Level, PBYTE pPrinterEnum, DWORD cb
         // Advance the buffer if the caller provided it.
         if (pCallBuffer)
             pCallBuffer += cbNeeded;
+
+        // dwErrorCode shall not be overwritten if a previous EnumPrinters call already succeeded.
+        if (dwErrorCode != ERROR_SUCCESS)
+            dwErrorCode = GetLastError();
     }
 
-    return bReturnValue;
+Cleanup:
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
 
 BOOL WINAPI
@@ -148,6 +154,7 @@ BOOL WINAPI
 OpenPrinterW(PWSTR pPrinterName, PHANDLE phPrinter, PPRINTER_DEFAULTSW pDefault)
 {
     BOOL bReturnValue;
+    DWORD dwErrorCode = ERROR_INVALID_PRINTER_NAME;
     HANDLE hPrinter;
     PLIST_ENTRY pEntry;
     PSPOOLSS_PRINTER_HANDLE pHandle;
@@ -156,8 +163,8 @@ OpenPrinterW(PWSTR pPrinterName, PHANDLE phPrinter, PPRINTER_DEFAULTSW pDefault)
     // Sanity checks.
     if (!pPrinterName || !phPrinter)
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
+        dwErrorCode = ERROR_INVALID_PARAMETER;
+        goto Cleanup;
     }
 
     // Loop through all Print Providers to find one able to open this Printer.
@@ -173,27 +180,33 @@ OpenPrinterW(PWSTR pPrinterName, PHANDLE phPrinter, PPRINTER_DEFAULTSW pDefault)
             pHandle = DllAllocSplMem(sizeof(SPOOLSS_PRINTER_HANDLE));
             if (!pHandle)
             {
-                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
-                return FALSE;
+                dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+                goto Cleanup;
             }
 
             pHandle->pPrintProvider = pPrintProvider;
             pHandle->hPrinter = hPrinter;
             *phPrinter = (HANDLE)pHandle;
 
-            SetLastError(ERROR_SUCCESS);
-            return TRUE;
+            dwErrorCode = ERROR_SUCCESS;
+            goto Cleanup;
         }
         else if (bReturnValue == ROUTER_STOP_ROUTING)
         {
             ERR("A Print Provider returned ROUTER_STOP_ROUTING for Printer \"%S\"!\n", pPrinterName);
-            return FALSE;
+            dwErrorCode = GetLastError();
+            goto Cleanup;
         }
     }
 
-    // We found no Print Provider able to open this Printer.
-    return FALSE;
+    // ERROR_INVALID_NAME by the Print Provider is translated to ERROR_INVALID_PRINTER_NAME here, but not in other APIs as far as I know.
+    if (dwErrorCode == ERROR_INVALID_NAME)
+        dwErrorCode = ERROR_INVALID_PRINTER_NAME;
+
+Cleanup:
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
 
 BOOL WINAPI