|
|
/*++
Copyright (c) 1996-1999 Microsoft Corporation
Module Name:
semanchk.c
Abstract:
function for checking GPD semantics which involves dependency between entries.
Environment:
user-mode only.
Revision History:
02/15/97 -zhanw- Created it.
--*/
#ifndef KERNEL_MODE
#include "gpdparse.h"
// ---- functions defined in semanchk.c ---- //
BOOL BCheckGPDSemantics( IN PINFOHEADER pInfoHdr, POPTSELECT poptsel // assume fully initialized
) ;
// ------- end function declarations ------- //
BOOL BCheckGPDSemantics( IN PINFOHEADER pInfoHdr, POPTSELECT poptsel // assume fully initialized
) /*++
Routine Description: This function checks if the given snapshot makes sense. It covers only conditionally required entries and printing commands since other statically required entries are already covered by snapshot functions.
Arguments: pInfoHdr: pointer to INFOHEADER structure.
Return Value: TRUE if the semantics is correct. Otherwise, FALSE.
--*/ { DWORD dwFeaIndex, dwI, dwNumOpts, dwListIndex , dwMoveUnitsX, dwMoveUnitsY, dwResX, dwResY ; BOOL bStatus = TRUE ; // until fails.
PGPDDRIVERINFO pDrvInfo ; PUIINFO pUIInfo ; PFEATURE pFeature ;
if(!pInfoHdr) return FALSE ; pDrvInfo = (PGPDDRIVERINFO) GET_DRIVER_INFO_FROM_INFOHEADER(pInfoHdr) ; if(!pDrvInfo) return FALSE ; pUIInfo = GET_UIINFO_FROM_INFOHEADER(pInfoHdr) ; if(!pUIInfo) return FALSE ;
// Fix for bug 6774
if(pUIInfo->dwPrintRate && (pUIInfo->dwPrintRateUnit == INVALID_INDEX)) { ERR(("*PrintRateUnit must be present if *PrintRate exists.\n")) ; bStatus = FALSE ; } // end fix for bug 6774
//
// 1. global printing entries
//
// - *MemoryUsage cannot be an empty list if *Memory feature exists.
//
// - *XMoveUnit (*YMoveUnit) must be non-trivial (greater than 1) if
// there is any x-move (y-move) command.
//
// - *DefaultFont cannot be 0 if *DeviceFonts is not an empty list.
//
// - CmdCR, CmdLF, and CmdFF are always required.
//
if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_MEMOPTION ) && (pDrvInfo->Globals.liMemoryUsage == END_OF_LIST) ) { ERR(("*MemoryUsage cannot be an empty list if *Memory feature exists.\n")) ; #ifdef STRICT_CHECKS
bStatus = FALSE ; #endif
}
if((COMMANDPTR(pDrvInfo , CMD_XMOVEABSOLUTE ) || COMMANDPTR(pDrvInfo , CMD_XMOVERELLEFT ) || COMMANDPTR(pDrvInfo , CMD_XMOVERELRIGHT )) && pDrvInfo->Globals.ptDeviceUnits.x <= 1) { ERR(("*XMoveUnit must be > 1 if any x-move command exists.\n")) ; bStatus = FALSE ; }
if((COMMANDPTR(pDrvInfo , CMD_YMOVEABSOLUTE ) || COMMANDPTR(pDrvInfo , CMD_YMOVERELUP ) || COMMANDPTR(pDrvInfo , CMD_YMOVERELDOWN )) && pDrvInfo->Globals.ptDeviceUnits.y <= 1) { ERR(("*YMoveUnit must be > 1 if any y-move command exists.\n")) ; bStatus = FALSE ; }
if((pDrvInfo->Globals.liDeviceFontList != END_OF_LIST) && (pDrvInfo->Globals.dwDefaultFont == 0) ) { ERR(("*DefaultFont cannot be 0 if *DeviceFonts is not an empty list.\n")) ; #ifdef STRICT_CHECKS
bStatus = FALSE ; #endif
}
if (!COMMANDPTR(pDrvInfo , CMD_FORMFEED ) || !COMMANDPTR(pDrvInfo , CMD_CARRIAGERETURN ) || !COMMANDPTR(pDrvInfo , CMD_LINEFEED ) ) { ERR(("CmdCR, CmdLF, and CmdFF are always required.\n")) ; bStatus = FALSE ; }
// are there an integral number of master units per
// moveunit?
if( pDrvInfo->Globals.ptMasterUnits.x % pDrvInfo->Globals.ptDeviceUnits.x ) { ERR(("Must be whole number of master units per x move unit.\n")) ; bStatus = FALSE ; } if( pDrvInfo->Globals.ptMasterUnits.y % pDrvInfo->Globals.ptDeviceUnits.y ) { ERR(("Must be whole number of master units per y move unit.\n")) ; bStatus = FALSE ; }
if(pDrvInfo->Globals.ptDeviceUnits.x > 1) { dwMoveUnitsX = pDrvInfo->Globals.ptMasterUnits.x / pDrvInfo->Globals.ptDeviceUnits.x ; } else dwMoveUnitsX = 1 ;
if(pDrvInfo->Globals.ptDeviceUnits.y > 1) { dwMoveUnitsY = pDrvInfo->Globals.ptMasterUnits.y / pDrvInfo->Globals.ptDeviceUnits.y ; } else dwMoveUnitsY = 1 ;
if(!dwMoveUnitsX || !dwMoveUnitsY) { ERR(("master units cannot be coarser than X or Y MoveUnit.\n")) ; return FALSE ; }
//
// 2. printing commands
//
// - if *XMoveThreshold (*YMoveThreshold) is 0, then CmdXMoveAbsolute
// (CmdYMoveAbsolute) must exist. Similarly, if *XMoveThreshold
// (*YMoveThreshold) is *, then CmdXMoveRelRight (CmdYMoveRelDown and
// (CmdYMoveRelUp) must exist.
//
#if 0
// if Threshold is omitted by user, its set to 0 by default
// by the snapshot code. So this check will fail when
// everything is ok.
if((pDrvInfo->Globals.dwXMoveThreshold == 0) && !COMMANDPTR(pDrvInfo , CMD_XMOVEABSOLUTE )) { ERR(("*CmdXMoveAbsolute must exist if *XMoveThreshold is 0.\n")) ; bStatus = FALSE ; }
if((pDrvInfo->Globals.dwYMoveThreshold == 0) && !COMMANDPTR(pDrvInfo , CMD_YMOVEABSOLUTE )) { ERR(("*CmdYMoveAbsolute must exist if *YMoveThreshold is 0.\n")) ; bStatus = FALSE ; } #endif
if((pDrvInfo->Globals.dwXMoveThreshold == WILDCARD_VALUE) && !COMMANDPTR(pDrvInfo , CMD_XMOVERELRIGHT ) ) { ERR(("XMoveRelativeRight must exist if *XMoveThreshold is *.\n")) ; bStatus = FALSE ; }
if((pDrvInfo->Globals.dwYMoveThreshold == WILDCARD_VALUE) && !COMMANDPTR(pDrvInfo , CMD_YMOVERELDOWN )) { ERR(("YMoveRelativeDown must exist if *YMoveThreshold is *.\n")) ; bStatus = FALSE ; }
// - CmdSendBlockData must exist if *PrinterType is not TTY.
if((pDrvInfo->Globals.printertype != PT_TTY) && !COMMANDPTR(pDrvInfo , CMD_SENDBLOCKDATA )) { ERR(("*CmdSendBlockData must exist if *PrinterType is not TTY.\n")) ; bStatus = FALSE ; }
//
// - CmdSetFontID, CmdSelectFontID, CmdSetCharCode must be consistent
// in their presence (i.e. all or none). Furthermore, if
// CmdSetFontID/CmdSelectFontID/CmdSetCharCode all exist, then
// *FontFormat must be one of the pre-defined constants.
//
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_SETFONTID ) ) dwI++ ; if(COMMANDPTR(pDrvInfo , CMD_SELECTFONTID ) ) dwI++ ; if(COMMANDPTR(pDrvInfo , CMD_SETCHARCODE ) ) dwI++ ;
if(dwI && dwI != 3) { ERR(("CmdSetFontID, CmdSelectFontID, CmdSetCharCode must be present or absent together.\n")) ; bStatus = FALSE ; }
if((dwI == 3) && (pDrvInfo->Globals.fontformat == UNUSED_ITEM) ) { ERR(("if font cmds exist, then *FontFormat must be defined\n")) ; bStatus = FALSE ; }
// - CmdBoldOn and CmdBoldOff must be paired (i.e. both or none). The
// same goes for:
// CmdItalicOn & CmdItalicOff,
// CmdUnderlineOn & CmdUnderlineOff,
// CmdStrikeThruOn & CmdStrikeThruOff,
// CmdWhiteTextOn & CmdWhiteTextOff,
// CmdSelectSingleByteMode & CmdSelectDoubleByteMode,
// CmdVerticalPrintingOn/CmdVerticalPrintingOff.
//
// - CmdSetRectWidth and CmdSetRectHeight must be paired.
//
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_BOLDON ) ) dwI++ ; if(dwI && (COMMANDPTR(pDrvInfo , CMD_BOLDOFF ) || COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) ) dwI++ ;
if(dwI && dwI != 2) { ERR(("CmdBoldOn and CmdBoldOff must be paired.\n")) ; bStatus = FALSE ; }
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_ITALICON) ) dwI++ ; if(dwI && (COMMANDPTR(pDrvInfo , CMD_ITALICOFF ) || COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) ) dwI++ ;
if(dwI && dwI != 2) { ERR(("CmdItalicOn & CmdItalicOff must be paired.\n")) ; bStatus = FALSE ; }
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_UNDERLINEON ) ) dwI++ ; if(dwI && (COMMANDPTR(pDrvInfo , CMD_UNDERLINEOFF ) || COMMANDPTR(pDrvInfo , CMD_CLEARALLFONTATTRIBS )) ) dwI++ ;
if(dwI && dwI != 2) { ERR(("CmdUnderlineOn & CmdUnderlineOff must be paired.\n")) ; bStatus = FALSE ; }
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_STRIKETHRUON ) ) dwI++ ; if(COMMANDPTR(pDrvInfo , CMD_STRIKETHRUOFF ) ) dwI++ ;
if(dwI && dwI != 2) { ERR(("CmdStrikeThruOn & CmdStrikeThruOff must be paired.\n")) ; bStatus = FALSE ; }
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_WHITETEXTON ) ) dwI++ ; if(COMMANDPTR(pDrvInfo , CMD_WHITETEXTOFF ) ) dwI++ ;
if(dwI && dwI != 2) { ERR(("CmdWhiteTextOn & CmdWhiteTextOff must be paired.\n")) ; bStatus = FALSE ; }
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_SELECTSINGLEBYTEMODE ) ) dwI++ ; if(COMMANDPTR(pDrvInfo , CMD_SELECTDOUBLEBYTEMODE ) ) dwI++ ;
if(dwI && dwI != 2) { ERR(("CmdSelectSingleByteMode & CmdSelectDoubleByteMode must be paired.\n")) ; bStatus = FALSE ; }
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_VERTICALPRINTINGON ) ) dwI++ ; if(COMMANDPTR(pDrvInfo , CMD_VERTICALPRINTINGOFF ) ) dwI++ ;
if(dwI && dwI != 2) { ERR(("CmdVerticalPrintingOn/CmdVerticalPrintingOff must be paired.\n")) ; bStatus = FALSE ; }
dwI = 0 ;
if(COMMANDPTR(pDrvInfo , CMD_SETRECTWIDTH ) ) dwI++ ; if(COMMANDPTR(pDrvInfo , CMD_SETRECTHEIGHT ) ) dwI++ ;
if(dwI && dwI != 2) { ERR(("CmdSetRectWidth and CmdSetRectHeight must be paired.\n")) ; bStatus = FALSE ; }
// Note because this check involves looking at the command table
// which is snapshot specific, we cannot perform this for every
// option as Zhanw requested. Only the current option.
//
// 3. special entries in various types of *Option constructs
//
// - For each ColorMode option whose *DevNumOfPlanes is greater than 1,
// *ColorPlaneOrder cannot be an empty list.
//
// - For each ColorMode option whose *DevNumOfPlanes is greater than 1,
// and *DevBPP is 1, search through its *ColorPlaneOrder list:
// if YELLOW is in the list, then CmdSendYellowData must exist. The
// same goes for other colors: MAGENTA, CYAN, BLACK, RED, GREEN, BLUE.
pUIInfo = GET_UIINFO_FROM_INFOHEADER(pInfoHdr) ;
pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_COLORMODE) ; if(pFeature) { PCOLORMODE pColorMode ; PCOLORMODEEX pCMex ; PLISTNODE pLNode ; DWORD dwOptIndex ;
dwNumOpts = pFeature->Options.dwCount ;
pColorMode = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_COLORMODE ) ) { dwOptIndex = poptsel[dwFeaIndex].ubCurOptIndex ;
pCMex = OFFSET_TO_POINTER(pInfoHdr, pColorMode[dwOptIndex].GenericOption.loRenderOffset) ;
if((pCMex->dwPrinterNumOfPlanes > 1) && (pCMex->liColorPlaneOrder == END_OF_LIST) ) { ERR(("*ColorPlaneOrder must be specified if *DevNumOfPlanes > 1.\n")) ; bStatus = FALSE ; } if((pCMex->dwPrinterNumOfPlanes > 1) && (pCMex->dwPrinterBPP == 1) ) { for(dwListIndex = pCMex->liColorPlaneOrder ; pLNode = LISTNODEPTR(pDrvInfo , dwListIndex ) ; dwListIndex = pLNode->dwNextItem) { switch(pLNode->dwData) { case COLOR_YELLOW: { if(!COMMANDPTR(pDrvInfo , CMD_SENDYELLOWDATA)) { ERR(("*CmdSendYellowData must exist.\n")) ; bStatus = FALSE ; } break ; } case COLOR_MAGENTA: { if(!COMMANDPTR(pDrvInfo , CMD_SENDMAGENTADATA)) { ERR(("*CmdSendMagentaData must exist.\n")) ; bStatus = FALSE ; } break ; } case COLOR_CYAN: { if(!COMMANDPTR(pDrvInfo , CMD_SENDCYANDATA)) { ERR(("*CmdSendCyanData must exist.\n")) ; bStatus = FALSE ; } break ; } case COLOR_BLACK: { if(!COMMANDPTR(pDrvInfo , CMD_SENDBLACKDATA)) { ERR(("*CmdSendBlackData must exist.\n")) ; bStatus = FALSE ; } break ; } case COLOR_RED: { if(!COMMANDPTR(pDrvInfo , CMD_SENDREDDATA)) { ERR(("*CmdSendRedData must exist.\n")) ; bStatus = FALSE ; } break ; } case COLOR_GREEN: { if(!COMMANDPTR(pDrvInfo , CMD_SENDGREENDATA)) { ERR(("*CmdSendGreenData must exist.\n")) ; bStatus = FALSE ; } break ; } case COLOR_BLUE: { if(!COMMANDPTR(pDrvInfo , CMD_SENDBLUEDATA)) { ERR(("*CmdSendBlueData must exist.\n")) ; bStatus = FALSE ; } break ; } default: { ERR(("Unrecogized color.\n")) ; bStatus = FALSE ; break ; } } } } } }
dwResX = dwResY = 1 ; // default in case something goes wrong.
if(BGIDtoFeaIndex(pInfoHdr , &dwFeaIndex , GID_RESOLUTION ) ) { pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_RESOLUTION) ; if(pFeature) { PRESOLUTION pRes ; DWORD dwOptIndex ;
dwOptIndex = poptsel[dwFeaIndex].ubCurOptIndex ; dwNumOpts = pFeature->Options.dwCount ;
pRes = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
for(dwI = 0 ; dwI < dwNumOpts ; dwI++) {
if( pDrvInfo->Globals.ptMasterUnits.x < pRes[dwI].iXdpi ) { ERR(("master units cannot be coarser than x res unit.\n")) ; return FALSE ; // fatal error
} if( pDrvInfo->Globals.ptMasterUnits.x % pRes[dwI].iXdpi ) { ERR(("Must be whole number of master units per x res unit.\n")) ; bStatus = FALSE ; }
if( pDrvInfo->Globals.ptMasterUnits.y < pRes[dwI].iYdpi ) { ERR(("master units cannot be coarser than y res unit.\n")) ; return FALSE ; } if ( pDrvInfo->Globals.ptMasterUnits.y % pRes[dwI].iYdpi ) { ERR(("Must be whole number of master units per y res unit.\n")) ; bStatus = FALSE ; } }
// number of master units per resolution unit.
dwResX = pDrvInfo->Globals.ptMasterUnits.x / pRes[dwOptIndex].iXdpi ; dwResY = pDrvInfo->Globals.ptMasterUnits.y / pRes[dwOptIndex].iYdpi ; } } else { ERR(("Resolution is a required feature.\n")) ; }
//
// - For each non-standard Halftone option, *rcHPPatternID must be
// greater than 0 and *HTPatternSize must be a pair of postive integers.
// NOTE: check with DanielC --- should we enforce that xSize==ySize?
//
// Halftone check is performed in BinitSpecialFeatureOptionFields
// see postproc.c
pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGESIZE) ; if(pFeature) { PPAGESIZE pPagesize ; PPAGESIZEEX pPageSzEx ;
dwNumOpts = pFeature->Options.dwCount ;
pPagesize = OFFSET_TO_POINTER(pInfoHdr, pFeature->Options.loOffset ) ;
for(dwI = 0 ; dwI < dwNumOpts ; dwI++) { if(GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGEPROTECTION) && !pPagesize[dwI].dwPageProtectionMemory) { ERR(("*PageProtectMem must be greater than 0 if PageProtect feature exists.\n")) ; #ifdef STRICT_CHECKS
bStatus = FALSE ; #endif
break ; } pPageSzEx = OFFSET_TO_POINTER(pInfoHdr, pPagesize[dwI].GenericOption.loRenderOffset) ; if(pPagesize[dwI].dwPaperSizeID != DMPAPER_USER) { INT iPDx, iPDy ; // holds page dimensions
// in same coordinate system as ImageableArea
if(pPageSzEx->bRotateSize) { iPDx = (INT)pPagesize[dwI].szPaperSize.cy ; iPDy = (INT)pPagesize[dwI].szPaperSize.cx ; } else { iPDx = (INT)pPagesize[dwI].szPaperSize.cx ; iPDy = (INT)pPagesize[dwI].szPaperSize.cy ; }
if((iPDx <= 0) || (iPDy <= 0)) { ERR(("*PageDimensions is required for non-standard sizes.\n")) ; bStatus = FALSE ; break ; } if(((INT)pPageSzEx->szImageArea.cx <= 0) || ((INT)pPageSzEx->szImageArea.cy <= 0) ) { ERR(("*PrintableArea is required and must be positive.\n")) ; bStatus = FALSE ; break ; } if(((INT)pPageSzEx->ptImageOrigin.x < 0) || ((INT)pPageSzEx->ptImageOrigin.y < 0) )
{ ERR(("*PrintableOrigin is required and cannot be negative.\n")) ; bStatus = FALSE ; break ; }
if((pPageSzEx->szImageArea.cx % dwResX) || (pPageSzEx->szImageArea.cy % dwResY) ) { ERR(("*PrintableArea must be a integral number of ResolutionUnits.\n")) ; #ifdef STRICT_CHECKS
bStatus = FALSE ; #endif
break ; } if((pPageSzEx->ptImageOrigin.x % dwResX) || (pPageSzEx->ptImageOrigin.y % dwResY) ) { ERR(("*PrintableOrigin must be a integral number of ResolutionUnits.\n")) ; #ifdef STRICT_CHECKS
bStatus = FALSE ; #endif
break ; }
if(pDrvInfo->Globals.bRotateCoordinate) { // zhanw assumes printing offset is zero otherwise
if((pPageSzEx->ptImageOrigin.x % dwMoveUnitsX) || (pPageSzEx->ptImageOrigin.y % dwMoveUnitsY) )
{ ERR(("*PrintableOrigin must be a integral number of MoveUnits.\n")) ; #ifdef STRICT_CHECKS
bStatus = FALSE ; #endif
break ; } if((pPageSzEx->ptPrinterCursorOrig.x % dwMoveUnitsX) || (pPageSzEx->ptPrinterCursorOrig.y % dwMoveUnitsY) )
{ ERR(("*CursorOrigin must be a integral number of MoveUnits.\n")) ; #ifdef STRICT_CHECKS
bStatus = FALSE ; #endif
break ; } } else if((pPageSzEx->ptImageOrigin.x != pPageSzEx->ptPrinterCursorOrig.x) || (pPageSzEx->ptImageOrigin.y != pPageSzEx->ptPrinterCursorOrig.y) )
{ ; // this may be unnecessary.
// ERR(("For non-rotating printers, *PrintableOrigin should be same as *CursorOrigin.\n")) ;
}
if((iPDx + iPDx/100 < pPageSzEx->szImageArea.cx + pPageSzEx->ptImageOrigin.x) || (iPDy + iPDy/100 < pPageSzEx->szImageArea.cy + pPageSzEx->ptImageOrigin.y) ) { // I give up to 1 percent leeway
ERR(("*PrintableArea must be contained within *PageDimensions.\n")) ; bStatus = FALSE ; break ; } } else // (dwPaperSizeID == DMPAPER_USER)
{ if(((INT)pPageSzEx->ptMinSize.x <= 0) || ((INT)pPageSzEx->ptMinSize.y <= 0) ) { ERR(("If User Defined papersize exists *MinSize is required and must be positive.\n")) ; #ifdef STRICT_CHECKS
bStatus = FALSE ; #endif
} if(((INT)pPageSzEx->ptMaxSize.x <= 0) || ((INT)pPageSzEx->ptMaxSize.y <= 0) ) { ERR(("If User Defined papersize exists *MaxSize is required and must be positive.\n")) ; bStatus = FALSE ; } if((INT)pPageSzEx->dwMaxPrintableWidth <= 0) { ERR(("If User Defined papersize exists *MaxPrintableWidth is required and must be positive.\n")) ; bStatus = FALSE ; } } } }
// - For each PaperSize option, *PageProtectMem must be greater than 0
// if PageProtect feature exists.
//
// - For all non-CUSTOMSIZE PaperSize options, *PrintableArea and
// *PrintableOrigin must be explicitly defined. Specifically,
// *PrintableArea must be a pair of positive integers, and
// *PrintableOrigin must be a pair of non-negative integers.
// note: BInitSnapshotTable function assigns
// UNUSED_ITEM (-1) as the default value for *PrintableOrigin.
//
// - For CUSTOMSIZE option, *MinSize, *MaxSize, and *MaxPrintableWidth
// must be explicitly defined. Specifically, both *MinSize and *MaxSize
// must be a pair of positive integers. *MaxPrintableWidth must be a
// positive integer.
// BInitSnapshotTable function assigns 0 (instead of NO_LIMIT_NUM)
// as the default value for *MaxPrintableWidth.
//
// - For all non-standard non-CUSTOMSIZE PaperSize options, *PageDimensions
// must be explicitly defined. Specifically, it must be a pair of positive
// integers.
//
// - For any feature or option, if *Installable entry is TRUE, then
// either *InstallableFeatureName or *rcInstallableFeatureNameID must
// be present in that particular feature or option construct.
//
// - If any feature or option has *Installable being TRUE, then
// either *InstalledOptionName/*NotInstalledOptionName or
// *rcInstalledOptionNameID/*rcNotInstalledOptionNameID must be
// defined at the root level.
//
// once synthetic features are created by BCreateSynthFeatures()
// they undergo the same checks at createsnapshot time as
// other features, triggering a warning if the Names of the feature and
// its options are absent.
#if 1
{ DWORD dwNumFea, dwFea, dwNumOpt, dwOpt, dwOptSize ; PENHARRAYREF pearTableContents ; PBYTE pubRaw ; // raw binary data.
PBYTE pubOptions ; // points to start of array of OPTIONS
PFEATURE pFea ; PBYTE pubnRaw ; // Parser's raw binary data.
PSTATICFIELDS pStatic ;
pubnRaw = pInfoHdr->RawData.pvPrivateData ; pStatic = (PSTATICFIELDS)pubnRaw ; // transform pubRaw from PSTATIC
pubRaw = pStatic->pubBUDData ; // to PMINIRAWBINARYDATA
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
dwNumFea = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
pFea = (PFEATURE)((PBYTE)pInfoHdr + pUIInfo->loFeatureList) ;
for(dwFea = 0 ; dwFea < dwNumFea ; dwFea++) { if(!pFea[dwFea].iHelpIndex) { ERR(("*HelpIndex must be positive.\n")) ; bStatus = FALSE ; }
dwNumOpt = pFea[dwFea].Options.dwCount ; pubOptions = (PBYTE)pInfoHdr + pFea[dwFea].Options.loOffset ; dwOptSize = pFea[dwFea].dwOptionSize ;
for(dwOpt = 0 ; dwOpt < dwNumOpt ; dwOpt++) { if(!((POPTION)(pubOptions + dwOptSize * dwOpt))->iHelpIndex ) { ERR(("*HelpIndex must be positive.\n")) ; bStatus = FALSE ; } } } } #else
{ DWORD dwNumFea, dwFea, dwNumOpt, dwOpt; PENHARRAYREF pearTableContents ; PBYTE pubRaw ; // raw binary data.
PBYTE pubOptions ; // points to start of array of OPTIONS
PFEATURE pFea ;
pubRaw = pInfoHdr->RawData.pvPrivateData ;
pearTableContents = (PENHARRAYREF)(pubRaw + sizeof(MINIRAWBINARYDATA)) ;
dwNumFea = pearTableContents[MTI_DFEATURE_OPTIONS].dwCount ;
for(dwFea = 0 ; dwFea < dwNumFea ; dwFea++) { pFea = PGetIndexedFeature(pUIInfo, dwFea) ;
if(!pFea->iHelpIndex) { ERR(("*HelpIndex must be positive.\n")) ; bStatus = FALSE ; }
dwNumOpt = pFea->Options.dwCount ;
for(dwOpt = 0 ; dwOpt < dwNumOpt ; dwOpt++) { pubOptions = PGetIndexedOption(pUIInfo, pFea, dwOpt);
if(!((POPTION)pubOptions))->iHelpIndex ) { ERR(("*HelpIndex must be positive.\n")) ; bStatus = FALSE ; } } } }
#endif
return (bStatus); }
#endif
|