[WINSPOOL]
authorColin Finck <colin@reactos.org>
Tue, 23 Jun 2015 13:46:14 +0000 (13:46 +0000)
committerColin Finck <colin@reactos.org>
Tue, 23 Jun 2015 13:46:14 +0000 (13:46 +0000)
Don't rely on pure magic to transmit the error code of the RPC call to the calling application. Instead use SetLastError on the return value of the call (this is what all these DWORD return values are for!)

[SPOOLSV]
For every RPC function, return the error code of the called Spooler Router function instead of the error code of RpcRevertToSelf.

[LOCALSPL, WINPRINT]
- Change the code structure in every function called from the Spooler Router to always set an error code, especially ERROR_SUCCESS on success.
- Store Attributes and Status values for a local printer.
- Fail in LocalAddJob if an invalid handle has been supplied or the printer is set to do direct printing.

svn path=/branches/colins-printing-for-freedom/; revision=68247

15 files changed:
reactos/win32ss/printing/base/spoolss/main.c
reactos/win32ss/printing/base/spoolsv/init.c
reactos/win32ss/printing/base/spoolsv/jobs.c
reactos/win32ss/printing/base/spoolsv/printers.c
reactos/win32ss/printing/base/spoolsv/printprocessors.c
reactos/win32ss/printing/base/winspool/jobs.c
reactos/win32ss/printing/base/winspool/main.c
reactos/win32ss/printing/base/winspool/printers.c
reactos/win32ss/printing/base/winspool/printprocessors.c
reactos/win32ss/printing/processors/winprint/main.c
reactos/win32ss/printing/providers/localspl/jobs.c
reactos/win32ss/printing/providers/localspl/main.c
reactos/win32ss/printing/providers/localspl/precomp.h
reactos/win32ss/printing/providers/localspl/printers.c
reactos/win32ss/printing/providers/localspl/printprocessors.c

index ec01ff0..bc9963b 100644 (file)
@@ -94,9 +94,10 @@ SplIsUpgrade()
        return FALSE;
 }
 
-DWORD WINAPI
+BOOL WINAPI
 SpoolerInit()
 {
     // Nothing to do here yet
-    return ERROR_SUCCESS;
+    SetLastError(ERROR_SUCCESS);
+    return TRUE;
 }
index 2cbb6f6..435b24e 100644 (file)
@@ -21,13 +21,9 @@ _RpcSpoolerInit()
         return dwErrorCode;
     }
 
-    dwErrorCode = SpoolerInit();
-    if (dwErrorCode != ERROR_SUCCESS)
-    {
-        ERR("SpoolerInit failed with error %lu!\n", dwErrorCode);
-        RpcRevertToSelf();
-        return dwErrorCode;
-    }
+    SpoolerInit();
+    dwErrorCode = GetLastError();
 
-    return RpcRevertToSelf();
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
index f1d7cd0..15f56d6 100644 (file)
@@ -19,15 +19,11 @@ _RpcAddJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD Level, BYTE* pAddJob, DWORD c
         return dwErrorCode;
     }
 
-    dwErrorCode = AddJobW(hPrinter, Level, pAddJob, cbBuf, pcbNeeded);
-    if (dwErrorCode != ERROR_SUCCESS)
-    {
-        ERR("AddJobW failed with error %lu!\n", dwErrorCode);
-        RpcRevertToSelf();
-        return dwErrorCode;
-    }
+    AddJobW(hPrinter, Level, pAddJob, cbBuf, pcbNeeded);
+    dwErrorCode = GetLastError();
 
-    return RpcRevertToSelf();
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
 
 DWORD
@@ -42,15 +38,11 @@ _RpcGetJob(WINSPOOL_PRINTER_HANDLE hPrinter, DWORD JobId, DWORD Level, BYTE* pJo
         return dwErrorCode;
     }
 
