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.

531 lines
20 KiB

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. /* treewalk.c - functions to enumerate string and font IDs found
  3. in the GPD file. */
  4. /* this source file used only by mdt so is built only
  5. as part of the gpd library */
  6. #include "gpdparse.h"
  7. #ifndef PARSERDLL
  8. // ---- functions defined in treewalk.c ---- //
  9. BOOL GetGPDResourceIDs(
  10. PDWORD pdwResArray,
  11. DWORD dwArraySize, // number of elements in array.
  12. PDWORD pdwNeeded,
  13. BOOL bFontIDs,
  14. PRAWBINARYDATA prbd) ;
  15. BOOL BWalkTheAttribTree(
  16. PBYTE pubnRaw, // start of Rawbinary data
  17. IN ATREEREF atrRoot, // root of attribute tree to navigate.
  18. IN BOOL bList, // is the value stored as a list?
  19. OUT PDWORD arIDarray, // caller supplied array to be
  20. // filled in with all resource IDs found.
  21. IN DWORD dwArraySize, // number of elements in array.
  22. IN OUT PDWORD pdwNeeded // number of resource IDs
  23. );
  24. BOOL BRecurseDownTheTree(
  25. PBYTE pubnRaw, // start of Rawbinary data
  26. IN DWORD dwNodeIndex, // first node in chain of attribute tree to navigate.
  27. IN BOOL bList, // is the value stored as a list?
  28. OUT PDWORD arIDarray, // caller supplied array to be
  29. // filled in with all resource IDs found.
  30. IN DWORD dwArraySize, // number of elements in array.
  31. IN OUT PDWORD pdwNeeded // number of resource IDs
  32. ) ;
  33. BOOL bWalkTheList(
  34. PBYTE pubnRaw, // start of Rawbinary data
  35. IN DWORD dwListIndex, // first node in LIST to navigate.
  36. OUT PDWORD arIDarray, // caller supplied array to be
  37. // filled in with all resource IDs found.
  38. IN DWORD dwArraySize, // number of elements in array.
  39. IN OUT PDWORD pdwNeeded // number of resource IDs
  40. );
  41. BOOL bAddIDtoArray(
  42. IN DWORD dwID, // ID value to add to array.
  43. OUT PDWORD arIDarray, // caller supplied array to be
  44. // filled in with all resource IDs found.
  45. IN DWORD dwArraySize, // number of elements in array.
  46. IN OUT PDWORD pdwNeeded // number of resource IDs
  47. );
  48. BOOL GetGPDResourceIDs(
  49. PDWORD pdwResArray,
  50. DWORD dwArraySize, // number of elements in array.
  51. PDWORD pdwNeeded,
  52. BOOL bFontIDs,
  53. PRAWBINARYDATA prbd)
  54. /*
  55. Parameters:
  56. pdwResArray Resource IDs are loaded into this array
  57. dwArraySize Number of elements in the array
  58. pdwNeeded Number of IDs of the specified resource in the GPD
  59. bFontIDs True if UFM IDs should be loaded into array or false if string IDs should be loaded
  60. prbd GPD raw data pointer from GPDPARSE.DLL.
  61. Returns:
  62. Return FALSE only if BUD corruption has occured.
  63. if pdwResArray is NULL, the number of elements required for the array is stored in pdwNeeded.
  64. if pdwResArray is not NULL, the number of Resource IDs copied into the array is stored in pdwNeeded.
  65. */
  66. {
  67. PENHARRAYREF pearTableContents ;
  68. PBYTE pubRaw ;
  69. PSTATICFIELDS pStatic ;
  70. PBYTE pubHeap ; // ptr to start of heap.
  71. PGLOBALATTRIB pga ;
  72. PATREEREF patrRoot ; // root of attribute tree to navigate.
  73. BOOL bStatus = TRUE ;
  74. DWORD dwNumFeatures, dwFea, dwNumStructs, dwIndex,
  75. dwStart, dwEnd, dwI;
  76. PDFEATURE_OPTIONS pfo ;
  77. PTTFONTSUBTABLE pttfs ;
  78. PFONTCART pfontcart ;
  79. *pdwNeeded = 0 ; // initally set to zero.
  80. pStatic = (PSTATICFIELDS)prbd ; // transform pubRaw from PSTATIC
  81. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  82. // pmrbd = (PMINIRAWBINARYDATA)pubRaw ;
  83. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  84. // need to do this for each section in ssTableIndex
  85. pga = (PGLOBALATTRIB)(pubRaw + pearTableContents[MTI_GLOBALATTRIB].
  86. loOffset) ;
  87. dwStart = pStatic->ssTableIndex[SSTI_GLOBALS].dwStart ; // starting Index
  88. dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_UIINFO].dwEnd ; // Ending Index
  89. for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
  90. {
  91. if(!(pStatic->snapShotTable[dwI].dwNbytes))
  92. continue ; // skip over section delimiter.
  93. if(bFontIDs && !(pStatic->snapShotTable[dwI].dwFlags & SSF_FONTID))
  94. continue;
  95. if(!bFontIDs && !(pStatic->snapShotTable[dwI].dwFlags & SSF_STRINGID))
  96. continue;
  97. patrRoot = (PATREEREF)((PBYTE)pga +
  98. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  99. bStatus = BWalkTheAttribTree(
  100. (PBYTE)prbd, // start of Rawbinary data
  101. *patrRoot, //
  102. pStatic->snapShotTable[dwI].dwFlags & SSF_LIST, // is the value stored as a list?
  103. pdwResArray,
  104. dwArraySize, // number of elements in array.
  105. pdwNeeded ) ;
  106. }
  107. if(!bStatus)
  108. return(bStatus);
  109. // find IDs in Feature/Option structure.
  110. pfo = (PDFEATURE_OPTIONS)(pubRaw + pearTableContents[MTI_DFEATURE_OPTIONS].
  111. loOffset) ;
  112. dwNumFeatures = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
  113. dwNumFeatures += pearTableContents[MTI_SYNTHESIZED_FEATURES].dwCount ;
  114. for( dwFea = 0 ; dwFea < dwNumFeatures ; dwFea++)
  115. {
  116. dwStart = pStatic->ssTableIndex[SSTI_FEATURES].dwStart ; // starting Index
  117. dwEnd = pStatic->ssTableIndex[SSTI_UPDATE_OPTIONEX].dwEnd ; // Ending Index
  118. for(dwI = dwStart ; bStatus && (dwI < dwEnd) ; dwI++)
  119. {
  120. if(!(pStatic->snapShotTable[dwI].dwNbytes))
  121. continue ; // skip over section delimiter.
  122. if(bFontIDs && !(pStatic->snapShotTable[dwI].dwFlags & SSF_FONTID))
  123. continue;
  124. if(!bFontIDs && !(pStatic->snapShotTable[dwI].dwFlags & SSF_STRINGID))
  125. continue;
  126. patrRoot = (PATREEREF)((PBYTE)(pfo + dwFea) +
  127. pStatic->snapShotTable[dwI].dwSrcOffset) ;
  128. bStatus = BWalkTheAttribTree(
  129. (PBYTE)prbd, // start of Rawbinary data
  130. *patrRoot, //
  131. pStatic->snapShotTable[dwI].dwFlags & SSF_LIST, // is the value stored as a list?
  132. pdwResArray,
  133. dwArraySize, // number of elements in array.
  134. pdwNeeded ) ;
  135. }
  136. if(!bStatus)
  137. return(bStatus);
  138. }
  139. pfontcart = (PFONTCART)(pubRaw + pearTableContents[MTI_FONTCART].
  140. loOffset) ;
  141. dwNumStructs = pearTableContents[MTI_FONTCART].dwCount ;
  142. for( dwIndex = 0 ; bStatus && (dwIndex < dwNumStructs) ; dwIndex++)
  143. {
  144. if(bFontIDs)
  145. {
  146. bStatus = bWalkTheList(
  147. (PBYTE)prbd, pfontcart[dwIndex].dwPortFontLst,
  148. pdwResArray, dwArraySize, pdwNeeded ) ;
  149. if(!bStatus)
  150. break;
  151. bStatus = bWalkTheList(
  152. (PBYTE)prbd, pfontcart[dwIndex].dwLandFontLst,
  153. pdwResArray, dwArraySize, pdwNeeded ) ;
  154. if(!bStatus)
  155. break;
  156. }
  157. else
  158. {
  159. bStatus = bAddIDtoArray(
  160. pfontcart[dwIndex].dwRCCartNameID, // ID value to add to array.
  161. pdwResArray, dwArraySize, pdwNeeded) ;
  162. }
  163. // DWORD dwFontLst ; // Index to list of FontIDs
  164. // is already incorporated into landscape and portrait lists
  165. }
  166. pttfs = (PTTFONTSUBTABLE)(pubRaw + pearTableContents[MTI_TTFONTSUBTABLE].
  167. loOffset) ;
  168. dwNumStructs = pearTableContents[MTI_TTFONTSUBTABLE].dwCount ;
  169. for( dwIndex = 0 ; !bFontIDs && bStatus &&
  170. (dwIndex < dwNumStructs) ; dwIndex++)
  171. {
  172. bStatus = bAddIDtoArray(
  173. pttfs[dwIndex].dwRcTTFontNameID, // ID value to add to array.
  174. pdwResArray, dwArraySize, pdwNeeded) ;
  175. if(!bStatus)
  176. break;
  177. bStatus = bAddIDtoArray(
  178. pttfs[dwIndex].dwRcDevFontNameID, // ID value to add to array.
  179. pdwResArray, dwArraySize, pdwNeeded) ;
  180. }
  181. return(bStatus);
  182. }
  183. // Return FALSE only if BUD corruption has occured.
  184. BOOL BWalkTheAttribTree(
  185. PBYTE pubnRaw, // start of Rawbinary data
  186. IN ATREEREF atrRoot, // root of attribute tree to navigate.
  187. IN BOOL bList, // is the value stored as a list?
  188. OUT PDWORD arIDarray, // caller supplied array to be
  189. // filled in with all resource IDs found.
  190. IN DWORD dwArraySize, // number of elements in array.
  191. IN OUT PDWORD pdwNeeded // number of resource IDs
  192. // or values found. Initial value
  193. // may be non-zero since this
  194. // accumulates starting from the
  195. // first call. Also serves to track where
  196. // in arIDarray the function should
  197. // be storing the ID values.
  198. )
  199. {
  200. PATTRIB_TREE patt ; // start of ATTRIBUTE tree array.
  201. DWORD dwNodeIndex; // Points to first node in chain
  202. PENHARRAYREF pearTableContents ;
  203. PBYTE pubRaw ;
  204. PSTATICFIELDS pStatic ;
  205. PBYTE pubHeap ; // ptr to start of heap.
  206. BOOL bStatus = TRUE ;
  207. DWORD dwValue, dwListIndex ; // index to listnode.
  208. PDWORD pdwID ; // points to value on the heap.
  209. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  210. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  211. // obtain pointers to structures:
  212. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  213. patt = (PATTRIB_TREE)(pubRaw + pearTableContents[MTI_ATTRIBTREE].
  214. loOffset) ;
  215. pubHeap = (PBYTE)(pubRaw + pearTableContents[MTI_STRINGHEAP].
  216. loOffset) ;
  217. // *pdwNeeded = 0 ; // this is done only once by the caller.
  218. // after processing initial special cases, call another
  219. // function to perform the recursion at each Feature level.
  220. if(atrRoot == ATTRIB_UNINITIALIZED)
  221. return TRUE ; // go to next keyword.
  222. if(atrRoot & ATTRIB_HEAP_VALUE)
  223. {
  224. dwValue = *(PDWORD)(pubHeap + (atrRoot & ~ATTRIB_HEAP_VALUE) );
  225. if(bList)
  226. {
  227. dwListIndex = dwValue ;
  228. // now need to traverse the listnodes.
  229. bStatus = bWalkTheList(
  230. pubnRaw, dwListIndex,
  231. arIDarray, dwArraySize, pdwNeeded ) ;
  232. }
  233. else // ID Value is in the heap.
  234. {
  235. bStatus = bAddIDtoArray(dwValue, // ID value to add to array.
  236. arIDarray, dwArraySize, pdwNeeded) ;
  237. }
  238. return(bStatus); // no more tree traveral to be done.
  239. }
  240. // else atrRoot specifies a node index
  241. dwNodeIndex = atrRoot ;
  242. // first node only might be the global default initializer:
  243. if(patt[dwNodeIndex].dwFeature == DEFAULT_INIT )
  244. {
  245. // we have a global default initializer!
  246. // it may be assumed dwOffset contains heap offset.
  247. if(patt[dwNodeIndex].eOffsetMeans != VALUE_AT_HEAP )
  248. return(FALSE); // assumption violated. BUD is corrupted.
  249. dwValue = *(PDWORD)(pubHeap + patt[dwNodeIndex].dwOffset) ;
  250. if(bList)
  251. {
  252. dwListIndex = dwValue ;
  253. // now need to traverse the listnodes.
  254. bStatus = bWalkTheList(
  255. pubnRaw, dwListIndex,
  256. arIDarray, dwArraySize, pdwNeeded ) ;
  257. }
  258. else // ID Value is in the heap.
  259. {
  260. bStatus = bAddIDtoArray(dwValue, // ID value to add to array.
  261. arIDarray, dwArraySize, pdwNeeded) ;
  262. }
  263. dwNodeIndex = patt[dwNodeIndex].dwNext ; // to the next node.
  264. }
  265. if(bStatus)
  266. bStatus = BRecurseDownTheTree(
  267. pubnRaw, dwNodeIndex, bList,
  268. arIDarray, dwArraySize, pdwNeeded ) ;
  269. // have we overflowed the caller supplied array?
  270. // who cares, just return. It is the callers responsibility
  271. // to see how many IDs were found and how much was
  272. // allocated.
  273. return(bStatus);
  274. }
  275. BOOL BRecurseDownTheTree(
  276. PBYTE pubnRaw, // start of Rawbinary data
  277. IN DWORD dwNodeIndex, // first node in chain of attribute tree to navigate.
  278. IN BOOL bList, // is the value stored as a list?
  279. OUT PDWORD arIDarray, // caller supplied array to be
  280. // filled in with all resource IDs found.
  281. IN DWORD dwArraySize, // number of elements in array.
  282. IN OUT PDWORD pdwNeeded // number of resource IDs
  283. // or values found. Initial value
  284. // may be non-zero since this
  285. // accumulates starting from the
  286. // first call. Also serves to track where
  287. // in arIDarray the function should
  288. // be storing the ID values.
  289. )
  290. {
  291. PATTRIB_TREE patt ; // start of ATTRIBUTE tree array.
  292. PENHARRAYREF pearTableContents ;
  293. PBYTE pubRaw ;
  294. PSTATICFIELDS pStatic ;
  295. PBYTE pubHeap ; // ptr to start of heap.
  296. BOOL bStatus = TRUE ;
  297. DWORD dwValue;
  298. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  299. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  300. // obtain pointers to structures:
  301. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  302. patt = (PATTRIB_TREE)(pubRaw + pearTableContents[MTI_ATTRIBTREE].
  303. loOffset) ;
  304. pubHeap = (PBYTE)(pubRaw + pearTableContents[MTI_STRINGHEAP].
  305. loOffset) ;
  306. // traverse the tree with wild abandon! No more
  307. // special cases to worry about!
  308. for( ; bStatus && dwNodeIndex != END_OF_LIST ;
  309. dwNodeIndex = patt[dwNodeIndex].dwNext )
  310. {
  311. // does this node contain a sublevel?
  312. if(patt[dwNodeIndex].eOffsetMeans == NEXT_FEATURE)
  313. {
  314. DWORD dwNewNodeIndex;
  315. // Down to the next level we go.
  316. dwNewNodeIndex = patt[dwNodeIndex ].dwOffset ;
  317. bStatus = BRecurseDownTheTree(
  318. pubnRaw, dwNewNodeIndex, bList,
  319. arIDarray, dwArraySize, pdwNeeded ) ;
  320. }
  321. else if(patt[dwNodeIndex].eOffsetMeans == VALUE_AT_HEAP)
  322. {
  323. dwValue = *(PDWORD)(pubHeap + patt[dwNodeIndex].dwOffset) ;
  324. if(bList)
  325. {
  326. DWORD dwListIndex = dwValue;
  327. // now need to traverse the listnodes.
  328. bStatus = bWalkTheList(
  329. pubnRaw, dwListIndex,
  330. arIDarray, dwArraySize, pdwNeeded ) ;
  331. }
  332. else // ID Value is in the heap.
  333. {
  334. bStatus = bAddIDtoArray(dwValue, // ID value to add to array.
  335. arIDarray, dwArraySize, pdwNeeded) ;
  336. }
  337. }
  338. else
  339. bStatus = FALSE ; // Tree corruption.
  340. }
  341. return(bStatus);
  342. }
  343. BOOL bWalkTheList(
  344. PBYTE pubnRaw, // start of Rawbinary data
  345. IN DWORD dwListIndex, // first node in LIST to navigate.
  346. OUT PDWORD arIDarray, // caller supplied array to be
  347. // filled in with all resource IDs found.
  348. IN DWORD dwArraySize, // number of elements in array.
  349. IN OUT PDWORD pdwNeeded // number of resource IDs
  350. // or values found. Initial value
  351. // may be non-zero since this
  352. // accumulates starting from the
  353. // first call. Also serves to track where
  354. // in arIDarray the function should
  355. // be storing the ID values.
  356. )
  357. {
  358. PLISTNODE plstRoot ; // start of LIST array
  359. PENHARRAYREF pearTableContents ;
  360. PBYTE pubRaw ;
  361. PSTATICFIELDS pStatic ;
  362. BOOL bStatus = TRUE ;
  363. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  364. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  365. // obtain pointers to structures:
  366. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  367. plstRoot = (PLISTNODE)(pubRaw + pearTableContents[MTI_LISTNODES].
  368. loOffset) ;
  369. for( ; bStatus && dwListIndex != END_OF_LIST ;
  370. dwListIndex = plstRoot[dwListIndex].dwNextItem )
  371. {
  372. bStatus = bAddIDtoArray(
  373. plstRoot[dwListIndex].dwData, // ID value to add to array.
  374. arIDarray, dwArraySize, pdwNeeded) ;
  375. }
  376. return(bStatus);
  377. }
  378. BOOL bAddIDtoArray(
  379. IN DWORD dwID, // ID value to add to array.
  380. OUT PDWORD arIDarray, // caller supplied array to be
  381. // filled in with all resource IDs found.
  382. IN DWORD dwArraySize, // number of elements in array.
  383. IN OUT PDWORD pdwNeeded // number of resource IDs
  384. // or values found. Initial value
  385. // may be non-zero since this
  386. // accumulates starting from the
  387. // first call. Also serves to track where
  388. // in arIDarray the function should
  389. // be storing the ID values.
  390. )
  391. {
  392. if(arIDarray && *pdwNeeded < dwArraySize)
  393. {
  394. arIDarray[*pdwNeeded] = dwID ;
  395. }
  396. (*pdwNeeded)++ ;
  397. return(TRUE);
  398. }
  399. /* simplified rules for traversing attribute tree:
  400. features: only time you need to check features is
  401. when you are looking at the first node. Because this may be
  402. the Global default Initializer.
  403. Otherwise dwNext will always take you along to the next option
  404. until you hit END_OF_LIST.
  405. Now OffsetMeans = heapoffset means you extract the value
  406. at the heap or interpret the heapoffset as the array index
  407. of a listnode.
  408. if Offsetmeans = Next_Fea, interpret heapoffset as treenode
  409. index and begin searching in this new branch.
  410. You must perform recursion.
  411. so this function must pass in a writable counter
  412. that track which entry in the user supplied array is
  413. 'current' (ready to be written into). This serves both
  414. to keep track of where to write the ID values and how large
  415. an array the user should supply. This same counter
  416. must be passed into the function that walks the listnodes. */
  417. #endif PARSERDLL