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.

853 lines
28 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. semanchk.c
  5. Abstract:
  6. function for checking GPD semantics which involves dependency between
  7. entries.
  8. Environment:
  9. user-mode only.
  10. Revision History:
  11. 02/15/97 -zhanw-
  12. Created it.
  13. --*/
  14. #ifndef KERNEL_MODE
  15. #include "gpdparse.h"
  16. // ---- functions defined in semanchk.c ---- //
  17. BOOL
  18. BCheckGPDSemantics(
  19. IN PINFOHEADER pInfoHdr,
  20. POPTSELECT poptsel // assume fully initialized
  21. ) ;
  22. // ------- end function declarations ------- //
  23. BOOL
  24. BCheckGPDSemantics(
  25. IN PINFOHEADER pInfoHdr,
  26. POPTSELECT poptsel // assume fully initialized
  27. )
  28. /*++
  29. Routine Description:
  30. This function checks if the given snapshot makes sense. It covers only
  31. conditionally required entries and printing commands since other
  32. statically required entries are already covered by snapshot functions.
  33. Arguments:
  34. pInfoHdr: pointer to INFOHEADER structure.
  35. Return Value:
  36. TRUE if the semantics is correct. Otherwise, FALSE.
  37. --*/
  38. {
  39. DWORD dwFeaIndex, dwI, dwNumOpts, dwListIndex ,
  40. dwMoveUnitsX, dwMoveUnitsY, dwResX, dwResY ;
  41. BOOL bStatus = TRUE ; // until fails.
  42. PGPDDRIVERINFO pDrvInfo ;
  43. PUIINFO pUIInfo ;
  44. PFEATURE pFeature ;
  45. if(!pInfoHdr)
  46. return FALSE ;
  47. pDrvInfo = (PGPDDRIVERINFO) GET_DRIVER_INFO_FROM_INFOHEADER(pInfoHdr) ;
  48. if(!pDrvInfo)
  49. return FALSE ;
  50. pUIInfo = GET_UIINFO_FROM_INFOHEADER(pInfoHdr) ;
  51. if(!pUIInfo)
  52. return FALSE ;
  53. // Fix for bug 6774
  54. if(pUIInfo->dwPrintRate && (pUIInfo->dwPrintRateUnit == INVALID_INDEX))
  55. {
  56. ERR(("*PrintRateUnit must be present if *PrintRate exists.\n")) ;
  57. bStatus = FALSE ;
  58. }
  59. // end fix for bug 6774
  60. //
  61. // 1. global printing entries
  62. //
  63. // - *MemoryUsage cannot be an empty list if *Memory feature exists.
  64. //
  65. // - *XMoveUnit (*YMoveUnit) must be non-trivial (greater than 1) if
  66. // there is any x-move (y-move) command.
  67. //
  68. // - *DefaultFont cannot be 0 if *DeviceFonts is not an empty list.
  69. //
  70. // - CmdCR, CmdLF, and CmdFF are always required.
  71. //
  72. if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_MEMOPTION ) &&
  73. (pDrvInfo->Globals.liMemoryUsage == END_OF_LIST) )
  74. {
  75. ERR(("*MemoryUsage cannot be an empty list if *Memory feature exists.\n")) ;
  76. #ifdef STRICT_CHECKS
  77. bStatus = FALSE ;
  78. #endif
  79. }
  80. if((COMMANDPTR(pDrvInfo , CMD_XMOVEABSOLUTE ) ||
  81. COMMANDPTR(pDrvInfo , CMD_XMOVERELLEFT ) ||
  82. COMMANDPTR(pDrvInfo , CMD_XMOVERELRIGHT )) &&
  83. pDrvInfo->Globals.ptDeviceUnits.x <= 1)
  84. {
  85. ERR(("*XMoveUnit must be > 1 if any x-move command exists.\n")) ;
  86. bStatus = FALSE ;
  87. }
  88. if((COMMANDPTR(pDrvInfo , CMD_YMOVEABSOLUTE ) ||
  89. COMMANDPTR(pDrvInfo , CMD_YMOVERELUP ) ||
  90. COMMANDPTR(pDrvInfo , CMD_YMOVERELDOWN )) &&
  91. pDrvInfo->Globals.ptDeviceUnits.y <= 1)
  92. {
  93. ERR(("*YMoveUnit must be > 1 if any y-move command exists.\n")) ;
  94. bStatus = FALSE ;
  95. }
  96. if((pDrvInfo->Globals.liDeviceFontList != END_OF_LIST) &&
  97. (pDrvInfo->Globals.dwDefaultFont == 0) )
  98. {
  99. ERR(("*DefaultFont cannot be 0 if *DeviceFonts is not an empty list.\n")) ;
  100. #ifdef STRICT_CHECKS
  101. bStatus = FALSE ;
  102. #endif
  103. }
  104. if (!COMMANDPTR(pDrvInfo , CMD_FORMFEED ) ||
  105. !COMMANDPTR(pDrvInfo , CMD_CARRIAGERETURN ) ||
  106. !COMMANDPTR(pDrvInfo , CMD_LINEFEED ) )
  107. {
  108. ERR(("CmdCR, CmdLF, and CmdFF are always required.\n")) ;
  109. bStatus = FALSE ;
  110. }
  111. // are there an integral number of master units per
  112. // moveunit?
  113. if( pDrvInfo->Globals.ptMasterUnits.x %
  114. pDrvInfo->Globals.ptDeviceUnits.x )
  115. {
  116. ERR(("Must be whole number of master units per x move unit.\n")) ;
  117. bStatus = FALSE ;
  118. }
  119. if( pDrvInfo->Globals.ptMasterUnits.y %
  120. pDrvInfo->Globals.ptDeviceUnits.y )
  121. {
  122. ERR(("Must be whole number of master units per y move unit.\n")) ;
  123. bStatus = FALSE ;
  124. }
  125. if(pDrvInfo->Globals.ptDeviceUnits.x > 1)
  126. {
  127. dwMoveUnitsX = pDrvInfo->Globals.ptMasterUnits.x /
  128. pDrvInfo->Globals.ptDeviceUnits.x ;
  129. }
  130. else
  131. dwMoveUnitsX = 1 ;
  132. if(pDrvInfo->Globals.ptDeviceUnits.y > 1)
  133. {
  134. dwMoveUnitsY = pDrvInfo->Globals.ptMasterUnits.y /
  135. pDrvInfo->Globals.ptDeviceUnits.y ;
  136. }
  137. else
  138. dwMoveUnitsY = 1 ;
  139. if(!dwMoveUnitsX || !dwMoveUnitsY)
  140. {
  141. ERR(("master units cannot be coarser than X or Y MoveUnit.\n")) ;
  142. return FALSE ;
  143. }
  144. //
  145. // 2. printing commands
  146. //
  147. // - if *XMoveThreshold (*YMoveThreshold) is 0, then CmdXMoveAbsolute
  148. // (CmdYMoveAbsolute) must exist. Similarly, if *XMoveThreshold
  149. // (*YMoveThreshold) is *, then CmdXMoveRelRight (CmdYMoveRelDown and
  150. // (CmdYMoveRelUp) must exist.
  151. //
  152. #if 0
  153. // if Threshold is omitted by user, its set to 0 by default
  154. // by the snapshot code. So this check will fail when
  155. // everything is ok.
  156. if((pDrvInfo->Globals.dwXMoveThreshold == 0) &&
  157. !COMMANDPTR(pDrvInfo , CMD_XMOVEABSOLUTE ))
  158. {
  159. ERR(("*CmdXMoveAbsolute must exist if *XMoveThreshold is 0.\n")) ;
  160. bStatus = FALSE ;
  161. }
  162. if((pDrvInfo->Globals.dwYMoveThreshold == 0) &&
  163. !COMMANDPTR(pDrvInfo , CMD_YMOVEABSOLUTE ))
  164. {
  165. ERR(("*CmdYMoveAbsolute must exist if *YMoveThreshold is 0.\n")) ;
  166. bStatus = FALSE ;
  167. }
  168. #endif
  169. if((pDrvInfo->Globals.dwXMoveThreshold == WILDCARD_VALUE) &&
  170. !COMMANDPTR(pDrvInfo , CMD_XMOVERELRIGHT ) )
  171. {
  172. ERR(("XMoveRelativeRight must exist if *XMoveThreshold is *.\n")) ;
  173. bStatus = FALSE ;
  174. }
  175. if((pDrvInfo->Globals.dwYMoveThreshold == WILDCARD_VALUE) &&
  176. !COMMANDPTR(pDrvInfo , CMD_YMOVERELDOWN ))
  177. {
  178. ERR(("YMoveRelativeDown must exist if *YMoveThreshold is *.\n")) ;
  179. bStatus = FALSE ;
  180. }
  181. // - CmdSendBlockData must exist if *PrinterType is not TTY.
  182. if((pDrvInfo->Globals.printertype != PT_TTY) &&
  183. !COMMANDPTR(pDrvInfo , CMD_SENDBLOCKDATA ))
  184. {
  185. ERR(("*CmdSendBlockData must exist if *PrinterType is not TTY.\n")) ;
  186. bStatus = FALSE ;
  187. }
  188. //
  189. // - CmdSetFontID, CmdSelectFontID, CmdSetCharCode must be consistent
  190. // in their presence (i.e. all or none). Furthermore, if
  191. // CmdSetFontID/CmdSelectFontID/CmdSetCharCode all exist, then
  192. // *FontFormat must be one of the pre-defined constants.
  193. //
  194. dwI = 0 ;
  195. if(COMMANDPTR(pDrvInfo , CMD_SETFONTID ) )
  196. dwI++ ;
  197. if(COMMANDPTR(pDrvInfo , CMD_SELECTFONTID ) )
  198. dwI++ ;
  199. if(COMMANDPTR(pDrvInfo , CMD_SETCHARCODE ) )
  200. dwI++ ;
  201. if(dwI && dwI != 3)
  202. {
  203. ERR(("CmdSetFontID, CmdSelectFontID, CmdSetCharCode must be present or absent together.\n")) ;
  204. bStatus = FALSE ;
  205. }
  206. if((dwI == 3) && (pDrvInfo->Globals.fontformat == UNUSED_ITEM) )
  207. {
  208. ERR(("if font cmds exist, then *FontFormat must be defined\n")) ;
  209. bStatus = FALSE ;
  210. }
  211. // - CmdBoldOn and CmdBoldOff must be paired (i.e. both or none). The
  212. // same goes for:
  213. // CmdItalicOn & CmdItalicOff,
  214. // CmdUnderlineOn & CmdUnderlineOff,
  215. // CmdStrikeThruOn & CmdStrikeThruOff,
  216. // CmdWhiteTextOn & CmdWhiteTextOff,
  217. // CmdSelectSingleByteMode & CmdSelectDoubleByteMode,
  218. // CmdVerticalPrintingOn/CmdVerticalPrintingOff.
  219. //
  220. // - CmdSetRectWidth and CmdSetRectHeight must be paired.
  221. //
  222. dwI = 0 ;
  223. if(COMMANDPTR(pDrvInfo , CMD_BOLDON ) )
  224. dwI++ ;
  225. if(dwI && (COMMANDPTR(pDrvInfo , CMD_BOLDOFF ) ||
  226. COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) )
  227. dwI++ ;
  228. if(dwI && dwI != 2)
  229. {
  230. ERR(("CmdBoldOn and CmdBoldOff must be paired.\n")) ;
  231. bStatus = FALSE ;
  232. }
  233. dwI = 0 ;
  234. if(COMMANDPTR(pDrvInfo , CMD_ITALICON) )
  235. dwI++ ;
  236. if(dwI && (COMMANDPTR(pDrvInfo , CMD_ITALICOFF ) ||
  237. COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) )
  238. dwI++ ;
  239. if(dwI && dwI != 2)
  240. {
  241. ERR(("CmdItalicOn & CmdItalicOff must be paired.\n")) ;
  242. bStatus = FALSE ;
  243. }
  244. dwI = 0 ;
  245. if(COMMANDPTR(pDrvInfo , CMD_UNDERLINEON ) )
  246. dwI++ ;
  247. if(dwI && (COMMANDPTR(pDrvInfo , CMD_UNDERLINEOFF ) ||
  248. COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) )
  249. dwI++ ;
  250. if(dwI && dwI != 2)
  251. {
  252. ERR(("CmdUnderlineOn & CmdUnderlineOff must be paired.\n")) ;
  253. bStatus = FALSE ;
  254. }
  255. dwI = 0 ;
  256. if(COMMANDPTR(pDrvInfo , CMD_STRIKETHRUON ) )
  257. dwI++ ;
  258. if(COMMANDPTR(pDrvInfo , CMD_STRIKETHRUOFF ) )
  259. dwI++ ;
  260. if(dwI && dwI != 2)
  261. {
  262. ERR(("CmdStrikeThruOn & CmdStrikeThruOff must be paired.\n")) ;
  263. bStatus = FALSE ;
  264. }
  265. dwI = 0 ;
  266. if(COMMANDPTR(pDrvInfo , CMD_WHITETEXTON ) )
  267. dwI++ ;
  268. if(COMMANDPTR(pDrvInfo , CMD_WHITETEXTOFF ) )
  269. dwI++ ;
  270. if(dwI && dwI != 2)
  271. {
  272. ERR(("CmdWhiteTextOn & CmdWhiteTextOff must be paired.\n")) ;
  273. bStatus = FALSE ;
  274. }
  275. dwI = 0 ;
  276. if(COMMANDPTR(pDrvInfo , CMD_SELECTSINGLEBYTEMODE ) )
  277. dwI++ ;
  278. if(COMMANDPTR(pDrvInfo , CMD_SELECTDOUBLEBYTEMODE ) )
  279. dwI++ ;
  280. if(dwI && dwI != 2)
  281. {
  282. ERR(("CmdSelectSingleByteMode & CmdSelectDoubleByteMode must be paired.\n")) ;
  283. bStatus = FALSE ;
  284. }
  285. dwI = 0 ;
  286. if(COMMANDPTR(pDrvInfo , CMD_VERTICALPRINTINGON ) )
  287. dwI++ ;
  288. if(COMMANDPTR(pDrvInfo , CMD_VERTICALPRINTINGOFF ) )
  289. dwI++ ;
  290. if(dwI && dwI != 2)
  291. {
  292. ERR(("CmdVerticalPrintingOn/CmdVerticalPrintingOff must be paired.\n")) ;
  293. bStatus = FALSE ;
  294. }
  295. dwI = 0 ;
  296. if(COMMANDPTR(pDrvInfo , CMD_SETRECTWIDTH ) )
  297. dwI++ ;
  298. if(COMMANDPTR(pDrvInfo , CMD_SETRECTHEIGHT ) )
  299. dwI++ ;
  300. if(dwI && dwI != 2)
  301. {
  302. ERR(("CmdSetRectWidth and CmdSetRectHeight must be paired.\n")) ;
  303. bStatus = FALSE ;
  304. }
  305. // Note because this check involves looking at the command table
  306. // which is snapshot specific, we cannot perform this for every
  307. // option as Zhanw requested. Only the current option.
  308. //
  309. // 3. special entries in various types of *Option constructs
  310. //
  311. // - For each ColorMode option whose *DevNumOfPlanes is greater than 1,
  312. // *ColorPlaneOrder cannot be an empty list.
  313. //
  314. // - For each ColorMode option whose *DevNumOfPlanes is greater than 1,
  315. // and *DevBPP is 1, search through its *ColorPlaneOrder list:
  316. // if YELLOW is in the list, then CmdSendYellowData must exist. The
  317. // same goes for other colors: MAGENTA, CYAN, BLACK, RED, GREEN, BLUE.
  318. pUIInfo = GET_UIINFO_FROM_INFOHEADER(pInfoHdr) ;
  319. pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_COLORMODE) ;
  320. if(pFeature)
  321. {
  322. PCOLORMODE pColorMode ;
  323. PCOLORMODEEX pCMex ;
  324. PLISTNODE pLNode ;
  325. DWORD dwOptIndex ;
  326. dwNumOpts = pFeature->Options.dwCount ;
  327. pColorMode = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
  328. if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_COLORMODE ) )
  329. {
  330. dwOptIndex = poptsel[dwFeaIndex].ubCurOptIndex ;
  331. pCMex = OFFSET_TO_POINTER(pInfoHdr,
  332. pColorMode[dwOptIndex].GenericOption.loRenderOffset) ;
  333. if((pCMex->dwPrinterNumOfPlanes > 1) &&
  334. (pCMex->liColorPlaneOrder == END_OF_LIST) )
  335. {
  336. ERR(("*ColorPlaneOrder must be specified if *DevNumOfPlanes > 1.\n")) ;
  337. bStatus = FALSE ;
  338. }
  339. if((pCMex->dwPrinterNumOfPlanes > 1) &&
  340. (pCMex->dwPrinterBPP == 1) )
  341. {
  342. for(dwListIndex = pCMex->liColorPlaneOrder ;
  343. pLNode = LISTNODEPTR(pDrvInfo , dwListIndex ) ;
  344. dwListIndex = pLNode->dwNextItem)
  345. {
  346. switch(pLNode->dwData)
  347. {
  348. case COLOR_YELLOW:
  349. {
  350. if(!COMMANDPTR(pDrvInfo , CMD_SENDYELLOWDATA))
  351. {
  352. ERR(("*CmdSendYellowData must exist.\n")) ;
  353. bStatus = FALSE ;
  354. }
  355. break ;
  356. }
  357. case COLOR_MAGENTA:
  358. {
  359. if(!COMMANDPTR(pDrvInfo , CMD_SENDMAGENTADATA))
  360. {
  361. ERR(("*CmdSendMagentaData must exist.\n")) ;
  362. bStatus = FALSE ;
  363. }
  364. break ;
  365. }
  366. case COLOR_CYAN:
  367. {
  368. if(!COMMANDPTR(pDrvInfo , CMD_SENDCYANDATA))
  369. {
  370. ERR(("*CmdSendCyanData must exist.\n")) ;
  371. bStatus = FALSE ;
  372. }
  373. break ;
  374. }
  375. case COLOR_BLACK:
  376. {
  377. if(!COMMANDPTR(pDrvInfo , CMD_SENDBLACKDATA))
  378. {
  379. ERR(("*CmdSendBlackData must exist.\n")) ;
  380. bStatus = FALSE ;
  381. }
  382. break ;
  383. }
  384. case COLOR_RED:
  385. {
  386. if(!COMMANDPTR(pDrvInfo , CMD_SENDREDDATA))
  387. {
  388. ERR(("*CmdSendRedData must exist.\n")) ;
  389. bStatus = FALSE ;
  390. }
  391. break ;
  392. }
  393. case COLOR_GREEN:
  394. {
  395. if(!COMMANDPTR(pDrvInfo , CMD_SENDGREENDATA))
  396. {
  397. ERR(("*CmdSendGreenData must exist.\n")) ;
  398. bStatus = FALSE ;
  399. }
  400. break ;
  401. }
  402. case COLOR_BLUE:
  403. {
  404. if(!COMMANDPTR(pDrvInfo , CMD_SENDBLUEDATA))
  405. {
  406. ERR(("*CmdSendBlueData must exist.\n")) ;
  407. bStatus = FALSE ;
  408. }
  409. break ;
  410. }
  411. default:
  412. {
  413. ERR(("Unrecogized color.\n")) ;
  414. bStatus = FALSE ;
  415. break ;
  416. }
  417. }
  418. }
  419. }
  420. }
  421. }
  422. dwResX = dwResY = 1 ; // default in case something goes wrong.
  423. if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_RESOLUTION ) )
  424. {
  425. pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_RESOLUTION) ;
  426. if(pFeature)
  427. {
  428. PRESOLUTION pRes ;
  429. DWORD dwOptIndex ;
  430. dwOptIndex = poptsel[dwFeaIndex].ubCurOptIndex ;
  431. dwNumOpts = pFeature->Options.dwCount ;
  432. pRes = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
  433. for(dwI = 0 ; dwI < dwNumOpts ; dwI++)
  434. {
  435. if( pDrvInfo->Globals.ptMasterUnits.x < pRes[dwI].iXdpi )
  436. {
  437. ERR(("master units cannot be coarser than x res unit.\n")) ;
  438. return FALSE ; // fatal error
  439. }
  440. if( pDrvInfo->Globals.ptMasterUnits.x % pRes[dwI].iXdpi )
  441. {
  442. ERR(("Must be whole number of master units per x res unit.\n")) ;
  443. bStatus = FALSE ;
  444. }
  445. if( pDrvInfo->Globals.ptMasterUnits.y < pRes[dwI].iYdpi )
  446. {
  447. ERR(("master units cannot be coarser than y res unit.\n")) ;
  448. return FALSE ;
  449. }
  450. if ( pDrvInfo->Globals.ptMasterUnits.y % pRes[dwI].iYdpi )
  451. {
  452. ERR(("Must be whole number of master units per y res unit.\n")) ;
  453. bStatus = FALSE ;
  454. }
  455. }
  456. // number of master units per resolution unit.
  457. dwResX = pDrvInfo->Globals.ptMasterUnits.x /
  458. pRes[dwOptIndex].iXdpi ;
  459. dwResY = pDrvInfo->Globals.ptMasterUnits.y /
  460. pRes[dwOptIndex].iYdpi ;
  461. }
  462. }
  463. else
  464. {
  465. ERR(("Resolution is a required feature.\n")) ;
  466. }
  467. //
  468. // - For each non-standard Halftone option, *rcHPPatternID must be
  469. // greater than 0 and *HTPatternSize must be a pair of postive integers.
  470. // NOTE: check with DanielC --- should we enforce that xSize==ySize?
  471. //
  472. // Halftone check is performed in BinitSpecialFeatureOptionFields
  473. // see postproc.c
  474. pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGESIZE) ;
  475. if(pFeature)
  476. {
  477. PPAGESIZE pPagesize ;
  478. PPAGESIZEEX pPageSzEx ;
  479. dwNumOpts = pFeature->Options.dwCount ;
  480. pPagesize = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
  481. for(dwI = 0 ; dwI < dwNumOpts ; dwI++)
  482. {
  483. if(GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGEPROTECTION) &&
  484. !pPagesize[dwI].dwPageProtectionMemory)
  485. {
  486. ERR(("*PageProtectMem must be greater than 0 if PageProtect feature exists.\n")) ;
  487. #ifdef STRICT_CHECKS
  488. bStatus = FALSE ;
  489. #endif
  490. break ;
  491. }
  492. pPageSzEx = OFFSET_TO_POINTER(pInfoHdr,
  493. pPagesize[dwI].GenericOption.loRenderOffset) ;
  494. if(pPagesize[dwI].dwPaperSizeID != DMPAPER_USER)
  495. {
  496. INT iPDx, iPDy ; // holds page dimensions
  497. // in same coordinate system as ImageableArea
  498. if(pPageSzEx->bRotateSize)
  499. {
  500. iPDx = (INT)pPagesize[dwI].szPaperSize.cy ;
  501. iPDy = (INT)pPagesize[dwI].szPaperSize.cx ;
  502. }
  503. else
  504. {
  505. iPDx = (INT)pPagesize[dwI].szPaperSize.cx ;
  506. iPDy = (INT)pPagesize[dwI].szPaperSize.cy ;
  507. }
  508. if((iPDx <= 0) || (iPDy <= 0))
  509. {
  510. ERR(("*PageDimensions is required for non-standard sizes.\n")) ;
  511. bStatus = FALSE ;
  512. break ;
  513. }
  514. if(((INT)pPageSzEx->szImageArea.cx <= 0) ||
  515. ((INT)pPageSzEx->szImageArea.cy <= 0) )
  516. {
  517. ERR(("*PrintableArea is required and must be positive.\n")) ;
  518. bStatus = FALSE ;
  519. break ;
  520. }
  521. if(((INT)pPageSzEx->ptImageOrigin.x < 0) ||
  522. ((INT)pPageSzEx->ptImageOrigin.y < 0) )
  523. {
  524. ERR(("*PrintableOrigin is required and cannot be negative.\n")) ;
  525. bStatus = FALSE ;
  526. break ;
  527. }
  528. if((pPageSzEx->szImageArea.cx % dwResX) ||
  529. (pPageSzEx->szImageArea.cy % dwResY) )
  530. {
  531. ERR(("*PrintableArea must be a integral number of ResolutionUnits.\n")) ;
  532. #ifdef STRICT_CHECKS
  533. bStatus = FALSE ;
  534. #endif
  535. break ;
  536. }
  537. if((pPageSzEx->ptImageOrigin.x % dwResX) ||
  538. (pPageSzEx->ptImageOrigin.y % dwResY) )
  539. {
  540. ERR(("*PrintableOrigin must be a integral number of ResolutionUnits.\n")) ;
  541. #ifdef STRICT_CHECKS
  542. bStatus = FALSE ;
  543. #endif
  544. break ;
  545. }
  546. if(pDrvInfo->Globals.bRotateCoordinate)
  547. { // zhanw assumes printing offset is zero otherwise
  548. if((pPageSzEx->ptImageOrigin.x % dwMoveUnitsX) ||
  549. (pPageSzEx->ptImageOrigin.y % dwMoveUnitsY) )
  550. {
  551. ERR(("*PrintableOrigin must be a integral number of MoveUnits.\n")) ;
  552. #ifdef STRICT_CHECKS
  553. bStatus = FALSE ;
  554. #endif
  555. break ;
  556. }
  557. if((pPageSzEx->ptPrinterCursorOrig.x % dwMoveUnitsX) ||
  558. (pPageSzEx->ptPrinterCursorOrig.y % dwMoveUnitsY) )
  559. {
  560. ERR(("*CursorOrigin must be a integral number of MoveUnits.\n")) ;
  561. #ifdef STRICT_CHECKS
  562. bStatus = FALSE ;
  563. #endif
  564. break ;
  565. }
  566. }
  567. else if((pPageSzEx->ptImageOrigin.x != pPageSzEx->ptPrinterCursorOrig.x) ||
  568. (pPageSzEx->ptImageOrigin.y != pPageSzEx->ptPrinterCursorOrig.y) )
  569. {
  570. ; // this may be unnecessary.
  571. // ERR(("For non-rotating printers, *PrintableOrigin should be same as *CursorOrigin.\n")) ;
  572. }
  573. if((iPDx + iPDx/100 < pPageSzEx->szImageArea.cx + pPageSzEx->ptImageOrigin.x) ||
  574. (iPDy + iPDy/100 < pPageSzEx->szImageArea.cy + pPageSzEx->ptImageOrigin.y) )
  575. {
  576. // I give up to 1 percent leeway
  577. ERR(("*PrintableArea must be contained within *PageDimensions.\n")) ;
  578. bStatus = FALSE ;
  579. break ;
  580. }
  581. }
  582. else // (dwPaperSizeID == DMPAPER_USER)
  583. {
  584. if(((INT)pPageSzEx->ptMinSize.x <= 0) ||
  585. ((INT)pPageSzEx->ptMinSize.y <= 0) )
  586. {
  587. ERR(("If User Defined papersize exists *MinSize is required and must be positive.\n")) ;
  588. #ifdef STRICT_CHECKS
  589. bStatus = FALSE ;
  590. #endif
  591. }
  592. if(((INT)pPageSzEx->ptMaxSize.x <= 0) ||
  593. ((INT)pPageSzEx->ptMaxSize.y <= 0) )
  594. {
  595. ERR(("If User Defined papersize exists *MaxSize is required and must be positive.\n")) ;
  596. bStatus = FALSE ;
  597. }
  598. if((INT)pPageSzEx->dwMaxPrintableWidth <= 0)
  599. {
  600. ERR(("If User Defined papersize exists *MaxPrintableWidth is required and must be positive.\n")) ;
  601. bStatus = FALSE ;
  602. }
  603. }
  604. }
  605. }
  606. // - For each PaperSize option, *PageProtectMem must be greater than 0
  607. // if PageProtect feature exists.
  608. //
  609. // - For all non-CUSTOMSIZE PaperSize options, *PrintableArea and
  610. // *PrintableOrigin must be explicitly defined. Specifically,
  611. // *PrintableArea must be a pair of positive integers, and
  612. // *PrintableOrigin must be a pair of non-negative integers.
  613. // note: BInitSnapshotTable function assigns
  614. // UNUSED_ITEM (-1) as the default value for *PrintableOrigin.
  615. //
  616. // - For CUSTOMSIZE option, *MinSize, *MaxSize, and *MaxPrintableWidth
  617. // must be explicitly defined. Specifically, both *MinSize and *MaxSize
  618. // must be a pair of positive integers. *MaxPrintableWidth must be a
  619. // positive integer.
  620. // BInitSnapshotTable function assigns 0 (instead of NO_LIMIT_NUM)
  621. // as the default value for *MaxPrintableWidth.
  622. //
  623. // - For all non-standard non-CUSTOMSIZE PaperSize options, *PageDimensions
  624. // must be explicitly defined. Specifically, it must be a pair of positive
  625. // integers.
  626. //
  627. // - For any feature or option, if *Installable entry is TRUE, then
  628. // either *InstallableFeatureName or *rcInstallableFeatureNameID must
  629. // be present in that particular feature or option construct.
  630. //
  631. // - If any feature or option has *Installable being TRUE, then
  632. // either *InstalledOptionName/*NotInstalledOptionName or
  633. // *rcInstalledOptionNameID/*rcNotInstalledOptionNameID must be
  634. // defined at the root level.
  635. //
  636. // once synthetic features are created by BCreateSynthFeatures()
  637. // they undergo the same checks at createsnapshot time as
  638. // other features, triggering a warning if the Names of the feature and
  639. // its options are absent.
  640. #if 1
  641. {
  642. DWORD dwNumFea, dwFea, dwNumOpt, dwOpt, dwOptSize ;
  643. PENHARRAYREF pearTableContents ;
  644. PBYTE pubRaw ; // raw binary data.
  645. PBYTE pubOptions ; // points to start of array of OPTIONS
  646. PFEATURE pFea ;
  647. PBYTE pubnRaw ; // Parser's raw binary data.
  648. PSTATICFIELDS pStatic ;
  649. pubnRaw = pInfoHdr->RawData.pvPrivateData ;
  650. pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
  651. pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
  652. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  653. dwNumFea = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
  654. pFea = (PFEATURE)((PBYTE)pInfoHdr + pUIInfo->loFeatureList) ;
  655. for(dwFea = 0 ; dwFea < dwNumFea ; dwFea++)
  656. {
  657. if(!pFea[dwFea].iHelpIndex)
  658. {
  659. ERR(("*HelpIndex must be positive.\n")) ;
  660. bStatus = FALSE ;
  661. }
  662. dwNumOpt = pFea[dwFea].Options.dwCount ;
  663. pubOptions = (PBYTE)pInfoHdr + pFea[dwFea].Options.loOffset ;
  664. dwOptSize = pFea[dwFea].dwOptionSize ;
  665. for(dwOpt = 0 ; dwOpt < dwNumOpt ; dwOpt++)
  666. {
  667. if(!((POPTION)(pubOptions + dwOptSize * dwOpt))->iHelpIndex )
  668. {
  669. ERR(("*HelpIndex must be positive.\n")) ;
  670. bStatus = FALSE ;
  671. }
  672. }
  673. }
  674. }
  675. #else
  676. {
  677. DWORD dwNumFea, dwFea, dwNumOpt, dwOpt;
  678. PENHARRAYREF pearTableContents ;
  679. PBYTE pubRaw ; // raw binary data.
  680. PBYTE pubOptions ; // points to start of array of OPTIONS
  681. PFEATURE pFea ;
  682. pubRaw = pInfoHdr->RawData.pvPrivateData ;
  683. pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
  684. dwNumFea = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
  685. for(dwFea = 0 ; dwFea < dwNumFea ; dwFea++)
  686. {
  687. pFea = PGetIndexedFeature(pUIInfo, dwFea) ;
  688. if(!pFea->iHelpIndex)
  689. {
  690. ERR(("*HelpIndex must be positive.\n")) ;
  691. bStatus = FALSE ;
  692. }
  693. dwNumOpt = pFea->Options.dwCount ;
  694. for(dwOpt = 0 ; dwOpt < dwNumOpt ; dwOpt++)
  695. {
  696. pubOptions = PGetIndexedOption(pUIInfo, pFea, dwOpt);
  697. if(!((POPTION)pubOptions))->iHelpIndex )
  698. {
  699. ERR(("*HelpIndex must be positive.\n")) ;
  700. bStatus = FALSE ;
  701. }
  702. }
  703. }
  704. }
  705. #endif
  706. return (bStatus);
  707. }
  708. #endif