BOOL WINAPI
EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
{
- DATATYPES_INFO_1W DatatypesInfo1;
DWORD cbDatatype;
- PBYTE pCurrentOutputDatatype;
- PBYTE pCurrentOutputDatatypeInfo;
+ DWORD dwErrorCode;
+ DWORD dwOffsets[_countof(pwszDatatypes)];
PCWSTR* pCurrentDatatype;
+ PDWORD pCurrentOffset = dwOffsets;
// Sanity checks
if (Level != 1 || !pcbNeeded || !pcReturned)
{
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ dwErrorCode = ERROR_INVALID_PARAMETER;
+ goto Cleanup;
}
// Count the required buffer size and the number of datatypes.
{
cbDatatype = (wcslen(*pCurrentDatatype) + 1) * sizeof(WCHAR);
*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);
+
*pcReturned++;
+ pCurrentOffset++;
}
// 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 datatype strings right after the last DATATYPES_INFO_1W structure.
- pCurrentOutputDatatypeInfo = pDatatypes;
- pCurrentOutputDatatype = pDatatypes + *pcReturned * sizeof(DATATYPES_INFO_1W);
+ // Check if a buffer was supplied at all.
+ if (!pDatatypes)
+ {
+ dwErrorCode = ERROR_INVALID_PARAMETER;
+ goto Cleanup;
+ }
// Copy over all datatypes.
- for (pCurrentDatatype = pwszDatatypes; *pCurrentDatatype; pCurrentDatatype++)
- {
- // Copy the datatype string into the output buffer.
- cbDatatype = (wcslen(*pCurrentDatatype) + 1) * sizeof(WCHAR);
- CopyMemory(pCurrentOutputDatatype, *pCurrentDatatype, cbDatatype);
+ *pCurrentOffset = MAXDWORD;
+ PackStrings(pwszDatatypes, pDatatypes, dwOffsets, &pDatatypes[*pcbNeeded]);
- // Fill and copy the DATATYPES_INFO_1W structure belonging to this datatype.
- DatatypesInfo1.pName = (PWSTR)pCurrentOutputDatatype;
- CopyMemory(pCurrentOutputDatatypeInfo, &DatatypesInfo1, sizeof(DATATYPES_INFO_1W));
-
- // Advance to the next DATATYPES_INFO_1W location and string location in the output buffer.
- pCurrentOutputDatatype += cbDatatype;
- pCurrentOutputDatatypeInfo += sizeof(DATATYPES_INFO_1W);
- }
+ dwErrorCode = ERROR_SUCCESS;
- return TRUE;
+Cleanup:
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
}