mirror of
https://github.com/reactos/reactos.git
synced 2025-07-27 11:03:37 +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)
|
EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||||
{
|
{
|
||||||
DWORD cbDatatype;
|
DWORD cbDatatype;
|
||||||
|
DWORD dwDatatypeCount = 0;
|
||||||
DWORD dwErrorCode;
|
DWORD dwErrorCode;
|
||||||
DWORD dwOffsets[_countof(_pwszDatatypes)];
|
DWORD dwOffsets[_countof(_pwszDatatypes)];
|
||||||
PCWSTR* pCurrentDatatype;
|
PCWSTR* pCurrentDatatype;
|
||||||
|
@ -129,9 +130,9 @@ EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Lev
|
||||||
*pcbNeeded += sizeof(DATATYPES_INFO_1W) + cbDatatype;
|
*pcbNeeded += sizeof(DATATYPES_INFO_1W) + cbDatatype;
|
||||||
|
|
||||||
// Also calculate the offset in the output buffer of the pointer to this datatype string.
|
// 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++;
|
pCurrentOffset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Lev
|
||||||
*pCurrentOffset = MAXDWORD;
|
*pCurrentOffset = MAXDWORD;
|
||||||
PackStrings(_pwszDatatypes, pDatatypes, dwOffsets, &pDatatypes[*pcbNeeded]);
|
PackStrings(_pwszDatatypes, pDatatypes, dwOffsets, &pDatatypes[*pcbNeeded]);
|
||||||
|
|
||||||
|
*pcReturned = dwDatatypeCount;
|
||||||
dwErrorCode = ERROR_SUCCESS;
|
dwErrorCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
|
|
@ -898,6 +898,7 @@ BOOL WINAPI
|
||||||
LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||||
{
|
{
|
||||||
DWORD dwErrorCode;
|
DWORD dwErrorCode;
|
||||||
|
DWORD i;
|
||||||
PBYTE pEnd = &pStart[cbBuf];
|
PBYTE pEnd = &pStart[cbBuf];
|
||||||
PLOCAL_HANDLE pHandle;
|
PLOCAL_HANDLE pHandle;
|
||||||
PLOCAL_JOB pJob;
|
PLOCAL_JOB pJob;
|
||||||
|
@ -930,9 +931,10 @@ LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE
|
||||||
pFirstJobNode = LookupNodeByIndexSkiplist(&pPrinterHandle->pPrinter->JobList, FirstJob);
|
pFirstJobNode = LookupNodeByIndexSkiplist(&pPrinterHandle->pPrinter->JobList, FirstJob);
|
||||||
|
|
||||||
// Count the required buffer size and the number of jobs.
|
// Count the required buffer size and the number of jobs.
|
||||||
|
i = 0;
|
||||||
pNode = pFirstJobNode;
|
pNode = pFirstJobNode;
|
||||||
|
|
||||||
while (*pcReturned < NoJobs && pNode)
|
while (i < NoJobs && pNode)
|
||||||
{
|
{
|
||||||
pJob = (PLOCAL_JOB)pNode->Element;
|
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);
|
_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.
|
// 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];
|
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.
|
// Begin counting again and also empty the given buffer.
|
||||||
*pcbNeeded = 0;
|
*pcbNeeded = 0;
|
||||||
*pcReturned = 0;
|
|
||||||
ZeroMemory(pStart, cbBuf);
|
ZeroMemory(pStart, cbBuf);
|
||||||
|
|
||||||
// Now call the same functions again to copy the actual data for each job into the buffer.
|
// Now call the same functions again to copy the actual data for each job into the buffer.
|
||||||
|
i = 0;
|
||||||
pNode = pFirstJobNode;
|
pNode = pFirstJobNode;
|
||||||
|
|
||||||
while (*pcReturned < NoJobs && pNode)
|
while (i < NoJobs && pNode)
|
||||||
{
|
{
|
||||||
pJob = (PLOCAL_JOB)pNode->Element;
|
pJob = (PLOCAL_JOB)pNode->Element;
|
||||||
|
|
||||||
|
@ -976,10 +978,11 @@ LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE
|
||||||
goto Cleanup;
|
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.
|
// 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];
|
pNode = pNode->Next[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*pcReturned = i;
|
||||||
dwErrorCode = ERROR_SUCCESS;
|
dwErrorCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
|
|
@ -317,8 +317,6 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
*pcbNeeded += (wcslen(wszPrintProviderInfo[i]) + 1) * sizeof(WCHAR);
|
*pcbNeeded += (wcslen(wszPrintProviderInfo[i]) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
*pcReturned = 1;
|
|
||||||
|
|
||||||
// Check if the supplied buffer is large enough.
|
// Check if the supplied buffer is large enough.
|
||||||
if (cbBuf < *pcbNeeded)
|
if (cbBuf < *pcbNeeded)
|
||||||
{
|
{
|
||||||
|
@ -329,12 +327,15 @@ _LocalEnumPrintersLevel1(DWORD Flags, LPWSTR Name, LPBYTE pPrinterEnum, DWORD cb
|
||||||
// Copy over the print processor information.
|
// Copy over the print processor information.
|
||||||
((PPRINTER_INFO_1W)pPrinterEnum)->Flags = 0;
|
((PPRINTER_INFO_1W)pPrinterEnum)->Flags = 0;
|
||||||
PackStrings(wszPrintProviderInfo, pPrinterEnum, dwOffsets, &pPrinterEnum[*pcbNeeded]);
|
PackStrings(wszPrintProviderInfo, pPrinterEnum, dwOffsets, &pPrinterEnum[*pcbNeeded]);
|
||||||
|
*pcReturned = 1;
|
||||||
dwErrorCode = ERROR_SUCCESS;
|
dwErrorCode = ERROR_SUCCESS;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the required buffer size and the number of printers.
|
// Count the required buffer size and the number of printers.
|
||||||
|
i = 0;
|
||||||
|
|
||||||
for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
|
for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
|
||||||
{
|
{
|
||||||
pPrinter = (PLOCAL_PRINTER)pNode->Element;
|
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);
|
cbDescription = cchComputerName * sizeof(WCHAR) + cbName + cbComment + sizeof(WCHAR);
|
||||||
|
|
||||||
*pcbNeeded += sizeof(PRINTER_INFO_1W) + cchComputerName * sizeof(WCHAR) + cbName + cbComment + cbDescription;
|
*pcbNeeded += sizeof(PRINTER_INFO_1W) + cchComputerName * sizeof(WCHAR) + cbName + cbComment + cbDescription;
|
||||||
(*pcReturned)++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the supplied buffer is large enough.
|
// 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.
|
// 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 :(
|
// Due to all the required string processing, we can't just use PackStrings here :(
|
||||||
pPrinterInfo = pPrinterEnum;
|
pPrinterInfo = pPrinterEnum;
|
||||||
pPrinterString = pPrinterEnum + *pcReturned * sizeof(PRINTER_INFO_1W);
|
pPrinterString = pPrinterEnum + i * sizeof(PRINTER_INFO_1W);
|
||||||
|
|
||||||
// Copy over the printer information.
|
// Copy over the printer information.
|
||||||
for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
|
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);
|
pPrinterInfo += sizeof(PRINTER_INFO_1W);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*pcReturned = i;
|
||||||
dwErrorCode = ERROR_SUCCESS;
|
dwErrorCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
|
|
@ -438,6 +438,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
|
||||||
DWORD cchMaxSubKey;
|
DWORD cchMaxSubKey;
|
||||||
DWORD cchPrintProcessor;
|
DWORD cchPrintProcessor;
|
||||||
DWORD dwErrorCode;
|
DWORD dwErrorCode;
|
||||||
|
DWORD dwPrintProcessorCount;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
HKEY hKey = NULL;
|
HKEY hKey = NULL;
|
||||||
HKEY hSubKey = 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.
|
// 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)
|
if (dwErrorCode != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
|
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.
|
// Determine the required size of the output buffer.
|
||||||
*pcbNeeded = 0;
|
*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.
|
// 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.
|
// 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.
|
// Put the Print Processor strings right after the last PRINTPROCESSOR_INFO_1W structure.
|
||||||
pCurrentOutputPrintProcessorInfo = pPrintProcessorInfo;
|
pCurrentOutputPrintProcessorInfo = pPrintProcessorInfo;
|
||||||
pCurrentOutputPrintProcessor = pPrintProcessorInfo + *pcReturned * sizeof(PRINTPROCESSOR_INFO_1W);
|
pCurrentOutputPrintProcessor = pPrintProcessorInfo + dwPrintProcessorCount * sizeof(PRINTPROCESSOR_INFO_1W);
|
||||||
|
|
||||||
// Copy over all Print Processors.
|
// 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.
|
// 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;
|
cchPrintProcessor = cchMaxSubKey + 1;
|
||||||
|
@ -544,6 +545,7 @@ LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've finished successfully!
|
// We've finished successfully!
|
||||||
|
*pcReturned = dwPrintProcessorCount;
|
||||||
dwErrorCode = ERROR_SUCCESS;
|
dwErrorCode = ERROR_SUCCESS;
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue