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.
835 lines
28 KiB
835 lines
28 KiB
/*++
|
|
|
|
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;
|
|
}
|
|
|
|
|