-    dwErrorCode = GetJobW(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
-    if (dwErrorCode != ERROR_SUCCESS)
-    {
-        ERR("GetJobW failed with error %lu!\n", dwErrorCode);
-        RpcRevertToSelf();
-        return dwErrorCode;
-    }
+    GetJobW(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
+    dwErrorCode = GetLastError();
 
-    return RpcRevertToSelf();
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
 
 DWORD
index 1338e5d..ff1ec6e 100644 (file)
@@ -19,15 +19,11 @@ _RpcEnumPrinters(DWORD Flags, WINSPOOL_HANDLE Name, DWORD Level, BYTE* pPrinterE
         return dwErrorCode;
     }
 
-    dwErrorCode = EnumPrintersW(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
-    if (dwErrorCode != ERROR_SUCCESS)
-    {
-        ERR("EnumPrintersW failed with error %lu!\n", dwErrorCode);
-        RpcRevertToSelf();
-        return dwErrorCode;
-    }
+    EnumPrintersW(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+    dwErrorCode = GetLastError();
 
-    return RpcRevertToSelf();
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
 
 DWORD
@@ -47,13 +43,9 @@ _RpcOpenPrinter(WINSPOOL_HANDLE pPrinterName, WINSPOOL_PRINTER_HANDLE* phPrinter
     Default.pDatatype = pDatatype;
     Default.pDevMode = (PDEVMODEW)pDevModeContainer->pDevMode;
 
-    dwErrorCode = OpenPrinterW(pPrinterName, phPrinter, &Default);
-    if (dwErrorCode != ERROR_SUCCESS)
-    {
-        ERR("OpenPrinterW failed with error %lu!\n", dwErrorCode);
-        RpcRevertToSelf();
-        return dwErrorCode;
-    }
+    OpenPrinterW(pPrinterName, phPrinter, &Default);
+    dwErrorCode = GetLastError();
 
-    return RpcRevertToSelf();
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
index 9a7f2fd..173f7f4 100644 (file)
@@ -26,15 +26,11 @@ _RpcEnumPrintProcessorDatatypes(WINSPOOL_HANDLE pName, WCHAR *pPrintProcessorNam
         return dwErrorCode;
     }
 
-    dwErrorCode = EnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
-    if (dwErrorCode != ERROR_SUCCESS)
-    {
-        ERR("EnumPrintProcessorDatatypesW failed with error %lu!\n", dwErrorCode);
-        RpcRevertToSelf();
-        return dwErrorCode;
-    }
+    EnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
+    dwErrorCode = GetLastError();
 
-    return RpcRevertToSelf();
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
 
 DWORD
@@ -49,15 +45,11 @@ _RpcEnumPrintProcessors(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, DWORD Level,
         return dwErrorCode;
     }
 
-    dwErrorCode = EnumPrintProcessorsW(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
-    if (dwErrorCode != ERROR_SUCCESS)
-    {
-        ERR("EnumPrintProcessorsW failed with error %lu!\n", dwErrorCode);
-        RpcRevertToSelf();
-        return dwErrorCode;
-    }
+    EnumPrintProcessorsW(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
+    dwErrorCode = GetLastError();
 
-    return RpcRevertToSelf();
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
 
 DWORD
@@ -72,13 +64,9 @@ _RpcGetPrintProcessorDirectory(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, DWORD
         return dwErrorCode;
     }
 
-    dwErrorCode = GetPrintProcessorDirectoryW(pName, pEnvironment, Level, pPrintProcessorDirectory, cbBuf, pcbNeeded);
-    if (dwErrorCode != ERROR_SUCCESS)
-    {
-        ERR("EnumPrintProcessorsW failed with error %lu!\n", dwErrorCode);
-        RpcRevertToSelf();
-        return dwErrorCode;
-    }
+    GetPrintProcessorDirectoryW(pName, pEnvironment, Level, pPrintProcessorDirectory, cbBuf, pcbNeeded);
+    dwErrorCode = GetLastError();
 
-    return RpcRevertToSelf();
+    RpcRevertToSelf();
+    return dwErrorCode;
 }
index 44425a2..5866141 100644 (file)
@@ -17,11 +17,7 @@ AddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeede
     RpcTryExcept
     {
         dwErrorCode = _RpcAddJob(hPrinter, Level, pData, cbBuf, pcbNeeded);
-        if (dwErrorCode)
-        {
-            ERR("_RpcAddJob failed with error %lu!\n", dwErrorCode);
-        }
-
+        SetLastError(dwErrorCode);
         bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -43,11 +39,7 @@ GetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDW
     RpcTryExcept
     {
         dwErrorCode = _RpcGetJob(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
-        if (dwErrorCode)
-        {
-            ERR("_RpcGetJob failed with error %lu!\n", dwErrorCode);
-        }
-
+        SetLastError(dwErrorCode);
         bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
index a059a1a..016d807 100644 (file)
@@ -68,19 +68,15 @@ midl_user_free(void __RPC_FAR* ptr)
 BOOL WINAPI
 SpoolerInit()
 {
-    BOOL ReturnValue = FALSE;
-    DWORD ErrorCode;
+    BOOL bReturnValue = FALSE;
+    DWORD dwErrorCode;
 
     // Nothing to initialize here yet, but pass this call to the Spool Service as well.
     RpcTryExcept
     {
-        ErrorCode = _RpcSpoolerInit();
-        if (ErrorCode)
-        {
-            ERR("_RpcSpoolerInit failed with error %lu!\n", ErrorCode);
-        }
-
-        ReturnValue = (ErrorCode == ERROR_SUCCESS);
+        dwErrorCode = _RpcSpoolerInit();
+        SetLastError(dwErrorCode);
+        bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -88,5 +84,5 @@ SpoolerInit()
     }
     RpcEndExcept;
 
-    return ReturnValue;
+    return bReturnValue;
 }
index 6bb5f17..dd3e271 100644 (file)
@@ -23,11 +23,7 @@ EnumPrintersW(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD
     RpcTryExcept
     {
         dwErrorCode = _RpcEnumPrinters(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
-        if (dwErrorCode)
-        {
-            ERR("_RpcEnumPrinters failed with error %lu!\n", dwErrorCode);
-        }
-
+        SetLastError(dwErrorCode);
         bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -204,11 +200,7 @@ OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefau
     RpcTryExcept
     {
         dwErrorCode = _RpcOpenPrinter(pPrinterName, phPrinter, pDatatype, pDevModeContainer, AccessRequired);
-        if (dwErrorCode)
-        {
-            ERR("_RpcOpenPrinter failed with error %lu!\n", dwErrorCode);
-        }
-
+        SetLastError(dwErrorCode);
         bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
index 345736c..66b8336 100644 (file)
@@ -23,11 +23,7 @@ EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Lev
     RpcTryExcept
     {
         dwErrorCode = _RpcEnumPrintProcessorDatatypes(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
-        if (dwErrorCode)
-        {
-            ERR("_RpcEnumPrintProcessorDatatypes failed with error %lu!\n", dwErrorCode);
-        }
-
+        SetLastError(dwErrorCode);
         bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -49,11 +45,7 @@ EnumPrintProcessorsW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPri
     RpcTryExcept
     {
         dwErrorCode = _RpcEnumPrintProcessors(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
-        if (dwErrorCode)
-        {
-            ERR("_RpcEnumPrintProcessors failed with error %lu!\n", dwErrorCode);
-        }
-
+        SetLastError(dwErrorCode);
         bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -75,11 +67,7 @@ GetPrintProcessorDirectoryW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBY
     RpcTryExcept
     {
         dwErrorCode = _RpcGetPrintProcessorDirectory(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
-        if (dwErrorCode)
-        {
-            ERR("_RpcGetPrintProcessorDirectory failed with error %lu!\n", dwErrorCode);
-        }
-
+        SetLastError(dwErrorCode);
         bReturnValue = (dwErrorCode == ERROR_SUCCESS);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
index 270065c..bb45bfa 100644 (file)
@@ -49,13 +49,17 @@ BOOL WINAPI
 EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
     DWORD cbDatatype;
+    DWORD dwErrorCode;
     DWORD dwOffsets[_countof(pwszDatatypes)];
     PCWSTR* pCurrentDatatype;
     PDWORD pCurrentOffset = dwOffsets;
 
     // Sanity checks
     if (Level != 1 || !pcbNeeded || !pcReturned)
-        return FALSE;
+    {
+        dwErrorCode = ERROR_INVALID_PARAMETER;
+        goto Cleanup;
+    }
 
     // Count the required buffer size and the number of datatypes.
     *pcbNeeded = 0;
@@ -76,20 +80,24 @@ EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Lev
     // Check if the supplied buffer is large enough.
     if (cbBuf < *pcbNeeded)
     {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
+        dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
+        goto Cleanup;
     }
 
     // Check if a buffer was supplied at all.
     if (!pDatatypes)
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
+        dwErrorCode = ERROR_INVALID_PARAMETER;
+        goto Cleanup;
     }
 
     // Copy over all datatypes.
     *pCurrentOffset = MAXDWORD;
     PackStrings(pwszDatatypes, pDatatypes, dwOffsets, &pDatatypes[*pcbNeeded]);
 
-    return TRUE;
+    dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
index 7fa5753..aa81e3a 100644 (file)
@@ -196,36 +196,54 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
     const DWORD cchSpl = _countof("?????.SPL") - 1;
 
     ADDJOB_INFO_1W AddJobInfo1;
-    BOOL bReturnValue = FALSE;
     DWORD cchMachineName;
     DWORD cchUserName;
+    DWORD dwErrorCode;
     PBYTE p;
     PLOCAL_HANDLE pHandle;
     PLOCAL_JOB pJob;
     PLOCAL_PRINTER_HANDLE pPrinterHandle;
     RPC_BINDING_HANDLE hServerBinding = NULL;
-    RPC_STATUS Status;
     RPC_WSTR pwszBinding = NULL;
     RPC_WSTR pwszMachineName = NULL;
 
     // Check if this is a printer handle.
     pHandle = (PLOCAL_HANDLE)hPrinter;
     if (pHandle->HandleType != Printer)
+    {
+        dwErrorCode = ERROR_INVALID_HANDLE;
         goto Cleanup;
+    }
 
     pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->SpecificHandle;
 
+    // This handle must not have started a job yet!
+    if (pPrinterHandle->StartedJob)
+    {
+        dwErrorCode = ERROR_INVALID_HANDLE;
+        goto Cleanup;
+    }
+
     // Check if this is the right structure level.
     if (Level != 1)
+    {
+        dwErrorCode = ERROR_INVALID_LEVEL;
         goto Cleanup;
+    }
 
-    // FIXME: This needs to fail if the printer is set to do direct printing.
+    // Check if the printer is set to do direct printing.
+    // The Job List isn't used in this case.
+    if (pPrinterHandle->Printer->dwAttributes & PRINTER_ATTRIBUTE_DIRECT)
+    {
+        dwErrorCode = ERROR_INVALID_ACCESS;
+        goto Cleanup;
+    }
 
     // Check if the supplied buffer is large enough.
     *pcbNeeded = sizeof(ADDJOB_INFO_1W) + (cchSpoolDirectory + cchPrintersPath + cchSpl + 1) * sizeof(WCHAR);
     if (cbBuf < *pcbNeeded)
     {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
         goto Cleanup;
     }
 
@@ -233,13 +251,17 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
     pJob = DllAllocSplMem(sizeof(LOCAL_JOB));
     if (!pJob)
     {
-        ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+        dwErrorCode = GetLastError();
+        ERR("DllAllocSplMem failed with error %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
     // Reserve an ID for this job.
     if (!GetNextJobID(&pJob->dwJobID))
+    {
+        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
         goto Cleanup;
+    }
 
     // Copy over defaults to the LOCAL_JOB structure.
     pJob->Printer = pPrinterHandle->Printer;
@@ -254,7 +276,8 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
     pJob->pwszUserName = DllAllocSplMem(cchUserName * sizeof(WCHAR));
     if (!GetUserNameW(pJob->pwszUserName, &cchUserName))
     {
-        ERR("GetUserNameW failed with error %lu!\n", GetLastError());
+        dwErrorCode = GetLastError();
+        ERR("GetUserNameW failed with error %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
@@ -262,24 +285,24 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
     pJob->pwszNotifyName = AllocSplStr(pJob->pwszUserName);
 
     // Get the name of the machine that submitted the Job over RPC.
-    Status = RpcBindingServerFromClient(NULL, &hServerBinding);
-    if (Status != RPC_S_OK)
+    dwErrorCode = RpcBindingServerFromClient(NULL, &hServerBinding);
+    if (dwErrorCode != RPC_S_OK)
     {
-        ERR("RpcBindingServerFromClient failed with status %lu!\n", Status);
+        ERR("RpcBindingServerFromClient failed with status %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
-    Status = RpcBindingToStringBindingW(hServerBinding, &pwszBinding);
-    if (Status != RPC_S_OK)
+    dwErrorCode = RpcBindingToStringBindingW(hServerBinding, &pwszBinding);
+    if (dwErrorCode != RPC_S_OK)
     {
-        ERR("RpcBindingToStringBindingW failed with status %lu!\n", Status);
+        ERR("RpcBindingToStringBindingW failed with status %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
-    Status = RpcStringBindingParseW(pwszBinding, NULL, NULL, &pwszMachineName, NULL, NULL);
-    if (Status != RPC_S_OK)
+    dwErrorCode = RpcStringBindingParseW(pwszBinding, NULL, NULL, &pwszMachineName, NULL, NULL);
+    if (dwErrorCode != RPC_S_OK)
     {
-        ERR("RpcStringBindingParseW failed with status %lu!\n", Status);
+        ERR("RpcStringBindingParseW failed with status %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
@@ -291,6 +314,7 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
     // Add the job to the Global Job List.
     if (!InsertElementSkiplist(&GlobalJobList, pJob))
     {
+        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
         ERR("InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->dwJobID);
         goto Cleanup;
     }
@@ -299,6 +323,7 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
     // As all new jobs are created with default priority, we can be sure that it would always be inserted at the end.
     if (!InsertTailElementSkiplist(&pJob->Printer->JobList, pJob))
     {
+        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
         ERR("InsertTailElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->dwJobID);
         goto Cleanup;
     }
@@ -315,7 +340,7 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
     p += cchPrintersPath;
     swprintf((PWSTR)p, L"%05lu.SPL", pJob->dwJobID);
 
-    bReturnValue = TRUE;
+    dwErrorCode = ERROR_SUCCESS;
 
 Cleanup:
     if (pwszMachineName)
@@ -327,11 +352,12 @@ Cleanup:
     if (hServerBinding)
         RpcBindingFree(&hServerBinding);
 
-    return bReturnValue;
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
 
 
-static BOOL
+static DWORD
 _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE pOutput, DWORD cbBuf, PDWORD pcbNeeded)
 {
     DWORD cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
@@ -339,6 +365,7 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
     DWORD cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR);
     DWORD cbPrinterName = (wcslen(pJob->Printer->pwszPrinterName) + 1) * sizeof(WCHAR);
     DWORD cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
+    DWORD dwErrorCode;
     JOB_INFO_1W JobInfo1 = { 0 };
     PBYTE pString;
 
@@ -346,8 +373,8 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
     *pcbNeeded = sizeof(JOB_INFO_1W) + cbDatatype + cbDocumentName + cbMachineName + cbPrinterName + cbUserName;
     if (cbBuf < *pcbNeeded)
     {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
+        dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
+        goto Cleanup;
     }
 
     // Put the strings right after the JOB_INFO_1W structure.
@@ -381,10 +408,13 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
     CopyMemory(&JobInfo1.Submitted, &pJob->stSubmitted, sizeof(SYSTEMTIME));
     CopyMemory(pOutput, &JobInfo1, sizeof(JOB_INFO_1W));
 
-    return TRUE;
+    dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+    return dwErrorCode;
 }
 
-static BOOL
+static DWORD
 _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE pOutput, DWORD cbBuf, PDWORD pcbNeeded)
 {
     DWORD cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
@@ -395,6 +425,7 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
     DWORD cbPrinterName = (wcslen(pJob->Printer->pwszPrinterName) + 1) * sizeof(WCHAR);
     DWORD cbPrintProcessor = (wcslen(pJob->Printer->pPrintProcessor->pwszName) + 1) * sizeof(WCHAR);
     DWORD cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
+    DWORD dwErrorCode;
     FILETIME ftNow;
     FILETIME ftSubmitted;
     JOB_INFO_2W JobInfo2 = { 0 };
@@ -406,8 +437,8 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
     *pcbNeeded = sizeof(JOB_INFO_2W) + cbDatatype + sizeof(DEVMODEW) + cbDocumentName + cbDriverName + cbMachineName + cbNotifyName + cbPrinterName + cbPrintProcessor + cbUserName;
     if (cbBuf < *pcbNeeded)
     {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
+        dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
+        goto Cleanup;
     }
 
     // Put the strings right after the JOB_INFO_2W structure.
@@ -467,8 +498,9 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
     // Retrieve this through the element index of the job in the Printer's Job List.
     if (!LookupElementSkiplist(&pJob->Printer->JobList, pJob, &JobInfo2.Position))
     {
+        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
         ERR("pJob could not be located in the Printer's Job List!\n");
-        return FALSE;
+        goto Cleanup;
     }
 
     // Make the index 1-based.
@@ -486,12 +518,16 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE
 
     // Finally copy the structure to the output pointer.
     CopyMemory(pOutput, &JobInfo2, sizeof(JOB_INFO_2W));
-    return TRUE;
+    dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+    return dwErrorCode;
 }
 
 BOOL WINAPI
 LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pOutput, DWORD cbBuf, LPDWORD pcbNeeded)
 {
+    DWORD dwErrorCode;
     PLOCAL_HANDLE pHandle;
     PLOCAL_JOB pJob;
     PLOCAL_PRINTER_HANDLE pPrinterHandle;
@@ -499,7 +535,10 @@ LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pOutput, DWORD cbB
     // Check if this is a printer handle.
     pHandle = (PLOCAL_HANDLE)hPrinter;
     if (pHandle->HandleType != Printer)
-        return FALSE;
+    {
+        dwErrorCode = ERROR_INVALID_HANDLE;
+        goto Cleanup;
+    }
 
     pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->SpecificHandle;
 
@@ -507,17 +546,21 @@ LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pOutput, DWORD cbB
     pJob = LookupElementSkiplist(&GlobalJobList, &JobId, NULL);
     if (!pJob || pJob->Printer != pPrinterHandle->Printer)
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
+        dwErrorCode = ERROR_INVALID_PARAMETER;
+        goto Cleanup;
     }
 
     // The function behaves differently for each level.
     if (Level == 1)
-        return _LocalGetJobLevel1(pPrinterHandle, pJob, pOutput, cbBuf, pcbNeeded);
+        dwErrorCode = _LocalGetJobLevel1(pPrinterHandle, pJob, pOutput, cbBuf, pcbNeeded);
     else if (Level == 2)
-        return _LocalGetJobLevel2(pPrinterHandle, pJob, pOutput, cbBuf, pcbNeeded);
+        dwErrorCode = _LocalGetJobLevel2(pPrinterHandle, pJob, pOutput, cbBuf, pcbNeeded);
+    else
+        dwErrorCode = ERROR_INVALID_LEVEL;
 
-    return FALSE;
+Cleanup:
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
 
 PLOCAL_JOB
index 4ede442..602029c 100644 (file)
@@ -156,5 +156,6 @@ InitializePrintProvidor(LPPRINTPROVIDOR pPrintProvidor, DWORD cbPrintProvidor, L
 {
     CopyMemory(pPrintProvidor, &_PrintProviderFunctions, min(cbPrintProvidor, sizeof(PRINTPROVIDOR)));
 
+    SetLastError(ERROR_SUCCESS);
     return TRUE;
 }
index d45edfb..0d8e726 100644 (file)
@@ -73,6 +73,8 @@ typedef struct _LOCAL_PRINTER
     // This sort key must be the first element for LookupElementSkiplist to work!
     PWSTR pwszPrinterName;
 
+    DWORD dwAttributes;
+    DWORD dwStatus;
     PWSTR pwszPrinterDriver;
     PWSTR pwszDescription;
     PWSTR pwszDefaultDatatype;
index 8a8d616..b923b24 100644 (file)
@@ -38,7 +38,7 @@ InitializePrinterList()
 {
     const WCHAR wszPrintersKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Printers";
 
-    DWORD cbDevMode;
+    DWORD cbData;
     DWORD cchPrinterName;
     DWORD dwSubKeys;
     DWORD i;
@@ -173,11 +173,29 @@ InitializePrinterList()
         }
 
         // Get the default DevMode.
-        cbDevMode = sizeof(DEVMODEW);
-        lStatus = RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, (PBYTE)&pPrinter->DefaultDevMode, &cbDevMode);
-        if (lStatus != ERROR_SUCCESS || cbDevMode != sizeof(DEVMODEW))
+        cbData = sizeof(DEVMODEW);
+        lStatus = RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, (PBYTE)&pPrinter->DefaultDevMode, &cbData);
+        if (lStatus != ERROR_SUCCESS || cbData != sizeof(DEVMODEW))
         {
-            ERR("Couldn't query a valid DevMode for Printer \"%S\", status is %ld, cbDevMode is %lu!\n", wszPrinterName, lStatus, cbDevMode);
+            ERR("Couldn't query a valid DevMode for Printer \"%S\", status is %ld, cbData is %lu!\n", wszPrinterName, lStatus, cbData);
+            continue;
+        }
+
+        // Get the Attributes.
+        cbData = sizeof(DWORD);
+        lStatus = RegQueryValueExW(hSubKey, L"Attributes", NULL, NULL, (PBYTE)&pPrinter->dwAttributes, &cbData);
+        if (lStatus != ERROR_SUCCESS)
+        {
+            ERR("Couldn't query Attributes for Printer \"%S\", status is %ld!\n", wszPrinterName, lStatus);
+            continue;
+        }
+
+        // Get the Status.
+        cbData = sizeof(DWORD);
+        lStatus = RegQueryValueExW(hSubKey, L"Status", NULL, NULL, (PBYTE)&pPrinter->dwStatus, &cbData);
+        if (lStatus != ERROR_SUCCESS)
+        {
+            ERR("Couldn't query Status for Printer \"%S\", status is %ld!\n", wszPrinterName, lStatus);
             continue;
         }
 
@@ -223,7 +241,7 @@ Cleanup:
 }
 
 
-BOOL
+DWORD
 _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
     const WCHAR wszComma[] = L",";
@@ -232,6 +250,7 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
     DWORD cbComment;
     DWORD cbDescription;
     DWORD cchComputerName = 0;
+    DWORD dwErrorCode;
     DWORD i;
     PBYTE pPrinterInfo;
     PBYTE pPrinterString;
@@ -263,8 +282,9 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
                 cchComputerName = MAX_COMPUTERNAME_LENGTH + 1;
                 if (!GetComputerNameW(&wszComputerName[2], &cchComputerName))
                 {
-                    ERR("GetComputerNameW failed with error %lu!\n", GetLastError());
-                    return FALSE;
+                    dwErrorCode = GetLastError();
+                    ERR("GetComputerNameW failed with error %lu!\n", dwErrorCode);
+                    goto Cleanup;
                 }
 
                 // Add the leading slashes to the total length.
@@ -273,8 +293,8 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
                 // Now compare this with the local computer name and reject if it doesn't match.
                 if (wcsicmp(&Name[2], &wszComputerName[2]) != 0)
                 {
-                    SetLastError(ERROR_INVALID_NAME);
-                    return FALSE;
+                    dwErrorCode = ERROR_INVALID_NAME;
+                    goto Cleanup;
                 }
 
                 // Add a trailing backslash to wszComputerName, which will later be prepended in front of the printer names.
@@ -284,8 +304,8 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
             else if (wcsicmp(Name, wszPrintProviderInfo[0]) != 0)
             {
                 // The user supplied a name that cannot be processed by the local print provider.
-                SetLastError(ERROR_INVALID_NAME);
-                return FALSE;
+                dwErrorCode = ERROR_INVALID_NAME;
+                goto Cleanup;
             }
         }
         else
@@ -302,14 +322,15 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
             // Check if the supplied buffer is large enough.
             if (cbBuf < *pcbNeeded)
             {
-                SetLastError(ERROR_INSUFFICIENT_BUFFER);
-                return FALSE;
+                dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
+                goto Cleanup;
             }
 
             // Copy over the print processor information.
             ((PPRINTER_INFO_1W)pPrinterEnum)->Flags = 0;
             PackStrings(wszPrintProviderInfo, pPrinterEnum, dwOffsets, &pPrinterEnum[*pcbNeeded]);
-            return TRUE;
+            dwErrorCode = ERROR_SUCCESS;
+            goto Cleanup;
         }
     }
 
@@ -332,8 +353,8 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
     // Check if the supplied buffer is large enough.
     if (cbBuf < *pcbNeeded)
     {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
+        dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
+        goto Cleanup;
     }
 
     // Put the strings right after the last PRINTER_INFO_1W structure.
@@ -381,12 +402,17 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
         pPrinterInfo += sizeof(PRINTER_INFO_1W);
     }
 
-    return TRUE;
+    dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+    return dwErrorCode;
 }
 
 BOOL WINAPI
 LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
+    DWORD dwErrorCode;
+
     // Do no sanity checks here. This is verified by localspl_apitest!
 
     // Begin counting.
@@ -394,30 +420,36 @@ LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DW
     *pcReturned = 0;
 
     // Think positive :)
-    SetLastError(ERROR_SUCCESS);
+    // Treat it as success if the caller queried no information and we don't need to return any.
+    dwErrorCode = ERROR_SUCCESS;
 
     if (Flags & PRINTER_ENUM_LOCAL)
     {
         // The function behaves quite differently for each level.
         if (Level == 1)
-            return _LocalEnumPrintersLevel1(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
-
-        // TODO: Handle other levels.
-
-        // The caller supplied an invalid level.
-        return FALSE;
+        {
+            dwErrorCode = _LocalEnumPrintersLevel1(Flags, Name, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
+        }
+        else
+        {
+            // TODO: Handle other levels.
+            // The caller supplied an invalid level.
+            dwErrorCode = ERROR_INVALID_LEVEL;
+            goto Cleanup;
+        }
     }
 
-    // Treat it as success if the caller queried no information and we don't need to return any.
-    return TRUE;
+Cleanup:
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
 
 BOOL WINAPI
 LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDefault)
 {
-    BOOL bReturnValue = ROUTER_UNKNOWN;
     DWORD cchComputerName;
     DWORD cchPrinterName;
+    DWORD dwErrorCode;
     DWORD dwJobID;
     PWSTR p = lpPrinterName;
     PWSTR pwszPrinterName = NULL;
@@ -430,7 +462,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
     // Sanity checks
     if (!lpPrinterName || !phPrinter)
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
+        dwErrorCode = ERROR_INVALID_PARAMETER;
         goto Cleanup;
     }
 
@@ -445,7 +477,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
         if (!p)
         {
             // We didn't get a proper server name.
-            SetLastError(ERROR_INVALID_PRINTER_NAME);
+            dwErrorCode = ERROR_INVALID_PRINTER_NAME;
             goto Cleanup;
         }
 
@@ -456,14 +488,15 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
         cchComputerName = _countof(wszComputerName);
         if (!GetComputerNameW(wszComputerName, &cchComputerName))
         {
-            ERR("GetComputerNameW failed with error %lu!\n", GetLastError());
+            dwErrorCode = GetLastError();
+            ERR("GetComputerNameW failed with error %lu!\n", dwErrorCode);
             goto Cleanup;
         }
 
         // Now compare this with the local computer name and reject if it doesn't match, because this print provider only supports local printers.
         if (wcsicmp(lpPrinterName, wszComputerName) != 0)
         {
-            SetLastError(ERROR_INVALID_PRINTER_NAME);
+            dwErrorCode = ERROR_INVALID_PRINTER_NAME;
             goto Cleanup;
         }
 
@@ -481,7 +514,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
     // No printer name and no comma? This is invalid!
     if (!cchPrinterName && !p)
     {
-        SetLastError(ERROR_INVALID_PRINTER_NAME);
+        dwErrorCode = ERROR_INVALID_PRINTER_NAME;
         goto Cleanup;
     }
 
@@ -498,7 +531,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
         if (!pPrinter)
         {
             // The printer does not exist.
-            SetLastError(ERROR_INVALID_PRINTER_NAME);
+            dwErrorCode = ERROR_INVALID_PRINTER_NAME;
             goto Cleanup;
         }
 
@@ -512,7 +545,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
             // Use the datatype if it's valid.
             if (!FindDatatype(pPrinter->pPrintProcessor, pDefault->pDatatype))
             {
-                SetLastError(ERROR_INVALID_DATATYPE);
+                dwErrorCode = ERROR_INVALID_DATATYPE;
                 goto Cleanup;
             }
 
@@ -545,7 +578,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
             // The "Job " string has to follow now.
             if (wcscmp(p, L"Job ") != 0)
             {
-                SetLastError(ERROR_INVALID_PRINTER_NAME);
+                dwErrorCode = ERROR_INVALID_PRINTER_NAME;
                 goto Cleanup;
             }
 
@@ -561,7 +594,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
             if (!IS_VALID_JOB_ID(dwJobID))
             {
                 // The user supplied an invalid Job ID.
-                SetLastError(ERROR_INVALID_PRINTER_NAME);
+                dwErrorCode = ERROR_INVALID_PRINTER_NAME;
                 goto Cleanup;
             }
 
@@ -570,7 +603,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
             if (!pJob || pJob->Printer != pPrinter)
             {
                 // The user supplied a non-existing Job ID or the Job ID does not belong to the supplied printer name.
-                SetLastError(ERROR_INVALID_PRINTER_NAME);
+                dwErrorCode = ERROR_INVALID_PRINTER_NAME;
                 goto Cleanup;
             }
 
@@ -618,13 +651,13 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
         }
         else
         {
-            SetLastError(ERROR_INVALID_PRINTER_NAME);
+            dwErrorCode = ERROR_INVALID_PRINTER_NAME;
             goto Cleanup;
         }
     }
 
     *phPrinter = (HANDLE)pHandle;
-    bReturnValue = ROUTER_SUCCESS;
+    dwErrorCode = ERROR_SUCCESS;
 
     // Don't let the cleanup routines free this.
     pPrinterHandle = NULL;
@@ -642,12 +675,15 @@ Cleanup:
     if (pwszPrinterName)
         DllFreeSplMem(pwszPrinterName);
 
-    return bReturnValue;
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
 
 DWORD WINAPI
 LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
 {
+    DWORD dwErrorCode;
+    DWORD dwReturnValue = 0;
     PDOC_INFO_1W pDocumentInfo1;
     PLOCAL_HANDLE pHandle;
     PLOCAL_JOB pJob;
@@ -656,22 +692,22 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
     // Sanity checks
     if (!pDocInfo)
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return 0;
+        dwErrorCode = ERROR_INVALID_PARAMETER;
+        goto Cleanup;
     }
 
     if (!hPrinter)
     {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return 0;
+        dwErrorCode = ERROR_INVALID_HANDLE;
+        goto Cleanup;
     }
 
     // Check if this is a printer handle.
     pHandle = (PLOCAL_HANDLE)hPrinter;
     if (pHandle->HandleType != Printer)
     {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return 0;
+        dwErrorCode = ERROR_INVALID_HANDLE;
+        goto Cleanup;
     }
 
     pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->SpecificHandle;
@@ -679,8 +715,8 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
     // Check if this is the right document information level.
     if (Level != 1)
     {
-        SetLastError(ERROR_INVALID_LEVEL);
-        return 0;
+        dwErrorCode = ERROR_INVALID_LEVEL;
+        goto Cleanup;
     }
 
     pDocumentInfo1 = (PDOC_INFO_1W)pDocInfo;
@@ -696,8 +732,8 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
         // Use the datatype if it's valid.
         if (!FindDatatype(pJob->Printer->pPrintProcessor, pDocumentInfo1->pDatatype))
         {
-            SetLastError(ERROR_INVALID_DATATYPE);
-            return 0;
+            dwErrorCode = ERROR_INVALID_DATATYPE;
+            goto Cleanup;
         }
 
         pJob->pwszDatatype = AllocSplStr(pDocumentInfo1->pDatatype);
@@ -720,25 +756,35 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
 
     // Get an ID for the new job.
     if (!GetNextJobID(&pJob->dwJobID))
-        return 0;
+    {
+        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+        goto Cleanup;
+    }
 
     // Add the job to the Global Job List.
     if (!InsertElementSkiplist(&GlobalJobList, pJob))
     {
+        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
         ERR("InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->dwJobID);
-        return 0;
+        goto Cleanup;
     }
 
     // Add the job at the end of the Printer's Job List.
     // As all new jobs are created with default priority, we can be sure that it would always be inserted at the end.
     if (!InsertTailElementSkiplist(&pJob->Printer->JobList, pJob))
     {
+        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
         ERR("InsertTailElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->dwJobID);
-        return 0;
+        goto Cleanup;
     }
 
     pPrinterHandle->StartedJob = pJob;
-    return pJob->dwJobID;
+    dwErrorCode = ERROR_SUCCESS;
+    dwReturnValue = pJob->dwJobID;
+
+Cleanup:
+    SetLastError(dwErrorCode);
+    return dwReturnValue;
 }
 
 BOOL WINAPI
index a8b9a89..ac9e546 100644 (file)
@@ -24,18 +24,16 @@ static LIST_ENTRY _PrintProcessorList;
  * You can use it for further tasks and have to close it with RegCloseKey.
  *
  * @return
- * TRUE if the environment is valid and a registry key was opened, FALSE otherwise.
- * In case of failure, Last Error will be set to ERROR_INVALID_ENVIRONMENT.
+ * A Windows Error Code indicating success or failure.
  */
-static BOOL
+static DWORD
 _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
 {
     const WCHAR wszEnvironmentsKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Environments\\";
     const DWORD cchEnvironmentsKey = _countof(wszEnvironmentsKey) - 1;
 
-    BOOL bReturnValue = FALSE;
     DWORD cchEnvironment;
-    LONG lStatus;
+    DWORD dwErrorCode;
     PWSTR pwszEnvironmentKey = NULL;
 
     // Use the current environment if none was supplied.
@@ -55,25 +53,23 @@ _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
     CopyMemory(&pwszEnvironmentKey[cchEnvironmentsKey], pEnvironment, (cchEnvironment + 1) * sizeof(WCHAR));
 
     // Open the registry key.
-    lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszEnvironmentKey, 0, KEY_READ, hKey);
-    if (lStatus == ERROR_FILE_NOT_FOUND)
+    dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszEnvironmentKey, 0, KEY_READ, hKey);
+    if (dwErrorCode == ERROR_FILE_NOT_FOUND)
     {
-        SetLastError(ERROR_INVALID_ENVIRONMENT);
+        dwErrorCode = ERROR_INVALID_ENVIRONMENT;
         goto Cleanup;
     }
-    else if (lStatus != ERROR_SUCCESS)
+    else if (dwErrorCode != ERROR_SUCCESS)
     {
-        ERR("RegOpenKeyExW failed with status %ld!\n", lStatus);
+        ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
-    bReturnValue = TRUE;
-
 Cleanup:
     if (pwszEnvironmentKey)
         DllFreeSplMem(pwszEnvironmentKey);
 
-    return bReturnValue;
+    return dwErrorCode;
 }
 
 BOOL
@@ -146,7 +142,7 @@ InitializePrintProcessorList()
     wszPrintProcessorPath[cchPrintProcessorPath++] = L'\\';
 
     // Open the environment registry key.
-    if (!_OpenEnvironment(NULL, &hKey))
+    if (_OpenEnvironment(NULL, &hKey) != ERROR_SUCCESS)
         goto Cleanup;
 
     // Open the "Print Processors" subkey.
@@ -372,25 +368,33 @@ Cleanup:
 BOOL WINAPI
 LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
+    DWORD dwErrorCode;
     PLOCAL_PRINT_PROCESSOR pPrintProcessor;
 
     // Sanity checks
     if (Level != 1)
     {
-        SetLastError(ERROR_INVALID_LEVEL);
-        return FALSE;
+        dwErrorCode = ERROR_INVALID_LEVEL;
+        goto Cleanup;
     }
 
     // Try to find the Print Processor.
     pPrintProcessor = FindPrintProcessor(pPrintProcessorName);
     if (!pPrintProcessor)
     {
-        SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
-        return FALSE;
+        dwErrorCode = ERROR_UNKNOWN_PRINTPROCESSOR;
+        goto Cleanup;
     }
 
     // Call its EnumPrintProcessorDatatypesW function.
-    return pPrintProcessor->pfnEnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
+    if (pPrintProcessor->pfnEnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned))
+        dwErrorCode = ERROR_SUCCESS;
+    else
+        dwErrorCode = GetLastError();
+
+Cleanup:
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
 
 /**
@@ -431,13 +435,12 @@ LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD
 BOOL WINAPI
 LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
-    BOOL bReturnValue = FALSE;
     DWORD cchMaxSubKey;
     DWORD cchPrintProcessor;
+    DWORD dwErrorCode;
     DWORD i;
     HKEY hKey = NULL;
     HKEY hSubKey = NULL;
-    LONG lStatus;
     PBYTE pCurrentOutputPrintProcessor;
     PBYTE pCurrentOutputPrintProcessorInfo;
     PRINTPROCESSOR_INFO_1W PrintProcessorInfo1;
@@ -446,35 +449,36 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
     // Sanity checks
     if (Level != 1)
     {
-        SetLastError(ERROR_INVALID_LEVEL);
+        dwErrorCode = ERROR_INVALID_LEVEL;
         goto Cleanup;
     }
 
     if (!pcbNeeded || !pcReturned)
     {
-        // This error must be caught by RPC and returned as RPC_X_NULL_REF_POINTER.
-        ERR("pcbNeeded or pcReturned is NULL!\n");
+        // This error is also caught by RPC and returned as RPC_X_NULL_REF_POINTER.
+        dwErrorCode = ERROR_INVALID_PARAMETER;
         goto Cleanup;
     }
 
     // Verify pEnvironment and open its registry key.
     // We use the registry and not the PrintProcessorList here, because the caller may request information about a different environment.
-    if (!_OpenEnvironment(pEnvironment, &hKey))
+    dwErrorCode = _OpenEnvironment(pEnvironment, &hKey);
+    if (dwErrorCode != ERROR_SUCCESS)
         goto Cleanup;
 
     // Open the "Print Processors" subkey.
-    lStatus = RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ, &hSubKey);
-    if (lStatus != ERROR_SUCCESS)
+    dwErrorCode = (DWORD)RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ, &hSubKey);
+    if (dwErrorCode != ERROR_SUCCESS)
     {
-        ERR("RegOpenKeyExW failed with status %ld!\n", lStatus);
+        ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
     // Get the number of Print Processors and maximum sub key length.
-    lStatus = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, pcReturned, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
-    if (lStatus != ERROR_SUCCESS)
+    dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, pcReturned, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
+    if (dwErrorCode != ERROR_SUCCESS)
     {
-        ERR("RegQueryInfoKeyW failed with status %ld!\n", lStatus);
+        ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
@@ -482,6 +486,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
     pwszTemp = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
     if (!pwszTemp)
     {
+        dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
         ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
         goto Cleanup;
     }
@@ -494,10 +499,10 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
         // RegEnumKeyExW sucks! Unlike similar API functions, it only returns the actual numbers of characters copied when you supply a buffer large enough.
         // So use pwszTemp with its size cchMaxSubKey for this.
         cchPrintProcessor = cchMaxSubKey;
-        lStatus = RegEnumKeyExW(hSubKey, i, pwszTemp, &cchPrintProcessor, NULL, NULL, NULL, NULL);
-        if (lStatus != ERROR_SUCCESS)
+        dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, pwszTemp, &cchPrintProcessor, NULL, NULL, NULL, NULL);
+        if (dwErrorCode != ERROR_SUCCESS)
         {
-            ERR("RegEnumKeyExW failed with status %ld!\n", lStatus);
+            ERR("RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
             goto Cleanup;
         }
 
@@ -507,7 +512,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
     // Check if the supplied buffer is large enough.
     if (cbBuf < *pcbNeeded)
     {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
         goto Cleanup;
     }
 
@@ -522,10 +527,10 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
         cchPrintProcessor = cchMaxSubKey;
 
         // Copy the Print Processor name.
-        lStatus = RegEnumKeyExW(hSubKey, i, (PWSTR)pCurrentOutputPrintProcessor, &cchPrintProcessor, NULL, NULL, NULL, NULL);
-        if (lStatus != ERROR_SUCCESS)
+        dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, (PWSTR)pCurrentOutputPrintProcessor, &cchPrintProcessor, NULL, NULL, NULL, NULL);
+        if (dwErrorCode != ERROR_SUCCESS)
         {
-            ERR("RegEnumKeyExW failed with status %ld!\n", lStatus);
+            ERR("RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
             goto Cleanup;
         }
 
@@ -539,8 +544,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
     }
 
     // We've finished successfully!
-    SetLastError(ERROR_SUCCESS);
-    bReturnValue = TRUE;
+    dwErrorCode = ERROR_SUCCESS;
 
 Cleanup:
     if (pwszTemp)
@@ -552,7 +556,8 @@ Cleanup:
     if (hKey)
         RegCloseKey(hKey);
 
-    return bReturnValue;
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }
 
 /**
@@ -592,34 +597,34 @@ LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
     const WCHAR wszPath[] = L"\\PRTPROCS\\";
     const DWORD cchPath = _countof(wszPath) - 1;
 
-    BOOL bReturnValue = FALSE;
     DWORD cbDataWritten;
+    DWORD dwErrorCode;
     HKEY hKey = NULL;
-    LONG lStatus;
 
     // Sanity checks
     if (Level != 1)
     {
-        SetLastError(ERROR_INVALID_LEVEL);
+        dwErrorCode = ERROR_INVALID_LEVEL;
         goto Cleanup;
     }
 
     if (!pcbNeeded)
     {
-        // This error must be caught by RPC and returned as RPC_X_NULL_REF_POINTER.
-        ERR("pcbNeeded is NULL!\n");
+        // This error is also caught by RPC and returned as RPC_X_NULL_REF_POINTER.
+        dwErrorCode = ERROR_INVALID_PARAMETER;
         goto Cleanup;
     }
 
     // Verify pEnvironment and open its registry key.
-    if (!_OpenEnvironment(pEnvironment, &hKey))
+    dwErrorCode = _OpenEnvironment(pEnvironment, &hKey);
+    if (dwErrorCode != ERROR_SUCCESS)
         goto Cleanup;
 
     // Determine the size of the required buffer.
-    lStatus = RegQueryValueExW(hKey, L"Directory", NULL, NULL, NULL, pcbNeeded);
-    if (lStatus != ERROR_SUCCESS)
+    dwErrorCode = (DWORD)RegQueryValueExW(hKey, L"Directory", NULL, NULL, NULL, pcbNeeded);
+    if (dwErrorCode != ERROR_SUCCESS)
     {
-        ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
+        ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
@@ -629,7 +634,7 @@ LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
     // Is the supplied buffer large enough?
     if (cbBuf < *pcbNeeded)
     {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
         goto Cleanup;
     }
 
@@ -638,20 +643,20 @@ LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
     CopyMemory(&pPrintProcessorInfo[cchSpoolDirectory], wszPath, cchPath * sizeof(WCHAR));
 
     // Get the directory name from the registry.
-    lStatus = RegQueryValueExW(hKey, L"Directory", NULL, NULL, &pPrintProcessorInfo[cchSpoolDirectory + cchPath], &cbDataWritten);
-    if (lStatus != ERROR_SUCCESS)
+    dwErrorCode = (DWORD)RegQueryValueExW(hKey, L"Directory", NULL, NULL, &pPrintProcessorInfo[cchSpoolDirectory + cchPath], &cbDataWritten);
+    if (dwErrorCode != ERROR_SUCCESS)
     {
-        ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
+        ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
         goto Cleanup;
     }
 
     // We've finished successfully!
-    SetLastError(ERROR_SUCCESS);
-    bReturnValue = TRUE;
+    dwErrorCode = ERROR_SUCCESS;
 
 Cleanup:
     if (hKey)
         RegCloseKey(hKey);
 
-    return bReturnValue;
+    SetLastError(dwErrorCode);
+    return (dwErrorCode == ERROR_SUCCESS);
 }