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.
 
 
 
 
 
 

612 lines
21 KiB

// Copyright (c) 1996-1999 Microsoft Corporation
/*
* installb.c - creates synthesized features and options and
* associated constraints and links to the installable
* feature or options.
*/
#include "gpdparse.h"
// ---- functions defined in installb.c ---- //
DWORD DwCountSynthFeatures(
IN BOOL (*fnBCreateFeature)(DWORD, DWORD, DWORD, PGLOBL ), // callback
IN OUT PGLOBL pglobl
) ;
BOOL BCreateSynthFeatures(
IN DWORD dwFea, // index of installable feature
IN DWORD dwOpt, // index of installable Option or set to INVALID_INDEX
IN DWORD dwSynFea,
IN OUT PGLOBL pglobl) ;
BOOL BEnableInvInstallableCombos(
PGLOBL pglobl) ;
// ---------------------------------------------------- //
DWORD DwCountSynthFeatures(
IN BOOL (*fnBCreateFeature)(DWORD, DWORD, DWORD, PGLOBL ), // callback
IN OUT PGLOBL pglobl
)
/*
This function is called twice by PostProcess().
the first pass sets fnBCreateFeature = NULL
we just need to find out how many installable features and options
exist. Then we allocate this many synthesized features (outside of
this function)
In the second pass, we actually initialize the synthesized features
and all the constraints applicable to that feature. This is the
job of fnBCreateFeature.
*/
{
DWORD dwOpt , dwHeapOffset, dwNodeIndex,
dwFea, dwNumFea, dwNumOpt, dwNumSynFea ;
PDFEATURE_OPTIONS pfo ;
PATTRIB_TREE patt ; // start of ATTRIBUTE tree array.
PATREEREF patr ;
if(fnBCreateFeature &&
!gMasterTable[MTI_SYNTHESIZED_FEATURES].dwArraySize)
return(0) ; // May skip 2nd pass if dwNumSynFea == 0
patt = (PATTRIB_TREE) gMasterTable[MTI_ATTRIBTREE].pubStruct ;
pfo = (PDFEATURE_OPTIONS) gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct ;
dwNumFea = gMasterTable[MTI_DFEATURE_OPTIONS].dwArraySize ;
dwNumSynFea = 0 ;
for(dwFea = 0 ; dwFea < dwNumFea ; dwFea++)
{
if(!fnBCreateFeature)
{ // first pass clear all links to synthesiszed features.
// this will catch errors if gpd writer attempts to
// reference non-installable feature/options in
// InstalledConstraints and invalidInstallableCombinations.
pfo[dwFea].dwInstallableFeatureIndex = // backlink to Feature/Option
pfo[dwFea].dwInstallableOptionIndex = // that prompted this feature.
pfo[dwFea].dwFeatureSpawnsFeature = INVALID_INDEX;
// If this feature is installable, this points to the
// index of the resulting synthesized feature.
}
if(BReadDataInGlobalNode(&pfo[dwFea].atrFeaInstallable,
&dwHeapOffset, pglobl) &&
*(PDWORD)(mpubOffRef + dwHeapOffset) == BT_TRUE)
{
if(fnBCreateFeature)
{
if(!fnBCreateFeature(dwFea, INVALID_INDEX, dwNumSynFea, pglobl) )
// featureIndex, optionIndex, index of SynFea
{
ERR(("DwCountSynthFeatures: Unable to create synthesized feature for installable Feature index %d.\n",
dwFea));
pfo[dwFea].dwFeatureSpawnsFeature = INVALID_INDEX;
}
}
dwNumSynFea++ ;
}
dwNumOpt = pfo[dwFea].dwNumOptions ;
patr = &pfo[dwFea].atrOptInstallable ;
if(*patr == ATTRIB_UNINITIALIZED)
continue ;
if(*patr & ATTRIB_HEAP_VALUE)
{
ERR(("Internal error: DwCountSynthFeatures - atrOptInstallable should never be branchless.\n"));
continue ;
}
for(dwOpt = 0 ; dwOpt < dwNumOpt ; dwOpt++)
{
DWORD dwNodeIndex ;
dwNodeIndex = *patr ; // to avoid overwriting
// the attribute tree.
if(BfindMatchingOrDefaultNode(
patt , // start of ATTRIBUTE tree array.
&dwNodeIndex, // Points to first node in chain
dwOpt // may even take on the value DEFAULT_INIT
) )
{
if((patt[dwNodeIndex].eOffsetMeans == VALUE_AT_HEAP) &&
*(PDWORD)(mpubOffRef + patt[dwNodeIndex].dwOffset) == BT_TRUE )
{
if(fnBCreateFeature)
{
if(!fnBCreateFeature(dwFea, dwOpt, dwNumSynFea, pglobl) )
// featureIndex, optionIndex, index of SynFea
{
ERR(("DwCountSynthFeatures: Unable to create synthesized feature for installable option: fea=%d, opt=%d.\n",
dwFea, dwOpt));
pfo[dwFea].atrOptionSpawnsFeature = ATTRIB_UNINITIALIZED ;
// destroys the entire attribute tree for this feature,
// but what choice do we have? Something has gone terribly
// wrong.
}
}
dwNumSynFea++ ;
}
}
}
}
if(fnBCreateFeature)
BEnableInvInstallableCombos(pglobl) ;
return(dwNumSynFea) ;
}
BOOL BCreateSynthFeatures(
IN DWORD dwFea, // index of installable feature
IN DWORD dwOpt, // index of installable Option or set to INVALID_INDEX
IN DWORD dwSynFea, // index of synthesized feature
IN OUT PGLOBL pglobl)
{
DWORD dwOptI , dwHeapOffset, dwNodeIndex, dwValue,
dwPrevsNode, dwNewCnstRoot, dwJ, dwCNode ,
dwNumFea, dwNumOpt, dwOut, dwIn ;
BOOL bPrevsExists, bStatus = TRUE ;
PDFEATURE_OPTIONS pfo, pfoSyn ;
PGLOBALATTRIB pga ;
PATTRIB_TREE patt ; // start of ATTRIBUTE tree array.
PATREEREF patr ;
PCONSTRAINTS pcnstr ; // start of CONSTRAINTS array.
pcnstr = (PCONSTRAINTS) gMasterTable[MTI_CONSTRAINTS].pubStruct ;
patt = (PATTRIB_TREE) gMasterTable[MTI_ATTRIBTREE].pubStruct ;
pga = (PGLOBALATTRIB)gMasterTable[MTI_GLOBALATTRIB].pubStruct ;
pfo = (PDFEATURE_OPTIONS) gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct ;
pfoSyn = (PDFEATURE_OPTIONS) gMasterTable[MTI_SYNTHESIZED_FEATURES].pubStruct ;
dwNumFea = gMasterTable[MTI_DFEATURE_OPTIONS].dwArraySize ;
// initialize all fields with UNINITIALIZED just like normal fea/opt;
for(dwJ = 0 ; dwJ < gMasterTable[MTI_SYNTHESIZED_FEATURES].dwElementSiz /
sizeof(ATREEREF) ; dwJ++)
{
((PATREEREF)( (PDFEATURE_OPTIONS)gMasterTable[MTI_SYNTHESIZED_FEATURES].
pubStruct + dwSynFea))[dwJ] =
ATTRIB_UNINITIALIZED ; // the DFEATURE_OPTIONS struct is
// comprised entirely of ATREEREFs.
}
// create links between installable feature/option and
// the synthesized feature.
if(dwOpt != INVALID_INDEX)
{
if(!BexchangeDataInFOATNode(
dwFea,
dwOpt,
offsetof(DFEATURE_OPTIONS, atrOptionSpawnsFeature),
&dwOut, // previous contents of attribute node
&dwSynFea, FALSE, pglobl)) // new contents of attribute node.
return(FALSE);
// If this option is installable, this points to the
// index of the resulting synthesized feature.
}
else
pfo[dwFea].dwFeatureSpawnsFeature = dwSynFea;
// If this feature is installable, this points to the
// index of the resulting synthesized feature.
// note because this is temporary information,
// the index is stored directly into the atr node without
// even a HEAP_OFFSET flag.
// backlink to Feature/Option that created this syn feature.
// note dwOpt always initializes properly even if invalid.
pfoSyn[dwSynFea].dwInstallableFeatureIndex = dwFea ;
pfoSyn[dwSynFea].dwInstallableOptionIndex = dwOpt ;
// now initialize all other fields needed to establish
// a legitimate feature with 2 options!
// -------- Synthesize a Feature name. ------ //
if(dwOpt == INVALID_INDEX)
{ // installable Feature
pfoSyn[dwSynFea].atrFeaDisplayName =
pfo[dwFea].atrInstallableFeaDisplayName ;
pfoSyn[dwSynFea].atrFeaRcNameID =
pfo[dwFea].atrInstallableFeaRcNameID ;
}
else // installable Option
{
if(!BexchangeDataInFOATNode(
dwFea,
dwOpt,
offsetof(DFEATURE_OPTIONS, atrInstallableOptDisplayName ) ,
&dwHeapOffset, // previous contents of attribute node
NULL, FALSE, pglobl)) // NULL means Don't overwrite.
return(FALSE) ;
if(dwHeapOffset != INVALID_INDEX)
{
pfoSyn[dwSynFea].atrFeaDisplayName =
dwHeapOffset | ATTRIB_HEAP_VALUE ;
}
if(!BexchangeDataInFOATNode(
dwFea,
dwOpt,
offsetof(DFEATURE_OPTIONS, atrInstallableOptRcNameID ) ,
&dwHeapOffset, // previous contents of attribute node
NULL, FALSE, pglobl)) // NULL means Don't overwrite.
return(FALSE) ;
if(dwHeapOffset != INVALID_INDEX)
{
pfoSyn[dwSynFea].atrFeaRcNameID =
dwHeapOffset | ATTRIB_HEAP_VALUE ;
}
}
{ // !!! new stuff
PBYTE pubBaseKeyword = "SynthesizedFea_";
BYTE aubNum[4] ;
DWORD dwBaselen, dwDummy , dwI, dwNum = dwSynFea;
ARRAYREF arSymbolName ;
// compose featurekeyword string incorporating dwSynFea
// convert dwSynFea into 3 digit number.
for(dwI = 0 ; dwI < 3 ; dwI++)
{
aubNum[2 - dwI] = '0' + (BYTE)(dwNum % 10);
dwNum /= 10 ;
}
aubNum[3] = '\0' ; // null terminate
dwBaselen = strlen(pubBaseKeyword);
if(!BwriteToHeap(&arSymbolName.loOffset,
pubBaseKeyword, dwBaselen, 1, pglobl))
return(FALSE);
if(!BwriteToHeap(&dwDummy,
aubNum, 4, 1, pglobl)) // append 3 digit number to base + null terminator
return(FALSE);
arSymbolName.dwCount = dwBaselen + 3 ;
gmrbd.dwMaxPrnKeywordSize += arSymbolName.dwCount + 2 ;
// add 2 bytes for every feature
if(!BwriteToHeap(&(pfoSyn[dwSynFea].atrFeaKeyWord),
(PBYTE)&arSymbolName, sizeof(ARRAYREF), 4, pglobl))
return(FALSE);
pfoSyn[dwSynFea].atrFeaKeyWord |= ATTRIB_HEAP_VALUE ;
} // !!! end new stuff
#if 0
pfoSyn[dwSynFea].atrFeaKeyWord =
pfo[dwFea].atrFeaKeyWord ; // just to fill something in.
#endif
// grab offsets to "Installed" and "Not Installed"
// option name templates:
if(BReadDataInGlobalNode(&pga->atrNameInstalled, &dwHeapOffset, pglobl) )
{
if(!BexchangeDataInFOATNode(
dwSynFea,
1,
offsetof(DFEATURE_OPTIONS, atrOptDisplayName) ,
&dwOut, // previous contents of attribute node
&dwHeapOffset, TRUE, pglobl) ) // new contents of attribute node.
return(FALSE) ;
}
if(BReadDataInGlobalNode(&pga->atrNameNotInstalled, &dwHeapOffset, pglobl) )
{
if(!BexchangeDataInFOATNode(
dwSynFea,
0,
offsetof(DFEATURE_OPTIONS, atrOptDisplayName) ,
&dwOut, // previous contents of attribute node
&dwHeapOffset, TRUE, pglobl) ) // new contents of attribute node.
return(FALSE) ;
}
if(BReadDataInGlobalNode(&pga->atrNameIDInstalled, &dwHeapOffset, pglobl) )
{
if(!BexchangeDataInFOATNode(
dwSynFea,
1,
offsetof(DFEATURE_OPTIONS, atrOptRcNameID) ,
&dwOut, // previous contents of attribute node
&dwHeapOffset, TRUE, pglobl) ) // new contents of attribute node.
return(FALSE) ;
}
if(BReadDataInGlobalNode(&pga->atrNameIDNotInstalled, &dwHeapOffset, pglobl) )
{
if(!BexchangeDataInFOATNode(
dwSynFea,
0,
offsetof(DFEATURE_OPTIONS, atrOptRcNameID) ,
&dwOut, // previous contents of attribute node
&dwHeapOffset, TRUE, pglobl) ) // new contents of attribute node.
return(FALSE) ;
}
pfoSyn[dwSynFea].dwGID = GID_UNKNOWN ;
pfoSyn[dwSynFea].dwNumOptions = 2 ;
// label this FeatureType as PrinterSticky
dwValue = FT_PRINTERPROPERTY ;
patr = &pfoSyn[dwSynFea].atrFeatureType ;
if(!BwriteToHeap(patr, (PBYTE)&dwValue ,
sizeof(DWORD), 4, pglobl) )
{
bStatus = FALSE ; // heap overflow start over.
}
*patr |= ATTRIB_HEAP_VALUE ;
// leave optionID, atrFeaKeyWord, atrOptKeyWord uninitialized.
{ // !!! new stuff init atrOptKeyWord , hardcode to ON and OFF
ARRAYREF arSymbolName ;
if(!BwriteToHeap(&arSymbolName.loOffset,
"OFF", 4, 1, pglobl))
return(FALSE);
arSymbolName.dwCount = 3 ;
if(!BwriteToHeap(&dwHeapOffset,
(PBYTE)&arSymbolName, sizeof(ARRAYREF), 4, pglobl))
return(FALSE);
if(!BexchangeDataInFOATNode(
dwSynFea,
0,
offsetof(DFEATURE_OPTIONS, atrOptKeyWord) ,
&dwOut, // previous contents of attribute node
&dwHeapOffset, TRUE, pglobl) ) // new contents of attribute node.
return(FALSE) ;
// ----- init "ON" -----
if(!BwriteToHeap(&arSymbolName.loOffset,
"ON", 3, 1, pglobl))
return(FALSE);
arSymbolName.dwCount = 2 ;
if(!BwriteToHeap(&dwHeapOffset,
(PBYTE)&arSymbolName, sizeof(ARRAYREF), 4, pglobl))
return(FALSE);
if(!BexchangeDataInFOATNode(
dwSynFea,
1,
offsetof(DFEATURE_OPTIONS, atrOptKeyWord) ,
&dwOut, // previous contents of attribute node
&dwHeapOffset, TRUE, pglobl) ) // new contents of attribute node.
return(FALSE) ;
gmrbd.dwMaxPrnKeywordSize += 4 ; // sufficient to hold "OFF\0".
// note synthesized features are always pick_one.
}
// transfer atrOptInstallConstraints etc to atrConstraints.
if(dwOpt != INVALID_INDEX)
{
if(!BexchangeDataInFOATNode(
dwFea,
dwOpt,
offsetof(DFEATURE_OPTIONS, atrOptInstallConstraints ),
&dwOut, // previous contents of attribute node
NULL, // don't change contents of attribute node.
FALSE , pglobl) ) // not synthetic feature
return(FALSE);
dwIn = dwOut ;
if(dwIn != INVALID_INDEX)
BexchangeDataInFOATNode(
dwSynFea,
1, // "Installed"
offsetof(DFEATURE_OPTIONS, atrConstraints) ,
&dwOut, // previous contents of attribute node
&dwIn, // new contents of attribute node.
TRUE , pglobl) ;
if(!BexchangeDataInFOATNode(
dwFea,
dwOpt,
offsetof(DFEATURE_OPTIONS, atrOptNotInstallConstraints ),
&dwOut, // previous contents of attribute node
NULL, // don't change contents of attribute node.
FALSE , pglobl) ) // not synthetic feature
return(FALSE);
dwIn = dwOut ;
if(dwIn != INVALID_INDEX)
BexchangeDataInFOATNode(
dwSynFea,
0, // "Not Installed"
offsetof(DFEATURE_OPTIONS, atrConstraints) ,
&dwOut, // previous contents of attribute node
&dwIn, // new contents of attribute node.
TRUE , pglobl) ;
}
else
{
if(BReadDataInGlobalNode(&pfo[dwFea].atrFeaInstallConstraints, &dwHeapOffset, pglobl) )
BexchangeDataInFOATNode(
dwSynFea,
1, // "Installed"
offsetof(DFEATURE_OPTIONS, atrConstraints) ,
&dwOut, // previous contents of attribute node
&dwHeapOffset, // new contents of attribute node.
TRUE , pglobl) ;
if(BReadDataInGlobalNode(&pfo[dwFea].atrFeaNotInstallConstraints , &dwHeapOffset, pglobl) )
BexchangeDataInFOATNode(
dwSynFea,
0, // "Not Installed"
offsetof(DFEATURE_OPTIONS, atrConstraints) ,
&dwOut, // previous contents of attribute node
&dwHeapOffset, // new contents of attribute node.
TRUE , pglobl) ;
}
// now synthesize: selecting option 0 constrains all
// options of an Installable feature except option 0.
// Selecting option 0 constrains an installable option.
if(bStatus)
bStatus = BallocElementFromMasterTable(MTI_CONSTRAINTS, &dwNewCnstRoot, pglobl) ;
if(!bStatus)
return(FALSE);
dwCNode = dwNewCnstRoot ;
if(dwOpt != INVALID_INDEX)
{ // installable option
pcnstr[dwCNode].dwFeature = dwFea ;
pcnstr[dwCNode].dwOption = dwOpt ;
}
else // installable feature
{
dwNumOpt = pfo[dwFea].dwNumOptions ;
for(dwOptI = 1 ; bStatus && dwOptI < dwNumOpt ; dwOptI++)
{
pcnstr[dwCNode].dwFeature = dwFea ;
pcnstr[dwCNode].dwOption = dwOptI ;
if(dwOptI + 1 < dwNumOpt)
{
bStatus = BallocElementFromMasterTable(MTI_CONSTRAINTS,
&pcnstr[dwCNode].dwNextCnstrnt, pglobl) ;
dwCNode = pcnstr[dwCNode].dwNextCnstrnt ;
}
}
}
// get existing list and prepend new list to it.
bStatus = BexchangeArbDataInFOATNode(
dwSynFea,
0, // "Not Installed"
offsetof(DFEATURE_OPTIONS, atrConstraints) ,
sizeof(DWORD) , // number bytes to copy.
(PBYTE)&dwPrevsNode, // pubOut
(PBYTE)&dwNewCnstRoot, // pubIn
&bPrevsExists, // previous contents existed?
TRUE, // access the synthetic features.
pglobl
) ;
if(bPrevsExists)
{ // tack existing list onto new list.
pcnstr[dwCNode].dwNextCnstrnt = dwPrevsNode ;
}
else
{
pcnstr[dwCNode].dwNextCnstrnt = END_OF_LIST ;
}
return(bStatus) ;
}
BOOL BEnableInvInstallableCombos(
PGLOBL pglobl)
{
DWORD dwPrevsNode, dwRootNode, dwNewCombo , dwCurNode,
dwFeaInstallable, dwOpt, dwSynFea, dwFeaOffset ;
PDFEATURE_OPTIONS pfo;
PGLOBALATTRIB pga ;
PINVALIDCOMBO pinvc ; // start of InvalidCombo array
pga = (PGLOBALATTRIB)gMasterTable[MTI_GLOBALATTRIB].pubStruct ;
pfo = (PDFEATURE_OPTIONS) gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct ;
pinvc = (PINVALIDCOMBO) gMasterTable[MTI_INVALIDCOMBO].pubStruct ;
dwFeaOffset = gMasterTable[MTI_DFEATURE_OPTIONS].dwArraySize ;
dwRootNode = pga->atrInvldInstallCombo ;
if(dwRootNode == ATTRIB_UNINITIALIZED)
return(TRUE) ; // no InvalidInstallableCombos found.
while(dwRootNode != END_OF_LIST)
{
dwNewCombo = pinvc[dwRootNode].dwNewCombo ;
dwCurNode = dwRootNode ;
while(dwCurNode != END_OF_LIST)
{
dwFeaInstallable = pinvc[dwCurNode].dwFeature ;
dwOpt = pinvc[dwCurNode].dwOption ;
if(dwOpt != (WORD)DEFAULT_INIT)
{ // this option is installable
if(!BexchangeDataInFOATNode(
dwFeaInstallable,
dwOpt,
offsetof(DFEATURE_OPTIONS, atrOptionSpawnsFeature),
&dwSynFea, // previous contents of attribute node
NULL, FALSE, pglobl)) // new contents of attribute node.
return(FALSE);
}
else
dwSynFea = pfo[dwFeaInstallable].dwFeatureSpawnsFeature ;
pinvc[dwCurNode].dwFeature = dwSynFea + dwFeaOffset ;
// dwSynFea is the index of the resulting
// synthesized feature.
pinvc[dwCurNode].dwOption = 1 ; // can't tolerate
// all these things installed at the same time.
if(!BexchangeDataInFOATNode(dwSynFea , 1,
offsetof(DFEATURE_OPTIONS, atrInvalidCombos),
&dwPrevsNode, &dwRootNode, TRUE, pglobl))
return(FALSE);
if(dwPrevsNode == INVALID_INDEX)
pinvc[dwCurNode].dwNewCombo = END_OF_LIST ;
else
pinvc[dwCurNode].dwNewCombo = dwPrevsNode ;
dwCurNode = pinvc[dwCurNode].dwNextElement ; // last line
}
dwRootNode = dwNewCombo ; // last line
}
return(TRUE);
}