836 lines
28 KiB
C
836 lines
28 KiB
C
/*++
|
||
|
||
Copyright (c) 1996-1997 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
ppdcheck.c
|
||
|
||
Abstract:
|
||
|
||
PPD parser test program
|
||
|
||
Environment:
|
||
|
||
PostScript driver, PPD parser, Check build only
|
||
|
||
Revision History:
|
||
|
||
09/17/96 -davidx-
|
||
Implement PpdDump.
|
||
|
||
03/27/96 -davidx-
|
||
Created it.
|
||
|
||
--*/
|
||
|
||
#include "lib.h"
|
||
#include "ppd.h"
|
||
|
||
#include "pass2.h"
|
||
|
||
|
||
INT giDebugLevel;
|
||
|
||
|
||
HINSTANCE ghInstance;
|
||
PSTR gstrProgName;
|
||
PRAWBINARYDATA gpRawData;
|
||
PINFOHEADER gpInfoHdr;
|
||
PUIINFO gpUIInfo;
|
||
PPPDDATA gpPpdData;
|
||
DWORD gdwTotalSize, gdwNumFiles, gdwMaxFileSize;
|
||
|
||
extern const CHAR gstrFalseKwd[];
|
||
extern const CHAR gstrNoneKwd[];
|
||
|
||
#define DumpInt(label, n) DbgPrint("%s: %d\n", label, n)
|
||
#define DumpHex(label, n) DbgPrint("%s: 0x%x\n", label, n)
|
||
#define DumpStrW(label, offset) DbgPrint("%s: %ws\n", label, OFFSET_TO_POINTER(gpRawData, offset))
|
||
#define DumpStrA(label, offset) DbgPrint("%s: %s\n", label, OFFSET_TO_POINTER(gpRawData, offset))
|
||
#define DumpFix(label, n) DbgPrint("%s: %f\n", label, (FLOAT) (n) / FIX_24_8_SCALE)
|
||
#define DumpInvo(label, p) DbgPrint("%s: %d bytes\n", label, (p)->dwCount)
|
||
#define DumpSize(label, p) DbgPrint("%s: %d x %d\n", label, (p)->cx, (p)->cy)
|
||
#define DumpRect(label, p) DbgPrint("%s: (%d, %d) - (%d, %d)\n", label, \
|
||
(p)->left, (p)->top, (p)->right, (p)->bottom)
|
||
|
||
|
||
|
||
|
||
VOID
|
||
PpdDump(
|
||
VOID
|
||
)
|
||
|
||
{
|
||
DWORD index, dwFeatures;
|
||
PFEATURE pFeature;
|
||
POPTION pOption;
|
||
LPTSTR ptstrTable;
|
||
PUICONSTRAINT pUIConstraint;
|
||
PORDERDEPEND pOrderDep;
|
||
PFILEDATEINFO pFileDateInfo;
|
||
|
||
DbgPrint("\nRAWBINARYDATA:\n");
|
||
DumpInt (" dwFileSize", gpRawData->dwFileSize);
|
||
DumpHex (" dwParserSignature", gpRawData->dwParserSignature);
|
||
DumpHex (" dwParserVersion", gpRawData->dwParserVersion);
|
||
DumpHex (" dwChecksum32", gpRawData->dwChecksum32);
|
||
DumpInt (" dwDocumentFeatures", gpRawData->dwDocumentFeatures);
|
||
DumpInt (" dwPrinterFeatures", gpRawData->dwPrinterFeatures);
|
||
DumpInt (" Source PPD files", gpRawData->FileDateInfo.dwCount);
|
||
|
||
pFileDateInfo = OFFSET_TO_POINTER(gpRawData, gpRawData->FileDateInfo.loOffset);
|
||
|
||
ASSERT(gpRawData->FileDateInfo.dwCount == 0 || pFileDateInfo != NULL);
|
||
|
||
for (index=0; index < gpRawData->FileDateInfo.dwCount; index++, pFileDateInfo++)
|
||
{
|
||
FILETIME FileTime;
|
||
SYSTEMTIME SystemTime;
|
||
TCHAR TimeDateString[64];
|
||
|
||
DumpStrW(" loFileName", pFileDateInfo->loFileName);
|
||
|
||
FileTimeToLocalFileTime(&pFileDateInfo->FileTime, &FileTime);
|
||
FileTimeToSystemTime(&FileTime, &SystemTime);
|
||
|
||
GetDateFormat(LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, TimeDateString, 64);
|
||
DbgPrint(" FileTime: %ws ", TimeDateString);
|
||
|
||
GetTimeFormat(LOCALE_USER_DEFAULT, 0, &SystemTime, NULL, TimeDateString, 64);
|
||
DbgPrint("%ws\n", TimeDateString);
|
||
}
|
||
|
||
DbgPrint("\nUIINFO:\n");
|
||
DumpInt (" dwSize", gpUIInfo->dwSize);
|
||
DumpStrW(" loNickName", gpUIInfo->loNickName);
|
||
DumpHex (" dwSpecVersion", gpUIInfo->dwSpecVersion);
|
||
DumpHex (" dwTechnology", gpUIInfo->dwTechnology);
|
||
DumpInt (" dwDocumentFeatures", gpUIInfo->dwDocumentFeatures);
|
||
DumpInt (" dwPrinterFeatures", gpUIInfo->dwPrinterFeatures);
|
||
DumpInt (" UIConstraints.dwCount", gpUIInfo->UIConstraints.dwCount);
|
||
DumpInt (" dwMaxCopies", gpUIInfo->dwMaxCopies);
|
||
DumpInt (" dwMinScale", gpUIInfo->dwMinScale);
|
||
DumpInt (" dwMaxScale", gpUIInfo->dwMaxScale);
|
||
DumpInt (" dwLangEncoding", gpUIInfo->dwLangEncoding);
|
||
DumpInt (" dwLangLevel", gpUIInfo->dwLangLevel);
|
||
|
||
if (gpUIInfo->dwLangLevel >= 2 && gpPpdData->dwPSVersion < 2000)
|
||
DbgPrint(" *** Level 2 clone\n");
|
||
|
||
DumpInvo(" Password", &gpUIInfo->Password);
|
||
DumpInvo(" ExitServer", &gpUIInfo->ExitServer);
|
||
DumpHex (" dwProtocols", gpUIInfo->dwProtocols);
|
||
DumpInt (" dwJobTimeout", gpUIInfo->dwJobTimeout);
|
||
DumpInt (" dwWaitTimeout", gpUIInfo->dwWaitTimeout);
|
||
DumpInt (" dwTTRasterizer", gpUIInfo->dwTTRasterizer);
|
||
DumpInt (" dwFreeMem", gpUIInfo->dwFreeMem);
|
||
DumpInt (" dwPrintRate", gpUIInfo->dwPrintRate);
|
||
DumpInt (" dwPrintRateUnit", gpUIInfo->dwPrintRateUnit);
|
||
DumpFix (" fxScreenAngle", gpUIInfo->fxScreenAngle);
|
||
DumpFix (" fxScreenFreq", gpUIInfo->fxScreenFreq);
|
||
DumpHex (" dwFlags", gpUIInfo->dwFlags);
|
||
DumpInt (" dwCustomSizeOptIndex", gpUIInfo->dwCustomSizeOptIndex);
|
||
DumpInt (" ptMasterUnits.x", gpUIInfo->ptMasterUnits.x);
|
||
DumpInt (" ptMasterUnits.y", gpUIInfo->ptMasterUnits.y);
|
||
|
||
dwFeatures = gpUIInfo->dwDocumentFeatures + gpUIInfo->dwPrinterFeatures;
|
||
pFeature = OFFSET_TO_POINTER(gpRawData, gpUIInfo->loFeatureList);
|
||
pUIConstraint = OFFSET_TO_POINTER(gpRawData, gpUIInfo->UIConstraints.loOffset);
|
||
|
||
DbgPrint("\n FEATURES: count = %d\n", dwFeatures);
|
||
|
||
for (index = 0; index < dwFeatures; index++, pFeature++)
|
||
{
|
||
DWORD dwConstIndex, dwFeatureIndex, dwOptionIndex, dwOptionCount;
|
||
PFEATURE pConstFeature;
|
||
POPTION pConstOption;
|
||
|
||
DumpStrA("\n loKeywordName", pFeature->loKeywordName);
|
||
DumpStrW(" loDisplayName", pFeature->loDisplayName);
|
||
DumpHex (" dwFlags", pFeature->dwFlags);
|
||
DumpInt (" dwDefaultOptIndex", pFeature->dwDefaultOptIndex);
|
||
DumpInt (" dwNoneFalseOptIndex", pFeature->dwNoneFalseOptIndex);
|
||
DumpInt (" dwFeatureID", pFeature->dwFeatureID);
|
||
DumpInt (" dwUIType", pFeature->dwUIType);
|
||
DumpInt (" dwPriority", pFeature->dwPriority);
|
||
DumpInt (" dwFeatureType", pFeature->dwFeatureType);
|
||
DumpInt (" dwOptionSize", pFeature->dwOptionSize);
|
||
|
||
if (dwOptionCount = pFeature->Options.dwCount)
|
||
{
|
||
pOption = OFFSET_TO_POINTER(gpRawData, pFeature->Options.loOffset);
|
||
DbgPrint("\n OPTIONS: count = %d\n", dwOptionCount);
|
||
|
||
while (dwOptionCount--)
|
||
{
|
||
DumpStrA("\n loKeywordName", pOption->loKeywordName);
|
||
DumpStrW(" loDisplayName", pOption->loDisplayName);
|
||
DumpInvo(" Invocation", &pOption->Invocation);
|
||
|
||
switch (pFeature->dwFeatureID)
|
||
{
|
||
case GID_PAGESIZE:
|
||
|
||
{ PPAGESIZE pPaper = (PPAGESIZE) pOption;
|
||
|
||
DumpSize(" szPaperSize", &pPaper->szPaperSize);
|
||
DumpRect(" rcImgArea", &pPaper->rcImgArea);
|
||
DumpInt (" dwPaperSizeID", pPaper->dwPaperSizeID);
|
||
DumpHex (" dwFlags", pPaper->dwFlags);
|
||
}
|
||
break;
|
||
|
||
case GID_RESOLUTION:
|
||
|
||
{ PRESOLUTION pRes = (PRESOLUTION) pOption;
|
||
|
||
DumpInt (" iXdpi", pRes->iXdpi);
|
||
DumpInt (" iYdpi", pRes->iYdpi);
|
||
DumpFix (" fxScreenAngle", pRes->fxScreenAngle);
|
||
DumpFix (" fxScreenFreq", pRes->fxScreenFreq);
|
||
}
|
||
break;
|
||
|
||
case GID_DUPLEX:
|
||
|
||
DumpInt (" dwDuplexID", ((PDUPLEX) pOption)->dwDuplexID);
|
||
break;
|
||
|
||
case GID_COLLATE:
|
||
|
||
DumpInt (" dwCollateID", ((PCOLLATE) pOption)->dwCollateID);
|
||
break;
|
||
|
||
case GID_MEDIATYPE:
|
||
|
||
DumpInt (" dwMediaTypeID", ((PMEDIATYPE) pOption)->dwMediaTypeID);
|
||
break;
|
||
|
||
case GID_OUTPUTBIN:
|
||
|
||
DumpInt (" bOutputOrderReversed", ((POUTPUTBIN) pOption)->bOutputOrderReversed);
|
||
break;
|
||
|
||
case GID_INPUTSLOT:
|
||
|
||
{ PINPUTSLOT pTray = (PINPUTSLOT) pOption;
|
||
|
||
DumpHex (" dwFlags", pTray->dwFlags);
|
||
DumpInt (" dwPaperSourceID", pTray->dwPaperSourceID);
|
||
}
|
||
break;
|
||
|
||
case GID_MEMOPTION:
|
||
|
||
{ PMEMOPTION pMemOption = (PMEMOPTION) pOption;
|
||
|
||
DumpInt (" dwInstalledMem", pMemOption->dwInstalledMem);
|
||
DumpInt (" dwFreeMem", pMemOption->dwFreeMem);
|
||
DumpInt (" dwFreeFontMem", pMemOption->dwFreeFontMem);
|
||
}
|
||
break;
|
||
}
|
||
|
||
if ((dwConstIndex = pOption->dwUIConstraintList) != NULL_CONSTRAINT)
|
||
{
|
||
ASSERT(pUIConstraint != NULL);
|
||
DbgPrint("\n UICONSTRAINTS:\n");
|
||
|
||
while (dwConstIndex != NULL_CONSTRAINT)
|
||
{
|
||
ASSERT(dwConstIndex < gpUIInfo->UIConstraints.dwCount);
|
||
|
||
dwFeatureIndex = pUIConstraint[dwConstIndex].dwFeatureIndex;
|
||
dwOptionIndex = pUIConstraint[dwConstIndex].dwOptionIndex;
|
||
dwConstIndex = pUIConstraint[dwConstIndex].dwNextConstraint;
|
||
|
||
ASSERT(dwFeatureIndex < dwFeatures);
|
||
pConstFeature = PGetIndexedFeature(gpUIInfo, dwFeatureIndex);
|
||
DbgPrint(" %s", OFFSET_TO_POINTER(gpRawData, pConstFeature->loKeywordName));
|
||
|
||
if (dwOptionIndex != OPTION_INDEX_ANY)
|
||
{
|
||
ASSERT(dwOptionIndex < pConstFeature->Options.dwCount);
|
||
pConstOption = PGetIndexedOption(gpUIInfo, pConstFeature, dwOptionIndex);
|
||
DbgPrint(" %s", OFFSET_TO_POINTER(gpRawData, pConstOption->loKeywordName));
|
||
}
|
||
|
||
DbgPrint("\n");
|
||
}
|
||
}
|
||
|
||
pOption = (POPTION) ((PBYTE) pOption + pFeature->dwOptionSize);
|
||
}
|
||
}
|
||
|
||
if ((dwConstIndex = pFeature->dwUIConstraintList) != NULL_CONSTRAINT)
|
||
{
|
||
ASSERT(pUIConstraint != NULL);
|
||
DbgPrint("\n UICONSTRAINTS:\n");
|
||
|
||
while (dwConstIndex != NULL_CONSTRAINT)
|
||
{
|
||
ASSERT(dwConstIndex < gpUIInfo->UIConstraints.dwCount);
|
||
|
||
dwFeatureIndex = pUIConstraint[dwConstIndex].dwFeatureIndex;
|
||
dwOptionIndex = pUIConstraint[dwConstIndex].dwOptionIndex;
|
||
dwConstIndex = pUIConstraint[dwConstIndex].dwNextConstraint;
|
||
|
||
ASSERT(dwFeatureIndex < dwFeatures);
|
||
pConstFeature = PGetIndexedFeature(gpUIInfo, dwFeatureIndex);
|
||
DbgPrint(" %s", OFFSET_TO_POINTER(gpRawData, pConstFeature->loKeywordName));
|
||
|
||
if (dwOptionIndex != OPTION_INDEX_ANY)
|
||
{
|
||
ASSERT(dwOptionIndex < pConstFeature->Options.dwCount);
|
||
pConstOption = PGetIndexedOption(gpUIInfo, pConstFeature, dwOptionIndex);
|
||
|
||
DbgPrint(" %s", OFFSET_TO_POINTER(gpRawData, pConstOption->loKeywordName));
|
||
}
|
||
|
||
DbgPrint("\n");
|
||
}
|
||
}
|
||
}
|
||
|
||
DbgPrint("\n PREDEFINED FEATURES:\n");
|
||
|
||
for (index = 0; index < MAX_GID; index++)
|
||
{
|
||
if (pFeature = GET_PREDEFINED_FEATURE(gpUIInfo, index))
|
||
DbgPrint(" %s\n", OFFSET_TO_POINTER(gpRawData, pFeature->loKeywordName));
|
||
}
|
||
|
||
DbgPrint("\n DEFAULT FONT SUBSTITUTION TABLE: %d bytes\n", gpUIInfo->dwFontSubCount);
|
||
|
||
ptstrTable = OFFSET_TO_POINTER(gpRawData, gpUIInfo->loFontSubstTable);
|
||
|
||
if (ptstrTable) {
|
||
|
||
while (*ptstrTable) {
|
||
|
||
DbgPrint(" %ws => ", ptstrTable);
|
||
ptstrTable += _tcslen(ptstrTable) + 1;
|
||
DbgPrint("%ws\n", ptstrTable);
|
||
ptstrTable += _tcslen(ptstrTable) + 1;
|
||
}
|
||
}
|
||
|
||
DbgPrint("\nPPDDATA:\n");
|
||
|
||
#ifndef WINNT_40
|
||
DumpHex (" GetUserDefaultUILanguage() returns", GetUserDefaultUILanguage());
|
||
#endif
|
||
|
||
DumpHex (" dwUserDefUILangID", gpPpdData->dwUserDefUILangID);
|
||
DumpHex (" dwPpdFilever", gpPpdData->dwPpdFilever);
|
||
DumpHex (" dwFlags", gpPpdData->dwFlags);
|
||
DumpHex (" dwExtensions", gpPpdData->dwExtensions);
|
||
DumpInt (" dwSetResType", gpPpdData->dwSetResType);
|
||
DumpInt (" dwPSVersion", gpPpdData->dwPSVersion);
|
||
DumpInvo(" PSVersion", &gpPpdData->PSVersion);
|
||
DumpInvo(" Product", &gpPpdData->Product);
|
||
|
||
DumpHex (" dwOutputOrderIndex", gpPpdData->dwOutputOrderIndex);
|
||
DumpHex (" dwCustomSizeFlags", gpPpdData->dwCustomSizeFlags);
|
||
DumpInt (" dwLeadingEdgeLong", gpPpdData->dwLeadingEdgeLong);
|
||
DumpInt (" dwLeadingEdgeShort", gpPpdData->dwLeadingEdgeShort);
|
||
DumpInt (" dwUseHWMarginsTrue", gpPpdData->dwUseHWMarginsTrue);
|
||
DumpInt (" dwUseHWMarginsFalse", gpPpdData->dwUseHWMarginsFalse);
|
||
|
||
for (index = 0; index < CUSTOMPARAM_MAX; index++)
|
||
{
|
||
DbgPrint(" param %d: dwOrder = %d, lMinVal = %d, lMaxVal = %d\n", index,
|
||
gpPpdData->CustomSizeParams[index].dwOrder,
|
||
gpPpdData->CustomSizeParams[index].lMinVal,
|
||
gpPpdData->CustomSizeParams[index].lMaxVal);
|
||
}
|
||
|
||
DumpInvo(" PatchFile", &gpPpdData->PatchFile);
|
||
DumpInvo(" JclBegin", &gpPpdData->JclBegin);
|
||
DumpInvo(" JclEnterPS", &gpPpdData->JclEnterPS);
|
||
DumpInvo(" JclEnd", &gpPpdData->JclEnd);
|
||
DumpInvo(" ManualFeedFalse", &gpPpdData->ManualFeedFalse);
|
||
|
||
DumpHex (" dwNt4Checksum", gpPpdData->dwNt4Checksum);
|
||
DumpInt (" dwNt4DocFeatures", gpPpdData->dwNt4DocFeatures);
|
||
DumpInt (" dwNt4PrnFeatures", gpPpdData->dwNt4PrnFeatures);
|
||
|
||
if (gpPpdData->Nt4Mapping.dwCount)
|
||
{
|
||
PBYTE pubNt4Mapping;
|
||
|
||
pubNt4Mapping = OFFSET_TO_POINTER(gpRawData, gpPpdData->Nt4Mapping.loOffset);
|
||
|
||
ASSERT(pubNt4Mapping != NULL);
|
||
|
||
for (index=0; index < gpPpdData->Nt4Mapping.dwCount; index++)
|
||
DbgPrint(" %2d => %d\n", index, pubNt4Mapping[index]);
|
||
}
|
||
|
||
if (gpPpdData->DeviceFonts.dwCount)
|
||
{
|
||
PDEVFONT pDevFont;
|
||
|
||
DbgPrint("\n DEVICE FONTS:\n");
|
||
|
||
if (pDevFont = OFFSET_TO_POINTER(gpRawData, gpPpdData->loDefaultFont))
|
||
DumpStrA(" default", pDevFont->loFontName);
|
||
|
||
pDevFont = OFFSET_TO_POINTER(gpRawData, gpPpdData->DeviceFonts.loOffset);
|
||
|
||
for (index = 0; index < gpPpdData->DeviceFonts.dwCount; index++, pDevFont++)
|
||
{
|
||
DumpStrA("\n loFontName", pDevFont->loFontName);
|
||
DumpStrW(" loDisplayName", pDevFont->loDisplayName);
|
||
DumpStrA(" loEncoding", pDevFont->loEncoding);
|
||
DumpStrA(" loCharset", pDevFont->loCharset);
|
||
DumpStrA(" loVersion", pDevFont->loVersion);
|
||
DumpInt (" dwStatus", pDevFont->dwStatus);
|
||
}
|
||
}
|
||
|
||
if (gpPpdData->OrderDeps.dwCount)
|
||
{
|
||
pOrderDep = OFFSET_TO_POINTER(gpRawData, gpPpdData->OrderDeps.loOffset);
|
||
ASSERT(pOrderDep != NULL);
|
||
|
||
DbgPrint("\n ORDER DEPENDENCIES:\n");
|
||
|
||
for (index=0; index < gpPpdData->OrderDeps.dwCount; index++, pOrderDep++)
|
||
{
|
||
DbgPrint(" %d: order = %d section = 0x%x (in PPD: 0x%x) ",
|
||
index, pOrderDep->lOrder, pOrderDep->dwSection, pOrderDep->dwPPDSection);
|
||
|
||
pFeature = PGetIndexedFeature(gpUIInfo, pOrderDep->dwFeatureIndex);
|
||
ASSERT(pFeature != NULL);
|
||
DbgPrint("%s", OFFSET_TO_POINTER(gpRawData, pFeature->loKeywordName));
|
||
|
||
if (pOrderDep->dwOptionIndex != OPTION_INDEX_ANY)
|
||
{
|
||
pOption = PGetIndexedOption(gpUIInfo, pFeature, pOrderDep->dwOptionIndex);
|
||
ASSERT(pOption != NULL);
|
||
DbgPrint(" %s", OFFSET_TO_POINTER(gpRawData, pOption->loKeywordName));
|
||
}
|
||
|
||
DbgPrint(", next = %d\n", pOrderDep->dwNextOrderDep);
|
||
}
|
||
}
|
||
|
||
if (gpPpdData->QueryOrderDeps.dwCount)
|
||
{
|
||
pOrderDep = OFFSET_TO_POINTER(gpRawData, gpPpdData->QueryOrderDeps.loOffset);
|
||
ASSERT(pOrderDep != NULL);
|
||
|
||
DbgPrint("\n QUERY ORDER DEPENDENCIES:\n");
|
||
|
||
for (index=0; index < gpPpdData->QueryOrderDeps.dwCount; index++, pOrderDep++)
|
||
{
|
||
DbgPrint(" %d: order = %d section = 0x%x (in PPD: 0x%x) ",
|
||
index, pOrderDep->lOrder, pOrderDep->dwSection, pOrderDep->dwPPDSection);
|
||
|
||
pFeature = PGetIndexedFeature(gpUIInfo, pOrderDep->dwFeatureIndex);
|
||
ASSERT(pFeature != NULL);
|
||
DbgPrint("%s", OFFSET_TO_POINTER(gpRawData, pFeature->loKeywordName));
|
||
|
||
if (pOrderDep->dwOptionIndex != OPTION_INDEX_ANY)
|
||
{
|
||
pOption = PGetIndexedOption(gpUIInfo, pFeature, pOrderDep->dwOptionIndex);
|
||
ASSERT(pOption != NULL);
|
||
DbgPrint(" %s", OFFSET_TO_POINTER(gpRawData, pOption->loKeywordName));
|
||
}
|
||
|
||
DbgPrint(", next = %d\n", pOrderDep->dwNextOrderDep);
|
||
}
|
||
}
|
||
|
||
if (gpPpdData->JobPatchFiles.dwCount)
|
||
{
|
||
PJOBPATCHFILE pJobPatchFiles;
|
||
|
||
pJobPatchFiles = OFFSET_TO_POINTER(gpRawData, gpPpdData->JobPatchFiles.loOffset);
|
||
ASSERT(pJobPatchFiles);
|
||
|
||
DbgPrint("\n JOB PATCH FILES:\n");
|
||
|
||
for (index = 0; index < gpPpdData->JobPatchFiles.dwCount; index++, pJobPatchFiles++)
|
||
{
|
||
DbgPrint(" %2d No %li", index, pJobPatchFiles->lJobPatchNo);
|
||
DbgPrint(": '%s'\n", OFFSET_TO_POINTER(gpRawData, pJobPatchFiles->loOffset));
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
DumpNt4Mapping(
|
||
VOID
|
||
)
|
||
|
||
{
|
||
PFEATURE pFeatures;
|
||
PBYTE pubNt4Mapping;
|
||
DWORD iNt4, iNt5, cNt4, cNt5;
|
||
PSTR pName;
|
||
|
||
DbgPrint("checksum: 0x%x\n", gpPpdData->dwNt4Checksum);
|
||
DbgPrint("number of doc-sticky features: %d\n", gpPpdData->dwNt4DocFeatures);
|
||
DbgPrint("number of printer-sticky features: %d\n", gpPpdData->dwNt4PrnFeatures);
|
||
|
||
pubNt4Mapping = OFFSET_TO_POINTER(gpRawData, gpPpdData->Nt4Mapping.loOffset);
|
||
pFeatures = OFFSET_TO_POINTER(gpRawData, gpUIInfo->loFeatureList);
|
||
|
||
ASSERT(pubNt4Mapping != NULL);
|
||
|
||
cNt4 = gpPpdData->dwNt4DocFeatures + gpPpdData->dwNt4PrnFeatures;
|
||
cNt5 = gpPpdData->Nt4Mapping.dwCount;
|
||
|
||
ASSERT(cNt5 == 0 || pFeatures != NULL);
|
||
|
||
for (iNt4=0; iNt4 < cNt4; iNt4++)
|
||
{
|
||
for (iNt5=0; iNt5 < cNt5; iNt5++)
|
||
{
|
||
if (pubNt4Mapping[iNt5] == iNt4)
|
||
{
|
||
pName = OFFSET_TO_POINTER(gpRawData, pFeatures[iNt5].loKeywordName);
|
||
|
||
ASSERT(pName != NULL);
|
||
|
||
if (strcmp(pName, "JCLResolution") == EQUAL_STRING ||
|
||
strcmp(pName, "SetResolution") == EQUAL_STRING)
|
||
{
|
||
pName = "Resolution";
|
||
}
|
||
|
||
DbgPrint(" %2d: %s\n", pubNt4Mapping[iNt5], pName);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
ULONG _cdecl
|
||
DbgPrint(
|
||
PCSTR pstrFormat,
|
||
...
|
||
)
|
||
|
||
{
|
||
va_list ap;
|
||
|
||
va_start(ap, pstrFormat);
|
||
vprintf(pstrFormat, ap);
|
||
va_end(ap);
|
||
|
||
return 0;
|
||
}
|
||
|
||
typedef enum {
|
||
Free,
|
||
InBracket,
|
||
InHexDigitOdd,
|
||
InHexDigitEven
|
||
} eInvState;
|
||
|
||
static void CheckInvocationValue(POPTION pOption, LPSTR pstrFeatureName)
|
||
{
|
||
eInvState State = Free;
|
||
DWORD i;
|
||
LPSTR pInv = OFFSET_TO_POINTER(gpRawData, pOption->Invocation.loOffset);
|
||
|
||
ASSERT(pOption->Invocation.dwCount == 0 || pInv != NULL);
|
||
|
||
for (i=0; i< pOption->Invocation.dwCount; i++)
|
||
{
|
||
switch (State)
|
||
{
|
||
case Free:
|
||
if (*(pInv + i) == '<')
|
||
State = InBracket;
|
||
break;
|
||
case InBracket:
|
||
if (isxdigit(*(pInv + i)))
|
||
State = InHexDigitOdd;
|
||
else
|
||
State = Free;
|
||
break;
|
||
case InHexDigitOdd:
|
||
if (isxdigit(*(pInv + i)))
|
||
State = InHexDigitEven;
|
||
else
|
||
State = Free;
|
||
break;
|
||
case InHexDigitEven:
|
||
if (isxdigit(*(pInv + i)))
|
||
State = InHexDigitOdd;
|
||
else if (*(pInv + i) == '>')
|
||
{
|
||
LPSTR pstrOptionName = OFFSET_TO_POINTER(gpRawData, pOption->loKeywordName);
|
||
DbgPrint("Warning: invocation value of feature '%s', option '%s' contains hex digits\n - possibly forgotten to use 'JCL' as start of keyword ?\n",
|
||
pstrFeatureName, pstrOptionName);
|
||
return;
|
||
}
|
||
else
|
||
State = Free;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
PpdVerify(
|
||
VOID
|
||
)
|
||
|
||
{
|
||
DWORD index, dwFeatures;
|
||
PFEATURE pFeature;
|
||
POPTION pOption;
|
||
PSTR pstrFeatureName, pstrOptionName;
|
||
BOOL bNoneOption, bFalseOption;
|
||
PUICONSTRAINT pConstraint;
|
||
DWORD NoOfConstraints = gpUIInfo->UIConstraints.dwCount;
|
||
|
||
|
||
dwFeatures = gpUIInfo->dwDocumentFeatures + gpUIInfo->dwPrinterFeatures;
|
||
pFeature = OFFSET_TO_POINTER(gpRawData, gpUIInfo->loFeatureList);
|
||
pConstraint = OFFSET_TO_POINTER(gpRawData, gpUIInfo->UIConstraints.loOffset);
|
||
|
||
ASSERT(dwFeatures == 0 || pFeature != NULL);
|
||
|
||
for (index = 0; index < dwFeatures; index++, pFeature++)
|
||
{
|
||
DWORD dwOptionCount, dwOptionIndex = 0;
|
||
|
||
pstrFeatureName = OFFSET_TO_POINTER(gpRawData, pFeature->loKeywordName);
|
||
|
||
if (dwOptionCount = pFeature->Options.dwCount)
|
||
{
|
||
pOption = OFFSET_TO_POINTER(gpRawData, pFeature->Options.loOffset);
|
||
bNoneOption = bFalseOption = FALSE;
|
||
|
||
ASSERT(dwOptionCount == 0 || pOption != NULL);
|
||
|
||
while (dwOptionCount--)
|
||
{
|
||
pstrOptionName = OFFSET_TO_POINTER(gpRawData, pOption->loKeywordName);
|
||
|
||
ASSERT(pstrOptionName);
|
||
|
||
if (!strcmp(pstrOptionName, gstrNoneKwd))
|
||
bNoneOption = TRUE;
|
||
else if (!strcmp(pstrOptionName, gstrFalseKwd))
|
||
bFalseOption = TRUE;
|
||
|
||
if (giDebugLevel <= 2)
|
||
{
|
||
CheckInvocationValue(pOption, pstrFeatureName);
|
||
|
||
//
|
||
// check self constraining constraints
|
||
//
|
||
if (pOption->dwUIConstraintList != NULL_CONSTRAINT)
|
||
{
|
||
DWORD dwConstIndex = pOption->dwUIConstraintList;
|
||
do
|
||
{
|
||
if ((pConstraint[dwConstIndex].dwFeatureIndex == index) &&
|
||
((pConstraint[dwConstIndex].dwOptionIndex == dwOptionIndex) ||
|
||
(pConstraint[dwConstIndex].dwOptionIndex == OPTION_INDEX_ANY)))
|
||
DbgPrint("Warning : self constraining constraint found for feature '%s', Option '%s'\n", pstrFeatureName, pstrOptionName);
|
||
dwConstIndex = pConstraint[dwConstIndex].dwNextConstraint;
|
||
} while (dwConstIndex != NULL_CONSTRAINT);
|
||
}
|
||
}
|
||
pOption = (POPTION) ((PBYTE) pOption + pFeature->dwOptionSize);
|
||
dwOptionIndex++;
|
||
}
|
||
|
||
if (bNoneOption && bFalseOption)
|
||
DbgPrint("Error: Feature '%s' has both None and False options!\n",pstrFeatureName);
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
usage(
|
||
VOID
|
||
)
|
||
|
||
{
|
||
DbgPrint("usage: %s [-options] filenames ...\n", gstrProgName);
|
||
DbgPrint("where options are:\n");
|
||
DbgPrint(" -b attempt to read cached binary PPD data first\n");
|
||
DbgPrint(" -k keep the binary PPD data\n");
|
||
DbgPrint(" -wN set warning level to N\n");
|
||
DbgPrint(" -h display help information\n");
|
||
exit(-1);
|
||
}
|
||
|
||
|
||
INT _cdecl
|
||
main(
|
||
INT argc,
|
||
CHAR **argv
|
||
)
|
||
|
||
{
|
||
BOOL bUseCache, bKeepBPD;
|
||
DWORD dwTime;
|
||
|
||
//
|
||
// Go through the command line arguments
|
||
//
|
||
|
||
ghInstance = GetModuleHandle(NULL);
|
||
bUseCache = bKeepBPD = FALSE;
|
||
giDebugLevel = DBG_TERSE;
|
||
gdwTotalSize = gdwNumFiles = gdwMaxFileSize;
|
||
|
||
gstrProgName = *argv++;
|
||
argc--;
|
||
|
||
if (argc == 0)
|
||
usage();
|
||
|
||
dwTime = GetTickCount();
|
||
|
||
for ( ; argc--; argv++)
|
||
{
|
||
PSTR pArg = *argv;
|
||
|
||
if (*pArg == '-' || *pArg == '/')
|
||
{
|
||
//
|
||
// The argument is an option flag
|
||
//
|
||
|
||
switch (*++pArg) {
|
||
|
||
case 'b':
|
||
case 'B':
|
||
|
||
bUseCache = bKeepBPD = TRUE;
|
||
break;
|
||
|
||
case 'k':
|
||
case 'K':
|
||
|
||
bKeepBPD = TRUE;
|
||
break;
|
||
|
||
case 'w':
|
||
case 'W':
|
||
|
||
if (*++pArg >= '0' && *pArg <= '9')
|
||
{
|
||
giDebugLevel = *pArg - '0';
|
||
break;
|
||
}
|
||
|
||
default:
|
||
|
||
usage();
|
||
break;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
WCHAR wstrFilename[MAX_PATH];
|
||
PTSTR ptstrBpdFilename;
|
||
|
||
//
|
||
// Convert ANSI filename to Unicode filename
|
||
//
|
||
|
||
MultiByteToWideChar(CP_ACP, 0, pArg, -1, wstrFilename, MAX_PATH);
|
||
|
||
TERSE(("\n*** %ws\n", wstrFilename));
|
||
|
||
//
|
||
// If -b option is given, try to read cached binary data first
|
||
//
|
||
|
||
if (bUseCache)
|
||
gpRawData = PpdLoadCachedBinaryData(wstrFilename);
|
||
else
|
||
{
|
||
gpRawData = PpdParseTextFile(wstrFilename);
|
||
if (giDebugLevel <= 2)
|
||
CheckOptionIntegrity(wstrFilename);
|
||
}
|
||
|
||
if (gpRawData)
|
||
{
|
||
gpInfoHdr = (PINFOHEADER) gpRawData;
|
||
gpUIInfo = (PUIINFO) ((PBYTE) gpInfoHdr + gpInfoHdr->loUIInfoOffset);
|
||
gpPpdData = (PPPDDATA) ((PBYTE) gpInfoHdr + gpInfoHdr->loDriverOffset);
|
||
gpUIInfo->pInfoHeader = gpInfoHdr;
|
||
|
||
if (giDebugLevel == 8)
|
||
{
|
||
DbgPrint("*** PPD file: %s\n", StripDirPrefixA(pArg));
|
||
|
||
DumpNt4Mapping();
|
||
}
|
||
else if (giDebugLevel == 9)
|
||
PpdDump();
|
||
|
||
//
|
||
// extra error checking
|
||
//
|
||
|
||
PpdVerify();
|
||
|
||
gdwTotalSize += gpRawData->dwFileSize;
|
||
gdwNumFiles++;
|
||
|
||
if (gpRawData->dwFileSize > gdwMaxFileSize)
|
||
gdwMaxFileSize = gpRawData->dwFileSize;
|
||
|
||
MemFree(gpRawData);
|
||
|
||
//
|
||
// If -k option is not given, get rid of the BPD file after we're done
|
||
//
|
||
|
||
if (! bKeepBPD && (ptstrBpdFilename = GenerateBpdFilename(wstrFilename)))
|
||
{
|
||
DeleteFile(ptstrBpdFilename);
|
||
MemFree(ptstrBpdFilename);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#ifdef COLLECT_STATS
|
||
|
||
if (gdwNumFiles > 0)
|
||
{
|
||
dwTime = GetTickCount() - dwTime;
|
||
|
||
TERSE(("Number of files parsed: %d\n", gdwNumFiles));
|
||
TERSE(("Average binary file size: %d\n", gdwTotalSize / gdwNumFiles));
|
||
TERSE(("Maximum binary file size: %d\n", gdwMaxFileSize));
|
||
TERSE(("Average parsing time per file (ms): %d\n", dwTime / gdwNumFiles));
|
||
}
|
||
|
||
#endif // COLLECT_STATS
|
||
|
||
return 0;
|
||
}
|
||
|
||
|