Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

959 lines
21 KiB

/*
Copyright (c) 1992 Microsoft Corporation
Module Name:
pststjob.c
Abstract:
Author:
James Bratsanos <[email protected] or mcrafts!jamesb>
Revision History:
25 Feb 1993 Initial Version
Notes: Tab stop: 4
--*/
#include <windows.h>
#include <stdio.h>
#include "..\..\lib\psdiblib.h"
#include "..\..\..\ti\psglobal\pstodib.h"
#include "..\pstest\pststsh.h"
#include "pststexe.h"
#include "pststlib.h"
#include "tstkeys.h"
#include <string.h>
#define INCLUDE_PROFILE_CALLS
typedef struct {
LPTSTR lpOutputError;
DWORD dwPsError;
} PS_TRANSLATE_ERRORCODES;
PS_TRANSLATE_ERRORCODES adwTranslate[] = {
"Access violation during init",
PSERR_INTERPRETER_INIT_ACCESS_VIOLATION,
"Access violation during job execution",
PSERR_INTERPRETER_JOB_ACCESS_VIOLATION,
"String sequence error, during error caching",
PSERR_LOG_ERROR_STRING_OUT_OF_SEQUENCE,
"Memory allocation failure for Frame buffer",
PSERR_FRAME_BUFFER_MEM_ALLOC_FAILED,
"Font query problem failure",
PSERR_FONT_QUERY_PROBLEM,
"Exceeded internal font limit",
PSERR_EXCEEDED_INTERNAL_FONT_LIMIT
};
#define MAX_PELS_PER_LINE 2300
#define MAX_LINES 3000
#define FUDGE_STRIP 100
DWORD ComputeChecksum(LPBYTE pData,DWORD InitialChecksum,DWORD DataSize)
{
W2B w2b;
WORD OctetR;
WORD OctetS;
//
// We using two 16-bit checksum octets with one's complement arithmic
//
//
// 1. Get initial values for OctetR and OctetS
//
OctetR = HIWORD(InitialChecksum);
OctetS = LOWORD(InitialChecksum);
//
// 2. Since we doing 16-bit at a time, we will pack high byte with zero
// if data size in bytes is odd number
//
if (DataSize & 0x01) {
OctetR += (OctetS += (WORD)*pData++);
}
//
// 3. Now forming checksum 16-bit at a time
//
DataSize >>= 1;
while (DataSize--) {
w2b.b[0] = *pData++;
w2b.b[1] = *pData++;
OctetR += (OctetS += w2b.w);
}
return((DWORD)((DWORD)OctetR << 16) | (DWORD)OctetS);
}
DWORD LocGenCheckSum( PPSEVENT_PAGE_READY_STRUCT ppsPageReady )
{
DWORD dwRetVal = 0;
DWORD dwBytes;
LPDWORD lpdw;
dwBytes = ppsPageReady->dwWide / 8 * ppsPageReady->dwHigh;
return(ComputeChecksum( (LPBYTE) ppsPageReady->lpBuf, 0L, dwBytes));
}
VOID PsLogFilePrintf( HANDLE hHandle, DWORD dwClass, LPCTSTR lpFormat , ... )
{
DWORD dwNumWritten;
TCHAR sztBuff[500];
LPTSTR lpNextPos;
LPTSTR lpClass;
va_list marker;
lpNextPos = sztBuff;
switch (dwClass) {
case ERROR_CLASS_HEADER:
lpClass = TEXT("\nHEADER:::");
break;
case ERROR_CLASS_INFO:
lpClass = TEXT("\n INFO:::");
break;
case ERROR_CLASS_ERROR:
lpClass = TEXT("\n ERROR:::");
break;
case ERROR_CLASS_WARNING:
lpClass = TEXT("\n WARNING:::");
break;
case ERROR_CLASS_NONE:
lpClass = TEXT("\n ");
break ;
default:
lpClass = TEXT("\n???? Invalid Class passed to PsLogFilePrintf???");
break;
}
WriteFile( hHandle,
(LPVOID) lpClass,
lstrlen(lpClass) * sizeof(TCHAR),
&dwNumWritten,
(LPOVERLAPPED) NULL );
va_start( marker, lpFormat );
wvsprintf( lpNextPos, lpFormat, marker );
va_end( marker );
WriteFile( hHandle,
(LPVOID) sztBuff,
lstrlen( sztBuff ) * sizeof(TCHAR),
&dwNumWritten,
(LPOVERLAPPED) NULL );
}
void LJReset(FILE *chan)
{
fprintf(chan, "\x1b%c",'E'); // reset printer
}
void LJHeader(FILE *chan)
{
// spew out the stuff for initing the laser jet
LJReset(chan);
fprintf(chan, "\x01b*t300R"); // 300 dpi
fprintf(chan, "\x01b*p0x0Y"); // position is 0,0
}
void LJGraphicsStart(FILE *chan, unsigned int cnt)
{
fprintf(chan, "\x1b*b%dW", cnt);
}
void LJGraphicsEnd(FILE *chan)
{
fprintf(chan, "\x01b*rB");
}
void LJGraphicsLineOut(FILE *chan,
unsigned int line_num,
unsigned char *line_buf,
unsigned int BytesPerLine)
{
unsigned int start, end, len;
unsigned char *s, *e;
// find the first black byte
for (s = line_buf, start = 0; start < BytesPerLine ; start++, s++ ) {
if (*s) {
break;
}
}
if (start == BytesPerLine) {
return; // nothing to do
}
// find the last black byte
for (e = line_buf + BytesPerLine - 1, end = BytesPerLine ;
end ; end--, e--) {
if (*e) {
break;
}
}
len = end - start;
// output cursor position and then line
fprintf(chan, "\x1b*p%dY", line_num);
fprintf(chan, "\x1b*p%dX", start * 8);
fprintf(chan, "\x01b*r1A"); // graphics left marg is current x
LJGraphicsStart(chan, len);
fwrite(s, sizeof(char), len, chan);
LJGraphicsEnd(chan);
}
void LJPageFormFeed( FILE *fout )
{
fprintf(fout, "\x12"); // page feed
}
void LJWriteCaseName( FILE *fout, LPSTR lpStr )
{
fprintf(fout, "\x1b*p%dY", 0);
fprintf(fout, "\x1b*p%dX", 300);
fprintf(fout, "PSTODIB - TST case: %s",lpStr);
}
void LJOutputFrameBuffer( FILE *chan, PPSEVENT_PAGE_READY_STRUCT ppsPageReady,LPTSTR lpFileName )
{
DWORD dwBytesPerLine;
DWORD dwBytesToRead;
DWORD dwlines_to_strip;
LPSTR lpPtr;
DWORD dwHigh;
DWORD dwWide;
DWORD dwlinecnt;
dwBytesPerLine = (unsigned int) ppsPageReady->dwWide / 8;
dwBytesToRead = dwBytesPerLine;
dwlines_to_strip = 0;
lpPtr = ppsPageReady->lpBuf + ( dwBytesPerLine * (ppsPageReady->dwHigh-1)) ;
if (ppsPageReady->dwWide > MAX_PELS_PER_LINE) {
// error conditions
dwWide = MAX_PELS_PER_LINE;
dwBytesPerLine = (unsigned int)(ppsPageReady->dwWide) / 8;
}else{
dwWide = ppsPageReady->dwWide;
}
if (ppsPageReady->dwHigh > MAX_LINES) {
// max
dwlines_to_strip = ppsPageReady->dwHigh - MAX_LINES;
dwlines_to_strip += FUDGE_STRIP;
dwHigh = MAX_LINES;
} else {
dwHigh = ppsPageReady->dwHigh;
}
// spit out the laserjet header stuff
LJHeader(chan);
// got the header... transfer the data
dwlinecnt = 0;
while (1) {
// first read the line in
if (dwlinecnt > dwHigh) {
break;
}
if (dwlines_to_strip) {
dwlines_to_strip--;
continue;
}
// got the line... now need to write laser jet stuff
// to the output
LJGraphicsLineOut(chan, dwlinecnt, lpPtr, dwBytesPerLine);
dwlinecnt++;
lpPtr -= dwBytesToRead;
}
LJWriteCaseName( chan, lpFileName );
fprintf(chan, "\x12"); // page feed
LJReset(chan);
}
BOOL
PsLogNonPsError(
IN PPSDIBPARMS pPsToDib,
IN PPSEVENTSTRUCT pPsEvent )
{
PPSEVENT_NON_PS_ERROR_STRUCT pPsError;
LPPSTEST_JOB_INFO pData;
LPTSTR aStrs[2];
DWORD dwEventError;
TCHAR atchar[10];
WORD wStringCount;
int x;
LPTSTR lpErrorString=(LPTSTR) NULL;
if (!(pData = ValidateHandle(pPsToDib->hPrivateData))) {
return(FALSE);
}
pPsError = (PPSEVENT_NON_PS_ERROR_STRUCT) pPsEvent->lpVoid;
//
// Look for a match so we can find a string to match our error
//
for (x=0; x< sizeof(adwTranslate)/sizeof(adwTranslate[0]) ;x++ ) {
if (adwTranslate[x].dwPsError == pPsError->dwErrorCode) {
lpErrorString = adwTranslate[x].lpOutputError;
break;
}
}
if (lpErrorString != (LPTSTR) NULL) {
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"The following internal error occured: %s",
lpErrorString );
} else{
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"An internal PSTODIB error occured (%d)",
pPsError->dwErrorCode );
}
return(TRUE);
}
/*** PsPrintCallBack
*
* This is the main worker function for allowing data to get into the
*
*
*
*/
PROC
PsPrintCallBack(
IN PPSDIBPARMS pPsToDib,
IN OUT PPSEVENTSTRUCT pPsEvent)
{
BOOL bRetVal=TRUE; // Success in case we dont support
// Decide on a course of action based on the event passed in
//
switch( pPsEvent->uiEvent ) {
case PSEVENT_PAGE_READY:
// The data in the pPsEvent signifies the data we need to paint..
// for know we will treat the data as one text item null
// terminated simply for testing...
//
bRetVal = PsPrintGeneratePage( pPsToDib, pPsEvent );
break;
case PSEVENT_STDIN:
// The interpreter is asking for some data so simply call
// the print subsystem to try to satisfy the request
//
bRetVal = PsHandleStdInputRequest( pPsToDib, pPsEvent );
break;
#ifdef DJC
case PSEVENT_SCALE:
bRetVal = PsHandleScaleEvent( pPsToDib, pPsEvent);
break;
#endif
case PSEVENT_ERROR_REPORT:
bRetVal = PsGenerateErrorPage( pPsToDib, pPsEvent);
break;
#ifdef DJC
case PSEVENT_GET_CURRENT_PAGE_TYPE:
bRetVal = PsGetCurrentPageType( pPsToDib, pPsEvent);
break;
#endif
case PSEVENT_NON_PS_ERROR:
bRetVal = PsLogNonPsError( pPsToDib, pPsEvent );
break;
}
return (PROC) bRetVal;
}
BOOL
PsGenerateErrorPage(
IN PPSDIBPARMS pPsToDib,
IN OUT PPSEVENTSTRUCT pPsEvent)
{
PPSEVENT_ERROR_REPORT_STRUCT pPsErr;
LPPSTEST_JOB_INFO pData;
PCHAR pChar;
int i;
if (!(pData = ValidateHandle(pPsToDib->hPrivateData))) {
// do something here,,,, we have a major problem...
return(FALSE);
}
pPsErr = (PPSEVENT_ERROR_REPORT_STRUCT) pPsEvent->lpVoid;
//
// Only report the error page if there are actual errors and ONLY
// if the job had a FLUSHING mode, ie the error was critical enough
// to dump the rest of the postscript job.
//
if( pPsErr->dwErrCount &&
(pPsErr->dwErrFlags & PSEVENT_ERROR_REPORT_FLAG_FLUSHING )) {
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"Test case %s Had Postscript errors, they are:",
pData->lpTestInfo->szTestCaseName );
i = (int) pPsErr->dwErrCount;
while (--i) {
pChar = pPsErr->paErrs[i];
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_NONE,
"\n.....%s",
pChar );
}
}
return(TRUE);
}
#ifdef DJC
BOOL
PsHandleScaleEvent(
IN PPSDIBPARMS pPsToDib,
IN OUT PPSEVENTSTRUCT pPsEvent)
{
PPS_SCALE pScale;
pScale = (PPS_SCALE) pPsEvent->lpVoid;
pScale->dbScaleX = (double) pPsToDib->uiXDestRes / (double) pScale->uiXRes;
pScale->dbScaleY = (double) pPsToDib->uiYDestRes / (double) pScale->uiYRes;
#ifdef BLIT_TO_DESKTOP
pScale->dbScaleX *= .25; //DJC test
pScale->dbScaleY *= .25; //DJC test
#endif
return(TRUE);
}
#endif
LPPSTEST_JOB_INFO
ValidateHandle(
HANDLE hQProc
)
{
LPPSTEST_JOB_INFO pData = (LPPSTEST_JOB_INFO)hQProc;
if (pData ) {
return( pData );
} else {
return( (LPPSTEST_JOB_INFO) NULL );
}
}
BOOL
PsHandleStdInputRequest(
IN PPSDIBPARMS pPsToDib,
IN OUT PPSEVENTSTRUCT pPsEvent)
{
LPPSTEST_JOB_INFO pData;
PPSEVENT_STDIN_STRUCT pStdinStruct;
if (!(pData = ValidateHandle(pPsToDib->hPrivateData))) {
return FALSE;
}
// Cast the data to the correct structure
pStdinStruct = (PPSEVENT_STDIN_STRUCT) pPsEvent->lpVoid;
// Read from the printer the amount of data the interpreter
// claims he can handle
//
pStdinStruct->dwActualBytes = fread( pStdinStruct->lpBuff,
1,
pStdinStruct->dwBuffSize,
pData->fInput );
pData->dwTotalFileSize += pStdinStruct->dwActualBytes;
printf(".");
if (pStdinStruct->dwActualBytes == 0) {
// we read nothing from the file... declare an EOF
pStdinStruct->uiFlags |= PSSTDIN_FLAG_EOF;
}else{
// do not pass on the EOF, note this keeps binary from working!!!
// !!! NOTE !!!!
if (pStdinStruct->lpBuff[ pStdinStruct->dwActualBytes - 1] == 0x1a) {
pStdinStruct->dwActualBytes--;
}
}
return(TRUE);
}
VOID PsFormKeyName( LPPSTEST_JOB_INFO pData, LPTSTR lpKey )
{
// we form the key name by taking the job name as the root and
// adding the page number
wsprintf( lpKey, "%s_%d", pData->lpTestInfo->szTestCaseName, pData->dwCurPage );
}
BOOL PsPrintGeneratePage( PPSDIBPARMS pPsToDib, PPSEVENTSTRUCT pPsEvent)
{
LPPSTEST_JOB_INFO pData;
BOOL bPrintPage=FALSE;
PPSEVENT_PAGE_READY_STRUCT ppsPageReady;
TCHAR szBuff[300];
TCHAR szTempBuff[512];
TCHAR szInspect[10];
DWORD dwOrigCheckSum;
DWORD dwCheckSum;
BOOL bNewPage;
HANDLE hKey;
DWORD dwOrigCopies;
int iOrigPageType;
if (!(pData = ValidateHandle(pPsToDib->hPrivateData))) {
// do something here,,,, we have a major problem...
return(FALSE);
}
ppsPageReady = (PPSEVENT_PAGE_READY_STRUCT) pPsEvent->lpVoid;
// Now lets decide if this is the first time were doing this page, or
//
pData->dwCurPage++;
PsFormKeyName( pData, szBuff );
hKey = KeyOpenKey( szBuff,
pData->lpTestInfo->szFullPathToDataBase);
// Now decide if its new or has never been inspected
if( !KeyRetStringValue( hKey, KEY_PAGE_INSPECTED, szInspect ) ||
lstrcmpi( szInspect, KEY_INSPECTED ) != 0 ) {
// This is new so do whatever logic is required of a new test case
KeySetStringValue( hKey, KEY_PAGE_INSPECTED, KEY_NOT_INSPECTED);
KeySetDwordValue( hKey, KEY_PAGE_CKSUM, LocGenCheckSum(ppsPageReady));
KeySetDwordValue( hKey, KEY_PAGE_PAGETYPE, ppsPageReady->iWinPageType );
KeySetDwordValue( hKey, KEY_PAGE_COPIES, ppsPageReady->uiCopies);
// A new case should be printed.... no matter what
pData->dwActionFlags |= TST_ACTION_PAGE_REQUEST_PRINT;
bPrintPage = TRUE;
} else{
if (KeyRetDwordValue( hKey, KEY_PAGE_COPIES, &dwOrigCopies )){
if (dwOrigCopies != ppsPageReady->uiCopies ) {
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"Number of copies dont match for page %d, old=%d new=%d",
pData->dwCurPage,
dwOrigCopies,
ppsPageReady->uiCopies);
}
} else{
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"Data base problem, No copies for section %s",
szBuff );
}
if (KeyRetDwordValue( hKey, KEY_PAGE_PAGETYPE, (DWORD *) &iOrigPageType )){
if (iOrigPageType != ppsPageReady->iWinPageType ) {
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"Page tray number does not match for page %d, old=%d new=%d",
pData->dwCurPage,
iOrigPageType,
ppsPageReady->iWinPageType);
}
} else{
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"Data base problem, No page type for section %s",
szBuff );
}
// This is an existing case which passed so gen the checksum and
// make sure it matches
if (KeyRetDwordValue( hKey, KEY_PAGE_CKSUM, &dwOrigCheckSum )){
dwCheckSum = LocGenCheckSum(ppsPageReady);
if (dwOrigCheckSum != dwCheckSum ) {
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"Case %s Page %d bitmap checksums did not match old = %x new =%x",
pData->lpTestInfo->szTestCaseName,
pData->dwCurPage,
dwOrigCheckSum,
dwCheckSum);
bPrintPage = TRUE;
pData->dwActionFlags |= TST_ACTION_PAGE_REQUEST_PRINT;
}
} else{
PsLogFilePrintf( pData->hLocLogFile,
ERROR_CLASS_ERROR,
"Data base problem, No checksum for section %s",
szBuff );
}
}
KeyWriteKey( hKey );
KeyCloseKey( hKey);
// Now write out the buffer...
#ifdef HACK
LJOutputFrameBuffer( pData->LJout,
ppsPageReady,
pData->lpTestInfo->szFullPathToTestCase ) ;
#endif
}
int _CRTAPI1
main(
IN int argc,
IN TCHAR *argv[] )
{
PSDIBPARMS psDibParms;
BOOL bRetVal = FALSE;
LPTSTR lpCommandLine;
PSTEST_JOB_INFO JobInfo;
HANDLE hRoot;
DWORD dwStartTick;
TCHAR szInspect[128];
DWORD dwNumPages;
DWORD dwTestCaseSize;
// First clear out our structure
memset( (PVOID) &JobInfo, 0, sizeof(JobInfo));
JobInfo.hSharedMem = OpenFileMapping( FILE_MAP_WRITE, FALSE, argv[1]);
if (JobInfo.hSharedMem == (HANDLE)NULL) {
printf("\n!!!!ERROR cannot OpenFileMapping.... %s", argv[1]);
ExitProcess(1);
}
JobInfo.lpTestInfo = (LPTEST_STRUCTURE) MapViewOfFile( JobInfo.hSharedMem,
FILE_MAP_WRITE,
0,
0,
sizeof(TEST_STRUCTURE) );
if (JobInfo.lpTestInfo == (LPTEST_STRUCTURE) NULL ) {
printf("\nCould not map view of file...");
ExitProcess(2);
}
// Now verify were pointing to the correct thing
if (JobInfo.lpTestInfo->cbSize != sizeof(TEST_STRUCTURE)) {
printf("\nThe size of the shared memory is not correct, correct versions?");
ExitProcess(3);
}
if (JobInfo.lpTestInfo->hLogFile == (HANDLE)NULL) {
JobInfo.hLocLogFile = GetStdHandle( STD_OUTPUT_HANDLE);
}else{
JobInfo.hLocLogFile = JobInfo.lpTestInfo->hLogFile;
}
// Now open the file were gonna read from
JobInfo.fInput = fopen( JobInfo.lpTestInfo->szFullPathToTestCase, "rb");
if (JobInfo.fInput == (FILE *)NULL ) {
ExitProcess(4);
}
JobInfo.dwCurPage = 0; // 1st page
PsLogFilePrintf( JobInfo.hLocLogFile,
ERROR_CLASS_HEADER,
"Testing file %s",
JobInfo.lpTestInfo->szFullPathToTestCase );
KeyInitKeys();
#ifdef INCLUDE_PROFILE_CALLS
hRoot = KeyOpenKey( JobInfo.lpTestInfo->szTestCaseName,
JobInfo.lpTestInfo->szFullPathToDataBase);
// Now set up whether or not this has been inspected or not ....
if( !KeyRetStringValue( hRoot, KEY_ROOT_INSPECTED, szInspect ) ||
lstrcmpi( szInspect, KEY_INSPECTED ) != 0 ) {
JobInfo.dwActionFlags |= TST_ACTION_NEW_ROOT;
}
#endif
// This is new so do whatever logic is required of a new test case
// Now build up the structure for Starting PStoDIB
psDibParms.uiOpFlags = 0x00000000;
psDibParms.fpEventProc = (PSEVENTPROC) PsPrintCallBack;
psDibParms.hPrivateData = (HANDLE) &JobInfo;
psDibParms.uiXDestRes = 300;
psDibParms.uiYDestRes = 300;
dwStartTick = GetTickCount();
//JobInfo.LJout = fopen("bert.out","wb");
JobInfo.LJout = NULL;
bRetVal = !PStoDIB(&psDibParms);
//fclose(JobInfo.LJout);
#ifdef INCLUDE_PROFILE_CALLS
{
TCHAR xxx[512];
DWORD dwJobTime;
//
// Get the execution time of the job
dwJobTime = GetTickCount() - dwStartTick;
// Update the shared memory region
JobInfo.lpTestInfo->dwTotalTestTime += dwJobTime;
wsprintf(xxx,"Time of execution %d seconds", dwJobTime / 1000);
// DJC, add check for total pages and test case length..... becuase if
// that changed it negates everything...
KeySetStringValue( hRoot, KEY_ROOT_TIME, xxx);
// This is a new test case or one that has not been inspected, so update
// the page count and how many pages it generated
// DJC maybe dont write these values if there was an access violation
// DJC or fatal ps error
if (JobInfo.dwActionFlags & TST_ACTION_NEW_ROOT) {
KeySetDwordValue( hRoot, KEY_ROOT_NUM_PAGES, JobInfo.dwCurPage);
KeySetDwordValue( hRoot, KEY_ROOT_BYTES_IN_TEST_CASE, JobInfo.dwTotalFileSize );
KeySetStringValue( hRoot, KEY_ROOT_INSPECTED, KEY_NOT_INSPECTED);
} else {
if (!KeyRetDwordValue(hRoot,KEY_ROOT_BYTES_IN_TEST_CASE, &dwTestCaseSize)) {
PsLogFilePrintf( JobInfo.hLocLogFile,
ERROR_CLASS_ERROR,
"TestCase is marked inspected but no KEY exists for %s",
KEY_ROOT_BYTES_IN_TEST_CASE );
} else if ( dwTestCaseSize != JobInfo.dwTotalFileSize ) {
PsLogFilePrintf( JobInfo.hLocLogFile,
ERROR_CLASS_ERROR,
"Test case file size has changed, old=%d new=%d",
dwTestCaseSize,
JobInfo.dwTotalFileSize );
}
// Verify the size of the test case and the total pages printed is correct
if (!KeyRetDwordValue(hRoot,KEY_ROOT_NUM_PAGES, &dwNumPages)) {
PsLogFilePrintf( JobInfo.hLocLogFile,
ERROR_CLASS_ERROR,
"TestCase is marked inspected but no KEY exists for %s",
KEY_ROOT_NUM_PAGES );
} else if ( dwNumPages != JobInfo.dwCurPage ) {
PsLogFilePrintf( JobInfo.hLocLogFile,
ERROR_CLASS_ERROR,
"Number of pages printed not consistent old=%d new=%d",
dwNumPages,
JobInfo.dwCurPage);
}
// Verify test case size
}
KeyWriteKey( hRoot );
KeyCloseKey( hRoot);
}
#endif
ExitProcess(0);
return(bRetVal);
}