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

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. /* snapshot.c - functions to produce a snapshot from
  3. the multivalued GPD binary data.
  4. History of Changes
  5. 10/28/98 --hsingh--
  6. Added functions BgetLocFeaIndex() and BgetLocFeaOptIndex()
  7. to support special processing for Feauture Locale if present
  8. in the gpd.
  9. Bug Report 231798
  10. */
  11. #include "gpdparse.h"
  12. #ifndef PARSERDLL
  13. // ---- functions defined in snapshot.c ---- //
  14. PINFOHEADER PINFOHDRcreateSnapshot(
  15. PBYTE pubnRaw, // raw binary data. PSTATIC. BETA2
  16. POPTSELECT poptsel // assume fully initialized
  17. ) ;
  18. BOOL BinitOptionFields(
  19. PBYTE pubDestOption, // ptr to some type of option structure.
  20. PBYTE pubDestOptionEx, // option extra structure if any.
  21. PBYTE pubnRaw, // raw binary data.
  22. DWORD dwFea,
  23. DWORD dwOpt,
  24. POPTSELECT poptsel , // assume fully initialized
  25. PINFOHEADER pInfoHdr, // used to access global structure.
  26. BOOL bUpdate // if true only update selected fields.
  27. ) ;
  28. BOOL BinitUIinfo(
  29. PUIINFO pUIinfo ,
  30. PBYTE pubnRaw, // PSTATIC. BETA2
  31. POPTSELECT poptsel, // assume fully initialized
  32. BOOL bUpdate // if true only update selected fields.
  33. ) ;
  34. BOOL BinitFeatures(
  35. PFEATURE pFeaturesDest,
  36. PDFEATURE_OPTIONS pfoSrc,
  37. PBYTE pubnRaw, // raw binary data.
  38. POPTSELECT poptsel, // assume fully initialized
  39. BOOL bUpdate // if true only update selected fields.
  40. ) ;
  41. BOOL BinitGlobals(
  42. PGLOBALS pGlobals,
  43. PBYTE pubnRaw, // raw binary data.
  44. POPTSELECT poptsel, // assume fully initialized
  45. BOOL bUpdate // if true only update selected fields.
  46. ) ;
  47. BOOL BinitCommandTable(
  48. PDWORD pdwCmdTable, // dest array
  49. PBYTE pubnRaw, // raw binary data.
  50. POPTSELECT poptsel // assume fully initialized
  51. ) ;
  52. BOOL BinitRawData(
  53. PRAWBINARYDATA pRawData, // contained in INFOHEADER.
  54. PBYTE pubnRaw // Parser's raw binary data.
  55. ) ;
  56. BOOL BinitGPDdriverInfo(
  57. PGPDDRIVERINFO pGPDdriverInfo,
  58. PBYTE pubnRaw, // raw binary data.
  59. POPTSELECT poptsel // assume fully initialized
  60. ) ;
  61. BOOL BinitSequencedCmds(
  62. PGPDDRIVERINFO pGPDdriverInfo,
  63. PBYTE pubnRaw, // raw binary data.
  64. POPTSELECT poptsel // assume fully initialized
  65. ) ;
  66. BOOL BaddSequencedCmdToList(
  67. DWORD dwCmdIn, // index of a command in CommandArray
  68. PGPDDRIVERINFO pGPDdriverInfo,
  69. DWORD dwNewListNode, // an unused listnode to add to the list.
  70. PBYTE pubnRaw // raw binary data.
  71. ) ;
  72. BinitDefaultOptionArray(
  73. POPTSELECT poptsel, // assume is large enough
  74. PBYTE pubnRaw) ;
  75. TRISTATUS EdetermineDefaultOption(
  76. PBYTE pubnRaw, // start of Rawbinary data
  77. DWORD dwFeature, // determine the default for this feature
  78. PDFEATURE_OPTIONS pfo,
  79. POPTSELECT poptsel, // assume is large enough
  80. PDWORD pdwPriority) ;
  81. VOID VtileDefault(
  82. PBYTE pubDest,
  83. DWORD dwDefault,
  84. DWORD dwBytes) ;
  85. VOID VtransferValue(
  86. OUT PBYTE pubDest,
  87. IN PBYTE pubSrc ,
  88. IN DWORD dwBytes,
  89. IN DWORD dwFlags,
  90. IN DWORD dwDefaultValue, // holds bit flag value.
  91. IN PBYTE pubHeap ) ; // used to form ptr if SSF_MAKE_STRINGPTR
  92. BOOL BspecialProcessOption(
  93. PBYTE pubnRaw, // start of Rawbinary data
  94. PBYTE pubDestOption, // ptr to some type of option structure.
  95. PBYTE pubDestOptionEx,
  96. PDFEATURE_OPTIONS pfo , // source data
  97. IN POPTSELECT poptsel, // option array which determines path
  98. // through atr.
  99. PINFOHEADER pInfoHdr, // used to access global structure.
  100. DWORD dwFea, // feature index
  101. DWORD dwOpt,
  102. BOOL bDefaultOpt
  103. ) ;
  104. TRISTATUS EextractValueFromTree(
  105. PBYTE pubnRaw, // start of Rawbinary data
  106. DWORD dwSSTableIndex, // some info about this value.
  107. OUT PBYTE pubDest, // write value or link here
  108. OUT PDWORD pdwUnresolvedFeature, // if the attribute tree has
  109. // a dependency on this feature and the current option
  110. // for that feature is not defined in poptsel, this
  111. // function will write the index of the required
  112. // feature in pdwUnresolvedFeature.
  113. IN ATREEREF atrRoot, // root of attribute tree to navigate.
  114. IN POPTSELECT poptsel, // option array which determines path
  115. // through atr. may be filled with OPTION_INDEX_ANY
  116. // if we are jumpstarting
  117. IN DWORD dwFeature,
  118. IN OUT PDWORD pdwNextOpt // if multiple options are selected
  119. // for dwFeature, pdwNextOpt points to the Nth option to consider
  120. // in the poptsel list, at return time, this value
  121. // is incremented if there are remaining options selected,
  122. // else is reset to zero.
  123. // For the first call, or PICKONE features,
  124. // this value must be set to zero.
  125. ) ;
  126. BOOL RaisePriority(
  127. DWORD dwFeature1,
  128. DWORD dwFeature2,
  129. PBYTE pubnRaw,
  130. PDWORD pdwPriority) ;
  131. DWORD dwNumOptionSelected(
  132. IN DWORD dwNumFeatures,
  133. IN POPTSELECT poptsel
  134. ) ;
  135. BOOL BinitSnapShotIndexTable(PBYTE pubnRaw) ;
  136. BOOL BinitSizeOptionTables(PBYTE pubnRaw) ;
  137. PRAWBINARYDATA
  138. LoadRawBinaryData (
  139. IN PTSTR ptstrDataFilename
  140. ) ;
  141. PRAWBINARYDATA
  142. GpdLoadCachedBinaryData(
  143. PTSTR ptstrGpdFilename
  144. ) ;
  145. VOID
  146. UnloadRawBinaryData (
  147. IN PRAWBINARYDATA pnRawData
  148. ) ;
  149. PINFOHEADER
  150. InitBinaryData(
  151. IN PRAWBINARYDATA pnRawData, // actually pStatic
  152. IN PINFOHEADER pInfoHdr,
  153. IN POPTSELECT pOptions
  154. ) ;
  155. VOID
  156. FreeBinaryData(
  157. IN PINFOHEADER pInfoHdr
  158. ) ;
  159. BOOL BIsRawBinaryDataInDate(
  160. IN PBYTE pubRaw) ; // this is pointer to memory mapped file! BETA2
  161. BOOL BgetLocFeaIndex(
  162. IN PRAWBINARYDATA pnRawData, // raw binary data.
  163. OUT PDWORD pdwFea // Index of the Locale Feature (if present)
  164. ) ;
  165. BOOL BgetLocFeaOptIndex(
  166. IN PRAWBINARYDATA pnRawData,
  167. OUT PDWORD pdwFea,
  168. OUT PDWORD pdwOptIndex
  169. );
  170. #endif PARSERDLL
  171. BOOL BfindMatchingOrDefaultNode(
  172. IN PATTRIB_TREE patt , // start of ATTRIBUTE tree array.
  173. IN OUT PDWORD pdwNodeIndex, // Points to first node in chain
  174. IN DWORD dwOptionID // may even take on the value DEFAULT_INIT
  175. ) ;
  176. // ------- end function declarations ------- //
  177. #ifndef PARSERDLL
  178. /* ---- Memory Map ---- /*
  179. INFOHEADER {RAWBINARYDATA} <= reference pt for local offsets.
  180. UIINFO
  181. GPDDRIVERINFO (aka DRIVERINFO)
  182. CMD_TABLE of DWORDS
  183. LOCALLIST (to support sequenced commands)
  184. FEATURES
  185. OPTIONS and OPTIONEXTRAS
  186. /* ---- end Memory Map ---- */
  187. PINFOHEADER PINFOHDRcreateSnapshot(
  188. PBYTE pubnRaw, // raw binary data. PSTATIC. BETA2
  189. POPTSELECT poptsel // assume fully initialized
  190. )
  191. /* this function allocates the single memoryblock
  192. that contains the entire snapshot. */
  193. {
  194. DWORD dwCurOffset = 0, loGPDdriverInfo, loInfoHeader,
  195. loUIinfo, loCmdTable, loListArray, loFeatures, dwSize,
  196. dwNumFeatures, dwNumListNodes, dwTotSize, loOptions,
  197. dwSizeOption, dwSizeOptionEx, dwFea, dwGID , dwNumOptions,
  198. dwI , dwCmd;
  199. PDWORD pdwSymbolRoots ;
  200. PENHARRAYREF pearTableContents ;
  201. PDFEATURE_OPTIONS pfo ;
  202. PINFOHEADER pInfoHdr ;
  203. PUIINFO pUIinfo ;
  204. PSTATICFIELDS pStatic ;
  205. // PMINIRAWBINARYDATA pmrbd = NULL ;
  206. PGPDDRIVERINFO pGPDdriverInfo ;
  207. PBYTE pubRaw, // ptr to BUD data.
  208. pubOptionsDest , // ptr to any of the several varieties
  209. pubDestOptionEx ; // of option structures.
  210. BOOL bStatus ;
  211. PFEATURE pFeaturesDest ;
  212. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  213. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  214. loInfoHeader = dwCurOffset ;
  215. dwCurOffset += sizeof(INFOHEADER) ;
  216. loUIinfo = dwCurOffset ;
  217. dwCurOffset += sizeof(UIINFO) ;
  218. loGPDdriverInfo = dwCurOffset ;
  219. dwCurOffset += sizeof(GPDDRIVERINFO) ;
  220. loCmdTable = dwCurOffset ;
  221. dwCurOffset += sizeof(DWORD) * CMD_MAX ;
  222. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  223. dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
  224. dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
  225. dwNumListNodes = dwNumOptionSelected(dwNumFeatures, poptsel) ;
  226. // if there are pickmany, we could have more than dwNumFeatures.
  227. dwNumListNodes += NUM_CONFIGURATION_CMDS ;
  228. loListArray = dwCurOffset ;
  229. dwCurOffset += dwNumListNodes * sizeof(LISTNODE) ;
  230. loFeatures = dwCurOffset ;
  231. dwCurOffset += dwNumFeatures * sizeof(FEATURE) ;
  232. loOptions = dwCurOffset ;
  233. // There are too many options and optionextra structures
  234. // for me to track all the offsets, so just track the
  235. // amount of memory consumed.
  236. pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
  237. loOffset) ;
  238. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  239. for(dwTotSize = dwFea = 0 ; dwFea < dwNumFeatures ; dwFea++)
  240. {
  241. dwGID = pfo[dwFea].dwGID ;
  242. dwNumOptions = pfo[dwFea].dwNumOptions ;
  243. if(dwGID != GID_UNKNOWN)
  244. {
  245. dwSize = pStatic->pdwSizeOption[dwGID] +
  246. pStatic->pdwSizeOptionEx[dwGID] ;
  247. }
  248. else
  249. {
  250. dwSize = sizeof(OPTION);
  251. }
  252. dwTotSize += dwSize * dwNumOptions ; // of all options
  253. }
  254. dwCurOffset += dwTotSize ; // total size of local snapshot.
  255. // now allocate memory and partition this block into structures.
  256. if(!(pInfoHdr = (PINFOHEADER)MemAllocZ(dwCurOffset) ))
  257. {
  258. ERR(("Fatal: PINFOHDRcreateSnapshot - unable to alloc %d bytes.\n",
  259. dwCurOffset));
  260. // cannot use globals outside of parser.
  261. // use error num to relay failure.
  262. return(NULL) ; // This is unrecoverable
  263. }
  264. pUIinfo = (PUIINFO)((PBYTE)(pInfoHdr) + loUIinfo) ;
  265. pGPDdriverInfo = (PGPDDRIVERINFO)((PBYTE)(pInfoHdr) + loGPDdriverInfo) ;
  266. if(!BinitCommandTable((PDWORD)((PBYTE)(pInfoHdr) + loCmdTable),
  267. pubnRaw, poptsel) )
  268. {
  269. MemFree(pInfoHdr) ;
  270. return(NULL) ;
  271. }
  272. // init GPDDRIVERINFO
  273. // note all offsets in DataTable are relative to pubResourceData
  274. // the StringHeap. Except these :
  275. pGPDdriverInfo->pInfoHeader = pInfoHdr ;
  276. pGPDdriverInfo->DataType[DT_COMMANDTABLE].loOffset = loCmdTable ;
  277. pGPDdriverInfo->DataType[DT_COMMANDTABLE].dwCount = CMD_MAX ;
  278. pGPDdriverInfo->DataType[DT_LOCALLISTNODE].loOffset = loListArray ;
  279. pGPDdriverInfo->DataType[DT_LOCALLISTNODE].dwCount = dwNumListNodes ;
  280. if(!BinitGPDdriverInfo(pGPDdriverInfo, pubnRaw, poptsel) )
  281. {
  282. MemFree(pInfoHdr) ;
  283. return(NULL) ;
  284. }
  285. // init InfoHeader
  286. pInfoHdr->loUIInfoOffset = loUIinfo ;
  287. pInfoHdr->loDriverOffset = loGPDdriverInfo ;
  288. if(!BinitRawData(&pInfoHdr->RawData, pubnRaw) )
  289. {
  290. MemFree(pInfoHdr) ;
  291. return(NULL) ;
  292. }
  293. // init UIInfo
  294. pUIinfo->pInfoHeader = pInfoHdr ;
  295. pUIinfo->loFeatureList = loFeatures ; // from pInfoHdr
  296. pUIinfo->loFontSubstTable =
  297. pGPDdriverInfo->DataType[DT_FONTSUBST].loOffset ; // in pubRaw
  298. pUIinfo->dwFontSubCount =
  299. pGPDdriverInfo->DataType[DT_FONTSUBST].dwCount ;
  300. pUIinfo->UIGroups.dwCount = 0 ; // in pubRaw
  301. pUIinfo->CartridgeSlot.loOffset = // in pubRaw
  302. pGPDdriverInfo->DataType[DT_FONTSCART].loOffset ;
  303. pUIinfo->CartridgeSlot.dwCount =
  304. pGPDdriverInfo->DataType[DT_FONTSCART].dwCount ;
  305. // pUIinfo->dwFlags = FLAG_RULESABLE ;
  306. // start with just this
  307. // and turn on/off more flags as needed. ROTATE_90
  308. // and ORIENT_SUPPORT are never set. This is now obsolete.
  309. if(pGPDdriverInfo->Globals.fontformat != UNUSED_ITEM)
  310. pUIinfo->dwFlags |= FLAG_FONT_DOWNLOADABLE ;
  311. if(pGPDdriverInfo->Globals.liDeviceFontList != END_OF_LIST)
  312. pUIinfo->dwFlags |= FLAG_FONT_DEVICE ;
  313. #if 0
  314. Alvins code never looks at this flag anyway.
  315. for(dwCmd = CMD_FIRST_RULES ; dwCmd < CMD_LAST_RULES + 1 ; dwCmd++ )
  316. {
  317. if( ((PDWORD)((PBYTE)(pInfoHdr) + loCmdTable))[dwCmd] ==
  318. UNUSED_ITEM)
  319. pUIinfo->dwFlags &= ~FLAG_RULESABLE ; // clear flag
  320. } // if requisite command is missing.
  321. #endif
  322. if(!BinitUIinfo(pUIinfo, pubnRaw, poptsel, FALSE) )
  323. {
  324. MemFree(pInfoHdr) ;
  325. return(NULL) ;
  326. }
  327. // init features and options
  328. pFeaturesDest = (PFEATURE)((PBYTE)(pInfoHdr) + loFeatures) ;
  329. for( dwFea = 0 ; dwFea < dwNumFeatures ; dwFea++)
  330. {
  331. dwGID = pfo[dwFea].dwGID ;
  332. dwNumOptions = pfo[dwFea].dwNumOptions ;
  333. pFeaturesDest[dwFea].Options.loOffset = loOptions ;
  334. pFeaturesDest[dwFea].Options.dwCount = dwNumOptions ;
  335. if(!BinitFeatures(pFeaturesDest + dwFea, pfo + dwFea,
  336. pubnRaw, poptsel, FALSE))
  337. {
  338. MemFree(pInfoHdr) ;
  339. return(NULL) ;
  340. }
  341. if(dwGID != GID_UNKNOWN)
  342. {
  343. dwSizeOption = pStatic->pdwSizeOption[dwGID] ;
  344. dwSizeOptionEx = pStatic->pdwSizeOptionEx[dwGID] ;
  345. pUIinfo->aloPredefinedFeatures[dwGID] =
  346. loFeatures + dwFea * sizeof(FEATURE) ;
  347. // all fields initially set to zeros.
  348. }
  349. else
  350. {
  351. dwSizeOption = sizeof(OPTION);
  352. dwSizeOptionEx = 0 ;
  353. }
  354. // special non-atreeref fields
  355. (pFeaturesDest + dwFea)->dwFeatureID = dwGID ;
  356. (pFeaturesDest + dwFea)->dwOptionSize = dwSizeOption ;
  357. loOptions += dwSizeOption * dwNumOptions ;
  358. pubOptionsDest = (PBYTE)(pInfoHdr) + pFeaturesDest[dwFea].Options.loOffset ;
  359. for(dwI = 0 ; dwI < dwNumOptions ; dwI++)
  360. {
  361. if(dwSizeOptionEx)
  362. {
  363. ((POPTION)pubOptionsDest)->loRenderOffset = loOptions ;
  364. pubDestOptionEx = (PBYTE)(pInfoHdr) + loOptions ;
  365. loOptions += dwSizeOptionEx ;
  366. }
  367. else
  368. {
  369. ((POPTION)pubOptionsDest)->loRenderOffset = 0 ;
  370. pubDestOptionEx = NULL ;
  371. }
  372. if(!BinitOptionFields(pubOptionsDest, pubDestOptionEx,
  373. pubnRaw, dwFea, dwI, poptsel, pInfoHdr, FALSE) )
  374. {
  375. MemFree(pInfoHdr) ;
  376. return(NULL) ;
  377. }
  378. pubOptionsDest += dwSizeOption ;
  379. }
  380. }
  381. #ifndef KERNEL_MODE
  382. if(!BCheckGPDSemantics(pInfoHdr, poptsel) )
  383. {
  384. MemFree(pInfoHdr) ;
  385. pInfoHdr = NULL ;
  386. }
  387. #endif
  388. return(pInfoHdr) ;
  389. }
  390. BOOL BinitOptionFields(
  391. PBYTE pubDestOption, // ptr to some type of option structure.
  392. PBYTE pubDestOptionEx, // option extra structure if any.
  393. PBYTE pubnRaw, // raw binary data.
  394. DWORD dwFea,
  395. DWORD dwOpt,
  396. POPTSELECT poptsel , // assume fully initialized
  397. PINFOHEADER pInfoHdr, // used to access global structure.
  398. BOOL bUpdate // if true only update selected fields.
  399. )
  400. {
  401. PENHARRAYREF pearTableContents ;
  402. PDFEATURE_OPTIONS pfo ;
  403. // PMINIRAWBINARYDATA pmrbd ;
  404. PATREEREF patrRoot ; // root of attribute tree to navigate.
  405. DWORD dwUnresolvedFeature, // dummy storage
  406. dwI, dwStart , dwEnd, dwNextOpt, dwGID ;
  407. OPTSELECT optsPrevs ;
  408. PBYTE pubDest ;
  409. BOOL bStatus = TRUE ;
  410. PBYTE pubRaw ;
  411. PSTATICFIELDS pStatic ;
  412. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  413. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  414. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  415. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  416. pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
  417. loOffset) ;
  418. pfo += dwFea ; // index pfo to the proper feature.
  419. dwGID = pfo->dwGID ;
  420. // save previous option selection for this feature.
  421. optsPrevs = poptsel[dwFea] ; // save setting since we will sweep it.
  422. poptsel[dwFea].ubNext = NULL_OPTSELECT ;
  423. poptsel[dwFea].ubCurOptIndex = (BYTE)dwOpt ;
  424. if(bUpdate) // assume update comes after main group.
  425. dwStart = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONS].dwStart ; // starting Index
  426. else
  427. dwStart = pStatic->ssTableIndex[SSTI_OPTIONS].dwStart ; // starting Index
  428. dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONS].dwEnd ; // Ending Index
  429. for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
  430. {
  431. if(!(pStatic->snapShotTable[dwI].dwNbytes))
  432. continue ; // skip over section delimiter.
  433. if(dwGID >= MAX_GID)
  434. {
  435. if(pStatic->snapShotTable[dwI].dwGIDflags != 0xffffffff)
  436. continue ; // this field not used for generic GID.
  437. }
  438. else if(!(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID)))
  439. continue ; // this field not used for this GID.
  440. patrRoot = (PATREEREF)((PBYTE)pfo +
  441. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  442. pubDest = pubDestOption + pStatic->snapShotTable[dwI].dwDestOffset ;
  443. dwNextOpt = 0 ; // extract info for first option selected for
  444. // this feature.
  445. if(EextractValueFromTree(pubnRaw, dwI, pubDest,
  446. &dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
  447. // any value. Doesn't matter.
  448. &dwNextOpt) != TRI_SUCCESS)
  449. {
  450. ERR(("BinitOptionFields: Failed to extract value for attribute in Fea: %d, Opt: %d\n", dwFea, dwOpt));
  451. bStatus = FALSE ;
  452. }
  453. }
  454. if(bUpdate) // assume update comes after main group.
  455. dwStart = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONEX].dwStart ; // starting Index
  456. else
  457. dwStart = pStatic->ssTableIndex[SSTI_OPTIONEX].dwStart ; // starting Index
  458. dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONEX].dwEnd ; // Ending Index
  459. for(dwI = dwStart ; bStatus && pubDestOptionEx && (dwI < dwEnd)
  460. ; dwI++)
  461. {
  462. if(!(pStatic->snapShotTable[dwI].dwNbytes))
  463. continue ; // skip over section delimiter.
  464. if(!(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID)))
  465. continue ; // this field not used for this GID.
  466. patrRoot = (PATREEREF)((PBYTE)pfo +
  467. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  468. pubDest = pubDestOptionEx + pStatic->snapShotTable[dwI].dwDestOffset ;
  469. dwNextOpt = 0 ; // extract info for first option selected for
  470. // this feature.
  471. if(EextractValueFromTree(pubnRaw, dwI, pubDest,
  472. &dwUnresolvedFeature, *patrRoot, poptsel, 0,
  473. &dwNextOpt) != TRI_SUCCESS)
  474. {
  475. ERR(("BinitOptionFields: Failed to extract value for attribute in Fea: %d, Opt: %d\n", dwFea, dwOpt));
  476. bStatus = FALSE ;
  477. }
  478. }
  479. if(!bUpdate && !BspecialProcessOption(pubnRaw, pubDestOption,
  480. pubDestOptionEx,
  481. pfo , poptsel, pInfoHdr, dwFea, dwOpt,
  482. optsPrevs.ubCurOptIndex == dwOpt) )
  483. // dwOpt is the default option for dwFea!
  484. {
  485. bStatus = FALSE ;
  486. }
  487. poptsel[dwFea] = optsPrevs ; // restore previous setting.
  488. return(bStatus) ;
  489. }
  490. BOOL BinitUIinfo(
  491. PUIINFO pUIinfo ,
  492. PBYTE pubnRaw, // PSTATIC. BETA2
  493. POPTSELECT poptsel, // assume fully initialized
  494. BOOL bUpdate // if true only update selected fields.
  495. )
  496. {
  497. PENHARRAYREF pearTableContents ;
  498. PMINIRAWBINARYDATA pmrbd ;
  499. PATREEREF patrRoot ; // root of attribute tree to navigate.
  500. DWORD dwUnresolvedFeature, // dummy storage
  501. dwI, dwStart , dwEnd, dwNextOpt ;
  502. BOOL bStatus = TRUE ;
  503. PGLOBALATTRIB pga ;
  504. PBYTE pubDest, pubRaw ;
  505. PSTATICFIELDS pStatic ;
  506. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  507. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  508. pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  509. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  510. pga = (PGLOBALATTRIB)(pubRaw + pearTableContents[MTI_GLOBALATTRIB].
  511. loOffset) ;
  512. if(bUpdate) // assume update comes after main group.
  513. dwStart = pStatic->ssTableIndex[SSTI_UPDATE_UIINFO].dwStart ; // starting Index
  514. else
  515. dwStart = pStatic->ssTableIndex[SSTI_UIINFO].dwStart ; // starting Index
  516. dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_UIINFO].dwEnd ; // Ending Index
  517. for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
  518. {
  519. if(!(pStatic->snapShotTable[dwI].dwNbytes))
  520. continue ; // skip over section delimiter.
  521. patrRoot = (PATREEREF)((PBYTE)pga +
  522. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  523. pubDest = (PBYTE)pUIinfo + pStatic->snapShotTable[dwI].dwDestOffset ;
  524. dwNextOpt = 0 ; // extract info for first option selected for
  525. // this feature.
  526. if(EextractValueFromTree(pubnRaw, dwI, pubDest,
  527. &dwUnresolvedFeature, *patrRoot, poptsel, 0,
  528. &dwNextOpt) != TRI_SUCCESS)
  529. {
  530. bStatus = FALSE ;
  531. }
  532. }
  533. pUIinfo->pubResourceData =
  534. pubRaw + pearTableContents[MTI_STRINGHEAP].loOffset ;
  535. pUIinfo->dwSpecVersion = pmrbd->dwSpecVersion ; // don't change!
  536. pUIinfo->dwSize = sizeof(UIINFO);
  537. pUIinfo->dwTechnology = DT_RASPRINTER ;
  538. pUIinfo->dwDocumentFeatures = pmrbd->rbd.dwDocumentFeatures;
  539. pUIinfo->dwPrinterFeatures = pmrbd->rbd.dwPrinterFeatures;
  540. pUIinfo->dwCustomSizeOptIndex = UNUSED_ITEM; // until found later
  541. pUIinfo->dwFreeMem = 400000 ; // default just in case
  542. // there are no GID_MEMOPTION features.
  543. pUIinfo->dwMaxDocKeywordSize = pmrbd->dwMaxDocKeywordSize + KEYWORD_SIZE_EXTRA;
  544. pUIinfo->dwMaxPrnKeywordSize = pmrbd->dwMaxPrnKeywordSize + KEYWORD_SIZE_EXTRA;
  545. // dead: replace with macros
  546. // pUIinfo->dwWhichBasePtr[UIDT_FEATURE] = 0 ;
  547. // pUIinfo->dwWhichBasePtr[UIDT_OPTION] = 0 ;
  548. // pUIinfo->dwWhichBasePtr[UIDT_OPTIONEX] = 0 ;
  549. // pUIinfo->dwWhichBasePtr[UIDT_CONSTRAINT] = BASE_USE_RESOURCE_DATA ;
  550. // pUIinfo->dwWhichBasePtr[UIDT_GROUPS] = BASE_USE_RESOURCE_DATA ;
  551. // pUIinfo->dwWhichBasePtr[UIDT_LISTNODE] = BASE_USE_RESOURCE_DATA ;
  552. // pUIinfo->dwWhichBasePtr[UIDT_FONTSCART] = BASE_USE_RESOURCE_DATA ;
  553. // pUIinfo->dwWhichBasePtr[UIDT_FONTSUBST] = BASE_USE_RESOURCE_DATA ;
  554. return(bStatus) ;
  555. }
  556. BOOL BinitFeatures(
  557. PFEATURE pFeaturesDest,
  558. PDFEATURE_OPTIONS pfoSrc,
  559. PBYTE pubnRaw, // raw binary data.
  560. POPTSELECT poptsel, // assume fully initialized
  561. BOOL bUpdate // if true only update selected fields.
  562. )
  563. {
  564. PENHARRAYREF pearTableContents ;
  565. // PMINIRAWBINARYDATA pmrbd ;
  566. PATREEREF patrRoot ; // root of attribute tree to navigate.
  567. DWORD dwUnresolvedFeature, // dummy storage
  568. dwI, dwStart , dwEnd , dwNextOpt ;
  569. BOOL bStatus = TRUE ;
  570. PBYTE pubDest ;
  571. PBYTE pubRaw ;
  572. PSTATICFIELDS pStatic ;
  573. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  574. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  575. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  576. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  577. if(bUpdate) // assume update comes after main group.
  578. dwStart = pStatic->ssTableIndex[SSTI_UPDATE_FEATURES].dwStart ; // starting Index
  579. else
  580. dwStart = pStatic->ssTableIndex[SSTI_FEATURES].dwStart ; // starting Index
  581. dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_FEATURES].dwEnd ; // Ending Index
  582. for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
  583. {
  584. if(!pStatic->snapShotTable[dwI].dwNbytes)
  585. continue ; // ignore section delimiter.
  586. patrRoot = (PATREEREF)((PBYTE)pfoSrc +
  587. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  588. pubDest = (PBYTE)pFeaturesDest + pStatic->snapShotTable[dwI].dwDestOffset ;
  589. dwNextOpt = 0 ; // extract info for first option selected for
  590. // this feature.
  591. if(EextractValueFromTree(pubnRaw, dwI, pubDest,
  592. &dwUnresolvedFeature, *patrRoot, poptsel, 0,
  593. &dwNextOpt) != TRI_SUCCESS)
  594. {
  595. bStatus = FALSE ;
  596. }
  597. }
  598. return(bStatus) ;
  599. }
  600. BOOL BinitGlobals(
  601. PGLOBALS pGlobals,
  602. PBYTE pubnRaw, // raw binary data.
  603. POPTSELECT poptsel, // assume fully initialized
  604. BOOL bUpdate // if true only update selected fields.
  605. )
  606. {
  607. PENHARRAYREF pearTableContents ;
  608. // PMINIRAWBINARYDATA pmrbd ;
  609. PATREEREF patrRoot ; // root of attribute tree to navigate.
  610. DWORD dwUnresolvedFeature, // dummy storage
  611. dwI, dwStart , dwEnd, dwNextOpt ;
  612. BOOL bStatus = TRUE ;
  613. PGLOBALATTRIB pga ;
  614. PBYTE pubDest ;
  615. PBYTE pubRaw ;
  616. PSTATICFIELDS pStatic ;
  617. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  618. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  619. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  620. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  621. pga = (PGLOBALATTRIB)(pubRaw + pearTableContents[MTI_GLOBALATTRIB].
  622. loOffset) ;
  623. if (bUpdate)
  624. dwStart = pStatic->ssTableIndex[SSTI_UPDATE_GLOBALS].dwStart ;
  625. else
  626. dwStart = pStatic->ssTableIndex[SSTI_GLOBALS].dwStart ; // starting Index
  627. dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_GLOBALS].dwEnd ; // Ending Index
  628. for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
  629. {
  630. if(!(pStatic->snapShotTable[dwI].dwNbytes))
  631. continue ; // skip over section delimiter.
  632. patrRoot = (PATREEREF)((PBYTE)pga +
  633. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  634. pubDest = (PBYTE)pGlobals + pStatic->snapShotTable[dwI].dwDestOffset ;
  635. dwNextOpt = 0 ; // extract info for first option selected for
  636. // this feature.
  637. if(EextractValueFromTree(pubnRaw, dwI, pubDest,
  638. &dwUnresolvedFeature, *patrRoot, poptsel, 0,
  639. &dwNextOpt) != TRI_SUCCESS)
  640. {
  641. bStatus = FALSE ;
  642. }
  643. }
  644. return(bStatus) ;
  645. }
  646. BOOL BinitCommandTable(
  647. PDWORD pdwCmdTable, // dest array
  648. PBYTE pubnRaw, // raw binary data.
  649. POPTSELECT poptsel // assume fully initialized
  650. )
  651. {
  652. PENHARRAYREF pearTableContents ;
  653. // PMINIRAWBINARYDATA pmrbd ;
  654. PATREEREF patrRoot ; // root of attribute tree to navigate.
  655. DWORD dwUnresolvedFeature, // dummy storage
  656. dwNextOpt , dwI; // index to the commandTable
  657. // describing how to transfer the Command data type.
  658. BOOL bStatus = TRUE ;
  659. PBYTE pubRaw ;
  660. PSTATICFIELDS pStatic ;
  661. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  662. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  663. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  664. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  665. patrRoot = (PATREEREF)(pubRaw + pearTableContents[MTI_COMMANDTABLE].
  666. loOffset) ;
  667. // loop for every PATREEREF in the MTI_COMMANDTABLE !
  668. // not looping through each entry in the section.
  669. for(dwI = 0 ; bStatus && (dwI < CMD_MAX) ; dwI++)
  670. {
  671. dwNextOpt = 0 ; // extract info for first option selected for
  672. // this feature.
  673. if(EextractValueFromTree(pubnRaw, pStatic->dwSSTableCmdIndex,
  674. (PBYTE)(pdwCmdTable + dwI),
  675. &dwUnresolvedFeature, patrRoot[dwI], poptsel, 0,
  676. &dwNextOpt) != TRI_SUCCESS)
  677. {
  678. bStatus = FALSE ;
  679. }
  680. }
  681. return(bStatus) ;
  682. }
  683. BOOL BinitRawData(
  684. PRAWBINARYDATA pRawData, // contained in INFOHEADER.
  685. PBYTE pubnRaw // Parser's raw binary data.
  686. )
  687. {
  688. PMINIRAWBINARYDATA pmrbd ;
  689. PBYTE pubRaw ;
  690. PSTATICFIELDS pStatic ;
  691. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  692. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  693. pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  694. pRawData->dwFileSize = pmrbd->rbd.dwFileSize;
  695. pRawData->dwParserSignature = pmrbd->rbd.dwParserSignature;
  696. pRawData->dwParserVersion = pmrbd->rbd.dwParserVersion;
  697. pRawData->dwChecksum32 = pmrbd->rbd.dwChecksum32;
  698. pRawData->dwSrcFileChecksum32 = pmrbd->rbd.dwSrcFileChecksum32;
  699. // this not the count of synthesized vs.
  700. // explicitly defined features
  701. pRawData->dwDocumentFeatures = pmrbd->rbd.dwDocumentFeatures;
  702. pRawData->dwPrinterFeatures = pmrbd->rbd.dwPrinterFeatures;
  703. pRawData->pvPrivateData = pubnRaw ; // BETA2
  704. pRawData->pvReserved = NULL;
  705. return(TRUE) ;
  706. }
  707. BOOL BinitGPDdriverInfo(
  708. PGPDDRIVERINFO pGPDdriverInfo,
  709. PBYTE pubnRaw, // raw binary data.
  710. POPTSELECT poptsel // assume fully initialized
  711. )
  712. {
  713. PENHARRAYREF pearTableContents ;
  714. BOOL bStatus ;
  715. PBYTE pubRaw ;
  716. PSTATICFIELDS pStatic ;
  717. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  718. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  719. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  720. pGPDdriverInfo->dwSize = sizeof(GPDDRIVERINFO) ;
  721. pGPDdriverInfo->pubResourceData =
  722. pubRaw + pearTableContents[MTI_STRINGHEAP].loOffset ;
  723. pGPDdriverInfo->DataType[DT_COMMANDARRAY].loOffset =
  724. pearTableContents[MTI_COMMANDARRAY].loOffset -
  725. pearTableContents[MTI_STRINGHEAP].loOffset ;
  726. pGPDdriverInfo->DataType[DT_COMMANDARRAY].dwCount =
  727. pearTableContents[MTI_COMMANDARRAY].dwCount ;
  728. pGPDdriverInfo->DataType[DT_PARAMETERS].loOffset =
  729. pearTableContents[MTI_PARAMETER].loOffset -
  730. pearTableContents[MTI_STRINGHEAP].loOffset ;
  731. pGPDdriverInfo->DataType[DT_PARAMETERS].dwCount =
  732. pearTableContents[MTI_PARAMETER].dwCount ;
  733. pGPDdriverInfo->DataType[DT_TOKENSTREAM].loOffset =
  734. pearTableContents[MTI_TOKENSTREAM].loOffset -
  735. pearTableContents[MTI_STRINGHEAP].loOffset ;
  736. pGPDdriverInfo->DataType[DT_TOKENSTREAM].dwCount =
  737. pearTableContents[MTI_TOKENSTREAM].dwCount ;
  738. pGPDdriverInfo->DataType[DT_LISTNODE].loOffset =
  739. pearTableContents[MTI_LISTNODES].loOffset -
  740. pearTableContents[MTI_STRINGHEAP].loOffset ;
  741. pGPDdriverInfo->DataType[DT_LISTNODE].dwCount =
  742. pearTableContents[MTI_LISTNODES].dwCount ;
  743. pGPDdriverInfo->DataType[DT_FONTSCART].loOffset =
  744. pearTableContents[MTI_FONTCART].loOffset -
  745. pearTableContents[MTI_STRINGHEAP].loOffset ;
  746. pGPDdriverInfo->DataType[DT_FONTSCART].dwCount =
  747. pearTableContents[MTI_FONTCART].dwCount ;
  748. pGPDdriverInfo->DataType[DT_FONTSUBST].loOffset =
  749. pearTableContents[MTI_TTFONTSUBTABLE].loOffset -
  750. pearTableContents[MTI_STRINGHEAP].loOffset ;
  751. pGPDdriverInfo->DataType[DT_FONTSUBST].dwCount =
  752. pearTableContents[MTI_TTFONTSUBTABLE].dwCount ;
  753. bStatus = BinitSequencedCmds(pGPDdriverInfo, pubnRaw, poptsel) ;
  754. if(bStatus)
  755. bStatus = BinitGlobals(&pGPDdriverInfo->Globals, pubnRaw, poptsel, FALSE ) ;
  756. return(bStatus) ;
  757. }
  758. BOOL BinitSequencedCmds(
  759. PGPDDRIVERINFO pGPDdriverInfo,
  760. PBYTE pubnRaw, // raw binary data.
  761. POPTSELECT poptsel // assume fully initialized
  762. )
  763. {
  764. PINFOHEADER pInfoHdr ;
  765. PDWORD pdwCmdTable ; // start of local CommandTable
  766. PENHARRAYREF pearTableContents ;
  767. DWORD dwCmdIn , // command table index.
  768. // or commandArray index.
  769. dwNextOpt, dwFea, dwNumFeatures ,
  770. dwUnresolvedFeature,
  771. dwNewListNode = 0 ; // an unused listnode to
  772. // add to the list. initially none are used.
  773. PDFEATURE_OPTIONS pfo ;
  774. ATREEREF atrRoot ; // root of attribute tree
  775. // PMINIRAWBINARYDATA pmrbd ;
  776. OPTSELECT optsPrevs ;
  777. BOOL bStatus = TRUE ;
  778. PBYTE pubRaw ;
  779. PSTATICFIELDS pStatic ;
  780. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  781. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  782. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  783. pInfoHdr = pGPDdriverInfo->pInfoHeader ;
  784. pdwCmdTable = (PDWORD)((PBYTE)(pInfoHdr) +
  785. pGPDdriverInfo->DataType[DT_COMMANDTABLE].loOffset) ;
  786. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  787. pGPDdriverInfo->dwJobSetupIndex = END_OF_LIST ;
  788. pGPDdriverInfo->dwDocSetupIndex = END_OF_LIST ;
  789. pGPDdriverInfo->dwPageSetupIndex = END_OF_LIST ;
  790. pGPDdriverInfo->dwPageFinishIndex = END_OF_LIST ;
  791. pGPDdriverInfo->dwDocFinishIndex = END_OF_LIST ;
  792. pGPDdriverInfo->dwJobFinishIndex = END_OF_LIST ;
  793. // first add the configuration commands to the list.
  794. // get them from the commandtable. Assume they are all
  795. // contiguous
  796. for(dwCmdIn = FIRST_CONFIG_CMD ; dwCmdIn < LAST_CONFIG_CMD ; dwCmdIn++)
  797. {
  798. if((pdwCmdTable[dwCmdIn] != UNUSED_ITEM) &&
  799. BaddSequencedCmdToList(pdwCmdTable[dwCmdIn], pGPDdriverInfo,
  800. dwNewListNode, pubnRaw ) )
  801. dwNewListNode++ ;
  802. }
  803. // now wander through all the features, seeing what
  804. // command is needed.
  805. pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
  806. loOffset) ;
  807. dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
  808. dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
  809. for(dwFea = 0 ; dwFea < dwNumFeatures ; dwFea++)
  810. {
  811. dwNextOpt = 0 ; // extract info for first option selected for
  812. // this feature.
  813. atrRoot = pfo[dwFea].atrCommandIndex ;
  814. if(EextractValueFromTree(pubnRaw, pStatic->dwSSCmdSelectIndex,
  815. (PBYTE)&dwCmdIn, // CmdArray index - dest
  816. &dwUnresolvedFeature, atrRoot, poptsel, dwFea,
  817. &dwNextOpt) != TRI_SUCCESS)
  818. {
  819. bStatus = FALSE ;
  820. continue ;
  821. }
  822. if( (dwCmdIn != UNUSED_ITEM) &&
  823. BaddSequencedCmdToList(dwCmdIn, pGPDdriverInfo,
  824. dwNewListNode, pubnRaw ) )
  825. dwNewListNode++ ;
  826. while(dwNextOpt) // multiple options selected.
  827. {
  828. if(EextractValueFromTree(pubnRaw, pStatic->dwSSCmdSelectIndex,
  829. (PBYTE)&dwCmdIn, // CmdArray index - dest
  830. &dwUnresolvedFeature, atrRoot, poptsel, dwFea,
  831. &dwNextOpt) != TRI_SUCCESS)
  832. {
  833. bStatus = FALSE ;
  834. continue ;
  835. }
  836. if((dwCmdIn != UNUSED_ITEM) &&
  837. BaddSequencedCmdToList(dwCmdIn, pGPDdriverInfo,
  838. dwNewListNode, pubnRaw ) )
  839. dwNewListNode++ ;
  840. }
  841. }
  842. return(bStatus);
  843. }
  844. BOOL BaddSequencedCmdToList(
  845. DWORD dwCmdIn, // index of a command in CommandArray
  846. PGPDDRIVERINFO pGPDdriverInfo,
  847. DWORD dwNewListNode, // an unused listnode to add to the list.
  848. PBYTE pubnRaw // raw binary data.
  849. )
  850. /* remember:
  851. the pdwSeqCmdRoot points to the first node in a list.
  852. There is a list for each SEQSECTION.
  853. Each node contains the index to a command in the command array
  854. and an index to the next node in the list.
  855. */
  856. {
  857. PCOMMAND pcmdArray ; // the Command Array
  858. SEQSECTION eSection;
  859. PDWORD pdwSeqCmdRoot ; // points to a list root.
  860. DWORD dwOrder, // order value of a command.
  861. dwCurListNode, // node index as we traverse the list.
  862. dwPrevsListNode ; // the prevs node in the list.
  863. PINFOHEADER pInfoHdr ;
  864. PLISTNODE plstNodes ; // start of local listnodes array
  865. PENHARRAYREF pearTableContents ;
  866. PBYTE pubRaw ;
  867. PSTATICFIELDS pStatic ;
  868. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  869. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  870. pInfoHdr = pGPDdriverInfo->pInfoHeader ;
  871. plstNodes = (PLISTNODE)((PBYTE)pInfoHdr +
  872. pGPDdriverInfo->DataType[DT_LOCALLISTNODE].loOffset) ;
  873. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  874. pcmdArray = (PCOMMAND)(pubRaw +
  875. pearTableContents[MTI_COMMANDARRAY].loOffset) ;
  876. eSection = pcmdArray[dwCmdIn].ordOrder.eSection ;
  877. switch(eSection)
  878. {
  879. case (SS_JOBSETUP):
  880. {
  881. pdwSeqCmdRoot = &pGPDdriverInfo->dwJobSetupIndex;
  882. break ;
  883. }
  884. case (SS_DOCSETUP):
  885. {
  886. pdwSeqCmdRoot = &pGPDdriverInfo->dwDocSetupIndex;
  887. break ;
  888. }
  889. case (SS_PAGESETUP):
  890. {
  891. pdwSeqCmdRoot = &pGPDdriverInfo->dwPageSetupIndex;
  892. break ;
  893. }
  894. case (SS_PAGEFINISH):
  895. {
  896. pdwSeqCmdRoot = &pGPDdriverInfo->dwPageFinishIndex;
  897. break ;
  898. }
  899. case (SS_DOCFINISH):
  900. {
  901. pdwSeqCmdRoot = &pGPDdriverInfo->dwDocFinishIndex;
  902. break ;
  903. }
  904. case (SS_JOBFINISH):
  905. {
  906. pdwSeqCmdRoot = &pGPDdriverInfo->dwJobFinishIndex;
  907. break ;
  908. }
  909. default:
  910. {
  911. ERR(("BaddSequencedCmdToList: Invalid or non-existent *Order value specified.\n"));
  912. return(FALSE); // command not added to linked list.
  913. }
  914. }
  915. // Insert a new node in the list pointed to by pdwSeqCmdRoot
  916. dwOrder = pcmdArray[dwCmdIn].ordOrder.dwOrder ;
  917. // walk the list until you find an order larger than yours.
  918. dwPrevsListNode = END_OF_LIST ;
  919. dwCurListNode = *pdwSeqCmdRoot ;
  920. while((dwCurListNode != END_OF_LIST) &&
  921. (pcmdArray[plstNodes[dwCurListNode].dwData].ordOrder.dwOrder
  922. < dwOrder) )
  923. {
  924. dwPrevsListNode = dwCurListNode ;
  925. dwCurListNode = plstNodes[dwCurListNode].dwNextItem ;
  926. }
  927. plstNodes[dwNewListNode].dwData = dwCmdIn ;
  928. plstNodes[dwNewListNode].dwNextItem = dwCurListNode ;
  929. if(dwPrevsListNode == END_OF_LIST)
  930. *pdwSeqCmdRoot = dwNewListNode ;
  931. else
  932. plstNodes[dwPrevsListNode].dwNextItem = dwNewListNode ;
  933. return(TRUE) ;
  934. }
  935. /*++
  936. The default Option array (as determined from the gpd) is initialized.
  937. Since the options or attributues of features may be dependent on the
  938. some other features, the order of initialization of feature assumes
  939. importance. The priority array therefore tries to order the
  940. initialization so that when a feature has to be initialised, all the
  941. features on which it is dependent on have already been initialised.
  942. If, inspite of the priority array, a feature's option cannot be
  943. determined until some other feature's option has been determined,
  944. the RaisePriority Function is used (This is called by
  945. EdetermineDefaultOption() ).
  946. A quirky code here is the pdwPriorityCopy which is initialised
  947. to pdwPriority. The latter is in read only space and therefore
  948. prevents change of priority in the RaisePriority Function.
  949. Therefore pdwPriorityCopy is passed to that function.
  950. Some special case processing is required for the *Feature:Locale
  951. keyword if it occurs in the .gpd. The default option for this
  952. feature is to be set to the SystemDefaultLocale.
  953. --*/
  954. BinitDefaultOptionArray(
  955. POPTSELECT poptsel, // assume is large enough
  956. PBYTE pubnRaw)
  957. {
  958. PENHARRAYREF pearTableContents ;
  959. // PMINIRAWBINARYDATA pmrbd ;
  960. PDFEATURE_OPTIONS pfo ;
  961. PDWORD pdwPriority, // Array of feature indices arranged
  962. // according to priority.
  963. pdwPriorityCopy; // pdwPriority is in read only space.
  964. // We might have to change the
  965. // priorities temporarily to allow
  966. // Default option array to be
  967. // constructed. This change is done in
  968. // pdwPriorityCopy
  969. DWORD dwNumFeatures, // Total number of features
  970. dwI ,
  971. dwFea, // Index of Feature Locale
  972. dwOptIndex; // Index of Option of Locale that
  973. // matches System Locale
  974. PBYTE pubRaw ;
  975. PSTATICFIELDS pStatic ;
  976. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  977. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  978. // obtain pointers to structures:
  979. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  980. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  981. dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
  982. dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
  983. // both explicit and synthesized features are contiguous.
  984. if(dwNumFeatures > MAX_COMBINED_OPTIONS)
  985. return(FALSE); // too many to save
  986. dwFea = dwOptIndex = (DWORD)-1; // For safety sake only. Should be initialized
  987. // in the function BgetLocFeaOptIndex().
  988. // returns TRUE if everything OK. if return is TRUE and dwFea is -1
  989. // Locale is not present and no special processing is required.
  990. // If dwFea != -1 and dwOptIndex == -1 means none of the options in
  991. // the .gpd match the system default. Again no special processing
  992. // for locale is required.
  993. // Assuming that only a single matching option is possible for
  994. // Locale.
  995. if ( !BgetLocFeaOptIndex(
  996. (PRAWBINARYDATA)pubnRaw, &dwFea, &dwOptIndex) )
  997. {
  998. return FALSE;
  999. }
  1000. pdwPriority = (PDWORD)(pubRaw + pearTableContents[MTI_PRIORITYARRAY].
  1001. loOffset) ;
  1002. pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
  1003. loOffset) ;
  1004. if ( ! (pdwPriorityCopy = (PDWORD) MemAlloc (
  1005. pearTableContents[MTI_PRIORITYARRAY].dwCount *
  1006. pearTableContents[MTI_PRIORITYARRAY].dwElementSiz ) ) )
  1007. {
  1008. // Set error codes and
  1009. ERR(("Fatal: BinitDefaultOptionArray - unable to allocate memory\n" ));
  1010. return FALSE;
  1011. }
  1012. memcpy(pdwPriorityCopy, pdwPriority,
  1013. pearTableContents[MTI_PRIORITYARRAY].dwCount *
  1014. pearTableContents[MTI_PRIORITYARRAY].dwElementSiz );
  1015. for(dwI = 0 ; dwI < dwNumFeatures ; dwI++)
  1016. {
  1017. poptsel[dwI].ubCurOptIndex = OPTION_INDEX_ANY ;
  1018. poptsel[dwI].ubNext = NULL_OPTSELECT ;
  1019. }
  1020. // Initialize the option array for Feature Locale.
  1021. // Or should we call ReconstructOptionArray.????
  1022. if ( dwFea != -1 && dwOptIndex != -1)
  1023. {
  1024. poptsel[dwFea].ubCurOptIndex = (BYTE)dwOptIndex;
  1025. poptsel[dwFea].ubNext = NULL_OPTSELECT ;
  1026. }
  1027. for(dwI = 0 ; dwI < dwNumFeatures ; dwI++)
  1028. {
  1029. // The order of evaluation is determined
  1030. // by the priority array.
  1031. if(poptsel[pdwPriorityCopy[dwI]].ubCurOptIndex == OPTION_INDEX_ANY)
  1032. {
  1033. if(EdetermineDefaultOption(pubnRaw , pdwPriorityCopy[dwI],
  1034. pfo, poptsel, pdwPriorityCopy) != TRI_SUCCESS)
  1035. {
  1036. ERR(("BinitDefaultOptionArray: failed to determine consistent \
  1037. default options.\n"));
  1038. if ( pdwPriorityCopy )
  1039. MemFree(pdwPriorityCopy);
  1040. return(FALSE);
  1041. }
  1042. }
  1043. }
  1044. // BUG_BUG!!!! now verify the set options thus determined is
  1045. // fully self consistent. is not precluded by UIConstraints.
  1046. // warn user and fail otherwise .
  1047. // successful execution of EdetermineDefaultOption basically
  1048. // assures this.
  1049. if ( pdwPriorityCopy )
  1050. MemFree(pdwPriorityCopy);
  1051. return(TRUE);
  1052. }
  1053. TRISTATUS EdetermineDefaultOption(
  1054. PBYTE pubnRaw, // start of Rawbinary data
  1055. DWORD dwFeature, // determine the default for this feature
  1056. PDFEATURE_OPTIONS pfo,
  1057. POPTSELECT poptsel, // assume is large enough
  1058. PDWORD pdwPriority) // Priority array indicating the priority of various
  1059. // features.
  1060. {
  1061. // PMINIRAWBINARYDATA pmrbd ;
  1062. TRISTATUS eStatus ;
  1063. DWORD dwUnresolvedFeature , // no option has been determined
  1064. dwNextOpt , // for this feature
  1065. dwOption ; // for BextractValueFromTree
  1066. // to write into.
  1067. PBYTE pubRaw ;
  1068. PSTATICFIELDS pStatic ;
  1069. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  1070. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  1071. // This function will modify the priority array
  1072. // each time the tree walk fails so that each feature
  1073. // evaluated depends only on default options that have
  1074. // previously evaluated .
  1075. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  1076. dwNextOpt = 0 ; // extract info for first option selected for
  1077. // this feature.
  1078. while((eStatus = EextractValueFromTree(
  1079. pubnRaw, pStatic->dwSSdefaultOptionIndex,
  1080. (PBYTE )&dwOption,
  1081. &dwUnresolvedFeature,
  1082. pfo[dwFeature].atrDefaultOption,
  1083. poptsel, 0,
  1084. &dwNextOpt)) == TRI_AGAIN)
  1085. {
  1086. // recursion handles depth, while loop handles breadth
  1087. if(poptsel[dwUnresolvedFeature].ubCurOptIndex == OPTION_PENDING)
  1088. {
  1089. ERR(("Fatal syntax error: EdetermineDefaultOption - circular dependency in default options.\n"));
  1090. return(TRI_UTTER_FAILURE) ;
  1091. }
  1092. poptsel[dwFeature].ubCurOptIndex = OPTION_PENDING ;
  1093. // marks entry in option array so we can detect infinite loops.
  1094. if(!RaisePriority(dwFeature, dwUnresolvedFeature, pubnRaw, pdwPriority))
  1095. return(FALSE) ; // modify Priority array to reflect
  1096. // reality.
  1097. eStatus = EdetermineDefaultOption(pubnRaw, dwUnresolvedFeature,
  1098. pfo, poptsel, pdwPriority) ;
  1099. if(eStatus == TRI_UTTER_FAILURE)
  1100. return(TRI_UTTER_FAILURE) ;
  1101. }
  1102. if(eStatus == TRI_SUCCESS)
  1103. poptsel[dwFeature].ubCurOptIndex = (BYTE)dwOption ;
  1104. return(eStatus);
  1105. }
  1106. VOID VtileDefault(
  1107. PBYTE pubDest,
  1108. DWORD dwDefault,
  1109. DWORD dwBytes)
  1110. {
  1111. DWORD dwRemain ;
  1112. // This function will copy the same DWORD
  1113. // repeatedly into the dest until dwBytes have
  1114. // been written.
  1115. for (dwRemain = dwBytes ; dwRemain > sizeof(DWORD) ;
  1116. dwRemain -= sizeof(DWORD) )
  1117. {
  1118. memcpy(pubDest , &dwDefault, sizeof(DWORD)) ;
  1119. pubDest += sizeof(DWORD) ;
  1120. }
  1121. memcpy(pubDest, &dwDefault, dwRemain) ;
  1122. }
  1123. VOID VtransferValue(
  1124. OUT PBYTE pubDest,
  1125. IN PBYTE pubSrc ,
  1126. IN DWORD dwBytes,
  1127. IN DWORD dwFlags,
  1128. IN DWORD dwDefaultValue, // holds bit flag value.
  1129. IN PBYTE pubHeap ) // used to form ptr if SSF_MAKE_STRINGPTR
  1130. /* this wrapper implements:
  1131. SSF_OFFSETONLY, SSF_MAKE_STRINGPTR,
  1132. SSF_SECOND_DWORD, SSF_SETRCID, SSF_STRINGLEN,
  1133. SSF_BITFIELD_ xxx
  1134. notice all of these flags are basically
  1135. mutually exclusive. But this function only
  1136. enforces this for the first three flags.
  1137. */
  1138. {
  1139. if(dwFlags & SSF_SECOND_DWORD)
  1140. {
  1141. memcpy(pubDest, pubSrc + sizeof(DWORD) , dwBytes) ;
  1142. }
  1143. else if(dwFlags & SSF_MAKE_STRINGPTR)
  1144. {
  1145. PBYTE pubStr ;
  1146. pubStr = pubHeap + ((PARRAYREF)pubSrc)->loOffset ;
  1147. memcpy(pubDest, (PBYTE)&pubStr , sizeof(PBYTE)) ;
  1148. }
  1149. else if(dwFlags & SSF_OFFSETONLY)
  1150. {
  1151. memcpy(pubDest, (PBYTE)&(((PARRAYREF)pubSrc)->loOffset) , dwBytes) ;
  1152. }
  1153. else if(dwFlags & SSF_STRINGLEN)
  1154. {
  1155. memcpy(pubDest, (PBYTE)&(((PARRAYREF)pubSrc)->dwCount) , dwBytes) ;
  1156. }
  1157. else if(dwFlags & SSF_BITFIELD_DEF_FALSE ||
  1158. dwFlags & SSF_BITFIELD_DEF_TRUE)
  1159. {
  1160. if(*(PDWORD)pubSrc) // assume fields are zero initialized
  1161. *(PDWORD)pubDest |= dwDefaultValue ;
  1162. else
  1163. *(PDWORD)pubDest &= ~dwDefaultValue ;
  1164. }
  1165. else
  1166. {
  1167. memcpy(pubDest, pubSrc , dwBytes) ;
  1168. }
  1169. if(dwBytes == sizeof(DWORD) )
  1170. {
  1171. if(dwFlags & SSF_KB_TO_BYTES)
  1172. *(PDWORD)pubDest <<= 10 ; // convert Kbytes to bytes
  1173. else if(dwFlags & SSF_MB_TO_BYTES)
  1174. *(PDWORD)pubDest <<= 20 ; // convert Mbytes to bytes
  1175. if(dwFlags & SSF_SETRCID)
  1176. *(PDWORD)pubDest |= GET_RESOURCE_FROM_DLL ;
  1177. }
  1178. }
  1179. BOOL BspecialProcessOption(
  1180. PBYTE pubnRaw, // start of Rawbinary data
  1181. PBYTE pubDestOption, // ptr to some type of option structure.
  1182. PBYTE pubDestOptionEx,
  1183. PDFEATURE_OPTIONS pfo , // source data
  1184. IN POPTSELECT poptsel, // option array which determines path
  1185. // through atr.
  1186. PINFOHEADER pInfoHdr, // used to access global structure.
  1187. DWORD dwFea, // feature index
  1188. DWORD dwOpt,
  1189. BOOL bDefaultOpt
  1190. )
  1191. {
  1192. PGPDDRIVERINFO pGPDdriverInfo ;
  1193. // PMINIRAWBINARYDATA pmrbd ;
  1194. DWORD dwGID, dwNextOpt, dwUnresolvedFeature, dwI ;
  1195. PBYTE pubDest ;
  1196. PATREEREF patrRoot ;
  1197. PUIINFO pUIinfo ;
  1198. BOOL bStatus = TRUE ;
  1199. PBYTE pubRaw ;
  1200. PSTATICFIELDS pStatic ;
  1201. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  1202. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  1203. pGPDdriverInfo = (PGPDDRIVERINFO)((PBYTE)(pInfoHdr) +
  1204. pInfoHdr->loDriverOffset) ;
  1205. pUIinfo = (PUIINFO)((PBYTE)(pInfoHdr) +
  1206. pInfoHdr->loUIInfoOffset) ;
  1207. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  1208. dwGID = pfo->dwGID ;
  1209. #if 0
  1210. // dead code for now.
  1211. // Extract atrMargins convert to ImageableArea, place in rcImgArea.
  1212. dwI = pStatic->dwSSPaperSizeMarginsIndex;
  1213. if(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID))
  1214. {
  1215. RECT rcMargins ;
  1216. PRECT prcImageArea ;
  1217. SIZE szPaperSize ;
  1218. patrRoot = (PATREEREF)((PBYTE)pfo +
  1219. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  1220. pubDest = (PBYTE)&rcMargins ;
  1221. dwNextOpt = 0 ; // extract info for first option selected for
  1222. // this feature.
  1223. if(EextractValueFromTree(pubnRaw, dwI, pubDest,
  1224. &dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
  1225. // any value. Doesn't matter.
  1226. &dwNextOpt) != TRI_SUCCESS)
  1227. {
  1228. bStatus = FALSE ;
  1229. }
  1230. szPaperSize = ((PPAGESIZE)pubDestOption)->szPaperSize ;
  1231. prcImageArea = &((PPAGESIZE)pubDestOption)->rcImgAreaP ;
  1232. prcImageArea->left = rcMargins.left ;
  1233. prcImageArea->top = rcMargins.top ;
  1234. prcImageArea->right = szPaperSize.x - rcMargins.right ;
  1235. prcImageArea->bottom = szPaperSize.y - rcMargins.bottom ;
  1236. }
  1237. // Extract atrMin/MaxSize place in ptMin/MaxSize in GLOBALS.
  1238. dwI = pStatic->dwSSPaperSizeMinSizeIndex;
  1239. if(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID) &&
  1240. ((PPAGESIZE)pubDestOption)->dwPaperSizeID == DMPAPER_USER )
  1241. {
  1242. pUIinfo->dwCustomSizeOptIndex = dwOpt ;
  1243. pUIinfo->dwFlags |= FLAG_CUSTOMSIZE_SUPPORT ;
  1244. patrRoot = (PATREEREF)((PBYTE)pfo +
  1245. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  1246. pubDest = (PBYTE)(&pGPDdriverInfo->Globals) +
  1247. pStatic->snapShotTable[dwI].dwDestOffset;
  1248. dwNextOpt = 0 ; // extract info for first option selected for
  1249. // this feature.
  1250. if(EextractValueFromTree(pubnRaw, dwI, pubDest,
  1251. &dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
  1252. // any value. Doesn't matter.
  1253. &dwNextOpt) != TRI_SUCCESS)
  1254. {
  1255. bStatus = FALSE ;
  1256. }
  1257. }
  1258. dwI = pStatic->dwSSPaperSizeMaxSizeIndex;
  1259. if(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID) &&
  1260. ((PPAGESIZE)pubDestOption)->dwPaperSizeID == DMPAPER_USER )
  1261. {
  1262. patrRoot = (PATREEREF)((PBYTE)pfo +
  1263. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  1264. pubDest = (PBYTE)(&pGPDdriverInfo->Globals) +
  1265. pStatic->snapShotTable[dwI].dwDestOffset;
  1266. dwNextOpt = 0 ; // extract info for first option selected for
  1267. // this feature.
  1268. if(EextractValueFromTree(pubnRaw, dwI, pubDest,
  1269. &dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
  1270. // any value. Doesn't matter.
  1271. &dwNextOpt) != TRI_SUCCESS)
  1272. {
  1273. bStatus = FALSE ;
  1274. }
  1275. }
  1276. #endif
  1277. dwI = pStatic->dwSSPaperSizeCursorOriginIndex ;
  1278. if(pStatic->snapShotTable[dwI].dwGIDflags & ( 1 << dwGID) )
  1279. {
  1280. TRISTATUS triStatus ;
  1281. patrRoot = (PATREEREF)((PBYTE)pfo +
  1282. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  1283. pubDest = pubDestOptionEx +
  1284. pStatic->snapShotTable[dwI].dwDestOffset;
  1285. dwNextOpt = 0 ; // extract info for first option selected for
  1286. // this feature.
  1287. if((triStatus = EextractValueFromTree(pubnRaw, dwI, pubDest,
  1288. &dwUnresolvedFeature, *patrRoot, poptsel, 0, // set to
  1289. // any value. Doesn't matter.
  1290. &dwNextOpt)) != TRI_SUCCESS)
  1291. {
  1292. if(triStatus == TRI_UNINITIALIZED)
  1293. {
  1294. ((PPAGESIZEEX)pubDestOptionEx)->ptPrinterCursorOrig =
  1295. ((PPAGESIZEEX)pubDestOptionEx)->ptImageOrigin ;
  1296. }
  1297. else
  1298. bStatus = FALSE ;
  1299. }
  1300. }
  1301. if(dwGID == GID_MEMOPTION &&
  1302. bDefaultOpt)
  1303. {
  1304. pUIinfo->dwFreeMem = ((PMEMOPTION)pubDestOption)->dwFreeMem ;
  1305. }
  1306. if(dwGID == GID_COLORMODE &&
  1307. ((PCOLORMODEEX)pubDestOptionEx)->bColor )
  1308. {
  1309. pUIinfo->dwFlags |= FLAG_COLOR_DEVICE ;
  1310. }
  1311. return(bStatus);
  1312. }
  1313. TRISTATUS EextractValueFromTree(
  1314. PBYTE pubnRaw, // start of Rawbinary data
  1315. DWORD dwSSTableIndex, // some info about this value.
  1316. OUT PBYTE pubDest, // write value or link here
  1317. OUT PDWORD pdwUnresolvedFeature, // if the attribute tree has
  1318. // a dependency on this feature and the current option
  1319. // for that feature is not defined in poptsel, this
  1320. // function will write the index of the required
  1321. // feature in pdwUnresolvedFeature.
  1322. IN ATREEREF atrRoot, // root of attribute tree to navigate.
  1323. IN POPTSELECT poptsel, // option array which determines path
  1324. // through atr. may be filled with OPTION_INDEX_ANY
  1325. // if we are jumpstarting
  1326. IN DWORD dwFeature,
  1327. IN OUT PDWORD pdwNextOpt // if multiple options are selected
  1328. // for dwFeature, pdwNextOpt points to the Nth option to consider
  1329. // in the poptsel list, at return time, this value
  1330. // is incremented if there are remaining options selected,
  1331. // else is reset to zero.
  1332. // For the first call, or PICKONE features,
  1333. // this value must be set to zero.
  1334. )
  1335. {
  1336. BOOL bMissingDependency = FALSE;
  1337. PATTRIB_TREE patt ; // start of ATTRIBUTE tree array.
  1338. PENHARRAYREF pearTableContents ;
  1339. // PMINIRAWBINARYDATA pmrbd ;
  1340. DWORD dwBytes , // size of value in bytes
  1341. dwValueNodeIndex , dwNodeIndex, dwFea, dwI ,
  1342. dwDefault , // value to copy or tile to dest.
  1343. dwOption, dwFlags ;
  1344. PBYTE pubHeap , // ptr to start of heap.
  1345. pubSrc ; // ptr to value bytes
  1346. PBYTE pubRaw ;
  1347. PSTATICFIELDS pStatic ;
  1348. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  1349. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  1350. // obtain pointers to structures:
  1351. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  1352. patt = (PATTRIB_TREE)(pubRaw + pearTableContents[MTI_ATTRIBTREE].
  1353. loOffset) ;
  1354. pubHeap = (PBYTE)(pubRaw + pearTableContents[MTI_STRINGHEAP].
  1355. loOffset) ;
  1356. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  1357. dwBytes = pStatic->snapShotTable[dwSSTableIndex].dwNbytes ;
  1358. dwFlags = pStatic->snapShotTable[dwSSTableIndex].dwFlags ;
  1359. dwDefault = pStatic->snapShotTable[dwSSTableIndex].dwDefaultValue ;
  1360. // now attempt to navigate the attributeTree.
  1361. if(atrRoot == ATTRIB_UNINITIALIZED)
  1362. {
  1363. DWORD dwRemain ; // bytes remaining to copy.
  1364. UNINITIALIZED_BRANCH:
  1365. if(dwFlags & SSF_BITFIELD_DEF_FALSE)
  1366. {
  1367. *(PDWORD)pubDest &= ~dwDefault ; // clear bitflag
  1368. }
  1369. else if(dwFlags & SSF_BITFIELD_DEF_TRUE)
  1370. {
  1371. *(PDWORD)pubDest |= dwDefault ; // set bitflag
  1372. }
  1373. else if(!(dwFlags & SSF_DONT_USEDEFAULT))
  1374. {
  1375. if (dwBytes == sizeof(DWORD))
  1376. memcpy (pubDest, &dwDefault, sizeof(DWORD));
  1377. else if (dwBytes == (sizeof(DWORD)*2))
  1378. {
  1379. memcpy (pubDest, &dwDefault, sizeof(DWORD));
  1380. memcpy (pubDest+sizeof(DWORD), &dwDefault, sizeof(DWORD));
  1381. }
  1382. else
  1383. VtileDefault(pubDest, dwDefault, dwBytes) ;
  1384. }
  1385. if(dwFlags & SSF_REQUIRED)
  1386. {
  1387. ERR(("EextractValueFromTree: a required keyword is missing from the GPD file. %s\n",
  1388. pStatic->snapShotTable[dwSSTableIndex].pstrKeyword ));
  1389. return(TRI_UNINITIALIZED) ;
  1390. }
  1391. if(dwFlags & SSF_FAILIFZERO)
  1392. { // see if dest is completely zeroed. Fail if it is.
  1393. for(dwI = 0 ; (dwI < dwBytes) && !pubDest[dwI] ; dwI++)
  1394. ;
  1395. if(dwI == dwBytes)
  1396. {
  1397. ERR(("EextractValueFromTree: None of several initializers found. %s\n",
  1398. pStatic->snapShotTable[dwSSTableIndex].pstrKeyword ));
  1399. return(TRI_UNINITIALIZED) ; // of the two or more
  1400. // keywords that could have initialized this field,
  1401. // none were found.
  1402. }
  1403. }
  1404. if(dwFlags & SSF_RETURN_UNINITIALIZED)
  1405. return(TRI_UNINITIALIZED) ;
  1406. return(TRI_SUCCESS) ; // no value defined.
  1407. }
  1408. else if(atrRoot & ATTRIB_HEAP_VALUE)
  1409. {
  1410. DWORD dwTmp ;
  1411. if(dwFlags & SSF_HEAPOFFSET)
  1412. {
  1413. dwTmp = atrRoot & ~ATTRIB_HEAP_VALUE ;
  1414. pubSrc = (PBYTE)&dwTmp ;
  1415. }
  1416. else
  1417. pubSrc = pubHeap + (atrRoot & ~ATTRIB_HEAP_VALUE) ;
  1418. if (dwBytes == sizeof(DWORD) && !(dwFlags &
  1419. (SSF_SECOND_DWORD |
  1420. SSF_MAKE_STRINGPTR |
  1421. SSF_OFFSETONLY |
  1422. SSF_STRINGLEN |
  1423. SSF_BITFIELD_DEF_FALSE |
  1424. SSF_BITFIELD_DEF_TRUE |
  1425. SSF_KB_TO_BYTES |
  1426. SSF_MB_TO_BYTES |
  1427. SSF_SETRCID)))
  1428. {
  1429. memcpy (pubDest,pubSrc,sizeof(DWORD));
  1430. }
  1431. else
  1432. {
  1433. VtransferValue(pubDest, pubSrc , dwBytes, dwFlags, dwDefault, pubHeap ) ;
  1434. }
  1435. if(dwFlags & SSF_NON_LOCALIZABLE)
  1436. // pmrbd->bContainsNames = TRUE ;
  1437. ; // set a flag here.
  1438. return(TRI_SUCCESS) ;
  1439. }
  1440. // atrRoot specifies a node index
  1441. dwNodeIndex = atrRoot ;
  1442. dwValueNodeIndex = END_OF_LIST ;
  1443. if(patt[dwNodeIndex].dwFeature == DEFAULT_INIT )
  1444. {
  1445. dwValueNodeIndex = dwNodeIndex ;
  1446. dwNodeIndex = patt[dwNodeIndex].dwNext ;
  1447. }
  1448. while (dwNodeIndex != END_OF_LIST)
  1449. {
  1450. if((dwFea = patt[dwNodeIndex].dwFeature) == dwFeature)
  1451. // for this feature, I may want to examine not the first
  1452. // selected option, but other selections. (PICKMANY)
  1453. // walk the PICKMANY list.
  1454. {
  1455. for(dwI = 0 ; dwI < *pdwNextOpt ; dwI++)
  1456. {
  1457. if(poptsel[dwFea].ubNext != NULL_OPTSELECT)
  1458. dwFea = poptsel[dwFea].ubNext ;
  1459. else
  1460. break ;
  1461. }
  1462. if(poptsel[dwFea].ubNext != NULL_OPTSELECT)
  1463. (*pdwNextOpt)++ ;
  1464. else
  1465. *pdwNextOpt = 0 ; // reset to indicate end of list.
  1466. }
  1467. dwOption =
  1468. (DWORD)poptsel[dwFea].ubCurOptIndex ;
  1469. if(dwOption == OPTION_PENDING)
  1470. {
  1471. ERR(("EextractValueFromTree: Fatal syntax error, circular dependency in default options.\n"));
  1472. return(TRI_UTTER_FAILURE) ;
  1473. }
  1474. if(dwOption == OPTION_INDEX_ANY)
  1475. {
  1476. *pdwUnresolvedFeature = patt[dwNodeIndex].dwFeature ;
  1477. return(TRI_AGAIN) ; // option array not fully defined.
  1478. }
  1479. // valid option for this feature, see if a matching
  1480. // node exists.
  1481. #ifndef OLDWAY
  1482. while (patt[dwNodeIndex].dwOption != dwOption &&
  1483. patt[dwNodeIndex].dwNext != END_OF_LIST)
  1484. {
  1485. dwNodeIndex = patt[dwNodeIndex].dwNext;
  1486. }
  1487. if(patt[dwNodeIndex].dwOption != dwOption &&
  1488. patt[dwNodeIndex].dwOption != DEFAULT_INIT)
  1489. {
  1490. break;
  1491. }
  1492. #else
  1493. if(!BfindMatchingOrDefaultNode(patt , &dwNodeIndex, dwOption))
  1494. {
  1495. // attribute tree does not contain the specified
  1496. // branch. Use the Global Default Initializer if exists.
  1497. break ;
  1498. }
  1499. #endif
  1500. if(patt[dwNodeIndex].eOffsetMeans == VALUE_AT_HEAP)
  1501. {
  1502. dwValueNodeIndex = dwNodeIndex ; // Eureka !
  1503. break ;
  1504. }
  1505. // does this node contain a sublevel?
  1506. if(patt[dwNodeIndex].eOffsetMeans == NEXT_FEATURE)
  1507. {
  1508. // Down to the next level we go.
  1509. dwNodeIndex = patt[dwNodeIndex ].dwOffset ;
  1510. }
  1511. else
  1512. break; // tree corruption has occurred. exit.
  1513. }
  1514. if(dwValueNodeIndex != END_OF_LIST &&
  1515. patt[dwValueNodeIndex].eOffsetMeans == VALUE_AT_HEAP )
  1516. {
  1517. if(dwFlags & SSF_HEAPOFFSET)
  1518. pubSrc = (PBYTE)&(patt[dwValueNodeIndex].dwOffset) ;
  1519. else
  1520. pubSrc = pubHeap + patt[dwValueNodeIndex].dwOffset ;
  1521. if (dwBytes == sizeof(DWORD) && !(dwFlags &
  1522. (SSF_SECOND_DWORD |
  1523. SSF_MAKE_STRINGPTR |
  1524. SSF_OFFSETONLY |
  1525. SSF_STRINGLEN |
  1526. SSF_BITFIELD_DEF_FALSE |
  1527. SSF_BITFIELD_DEF_TRUE |
  1528. SSF_KB_TO_BYTES |
  1529. SSF_MB_TO_BYTES |
  1530. SSF_SETRCID)))
  1531. {
  1532. memcpy (pubDest,pubSrc,sizeof(DWORD));
  1533. }
  1534. else
  1535. {
  1536. VtransferValue(pubDest, pubSrc , dwBytes, dwFlags, dwDefault, pubHeap ) ;
  1537. }
  1538. if(dwFlags & SSF_NON_LOCALIZABLE)
  1539. // pmrbd->bContainsNames = TRUE ;
  1540. ; // set a flag here
  1541. return(TRI_SUCCESS) ;
  1542. }
  1543. // attribute tree does not contain the specified
  1544. // branch. This is not necessarily an error since
  1545. // the attribute tree is allowed to be sparsely populated.
  1546. goto UNINITIALIZED_BRANCH ;
  1547. }
  1548. BOOL RaisePriority(
  1549. DWORD dwFeature1,
  1550. DWORD dwFeature2,
  1551. PBYTE pubnRaw,
  1552. PDWORD pdwPriority)
  1553. {
  1554. // takes to lower priority feature and assigns
  1555. // it the priority of the other feature.
  1556. // The priority of all features between feature1
  1557. // and feature2 including the higher priority feature
  1558. // are demoted one level.
  1559. PENHARRAYREF pearTableContents ;
  1560. // PDWORD pdwPriority ;
  1561. DWORD dwHigherP, dwLowerP, dwFeature, dwI, dwEntries ;
  1562. PBYTE pubRaw ;
  1563. PSTATICFIELDS pStatic ;
  1564. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  1565. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  1566. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  1567. /**
  1568. pdwPriority = (PDWORD)(pubRaw + pearTableContents[MTI_PRIORITYARRAY].
  1569. loOffset) ;
  1570. **/
  1571. dwEntries = pearTableContents[MTI_PRIORITYARRAY].dwCount ;
  1572. dwHigherP = dwLowerP = dwEntries ; // init to invalid value.
  1573. // a Priority 1 is considered
  1574. // a 'higher' priority than a priority 2, but arithmetically its
  1575. // the other way around.
  1576. for(dwI = 0 ; dwI < dwEntries ; dwI++)
  1577. {
  1578. if(pdwPriority[dwI] == dwFeature1)
  1579. {
  1580. if(dwHigherP == dwEntries)
  1581. dwHigherP = dwI ;
  1582. else
  1583. {
  1584. dwLowerP = dwI ;
  1585. break ;
  1586. }
  1587. }
  1588. else if(pdwPriority[dwI] == dwFeature2)
  1589. {
  1590. if(dwHigherP == dwEntries)
  1591. dwHigherP = dwI ;
  1592. else
  1593. {
  1594. dwLowerP = dwI ;
  1595. break ;
  1596. }
  1597. }
  1598. }
  1599. // BUG_BUG paranoid: could verify
  1600. // if( dwHigherP == dwEntries || dwLowerP == dwEntries )
  1601. // return(FALSE); priority array or arg values
  1602. // are corrupted .
  1603. ASSERT(dwHigherP != dwEntries && dwLowerP != dwEntries);
  1604. dwFeature = pdwPriority[dwLowerP] ; // this feature will be promoted.
  1605. for(dwI = dwLowerP ; dwI > dwHigherP ; dwI--)
  1606. {
  1607. pdwPriority[dwI] = pdwPriority[dwI - 1] ;
  1608. }
  1609. pdwPriority[dwHigherP] = dwFeature ;
  1610. return(TRUE) ;
  1611. }
  1612. DWORD dwNumOptionSelected(
  1613. IN DWORD dwNumFeatures,
  1614. IN POPTSELECT poptsel
  1615. )
  1616. /* reports number of options actually selected in
  1617. option select array. The caller supplies dwNumFeatures -
  1618. the number of Doc and Printer sticky features, and this
  1619. function does the rest. The actual number of options
  1620. selected may be larger than dwNumFeatures if there are
  1621. PICKMANY features. */
  1622. {
  1623. DWORD dwCount, dwI, // feature Index
  1624. dwNext ; // if pick many, next option selection for this feature.
  1625. dwCount = dwNumFeatures ;
  1626. for(dwI = 0 ; dwI < dwNumFeatures ; dwI++)
  1627. {
  1628. for(dwNext = dwI ;
  1629. poptsel[dwNext].ubNext != NULL_OPTSELECT ;
  1630. dwNext = poptsel[dwNext].ubNext )
  1631. {
  1632. dwCount++ ;
  1633. }
  1634. }
  1635. return(dwCount) ;
  1636. }
  1637. // assume a pointer to this table is stored in the RAWbinary data.
  1638. BOOL BinitSnapShotIndexTable(PBYTE pubnRaw)
  1639. /*
  1640. snapShotTable[] is assumed to be divided into sections
  1641. with an entry with dwNbytes = 0 dividing the sections.
  1642. The end of the table is also terminated by an entry
  1643. with dwNbytes = 0.
  1644. This function initializes pmrbd->ssTableIndex
  1645. which serves as an index into pmrbd->snapShotTable.
  1646. */
  1647. {
  1648. PSTATICFIELDS pStatic ;
  1649. // PMINIRAWBINARYDATA pmrbd ;
  1650. DWORD dwI, // snapShotTable Index
  1651. dwSect ; // SSTABLEINDEX Index
  1652. PRANGE prng ;
  1653. pStatic = (PSTATICFIELDS)pubnRaw ;
  1654. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  1655. pStatic->ssTableIndex = (PRANGE)
  1656. MemAlloc(sizeof(RANGE) * MAX_STRUCTURETYPES) ;
  1657. if(!pStatic->ssTableIndex)
  1658. return(FALSE) ;
  1659. prng = pStatic->ssTableIndex ;
  1660. for(dwI = dwSect = 0 ; dwSect < MAX_STRUCTURETYPES ; dwSect++, dwI++)
  1661. {
  1662. prng[dwSect].dwStart = dwI ;
  1663. for( ; pStatic->snapShotTable[dwI].dwNbytes ; dwI++ )
  1664. ;
  1665. prng[dwSect].dwEnd = dwI ; // one past the last entry
  1666. }
  1667. return(TRUE);
  1668. }
  1669. BOOL BinitSizeOptionTables(PBYTE pubnRaw)
  1670. {
  1671. // PMINIRAWBINARYDATA pmrbd ;
  1672. PSTATICFIELDS pStatic ;
  1673. pStatic = (PSTATICFIELDS)pubnRaw ;
  1674. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  1675. pStatic->pdwSizeOption = (PDWORD)
  1676. MemAlloc(sizeof(DWORD) * MAX_GID * 2) ;
  1677. if(!pStatic->pdwSizeOption)
  1678. return(FALSE) ;
  1679. pStatic->pdwSizeOptionEx = pStatic->pdwSizeOption + MAX_GID ;
  1680. pStatic->pdwSizeOption[GID_RESOLUTION] = sizeof(RESOLUTION);
  1681. pStatic->pdwSizeOptionEx[GID_RESOLUTION] = sizeof(RESOLUTIONEX);
  1682. pStatic->pdwSizeOption[GID_PAGESIZE] = sizeof(PAGESIZE);
  1683. pStatic->pdwSizeOptionEx[GID_PAGESIZE] = sizeof(PAGESIZEEX);
  1684. pStatic->pdwSizeOption[GID_PAGEREGION] = sizeof(OPTION);
  1685. pStatic->pdwSizeOptionEx[GID_PAGEREGION] = 0 ;
  1686. pStatic->pdwSizeOption[GID_DUPLEX] = sizeof(DUPLEX);
  1687. pStatic->pdwSizeOptionEx[GID_DUPLEX] = 0 ;
  1688. pStatic->pdwSizeOption[GID_INPUTSLOT] = sizeof(INPUTSLOT);
  1689. pStatic->pdwSizeOptionEx[GID_INPUTSLOT] = 0 ; // sizeof(INPUTSLOTEX);
  1690. pStatic->pdwSizeOption[GID_MEDIATYPE] = sizeof(MEDIATYPE);
  1691. pStatic->pdwSizeOptionEx[GID_MEDIATYPE] = 0 ;
  1692. pStatic->pdwSizeOption[GID_MEMOPTION] = sizeof(MEMOPTION);
  1693. pStatic->pdwSizeOptionEx[GID_MEMOPTION] = 0 ;
  1694. pStatic->pdwSizeOption[GID_COLORMODE] = sizeof(COLORMODE);
  1695. pStatic->pdwSizeOptionEx[GID_COLORMODE] = sizeof(COLORMODEEX);
  1696. pStatic->pdwSizeOption[GID_ORIENTATION] = sizeof(ORIENTATION);
  1697. pStatic->pdwSizeOptionEx[GID_ORIENTATION] = 0 ;
  1698. pStatic->pdwSizeOption[GID_PAGEPROTECTION] = sizeof(PAGEPROTECT);
  1699. pStatic->pdwSizeOptionEx[GID_PAGEPROTECTION] = 0 ;
  1700. pStatic->pdwSizeOption[GID_COLLATE] = sizeof(COLLATE);
  1701. pStatic->pdwSizeOptionEx[GID_COLLATE] = 0 ;
  1702. pStatic->pdwSizeOption[GID_OUTPUTBIN] = sizeof(OUTPUTBIN);
  1703. pStatic->pdwSizeOptionEx[GID_OUTPUTBIN] = 0 ;
  1704. pStatic->pdwSizeOption[GID_HALFTONING] = sizeof(HALFTONING);
  1705. pStatic->pdwSizeOptionEx[GID_HALFTONING] = 0 ;
  1706. // outside array bounds.
  1707. // pmrbd->pdwSizeOption[GID_UNKNOWN] = sizeof(OPTION);
  1708. // pmrbd->pdwSizeOptionEx[GID_UNKNOWN] = 0 ;
  1709. return(TRUE) ;
  1710. }
  1711. PRAWBINARYDATA
  1712. LoadRawBinaryData (
  1713. IN PTSTR ptstrDataFilename
  1714. )
  1715. /*++
  1716. Routine Description:
  1717. Load raw binary printer description data.
  1718. Arguments:
  1719. ptstrDataFilename - Specifies the name of the original printer description file
  1720. Return Value:
  1721. Pointer to raw binary printer description data
  1722. NULL if there is an error
  1723. --*/
  1724. {
  1725. // PMINIRAWBINARYDATA pmrbd ;
  1726. PSTATICFIELDS pStatic ;
  1727. PRAWBINARYDATA pnRawData; // actually points to pStatic structure
  1728. DWORD dwI ;
  1729. // extern int giDebugLevel ;
  1730. // giDebugLevel = 5 ;
  1731. //
  1732. // Sanity check
  1733. //
  1734. if (ptstrDataFilename == NULL) {
  1735. ERR(("GPD filename is NULL.\n"));
  1736. return NULL;
  1737. }
  1738. //
  1739. // Attempt to load cached binary printer description data first
  1740. //
  1741. if (!(pnRawData = GpdLoadCachedBinaryData(ptstrDataFilename)))
  1742. {
  1743. #ifndef KERNEL_MODE
  1744. #ifdef PARSERLIB
  1745. (VOID) BcreateGPDbinary(ptstrDataFilename, 0) ;
  1746. // 0 = min Verbosity Level
  1747. pnRawData = GpdLoadCachedBinaryData(ptstrDataFilename) ;
  1748. #else PARSERLIB
  1749. //
  1750. // If there is no cached binary data or it's out-of-date, we'll parse
  1751. // the ASCII text file and cache the resulting binary data.
  1752. //
  1753. DWORD pathlen = 0 ;
  1754. DWORD namelen = 0 ;
  1755. WCHAR * pwDLLQualifiedName = NULL ;
  1756. // WCHAR awchDLLpath[MAX_PATH];
  1757. PWSTR pwstrDLLname = TEXT("gpdparse.dll") ;
  1758. typedef BOOL (*PFBCREATEGPDBINARY)(PWSTR, DWORD) ;
  1759. PFBCREATEGPDBINARY pfBcreateGPDbinary = NULL ;
  1760. PWSTR pwstrLastBackSlash ;
  1761. HINSTANCE hParser = NULL ;
  1762. // how large should pwDLLQualifiedName be???
  1763. pathlen = wcslen(ptstrDataFilename) ;
  1764. namelen = pathlen + wcslen(pwstrDLLname) + 1;
  1765. if(!(pwDLLQualifiedName = (PWSTR)MemAllocZ(namelen * sizeof(WCHAR)) ))
  1766. {
  1767. ERR(("Fatal: unable to alloc memory for pwDLLQualifiedName: %d WCHARs.\n",
  1768. namelen));
  1769. return(NULL) ; // This is unrecoverable
  1770. }
  1771. wcsncpy(pwDLLQualifiedName, ptstrDataFilename , namelen);
  1772. if (pwstrLastBackSlash = wcsrchr(pwDLLQualifiedName, TEXT('\\')))
  1773. {
  1774. *(pwstrLastBackSlash + 1) = NUL;
  1775. // wcscat(pwDLLQualifiedName, pwstrDLLname) ;
  1776. StringCchCatW(pwDLLQualifiedName, namelen, pwstrDLLname);
  1777. hParser = LoadLibrary(pwDLLQualifiedName) ;
  1778. if(hParser)
  1779. pfBcreateGPDbinary = (PFBCREATEGPDBINARY)GetProcAddress(hParser, "BcreateGPDbinary") ;
  1780. else
  1781. ERR(("Couldn't load gpdparse.dll: %S\n", pwDLLQualifiedName)) ;
  1782. if(pfBcreateGPDbinary)
  1783. (VOID) pfBcreateGPDbinary(ptstrDataFilename, 0) ;
  1784. // 0 = min Verbosity Level
  1785. if(hParser)
  1786. FreeLibrary(hParser) ;
  1787. pnRawData = GpdLoadCachedBinaryData(ptstrDataFilename) ;
  1788. }
  1789. if(pwDLLQualifiedName)
  1790. MemFree(pwDLLQualifiedName) ;
  1791. #endif PARSERLIB
  1792. #endif KERNEL_MODE
  1793. }
  1794. if(!pnRawData)
  1795. {
  1796. // there is nothing I can do about this now.
  1797. ERR(("Unable to locate or create Binary data.\n"));
  1798. SetLastError(ERROR_FILE_CORRUPT);
  1799. return NULL;
  1800. }
  1801. pStatic = (PSTATICFIELDS)pnRawData ;
  1802. /* BETA2 */
  1803. // pmrbd->rbd.pvReserved = NULL; Do when creating BUD file.
  1804. pStatic->pdwSizeOption = NULL ;
  1805. pStatic->ssTableIndex = NULL ;
  1806. pStatic->snapShotTable = NULL ;
  1807. // Call initialization functions to setup a few tables
  1808. // needed to create snapshots.
  1809. if(BinitSizeOptionTables((PBYTE)pnRawData) &&
  1810. (dwI = DwInitSnapShotTable1((PBYTE)pnRawData) ) &&
  1811. (dwI = DwInitSnapShotTable2((PBYTE)pnRawData, dwI) ) &&
  1812. (dwI < MAX_SNAPSHOT_ELEMENTS) &&
  1813. BinitSnapShotIndexTable((PBYTE)pnRawData) )
  1814. {
  1815. return (pnRawData);
  1816. }
  1817. if(dwI >= MAX_SNAPSHOT_ELEMENTS)
  1818. RIP(("Too many entries to fit inside SnapShotTable\n"));
  1819. UnloadRawBinaryData (pnRawData) ;
  1820. return (NULL); // failure
  1821. }
  1822. PRAWBINARYDATA
  1823. GpdLoadCachedBinaryData(
  1824. PTSTR ptstrGpdFilename
  1825. )
  1826. /*++
  1827. Routine Description:
  1828. Load cached binary GPD data file into memory
  1829. Arguments:
  1830. ptstrGpdFilename - Specifies the GPD filename
  1831. Return Value:
  1832. Pointer to Binary GPD data if successful, NULL if there is an error
  1833. BETA2 returns pointer to pStatic.
  1834. --*/
  1835. {
  1836. HFILEMAP hFileMap;
  1837. DWORD dwSize;
  1838. PVOID pvData;
  1839. PTSTR ptstrBpdFilename;
  1840. PRAWBINARYDATA pRawData ;
  1841. PSTATICFIELDS pstaticData = NULL;
  1842. // PMINIRAWBINARYDATA pmrbd ;
  1843. //
  1844. // Generate BPD filename from the specified PPD filename
  1845. //
  1846. if (! (ptstrBpdFilename = pwstrGenerateGPDfilename(ptstrGpdFilename)))
  1847. return NULL;
  1848. //
  1849. // First map the data file into memory
  1850. //
  1851. if (! (hFileMap = MapFileIntoMemory(ptstrBpdFilename, &pvData, &dwSize)))
  1852. {
  1853. // ERR(("Couldn't map file '%ws' into memory: %d\n", ptstrBpdFilename, GetLastError()));
  1854. MemFree(ptstrBpdFilename);
  1855. return NULL;
  1856. }
  1857. //
  1858. // Verify size, parser version number, and signature.
  1859. // Allocate a memory buffer and copy data into it.
  1860. //
  1861. pRawData = pvData;
  1862. // pmrbd = (PMINIRAWBINARYDATA)pRawData ;
  1863. pstaticData = NULL;
  1864. if ((dwSize > sizeof(PMINIRAWBINARYDATA) +
  1865. sizeof(ENHARRAYREF) * MTI_NUM_SAVED_OBJECTS) &&
  1866. (dwSize >= pRawData->dwFileSize) &&
  1867. (pRawData->dwParserVersion == GPD_PARSER_VERSION) &&
  1868. (pRawData->dwParserSignature == GPD_PARSER_SIGNATURE) &&
  1869. (BIsRawBinaryDataInDate((PBYTE)pRawData)) &&
  1870. (pstaticData = MemAlloc(sizeof(STATICFIELDS))))
  1871. {
  1872. CopyMemory(&(pstaticData->rbd), pRawData, sizeof(RAWBINARYDATA));
  1873. // copy only the first structure of the BUD file.
  1874. pstaticData->hFileMap = hFileMap ;
  1875. pstaticData->pubBUDData = (PBYTE)pRawData ; // BETA2
  1876. // this points to the entire BUD file.
  1877. }
  1878. else
  1879. {
  1880. ERR(("Invalid binary GPD data\n")); // warning
  1881. SetLastError(ERROR_INVALID_DATA);
  1882. UnmapFileFromMemory(hFileMap); // BETA2
  1883. MemFree(ptstrBpdFilename);
  1884. return(NULL) ; // fatal error.
  1885. }
  1886. MemFree(ptstrBpdFilename);
  1887. return &(pstaticData->rbd); // BETA2
  1888. }
  1889. VOID
  1890. UnloadRawBinaryData (
  1891. IN PRAWBINARYDATA pnRawData
  1892. )
  1893. {
  1894. PSTATICFIELDS pStatic ;
  1895. // PMINIRAWBINARYDATA pmrbd ;
  1896. // pmrbd = (PMINIRAWBINARYDATA)pRawData ;
  1897. pStatic = (PSTATICFIELDS)pnRawData ;
  1898. if(!pnRawData)
  1899. {
  1900. ERR(("GpdUnloadRawBinaryData given Null ptr.\n"));
  1901. return ;
  1902. }
  1903. if(pStatic->pdwSizeOption)
  1904. MemFree(pStatic->pdwSizeOption);
  1905. if(pStatic->ssTableIndex)
  1906. MemFree(pStatic->ssTableIndex);
  1907. if(pStatic->snapShotTable)
  1908. MemFree(pStatic->snapShotTable);
  1909. UnmapFileFromMemory(pStatic->hFileMap); // BETA2
  1910. MemFree(pnRawData);
  1911. }
  1912. PINFOHEADER
  1913. InitBinaryData(
  1914. IN PRAWBINARYDATA pnRawData, // actually pStatic
  1915. IN PINFOHEADER pInfoHdr,
  1916. IN POPTSELECT pOptions
  1917. )
  1918. {
  1919. BOOL bDeleteOptArray = FALSE ;
  1920. if(pInfoHdr)
  1921. {
  1922. FreeBinaryData(pInfoHdr) ;
  1923. // there's no advantage to keeping the block
  1924. // if we are going to reinitialize everything.
  1925. // eventually we can optimize.
  1926. }
  1927. if(!pOptions) // if not passed from UI
  1928. {
  1929. bDeleteOptArray = TRUE ;
  1930. pOptions = (POPTSELECT)MemAlloc(sizeof(OPTSELECT) * MAX_COMBINED_OPTIONS) ;
  1931. if(!pOptions ||
  1932. !BinitDefaultOptionArray(pOptions, (PBYTE)pnRawData))
  1933. {
  1934. if(pOptions)
  1935. MemFree(pOptions);
  1936. return(NULL); // Bummer, you lose any pInfoHdr you passed in.
  1937. }
  1938. }
  1939. pInfoHdr = PINFOHDRcreateSnapshot((PBYTE)pnRawData, pOptions) ;
  1940. if(bDeleteOptArray && pOptions)
  1941. MemFree(pOptions);
  1942. return( pInfoHdr );
  1943. }
  1944. VOID
  1945. FreeBinaryData(
  1946. IN PINFOHEADER pInfoHdr
  1947. )
  1948. {
  1949. if(pInfoHdr)
  1950. MemFree(pInfoHdr);
  1951. }
  1952. BOOL BIsRawBinaryDataInDate(
  1953. IN PBYTE pubRaw) // this is pointer to memory mapped file! BETA2
  1954. {
  1955. #ifdef KERNEL_MODE
  1956. return(TRUE);
  1957. #else // !KERNEL_MODE
  1958. PENHARRAYREF pearTableContents ;
  1959. PGPDFILEDATEINFO pfdi ;
  1960. DWORD dwNumFiles, dwI ;
  1961. BOOL bInDate ;
  1962. PBYTE pubHeap ;
  1963. PWSTR pwstrFileName ;
  1964. FILETIME FileTime;
  1965. HANDLE hFile;
  1966. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  1967. pubHeap = pubRaw + pearTableContents[MTI_STRINGHEAP].loOffset ;
  1968. dwNumFiles = pearTableContents[MTI_GPDFILEDATEINFO].dwCount ;
  1969. pfdi = (PGPDFILEDATEINFO)(pubRaw + pearTableContents[MTI_GPDFILEDATEINFO].
  1970. loOffset) ;
  1971. for(dwI = 0 ; dwI < dwNumFiles ; dwI++)
  1972. {
  1973. pwstrFileName = OFFSET_TO_POINTER(pubHeap, pfdi[dwI].arFileName.loOffset);
  1974. bInDate = FALSE ;
  1975. hFile = CreateFile(pwstrFileName,
  1976. GENERIC_READ,
  1977. FILE_SHARE_READ,
  1978. NULL,
  1979. OPEN_EXISTING,
  1980. FILE_ATTRIBUTE_NORMAL | SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS,
  1981. NULL);
  1982. if (hFile != INVALID_HANDLE_VALUE)
  1983. {
  1984. if (GetFileTime(hFile, NULL, NULL, &FileTime))
  1985. bInDate = (CompareFileTime(&FileTime, &pfdi[dwI].FileTime) == 0 ) ;
  1986. else
  1987. ERR(("GetFileTime '%S' failed.\n", pwstrFileName));
  1988. CloseHandle(hFile);
  1989. }
  1990. else {
  1991. ERR(("CreateFile '%S' failed.\n", pwstrFileName));
  1992. }
  1993. if(!bInDate)
  1994. {
  1995. ERR(("Raw binary data file is out-of-date.\n"));
  1996. return(FALSE) ;
  1997. }
  1998. }
  1999. return(TRUE);
  2000. #endif // !KERNEL_MODE
  2001. }
  2002. // Puts the Index of Feature Locale(if present) in *pdwFea and returns TRUE.
  2003. // If Locale not present returns TRUE and puts -1 in *pdwFea.
  2004. // Any other processing error, returns FALSE.
  2005. BOOL BgetLocFeaIndex (
  2006. IN PRAWBINARYDATA pnRawData,
  2007. OUT PDWORD pdwFea // The index of the Locale feature
  2008. )
  2009. {
  2010. DWORD dwNumFeatures, // Total Number of features
  2011. dwHeapOffset;
  2012. BOOL bStatus = TRUE; // Warning!!!!!!.
  2013. // Dont remove initialization.
  2014. PBYTE pubSrc,
  2015. pubRaw,
  2016. pubResourceData;
  2017. ATREEREF atrLocKW;
  2018. PDFEATURE_OPTIONS pfoSrc;
  2019. PENHARRAYREF pearTableContents;
  2020. // At this point we only have the raw data which is a big structure
  2021. // with arrays, trees etc. Function PINFOHDRcreateSnapshota()
  2022. // goes through all the Raw Data and extracts info into well defined
  2023. // structures from where it is easy to get the required information.
  2024. // Unfortunately when this function is called, PINFOHDRcreateSnapshot()
  2025. // has not been called earlier, so we are left with getting our hands
  2026. // dirty with the raw data.
  2027. // Since it does make sense to go through the entire raw data just to
  2028. // get the small info that we want, we will attempt to navigate only
  2029. // certain areas.
  2030. pubRaw = ((PSTATICFIELDS)pnRawData)->pubBUDData;
  2031. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  2032. pubResourceData = pubRaw + pearTableContents[MTI_STRINGHEAP].loOffset;
  2033. pfoSrc = (PDFEATURE_OPTIONS)(pubRaw +
  2034. pearTableContents[MTI_DFEATURE_OPTIONS].loOffset);
  2035. dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
  2036. // dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
  2037. if(dwNumFeatures > MAX_COMBINED_OPTIONS)
  2038. return FALSE; // too many
  2039. for ( *pdwFea = 0; bStatus && (*pdwFea < dwNumFeatures); (*pdwFea)++)
  2040. {
  2041. atrLocKW = pfoSrc[*pdwFea].atrFeaKeyWord;
  2042. if ( atrLocKW & ATTRIB_HEAP_VALUE)
  2043. {
  2044. // Get a pointer to the ARRAYREF structure that holds the
  2045. // heap offset of the real string.
  2046. pubSrc = (pubResourceData + (atrLocKW & ~ATTRIB_HEAP_VALUE));
  2047. dwHeapOffset = *((PDWORD)&(((PARRAYREF)pubSrc)->loOffset));
  2048. }
  2049. else
  2050. {
  2051. // It can come here either
  2052. // if (atrRoot == ATTRIB_UNINITIALIZED
  2053. // For a *Feature: <symbolname> to appear
  2054. // without <symbolname> is a syntactic error.
  2055. // Has to be caught earlier.
  2056. // or if
  2057. // patt[dwNodeIndex].dwFeature == DEFAULT_INIT)
  2058. // or if it points to another node.
  2059. // These should never happen.
  2060. // Feature keyword not initialized. Serious Problem.
  2061. // Should have been caught in the parsing stage. Cannot continue.
  2062. ERR(("Feature Symbol Name cannot be determined\n"));
  2063. bStatus = FALSE;
  2064. }
  2065. if ( bStatus && !strncmp(LOCALE_KEYWORD,
  2066. (LPSTR)OFFSET_TO_POINTER(pubResourceData, dwHeapOffset),
  2067. strlen(LOCALE_KEYWORD) ) )
  2068. {
  2069. // FOUND.... Locale.
  2070. break;
  2071. }
  2072. } //for *pdwFea
  2073. if (bStatus && *pdwFea == dwNumFeatures)
  2074. {
  2075. //Feature Locale does not appear in the GPD. Nothing to do.
  2076. *pdwFea = (DWORD)-1;
  2077. }
  2078. return bStatus;
  2079. } //BgetLocFeaIndex(...)
  2080. /*++
  2081. Returns FALSE if some processing error occurs.
  2082. If TRUE is returned then
  2083. i) if dwFea = -1 --> *Feature:Locale not found.
  2084. ii) if dwFea != -1 but dwOptIndex = -1, --> None of the options
  2085. match system locale. OR for some reason we have not been
  2086. able to determine default option. The calling function may
  2087. handle whatever way it wants.
  2088. iii) if neither dwFea nor dwOptIndex is -1 --> Locale feature and
  2089. matching option index found.
  2090. 1) Check if Locale keyword appears in the .gpd. If no, return. No action is
  2091. required. This process also gets the Index of the Locale feature
  2092. if present,
  2093. 2) query the SystemDefaultLCID. Reason: We want to see which Locale
  2094. option in .gpd matches the SystemLCID.
  2095. 3) Go through the option array of the Locale feature and get the Index of
  2096. the option that has OptionId = SystemDefaultCodePage.
  2097. IMPORTANT assumption here is that only one Option will match
  2098. the system LCID. Multiple matching option will result in
  2099. great ambiguity.
  2100. 4) If option not present in GPD, do nothing. return quietly.
  2101. --*/
  2102. BOOL BgetLocFeaOptIndex(
  2103. IN PRAWBINARYDATA pnRawData,
  2104. OUT PDWORD pdwFea, // Assuming space already allocated.
  2105. OUT PDWORD pdwOptIndex // Assuming space already allocated.
  2106. )
  2107. {
  2108. DWORD dwNumFeatures, // Total features
  2109. dwNumOptions, // Total number of options for a feature.
  2110. // dwOptionID
  2111. dwValue; //
  2112. ATREEREF atrOptIDRoot, // Root of OptionID attrib tree.
  2113. // The OptionID (which is = the LCID)
  2114. // is determined by following tree rooted
  2115. // at atrOptIDRoot
  2116. atrOptIDNode; // The heap pointer ( leaf of the tree).
  2117. LCID lcidSystemLocale; // The System locale
  2118. PENHARRAYREF pearTableContents;
  2119. PBYTE pubnRaw,
  2120. pubRaw;
  2121. PDFEATURE_OPTIONS pfo;
  2122. PBYTE pubHeap;
  2123. PATTRIB_TREE patt;
  2124. pubRaw = ((PSTATICFIELDS)pnRawData)->pubBUDData;
  2125. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  2126. pfo = (PDFEATURE_OPTIONS) (pubRaw +
  2127. pearTableContents[MTI_DFEATURE_OPTIONS].loOffset);
  2128. // 1. Extract index of feature locale from raw data
  2129. if ( !BgetLocFeaIndex(pnRawData, pdwFea))
  2130. return FALSE; //Big Time Error.
  2131. if (*pdwFea == -1) {
  2132. return TRUE; //indicates nothing to do. For reasons go into the
  2133. // function dwGetLocFeaIndex
  2134. }
  2135. lcidSystemLocale = LOCALE_SYSTEM_DEFAULT;
  2136. #ifndef WINNT_40
  2137. // 2) Determine the locale(LCID) and put it in lcidSystemLocale
  2138. if ( ! (lcidSystemLocale = GetSystemDefaultLCID() ) )
  2139. {
  2140. ERR(("Cannot determine System locale\n") );
  2141. *pdwOptIndex = (DWORD)-1; //No matching option found.
  2142. return TRUE;
  2143. }
  2144. #endif //ifndef WINNT_40
  2145. // 3. Get Index (dwOptIndex) of Option whose OptionID = lcidSystemLocale
  2146. patt = (PATTRIB_TREE)(pubRaw + pearTableContents[MTI_ATTRIBTREE].
  2147. loOffset) ;
  2148. pubHeap = (PBYTE)(pubRaw + pearTableContents[MTI_STRINGHEAP].
  2149. loOffset) ;
  2150. // Pointer to root of atrOptIdvalue tree (or list)
  2151. atrOptIDRoot = pfo[*pdwFea].atrOptIDvalue;
  2152. if(atrOptIDRoot == ATTRIB_UNINITIALIZED)
  2153. {
  2154. // GPD is coded incorrectly though it may be correct syntactically.
  2155. // The reason for the error is :
  2156. // Every option for the Locale Feature
  2157. // has to have an OptionID that matches the LCID values as
  2158. // specified in Win32. If *OptionID field does not appear in
  2159. // the Option construct, it is an inexcusable error.
  2160. // Instead of failing, let us just indicate that we have not been
  2161. // able to determine the default option i.e. *pdwOptIndex = -1.
  2162. *pdwOptIndex = (DWORD)-1;
  2163. return TRUE; // or should it be FALSE
  2164. }
  2165. else if (atrOptIDRoot & ATTRIB_HEAP_VALUE)
  2166. {
  2167. // It cannot appear here.
  2168. // Because *OptionID is ATT_LOCAL_OPTION_ONLY
  2169. // Instead of failing, let us prefer to continue
  2170. ERR(("OptionID for Feature Locale cannot be determined\n"));
  2171. *pdwOptIndex = (DWORD)-1;
  2172. return TRUE;
  2173. }
  2174. else if (patt[atrOptIDRoot].dwFeature == DEFAULT_INIT)
  2175. {
  2176. if ( patt[atrOptIDRoot].dwNext == END_OF_LIST)
  2177. {
  2178. *pdwOptIndex = (DWORD)-1;
  2179. return TRUE;
  2180. }
  2181. atrOptIDRoot = patt[atrOptIDRoot].dwNext ; // to the next node.
  2182. }
  2183. for(; atrOptIDRoot != END_OF_LIST;
  2184. atrOptIDRoot = patt[atrOptIDRoot].dwNext)
  2185. {
  2186. // Should not be anything else.
  2187. if( patt[atrOptIDRoot].eOffsetMeans == VALUE_AT_HEAP)
  2188. {
  2189. atrOptIDNode = patt[atrOptIDRoot].dwOffset;
  2190. dwValue = *(PDWORD)(pubHeap + atrOptIDNode );
  2191. if (dwValue == (DWORD)lcidSystemLocale)
  2192. // Found the option with matching LCID
  2193. {
  2194. *pdwOptIndex = patt[atrOptIDRoot].dwOption;
  2195. break;
  2196. }
  2197. } //if
  2198. else
  2199. {
  2200. ERR(("OptionID for Feature Locale cannot be determined\n"));
  2201. *pdwOptIndex = (DWORD)-1;
  2202. return TRUE;
  2203. }
  2204. } // for
  2205. // 4. Option not present in GPD i.e. Matching locale not found
  2206. // Let the default as specified in GPD continue as default.
  2207. if ( atrOptIDRoot == END_OF_LIST)
  2208. {
  2209. *pdwOptIndex = (DWORD)-1;
  2210. }
  2211. return TRUE;
  2212. } //BgetLocFeaOptIndex
  2213. #endif PARSERDLL
  2214. BOOL BfindMatchingOrDefaultNode(
  2215. IN PATTRIB_TREE patt , // start of ATTRIBUTE tree array.
  2216. IN OUT PDWORD pdwNodeIndex, // Points to first node in chain
  2217. IN DWORD dwOptionID // may even take on the value DEFAULT_INIT
  2218. )
  2219. /* caller passes a NodeIndex that points to the first node in
  2220. a horizontal (option) chain. Caller finds via optionarray
  2221. the corresponding dwOption that is associated with this
  2222. feature.
  2223. search horizontally along the tree searching for a matching
  2224. option. If found, return the index of that node, else see
  2225. if there is a default initializer node at the end of the chain.
  2226. */
  2227. {
  2228. for( ; FOREVER ; )
  2229. {
  2230. if(patt[*pdwNodeIndex].dwOption == dwOptionID )
  2231. {
  2232. // we found it!
  2233. return(TRUE) ;
  2234. }
  2235. if(patt[*pdwNodeIndex].dwNext == END_OF_LIST)
  2236. {
  2237. if(patt[*pdwNodeIndex].dwOption == DEFAULT_INIT )
  2238. return(TRUE) ;
  2239. return(FALSE) ;
  2240. }
  2241. *pdwNodeIndex = patt[*pdwNodeIndex].dwNext ;
  2242. }
  2243. return FALSE;
  2244. }