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

/*++
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