mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 05:00:27 +00:00
[LOCALSPL, WINPRINT]
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
This commit is contained in:
parent
86dbf40cd1
commit
259a6572ae
4 changed files with 24 additions and 15 deletions
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue