[LOCALSPL, WINPRINT]
authorColin Finck <colin@reactos.org>
Fri, 3 Jul 2015 09:06:35 +0000 (09:06 +0000)
committerColin Finck <colin@reactos.org>
Fri, 3 Jul 2015 09:06:35 +0000 (09:06 +0000)
Bugfix: All functions returning multiple elements must only set *pcReturned to the element count on success!
Currently, this was also done when querying the needed buffer size. But for this case, *pcReturned just has to be zeroed.

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

reactos/win32ss/printing/processors/winprint/main.c
reactos/win32ss/printing/providers/localspl/jobs.c
reactos/win32ss/printing/providers/localspl/printers.c
reactos/win32ss/printing/providers/localspl/printprocessors.c

index 4e733e9..6169f4f 100644 (file)
@@ -107,6 +107,7 @@ BOOL WINAPI
 EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
     DWORD cbDatatype;
+    DWORD dwDatatypeCount = 0;
     DWORD dwErrorCode;
     DWORD dwOffsets[_countof(_pwszDatatypes)];
     PCWSTR* pCurrentDatatype;
@@ -129,9 +130,9 @@ EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Lev
         *pcbNeeded += sizeof(DATATYPES_INFO_1W) + cbDatatype;
 
         // Also calculate the offset in the output buffer of the pointer to this datatype string.
-        *pCurrentOffset = *pcReturned * sizeof(DATATYPES_INFO_1W) + FIELD_OFFSET(DATATYPES_INFO_1W, pName);
+        *pCurrentOffset = dwDatatypeCount * sizeof(DATATYPES_INFO_1W) + FIELD_OFFSET(DATATYPES_INFO_1W, pName);
 
-        (*pcReturned)++;
+        dwDatatypeCount++;
         pCurrentOffset++;
     }
 
@@ -153,6 +154,7 @@ EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Lev
     *pCurrentOffset = MAXDWORD;
     PackStrings(_pwszDatatypes, pDatatypes, dwOffsets, &pDatatypes[*pcbNeeded]);
 
+    *pcReturned = dwDatatypeCount;
     dwErrorCode = ERROR_SUCCESS;
 
 Cleanup:
index 98b9e7d..35291ac 100644 (file)
@@ -898,6 +898,7 @@ BOOL WINAPI
 LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
     DWORD dwErrorCode;
+    DWORD i;
     PBYTE pEnd = &pStart[cbBuf];
     PLOCAL_HANDLE pHandle;
     PLOCAL_JOB pJob;
@@ -930,9 +931,10 @@ LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE
     pFirstJobNode = LookupNodeByIndexSkiplist(&pPrinterHandle->pPrinter->JobList, FirstJob);
 
     // Count the required buffer size and the number of jobs.
+    i = 0;
     pNode = pFirstJobNode;
 
-    while (*pcReturned < NoJobs && pNode)
+    while (i < NoJobs && pNode)
     {
         pJob = (PLOCAL_JOB)pNode->Element;
 
@@ -943,7 +945,7 @@ LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE
             _LocalGetJobLevel2(pPrinterHandle, pJob, NULL, NULL, 0, pcbNeeded);
 
         // We stop either when there are no more jobs in the list or when the caller didn't request more, whatever comes first.
-        (*pcReturned)++;
+        i++;
         pNode = pNode->Next[0];
     }
 
@@ -956,13 +958,13 @@ LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE
 
     // Begin counting again and also empty the given buffer.
     *pcbNeeded = 0;
-    *pcReturned = 0;
     ZeroMemory(pStart, cbBuf);
 
     // Now call the same functions again to copy the actual data for each job into the buffer.
+    i = 0;
     pNode = pFirstJobNode;
 
-    while (*pcReturned < NoJobs && pNode)
+    while (i < NoJobs && pNode)
     {
         pJob = (PLOCAL_JOB)pNode->Element;
 
@@ -976,10 +978,11 @@ LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE
             goto Cleanup;
 
         // We stop either when there are no more jobs in the list or when the caller didn't request more, whatever comes first.
-        (*pcReturned)++;
+        i++;
         pNode = pNode->Next[0];
     }
 
