|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
psndsdb.c
Abstract:
Read the Print Configuration Attributes
$Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\PS40DB.C $ * * Rev 1.4 10 Apr 1996 14:23:28 terryt * Hotfix for 21181hq * * Rev 1.4 12 Mar 1996 19:55:22 terryt * Relative NDS names and merge * * Rev 1.3 04 Jan 1996 18:57:36 terryt * Bug fixes reported by MS * * Rev 1.2 22 Dec 1995 14:26:22 terryt * Add Microsoft headers * * Rev 1.1 20 Nov 1995 15:09:46 terryt * Context and capture changes * * Rev 1.0 15 Nov 1995 18:07:52 terryt * Initial revision.
--*/ #include "common.h"
extern DWORD SwapLong(DWORD number); extern char *TYPED_USER_NAME;
unsigned int PS40GetJobName( unsigned int NDSCaptureFlag, unsigned short SearchFlag, unsigned char *pOwner, unsigned char *pJobName, PPS_JOB_RECORD pJobRecord, unsigned char GetDefault );
#include <pshpack1.h>
#define NWPS_JOB_NAME_SIZE 32 /* 31 bytes and a '\0' */
#define NWPS_FORM_NAME_SIZE 12 /* 12 bytes and a '\0' */
#define NWPS_BANNER_NAME_SIZE 12 /* 12 bytes and a '\0' */
#define NWPS_BANNER_FILE_SIZE 12 /* 12 bytes and a '\0' */
#define NWPS_DEVI_NAME_SIZE 32 /* 32 bytes and a '\0' */
#define NWPS_MODE_NAME_SIZE 32 /* 32 bytes and a '\0' */
#define NWPS_BIND_NAME_SIZE 48
#define NWPS_MAX_NAME_SIZE 514
/*
// NWPS_Job_Old_Db_Hdr is the first record in the 4.0 PrnConDB database.
// It contains the following information about the database:
// The version number,
// the number of NWPS_Job_Rec records in PrnConDB,
// the name of the default print job configuration and
// the name of the job record owner.
*/ typedef struct { char text[ 76 ]; /* Printcon database. Version 4.0 */ char DefaultJobName[ 32 ]; /* Name of default Job */ char Owner[ 256 ]; /* owner of the job record */ WORD NumberOfRecords; /* # of NWPS_Job_Rec's in PrnConDB */ WORD NumberOfBlocks; /* # of 50-(NWPS_Job_Name_Rec) blocks */ BYTE MajorVersion; /* 4 */ BYTE MinorVersion; /* 0 */ } PRINTCON_40_HEADER;
#define PRINTCON_40_HEADER_SIZE sizeof(PRINTCON_40_HEADER)
/*
// NWPS_Job_41_Db_Hdr is the first record in the 4.1 PrnConDB database.
// It contains the following information about the database:
// The version number,
// the number of NWPS_Job_Rec records in PrnConDB,
// the name of the default print job configuration and
// the name of the job record owner IN UNICODE.
*/ typedef struct { char text[ 76 ]; /* Printcon database. Version 4.1 */ char DefaultJobName[ 32 ]; /* Name of default Job */ char unused[ 256 ]; /* no longer used. */ WORD NumberOfRecords; /* # of NWPS_Job_Rec's in PrnConDB */ WORD NumberOfBlocks; /* # of 50-(NWPS_Job_Name_Rec) blocks */ BYTE MajorVersion; /* 4 */ BYTE MinorVersion; /* 1 unicode defaultPJOwner etc. */ WORD Owner[ 256 ]; /* owner of the default job record */ } PRINTCON_41_HEADER;
#define PRINTCON_41_HEADER_SIZE sizeof(PRINTCON_41_HEADER)
/*
// NWPS_Job_Name_Rec is the type of record found in the
// second section of the PrnConDB database. Each one of
// these records contains the name of each NWPS_Job_Rec
// and a pointer to their location in the third section of
// the database. There is space set aside in this second
// section for fifty NWPS_Job_Name_Rec records; if this
// limit is exceeded then another fifty-record block following
// the first one is allocated after the third section of the
// database is moved down to make room for the expansion.
*/ typedef struct { char JobName[ NWPS_JOB_NAME_SIZE ]; /* 1 - 31 chars long + 0 */ long JobRecordOffset; /* Offset of the record
// (from the beginning
// of the 3rd section for 4.0
// databases and from the start
// of the file for pre-4.0)
*/ } JOB_NAME_AREA;
#define JOB_NAME_AREA_SIZE sizeof(JOB_NAME_AREA)
typedef struct { union { struct { DWORD DataType : 1; /* 0=Byte stream 1 = Text */ DWORD FormFeed : 1; /* 0 = FF; 1 = suppress FF */ DWORD NotifyWhenDone : 1; /* 0 = no, 1 = yes */ DWORD BannerFlag : 1; /* 0 = no, 1 = yes */ DWORD AutoEndCap : 1; /* 0 = no, 1 = yes */ DWORD TimeOutFlag: 1; /* 0 = no, 1 = yes */ DWORD SystemType : 3; /* 0 = bindery 1 = NDS */ DWORD Destination: 3; /* 0 = queue 1 = printer */ DWORD unknown : 20; }; DWORD PrintJobFlags; }; WORD NumberOfCopies; /* 1 - 65,000 */ WORD TimeoutCount; /* 1 - 1,000 */ BYTE TabSize; /* 1 - 18 */ BYTE LocalPrinter; /* 0=Lpt1, 1=Lpt2, 2=Lpt3 etc. */ char FormName[ NWPS_FORM_NAME_SIZE + 2 ]; /* 1-12 chars */ char Name[ NWPS_BANNER_NAME_SIZE + 2 ]; /* 1-12 chars */ char BannerName[ NWPS_BANNER_FILE_SIZE + 2 ]; /* 1-12 chars */ char Device[ NWPS_DEVI_NAME_SIZE + 2 ]; /* 1-32 chars */ char Mode[ NWPS_MODE_NAME_SIZE + 2 ]; /* 1-32 chars */ union { struct { /* pad structures on even boundries */ char Server[ NWPS_BIND_NAME_SIZE + 2 ]; /* 2-48 chars */ char QueueName[ NWPS_BIND_NAME_SIZE + 2 ]; /* 1-48 chars */ char PrintServer[ NWPS_BIND_NAME_SIZE + 2 ]; /* 1-48 chars */ } NonDS; char DSObjectName[ NWPS_MAX_NAME_SIZE ]; } u; BYTE reserved[390]; /* Adds up to 1024 total (was 1026) */ } JOB_RECORD_AREA;
#define JOB_RECORD_AREA_SIZE sizeof(JOB_RECORD_AREA)
#include <poppack.h>
/*++
*******************************************************************
PS40JobGetDefault
Routine Description:
Get the default print job configuration from 40.
Arguments: NDSCaptureFlag SearchFlag = pOwner = pJobName = A pointer to return the default job configuration name. pJobRecord = A pointer to return the default job configuration.
Return Value:
SUCCESSFUL 0x0000 PS_ERR_BAD_VERSION 0x7770 PS_ERR_GETTING_DEFAULT 0x7773 PS_ERR_OPENING_DB 0x7774 PS_ERR_READING_DB 0x7775 PS_ERR_READING_RECORD 0x7776 PS_ERR_INTERNAL_ERROR 0x7779 PS_ERR_NO_DEFAULT_SPECIFIED 0x777B INVALID_CONNECTION 0x8801
******************************************************************* --*/ unsigned int PS40JobGetDefault( unsigned int NDSCaptureFlag, unsigned short SearchFlag, unsigned char *pOwner, unsigned char *pJobName, PPS_JOB_RECORD pJobRecord ) { return PS40GetJobName( NDSCaptureFlag, SearchFlag, pOwner, pJobName, pJobRecord, TRUE); }
/*++
*******************************************************************
PS40JobRead
Routine Description:
Get the print job configuration from 40.
Arguments:
NDSCaptureFlag = pOwner = pJobName = A pointer to return the default job configuration name. pJobRecord = A pointer to return the default job configuration.
Return Value:
SUCCESSFUL 0x0000 PS_ERR_BAD_VERSION 0x7770 PS_ERR_GETTING_DEFAULT 0x7773 PS_ERR_OPENING_DB 0x7774 PS_ERR_READING_DB 0x7775 PS_ERR_READING_RECORD 0x7776 PS_ERR_INTERNAL_ERROR 0x7779 PS_ERR_NO_DEFAULT_SPECIFIED 0x777B INVALID_CONNECTION 0x8801
******************************************************************* --*/ unsigned int PS40JobRead( unsigned int NDSCaptureFlag, unsigned char *pOwner, unsigned char *pJobName, PPS_JOB_RECORD pJobRecord ) { return PS40GetJobName( NDSCaptureFlag, 0, pOwner, pJobName, pJobRecord, FALSE); }
/*++
*******************************************************************
PS40GetJobName
Routine Description:
Common routine to get the print job configuration from 40.
Arguments: NDSCaptureFlag = SearchFlag = pOwner = pJobName = A pointer to return the default job configuration name. pJobRecord = A pointer to return the default job configuration. GetDefault = TRUE = get the default job name, FALSE = Don't get the default job name.
Return Value:
SUCCESSFUL 0x0000 PS_ERR_BAD_VERSION 0x7770 PS_ERR_GETTING_DEFAULT 0x7773 PS_ERR_OPENING_DB 0x7774 PS_ERR_READING_DB 0x7775 PS_ERR_READING_RECORD 0x7776 PS_ERR_INTERNAL_ERROR 0x7779 PS_ERR_NO_DEFAULT_SPECIFIED 0x777B INVALID_CONNECTION 0x8801
******************************************************************* --*/ unsigned int PS40GetJobName( unsigned int NDSCaptureFlag, unsigned short SearchFlag, unsigned char *pOwner, unsigned char *pJobName, PPS_JOB_RECORD pJobRecord, unsigned char GetDefault ) { unsigned char *pSearchJobName; unsigned long ObjectId; HANDLE stream = NULL; unsigned int Count; unsigned int Bytes; unsigned int RetCode = 0; unsigned int ConnectionNumber; JOB_NAME_AREA JobNameArea; JOB_RECORD_AREA JobRecord; PRINTCON_40_HEADER PrintConHeader; unsigned int Version40 = FALSE; unsigned int ConnectionHandle; unsigned char MailDirPath[NCP_MAX_PATH_LENGTH]; unsigned char TempJobName[33]; PBYTE JobContext = NULL; unsigned FileSize;
// TRACKING Printer names can be used instead of queues
// Must lookup "default print queue" if NT doesn't
if ( NDSCaptureFlag ) {
if ( !GetDefault ) { JobContext = strchr( pJobName, ':' ); if ( JobContext ) { *JobContext = '\0'; strncpy( TempJobName, pJobName, 32 ); TempJobName[32] = 0; *JobContext++ = ':'; pJobName = TempJobName; } }
if ( JobContext ) { if (NDSfopenStream ( JobContext, "Print Job Configuration", &stream, &FileSize )) { RetCode = PS_ERR_OPENING_DB; goto CommonExit; } } else { if (NDSfopenStream ( TYPED_USER_NAME, "Print Job Configuration", &stream, &FileSize)) { PBYTE p;
for ( p = TYPED_USER_NAME; p ; p = strchr ( p, '.' ) ) { p++; if ( *p == 'O' && *(p+1) == 'U' && *(p+2) == '=' ) break;
if ( *p == 'O' && *(p+1) == '=' ) break; } if (NDSfopenStream ( p, "Print Job Configuration", &stream, &FileSize)) { RetCode = PS_ERR_OPENING_DB; goto CommonExit; } } } } else {
if (!CGetDefaultConnectionID (&ConnectionHandle)) { RetCode = PS_ERR_OPENING_DB; goto CommonExit; }
RetCode = GetConnectionNumber(ConnectionHandle, &ConnectionNumber); if (RetCode) { goto CommonExit; }
RetCode = GetBinderyObjectID (ConnectionHandle, LOGIN_NAME, OT_USER, &ObjectId); if (RetCode) { goto CommonExit; }
/** Build the path to open the file **/
sprintf(MailDirPath, "SYS:MAIL/%lX/PRINTJOB.DAT", SwapLong(ObjectId)); stream = CreateFileA( NTNWtoUNCFormat( MailDirPath ), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (stream == INVALID_HANDLE_VALUE) {
sprintf(MailDirPath, "SYS:PUBLIC/PRINTJOB.DAT");
stream = CreateFileA( NTNWtoUNCFormat(MailDirPath), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (stream == INVALID_HANDLE_VALUE) { RetCode = PS_ERR_OPENING_DB; goto CommonExit; } } }
if ( !ReadFile( stream, (PBYTE) &PrintConHeader, PRINTCON_40_HEADER_SIZE, &Bytes, NULL ) ) { RetCode = PS_ERR_INTERNAL_ERROR; goto CommonExit; }
if (Bytes < PRINTCON_40_HEADER_SIZE) { if ( !( NDSCaptureFlag && Bytes) ) { RetCode = PS_ERR_INTERNAL_ERROR; goto CommonExit; } }
/** Check the version number **/
if ( PrintConHeader.MajorVersion != 4 ) { RetCode = PS_ERR_BAD_VERSION; goto CommonExit; }
if ( PrintConHeader.MinorVersion == 0 ) { Version40 = TRUE; }
/** Get the name we are looking for **/
if (GetDefault) { if (PrintConHeader.DefaultJobName[0] == 0) { RetCode = PS_ERR_GETTING_DEFAULT; goto CommonExit; } pSearchJobName = PrintConHeader.DefaultJobName; } else { pSearchJobName = pJobName; }
if ( !Version40 ) { SetFilePointer( stream, PRINTCON_41_HEADER_SIZE, NULL, FILE_BEGIN ); }
Count = 0;
/** Go through all of the job entry to look for the name **/
while (Count < PrintConHeader.NumberOfRecords) { if ( !ReadFile( stream, (PBYTE) &JobNameArea, JOB_NAME_AREA_SIZE, &Bytes, NULL) ) { RetCode = PS_ERR_INTERNAL_ERROR; goto CommonExit; }
if (Bytes < JOB_NAME_AREA_SIZE) { if ( !( NDSCaptureFlag && Bytes) ) { RetCode = PS_ERR_INTERNAL_ERROR; goto CommonExit; } } Count++;
/** Skip the entry with a null job name **/
if (JobNameArea.JobName[0] == 0) { continue; } /** Is this the job name we are looking for? **/
if (!_strcmpi(pSearchJobName, JobNameArea.JobName)) { break; } }
/** See if we found the job name **/
if (Count > PrintConHeader.NumberOfRecords) { if (GetDefault) { RetCode = PS_ERR_GETTING_DEFAULT; } else { RetCode = PS_ERR_READING_RECORD; } goto CommonExit; }
/*
* The Job offset starts at the beginning of the third section. * The third section starts after the Header and after the * 50 record blocks. */ if ( Version40 ) { SetFilePointer( stream, PRINTCON_40_HEADER_SIZE + ( PrintConHeader.NumberOfBlocks * 50) * JOB_NAME_AREA_SIZE + JobNameArea.JobRecordOffset, NULL, FILE_BEGIN ); } else { SetFilePointer( stream, PRINTCON_41_HEADER_SIZE + ( PrintConHeader.NumberOfBlocks * 50) * JOB_NAME_AREA_SIZE + JobNameArea.JobRecordOffset, NULL, FILE_BEGIN ); }
memset((PBYTE)&JobRecord, 0, sizeof(JobRecord));
if ( !ReadFile( stream, (PBYTE) &JobRecord, JOB_RECORD_AREA_SIZE, &Bytes, NULL) ) { RetCode = PS_ERR_READING_RECORD; goto CommonExit; }
if (Bytes < JOB_RECORD_AREA_SIZE) { if ( !( NDSCaptureFlag && Bytes) ) { RetCode = PS_ERR_READING_RECORD; goto CommonExit; } }
memset(pJobRecord, 0, PS_JOB_RECORD_SIZE);
if (JobRecord.NotifyWhenDone) { pJobRecord->PrintJobFlag |= PS_JOB_NOTIFY; } if (JobRecord.BannerFlag) { pJobRecord->PrintJobFlag |= PS_JOB_PRINT_BANNER; } if (JobRecord.DataType) { pJobRecord->PrintJobFlag |= PS_JOB_EXPAND_TABS; } if (JobRecord.FormFeed) { pJobRecord->PrintJobFlag |= PS_JOB_NO_FORMFEED; } if (JobRecord.AutoEndCap) { pJobRecord->PrintJobFlag |= PS_JOB_AUTO_END; } if (JobRecord.TimeoutCount) { pJobRecord->PrintJobFlag |= PS_JOB_TIMEOUT; } if (JobRecord.Destination) { pJobRecord->PrintJobFlag |= PS_JOB_DS_PRINTER; } if ( JobRecord.SystemType ) { pJobRecord->PrintJobFlag |= PS_JOB_ENV_DS; }
pJobRecord->Copies = JobRecord.NumberOfCopies; pJobRecord->TabSize = JobRecord.TabSize; pJobRecord->TimeOutCount = JobRecord.TimeoutCount; pJobRecord->LocalPrinter = JobRecord.LocalPrinter;
strcpy(pJobRecord->Mode, JobRecord.Mode); strcpy(pJobRecord->Device, JobRecord.Device); strcpy(pJobRecord->FormName, JobRecord.FormName); strcpy(pJobRecord->BannerName, JobRecord.BannerName);
if ( JobRecord.SystemType ) { ConvertUnicodeToAscii( JobRecord.u.DSObjectName ); strcpy(pJobRecord->u.DSObjectName, JobRecord.u.DSObjectName); } else { strcpy(pJobRecord->u.NonDS.PrintQueue, JobRecord.u.NonDS.QueueName); strcpy(pJobRecord->u.NonDS.FileServer, JobRecord.u.NonDS.Server); }
if (GetDefault && pJobName) { strcpy(pJobName, JobNameArea.JobName); }
if (pOwner) { *pOwner = 0; }
CommonExit: if (stream != NULL) { // 07/19/96 cjc (Citrix code merge)
// fclose causes a trap cause it expects *stream but
// really should be using CloseHandle anyway.
CloseHandle( stream ); // if ( NDSCaptureFlag )
// CloseHandle( stream );
// else
// fclose( stream );
}
return RetCode; }
|