You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
435 lines
12 KiB
435 lines
12 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
helper.c
|
|
|
|
Abstract:
|
|
|
|
Helper functions
|
|
|
|
Environment:
|
|
|
|
Windows NT printer drivers
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "lib.h"
|
|
|
|
VOID
|
|
VFreeParserInfo(
|
|
IN PPARSERINFO pParserInfo
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function frees and unload binary data
|
|
|
|
Arguments:
|
|
|
|
pParserInfo - Pointer to parser information
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
if (pParserInfo->pInfoHeader)
|
|
{
|
|
FreeBinaryData(pParserInfo->pInfoHeader);
|
|
pParserInfo->pInfoHeader = NULL;
|
|
}
|
|
|
|
if ( pParserInfo->pRawData)
|
|
{
|
|
UnloadRawBinaryData(pParserInfo->pRawData);
|
|
pParserInfo->pRawData = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
PUIINFO
|
|
PGetUIInfo(
|
|
IN HANDLE hPrinter,
|
|
IN PRAWBINARYDATA pRawData,
|
|
IN POPTSELECT pCombineOptions,
|
|
IN POPTSELECT pOptions,
|
|
OUT PPARSERINFO pParserInfo,
|
|
OUT PDWORD pdwFeatureCount
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function loads up the binary data and returns the pUIInfo
|
|
|
|
Arguments:
|
|
|
|
hPrinter - Identifies the printer in question
|
|
pRawData - Points to raw binary printer description data
|
|
pCombineOptions - Points to buffer to contain the combined options array
|
|
pParserInfo - Points to struct that contains pInfoHeader and pRawData
|
|
pdwFeatureCount - Retrieve the count of the features
|
|
|
|
Return Value:
|
|
|
|
Point to UIINFO struct
|
|
|
|
--*/
|
|
{
|
|
OPTSELECT DocOptions[MAX_PRINTER_OPTIONS], PrinterOptions[MAX_PRINTER_OPTIONS];
|
|
PINFOHEADER pInfoHeader = NULL;
|
|
PUIINFO pUIInfo = NULL;
|
|
|
|
ASSERT(pRawData != NULL);
|
|
|
|
if (pOptions == NULL)
|
|
{
|
|
if (! InitDefaultOptions(pRawData,
|
|
PrinterOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
MODE_PRINTER_STICKY))
|
|
goto getuiinfo_exit;
|
|
}
|
|
|
|
if (! InitDefaultOptions(pRawData,
|
|
DocOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
MODE_DOCUMENT_STICKY))
|
|
goto getuiinfo_exit;
|
|
|
|
//
|
|
// Combine doc sticky options with printer sticky items
|
|
//
|
|
|
|
CombineOptionArray(pRawData,
|
|
pCombineOptions,
|
|
MAX_COMBINED_OPTIONS,
|
|
DocOptions,
|
|
pOptions ? pOptions : PrinterOptions);
|
|
|
|
//
|
|
// Get an updated instance of printer description data
|
|
//
|
|
|
|
pInfoHeader = InitBinaryData(pRawData,
|
|
NULL,
|
|
pCombineOptions);
|
|
|
|
if (pInfoHeader == NULL)
|
|
{
|
|
ERR(("InitBinaryData failed\n"));
|
|
goto getuiinfo_exit;
|
|
}
|
|
|
|
pUIInfo = OFFSET_TO_POINTER(pInfoHeader, pInfoHeader->loUIInfoOffset);
|
|
|
|
if (pdwFeatureCount)
|
|
*pdwFeatureCount = pRawData->dwDocumentFeatures + pRawData->dwPrinterFeatures;
|
|
|
|
getuiinfo_exit:
|
|
|
|
//
|
|
// PGetUIInfo always use the passed in pRawData. We assign NULL to
|
|
// pParserInfo->pRawData, so VFreeParserInfo won't unload it.
|
|
//
|
|
|
|
pParserInfo->pRawData = NULL;
|
|
pParserInfo->pInfoHeader = pInfoHeader;
|
|
|
|
if (pUIInfo == NULL)
|
|
VFreeParserInfo(pParserInfo);
|
|
|
|
return pUIInfo;
|
|
}
|
|
|
|
PSTR
|
|
PstrConvertIndexToKeyword(
|
|
IN HANDLE hPrinter,
|
|
IN POPTSELECT pOptions,
|
|
IN PDWORD pdwKeywordSize,
|
|
IN PUIINFO pUIInfo,
|
|
IN POPTSELECT pCombineOptions,
|
|
IN DWORD dwFeatureCount
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function convert the indexed based pOptions array to
|
|
Feature.Option keywordname.
|
|
|
|
Arguments:
|
|
|
|
hPrinter - Identifies the printer in question
|
|
pOptions - Index based optionsarray (pPrinterData->aOptions)
|
|
pdwKeywordSize - Retrieve the size of the buffer to write to registry
|
|
pUIInfo - Pointer to UIINFO
|
|
pCombinedOptions - Pointer to the combined options
|
|
dwFeatureCount - Number of features in pCombinedOptions
|
|
|
|
Return Value:
|
|
|
|
Pointer to buffer containing Feature.Option keyword names
|
|
|
|
--*/
|
|
{
|
|
|
|
PFEATURE pFeature;
|
|
POPTION pOption;
|
|
PSTR pstrKeywordBuf, pstrEnd, pstrBufTop = NULL;
|
|
DWORD i;
|
|
PSTR pFeatureKeyword, pOptionKeyword;
|
|
BYTE ubNext, ubCurOptIndex;
|
|
|
|
if ((pCombineOptions && pUIInfo && dwFeatureCount) &&
|
|
(pUIInfo->dwMaxPrnKeywordSize) &&
|
|
(pFeature = PGetIndexedFeature(pUIInfo, 0)) &&
|
|
(pstrBufTop = pstrKeywordBuf = MemAllocZ( pUIInfo->dwMaxPrnKeywordSize )))
|
|
{
|
|
pstrEnd = pstrBufTop + pUIInfo->dwMaxPrnKeywordSize;
|
|
|
|
for (i = 0; i < dwFeatureCount; i++ , pFeature++)
|
|
{
|
|
if (pFeature && pFeature->dwFeatureType == FEATURETYPE_PRINTERPROPERTY)
|
|
{
|
|
pFeatureKeyword = OFFSET_TO_POINTER(pUIInfo->pubResourceData,
|
|
pFeature->loKeywordName);
|
|
ASSERT(pFeatureKeyword != NULL);
|
|
|
|
if (pFeatureKeyword != NULL)
|
|
{
|
|
StringCchCopyA(pstrKeywordBuf, pstrEnd - pstrKeywordBuf, pFeatureKeyword);
|
|
pstrKeywordBuf += strlen(pFeatureKeyword) + 1;
|
|
}
|
|
|
|
if ((pFeatureKeyword == NULL) || (pstrKeywordBuf >= pstrEnd))
|
|
{
|
|
ERR(("ConvertToKeyword, Feature failed"));
|
|
MemFree(pstrBufTop);
|
|
pstrBufTop = NULL;
|
|
goto converttokeyword_exit;
|
|
}
|
|
|
|
//
|
|
// Handle multiple selections
|
|
//
|
|
|
|
ubNext = (BYTE)i;
|
|
|
|
while (1)
|
|
{
|
|
if (ubNext == NULL_OPTSELECT )
|
|
break;
|
|
|
|
ubCurOptIndex = pCombineOptions[ubNext].ubCurOptIndex;
|
|
|
|
pOption = PGetIndexedOption(pUIInfo, pFeature,
|
|
ubCurOptIndex == OPTION_INDEX_ANY ?
|
|
0 : ubCurOptIndex);
|
|
|
|
ubNext = pCombineOptions[ubNext].ubNext;
|
|
|
|
ASSERT(pOption != NULL);
|
|
|
|
if (pOption == NULL)
|
|
break;
|
|
|
|
pOptionKeyword = OFFSET_TO_POINTER(pUIInfo->pubResourceData,
|
|
pOption->loKeywordName);
|
|
|
|
ASSERT(pOptionKeyword != NULL);
|
|
|
|
if (pOptionKeyword != NULL)
|
|
{
|
|
StringCchCopyA(pstrKeywordBuf, pstrEnd - pstrKeywordBuf, pOptionKeyword);
|
|
pstrKeywordBuf += strlen(pOptionKeyword) + 1;
|
|
}
|
|
|
|
if ((pOptionKeyword == NULL) || (pstrKeywordBuf >= pstrEnd))
|
|
{
|
|
ERR(("ConvertToKeyword, Option failed"));
|
|
MemFree(pstrBufTop);
|
|
pstrBufTop = NULL;
|
|
goto converttokeyword_exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// terminate the Feature.Option... with valid delimiter
|
|
//
|
|
|
|
*pstrKeywordBuf++ = END_OF_FEATURE;
|
|
|
|
if (pstrKeywordBuf >= pstrEnd)
|
|
{
|
|
ERR(("ConvertToKeyword, Over writing buffer"));
|
|
MemFree(pstrBufTop);
|
|
pstrBufTop = NULL;
|
|
goto converttokeyword_exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add 2 NULs termination for MULTI_SZ buffer
|
|
//
|
|
if ((pstrEnd - pstrKeywordBuf) < 2)
|
|
{
|
|
ERR(("ConvertToKeyword, Over writing buffer"));
|
|
MemFree(pstrBufTop);
|
|
pstrBufTop = NULL;
|
|
goto converttokeyword_exit;
|
|
}
|
|
|
|
*pstrKeywordBuf++ = NUL;
|
|
*pstrKeywordBuf++ = NUL;
|
|
|
|
if (pdwKeywordSize)
|
|
*pdwKeywordSize = (DWORD)(pstrKeywordBuf - pstrBufTop);
|
|
|
|
}
|
|
|
|
converttokeyword_exit:
|
|
|
|
return pstrBufTop;
|
|
|
|
}
|
|
|
|
VOID
|
|
VConvertKeywordToIndex(
|
|
IN HANDLE hPrinter,
|
|
IN PSTR pstrKeyword,
|
|
IN DWORD dwKeywordSize,
|
|
OUT POPTSELECT pOptions,
|
|
IN PRAWBINARYDATA pRawData,
|
|
IN PUIINFO pUIInfo,
|
|
IN POPTSELECT pCombineOptions,
|
|
IN DWORD dwFeatureCount
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
hPrinter - Identifies the printer in question
|
|
ptstrKeyword - Buffer containing Feature.Option keyword names
|
|
pOptions - Index based options array contain the conversion
|
|
pUIInfo - Pointer to UIINFO
|
|
pCombinedOptions - Pointer to the combined options
|
|
dwFeatureCount - Number of features in pCombinedOptions
|
|
|
|
|
|
Return Value:
|
|
|
|
None, if for some reasons we could not convert, we get the default.
|
|
|
|
--*/
|
|
|
|
{
|
|
PSTR pstrEnd = pstrKeyword + dwKeywordSize;
|
|
|
|
|
|
if (pCombineOptions && pUIInfo && dwFeatureCount)
|
|
{
|
|
|
|
CHAR achName[256];
|
|
BOOL abEnableOptions[MAX_PRINTER_OPTIONS];
|
|
PFEATURE pFeature;
|
|
POPTION pOption;
|
|
DWORD dwFeatureIndex, dwOptionIndex = OPTION_INDEX_ANY;
|
|
|
|
while (pstrKeyword < pstrEnd && *pstrKeyword != NUL)
|
|
{
|
|
ZeroMemory(abEnableOptions, sizeof(abEnableOptions));
|
|
|
|
//
|
|
// Get the feature keyword name
|
|
//
|
|
|
|
StringCchCopyA(achName, CCHOF(achName), pstrKeyword);
|
|
pstrKeyword += strlen(achName) + 1;
|
|
|
|
if (pstrKeyword >= pstrEnd)
|
|
{
|
|
ERR(("Feature: Over writing the allocated buffer \n"));
|
|
goto converttoindex_exit;
|
|
}
|
|
|
|
pFeature = PGetNamedFeature(pUIInfo,
|
|
achName,
|
|
&dwFeatureIndex);
|
|
|
|
if (pFeature == NULL)
|
|
{
|
|
//
|
|
// If we can't map the registry Feature name to a valid feature,
|
|
// we need to skip all the feature's option names in the registry.
|
|
//
|
|
|
|
while (*pstrKeyword != END_OF_FEATURE && pstrKeyword < pstrEnd)
|
|
pstrKeyword++;
|
|
|
|
pstrKeyword++;
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Handle multiple selection
|
|
//
|
|
|
|
while (pstrKeyword < pstrEnd && *pstrKeyword != END_OF_FEATURE)
|
|
{
|
|
StringCchCopyA(achName, CCHOF(achName), pstrKeyword);
|
|
pstrKeyword += strlen(achName) + 1;
|
|
|
|
if (pstrKeyword >= pstrEnd)
|
|
{
|
|
ERR(("Option: Over writing the allocated buffer \n"));
|
|
goto converttoindex_exit;
|
|
}
|
|
|
|
pOption = PGetNamedOption(pUIInfo,
|
|
pFeature,
|
|
achName,
|
|
&dwOptionIndex);
|
|
if (pOption)
|
|
abEnableOptions[dwOptionIndex] = TRUE;
|
|
}
|
|
|
|
if (dwOptionIndex != OPTION_INDEX_ANY)
|
|
ReconstructOptionArray(pRawData,
|
|
pCombineOptions,
|
|
MAX_COMBINED_OPTIONS,
|
|
dwFeatureIndex,
|
|
abEnableOptions);
|
|
|
|
//
|
|
// skip our delimiter to go to next feature
|
|
//
|
|
|
|
pstrKeyword++;
|
|
|
|
}
|
|
|
|
SeparateOptionArray(pRawData,
|
|
pCombineOptions,
|
|
pOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
MODE_PRINTER_STICKY);
|
|
}
|
|
|
|
converttoindex_exit:
|
|
|
|
return;
|
|
}
|
|
|