Leaked source code of windows server 2003
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.
 
 
 
 
 
 

2804 lines
91 KiB

// Copyright (c) 1996-1999 Microsoft Corporation
/* snapshot.c - functions to produce a snapshot from
the multivalued GPD binary data.
History of Changes
10/28/98 --hsingh--
Added functions BgetLocFeaIndex() and BgetLocFeaOptIndex()
to support special processing for Feauture Locale if present
in the gpd.
Bug Report 231798
*/
#include "gpdparse.h"
#ifndef PARSERDLL
// ---- functions defined in snapshot.c ---- //
PINFOHEADER PINFOHDRcreateSnapshot(
PBYTE pubnRaw, // raw binary data. PSTATIC. BETA2
POPTSELECT poptsel // assume fully initialized
) ;
BOOL BinitOptionFields(
PBYTE pubDestOption, // ptr to some type of option structure.
PBYTE pubDestOptionEx, // option extra structure if any.
PBYTE pubnRaw, // raw binary data.
DWORD dwFea,
DWORD dwOpt,
POPTSELECT poptsel , // assume fully initialized
PINFOHEADER pInfoHdr, // used to access global structure.
BOOL bUpdate // if true only update selected fields.
) ;
BOOL BinitUIinfo(
PUIINFO pUIinfo ,
PBYTE pubnRaw, // PSTATIC. BETA2
POPTSELECT poptsel, // assume fully initialized
BOOL bUpdate // if true only update selected fields.
) ;
BOOL BinitFeatures(
PFEATURE pFeaturesDest,
PDFEATURE_OPTIONS pfoSrc,
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel, // assume fully initialized
BOOL bUpdate // if true only update selected fields.
) ;
BOOL BinitGlobals(
PGLOBALS pGlobals,
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel, // assume fully initialized
BOOL bUpdate // if true only update selected fields.
) ;
BOOL BinitCommandTable(
PDWORD pdwCmdTable, // dest array
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel // assume fully initialized
) ;
BOOL BinitRawData(
PRAWBINARYDATA pRawData, // contained in INFOHEADER.
PBYTE pubnRaw // Parser's raw binary data.
) ;
BOOL BinitGPDdriverInfo(
PGPDDRIVERINFO pGPDdriverInfo,
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel // assume fully initialized
) ;
BOOL BinitSequencedCmds(
PGPDDRIVERINFO pGPDdriverInfo,
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel // assume fully initialized
) ;
BOOL BaddSequencedCmdToList(
DWORD dwCmdIn, // index of a command in CommandArray
PGPDDRIVERINFO pGPDdriverInfo,
DWORD dwNewListNode, // an unused listnode to add to the list.
PBYTE pubnRaw // raw binary data.
) ;
BinitDefaultOptionArray(
POPTSELECT poptsel, // assume is large enough
PBYTE pubnRaw) ;
TRISTATUS EdetermineDefaultOption(
PBYTE pubnRaw, // start of Rawbinary data
DWORD dwFeature, // determine the default for this feature
PDFEATURE_OPTIONS pfo,
POPTSELECT poptsel, // assume is large enough
PDWORD pdwPriority) ;
VOID VtileDefault(
PBYTE pubDest,
DWORD dwDefault,
DWORD dwBytes) ;
VOID VtransferValue(
OUT PBYTE pubDest,
IN PBYTE pubSrc ,
IN DWORD dwBytes,
IN DWORD dwFlags,
IN DWORD dwDefaultValue, // holds bit flag value.
IN PBYTE pubHeap ) ; // used to form ptr if SSF_MAKE_STRINGPTR
BOOL BspecialProcessOption(
PBYTE pubnRaw, // start of Rawbinary data
PBYTE pubDestOption, // ptr to some type of option structure.
PBYTE pubDestOptionEx,
PDFEATURE_OPTIONS pfo , // source data
IN POPTSELECT poptsel, // option array which determines path
// through atr.
PINFOHEADER pInfoHdr, // used to access global structure.
DWORD dwFea, // feature index
DWORD dwOpt,
BOOL bDefaultOpt
) ;
TRISTATUS EextractValueFromTree(
PBYTE pubnRaw, // start of Rawbinary data
DWORD dwSSTableIndex, // some info about this value.
OUT PBYTE pubDest, // write value or link here
OUT PDWORD pdwUnresolvedFeature, // if the attribute tree has
// a dependency on this feature and the current option
// for that feature is not defined in poptsel, this
// function will write the index of the required
// feature in pdwUnresolvedFeature.
IN ATREEREF atrRoot, // root of attribute tree to navigate.
IN POPTSELECT poptsel, // option array which determines path
// through atr. may be filled with OPTION_INDEX_ANY
// if we are jumpstarting
IN DWORD dwFeature,
IN OUT PDWORD pdwNextOpt // if multiple options are selected
// for dwFeature, pdwNextOpt points to the Nth option to consider
// in the poptsel list, at return time, this value
// is incremented if there are remaining options selected,
// else is reset to zero.
// For the first call, or PICKONE features,
// this value must be set to zero.
) ;
BOOL RaisePriority(
DWORD dwFeature1,
DWORD dwFeature2,
PBYTE pubnRaw,
PDWORD pdwPriority) ;
DWORD dwNumOptionSelected(
IN DWORD dwNumFeatures,
IN POPTSELECT poptsel
) ;
BOOL BinitSnapShotIndexTable(PBYTE pubnRaw) ;
BOOL BinitSizeOptionTables(PBYTE pubnRaw) ;
PRAWBINARYDATA
LoadRawBinaryData (
IN PTSTR ptstrDataFilename
) ;
PRAWBINARYDATA
GpdLoadCachedBinaryData(
PTSTR ptstrGpdFilename
) ;
VOID
UnloadRawBinaryData (
IN PRAWBINARYDATA pnRawData
) ;
PINFOHEADER
InitBinaryData(
IN PRAWBINARYDATA pnRawData, // actually pStatic
IN PINFOHEADER pInfoHdr,
IN POPTSELECT pOptions
) ;
VOID
FreeBinaryData(
IN PINFOHEADER pInfoHdr
) ;
BOOL BIsRawBinaryDataInDate(
IN PBYTE pubRaw) ; // this is pointer to memory mapped file! BETA2
BOOL BgetLocFeaIndex(
IN PRAWBINARYDATA pnRawData, // raw binary data.
OUT PDWORD pdwFea // Index of the Locale Feature (if present)
) ;
BOOL BgetLocFeaOptIndex(
IN PRAWBINARYDATA pnRawData,
OUT PDWORD pdwFea,
OUT PDWORD pdwOptIndex
);
#endif PARSERDLL
BOOL BfindMatchingOrDefaultNode(
IN PATTRIB_TREE patt , // start of ATTRIBUTE tree array.
IN OUT PDWORD pdwNodeIndex, // Points to first node in chain
IN DWORD dwOptionID // may even take on the value DEFAULT_INIT
) ;
// ------- end function declarations ------- //
#ifndef PARSERDLL
/* ---- Memory Map ---- /*
INFOHEADER {RAWBINARYDATA} <= reference pt for local offsets.
UIINFO
GPDDRIVERINFO (aka DRIVERINFO)
CMD_TABLE of DWORDS
LOCALLIST (to support sequenced commands)
FEATURES
OPTIONS and OPTIONEXTRAS
/* ---- end Memory Map ---- */
PINFOHEADER PINFOHDRcreateSnapshot(
PBYTE pubnRaw, // raw binary data. PSTATIC. BETA2
POPTSELECT poptsel // assume fully initialized
)
/* this function allocates the single memoryblock
that contains the entire snapshot. */
{
DWORD dwCurOffset = 0, loGPDdriverInfo, loInfoHeader,
loUIinfo, loCmdTable, loListArray, loFeatures, dwSize,
dwNumFeatures, dwNumListNodes, dwTotSize, loOptions,
dwSizeOption, dwSizeOptionEx, dwFea, dwGID , dwNumOptions,
dwI , dwCmd;
PDWORD pdwSymbolRoots ;
PENHARRAYREF pearTableContents ;
PDFEATURE_OPTIONS pfo ;
PINFOHEADER pInfoHdr ;
PUIINFO pUIinfo ;
PSTATICFIELDS pStatic ;
// PMINIRAWBINARYDATA pmrbd = NULL ;
PGPDDRIVERINFO pGPDdriverInfo ;
PBYTE pubRaw, // ptr to BUD data.
pubOptionsDest , // ptr to any of the several varieties
pubDestOptionEx ; // of option structures.
BOOL bStatus ;
PFEATURE pFeaturesDest ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
loInfoHeader = dwCurOffset ;
dwCurOffset += sizeof(INFOHEADER) ;
loUIinfo = dwCurOffset ;
dwCurOffset += sizeof(UIINFO) ;
loGPDdriverInfo = dwCurOffset ;
dwCurOffset += sizeof(GPDDRIVERINFO) ;
loCmdTable = dwCurOffset ;
dwCurOffset += sizeof(DWORD) * CMD_MAX ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
dwNumListNodes = dwNumOptionSelected(dwNumFeatures, poptsel) ;
// if there are pickmany, we could have more than dwNumFeatures.
dwNumListNodes += NUM_CONFIGURATION_CMDS ;
loListArray = dwCurOffset ;
dwCurOffset += dwNumListNodes * sizeof(LISTNODE) ;
loFeatures = dwCurOffset ;
dwCurOffset += dwNumFeatures * sizeof(FEATURE) ;
loOptions = dwCurOffset ;
// There are too many options and optionextra structures
// for me to track all the offsets, so just track the
// amount of memory consumed.
pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
loOffset) ;
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
for(dwTotSize = dwFea = 0 ; dwFea < dwNumFeatures ; dwFea++)
{
dwGID = pfo[dwFea].dwGID ;
dwNumOptions = pfo[dwFea].dwNumOptions ;
if(dwGID != GID_UNKNOWN)
{
dwSize = pStatic->pdwSizeOption[dwGID] +
pStatic->pdwSizeOptionEx[dwGID] ;
}
else
{
dwSize = sizeof(OPTION);
}
dwTotSize += dwSize * dwNumOptions ; // of all options
}
dwCurOffset += dwTotSize ; // total size of local snapshot.
// now allocate memory and partition this block into structures.
if(!(pInfoHdr = (PINFOHEADER)MemAllocZ(dwCurOffset) ))
{
ERR(("Fatal: PINFOHDRcreateSnapshot - unable to alloc %d bytes.\n",
dwCurOffset));
// cannot use globals outside of parser.
// use error num to relay failure.
return(NULL) ; // This is unrecoverable
}
pUIinfo = (PUIINFO)((PBYTE)(pInfoHdr) + loUIinfo) ;
pGPDdriverInfo = (PGPDDRIVERINFO)((PBYTE)(pInfoHdr) + loGPDdriverInfo) ;
if(!BinitCommandTable((PDWORD)((PBYTE)(pInfoHdr) + loCmdTable),
pubnRaw, poptsel) )
{
MemFree(pInfoHdr) ;
return(NULL) ;
}
// init GPDDRIVERINFO
// note all offsets in DataTable are relative to pubResourceData
// the StringHeap. Except these :
pGPDdriverInfo->pInfoHeader = pInfoHdr ;
pGPDdriverInfo->DataType[DT_COMMANDTABLE].loOffset = loCmdTable ;
pGPDdriverInfo->DataType[DT_COMMANDTABLE].dwCount = CMD_MAX ;
pGPDdriverInfo->DataType[DT_LOCALLISTNODE].loOffset = loListArray ;
pGPDdriverInfo->DataType[DT_LOCALLISTNODE].dwCount = dwNumListNodes ;
if(!BinitGPDdriverInfo(pGPDdriverInfo, pubnRaw, poptsel) )
{
MemFree(pInfoHdr) ;
return(NULL) ;
}
// init InfoHeader
pInfoHdr->loUIInfoOffset = loUIinfo ;
pInfoHdr->loDriverOffset = loGPDdriverInfo ;
if(!BinitRawData(&pInfoHdr->RawData, pubnRaw) )
{
MemFree(pInfoHdr) ;
return(NULL) ;
}
// init UIInfo
pUIinfo->pInfoHeader = pInfoHdr ;
pUIinfo->loFeatureList = loFeatures ; // from pInfoHdr
pUIinfo->loFontSubstTable =
pGPDdriverInfo->DataType[DT_FONTSUBST].loOffset ; // in pubRaw
pUIinfo->dwFontSubCount =
pGPDdriverInfo->DataType[DT_FONTSUBST].dwCount ;
pUIinfo->UIGroups.dwCount = 0 ; // in pubRaw
pUIinfo->CartridgeSlot.loOffset = // in pubRaw
pGPDdriverInfo->DataType[DT_FONTSCART].loOffset ;
pUIinfo->CartridgeSlot.dwCount =
pGPDdriverInfo->DataType[DT_FONTSCART].dwCount ;
// pUIinfo->dwFlags = FLAG_RULESABLE ;
// start with just this
// and turn on/off more flags as needed. ROTATE_90
// and ORIENT_SUPPORT are never set. This is now obsolete.
if(pGPDdriverInfo->Globals.fontformat != UNUSED_ITEM)
pUIinfo->dwFlags |= FLAG_FONT_DOWNLOADABLE ;
if(pGPDdriverInfo->Globals.liDeviceFontList != END_OF_LIST)
pUIinfo->dwFlags |= FLAG_FONT_DEVICE ;
#if 0
Alvins code never looks at this flag anyway.
for(dwCmd = CMD_FIRST_RULES ; dwCmd < CMD_LAST_RULES + 1 ; dwCmd++ )
{
if( ((PDWORD)((PBYTE)(pInfoHdr) + loCmdTable))[dwCmd] ==
UNUSED_ITEM)
pUIinfo->dwFlags &= ~FLAG_RULESABLE ; // clear flag
} // if requisite command is missing.
#endif
if(!BinitUIinfo(pUIinfo, pubnRaw, poptsel, FALSE) )
{
MemFree(pInfoHdr) ;
return(NULL) ;
}
// init features and options
pFeaturesDest = (PFEATURE)((PBYTE)(pInfoHdr) + loFeatures) ;
for( dwFea = 0 ; dwFea < dwNumFeatures ; dwFea++)
{
dwGID = pfo[dwFea].dwGID ;
dwNumOptions = pfo[dwFea].dwNumOptions ;
pFeaturesDest[dwFea].Options.loOffset = loOptions ;
pFeaturesDest[dwFea].Options.dwCount = dwNumOptions ;
if(!BinitFeatures(pFeaturesDest + dwFea, pfo + dwFea,
pubnRaw, poptsel, FALSE))
{
MemFree(pInfoHdr) ;
return(NULL) ;
}
if(dwGID != GID_UNKNOWN)
{
dwSizeOption = pStatic->pdwSizeOption[dwGID] ;
dwSizeOptionEx = pStatic->pdwSizeOptionEx[dwGID] ;
pUIinfo->aloPredefinedFeatures[dwGID] =
loFeatures + dwFea * sizeof(FEATURE) ;
// all fields initially set to zeros.
}
else
{
dwSizeOption = sizeof(OPTION);
dwSizeOptionEx = 0 ;
}
// special non-atreeref fields
(pFeaturesDest + dwFea)->dwFeatureID = dwGID ;
(pFeaturesDest + dwFea)->dwOptionSize = dwSizeOption ;
loOptions += dwSizeOption * dwNumOptions ;
pubOptionsDest = (PBYTE)(pInfoHdr) + pFeaturesDest[dwFea].Options.loOffset ;
for(dwI = 0 ; dwI < dwNumOptions ; dwI++)
{
if(dwSizeOptionEx)
{
((POPTION)pubOptionsDest)->loRenderOffset = loOptions ;
pubDestOptionEx = (PBYTE)(pInfoHdr) + loOptions ;
loOptions += dwSizeOptionEx ;
}
else
{
((POPTION)pubOptionsDest)->loRenderOffset = 0 ;
pubDestOptionEx = NULL ;
}
if(!BinitOptionFields(pubOptionsDest, pubDestOptionEx,
pubnRaw, dwFea, dwI, poptsel, pInfoHdr, FALSE) )
{
MemFree(pInfoHdr) ;
return(NULL) ;
}
pubOptionsDest += dwSizeOption ;
}
}
#ifndef KERNEL_MODE
if(!BCheckGPDSemantics(pInfoHdr, poptsel) )
{
MemFree(pInfoHdr) ;
pInfoHdr = NULL ;
}
#endif
return(pInfoHdr) ;
}
BOOL BinitOptionFields(
PBYTE pubDestOption, // ptr to some type of option structure.
PBYTE pubDestOptionEx, // option extra structure if any.
PBYTE pubnRaw, // raw binary data.
DWORD dwFea,
DWORD dwOpt,
POPTSELECT poptsel , // assume fully initialized
PINFOHEADER pInfoHdr, // used to access global structure.
BOOL bUpdate // if true only update selected fields.
)
{
PENHARRAYREF pearTableContents ;
PDFEATURE_OPTIONS pfo ;
// PMINIRAWBINARYDATA pmrbd ;
PATREEREF patrRoot ; // root of attribute tree to navigate.
DWORD dwUnresolvedFeature, // dummy storage
dwI, dwStart , dwEnd, dwNextOpt, dwGID ;
OPTSELECT optsPrevs ;
PBYTE pubDest ;
BOOL bStatus = TRUE ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
loOffset) ;
pfo += dwFea ; // index pfo to the proper feature.
dwGID = pfo->dwGID ;
// save previous option selection for this feature.
optsPrevs = poptsel[dwFea] ; // save setting since we will sweep it.
poptsel[dwFea].ubNext = NULL_OPTSELECT ;
poptsel[dwFea].ubCurOptIndex = (BYTE)dwOpt ;
if(bUpdate) // assume update comes after main group.
dwStart = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONS].dwStart ; // starting Index
else
dwStart = pStatic->ssTableIndex[SSTI_OPTIONS].dwStart ; // starting Index
dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONS].dwEnd ; // Ending Index
for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
{
if(!(pStatic->snapShotTable[dwI].dwNbytes))
continue ; // skip over section delimiter.
if(dwGID >= MAX_GID)
{
if(pStatic->snapShotTable[dwI].dwGIDflags != 0xffffffff)
continue ; // this field not used for generic GID.
}
else if(!(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID)))
continue ; // this field not used for this GID.
patrRoot = (PATREEREF)((PBYTE)pfo +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = pubDestOption + pStatic->snapShotTable[dwI].dwDestOffset ;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
// any value. Doesn't matter.
&dwNextOpt) != TRI_SUCCESS)
{
ERR(("BinitOptionFields: Failed to extract value for attribute in Fea: %d, Opt: %d\n", dwFea, dwOpt));
bStatus = FALSE ;
}
}
if(bUpdate) // assume update comes after main group.
dwStart = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONEX].dwStart ; // starting Index
else
dwStart = pStatic->ssTableIndex[SSTI_OPTIONEX].dwStart ; // starting Index
dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONEX].dwEnd ; // Ending Index
for(dwI = dwStart ; bStatus && pubDestOptionEx && (dwI < dwEnd)
; dwI++)
{
if(!(pStatic->snapShotTable[dwI].dwNbytes))
continue ; // skip over section delimiter.
if(!(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID)))
continue ; // this field not used for this GID.
patrRoot = (PATREEREF)((PBYTE)pfo +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = pubDestOptionEx + pStatic->snapShotTable[dwI].dwDestOffset ;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0,
&dwNextOpt) != TRI_SUCCESS)
{
ERR(("BinitOptionFields: Failed to extract value for attribute in Fea: %d, Opt: %d\n", dwFea, dwOpt));
bStatus = FALSE ;
}
}
if(!bUpdate && !BspecialProcessOption(pubnRaw, pubDestOption,
pubDestOptionEx,
pfo , poptsel, pInfoHdr, dwFea, dwOpt,
optsPrevs.ubCurOptIndex == dwOpt) )
// dwOpt is the default option for dwFea!
{
bStatus = FALSE ;
}
poptsel[dwFea] = optsPrevs ; // restore previous setting.
return(bStatus) ;
}
BOOL BinitUIinfo(
PUIINFO pUIinfo ,
PBYTE pubnRaw, // PSTATIC. BETA2
POPTSELECT poptsel, // assume fully initialized
BOOL bUpdate // if true only update selected fields.
)
{
PENHARRAYREF pearTableContents ;
PMINIRAWBINARYDATA pmrbd ;
PATREEREF patrRoot ; // root of attribute tree to navigate.
DWORD dwUnresolvedFeature, // dummy storage
dwI, dwStart , dwEnd, dwNextOpt ;
BOOL bStatus = TRUE ;
PGLOBALATTRIB pga ;
PBYTE pubDest, pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pga = (PGLOBALATTRIB)(pubRaw + pearTableContents[MTI_GLOBALATTRIB].
loOffset) ;
if(bUpdate) // assume update comes after main group.
dwStart = pStatic->ssTableIndex[SSTI_UPDATE_UIINFO].dwStart ; // starting Index
else
dwStart = pStatic->ssTableIndex[SSTI_UIINFO].dwStart ; // starting Index
dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_UIINFO].dwEnd ; // Ending Index
for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
{
if(!(pStatic->snapShotTable[dwI].dwNbytes))
continue ; // skip over section delimiter.
patrRoot = (PATREEREF)((PBYTE)pga +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = (PBYTE)pUIinfo + pStatic->snapShotTable[dwI].dwDestOffset ;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0,
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
}
}
pUIinfo->pubResourceData =
pubRaw + pearTableContents[MTI_STRINGHEAP].loOffset ;
pUIinfo->dwSpecVersion = pmrbd->dwSpecVersion ; // don't change!
pUIinfo->dwSize = sizeof(UIINFO);
pUIinfo->dwTechnology = DT_RASPRINTER ;
pUIinfo->dwDocumentFeatures = pmrbd->rbd.dwDocumentFeatures;
pUIinfo->dwPrinterFeatures = pmrbd->rbd.dwPrinterFeatures;
pUIinfo->dwCustomSizeOptIndex = UNUSED_ITEM; // until found later
pUIinfo->dwFreeMem = 400000 ; // default just in case
// there are no GID_MEMOPTION features.
pUIinfo->dwMaxDocKeywordSize = pmrbd->dwMaxDocKeywordSize + KEYWORD_SIZE_EXTRA;
pUIinfo->dwMaxPrnKeywordSize = pmrbd->dwMaxPrnKeywordSize + KEYWORD_SIZE_EXTRA;
// dead: replace with macros
// pUIinfo->dwWhichBasePtr[UIDT_FEATURE] = 0 ;
// pUIinfo->dwWhichBasePtr[UIDT_OPTION] = 0 ;
// pUIinfo->dwWhichBasePtr[UIDT_OPTIONEX] = 0 ;
// pUIinfo->dwWhichBasePtr[UIDT_CONSTRAINT] = BASE_USE_RESOURCE_DATA ;
// pUIinfo->dwWhichBasePtr[UIDT_GROUPS] = BASE_USE_RESOURCE_DATA ;
// pUIinfo->dwWhichBasePtr[UIDT_LISTNODE] = BASE_USE_RESOURCE_DATA ;
// pUIinfo->dwWhichBasePtr[UIDT_FONTSCART] = BASE_USE_RESOURCE_DATA ;
// pUIinfo->dwWhichBasePtr[UIDT_FONTSUBST] = BASE_USE_RESOURCE_DATA ;
return(bStatus) ;
}
BOOL BinitFeatures(
PFEATURE pFeaturesDest,
PDFEATURE_OPTIONS pfoSrc,
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel, // assume fully initialized
BOOL bUpdate // if true only update selected fields.
)
{
PENHARRAYREF pearTableContents ;
// PMINIRAWBINARYDATA pmrbd ;
PATREEREF patrRoot ; // root of attribute tree to navigate.
DWORD dwUnresolvedFeature, // dummy storage
dwI, dwStart , dwEnd , dwNextOpt ;
BOOL bStatus = TRUE ;
PBYTE pubDest ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
if(bUpdate) // assume update comes after main group.
dwStart = pStatic->ssTableIndex[SSTI_UPDATE_FEATURES].dwStart ; // starting Index
else
dwStart = pStatic->ssTableIndex[SSTI_FEATURES].dwStart ; // starting Index
dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_FEATURES].dwEnd ; // Ending Index
for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
{
if(!pStatic->snapShotTable[dwI].dwNbytes)
continue ; // ignore section delimiter.
patrRoot = (PATREEREF)((PBYTE)pfoSrc +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = (PBYTE)pFeaturesDest + pStatic->snapShotTable[dwI].dwDestOffset ;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0,
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
}
}
return(bStatus) ;
}
BOOL BinitGlobals(
PGLOBALS pGlobals,
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel, // assume fully initialized
BOOL bUpdate // if true only update selected fields.
)
{
PENHARRAYREF pearTableContents ;
// PMINIRAWBINARYDATA pmrbd ;
PATREEREF patrRoot ; // root of attribute tree to navigate.
DWORD dwUnresolvedFeature, // dummy storage
dwI, dwStart , dwEnd, dwNextOpt ;
BOOL bStatus = TRUE ;
PGLOBALATTRIB pga ;
PBYTE pubDest ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pga = (PGLOBALATTRIB)(pubRaw + pearTableContents[MTI_GLOBALATTRIB].
loOffset) ;
if (bUpdate)
dwStart = pStatic->ssTableIndex[SSTI_UPDATE_GLOBALS].dwStart ;
else
dwStart = pStatic->ssTableIndex[SSTI_GLOBALS].dwStart ; // starting Index
dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_GLOBALS].dwEnd ; // Ending Index
for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
{
if(!(pStatic->snapShotTable[dwI].dwNbytes))
continue ; // skip over section delimiter.
patrRoot = (PATREEREF)((PBYTE)pga +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = (PBYTE)pGlobals + pStatic->snapShotTable[dwI].dwDestOffset ;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0,
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
}
}
return(bStatus) ;
}
BOOL BinitCommandTable(
PDWORD pdwCmdTable, // dest array
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel // assume fully initialized
)
{
PENHARRAYREF pearTableContents ;
// PMINIRAWBINARYDATA pmrbd ;
PATREEREF patrRoot ; // root of attribute tree to navigate.
DWORD dwUnresolvedFeature, // dummy storage
dwNextOpt , dwI; // index to the commandTable
// describing how to transfer the Command data type.
BOOL bStatus = TRUE ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
patrRoot = (PATREEREF)(pubRaw + pearTableContents[MTI_COMMANDTABLE].
loOffset) ;
// loop for every PATREEREF in the MTI_COMMANDTABLE !
// not looping through each entry in the section.
for(dwI = 0 ; bStatus && (dwI < CMD_MAX) ; dwI++)
{
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, pStatic->dwSSTableCmdIndex,
(PBYTE)(pdwCmdTable + dwI),
&dwUnresolvedFeature, patrRoot[dwI], poptsel, 0,
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
}
}
return(bStatus) ;
}
BOOL BinitRawData(
PRAWBINARYDATA pRawData, // contained in INFOHEADER.
PBYTE pubnRaw // Parser's raw binary data.
)
{
PMINIRAWBINARYDATA pmrbd ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pRawData->dwFileSize = pmrbd->rbd.dwFileSize;
pRawData->dwParserSignature = pmrbd->rbd.dwParserSignature;
pRawData->dwParserVersion = pmrbd->rbd.dwParserVersion;
pRawData->dwChecksum32 = pmrbd->rbd.dwChecksum32;
pRawData->dwSrcFileChecksum32 = pmrbd->rbd.dwSrcFileChecksum32;
// this not the count of synthesized vs.
// explicitly defined features
pRawData->dwDocumentFeatures = pmrbd->rbd.dwDocumentFeatures;
pRawData->dwPrinterFeatures = pmrbd->rbd.dwPrinterFeatures;
pRawData->pvPrivateData = pubnRaw ; // BETA2
pRawData->pvReserved = NULL;
return(TRUE) ;
}
BOOL BinitGPDdriverInfo(
PGPDDRIVERINFO pGPDdriverInfo,
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel // assume fully initialized
)
{
PENHARRAYREF pearTableContents ;
BOOL bStatus ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pGPDdriverInfo->dwSize = sizeof(GPDDRIVERINFO) ;
pGPDdriverInfo->pubResourceData =
pubRaw + pearTableContents[MTI_STRINGHEAP].loOffset ;
pGPDdriverInfo->DataType[DT_COMMANDARRAY].loOffset =
pearTableContents[MTI_COMMANDARRAY].loOffset -
pearTableContents[MTI_STRINGHEAP].loOffset ;
pGPDdriverInfo->DataType[DT_COMMANDARRAY].dwCount =
pearTableContents[MTI_COMMANDARRAY].dwCount ;
pGPDdriverInfo->DataType[DT_PARAMETERS].loOffset =
pearTableContents[MTI_PARAMETER].loOffset -
pearTableContents[MTI_STRINGHEAP].loOffset ;
pGPDdriverInfo->DataType[DT_PARAMETERS].dwCount =
pearTableContents[MTI_PARAMETER].dwCount ;
pGPDdriverInfo->DataType[DT_TOKENSTREAM].loOffset =
pearTableContents[MTI_TOKENSTREAM].loOffset -
pearTableContents[MTI_STRINGHEAP].loOffset ;
pGPDdriverInfo->DataType[DT_TOKENSTREAM].dwCount =
pearTableContents[MTI_TOKENSTREAM].dwCount ;
pGPDdriverInfo->DataType[DT_LISTNODE].loOffset =
pearTableContents[MTI_LISTNODES].loOffset -
pearTableContents[MTI_STRINGHEAP].loOffset ;
pGPDdriverInfo->DataType[DT_LISTNODE].dwCount =
pearTableContents[MTI_LISTNODES].dwCount ;
pGPDdriverInfo->DataType[DT_FONTSCART].loOffset =
pearTableContents[MTI_FONTCART].loOffset -
pearTableContents[MTI_STRINGHEAP].loOffset ;
pGPDdriverInfo->DataType[DT_FONTSCART].dwCount =
pearTableContents[MTI_FONTCART].dwCount ;
pGPDdriverInfo->DataType[DT_FONTSUBST].loOffset =
pearTableContents[MTI_TTFONTSUBTABLE].loOffset -
pearTableContents[MTI_STRINGHEAP].loOffset ;
pGPDdriverInfo->DataType[DT_FONTSUBST].dwCount =
pearTableContents[MTI_TTFONTSUBTABLE].dwCount ;
bStatus = BinitSequencedCmds(pGPDdriverInfo, pubnRaw, poptsel) ;
if(bStatus)
bStatus = BinitGlobals(&pGPDdriverInfo->Globals, pubnRaw, poptsel, FALSE ) ;
return(bStatus) ;
}
BOOL BinitSequencedCmds(
PGPDDRIVERINFO pGPDdriverInfo,
PBYTE pubnRaw, // raw binary data.
POPTSELECT poptsel // assume fully initialized
)
{
PINFOHEADER pInfoHdr ;
PDWORD pdwCmdTable ; // start of local CommandTable
PENHARRAYREF pearTableContents ;
DWORD dwCmdIn , // command table index.
// or commandArray index.
dwNextOpt, dwFea, dwNumFeatures ,
dwUnresolvedFeature,
dwNewListNode = 0 ; // an unused listnode to
// add to the list. initially none are used.
PDFEATURE_OPTIONS pfo ;
ATREEREF atrRoot ; // root of attribute tree
// PMINIRAWBINARYDATA pmrbd ;
OPTSELECT optsPrevs ;
BOOL bStatus = TRUE ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pInfoHdr = pGPDdriverInfo->pInfoHeader ;
pdwCmdTable = (PDWORD)((PBYTE)(pInfoHdr) +
pGPDdriverInfo->DataType[DT_COMMANDTABLE].loOffset) ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pGPDdriverInfo->dwJobSetupIndex = END_OF_LIST ;
pGPDdriverInfo->dwDocSetupIndex = END_OF_LIST ;
pGPDdriverInfo->dwPageSetupIndex = END_OF_LIST ;
pGPDdriverInfo->dwPageFinishIndex = END_OF_LIST ;
pGPDdriverInfo->dwDocFinishIndex = END_OF_LIST ;
pGPDdriverInfo->dwJobFinishIndex = END_OF_LIST ;
// first add the configuration commands to the list.
// get them from the commandtable. Assume they are all
// contiguous
for(dwCmdIn = FIRST_CONFIG_CMD ; dwCmdIn < LAST_CONFIG_CMD ; dwCmdIn++)
{
if((pdwCmdTable[dwCmdIn] != UNUSED_ITEM) &&
BaddSequencedCmdToList(pdwCmdTable[dwCmdIn], pGPDdriverInfo,
dwNewListNode, pubnRaw ) )
dwNewListNode++ ;
}
// now wander through all the features, seeing what
// command is needed.
pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
loOffset) ;
dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
for(dwFea = 0 ; dwFea < dwNumFeatures ; dwFea++)
{
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
atrRoot = pfo[dwFea].atrCommandIndex ;
if(EextractValueFromTree(pubnRaw, pStatic->dwSSCmdSelectIndex,
(PBYTE)&dwCmdIn, // CmdArray index - dest
&dwUnresolvedFeature, atrRoot, poptsel, dwFea,
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
continue ;
}
if( (dwCmdIn != UNUSED_ITEM) &&
BaddSequencedCmdToList(dwCmdIn, pGPDdriverInfo,
dwNewListNode, pubnRaw ) )
dwNewListNode++ ;
while(dwNextOpt) // multiple options selected.
{
if(EextractValueFromTree(pubnRaw, pStatic->dwSSCmdSelectIndex,
(PBYTE)&dwCmdIn, // CmdArray index - dest
&dwUnresolvedFeature, atrRoot, poptsel, dwFea,
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
continue ;
}
if((dwCmdIn != UNUSED_ITEM) &&
BaddSequencedCmdToList(dwCmdIn, pGPDdriverInfo,
dwNewListNode, pubnRaw ) )
dwNewListNode++ ;
}
}
return(bStatus);
}
BOOL BaddSequencedCmdToList(
DWORD dwCmdIn, // index of a command in CommandArray
PGPDDRIVERINFO pGPDdriverInfo,
DWORD dwNewListNode, // an unused listnode to add to the list.
PBYTE pubnRaw // raw binary data.
)
/* remember:
the pdwSeqCmdRoot points to the first node in a list.
There is a list for each SEQSECTION.
Each node contains the index to a command in the command array
and an index to the next node in the list.
*/
{
PCOMMAND pcmdArray ; // the Command Array
SEQSECTION eSection;
PDWORD pdwSeqCmdRoot ; // points to a list root.
DWORD dwOrder, // order value of a command.
dwCurListNode, // node index as we traverse the list.
dwPrevsListNode ; // the prevs node in the list.
PINFOHEADER pInfoHdr ;
PLISTNODE plstNodes ; // start of local listnodes array
PENHARRAYREF pearTableContents ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
pInfoHdr = pGPDdriverInfo->pInfoHeader ;
plstNodes = (PLISTNODE)((PBYTE)pInfoHdr +
pGPDdriverInfo->DataType[DT_LOCALLISTNODE].loOffset) ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pcmdArray = (PCOMMAND)(pubRaw +
pearTableContents[MTI_COMMANDARRAY].loOffset) ;
eSection = pcmdArray[dwCmdIn].ordOrder.eSection ;
switch(eSection)
{
case (SS_JOBSETUP):
{
pdwSeqCmdRoot = &pGPDdriverInfo->dwJobSetupIndex;
break ;
}
case (SS_DOCSETUP):
{
pdwSeqCmdRoot = &pGPDdriverInfo->dwDocSetupIndex;
break ;
}
case (SS_PAGESETUP):
{
pdwSeqCmdRoot = &pGPDdriverInfo->dwPageSetupIndex;
break ;
}
case (SS_PAGEFINISH):
{
pdwSeqCmdRoot = &pGPDdriverInfo->dwPageFinishIndex;
break ;
}
case (SS_DOCFINISH):
{
pdwSeqCmdRoot = &pGPDdriverInfo->dwDocFinishIndex;
break ;
}
case (SS_JOBFINISH):
{
pdwSeqCmdRoot = &pGPDdriverInfo->dwJobFinishIndex;
break ;
}
default:
{
ERR(("BaddSequencedCmdToList: Invalid or non-existent *Order value specified.\n"));
return(FALSE); // command not added to linked list.
}
}
// Insert a new node in the list pointed to by pdwSeqCmdRoot
dwOrder = pcmdArray[dwCmdIn].ordOrder.dwOrder ;
// walk the list until you find an order larger than yours.
dwPrevsListNode = END_OF_LIST ;
dwCurListNode = *pdwSeqCmdRoot ;
while((dwCurListNode != END_OF_LIST) &&
(pcmdArray[plstNodes[dwCurListNode].dwData].ordOrder.dwOrder
< dwOrder) )
{
dwPrevsListNode = dwCurListNode ;
dwCurListNode = plstNodes[dwCurListNode].dwNextItem ;
}
plstNodes[dwNewListNode].dwData = dwCmdIn ;
plstNodes[dwNewListNode].dwNextItem = dwCurListNode ;
if(dwPrevsListNode == END_OF_LIST)
*pdwSeqCmdRoot = dwNewListNode ;
else
plstNodes[dwPrevsListNode].dwNextItem = dwNewListNode ;
return(TRUE) ;
}
/*++
The default Option array (as determined from the gpd) is initialized.
Since the options or attributues of features may be dependent on the
some other features, the order of initialization of feature assumes
importance. The priority array therefore tries to order the
initialization so that when a feature has to be initialised, all the
features on which it is dependent on have already been initialised.
If, inspite of the priority array, a feature's option cannot be
determined until some other feature's option has been determined,
the RaisePriority Function is used (This is called by
EdetermineDefaultOption() ).
A quirky code here is the pdwPriorityCopy which is initialised
to pdwPriority. The latter is in read only space and therefore
prevents change of priority in the RaisePriority Function.
Therefore pdwPriorityCopy is passed to that function.
Some special case processing is required for the *Feature:Locale
keyword if it occurs in the .gpd. The default option for this
feature is to be set to the SystemDefaultLocale.
--*/
BinitDefaultOptionArray(
POPTSELECT poptsel, // assume is large enough
PBYTE pubnRaw)
{
PENHARRAYREF pearTableContents ;
// PMINIRAWBINARYDATA pmrbd ;
PDFEATURE_OPTIONS pfo ;
PDWORD pdwPriority, // Array of feature indices arranged
// according to priority.
pdwPriorityCopy; // pdwPriority is in read only space.
// We might have to change the
// priorities temporarily to allow
// Default option array to be
// constructed. This change is done in
// pdwPriorityCopy
DWORD dwNumFeatures, // Total number of features
dwI ,
dwFea, // Index of Feature Locale
dwOptIndex; // Index of Option of Locale that
// matches System Locale
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
// obtain pointers to structures:
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
// both explicit and synthesized features are contiguous.
if(dwNumFeatures > MAX_COMBINED_OPTIONS)
return(FALSE); // too many to save
dwFea = dwOptIndex = (DWORD)-1; // For safety sake only. Should be initialized
// in the function BgetLocFeaOptIndex().
// returns TRUE if everything OK. if return is TRUE and dwFea is -1
// Locale is not present and no special processing is required.
// If dwFea != -1 and dwOptIndex == -1 means none of the options in
// the .gpd match the system default. Again no special processing
// for locale is required.
// Assuming that only a single matching option is possible for
// Locale.
if ( !BgetLocFeaOptIndex(
(PRAWBINARYDATA)pubnRaw, &dwFea, &dwOptIndex) )
{
return FALSE;
}
pdwPriority = (PDWORD)(pubRaw + pearTableContents[MTI_PRIORITYARRAY].
loOffset) ;
pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
loOffset) ;
if ( ! (pdwPriorityCopy = (PDWORD) MemAlloc (
pearTableContents[MTI_PRIORITYARRAY].dwCount *
pearTableContents[MTI_PRIORITYARRAY].dwElementSiz ) ) )
{
// Set error codes and
ERR(("Fatal: BinitDefaultOptionArray - unable to allocate memory\n" ));
return FALSE;
}
memcpy(pdwPriorityCopy, pdwPriority,
pearTableContents[MTI_PRIORITYARRAY].dwCount *
pearTableContents[MTI_PRIORITYARRAY].dwElementSiz );
for(dwI = 0 ; dwI < dwNumFeatures ; dwI++)
{
poptsel[dwI].ubCurOptIndex = OPTION_INDEX_ANY ;
poptsel[dwI].ubNext = NULL_OPTSELECT ;
}
// Initialize the option array for Feature Locale.
// Or should we call ReconstructOptionArray.????
if ( dwFea != -1 && dwOptIndex != -1)
{
poptsel[dwFea].ubCurOptIndex = (BYTE)dwOptIndex;
poptsel[dwFea].ubNext = NULL_OPTSELECT ;
}
for(dwI = 0 ; dwI < dwNumFeatures ; dwI++)
{
// The order of evaluation is determined
// by the priority array.
if(poptsel[pdwPriorityCopy[dwI]].ubCurOptIndex == OPTION_INDEX_ANY)
{
if(EdetermineDefaultOption(pubnRaw , pdwPriorityCopy[dwI],
pfo, poptsel, pdwPriorityCopy) != TRI_SUCCESS)
{
ERR(("BinitDefaultOptionArray: failed to determine consistent \
default options.\n"));
if ( pdwPriorityCopy )
MemFree(pdwPriorityCopy);
return(FALSE);
}
}
}
// BUG_BUG!!!! now verify the set options thus determined is
// fully self consistent. is not precluded by UIConstraints.
// warn user and fail otherwise .
// successful execution of EdetermineDefaultOption basically
// assures this.
if ( pdwPriorityCopy )
MemFree(pdwPriorityCopy);
return(TRUE);
}
TRISTATUS EdetermineDefaultOption(
PBYTE pubnRaw, // start of Rawbinary data
DWORD dwFeature, // determine the default for this feature
PDFEATURE_OPTIONS pfo,
POPTSELECT poptsel, // assume is large enough
PDWORD pdwPriority) // Priority array indicating the priority of various
// features.
{
// PMINIRAWBINARYDATA pmrbd ;
TRISTATUS eStatus ;
DWORD dwUnresolvedFeature , // no option has been determined
dwNextOpt , // for this feature
dwOption ; // for BextractValueFromTree
// to write into.
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
// This function will modify the priority array
// each time the tree walk fails so that each feature
// evaluated depends only on default options that have
// previously evaluated .
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
while((eStatus = EextractValueFromTree(
pubnRaw, pStatic->dwSSdefaultOptionIndex,
(PBYTE )&dwOption,
&dwUnresolvedFeature,
pfo[dwFeature].atrDefaultOption,
poptsel, 0,
&dwNextOpt)) == TRI_AGAIN)
{
// recursion handles depth, while loop handles breadth
if(poptsel[dwUnresolvedFeature].ubCurOptIndex == OPTION_PENDING)
{
ERR(("Fatal syntax error: EdetermineDefaultOption - circular dependency in default options.\n"));
return(TRI_UTTER_FAILURE) ;
}
poptsel[dwFeature].ubCurOptIndex = OPTION_PENDING ;
// marks entry in option array so we can detect infinite loops.
if(!RaisePriority(dwFeature, dwUnresolvedFeature, pubnRaw, pdwPriority))
return(FALSE) ; // modify Priority array to reflect
// reality.
eStatus = EdetermineDefaultOption(pubnRaw, dwUnresolvedFeature,
pfo, poptsel, pdwPriority) ;
if(eStatus == TRI_UTTER_FAILURE)
return(TRI_UTTER_FAILURE) ;
}
if(eStatus == TRI_SUCCESS)
poptsel[dwFeature].ubCurOptIndex = (BYTE)dwOption ;
return(eStatus);
}
VOID VtileDefault(
PBYTE pubDest,
DWORD dwDefault,
DWORD dwBytes)
{
DWORD dwRemain ;
// This function will copy the same DWORD
// repeatedly into the dest until dwBytes have
// been written.
for (dwRemain = dwBytes ; dwRemain > sizeof(DWORD) ;
dwRemain -= sizeof(DWORD) )
{
memcpy(pubDest , &dwDefault, sizeof(DWORD)) ;
pubDest += sizeof(DWORD) ;
}
memcpy(pubDest, &dwDefault, dwRemain) ;
}
VOID VtransferValue(
OUT PBYTE pubDest,
IN PBYTE pubSrc ,
IN DWORD dwBytes,
IN DWORD dwFlags,
IN DWORD dwDefaultValue, // holds bit flag value.
IN PBYTE pubHeap ) // used to form ptr if SSF_MAKE_STRINGPTR
/* this wrapper implements:
SSF_OFFSETONLY, SSF_MAKE_STRINGPTR,
SSF_SECOND_DWORD, SSF_SETRCID, SSF_STRINGLEN,
SSF_BITFIELD_ xxx
notice all of these flags are basically
mutually exclusive. But this function only
enforces this for the first three flags.
*/
{
if(dwFlags & SSF_SECOND_DWORD)
{
memcpy(pubDest, pubSrc + sizeof(DWORD) , dwBytes) ;
}
else if(dwFlags & SSF_MAKE_STRINGPTR)
{
PBYTE pubStr ;
pubStr = pubHeap + ((PARRAYREF)pubSrc)->loOffset ;
memcpy(pubDest, (PBYTE)&pubStr , sizeof(PBYTE)) ;
}
else if(dwFlags & SSF_OFFSETONLY)
{
memcpy(pubDest, (PBYTE)&(((PARRAYREF)pubSrc)->loOffset) , dwBytes) ;
}
else if(dwFlags & SSF_STRINGLEN)
{
memcpy(pubDest, (PBYTE)&(((PARRAYREF)pubSrc)->dwCount) , dwBytes) ;
}
else if(dwFlags & SSF_BITFIELD_DEF_FALSE ||
dwFlags & SSF_BITFIELD_DEF_TRUE)
{
if(*(PDWORD)pubSrc) // assume fields are zero initialized
*(PDWORD)pubDest |= dwDefaultValue ;
else
*(PDWORD)pubDest &= ~dwDefaultValue ;
}
else
{
memcpy(pubDest, pubSrc , dwBytes) ;
}
if(dwBytes == sizeof(DWORD) )
{
if(dwFlags & SSF_KB_TO_BYTES)
*(PDWORD)pubDest <<= 10 ; // convert Kbytes to bytes
else if(dwFlags & SSF_MB_TO_BYTES)
*(PDWORD)pubDest <<= 20 ; // convert Mbytes to bytes
if(dwFlags & SSF_SETRCID)
*(PDWORD)pubDest |= GET_RESOURCE_FROM_DLL ;
}
}
BOOL BspecialProcessOption(
PBYTE pubnRaw, // start of Rawbinary data
PBYTE pubDestOption, // ptr to some type of option structure.
PBYTE pubDestOptionEx,
PDFEATURE_OPTIONS pfo , // source data
IN POPTSELECT poptsel, // option array which determines path
// through atr.
PINFOHEADER pInfoHdr, // used to access global structure.
DWORD dwFea, // feature index
DWORD dwOpt,
BOOL bDefaultOpt
)
{
PGPDDRIVERINFO pGPDdriverInfo ;
// PMINIRAWBINARYDATA pmrbd ;
DWORD dwGID, dwNextOpt, dwUnresolvedFeature, dwI ;
PBYTE pubDest ;
PATREEREF patrRoot ;
PUIINFO pUIinfo ;
BOOL bStatus = TRUE ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
pGPDdriverInfo = (PGPDDRIVERINFO)((PBYTE)(pInfoHdr) +
pInfoHdr->loDriverOffset) ;
pUIinfo = (PUIINFO)((PBYTE)(pInfoHdr) +
pInfoHdr->loUIInfoOffset) ;
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
dwGID = pfo->dwGID ;
#if 0
// dead code for now.
// Extract atrMargins convert to ImageableArea, place in rcImgArea.
dwI = pStatic->dwSSPaperSizeMarginsIndex;
if(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID))
{
RECT rcMargins ;
PRECT prcImageArea ;
SIZE szPaperSize ;
patrRoot = (PATREEREF)((PBYTE)pfo +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = (PBYTE)&rcMargins ;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
// any value. Doesn't matter.
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
}
szPaperSize = ((PPAGESIZE)pubDestOption)->szPaperSize ;
prcImageArea = &((PPAGESIZE)pubDestOption)->rcImgAreaP ;
prcImageArea->left = rcMargins.left ;
prcImageArea->top = rcMargins.top ;
prcImageArea->right = szPaperSize.x - rcMargins.right ;
prcImageArea->bottom = szPaperSize.y - rcMargins.bottom ;
}
// Extract atrMin/MaxSize place in ptMin/MaxSize in GLOBALS.
dwI = pStatic->dwSSPaperSizeMinSizeIndex;
if(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID) &&
((PPAGESIZE)pubDestOption)->dwPaperSizeID == DMPAPER_USER )
{
pUIinfo->dwCustomSizeOptIndex = dwOpt ;
pUIinfo->dwFlags |= FLAG_CUSTOMSIZE_SUPPORT ;
patrRoot = (PATREEREF)((PBYTE)pfo +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = (PBYTE)(&pGPDdriverInfo->Globals) +
pStatic->snapShotTable[dwI].dwDestOffset;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
// any value. Doesn't matter.
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
}
}
dwI = pStatic->dwSSPaperSizeMaxSizeIndex;
if(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID) &&
((PPAGESIZE)pubDestOption)->dwPaperSizeID == DMPAPER_USER )
{
patrRoot = (PATREEREF)((PBYTE)pfo +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = (PBYTE)(&pGPDdriverInfo->Globals) +
pStatic->snapShotTable[dwI].dwDestOffset;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if(EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
// any value. Doesn't matter.
&dwNextOpt) != TRI_SUCCESS)
{
bStatus = FALSE ;
}
}
#endif
dwI = pStatic->dwSSPaperSizeCursorOriginIndex ;
if(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID) )
{
TRISTATUS triStatus ;
patrRoot = (PATREEREF)((PBYTE)pfo +
pStatic->snapShotTable[dwI].dwSrcOffset) ;
pubDest = pubDestOptionEx +
pStatic->snapShotTable[dwI].dwDestOffset;
dwNextOpt = 0 ; // extract info for first option selected for
// this feature.
if((triStatus = EextractValueFromTree(pubnRaw, dwI, pubDest,
&dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
// any value. Doesn't matter.
&dwNextOpt)) != TRI_SUCCESS)
{
if(triStatus == TRI_UNINITIALIZED)
{
((PPAGESIZEEX)pubDestOptionEx)->ptPrinterCursorOrig =
((PPAGESIZEEX)pubDestOptionEx)->ptImageOrigin ;
}
else
bStatus = FALSE ;
}
}
if(dwGID == GID_MEMOPTION &&
bDefaultOpt)
{
pUIinfo->dwFreeMem = ((PMEMOPTION)pubDestOption)->dwFreeMem ;
}
if(dwGID == GID_COLORMODE &&
((PCOLORMODEEX)pubDestOptionEx)->bColor )
{
pUIinfo->dwFlags |= FLAG_COLOR_DEVICE ;
}
return(bStatus);
}
TRISTATUS EextractValueFromTree(
PBYTE pubnRaw, // start of Rawbinary data
DWORD dwSSTableIndex, // some info about this value.
OUT PBYTE pubDest, // write value or link here
OUT PDWORD pdwUnresolvedFeature, // if the attribute tree has
// a dependency on this feature and the current option
// for that feature is not defined in poptsel, this
// function will write the index of the required
// feature in pdwUnresolvedFeature.
IN ATREEREF atrRoot, // root of attribute tree to navigate.
IN POPTSELECT poptsel, // option array which determines path
// through atr. may be filled with OPTION_INDEX_ANY
// if we are jumpstarting
IN DWORD dwFeature,
IN OUT PDWORD pdwNextOpt // if multiple options are selected
// for dwFeature, pdwNextOpt points to the Nth option to consider
// in the poptsel list, at return time, this value
// is incremented if there are remaining options selected,
// else is reset to zero.
// For the first call, or PICKONE features,
// this value must be set to zero.
)
{
BOOL bMissingDependency = FALSE;
PATTRIB_TREE patt ; // start of ATTRIBUTE tree array.
PENHARRAYREF pearTableContents ;
// PMINIRAWBINARYDATA pmrbd ;
DWORD dwBytes , // size of value in bytes
dwValueNodeIndex , dwNodeIndex, dwFea, dwI ,
dwDefault , // value to copy or tile to dest.
dwOption, dwFlags ;
PBYTE pubHeap , // ptr to start of heap.
pubSrc ; // ptr to value bytes
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
// obtain pointers to structures:
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
patt = (PATTRIB_TREE)(pubRaw + pearTableContents[MTI_ATTRIBTREE].
loOffset) ;
pubHeap = (PBYTE)(pubRaw + pearTableContents[MTI_STRINGHEAP].
loOffset) ;
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
dwBytes = pStatic->snapShotTable[dwSSTableIndex].dwNbytes ;
dwFlags = pStatic->snapShotTable[dwSSTableIndex].dwFlags ;
dwDefault = pStatic->snapShotTable[dwSSTableIndex].dwDefaultValue ;
// now attempt to navigate the attributeTree.
if(atrRoot == ATTRIB_UNINITIALIZED)
{
DWORD dwRemain ; // bytes remaining to copy.
UNINITIALIZED_BRANCH:
if(dwFlags & SSF_BITFIELD_DEF_FALSE)
{
*(PDWORD)pubDest &= ~dwDefault ; // clear bitflag
}
else if(dwFlags & SSF_BITFIELD_DEF_TRUE)
{
*(PDWORD)pubDest |= dwDefault ; // set bitflag
}
else if(!(dwFlags & SSF_DONT_USEDEFAULT))
{
if (dwBytes == sizeof(DWORD))
memcpy (pubDest, &dwDefault, sizeof(DWORD));
else if (dwBytes == (sizeof(DWORD)*2))
{
memcpy (pubDest, &dwDefault, sizeof(DWORD));
memcpy (pubDest+sizeof(DWORD), &dwDefault, sizeof(DWORD));
}
else
VtileDefault(pubDest, dwDefault, dwBytes) ;
}
if(dwFlags & SSF_REQUIRED)
{
ERR(("EextractValueFromTree: a required keyword is missing from the GPD file. %s\n",
pStatic->snapShotTable[dwSSTableIndex].pstrKeyword ));
return(TRI_UNINITIALIZED) ;
}
if(dwFlags & SSF_FAILIFZERO)
{ // see if dest is completely zeroed. Fail if it is.
for(dwI = 0 ; (dwI < dwBytes) && !pubDest[dwI] ; dwI++)
;
if(dwI == dwBytes)
{
ERR(("EextractValueFromTree: None of several initializers found. %s\n",
pStatic->snapShotTable[dwSSTableIndex].pstrKeyword ));
return(TRI_UNINITIALIZED) ; // of the two or more
// keywords that could have initialized this field,
// none were found.
}
}
if(dwFlags & SSF_RETURN_UNINITIALIZED)
return(TRI_UNINITIALIZED) ;
return(TRI_SUCCESS) ; // no value defined.
}
else if(atrRoot & ATTRIB_HEAP_VALUE)
{
DWORD dwTmp ;
if(dwFlags & SSF_HEAPOFFSET)
{
dwTmp = atrRoot & ~ATTRIB_HEAP_VALUE ;
pubSrc = (PBYTE)&dwTmp ;
}
else
pubSrc = pubHeap + (atrRoot & ~ATTRIB_HEAP_VALUE) ;
if (dwBytes == sizeof(DWORD) && !(dwFlags &
(SSF_SECOND_DWORD |
SSF_MAKE_STRINGPTR |
SSF_OFFSETONLY |
SSF_STRINGLEN |
SSF_BITFIELD_DEF_FALSE |
SSF_BITFIELD_DEF_TRUE |
SSF_KB_TO_BYTES |
SSF_MB_TO_BYTES |
SSF_SETRCID)))
{
memcpy (pubDest,pubSrc,sizeof(DWORD));
}
else
{
VtransferValue(pubDest, pubSrc , dwBytes, dwFlags, dwDefault, pubHeap ) ;
}
if(dwFlags & SSF_NON_LOCALIZABLE)
// pmrbd->bContainsNames = TRUE ;
; // set a flag here.
return(TRI_SUCCESS) ;
}
// atrRoot specifies a node index
dwNodeIndex = atrRoot ;
dwValueNodeIndex = END_OF_LIST ;
if(patt[dwNodeIndex].dwFeature == DEFAULT_INIT )
{
dwValueNodeIndex = dwNodeIndex ;
dwNodeIndex = patt[dwNodeIndex].dwNext ;
}
while (dwNodeIndex != END_OF_LIST)
{
if((dwFea = patt[dwNodeIndex].dwFeature) == dwFeature)
// for this feature, I may want to examine not the first
// selected option, but other selections. (PICKMANY)
// walk the PICKMANY list.
{
for(dwI = 0 ; dwI < *pdwNextOpt ; dwI++)
{
if(poptsel[dwFea].ubNext != NULL_OPTSELECT)
dwFea = poptsel[dwFea].ubNext ;
else
break ;
}
if(poptsel[dwFea].ubNext != NULL_OPTSELECT)
(*pdwNextOpt)++ ;
else
*pdwNextOpt = 0 ; // reset to indicate end of list.
}
dwOption =
(DWORD)poptsel[dwFea].ubCurOptIndex ;
if(dwOption == OPTION_PENDING)
{
ERR(("EextractValueFromTree: Fatal syntax error, circular dependency in default options.\n"));
return(TRI_UTTER_FAILURE) ;
}
if(dwOption == OPTION_INDEX_ANY)
{
*pdwUnresolvedFeature = patt[dwNodeIndex].dwFeature ;
return(TRI_AGAIN) ; // option array not fully defined.
}
// valid option for this feature, see if a matching
// node exists.
#ifndef OLDWAY
while (patt[dwNodeIndex].dwOption != dwOption &&
patt[dwNodeIndex].dwNext != END_OF_LIST)
{
dwNodeIndex = patt[dwNodeIndex].dwNext;
}
if(patt[dwNodeIndex].dwOption != dwOption &&
patt[dwNodeIndex].dwOption != DEFAULT_INIT)
{
break;
}
#else
if(!BfindMatchingOrDefaultNode(patt , &dwNodeIndex, dwOption))
{
// attribute tree does not contain the specified
// branch. Use the Global Default Initializer if exists.
break ;
}
#endif
if(patt[dwNodeIndex].eOffsetMeans == VALUE_AT_HEAP)
{
dwValueNodeIndex = dwNodeIndex ; // Eureka !
break ;
}
// does this node contain a sublevel?
if(patt[dwNodeIndex].eOffsetMeans == NEXT_FEATURE)
{
// Down to the next level we go.
dwNodeIndex = patt[dwNodeIndex ].dwOffset ;
}
else
break; // tree corruption has occurred. exit.
}
if(dwValueNodeIndex != END_OF_LIST &&
patt[dwValueNodeIndex].eOffsetMeans == VALUE_AT_HEAP )
{
if(dwFlags & SSF_HEAPOFFSET)
pubSrc = (PBYTE)&(patt[dwValueNodeIndex].dwOffset) ;
else
pubSrc = pubHeap + patt[dwValueNodeIndex].dwOffset ;
if (dwBytes == sizeof(DWORD) && !(dwFlags &
(SSF_SECOND_DWORD |
SSF_MAKE_STRINGPTR |
SSF_OFFSETONLY |
SSF_STRINGLEN |
SSF_BITFIELD_DEF_FALSE |
SSF_BITFIELD_DEF_TRUE |
SSF_KB_TO_BYTES |
SSF_MB_TO_BYTES |
SSF_SETRCID)))
{
memcpy (pubDest,pubSrc,sizeof(DWORD));
}
else
{
VtransferValue(pubDest, pubSrc , dwBytes, dwFlags, dwDefault, pubHeap ) ;
}
if(dwFlags & SSF_NON_LOCALIZABLE)
// pmrbd->bContainsNames = TRUE ;
; // set a flag here
return(TRI_SUCCESS) ;
}
// attribute tree does not contain the specified
// branch. This is not necessarily an error since
// the attribute tree is allowed to be sparsely populated.
goto UNINITIALIZED_BRANCH ;
}
BOOL RaisePriority(
DWORD dwFeature1,
DWORD dwFeature2,
PBYTE pubnRaw,
PDWORD pdwPriority)
{
// takes to lower priority feature and assigns
// it the priority of the other feature.
// The priority of all features between feature1
// and feature2 including the higher priority feature
// are demoted one level.
PENHARRAYREF pearTableContents ;
// PDWORD pdwPriority ;
DWORD dwHigherP, dwLowerP, dwFeature, dwI, dwEntries ;
PBYTE pubRaw ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
/**
pdwPriority = (PDWORD)(pubRaw + pearTableContents[MTI_PRIORITYARRAY].
loOffset) ;
**/
dwEntries = pearTableContents[MTI_PRIORITYARRAY].dwCount ;
dwHigherP = dwLowerP = dwEntries ; // init to invalid value.
// a Priority 1 is considered
// a 'higher' priority than a priority 2, but arithmetically its
// the other way around.
for(dwI = 0 ; dwI < dwEntries ; dwI++)
{
if(pdwPriority[dwI] == dwFeature1)
{
if(dwHigherP == dwEntries)
dwHigherP = dwI ;
else
{
dwLowerP = dwI ;
break ;
}
}
else if(pdwPriority[dwI] == dwFeature2)
{
if(dwHigherP == dwEntries)
dwHigherP = dwI ;
else
{
dwLowerP = dwI ;
break ;
}
}
}
// BUG_BUG paranoid: could verify
// if( dwHigherP == dwEntries || dwLowerP == dwEntries )
// return(FALSE); priority array or arg values
// are corrupted .
ASSERT(dwHigherP != dwEntries && dwLowerP != dwEntries);
dwFeature = pdwPriority[dwLowerP] ; // this feature will be promoted.
for(dwI = dwLowerP ; dwI > dwHigherP ; dwI--)
{
pdwPriority[dwI] = pdwPriority[dwI - 1] ;
}
pdwPriority[dwHigherP] = dwFeature ;
return(TRUE) ;
}
DWORD dwNumOptionSelected(
IN DWORD dwNumFeatures,
IN POPTSELECT poptsel
)
/* reports number of options actually selected in
option select array. The caller supplies dwNumFeatures -
the number of Doc and Printer sticky features, and this
function does the rest. The actual number of options
selected may be larger than dwNumFeatures if there are
PICKMANY features. */
{
DWORD dwCount, dwI, // feature Index
dwNext ; // if pick many, next option selection for this feature.
dwCount = dwNumFeatures ;
for(dwI = 0 ; dwI < dwNumFeatures ; dwI++)
{
for(dwNext = dwI ;
poptsel[dwNext].ubNext != NULL_OPTSELECT ;
dwNext = poptsel[dwNext].ubNext )
{
dwCount++ ;
}
}
return(dwCount) ;
}
// assume a pointer to this table is stored in the RAWbinary data.
BOOL BinitSnapShotIndexTable(PBYTE pubnRaw)
/*
snapShotTable[] is assumed to be divided into sections
with an entry with dwNbytes = 0 dividing the sections.
The end of the table is also terminated by an entry
with dwNbytes = 0.
This function initializes pmrbd->ssTableIndex
which serves as an index into pmrbd->snapShotTable.
*/
{
PSTATICFIELDS pStatic ;
// PMINIRAWBINARYDATA pmrbd ;
DWORD dwI, // snapShotTable Index
dwSect ; // SSTABLEINDEX Index
PRANGE prng ;
pStatic = (PSTATICFIELDS)pubnRaw ;
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pStatic->ssTableIndex = (PRANGE)
MemAlloc(sizeof(RANGE) * MAX_STRUCTURETYPES) ;
if(!pStatic->ssTableIndex)
return(FALSE) ;
prng = pStatic->ssTableIndex ;
for(dwI = dwSect = 0 ; dwSect < MAX_STRUCTURETYPES ; dwSect++, dwI++)
{
prng[dwSect].dwStart = dwI ;
for( ; pStatic->snapShotTable[dwI].dwNbytes ; dwI++ )
;
prng[dwSect].dwEnd = dwI ; // one past the last entry
}
return(TRUE);
}
BOOL BinitSizeOptionTables(PBYTE pubnRaw)
{
// PMINIRAWBINARYDATA pmrbd ;
PSTATICFIELDS pStatic ;
pStatic = (PSTATICFIELDS)pubnRaw ;
// pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
pStatic->pdwSizeOption = (PDWORD)
MemAlloc(sizeof(DWORD) * MAX_GID * 2) ;
if(!pStatic->pdwSizeOption)
return(FALSE) ;
pStatic->pdwSizeOptionEx = pStatic->pdwSizeOption + MAX_GID ;
pStatic->pdwSizeOption[GID_RESOLUTION] = sizeof(RESOLUTION);
pStatic->pdwSizeOptionEx[GID_RESOLUTION] = sizeof(RESOLUTIONEX);
pStatic->pdwSizeOption[GID_PAGESIZE] = sizeof(PAGESIZE);
pStatic->pdwSizeOptionEx[GID_PAGESIZE] = sizeof(PAGESIZEEX);
pStatic->pdwSizeOption[GID_PAGEREGION] = sizeof(OPTION);
pStatic->pdwSizeOptionEx[GID_PAGEREGION] = 0 ;
pStatic->pdwSizeOption[GID_DUPLEX] = sizeof(DUPLEX);
pStatic->pdwSizeOptionEx[GID_DUPLEX] = 0 ;
pStatic->pdwSizeOption[GID_INPUTSLOT] = sizeof(INPUTSLOT);
pStatic->pdwSizeOptionEx[GID_INPUTSLOT] = 0 ; // sizeof(INPUTSLOTEX);
pStatic->pdwSizeOption[GID_MEDIATYPE] = sizeof(MEDIATYPE);
pStatic->pdwSizeOptionEx[GID_MEDIATYPE] = 0 ;
pStatic->pdwSizeOption[GID_MEMOPTION] = sizeof(MEMOPTION);
pStatic->pdwSizeOptionEx[GID_MEMOPTION] = 0 ;
pStatic->pdwSizeOption[GID_COLORMODE] = sizeof(COLORMODE);
pStatic->pdwSizeOptionEx[GID_COLORMODE] = sizeof(COLORMODEEX);
pStatic->pdwSizeOption[GID_ORIENTATION] = sizeof(ORIENTATION);
pStatic->pdwSizeOptionEx[GID_ORIENTATION] = 0 ;
pStatic->pdwSizeOption[GID_PAGEPROTECTION] = sizeof(PAGEPROTECT);
pStatic->pdwSizeOptionEx[GID_PAGEPROTECTION] = 0 ;
pStatic->pdwSizeOption[GID_COLLATE] = sizeof(COLLATE);
pStatic->pdwSizeOptionEx[GID_COLLATE] = 0 ;
pStatic->pdwSizeOption[GID_OUTPUTBIN] = sizeof(OUTPUTBIN);
pStatic->pdwSizeOptionEx[GID_OUTPUTBIN] = 0 ;
pStatic->pdwSizeOption[GID_HALFTONING] = sizeof(HALFTONING);
pStatic->pdwSizeOptionEx[GID_HALFTONING] = 0 ;
// outside array bounds.
// pmrbd->pdwSizeOption[GID_UNKNOWN] = sizeof(OPTION);
// pmrbd->pdwSizeOptionEx[GID_UNKNOWN] = 0 ;
return(TRUE) ;
}
PRAWBINARYDATA
LoadRawBinaryData (
IN PTSTR ptstrDataFilename
)
/*++
Routine Description:
Load raw binary printer description data.
Arguments:
ptstrDataFilename - Specifies the name of the original printer description file
Return Value:
Pointer to raw binary printer description data
NULL if there is an error
--*/
{
// PMINIRAWBINARYDATA pmrbd ;
PSTATICFIELDS pStatic ;
PRAWBINARYDATA pnRawData; // actually points to pStatic structure
DWORD dwI ;
// extern int giDebugLevel ;
// giDebugLevel = 5 ;
//
// Sanity check
//
if (ptstrDataFilename == NULL) {
ERR(("GPD filename is NULL.\n"));
return NULL;
}
//
// Attempt to load cached binary printer description data first
//
if (!(pnRawData = GpdLoadCachedBinaryData(ptstrDataFilename)))
{
#ifndef KERNEL_MODE
#ifdef PARSERLIB
(VOID) BcreateGPDbinary(ptstrDataFilename, 0) ;
// 0 = min Verbosity Level
pnRawData = GpdLoadCachedBinaryData(ptstrDataFilename) ;
#else PARSERLIB
//
// If there is no cached binary data or it's out-of-date, we'll parse
// the ASCII text file and cache the resulting binary data.
//
DWORD pathlen = 0 ;
DWORD namelen = 0 ;
WCHAR * pwDLLQualifiedName = NULL ;
// WCHAR awchDLLpath[MAX_PATH];
PWSTR pwstrDLLname = TEXT("gpdparse.dll") ;
typedef BOOL (*PFBCREATEGPDBINARY)(PWSTR, DWORD) ;
PFBCREATEGPDBINARY pfBcreateGPDbinary = NULL ;
PWSTR pwstrLastBackSlash ;
HINSTANCE hParser = NULL ;
// how large should pwDLLQualifiedName be???
pathlen = wcslen(ptstrDataFilename) ;
namelen = pathlen + wcslen(pwstrDLLname) + 1;
if(!(pwDLLQualifiedName = (PWSTR)MemAllocZ(namelen * sizeof(WCHAR)) ))
{
ERR(("Fatal: unable to alloc memory for pwDLLQualifiedName: %d WCHARs.\n",
namelen));
return(NULL) ; // This is unrecoverable
}
wcsncpy(pwDLLQualifiedName, ptstrDataFilename , namelen);
if (pwstrLastBackSlash = wcsrchr(pwDLLQualifiedName, TEXT('\\')))
{
*(pwstrLastBackSlash + 1) = NUL;
// wcscat(pwDLLQualifiedName, pwstrDLLname) ;
StringCchCatW(pwDLLQualifiedName, namelen, pwstrDLLname);
hParser = LoadLibrary(pwDLLQualifiedName) ;
if(hParser)
pfBcreateGPDbinary = (PFBCREATEGPDBINARY)GetProcAddress(hParser, "BcreateGPDbinary") ;
else
ERR(("Couldn't load gpdparse.dll: %S\n", pwDLLQualifiedName)) ;
if(pfBcreateGPDbinary)
(VOID) pfBcreateGPDbinary(ptstrDataFilename, 0) ;
// 0 = min Verbosity Level
if(hParser)
FreeLibrary(hParser) ;
pnRawData = GpdLoadCachedBinaryData(ptstrDataFilename) ;
}
if(pwDLLQualifiedName)
MemFree(pwDLLQualifiedName) ;
#endif PARSERLIB
#endif KERNEL_MODE
}
if(!pnRawData)
{
// there is nothing I can do about this now.
ERR(("Unable to locate or create Binary data.\n"));
SetLastError(ERROR_FILE_CORRUPT);
return NULL;
}
pStatic = (PSTATICFIELDS)pnRawData ;
/* BETA2 */
// pmrbd->rbd.pvReserved = NULL; Do when creating BUD file.
pStatic->pdwSizeOption = NULL ;
pStatic->ssTableIndex = NULL ;
pStatic->snapShotTable = NULL ;
// Call initialization functions to setup a few tables
// needed to create snapshots.
if(BinitSizeOptionTables((PBYTE)pnRawData) &&
(dwI = DwInitSnapShotTable1((PBYTE)pnRawData) ) &&
(dwI = DwInitSnapShotTable2((PBYTE)pnRawData, dwI) ) &&
(dwI < MAX_SNAPSHOT_ELEMENTS) &&
BinitSnapShotIndexTable((PBYTE)pnRawData) )
{
return (pnRawData);
}
if(dwI >= MAX_SNAPSHOT_ELEMENTS)
RIP(("Too many entries to fit inside SnapShotTable\n"));
UnloadRawBinaryData (pnRawData) ;
return (NULL); // failure
}
PRAWBINARYDATA
GpdLoadCachedBinaryData(
PTSTR ptstrGpdFilename
)
/*++
Routine Description:
Load cached binary GPD data file into memory
Arguments:
ptstrGpdFilename - Specifies the GPD filename
Return Value:
Pointer to Binary GPD data if successful, NULL if there is an error
BETA2 returns pointer to pStatic.
--*/
{
HFILEMAP hFileMap;
DWORD dwSize;
PVOID pvData;
PTSTR ptstrBpdFilename;
PRAWBINARYDATA pRawData ;
PSTATICFIELDS pstaticData = NULL;
// PMINIRAWBINARYDATA pmrbd ;
//
// Generate BPD filename from the specified PPD filename
//
if (! (ptstrBpdFilename = pwstrGenerateGPDfilename(ptstrGpdFilename)))
return NULL;
//
// First map the data file into memory
//
if (! (hFileMap = MapFileIntoMemory(ptstrBpdFilename, &pvData, &dwSize)))
{
// ERR(("Couldn't map file '%ws' into memory: %d\n", ptstrBpdFilename, GetLastError()));
MemFree(ptstrBpdFilename);
return NULL;
}
//
// Verify size, parser version number, and signature.
// Allocate a memory buffer and copy data into it.
//
pRawData = pvData;
// pmrbd = (PMINIRAWBINARYDATA)pRawData ;
pstaticData = NULL;
if ((dwSize > sizeof(PMINIRAWBINARYDATA) +
sizeof(ENHARRAYREF) * MTI_NUM_SAVED_OBJECTS) &&
(dwSize >= pRawData->dwFileSize) &&
(pRawData->dwParserVersion == GPD_PARSER_VERSION) &&
(pRawData->dwParserSignature == GPD_PARSER_SIGNATURE) &&
(BIsRawBinaryDataInDate((PBYTE)pRawData)) &&
(pstaticData = MemAlloc(sizeof(STATICFIELDS))))
{
CopyMemory(&(pstaticData->rbd), pRawData, sizeof(RAWBINARYDATA));
// copy only the first structure of the BUD file.
pstaticData->hFileMap = hFileMap ;
pstaticData->pubBUDData = (PBYTE)pRawData ; // BETA2
// this points to the entire BUD file.
}
else
{
ERR(("Invalid binary GPD data\n")); // warning
SetLastError(ERROR_INVALID_DATA);
UnmapFileFromMemory(hFileMap); // BETA2
MemFree(ptstrBpdFilename);
return(NULL) ; // fatal error.
}
MemFree(ptstrBpdFilename);
return &(pstaticData->rbd); // BETA2
}
VOID
UnloadRawBinaryData (
IN PRAWBINARYDATA pnRawData
)
{
PSTATICFIELDS pStatic ;
// PMINIRAWBINARYDATA pmrbd ;
// pmrbd = (PMINIRAWBINARYDATA)pRawData ;
pStatic = (PSTATICFIELDS)pnRawData ;
if(!pnRawData)
{
ERR(("GpdUnloadRawBinaryData given Null ptr.\n"));
return ;
}
if(pStatic->pdwSizeOption)
MemFree(pStatic->pdwSizeOption);
if(pStatic->ssTableIndex)
MemFree(pStatic->ssTableIndex);
if(pStatic->snapShotTable)
MemFree(pStatic->snapShotTable);
UnmapFileFromMemory(pStatic->hFileMap); // BETA2
MemFree(pnRawData);
}
PINFOHEADER
InitBinaryData(
IN PRAWBINARYDATA pnRawData, // actually pStatic
IN PINFOHEADER pInfoHdr,
IN POPTSELECT pOptions
)
{
BOOL bDeleteOptArray = FALSE ;
if(pInfoHdr)
{
FreeBinaryData(pInfoHdr) ;
// there's no advantage to keeping the block
// if we are going to reinitialize everything.
// eventually we can optimize.
}
if(!pOptions) // if not passed from UI
{
bDeleteOptArray = TRUE ;
pOptions = (POPTSELECT)MemAlloc(sizeof(OPTSELECT) * MAX_COMBINED_OPTIONS) ;
if(!pOptions ||
!BinitDefaultOptionArray(pOptions, (PBYTE)pnRawData))
{
if(pOptions)
MemFree(pOptions);
return(NULL); // Bummer, you lose any pInfoHdr you passed in.
}
}
pInfoHdr = PINFOHDRcreateSnapshot((PBYTE)pnRawData, pOptions) ;
if(bDeleteOptArray && pOptions)
MemFree(pOptions);
return( pInfoHdr );
}
VOID
FreeBinaryData(
IN PINFOHEADER pInfoHdr
)
{
if(pInfoHdr)
MemFree(pInfoHdr);
}
BOOL BIsRawBinaryDataInDate(
IN PBYTE pubRaw) // this is pointer to memory mapped file! BETA2
{
#ifdef KERNEL_MODE
return(TRUE);
#else // !KERNEL_MODE
PENHARRAYREF pearTableContents ;
PGPDFILEDATEINFO pfdi ;
DWORD dwNumFiles, dwI ;
BOOL bInDate ;
PBYTE pubHeap ;
PWSTR pwstrFileName ;
FILETIME FileTime;
HANDLE hFile;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pubHeap = pubRaw + pearTableContents[MTI_STRINGHEAP].loOffset ;
dwNumFiles = pearTableContents[MTI_GPDFILEDATEINFO].dwCount ;
pfdi = (PGPDFILEDATEINFO)(pubRaw + pearTableContents[MTI_GPDFILEDATEINFO].
loOffset) ;
for(dwI = 0 ; dwI < dwNumFiles ; dwI++)
{
pwstrFileName = OFFSET_TO_POINTER(pubHeap, pfdi[dwI].arFileName.loOffset);
bInDate = FALSE ;
hFile = CreateFile(pwstrFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS,
NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
if (GetFileTime(hFile, NULL, NULL, &FileTime))
bInDate = (CompareFileTime(&FileTime, &pfdi[dwI].FileTime) == 0 ) ;
else
ERR(("GetFileTime '%S' failed.\n", pwstrFileName));
CloseHandle(hFile);
}
else {
ERR(("CreateFile '%S' failed.\n", pwstrFileName));
}
if(!bInDate)
{
ERR(("Raw binary data file is out-of-date.\n"));
return(FALSE) ;
}
}
return(TRUE);
#endif // !KERNEL_MODE
}
// Puts the Index of Feature Locale(if present) in *pdwFea and returns TRUE.
// If Locale not present returns TRUE and puts -1 in *pdwFea.
// Any other processing error, returns FALSE.
BOOL BgetLocFeaIndex (
IN PRAWBINARYDATA pnRawData,
OUT PDWORD pdwFea // The index of the Locale feature
)
{
DWORD dwNumFeatures, // Total Number of features
dwHeapOffset;
BOOL bStatus = TRUE; // Warning!!!!!!.
// Dont remove initialization.
PBYTE pubSrc,
pubRaw,
pubResourceData;
ATREEREF atrLocKW;
PDFEATURE_OPTIONS pfoSrc;
PENHARRAYREF pearTableContents;
// At this point we only have the raw data which is a big structure
// with arrays, trees etc. Function PINFOHDRcreateSnapshota()
// goes through all the Raw Data and extracts info into well defined
// structures from where it is easy to get the required information.
// Unfortunately when this function is called, PINFOHDRcreateSnapshot()
// has not been called earlier, so we are left with getting our hands
// dirty with the raw data.
// Since it does make sense to go through the entire raw data just to
// get the small info that we want, we will attempt to navigate only
// certain areas.
pubRaw = ((PSTATICFIELDS)pnRawData)->pubBUDData;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pubResourceData = pubRaw + pearTableContents[MTI_STRINGHEAP].loOffset;
pfoSrc = (PDFEATURE_OPTIONS)(pubRaw +
pearTableContents[MTI_DFEATURE_OPTIONS].loOffset);
dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
// dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
if(dwNumFeatures > MAX_COMBINED_OPTIONS)
return FALSE; // too many
for ( *pdwFea = 0; bStatus && (*pdwFea < dwNumFeatures); (*pdwFea)++)
{
atrLocKW = pfoSrc[*pdwFea].atrFeaKeyWord;
if ( atrLocKW & ATTRIB_HEAP_VALUE)
{
// Get a pointer to the ARRAYREF structure that holds the
// heap offset of the real string.
pubSrc = (pubResourceData + (atrLocKW & ~ATTRIB_HEAP_VALUE));
dwHeapOffset = *((PDWORD)&(((PARRAYREF)pubSrc)->loOffset));
}
else
{
// It can come here either
// if (atrRoot == ATTRIB_UNINITIALIZED
// For a *Feature: <symbolname> to appear
// without <symbolname> is a syntactic error.
// Has to be caught earlier.
// or if
// patt[dwNodeIndex].dwFeature == DEFAULT_INIT)
// or if it points to another node.
// These should never happen.
// Feature keyword not initialized. Serious Problem.
// Should have been caught in the parsing stage. Cannot continue.
ERR(("Feature Symbol Name cannot be determined\n"));
bStatus = FALSE;
}
if ( bStatus && !strncmp(LOCALE_KEYWORD,
(LPSTR)OFFSET_TO_POINTER(pubResourceData, dwHeapOffset),
strlen(LOCALE_KEYWORD) ) )
{
// FOUND.... Locale.
break;
}
} //for *pdwFea
if (bStatus && *pdwFea == dwNumFeatures)
{
//Feature Locale does not appear in the GPD. Nothing to do.
*pdwFea = (DWORD)-1;
}
return bStatus;
} //BgetLocFeaIndex(...)
/*++
Returns FALSE if some processing error occurs.
If TRUE is returned then
i) if dwFea = -1 --> *Feature:Locale not found.
ii) if dwFea != -1 but dwOptIndex = -1, --> None of the options
match system locale. OR for some reason we have not been
able to determine default option. The calling function may
handle whatever way it wants.
iii) if neither dwFea nor dwOptIndex is -1 --> Locale feature and
matching option index found.
1) Check if Locale keyword appears in the .gpd. If no, return. No action is
required. This process also gets the Index of the Locale feature
if present,
2) query the SystemDefaultLCID. Reason: We want to see which Locale
option in .gpd matches the SystemLCID.
3) Go through the option array of the Locale feature and get the Index of
the option that has OptionId = SystemDefaultCodePage.
IMPORTANT assumption here is that only one Option will match
the system LCID. Multiple matching option will result in
great ambiguity.
4) If option not present in GPD, do nothing. return quietly.
--*/
BOOL BgetLocFeaOptIndex(
IN PRAWBINARYDATA pnRawData,
OUT PDWORD pdwFea, // Assuming space already allocated.
OUT PDWORD pdwOptIndex // Assuming space already allocated.
)
{
DWORD dwNumFeatures, // Total features
dwNumOptions, // Total number of options for a feature.
// dwOptionID
dwValue; //
ATREEREF atrOptIDRoot, // Root of OptionID attrib tree.
// The OptionID (which is = the LCID)
// is determined by following tree rooted
// at atrOptIDRoot
atrOptIDNode; // The heap pointer ( leaf of the tree).
LCID lcidSystemLocale; // The System locale
PENHARRAYREF pearTableContents;
PBYTE pubnRaw,
pubRaw;
PDFEATURE_OPTIONS pfo;
PBYTE pubHeap;
PATTRIB_TREE patt;
pubRaw = ((PSTATICFIELDS)pnRawData)->pubBUDData;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
pfo = (PDFEATURE_OPTIONS) (pubRaw +
pearTableContents[MTI_DFEATURE_OPTIONS].loOffset);
// 1. Extract index of feature locale from raw data
if ( !BgetLocFeaIndex(pnRawData, pdwFea))
return FALSE; //Big Time Error.
if (*pdwFea == -1) {
return TRUE; //indicates nothing to do. For reasons go into the
// function dwGetLocFeaIndex
}
lcidSystemLocale = LOCALE_SYSTEM_DEFAULT;
#ifndef WINNT_40
// 2) Determine the locale(LCID) and put it in lcidSystemLocale
if ( ! (lcidSystemLocale = GetSystemDefaultLCID() ) )
{
ERR(("Cannot determine System locale\n") );
*pdwOptIndex = (DWORD)-1; //No matching option found.
return TRUE;
}
#endif //ifndef WINNT_40
// 3. Get Index (dwOptIndex) of Option whose OptionID = lcidSystemLocale
patt = (PATTRIB_TREE)(pubRaw + pearTableContents[MTI_ATTRIBTREE].
loOffset) ;
pubHeap = (PBYTE)(pubRaw + pearTableContents[MTI_STRINGHEAP].
loOffset) ;
// Pointer to root of atrOptIdvalue tree (or list)
atrOptIDRoot = pfo[*pdwFea].atrOptIDvalue;
if(atrOptIDRoot == ATTRIB_UNINITIALIZED)
{
// GPD is coded incorrectly though it may be correct syntactically.
// The reason for the error is :
// Every option for the Locale Feature
// has to have an OptionID that matches the LCID values as
// specified in Win32. If *OptionID field does not appear in
// the Option construct, it is an inexcusable error.
// Instead of failing, let us just indicate that we have not been
// able to determine the default option i.e. *pdwOptIndex = -1.
*pdwOptIndex = (DWORD)-1;
return TRUE; // or should it be FALSE
}
else if (atrOptIDRoot & ATTRIB_HEAP_VALUE)
{
// It cannot appear here.
// Because *OptionID is ATT_LOCAL_OPTION_ONLY
// Instead of failing, let us prefer to continue
ERR(("OptionID for Feature Locale cannot be determined\n"));
*pdwOptIndex = (DWORD)-1;
return TRUE;
}
else if (patt[atrOptIDRoot].dwFeature == DEFAULT_INIT)
{
if ( patt[atrOptIDRoot].dwNext == END_OF_LIST)
{
*pdwOptIndex = (DWORD)-1;
return TRUE;
}
atrOptIDRoot = patt[atrOptIDRoot].dwNext ; // to the next node.
}
for(; atrOptIDRoot != END_OF_LIST;
atrOptIDRoot = patt[atrOptIDRoot].dwNext)
{
// Should not be anything else.
if( patt[atrOptIDRoot].eOffsetMeans == VALUE_AT_HEAP)
{
atrOptIDNode = patt[atrOptIDRoot].dwOffset;
dwValue = *(PDWORD)(pubHeap + atrOptIDNode );
if (dwValue == (DWORD)lcidSystemLocale)
// Found the option with matching LCID
{
*pdwOptIndex = patt[atrOptIDRoot].dwOption;
break;
}
} //if
else
{
ERR(("OptionID for Feature Locale cannot be determined\n"));
*pdwOptIndex = (DWORD)-1;
return TRUE;
}
} // for
// 4. Option not present in GPD i.e. Matching locale not found
// Let the default as specified in GPD continue as default.
if ( atrOptIDRoot == END_OF_LIST)
{
*pdwOptIndex = (DWORD)-1;
}
return TRUE;
} //BgetLocFeaOptIndex
#endif PARSERDLL
BOOL BfindMatchingOrDefaultNode(
IN PATTRIB_TREE patt , // start of ATTRIBUTE tree array.
IN OUT PDWORD pdwNodeIndex, // Points to first node in chain
IN DWORD dwOptionID // may even take on the value DEFAULT_INIT
)
/* caller passes a NodeIndex that points to the first node in
a horizontal (option) chain. Caller finds via optionarray
the corresponding dwOption that is associated with this
feature.
search horizontally along the tree searching for a matching
option. If found, return the index of that node, else see
if there is a default initializer node at the end of the chain.
*/
{
for( ; FOREVER ; )
{
if(patt[*pdwNodeIndex].dwOption == dwOptionID )
{
// we found it!
return(TRUE) ;
}
if(patt[*pdwNodeIndex].dwNext == END_OF_LIST)
{
if(patt[*pdwNodeIndex].dwOption == DEFAULT_INIT )
return(TRUE) ;
return(FALSE) ;
}
*pdwNodeIndex = patt[*pdwNodeIndex].dwNext ;
}
return FALSE;
}