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.

1608 lines
57 KiB

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. /*
  3. * postproc.c - postprocessing functions
  4. History of Changes
  5. 9/30/98 --hsingh--
  6. Added three functions BsetUQMFlag(), BRecurseNodes(), BsetUQMTrue()
  7. to enable making the UpdateQualityMacro? keyword optional in
  8. .gpd file.
  9. Bug Report 225088
  10. */
  11. #include "gpdparse.h"
  12. // ---- functions defined in postproc.c ---- //
  13. DWORD dwFindLastNode(
  14. DWORD dwFirstNode,
  15. PGLOBL pglobl) ;
  16. BOOL BappendCommonFontsToPortAndLandscape(
  17. PGLOBL pglobl) ;
  18. BOOL BinitSpecialFeatureOptionFields(
  19. PGLOBL pglobl) ;
  20. BOOL BIdentifyConstantString(
  21. IN PARRAYREF parString,
  22. OUT PDWORD pdwDest, // write dword value here.
  23. IN DWORD dwClassIndex, // which class of constant is this?
  24. BOOL bCustomOptOK,
  25. PGLOBL pglobl
  26. ) ;
  27. BOOL BReadDataInGlobalNode(
  28. PATREEREF patr, // address of field in GlobalAttrib struct
  29. PDWORD pdwHeapOffset,
  30. PGLOBL pglobl
  31. ) ;
  32. BOOL BsetUQMFlag(PGLOBL pglobl);
  33. BOOL BRecurseNodes(
  34. IN DWORD dwNodeIndex,
  35. PGLOBL pglobl);
  36. BOOL BsetUQMTrue(
  37. IN DWORD dwFeature,
  38. PGLOBL pglobl);
  39. VOID VCountPrinterDocStickyFeatures(
  40. PGLOBL pglobl) ;
  41. BOOL BConvertSpecVersionToDWORD (
  42. PWSTR pwstrFileName ,
  43. PGLOBL pglobl) ;
  44. BOOL BinitMiniRawBinaryData(
  45. PGLOBL pglobl) ;
  46. BOOL BexchangeArbDataInFOATNode(
  47. DWORD dwFeature,
  48. DWORD dwOption,
  49. DWORD dwFieldOff, // offset of field in FeatureOption struct
  50. DWORD dwCount, // number bytes to copy.
  51. OUT PBYTE pubOut, // previous contents of attribute node
  52. IN PBYTE pubIn, // new contents of attribute node.
  53. PBOOL pbPrevsExists, // previous contents existed.
  54. BOOL bSynthetic, // access synthetic features
  55. PGLOBL pglobl
  56. ) ;
  57. BOOL BInitPriorityArray(
  58. PGLOBL pglobl) ;
  59. // ---------------------------------------------------- //
  60. typedef struct
  61. {
  62. DWORD paperID ;
  63. DWORD x ;
  64. DWORD y ;
  65. } PAPERDIM ;
  66. CONST PAPERDIM aPaperDimensions[] = {
  67. DMPAPER_LETTER, 215900, 279400,
  68. DMPAPER_LETTERSMALL, 215900, 279400,
  69. DMPAPER_TABLOID, 279400, 431800,
  70. DMPAPER_LEDGER, 431800, 279400,
  71. DMPAPER_LEGAL, 215900, 355600,
  72. DMPAPER_STATEMENT, 139700, 215900,
  73. DMPAPER_EXECUTIVE, 184150, 266700,
  74. DMPAPER_A3, 297000, 420000,
  75. DMPAPER_A4, 210000, 297000,
  76. DMPAPER_A4SMALL, 210000, 297000,
  77. DMPAPER_A5, 148000, 210000,
  78. DMPAPER_B4, 257000, 364000,
  79. DMPAPER_B5, 182000, 257000,
  80. DMPAPER_FOLIO, 215900, 330200,
  81. DMPAPER_QUARTO, 215000, 275000,
  82. DMPAPER_10X14, 254000, 355600,
  83. DMPAPER_11X17, 279400, 431800,
  84. DMPAPER_NOTE, 215900, 279400,
  85. DMPAPER_ENV_9, 98425, 225425,
  86. DMPAPER_ENV_10, 104775, 241300,
  87. DMPAPER_ENV_11, 114300, 263525,
  88. DMPAPER_ENV_12, 120650, 279400,
  89. DMPAPER_ENV_14, 127000, 292100,
  90. DMPAPER_CSHEET, 431800, 558800,
  91. DMPAPER_DSHEET, 558800, 863600,
  92. DMPAPER_ESHEET, 863600,1117600,
  93. DMPAPER_ENV_DL, 110000, 220000,
  94. DMPAPER_ENV_C5, 162000, 229000,
  95. DMPAPER_ENV_C3, 324000, 458000,
  96. DMPAPER_ENV_C4, 229000, 324000,
  97. DMPAPER_ENV_C6, 114000, 162000,
  98. DMPAPER_ENV_C65, 114000, 229000,
  99. DMPAPER_ENV_B4, 250000, 353000,
  100. DMPAPER_ENV_B5, 176000, 250000,
  101. DMPAPER_ENV_B6, 176000, 125000,
  102. DMPAPER_ENV_ITALY, 110000, 230000,
  103. DMPAPER_ENV_MONARCH, 98425, 190500,
  104. DMPAPER_ENV_PERSONAL, 92075, 165100,
  105. DMPAPER_FANFOLD_US, 377825, 279400,
  106. DMPAPER_FANFOLD_STD_GERMAN, 215900, 304800,
  107. DMPAPER_FANFOLD_LGL_GERMAN, 215900, 330200,
  108. DMPAPER_ISO_B4, 250000, 353000,
  109. DMPAPER_JAPANESE_POSTCARD, 100000, 148000,
  110. DMPAPER_9X11, 228600, 279400,
  111. DMPAPER_10X11, 254000, 279400,
  112. DMPAPER_15X11, 381000, 279400,
  113. DMPAPER_ENV_INVITE, 220000, 220000,
  114. DMPAPER_LETTER_EXTRA, 241300, 304800,
  115. DMPAPER_LEGAL_EXTRA, 241300, 381000,
  116. DMPAPER_TABLOID_EXTRA, 296926, 457200,
  117. DMPAPER_A4_EXTRA, 235458, 322326,
  118. DMPAPER_LETTER_TRANSVERSE, 215900, 279400,
  119. DMPAPER_A4_TRANSVERSE, 210000, 297000,
  120. DMPAPER_LETTER_EXTRA_TRANSVERSE, 241300, 304800,
  121. DMPAPER_A_PLUS, 227000, 356000,
  122. DMPAPER_B_PLUS, 305000, 487000,
  123. DMPAPER_LETTER_PLUS, 215900, 322326,
  124. DMPAPER_A4_PLUS, 210000, 330000,
  125. DMPAPER_A5_TRANSVERSE, 148000, 210000,
  126. DMPAPER_B5_TRANSVERSE, 182000, 257000,
  127. DMPAPER_A3_EXTRA, 322000, 445000,
  128. DMPAPER_A5_EXTRA, 174000, 235000,
  129. DMPAPER_B5_EXTRA, 201000, 276000,
  130. DMPAPER_A2, 420000, 594000,
  131. DMPAPER_A3_TRANSVERSE, 297000, 420000,
  132. DMPAPER_A3_EXTRA_TRANSVERSE, 322000, 445000,
  133. // Predefined forms currently availble only in Win95. Included here
  134. // for compatibility.
  135. // FE-only predefined forms.
  136. #ifndef WINNT_40
  137. DMPAPER_DBL_JAPANESE_POSTCARD, 200000, 148000,
  138. DMPAPER_A6, 105000, 148000,
  139. DMPAPER_JENV_KAKU2, 240000, 332000,
  140. DMPAPER_JENV_KAKU3, 216000, 277000,
  141. DMPAPER_JENV_CHOU3, 120000, 235000,
  142. DMPAPER_JENV_CHOU4, 90000, 205000,
  143. DMPAPER_LETTER_ROTATED, 279400, 215900,
  144. DMPAPER_A3_ROTATED, 420000, 297000,
  145. DMPAPER_A4_ROTATED, 297000, 210000,
  146. DMPAPER_A5_ROTATED, 210000, 148000,
  147. DMPAPER_B4_JIS_ROTATED, 364000, 257000,
  148. DMPAPER_B5_JIS_ROTATED, 257000, 182000,
  149. DMPAPER_JAPANESE_POSTCARD_ROTATED, 148000, 100000,
  150. DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED, 148000, 200000,
  151. DMPAPER_A6_ROTATED, 148000, 105000,
  152. DMPAPER_JENV_KAKU2_ROTATED, 332000, 240000,
  153. DMPAPER_JENV_KAKU3_ROTATED, 277000, 216000,
  154. DMPAPER_JENV_CHOU3_ROTATED, 235000, 120000,
  155. DMPAPER_JENV_CHOU4_ROTATED, 205000, 90000,
  156. DMPAPER_B6_JIS, 128000, 182000,
  157. DMPAPER_B6_JIS_ROTATED, 182000, 128000,
  158. DMPAPER_12X11, 304932, 279521,
  159. DMPAPER_JENV_YOU4, 105000, 235000,
  160. DMPAPER_JENV_YOU4_ROTATED, 235000, 105000,
  161. DMPAPER_P16K, 146000, 215000,
  162. DMPAPER_P32K, 970000, 151000,
  163. DMPAPER_P32KBIG, 101000, 160000,
  164. DMPAPER_PENV_1, 102000, 165000,
  165. DMPAPER_PENV_2, 110000, 176000,
  166. DMPAPER_PENV_3, 125000, 176000,
  167. DMPAPER_PENV_4, 110000, 208000,
  168. DMPAPER_PENV_5, 110000, 220000,
  169. DMPAPER_PENV_6, 120000, 230000,
  170. DMPAPER_PENV_7, 160000, 230000,
  171. DMPAPER_PENV_8, 120000, 309000,
  172. DMPAPER_PENV_9, 229000, 324000,
  173. DMPAPER_PENV_10, 324000, 458000,
  174. DMPAPER_P16K_ROTATED, 215000, 146000,
  175. DMPAPER_P32K_ROTATED, 151000, 970000,
  176. DMPAPER_P32KBIG_ROTATED, 160000, 101000,
  177. DMPAPER_PENV_1_ROTATED, 165000, 102000,
  178. DMPAPER_PENV_2_ROTATED, 176000, 110000,
  179. DMPAPER_PENV_3_ROTATED, 176000, 125000,
  180. DMPAPER_PENV_4_ROTATED, 208000, 110000,
  181. DMPAPER_PENV_5_ROTATED, 220000, 110000,
  182. DMPAPER_PENV_6_ROTATED, 230000, 120000,
  183. DMPAPER_PENV_7_ROTATED, 230000, 160000,
  184. DMPAPER_PENV_8_ROTATED, 309000, 120000,
  185. DMPAPER_PENV_9_ROTATED, 324000, 229000,
  186. DMPAPER_PENV_10_ROTATED, 458000, 324000,
  187. #endif
  188. 0, 0, 0
  189. };
  190. DWORD dwFindLastNode(
  191. DWORD dwFirstNode,
  192. PGLOBL pglobl)
  193. // assume dwFirstNode != END_OF_LIST
  194. {
  195. PLISTNODE plstRoot ; // start of LIST array
  196. plstRoot = (PLISTNODE) gMasterTable[MTI_LISTNODES].pubStruct ;
  197. while(plstRoot[dwFirstNode].dwNextItem != END_OF_LIST)
  198. dwFirstNode = plstRoot[dwFirstNode].dwNextItem ;
  199. return(dwFirstNode);
  200. } // dwFindLastNode(...)
  201. BOOL BappendCommonFontsToPortAndLandscape(
  202. PGLOBL pglobl)
  203. // append dwFontLst to dwPortFontLst and dwLandFontLst
  204. // in the FontCart structure.
  205. {
  206. DWORD dwNumFontCarts , dwI, dwNodeIndex;
  207. PFONTCART pfc ;
  208. PLISTNODE plstRoot ; // start of LIST array
  209. dwNumFontCarts = gMasterTable[MTI_FONTCART].dwArraySize ;
  210. if(!dwNumFontCarts)
  211. return (TRUE); // no fontcart structs to process.
  212. pfc = (PFONTCART)gMasterTable[MTI_FONTCART].pubStruct ;
  213. plstRoot = (PLISTNODE) gMasterTable[MTI_LISTNODES].pubStruct ;
  214. for(dwI = 0 ; dwI < dwNumFontCarts ; dwI++)
  215. {
  216. if(pfc[dwI].dwFontLst == END_OF_LIST)
  217. continue; // nothing to append.
  218. if(pfc[dwI].dwPortFontLst == END_OF_LIST)
  219. pfc[dwI].dwPortFontLst = pfc[dwI].dwFontLst ;
  220. else
  221. {
  222. dwNodeIndex = dwFindLastNode(pfc[dwI].dwPortFontLst, pglobl) ;
  223. plstRoot[dwNodeIndex].dwNextItem = pfc[dwI].dwFontLst ;
  224. }
  225. if(pfc[dwI].dwLandFontLst == END_OF_LIST)
  226. pfc[dwI].dwLandFontLst = pfc[dwI].dwFontLst ;
  227. else
  228. {
  229. dwNodeIndex = dwFindLastNode(pfc[dwI].dwLandFontLst, pglobl) ;
  230. plstRoot[dwNodeIndex].dwNextItem = pfc[dwI].dwFontLst ;
  231. }
  232. } //for dwI
  233. return (TRUE); //
  234. } //BappendCommonFontsToPortAndLandscape()
  235. BOOL BinitSpecialFeatureOptionFields(
  236. PGLOBL pglobl)
  237. // determine num options and Unicode names for feature and
  238. // option keywords.
  239. {
  240. DWORD dwOptionID , dwOptionIndex , dwHeapOffset,
  241. dwFeatureIndex, dwFeatureID, dwLargestString ,
  242. dwAccumulator ; // tracks amount of buffer needed to store
  243. // Feature/Option keyword strings in devmode.
  244. PSYMBOLNODE psn ;
  245. PDFEATURE_OPTIONS pfo ;
  246. ARRAYREF arSymbolName, arUnicodeName;
  247. BOOL bPickMany, // can user select multiple options?
  248. bExists ; // dummy
  249. PBYTE pubFeaDelim = " NewFeature " ,
  250. pubTrue = " TRUE ",
  251. pubFalse = " FALSE ";
  252. // do this just for non-synthesized features.
  253. // write atrFeaKeyWord directly as heap offset.
  254. // write atrOptKeyWord as single level tree
  255. // using BexchangeArbDataInFOATNode().
  256. gmrbd.dwMaxPrnKeywordSize = gmrbd.dwMaxDocKeywordSize = 0 ;
  257. // tell amanda how much room to reserve in devmode or registry
  258. // to store feature/option keywords.
  259. gmrbd.rbd.dwChecksum32 = 0 ; // seed
  260. pfo = (PDFEATURE_OPTIONS) gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct ;
  261. psn = (PSYMBOLNODE) gMasterTable[MTI_SYMBOLTREE].pubStruct ;
  262. dwFeatureIndex = mdwFeatureSymbols ;
  263. while(dwFeatureIndex != INVALID_INDEX)
  264. {
  265. DWORD dwRootOptions ,
  266. dwNonStandardSizeID = FIRST_NON_STANDARD_ID ;
  267. dwFeatureID = psn[dwFeatureIndex].dwSymbolID ;
  268. arSymbolName = psn[dwFeatureIndex].arSymbolName ;
  269. // ----- special checks for Feature describing multiple Resource DLLs.
  270. if(dwFeatureID && (dwFeatureID == gdwResDLL_ID) )
  271. {
  272. // does feature have correct symbolname?
  273. PBYTE pubResName = "RESDLL" ;
  274. DWORD dwLen ;
  275. dwLen = strlen(pubResName);
  276. if((dwLen != arSymbolName.dwCount) ||
  277. strncmp(mpubOffRef + arSymbolName.loOffset,
  278. pubResName, dwLen) )
  279. {
  280. ERR(("References to ResourceDLLs must be placed in the feature with symbolname: %s.\n", pubResName));
  281. return(FALSE);
  282. }
  283. // has atrOptRcNameID been defined?
  284. if(pfo[dwFeatureID].atrOptRcNameID != ATTRIB_UNINITIALIZED)
  285. {
  286. ERR(("ResourceDLL names must be declared explicitly using *Name not *rcNameID.\n"));
  287. return(FALSE);
  288. }
  289. }
  290. // ----- compute BUD checksum
  291. gmrbd.rbd.dwChecksum32 = ComputeCrc32Checksum (
  292. pubFeaDelim,
  293. strlen(pubFeaDelim),
  294. gmrbd.rbd.dwChecksum32 ) ;
  295. // perform checksum on arSymbolName
  296. gmrbd.rbd.dwChecksum32 = ComputeCrc32Checksum(
  297. mpubOffRef + arSymbolName.loOffset,
  298. arSymbolName.dwCount,
  299. gmrbd.rbd.dwChecksum32 ) ;
  300. // extract value for atrFeaInstallable using
  301. if(!BReadDataInGlobalNode(&pfo[dwFeatureID].atrFeaInstallable , &dwHeapOffset, pglobl)
  302. || *(PDWORD)(mpubOffRef + dwHeapOffset) != BT_TRUE)
  303. gmrbd.rbd.dwChecksum32 = // no synthesized feature associated
  304. ComputeCrc32Checksum(
  305. pubFalse,
  306. strlen(pubFalse),
  307. gmrbd.rbd.dwChecksum32 ) ;
  308. else
  309. gmrbd.rbd.dwChecksum32 = // associated with synthesized feature
  310. ComputeCrc32Checksum(
  311. pubTrue,
  312. strlen(pubTrue),
  313. gmrbd.rbd.dwChecksum32 ) ;
  314. // ----- end part I compute BUD checksum
  315. dwRootOptions = psn[dwFeatureIndex].dwSubSpaceIndex ;
  316. pfo[dwFeatureID].dwNumOptions =
  317. psn[dwRootOptions].dwSymbolID + 1 ;
  318. #if 0
  319. Don't convert symbol values to Unicode.
  320. if(!BwriteUnicodeToHeap(&arSymbolName, &arUnicodeName,
  321. iCodepage = 0))
  322. return(FALSE) ;
  323. #endif
  324. if(!BwriteToHeap(&(pfo[dwFeatureID].atrFeaKeyWord),
  325. (PBYTE)&arSymbolName, sizeof(ARRAYREF), 4, pglobl))
  326. return(FALSE);
  327. dwAccumulator = arSymbolName.dwCount + 2 ;
  328. pfo[dwFeatureID].atrFeaKeyWord |= ATTRIB_HEAP_VALUE ;
  329. { // !!! new stuff
  330. DWORD dwHeapOffset ;
  331. dwLargestString = 0 ; // track the largest option string
  332. if(!BReadDataInGlobalNode(&pfo[dwFeatureID].atrUIType , &dwHeapOffset, pglobl)
  333. || *(PDWORD)(mpubOffRef + dwHeapOffset) != UIT_PICKMANY)
  334. bPickMany = FALSE ;
  335. // accumulator += the largest option string;
  336. else
  337. bPickMany = TRUE ;
  338. // accumulator = sum of all option strings;
  339. }
  340. if(!BIdentifyConstantString(&arSymbolName,
  341. &(pfo[dwFeatureID].dwGID), CL_CONS_FEATURES, TRUE, pglobl) )
  342. {
  343. pfo[dwFeatureID].dwGID = GID_UNKNOWN ;
  344. }
  345. if((pfo[dwFeatureID].dwGID == GID_MEMOPTION) ||
  346. (pfo[dwFeatureID].dwGID == GID_PAGEPROTECTION))
  347. {
  348. DWORD dwHeapOffset, dwValue ;
  349. PATREEREF patr ;
  350. // set only if not explictly initialized in GPD file.
  351. if(!BReadDataInGlobalNode(&pfo[dwFeatureID].atrFeatureType , &dwHeapOffset, pglobl) )
  352. {
  353. // label this FeatureType as PrinterSticky
  354. dwValue = FT_PRINTERPROPERTY ;
  355. patr = &pfo[dwFeatureID].atrFeatureType ;
  356. if(!BwriteToHeap(patr, (PBYTE)&dwValue ,
  357. sizeof(DWORD), 4, pglobl) )
  358. {
  359. return(FALSE) ; // heap overflow start over.
  360. }
  361. *patr |= ATTRIB_HEAP_VALUE ;
  362. }
  363. }
  364. dwOptionIndex = dwRootOptions ;
  365. while(dwOptionIndex != INVALID_INDEX)
  366. {
  367. DWORD dwDevmodeID, dwConsClass, dwInstallable ;
  368. BOOL bCustomOptOK ;
  369. dwOptionID = psn[dwOptionIndex].dwSymbolID ;
  370. arSymbolName = psn[dwOptionIndex].arSymbolName ;
  371. // ----- part II compute BUD checksum
  372. // perform checksum on arSymbolName
  373. gmrbd.rbd.dwChecksum32 =
  374. ComputeCrc32Checksum(
  375. mpubOffRef + arSymbolName.loOffset,
  376. arSymbolName.dwCount,
  377. gmrbd.rbd.dwChecksum32 ) ;
  378. // extract value for atrOptInstallable using
  379. if( BexchangeArbDataInFOATNode(dwFeatureID, dwOptionID,
  380. offsetof(DFEATURE_OPTIONS, atrOptInstallable) ,
  381. sizeof(DWORD),
  382. (PBYTE)&dwInstallable, NULL, &bExists, FALSE , pglobl) &&
  383. bExists && dwInstallable == BT_TRUE)
  384. gmrbd.rbd.dwChecksum32 = // associated with synthesized feature
  385. ComputeCrc32Checksum(
  386. pubTrue,
  387. strlen(pubTrue),
  388. gmrbd.rbd.dwChecksum32 ) ;
  389. else
  390. gmrbd.rbd.dwChecksum32 = // no synthesized feature associated
  391. ComputeCrc32Checksum(
  392. pubFalse,
  393. strlen(pubFalse),
  394. gmrbd.rbd.dwChecksum32 ) ;
  395. // ----- end part II compute BUD checksum
  396. #if 0
  397. if(!BwriteUnicodeToHeap(&arSymbolName, &arUnicodeName,
  398. iCodepage = 0))
  399. return(FALSE) ;
  400. // if this is ever used, must use &arUnicodeName
  401. // as the 2nd argument to BwriteToHeap.
  402. #endif
  403. if(! BexchangeArbDataInFOATNode(
  404. dwFeatureID, dwOptionID,
  405. offsetof(DFEATURE_OPTIONS, atrOptKeyWord),
  406. sizeof(ARRAYREF),
  407. NULL, (PBYTE)&arSymbolName, &bExists, FALSE , pglobl))
  408. return(FALSE); // this is a fatal error.
  409. if(bPickMany)
  410. dwAccumulator += arSymbolName.dwCount + 1 ;
  411. else
  412. {
  413. // track largest option string
  414. if(dwLargestString < arSymbolName.dwCount + 1 )
  415. dwLargestString = arSymbolName.dwCount + 1 ;
  416. }
  417. switch(pfo[dwFeatureID].dwGID)
  418. {
  419. case GID_PAGESIZE:
  420. dwConsClass = CL_CONS_PAPERSIZE ;
  421. bCustomOptOK = TRUE ;
  422. break ;
  423. case GID_MEDIATYPE:
  424. dwConsClass = CL_CONS_MEDIATYPE ;
  425. bCustomOptOK = TRUE ;
  426. break ;
  427. case GID_INPUTSLOT:
  428. dwConsClass = CL_CONS_INPUTSLOT ;
  429. bCustomOptOK = TRUE ;
  430. break ;
  431. case GID_HALFTONING:
  432. dwConsClass = CL_CONS_HALFTONE ;
  433. bCustomOptOK = TRUE ;
  434. break ;
  435. case GID_DUPLEX:
  436. dwConsClass = CL_CONS_DUPLEX ;
  437. bCustomOptOK = FALSE ;
  438. break ;
  439. case GID_ORIENTATION:
  440. dwConsClass = CL_CONS_ORIENTATION ;
  441. bCustomOptOK = FALSE ;
  442. break ;
  443. case GID_PAGEPROTECTION:
  444. dwConsClass = CL_CONS_PAGEPROTECT ;
  445. bCustomOptOK = FALSE ;
  446. break ;
  447. case GID_COLLATE:
  448. dwConsClass = CL_CONS_COLLATE ;
  449. bCustomOptOK = FALSE ;
  450. break ;
  451. default:
  452. dwConsClass = CL_NUMCLASSES ;
  453. bCustomOptOK = TRUE ; // Irrelavent.
  454. break ;
  455. } //switch
  456. if(dwConsClass != CL_NUMCLASSES)
  457. {
  458. if(BIdentifyConstantString(&arSymbolName,
  459. &dwDevmodeID, dwConsClass, bCustomOptOK, pglobl) )
  460. {
  461. if(! BexchangeArbDataInFOATNode(
  462. dwFeatureID, dwOptionID,
  463. offsetof(DFEATURE_OPTIONS, atrOptIDvalue),
  464. sizeof(DWORD),
  465. NULL, (PBYTE)&dwDevmodeID, &bExists, FALSE , pglobl))
  466. return(FALSE); // this is a fatal error.
  467. if(dwConsClass == CL_CONS_PAPERSIZE &&
  468. dwDevmodeID < DMPAPER_USER)
  469. {
  470. // fill in the page dimensions.
  471. POINT ptDim ;
  472. DWORD dwI ;
  473. PGLOBALATTRIB pga ;
  474. BOOL bTRUE = TRUE ;
  475. PBYTE pub ;
  476. if(dwDevmodeID == DMPAPER_LETTER)
  477. {
  478. // pointer to dword containing heapoffset
  479. PATREEREF patrAttribRoot ;
  480. pub = gMasterTable[MTI_GLOBALATTRIB].pubStruct ;
  481. patrAttribRoot = &(((PGLOBALATTRIB)pub)->atrLetterSizeExists) ;
  482. BwriteToHeap((PDWORD) patrAttribRoot, (PBYTE)&bTRUE, 4 , 4 , pglobl);
  483. *patrAttribRoot |= ATTRIB_HEAP_VALUE ;
  484. }
  485. else if(dwDevmodeID == DMPAPER_A4)
  486. {
  487. PATREEREF patrAttribRoot ; // pointer to dword containing heapoffset
  488. pub = gMasterTable[MTI_GLOBALATTRIB].pubStruct ;
  489. patrAttribRoot = &(((PGLOBALATTRIB)pub)->atrA4SizeExists) ;
  490. BwriteToHeap((PDWORD) patrAttribRoot, (PBYTE)&bTRUE, 4 , 4 , pglobl);
  491. *patrAttribRoot |= ATTRIB_HEAP_VALUE ;
  492. }
  493. for(dwI = 0 ; aPaperDimensions[dwI].x ; dwI++)
  494. {
  495. if(aPaperDimensions[dwI].paperID == dwDevmodeID)
  496. break ;
  497. }
  498. // worst case causes (0,0) to be assigned.
  499. ptDim.x = aPaperDimensions[dwI].x ;
  500. ptDim.y = aPaperDimensions[dwI].y ;
  501. // convert from microns to master units
  502. ptDim.x /= 100 ; // microns to tenths of mm
  503. ptDim.y /= 100 ;
  504. pga = (PGLOBALATTRIB)gMasterTable[
  505. MTI_GLOBALATTRIB].pubStruct ;
  506. if(!BReadDataInGlobalNode(&pga->atrMasterUnits,
  507. &dwHeapOffset, pglobl) )
  508. return(FALSE);
  509. ptDim.x *= ((PPOINT)(mpubOffRef + dwHeapOffset))->x ;
  510. ptDim.y *= ((PPOINT)(mpubOffRef + dwHeapOffset))->y ;
  511. ptDim.x /= 254 ;
  512. ptDim.y /= 254 ;
  513. if(! BexchangeArbDataInFOATNode(
  514. dwFeatureID, dwOptionID,
  515. offsetof(DFEATURE_OPTIONS, atrPageDimensions),
  516. sizeof(POINT),
  517. NULL, (PBYTE)&ptDim, &bExists, FALSE , pglobl))
  518. return(FALSE); // this is a fatal error.
  519. }
  520. }
  521. else if(bCustomOptOK)
  522. // feature permits GPD defined options
  523. {
  524. DWORD dwID , // pattern size ID used by GDI
  525. dwOldID, // user specified ID value if any.
  526. dwRcPatID;
  527. POINT ptSize ;
  528. // Option Symbolvalue not found in tables.
  529. // assume its a user-defined value.
  530. #ifndef WINNT_40
  531. if((pfo[dwFeatureID].dwGID == GID_HALFTONING) &&
  532. BexchangeArbDataInFOATNode(
  533. dwFeatureID, dwOptionID,
  534. offsetof(DFEATURE_OPTIONS, atrRcHTPatternID),
  535. sizeof(DWORD),
  536. (PBYTE)&dwRcPatID, NULL, &bExists, FALSE , pglobl) &&
  537. bExists && dwRcPatID &&
  538. BexchangeArbDataInFOATNode(
  539. dwFeatureID, dwOptionID,
  540. offsetof(DFEATURE_OPTIONS, atrHTPatternSize),
  541. sizeof(POINT),
  542. (PBYTE)&ptSize, NULL, &bExists, FALSE, pglobl ) &&
  543. bExists &&
  544. (ptSize.x >= HT_USERPAT_CX_MIN) &&
  545. (ptSize.x <= HT_USERPAT_CX_MAX) &&
  546. (ptSize.y >= HT_USERPAT_CY_MIN) &&
  547. (ptSize.y <= HT_USERPAT_CY_MAX)
  548. )
  549. {
  550. dwID = HT_PATSIZE_USER ;
  551. // GID halftone code is to use
  552. // the user defined halftone matrix.
  553. }
  554. else
  555. #endif
  556. {
  557. dwID = dwNonStandardSizeID ;
  558. dwNonStandardSizeID++ ;
  559. // OEM will supply a halftone function.
  560. }
  561. if(! BexchangeArbDataInFOATNode(
  562. dwFeatureID, dwOptionID,
  563. offsetof(DFEATURE_OPTIONS, atrOptIDvalue),
  564. sizeof(DWORD),
  565. (PBYTE)&dwOldID, (PBYTE)NULL, &bExists, FALSE , pglobl ))
  566. return(FALSE); // this is a fatal error.
  567. if(!bExists && ! BexchangeArbDataInFOATNode(
  568. dwFeatureID, dwOptionID,
  569. offsetof(DFEATURE_OPTIONS, atrOptIDvalue),
  570. sizeof(DWORD),
  571. NULL, (PBYTE)&dwID, &bExists, FALSE , pglobl))
  572. return(FALSE); // this is a fatal error.
  573. }
  574. } // if(dwConsClass != CL_NUMCLASSES)
  575. // otherwise leave optionID uninitialized.
  576. dwOptionIndex = psn[dwOptionIndex].dwNextSymbol ;
  577. } //while
  578. { // !!! new stuff
  579. DWORD dwHeapOffset ;
  580. dwAccumulator += dwLargestString ; // is zero if not needed.
  581. if(!BReadDataInGlobalNode(&pfo[dwFeatureID].atrFeatureType , &dwHeapOffset, pglobl)
  582. || *(PDWORD)(mpubOffRef + dwHeapOffset) != FT_PRINTERPROPERTY)
  583. gmrbd.dwMaxDocKeywordSize += dwAccumulator;
  584. else
  585. gmrbd.dwMaxPrnKeywordSize += dwAccumulator;
  586. }
  587. dwFeatureIndex = psn[dwFeatureIndex].dwNextSymbol ;
  588. }
  589. return(TRUE) ;
  590. } // BinitSpecialFeatureOptionFields()
  591. BOOL BIdentifyConstantString(
  592. IN PARRAYREF parString,
  593. OUT PDWORD pdwDest, // write dword value here.
  594. IN DWORD dwClassIndex, // which class of constant is this?
  595. BOOL bCustomOptOK,
  596. IN PGLOBL pglobl
  597. )
  598. {
  599. DWORD dwI, dwCount, dwStart , dwLen;
  600. dwStart = gcieTable[dwClassIndex].dwStart ;
  601. dwCount = gcieTable[dwClassIndex].dwCount ;
  602. for(dwI = 0 ; dwI < dwCount ; dwI++)
  603. {
  604. dwLen = strlen(gConstantsTable[dwStart + dwI].pubName);
  605. if((dwLen == parString->dwCount) &&
  606. !strncmp(mpubOffRef + parString->loOffset,
  607. gConstantsTable[dwStart + dwI].pubName,
  608. dwLen) )
  609. {
  610. *pdwDest = gConstantsTable[dwStart + dwI].dwValue ;
  611. return(TRUE);
  612. }
  613. }
  614. if(bCustomOptOK)
  615. {
  616. if(gdwVerbosity >= 4)
  617. {
  618. #if defined(DEVSTUDIO) // This needs to be a one-liner
  619. ERR(("Note: '%0.*s' is not a predefined member of enumeration class %s\n",
  620. parString->dwCount , mpubOffRef + parString->loOffset,
  621. gConstantsTable[dwStart - 1]));
  622. #else
  623. ERR(("Note: Feature/Option name not a predefined member of enumeration class %s\n",
  624. gConstantsTable[dwStart - 1]));
  625. ERR(("\t%0.*s\n", parString->dwCount , mpubOffRef + parString->loOffset )) ;
  626. #endif
  627. }
  628. }
  629. else
  630. {
  631. #if defined(DEVSTUDIO) // Same with this one...
  632. ERR(("Error: '%0.*s'- user defined Option names not permitted for enumeration class %s\n",
  633. parString->dwCount , mpubOffRef + parString->loOffset, gConstantsTable[dwStart - 1]));
  634. #else
  635. ERR(("Error: user defined Option names not permitted for enumeration class %s\n",
  636. gConstantsTable[dwStart - 1]));
  637. ERR(("\t%0.*s\n", parString->dwCount , mpubOffRef + parString->loOffset )) ;
  638. #endif
  639. }
  640. return(FALSE);
  641. }
  642. BOOL BReadDataInGlobalNode(
  643. PATREEREF patr, // address of field in GlobalAttrib struct
  644. PDWORD pdwHeapOffset, // contents of attribute node.
  645. PGLOBL pglobl
  646. )
  647. /*
  648. this function will grab the first heap offset value it
  649. encounters from the specified attribute tree root.
  650. If the tree is multivalued, it selects the first
  651. option of each level.
  652. The high bit (if set) is cleared before the value is returned.
  653. If root is uninitialized, returns FALSE, not an error condition
  654. since GPD file is not required to initialize all fields.
  655. */
  656. {
  657. PATTRIB_TREE patt ; // start of ATTRIBUTE tree array.
  658. DWORD dwNodeIndex ;
  659. patt = (PATTRIB_TREE) gMasterTable[MTI_ATTRIBTREE].pubStruct ;
  660. if(*patr == ATTRIB_UNINITIALIZED)
  661. return(FALSE);
  662. if(*patr & ATTRIB_HEAP_VALUE)
  663. {
  664. *pdwHeapOffset = *patr & ~ATTRIB_HEAP_VALUE ;
  665. return(TRUE) ;
  666. }
  667. dwNodeIndex = *patr ;
  668. if(patt[dwNodeIndex].dwFeature == DEFAULT_INIT)
  669. {
  670. *pdwHeapOffset = patt[dwNodeIndex].dwOffset ;
  671. return(TRUE) ;
  672. }
  673. while(patt[dwNodeIndex].eOffsetMeans == NEXT_FEATURE)
  674. {
  675. // Down to the next level we go.
  676. dwNodeIndex = patt[dwNodeIndex].dwOffset ;
  677. }
  678. if(patt[dwNodeIndex].eOffsetMeans == VALUE_AT_HEAP)
  679. {
  680. *pdwHeapOffset = patt[dwNodeIndex].dwOffset ;
  681. return(TRUE) ;
  682. }
  683. else
  684. return(FALSE) ;
  685. } // BReadDataInGlobalNode(...)
  686. // Following three functions
  687. // Added on 9/30/98 in response to bug report 225088
  688. // BsetUQMFlag() goes through the attrib trees rooted at
  689. // atrDraftQualitySettings, atrBetterQualitySettings, atrBestQualitySettings,
  690. // & atrDefaultQuality and checks for a feature dependency. If found,
  691. // it updates the UpdateQualityMacro flag for that feature to TRUE.
  692. BOOL BsetUQMFlag(
  693. PGLOBL pglobl)
  694. {
  695. DWORD i; // Loop Counter.
  696. PATTRIB_TREE patt;
  697. ATREEREF atrAttribRoot;
  698. BOOL bStatus = TRUE;
  699. PGLOBALATTRIB pga =
  700. (PGLOBALATTRIB)gMasterTable[MTI_GLOBALATTRIB].pubStruct ;
  701. // List of features whose UQM flag needs to be updated.
  702. ATREEREF patr[] = { pga->atrDraftQualitySettings,
  703. pga->atrBetterQualitySettings,
  704. pga->atrBestQualitySettings,
  705. pga->atrDefaultQuality,
  706. };
  707. DWORD dwNumAttrib = sizeof(patr)/sizeof(ATREEREF);
  708. patt = (PATTRIB_TREE) gMasterTable[MTI_ATTRIBTREE].pubStruct ;
  709. // for the four quality settings
  710. for ( i = 0; bStatus && (i < dwNumAttrib); i++)
  711. {
  712. atrAttribRoot = patr[i] ;
  713. // It may be possible that only some of the four settings
  714. // may occur. In that case, atrAttribRoot == ATTRIB_UNINITIALIZED
  715. // only for those that dont occur.
  716. if(atrAttribRoot == ATTRIB_UNINITIALIZED)
  717. {
  718. // Occurs probably because patr[i] e.g. DraftQualityMacro keyword
  719. // appears no where in the .gpd. Continue and check whether other
  720. // patr[i] occur.
  721. continue;
  722. }
  723. else if (atrAttribRoot & ATTRIB_HEAP_VALUE)
  724. {
  725. // Indicates there is no dependency
  726. // of any feature. So we can safely
  727. // ignore and continue with the
  728. // next attribute.
  729. continue;
  730. }
  731. // If the above two are not true, it means atrAttribRoot points
  732. // to a valid node (in the attrib tree).
  733. // In the tree, at most
  734. // the first node can be the global default initializer:
  735. // (as stated (in treewalk.c line 351) and interpreted (from
  736. // state2.c function - BaddBranchToTree (...) ) )
  737. // Therefore it is safe check for this condition only once,
  738. // just before we start
  739. // recursing down the tree. No need to check once within the tree.
  740. // In a global default initializer!
  741. // it may be assumed dwOffset contains heap offset.
  742. // But we are concerned not with the heap value, but
  743. // the next Node.
  744. if(patt[atrAttribRoot].dwFeature == DEFAULT_INIT)
  745. {
  746. if ( patt[atrAttribRoot].dwNext == END_OF_LIST)
  747. continue;
  748. atrAttribRoot = patt[atrAttribRoot].dwNext ; // to the next node.
  749. } //if
  750. // Walk thru the tree and retrieve the features that are children
  751. // of the tree rooted at atrAttribRoot.
  752. bStatus = BRecurseNodes(atrAttribRoot, pglobl);
  753. } //for
  754. return bStatus;
  755. } //BsetUQMFlag
  756. // Recurse down the attribute tree. When we reach a feature we
  757. // set its UQM flag to true by calling the function BsetUQMTrue(..)
  758. // It is reasonable to assume that the dwFeature attribute in the
  759. // structure pointed to by atrAttribNode contains a valid feature ID.
  760. // The other special cases are handled in the previous function -
  761. // BsetUQMFlag()
  762. BOOL BRecurseNodes(
  763. IN ATREEREF atrAttribNode,
  764. IN OUT PGLOBL pglobl
  765. )
  766. {
  767. PATTRIB_TREE patt;
  768. BOOL bStatus = TRUE;
  769. PDFEATURE_OPTIONS pfo =
  770. (PDFEATURE_OPTIONS) (gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct);
  771. patt = (PATTRIB_TREE) gMasterTable[MTI_ATTRIBTREE].pubStruct ;
  772. // Is it safe to assume that a new feature is encountered only
  773. // when we go one level down the tree.
  774. // Yes. Because the nodes at the same level have the SAME feature
  775. // but DIFFERENT options.
  776. // Hack. Since ColorMode is handled in a special way in the UI, the
  777. // Quality Macro should not be executed for Color Mode.
  778. if ((*(pfo + patt[atrAttribNode].dwFeature)).dwGID != GID_COLORMODE)
  779. {
  780. bStatus = BsetUQMTrue(patt[atrAttribNode].dwFeature, pglobl);
  781. }
  782. // Even though the trees of some gpd's (e.g. cnb5500.gpd) appear very
  783. // uniform (i.e. most of the branches look similar), we cannot assume it
  784. // to be true for all .gpd Therefore we have to go through
  785. // all the branches of the tree.
  786. for(; bStatus && atrAttribNode != END_OF_LIST;
  787. atrAttribNode = patt[atrAttribNode].dwNext)
  788. {
  789. // This is what we are really interested in.
  790. // Check if the node has a sublevel. Yes means another feature.
  791. if( patt[atrAttribNode].eOffsetMeans == NEXT_FEATURE)
  792. {
  793. bStatus = BRecurseNodes(patt[atrAttribNode].dwOffset, pglobl);
  794. }
  795. } // for
  796. return bStatus;
  797. } // End of function BRecurseNodes(...)
  798. BOOL BsetUQMTrue(
  799. IN DWORD dwFeature,
  800. IN OUT PGLOBL pglobl)
  801. // For the feature dwFeature
  802. // Set the UpdateQualityMacro Flag to true;
  803. {
  804. BOOL bStatus = TRUE;
  805. DWORD dwTrue = BT_TRUE;
  806. PDFEATURE_OPTIONS pfo =
  807. (PDFEATURE_OPTIONS) (gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct);
  808. PATREEREF patrAttribRoot = &((*(pfo + dwFeature)).atrUpdateQualityMacro);
  809. // The tree rooted at atrAttribRoot can either be uninitilized or
  810. // have a pointer to a heap value.
  811. // Any other case is a violation of the semantics.
  812. if(*patrAttribRoot == ATTRIB_UNINITIALIZED)
  813. {
  814. // Put BT_TRUE in the heap and make *patrAttribRoot point to it.
  815. // i.e. have *patrAttribRoot hold a dword that is an offset into
  816. // the heap. It is then ORed with ATTRIB_HEAP_VALUE(which has
  817. // MSB set to 1). The MSB indicates that the DWORD is a
  818. // Heap Offset and not a ATTRIB_UNINITIALIZED, node index or any
  819. // other value.
  820. if((bStatus = BwriteToHeap((PDWORD)patrAttribRoot, (PBYTE)&dwTrue,
  821. gValueToSize[VALUE_CONSTANT_BOOLEANTYPE], 4, pglobl) ) )
  822. {
  823. *patrAttribRoot |= ATTRIB_HEAP_VALUE ;
  824. }
  825. else {
  826. *patrAttribRoot = ATTRIB_UNINITIALIZED ;
  827. // The global Error variables have been set in BwriteToHeap().
  828. }
  829. return bStatus;
  830. } //if(*patrAttribRoot == ATTRIB_UNINITIALIZED)
  831. /*
  832. Now comes the case when the user has specified the value of
  833. UpdateQualityMacro to be TRUE or FALSE. If the value is TRUE
  834. we still overwrite it with TRUE. If FALSE, we update it according
  835. to the dependencies in the .gpd file.
  836. Since we have reached here in the program, the dependencies
  837. indicate that the UQM needs to be set to TRUE.
  838. */
  839. else if (*patrAttribRoot & ATTRIB_HEAP_VALUE)
  840. {
  841. // The value should be a DWORD because UpdateQualityMacro's
  842. // mMainKeywordTable[dwI].flAgs = 0 ; (file framwrk1.c line 1566)
  843. // Therefore not checking for a list.
  844. PDWORD pdwValue = (PDWORD) ( (PBYTE) mpubOffRef +
  845. (*patrAttribRoot & ~ATTRIB_HEAP_VALUE) );
  846. //Change to TRUE irrespective of its previous value.
  847. *pdwValue = BT_TRUE; //Value in the heap changed to TRUE
  848. }
  849. // Since UpdateQualityMacro's
  850. // mMainKeywordTable[dwI].dwSubType = ATT_LOCAL_FEATURE_ONLY
  851. // (file framwrk1.c line 1574)
  852. // (i.e. it is not a free-float type), it cannot have a
  853. // sub-tree. So it should not point to another node.
  854. //
  855. // The following condition should never be true because UQM cannot
  856. // have a DEFAULT_INIT
  857. // if(patt[*patrAttribRoot].dwFeature == DEFAULT_INIT)
  858. // Reason : It cannot form a tree (reason as explained above).
  859. //
  860. //Thus control should never reach here.
  861. else {
  862. PATTRIB_TREE patt =
  863. (PATTRIB_TREE) gMasterTable[MTI_ATTRIBTREE].pubStruct ;
  864. if(patt[*patrAttribRoot].dwFeature == DEFAULT_INIT) {
  865. ERR(("Warning: unexpected value atrUpdateQualityMacro ATREEREF\n"));
  866. }
  867. else {
  868. ERR(("Warning: atrUpdateQualityMacro ATREEREF points to a tree. \
  869. Unexpected Condition\n"));
  870. }
  871. ERR(("Unexpected condition encountered while processing Quality Macros\n "));
  872. geErrorType = ERRTY_SYNTAX ;
  873. geErrorSev = ERRSEV_FATAL ;
  874. bStatus = FALSE;
  875. }
  876. return bStatus;
  877. } //BsetUQMTrue(...)
  878. // End of 3 functions added on 9/30/98 in response to
  879. // bug report no. 225088
  880. VOID VCountPrinterDocStickyFeatures(
  881. PGLOBL pglobl)
  882. {
  883. PDFEATURE_OPTIONS pfo ;
  884. DWORD dwHeapOffset, dwCount, dwI ;
  885. // extern MINIRAWBINARYDATA gmrbd ;
  886. // Not required now as it is part of the PGLOBL structure.
  887. pfo = (PDFEATURE_OPTIONS) gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct ;
  888. dwCount = gMasterTable[MTI_DFEATURE_OPTIONS].dwArraySize ;
  889. gmrbd.rbd.dwDocumentFeatures = 0 ;
  890. gmrbd.rbd.dwPrinterFeatures =
  891. gMasterTable[MTI_SYNTHESIZED_FEATURES].dwArraySize ;
  892. for(dwI = 0 ; dwI < dwCount ; dwI++)
  893. {
  894. if(BReadDataInGlobalNode(&pfo[dwI].atrFeatureType,
  895. &dwHeapOffset, pglobl) &&
  896. *(PDWORD)(mpubOffRef + dwHeapOffset) == FT_PRINTERPROPERTY)
  897. gmrbd.rbd.dwPrinterFeatures++ ;
  898. else
  899. gmrbd.rbd.dwDocumentFeatures++ ;
  900. }
  901. } // VCountPrinterDocStickyFeatures()
  902. BOOL BConvertSpecVersionToDWORD(
  903. PWSTR pwstrFileName,
  904. PGLOBL pglobl
  905. )
  906. // also used to prepend absolute path to resource Dll name.
  907. {
  908. BOOL bStatus ;
  909. DWORD dwMajor, dwMinor, dwHeapOffset, dwDelim, dwDummy, dwByteCount;
  910. // WCHAR awchDLLQualifiedName[MAX_PATH];
  911. PWSTR pwstrLastBackSlash, pwstrDLLName,
  912. pwstrDataFileName = NULL;
  913. ABSARRAYREF aarValue, aarToken ;
  914. PGLOBALATTRIB pga ;
  915. DWORD pathlen = 0 ;
  916. DWORD namelen = 0 ;
  917. WCHAR * pwDLLQualifiedName = NULL ;
  918. // extern MINIRAWBINARYDATA gmrbd ;
  919. // Not required now as it is part of the PGLOBL structure.
  920. pga = (PGLOBALATTRIB)gMasterTable[MTI_GLOBALATTRIB].pubStruct ;
  921. if(!BReadDataInGlobalNode(&pga->atrGPDSpecVersion ,
  922. &dwHeapOffset, pglobl) )
  923. {
  924. ERR(("Missing required keyword: *GPDSpecVersion.\n"));
  925. return(FALSE);
  926. }
  927. aarValue.dw = ((PARRAYREF)(mpubOffRef + dwHeapOffset))->dwCount ;
  928. aarValue.pub = mpubOffRef +
  929. ((PARRAYREF)(mpubOffRef + dwHeapOffset))->loOffset ;
  930. bStatus = BdelimitToken(&aarValue, ".", &aarToken, &dwDelim) ;
  931. if(bStatus)
  932. bStatus = BparseInteger(&aarToken, &dwMajor, VALUE_INTEGER, pglobl) ;
  933. if(bStatus)
  934. bStatus = BparseInteger(&aarValue, &dwMinor, VALUE_INTEGER, pglobl) ;
  935. if(bStatus)
  936. {
  937. gmrbd.dwSpecVersion = dwMajor << 16; // place in HiWord
  938. gmrbd.dwSpecVersion |= dwMinor & 0xffff; // place in LoWord
  939. }
  940. else
  941. {
  942. ERR(("BConvertSpecVersionToDWORD: syntax error in *GPDSpecVersion value. unknown version.\n"));
  943. }
  944. // -------- now to fix up the helpfile name. ------ //
  945. if(!BReadDataInGlobalNode(&pga->atrHelpFile ,
  946. &dwHeapOffset, pglobl) )
  947. {
  948. goto FIX_RESDLLNAME; // GPD doesn't have this keyword
  949. }
  950. pwstrDLLName = (PWSTR)(mpubOffRef +
  951. ((PARRAYREF)(mpubOffRef + dwHeapOffset))->loOffset) ;
  952. // how large should pwDLLQualifiedName be???
  953. pathlen = wcslen(pwstrFileName) ;
  954. namelen = pathlen + wcslen(pwstrDLLName) + 1;
  955. if(!(pwDLLQualifiedName = (PWSTR)MemAllocZ(namelen * sizeof(WCHAR)) ))
  956. {
  957. ERR(("Fatal: unable to alloc memory for pwDLLQualifiedName: %d WCHARs.\n",
  958. namelen));
  959. geErrorType = ERRTY_MEMORY_ALLOCATION ;
  960. geErrorSev = ERRSEV_FATAL ;
  961. return(FALSE) ; // This is unrecoverable
  962. }
  963. wcsncpy(pwDLLQualifiedName, pwstrFileName , namelen);
  964. if (pwstrLastBackSlash = wcsrchr(pwDLLQualifiedName,TEXT('\\')))
  965. {
  966. *(pwstrLastBackSlash + 1) = NUL;
  967. //Find a BackSlash in the Source DLL Name.
  968. pwstrDataFileName = wcsrchr( pwstrDLLName, TEXT('\\') );
  969. //Increment the pointer to first char of the DLL Name.
  970. if (pwstrDataFileName)
  971. pwstrDataFileName++;
  972. else
  973. pwstrDataFileName = pwstrDLLName;
  974. // wcscat(pwDLLQualifiedName, pwstrDataFileName) ;
  975. StringCchCatW(pwDLLQualifiedName, namelen, pwstrDataFileName);
  976. ((PARRAYREF)(mpubOffRef + dwHeapOffset))->dwCount =
  977. dwByteCount =
  978. wcslen(pwDLLQualifiedName) * sizeof(WCHAR) ;
  979. if(BwriteToHeap(&((PARRAYREF)(mpubOffRef + dwHeapOffset))->loOffset,
  980. // Store heap offset of dest string here.
  981. (PBYTE) pwDLLQualifiedName, dwByteCount, 2, pglobl) )
  982. {
  983. // add NUL terminator.
  984. BwriteToHeap(&dwDummy, "\0\0", 2, 1, pglobl) ;
  985. goto FIX_RESDLLNAME;
  986. }
  987. bStatus = FALSE ;
  988. }
  989. // -------- now to fix up the resource Dll name. ------ //
  990. FIX_RESDLLNAME:
  991. if(pwDLLQualifiedName)
  992. MemFree(pwDLLQualifiedName) ;
  993. #if 0 // fix for bug 34042
  994. if(!BReadDataInGlobalNode(&pga->atrResourceDLL ,
  995. &dwHeapOffset, pglobl) )
  996. {
  997. // return(bStatus); // GPD doesn't have this keyword
  998. // create a dummy filename!
  999. PATREEREF patr ;
  1000. ARRAYREF arDummyName ;
  1001. arDummyName.dwCount = wcslen(TEXT("No_Res")) * sizeof(WCHAR) ;
  1002. if(!BwriteToHeap(&arDummyName.loOffset,
  1003. (PBYTE)TEXT("No_Res\0"), arDummyName.dwCount + sizeof(WCHAR), 2, pglobl) )
  1004. // note: add null terminator or strcat will derail.
  1005. {
  1006. bStatus = FALSE ; // heap overflow start over.
  1007. }
  1008. patr = &pga->atrResourceDLL ;
  1009. if(!BwriteToHeap(patr, (PBYTE)(&arDummyName) , sizeof(ARRAYREF), 4, pglobl) )
  1010. {
  1011. bStatus = FALSE ; // heap overflow start over.
  1012. }
  1013. dwHeapOffset = *patr ;
  1014. *patr |= ATTRIB_HEAP_VALUE ;
  1015. }
  1016. // #if 0 move this to new location 25 lines up. fix for bug 34042
  1017. // ganesh's winres lib will take care of prepending fully qualified path...
  1018. pwstrDLLName = (PWSTR)(mpubOffRef +
  1019. ((PARRAYREF)(mpubOffRef + dwHeapOffset))->loOffset) ;
  1020. wcsncpy(awchDLLQualifiedName, pwstrFileName , MAX_PATH -1);
  1021. if (pwstrLastBackSlash = wcsrchr(awchDLLQualifiedName,TEXT('\\')))
  1022. {
  1023. *(pwstrLastBackSlash + 1) = NUL;
  1024. //Find a BackSlash in the Source DLL Name.
  1025. pwstrDataFileName = wcsrchr( pwstrDLLName, TEXT('\\') );
  1026. //Increment the pointer to first char of the DLL Name.
  1027. if (pwstrDataFileName)
  1028. pwstrDataFileName++;
  1029. else
  1030. pwstrDataFileName = pwstrDLLName;
  1031. wcscat(awchDLLQualifiedName, pwstrDataFileName) ;
  1032. ((PARRAYREF)(mpubOffRef + dwHeapOffset))->dwCount =
  1033. dwByteCount =
  1034. wcslen(awchDLLQualifiedName) * sizeof(WCHAR) ;
  1035. if(BwriteToHeap(&((PARRAYREF)(mpubOffRef + dwHeapOffset))->loOffset,
  1036. // Store heap offset of dest string here.
  1037. (PBYTE) awchDLLQualifiedName, dwByteCount, 2, pglobl) )
  1038. {
  1039. // add NUL terminator.
  1040. BwriteToHeap(&dwDummy, "\0\0", 2, 1, pglobl) ;
  1041. return(bStatus) ;
  1042. }
  1043. return(FALSE) ;
  1044. }
  1045. #endif
  1046. return(bStatus) ;
  1047. } // BConvertSpecVersionToDWORD(...)
  1048. BOOL BinitMiniRawBinaryData(
  1049. PGLOBL pglobl)
  1050. {
  1051. gmrbd.rbd.dwParserSignature = GPD_PARSER_SIGNATURE ;
  1052. gmrbd.rbd.dwParserVersion = GPD_PARSER_VERSION ;
  1053. gmrbd.rbd.pvReserved = NULL;
  1054. return(TRUE) ;
  1055. } //BinitMiniRawBinaryData()
  1056. BOOL BexchangeArbDataInFOATNode(
  1057. DWORD dwFeature,
  1058. DWORD dwOption,
  1059. DWORD dwFieldOff, // offset of field in FeatureOption struct
  1060. DWORD dwCount, // number bytes to copy.
  1061. OUT PBYTE pubOut, // previous contents of attribute node
  1062. IN PBYTE pubIn, // new contents of attribute node.
  1063. PBOOL pbPrevsExists, // previous contents existed.
  1064. BOOL bSynthetic, // access synthetic features
  1065. PGLOBL pglobl
  1066. )
  1067. /*
  1068. 'FOAT' means FeatureOption AttributeTree.
  1069. this function writes or overwrites the byte string specified by
  1070. pubIn into the heap at the location indicated by the attribute tree
  1071. HeapOffset field. The previous contents at HeapOffset is saved to
  1072. pubOut and pbPrevsExists is set to TRUE. If pubIn is NULL,
  1073. the current attribute tree is not altered.
  1074. The parameters dwFeature, dwOption, dwFieldOffset specify
  1075. the structure, field, and branch of the attribute tree.
  1076. If the specified option branch does not exist, one will be created,
  1077. pubOut may be set to NULL if the previous content is unimportant.
  1078. Assumptions:
  1079. The tree being accessed is strictly one level deep. That is the
  1080. node is fully specified by just Feature, Option. No default initializers.
  1081. */
  1082. {
  1083. PATTRIB_TREE patt ; // start of ATTRIBUTE tree array.
  1084. PATREEREF patr ;
  1085. ATREEREF atrCur ; // contains index of currently used attribute node.
  1086. DWORD dwFeaOffset ; // Start numbering features from this
  1087. // starting point. This gives synthetic
  1088. // features a separate non-overlapping number
  1089. // space from normal features.
  1090. PDFEATURE_OPTIONS pfo ;
  1091. if(bSynthetic)
  1092. {
  1093. pfo = (PDFEATURE_OPTIONS) gMasterTable[MTI_SYNTHESIZED_FEATURES].pubStruct +
  1094. dwFeature ;
  1095. dwFeaOffset = gMasterTable[MTI_DFEATURE_OPTIONS].dwArraySize ;
  1096. }
  1097. else
  1098. {
  1099. pfo = (PDFEATURE_OPTIONS) gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct +
  1100. dwFeature ;
  1101. dwFeaOffset = 0 ;
  1102. }
  1103. patt = (PATTRIB_TREE) gMasterTable[MTI_ATTRIBTREE].pubStruct ;
  1104. patr = (PATREEREF)((PBYTE)pfo + dwFieldOff) ;
  1105. atrCur = *patr ;
  1106. if(atrCur == ATTRIB_UNINITIALIZED)
  1107. {
  1108. if(pubIn)
  1109. {
  1110. if(!BcreateEndNode(patr, dwFeature + dwFeaOffset , dwOption, pglobl) )
  1111. return(FALSE) ; // resource exhaustion
  1112. if(!BwriteToHeap(&(patt[*patr].dwOffset), pubIn,
  1113. dwCount, 4, pglobl) )
  1114. return(FALSE) ; // A fatal error.
  1115. patt[*patr].eOffsetMeans = VALUE_AT_HEAP ;
  1116. }
  1117. *pbPrevsExists = FALSE ;
  1118. return(TRUE) ;
  1119. }
  1120. if(atrCur & ATTRIB_HEAP_VALUE)
  1121. {
  1122. ERR(("Internal error. BexchangeArbDataInFOATNode should never create a branchless node.\n"));
  1123. return(FALSE) ;
  1124. }
  1125. // offset field contains index to another node
  1126. // but we will tack the new node (if any) after
  1127. // the existing node. Don't change patr.
  1128. if(pubIn)
  1129. {
  1130. if(!BfindOrCreateMatchingNode(atrCur, &atrCur, dwFeature + dwFeaOffset , dwOption, pglobl))
  1131. return(FALSE) ; // Tree inconsistency error or resource exhaustion
  1132. if(patt[atrCur].eOffsetMeans != VALUE_AT_HEAP)
  1133. {
  1134. // just created a new node.
  1135. if(!BwriteToHeap(&(patt[atrCur].dwOffset), pubIn, dwCount, 4, pglobl) )
  1136. return(FALSE) ; // A fatal error.
  1137. patt[atrCur].eOffsetMeans = VALUE_AT_HEAP ;
  1138. *pbPrevsExists = FALSE ;
  1139. return(TRUE) ;
  1140. }
  1141. if(pubOut)
  1142. memcpy(pubOut, mpubOffRef + patt[atrCur].dwOffset, dwCount) ;
  1143. memcpy(mpubOffRef + patt[atrCur].dwOffset, pubIn, dwCount) ;
  1144. }
  1145. else
  1146. {
  1147. if(!BfindMatchingNode(atrCur, &atrCur, dwFeature + dwFeaOffset , dwOption, pglobl))
  1148. {
  1149. *pbPrevsExists = FALSE ; // nothing found, don't create.
  1150. return(TRUE) ;
  1151. }
  1152. if(pubOut)
  1153. memcpy(pubOut, mpubOffRef + patt[atrCur].dwOffset, dwCount) ;
  1154. }
  1155. *pbPrevsExists = TRUE ;
  1156. return(TRUE) ;
  1157. } // BexchangeArbDataInFOATNode(...)
  1158. typedef struct
  1159. {
  1160. DWORD dwUserPriority ;
  1161. DWORD dwNext ; // index of feature with a equal or greater
  1162. // numerical value for dwUserPriority .
  1163. } PRIORITY_NODE, *PPRIORITY_NODE ; // the prefix tag shall be 'pn'
  1164. BOOL BInitPriorityArray(
  1165. PGLOBL pglobl)
  1166. {
  1167. DWORD dwNumFea, dwFea, dwPrnStickyroot, dwDocStickyroot,
  1168. dwPrevsNode, dwCurNode, dwNumSyn, dwIndex, dwHeapOffset,
  1169. adwDefaultPriority[MAX_GID];
  1170. PDWORD pdwRoot, pdwPriority ;
  1171. PDFEATURE_OPTIONS pfo ;
  1172. PPRIORITY_NODE pnPri ;
  1173. BOOL bPrinterSticky ;
  1174. // init adwDefaultPriority[], the default priorities
  1175. // are very low compared to any value a user may
  1176. // explicitly assign.
  1177. // The last term is the priority starting from 0 = highest.
  1178. for(dwIndex = 0 ; dwIndex < MAX_GID ; dwIndex++)
  1179. {
  1180. adwDefaultPriority[dwIndex] = 0xffffffff ; // default if not enum below.
  1181. }
  1182. adwDefaultPriority[GID_PAGESIZE] = 0xffffffff - MAX_GID + 0 ;
  1183. adwDefaultPriority[GID_INPUTSLOT] = 0xffffffff - MAX_GID + 1 ;
  1184. adwDefaultPriority[GID_ORIENTATION] = 0xffffffff - MAX_GID + 2 ;
  1185. adwDefaultPriority[GID_COLORMODE] = 0xffffffff - MAX_GID + 3 ;
  1186. adwDefaultPriority[GID_DUPLEX] = 0xffffffff - MAX_GID + 4 ;
  1187. adwDefaultPriority[GID_MEDIATYPE] = 0xffffffff - MAX_GID + 5 ;
  1188. adwDefaultPriority[GID_RESOLUTION] = 0xffffffff - MAX_GID + 6 ;
  1189. adwDefaultPriority[GID_HALFTONING] = 0xffffffff - MAX_GID + 7 ;
  1190. dwPrnStickyroot = dwDocStickyroot = INVALID_INDEX ;
  1191. pfo = (PDFEATURE_OPTIONS) gMasterTable[MTI_DFEATURE_OPTIONS].pubStruct;
  1192. dwNumFea = gMasterTable[MTI_DFEATURE_OPTIONS].dwArraySize ;
  1193. if(!(pnPri = MemAllocZ(dwNumFea * sizeof(PRIORITY_NODE)) ))
  1194. {
  1195. ERR(("Fatal: BInitPriorityArray - unable to alloc %d bytes.\n",
  1196. dwNumFea * sizeof(PRIORITY_NODE)));
  1197. geErrorType = ERRTY_MEMORY_ALLOCATION ;
  1198. geErrorSev = ERRSEV_FATAL ;
  1199. gdwMasterTabIndex = 0xffff ;
  1200. return(FALSE) ; // This is unrecoverable
  1201. }
  1202. for(dwFea = 0 ; dwFea < dwNumFea ; dwFea++)
  1203. {
  1204. if(BReadDataInGlobalNode(&pfo[dwFea].atrFeatureType , &dwHeapOffset, pglobl)
  1205. && *(PDWORD)(mpubOffRef + dwHeapOffset) == FT_PRINTERPROPERTY)
  1206. bPrinterSticky = TRUE ;
  1207. else
  1208. bPrinterSticky = FALSE ;
  1209. if(BReadDataInGlobalNode(&pfo[dwFea].atrPriority , &dwHeapOffset, pglobl))
  1210. {
  1211. pnPri[dwFea].dwUserPriority =
  1212. *(PDWORD)(mpubOffRef + dwHeapOffset) ;
  1213. }
  1214. else
  1215. {
  1216. pnPri[dwFea].dwUserPriority = 0xffffffff; // lowest priority
  1217. if(pfo[dwFea].dwGID != GID_UNKNOWN)
  1218. {
  1219. pnPri[dwFea].dwUserPriority = adwDefaultPriority[pfo[dwFea].dwGID] ;
  1220. }
  1221. }
  1222. pdwRoot = (bPrinterSticky ) ? &dwPrnStickyroot : &dwDocStickyroot ;
  1223. dwCurNode = *pdwRoot ;
  1224. dwPrevsNode = INVALID_INDEX ;
  1225. while(dwCurNode != INVALID_INDEX)
  1226. {
  1227. if(pnPri[dwFea].dwUserPriority <= pnPri[dwCurNode].dwUserPriority)
  1228. break ;
  1229. dwPrevsNode = dwCurNode ;
  1230. dwCurNode = pnPri[dwCurNode].dwNext ;
  1231. }
  1232. if(dwPrevsNode == INVALID_INDEX)
  1233. *pdwRoot = dwFea ; // first on the list.
  1234. else
  1235. pnPri[dwPrevsNode].dwNext = dwFea ;
  1236. pnPri[dwFea].dwNext = dwCurNode ;
  1237. }
  1238. // pdwPriority array holds index of all features
  1239. // including synthesized - which are assigned indicies
  1240. // dwFea >= dwNumFea. The feature indicies are ordered
  1241. // with the highest priority feature index occupying
  1242. // pdwPriority[0].
  1243. dwNumSyn = gMasterTable[MTI_SYNTHESIZED_FEATURES].dwArraySize ;
  1244. pdwPriority = (PDWORD)gMasterTable[MTI_PRIORITYARRAY].pubStruct ;
  1245. for(dwIndex = 0 ; dwIndex < dwNumSyn ; dwIndex++)
  1246. {
  1247. pdwPriority[dwIndex] = dwIndex + dwNumFea ;
  1248. // take all synthesized features and assign them
  1249. // the highest pri.
  1250. }
  1251. for(dwCurNode = dwPrnStickyroot ; dwCurNode != INVALID_INDEX ;
  1252. dwIndex++ )
  1253. {
  1254. pdwPriority[dwIndex] = dwCurNode ;
  1255. dwCurNode = pnPri[dwCurNode].dwNext ;
  1256. }
  1257. for(dwCurNode = dwDocStickyroot ; dwCurNode != INVALID_INDEX ;
  1258. dwIndex++ )
  1259. {
  1260. pdwPriority[dwIndex] = dwCurNode ;
  1261. dwCurNode = pnPri[dwCurNode].dwNext ;
  1262. }
  1263. ASSERT(dwIndex == gMasterTable[MTI_PRIORITYARRAY].dwArraySize) ;
  1264. MemFree(pnPri) ;
  1265. return(TRUE);
  1266. } //BInitPriorityArray ()