+    *pcReturned = i;
     dwErrorCode = ERROR_SUCCESS;
 
 Cleanup:
index f937c2c..c7e89c5 100644 (file)
@@ -317,8 +317,6 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
             for (i = 0; i < 3; i++)
                 *pcbNeeded += (wcslen(wszPrintProviderInfo[i]) + 1) * sizeof(WCHAR);
 
-            *pcReturned = 1;
-
             // Check if the supplied buffer is large enough.
             if (cbBuf < *pcbNeeded)
             {
@@ -329,12 +327,15 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
             // Copy over the print processor information.
             ((PPRINTER_INFO_1W)pPrinterEnum)->Flags = 0;
             PackStrings(wszPrintProviderInfo, pPrinterEnum, dwOffsets, &pPrinterEnum[*pcbNeeded]);
+            *pcReturned = 1;
             dwErrorCode = ERROR_SUCCESS;
             goto Cleanup;
         }
     }
 
     // Count the required buffer size and the number of printers.
+    i = 0;
+
     for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
     {
         pPrinter = (PLOCAL_PRINTER)pNode->Element;
@@ -347,7 +348,7 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
         cbDescription = cchComputerName * sizeof(WCHAR) + cbName + cbComment + sizeof(WCHAR);
 
         *pcbNeeded += sizeof(PRINTER_INFO_1W) + cchComputerName * sizeof(WCHAR) + cbName + cbComment + cbDescription;
-        (*pcReturned)++;
+        i++;
     }
 
     // Check if the supplied buffer is large enough.
@@ -360,7 +361,7 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
     // Put the strings right after the last PRINTER_INFO_1W structure.
     // Due to all the required string processing, we can't just use PackStrings here :(
     pPrinterInfo = pPrinterEnum;
-    pPrinterString = pPrinterEnum + *pcReturned * sizeof(PRINTER_INFO_1W);
+    pPrinterString = pPrinterEnum + i * sizeof(PRINTER_INFO_1W);
 
     // Copy over the printer information.
     for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
@@ -402,6 +403,7 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
         pPrinterInfo += sizeof(PRINTER_INFO_1W);
     }
 
+    *pcReturned = i;
     dwErrorCode = ERROR_SUCCESS;
 
 Cleanup:
index 12dab40..9898598 100644 (file)
@@ -438,6 +438,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
     DWORD cchMaxSubKey;
     DWORD cchPrintProcessor;
     DWORD dwErrorCode;
+    DWORD dwPrintProcessorCount;
     DWORD i;
     HKEY hKey = NULL;
     HKEY hSubKey = NULL;
@@ -475,7 +476,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
     }
 
     // Get the number of Print Processors and maximum sub key length.
-    dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, pcReturned, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
+    dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwPrintProcessorCount, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
     if (dwErrorCode != ERROR_SUCCESS)
     {
         ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
@@ -494,7 +495,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
     // Determine the required size of the output buffer.
     *pcbNeeded = 0;
 
-    for (i = 0; i < *pcReturned; i++)
+    for (i = 0; i < dwPrintProcessorCount; i++)
     {
         // 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.
@@ -518,10 +519,10 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
 
     // Put the Print Processor strings right after the last PRINTPROCESSOR_INFO_1W structure.
     pCurrentOutputPrintProcessorInfo = pPrintProcessorInfo;
-    pCurrentOutputPrintProcessor = pPrintProcessorInfo + *pcReturned * sizeof(PRINTPROCESSOR_INFO_1W);
+    pCurrentOutputPrintProcessor = pPrintProcessorInfo + dwPrintProcessorCount * sizeof(PRINTPROCESSOR_INFO_1W);
 
     // Copy over all Print Processors.
-    for (i = 0; i < *pcReturned; i++)
+    for (i = 0; i < dwPrintProcessorCount; i++)
     {
         // This isn't really correct, but doesn't cause any harm, because we've extensively checked the size of the supplied buffer above.
         cchPrintProcessor = cchMaxSubKey + 1;
@@ -544,6 +545,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
     }
 
     // We've finished successfully!
+    *pcReturned = dwPrintProcessorCount;
     dwErrorCode = ERROR_SUCCESS;
 
 Cleanup: