|
|
/*======================================================================================//
| //
|Copyright (c) 1998 Sequent Computer Systems, Incorporated //
| //
|Description: //
| //
|---------------------------------------------------------------------------------------//
| This file implements the CProcConClient class methods defined in ProcConSvc.h //
|---------------------------------------------------------------------------------------//
| //
|Created: //
| //
| Jarl McDonald 07-98 //
| //
|Revision History: //
| //
|=======================================================================================*/ #include "ProcConSvc.h"
const PCINT32 SIGNATURE = 0xd06eface;
// CProcConClient Constructor...
CProcConClient::CProcConClient( ClientContext *ctxt ) : m_impersonating( FALSE ), m_cPC( *ctxt->cPC ), m_cDB( *ctxt->cDB ), m_cUser( *ctxt->cUser ), m_hPipe( ctxt->hPipe), m_clientNo( ctxt->clientNo ), m_inBufChars( ctxt->inBufChars ), m_outBufChars( ctxt->outBufChars ) { delete ctxt; // we're done with this
m_inBuf = (TCHAR *) new char[m_inBufChars]; if ( !m_inBuf ) PCLogNoMemory( TEXT("AllocInBuffer"), m_inBufChars );
m_outBuf = (TCHAR *) new char[m_outBufChars]; if ( !m_outBuf ) PCLogNoMemory( TEXT("AllocOutBuffer"), m_outBufChars );
m_hReadEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); if ( !m_hReadEvent ) PCLogUnExError( TEXT("PipeRead"), TEXT("CreateEvent") );
m_hWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); if ( !m_hWriteEvent ) PCLogUnExError( TEXT("PipeWrite"), TEXT("CreateEvent") );
memset( &m_olRead, 0, sizeof(m_olRead ) ); memset( &m_olWrite, 0, sizeof(m_olWrite ) ); m_olRead.hEvent = m_hReadEvent; m_olWrite.hEvent = m_hWriteEvent;
}
// CProcConClient Destructor...
CProcConClient::~CProcConClient( void ) { if ( m_hPipe ) { FlushFileBuffers( m_hPipe ); DisconnectNamedPipe( m_hPipe ); CloseHandle( m_hPipe ); m_hPipe = NULL; if ( m_impersonating && !RevertToSelf() ) PCLogUnExError( TEXT("PCClient"), TEXT("RevertToSelf") ); }
if ( m_hReadEvent ) CloseHandle( m_hReadEvent ); if ( m_hWriteEvent ) CloseHandle( m_hWriteEvent ); if ( m_inBuf ) delete [] ((char *) m_inBuf); if ( m_outBuf ) delete [] ((char *) m_outBuf); m_hReadEvent = m_hWriteEvent = m_inBuf = m_outBuf = NULL; } //--------------------------------------------------------------------------------------------//
// Function to determine if all CProcConClient initial conditions have been met //
// Input: None //
// Returns: TRUE if ready, FALSE if not //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::ReadyToRun( void ) { return m_hPipe && m_hReadEvent && m_hWriteEvent && m_inBuf && m_outBuf; }
//--------------------------------------------------------------------------------------------//
// CProcConClient thread function -- this function runs in its own thread //
// This function handles all pipe reads, writes and processing for a single connection. //
// Input: None //
// Returns: 0 //
// Note: This thread owns the pipe that it is constructed with and terminates //
// when the pipe is closed by the client. //
//--------------------------------------------------------------------------------------------//
PCULONG32 CProcConClient::Run( void ) { PCULONG32 bytesDone, bytesToWrite, rc; HANDLE waitList[] = { m_olRead.hEvent, m_olWrite.hEvent, m_cPC.GetShutEvent() }; BOOL inBufEmpty = TRUE, outBufEmpty = TRUE, reading = FALSE, writing = FALSE;
for ( BOOL quit = FALSE; !quit && !m_cPC.GotShutdown(); ) { // Initiate pipe read if needed...
if ( !reading && inBufEmpty ) { rc = ReadFile( m_hPipe, m_inBuf, m_inBufChars, &bytesDone, &m_olRead ); if ( !rc && GetLastError() != ERROR_IO_PENDING ) { if ( GetLastError() != ERROR_BROKEN_PIPE ) PCLogUnExError( TEXT("PCClient"), TEXT("ReadPipe") ); quit = TRUE; } else reading = TRUE; }
// Process any pending data...
if ( !writing && outBufEmpty && !inBufEmpty ) { inBufEmpty = TRUE; if ( ProcessRequest( bytesDone, &bytesToWrite ) ) outBufEmpty = FALSE; }
// Initiate pipe write if needed...
if ( !writing && !outBufEmpty ) { rc = WriteFile( m_hPipe, m_outBuf, bytesToWrite, &bytesDone, &m_olWrite ); if ( !rc && GetLastError() != ERROR_IO_PENDING ) { if ( GetLastError() != ERROR_BROKEN_PIPE && GetLastError() != ERROR_NO_DATA ) PCLogUnExError( TEXT("PCClient"), TEXT("WritePipe") ); quit = TRUE; } else writing = TRUE; }
// If we're quitting, don't enter wait...
if ( quit || m_cPC.GotShutdown() ) continue;
// Wait for something to happen...
rc = WaitForMultipleObjects( ENTRY_COUNT( waitList ), waitList, FALSE, INFINITE ); if ( rc == WAIT_FAILED ) { PCLogUnExError( TEXT("PCClient"), TEXT("Wait") ); break; }
// Process wait completion...
switch ( rc - WAIT_OBJECT_0 ) { case 0: // read completed
reading = inBufEmpty = FALSE; if ( !GetOverlappedResult( m_hPipe, &m_olRead, &bytesDone, TRUE ) ) { if ( GetLastError() != ERROR_BROKEN_PIPE && GetLastError() != ERROR_NO_DATA ) PCLogUnExError( TEXT("PCClient"), TEXT("ReadResult") ); quit = TRUE; } ResetEvent( m_olRead.hEvent ); break; case 1: // write completed
writing = FALSE; outBufEmpty = TRUE; if ( !GetOverlappedResult( m_hPipe, &m_olWrite, &bytesDone, TRUE ) || bytesToWrite != bytesDone ) { if ( GetLastError() != ERROR_BROKEN_PIPE && GetLastError() != ERROR_NO_DATA ) PCLogUnExError( TEXT("PCClient"), TEXT("WriteResult") ); quit = TRUE; } ResetEvent( m_olWrite.hEvent ); break; case 2: // quit requested
break; } // end switch
} return 0; }
//--------------------------------------------------------------------------------------------//
// Function to handle impersonation on a request by request basis. All decisions about which //
// types of requests require client impersonation are made in this function. //
// Input: request //
// Returns: TRUE if impersonation was properly set, FALSE otherwise //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::Impersonate( PCRequest *req ) { switch (req->reqType) { case PCTYPE_PROCLIST: // impersonation not required
break;
case PCTYPE_NAMERULE: // impersonation required
case PCTYPE_JOBSUMMARY: case PCTYPE_PROCSUMMARY: case PCTYPE_JOBLIST: case PCTYPE_PROCDETAIL: case PCTYPE_JOBDETAIL: case PCTYPE_SERVERINFO: case PCTYPE_SERVERPARMS: case PCTYPE_CONTROL: if ( !ImpersonateNamedPipeClient( m_hPipe ) ) { PCLogUnExError( TEXT("PCClient"), TEXT("Impersonate") ); return FALSE; } m_impersonating = TRUE; break;
default: SetLastError( PCERROR_INVALID_REQUEST ); return FALSE; }
return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to deactivate client impersonation on a request by request basis. This function //
// just uses the m_impersonation flag to determine if impersonation is currently in effect. //
// Input: request //
// Returns: //
//--------------------------------------------------------------------------------------------//
void CProcConClient::UnImpersonate( PCRequest *req ) { if (m_impersonating && !RevertToSelf()) { PCLogUnExError( TEXT("PCClient"), TEXT("RevertToSelf") ); } }
//--------------------------------------------------------------------------------------------//
// Function to process a request in the input buffer and build a response in the output buffer//
// Input: Number of bytes in the input buffer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::ProcessRequest( PCULONG32 inLen, PCULONG32 *outLen ) {
PCRequest *req = (PCRequest *) m_inBuf; PCResponse *rsp = (PCResponse *) m_outBuf; PrimeResponse( rsp, req );
// Perform cursory checks on incoming request length and contents...
PCULONG32 hdrBytesExpected = sizeof(PCRequest) - sizeof(req->reqData); if ( inLen < hdrBytesExpected || req->reqSignature != SIGNATURE || inLen < hdrBytesExpected + req->reqDataLen ) { return ErrorResponse( PCERROR_INVALID_REQUEST, rsp, outLen ); }
if (!Impersonate( req )) { PCLogUnExError( TEXT("PCClient"), TEXT("Impersonate") ); return ErrorResponse( GetLastError(), rsp, outLen ); }
ULONG rc = 0;
// Switch on requested data type to process it...
switch ( req->reqType ) { case PCTYPE_NAMERULE: rc = DoNameRules( req, rsp, outLen ); break;
case PCTYPE_JOBSUMMARY: rc = DoJobSummary( req, rsp, outLen ); break;
case PCTYPE_PROCSUMMARY: rc = DoProcSummary( req, rsp, outLen ); break;
case PCTYPE_PROCDETAIL: rc = DoProcDetail( req, rsp, outLen ); break;
case PCTYPE_JOBDETAIL: rc = DoJobDetail( req, rsp, outLen ); break;
case PCTYPE_PROCLIST: rc = DoProcList( req, rsp, outLen ); break;
case PCTYPE_JOBLIST: rc = DoJobList( req, rsp, outLen ); break;
case PCTYPE_SERVERINFO: rc = DoServerInfo( req, rsp, outLen ); break;
case PCTYPE_SERVERPARMS: rc = DoServerParms( req, rsp, outLen ); break;
case PCTYPE_CONTROL: rc = DoControl( req, rsp, outLen ); break;
default: rc = ErrorResponse( PCERROR_INVALID_REQUEST, rsp, outLen ); } // end switch
UnImpersonate( req ); return rc; }
//--------------------------------------------------------------------------------------------//
// Function to prime a response structure with local data and request data //
// Input: pointers to request and response structures //
//--------------------------------------------------------------------------------------------//
void CProcConClient::PrimeResponse( PCResponse *rsp, PCRequest *req ) {
memset( rsp, 0, sizeof(*rsp) ); rsp->rspReqSignature = SIGNATURE; // sanity check signature
rsp->rspReqSeq = req->reqSeq; // echo of requestor sequence number
rsp->rspReqOp = req->reqOp; // echo of original request operation
rsp->rspReqType = req->reqType; // echo of original request data type
rsp->rspReqVersion = req->reqVersion; // echo of original request data version
rsp->rspVersion = 1; // 1 for base version
rsp->rspTimeStamp = (PCINT32) time( NULL ); // $$ // time stamp associated with the data returned
}
//--------------------------------------------------------------------------------------------//
// Function to build an error response in the output buffer //
// Input: Error code, request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::ErrorResponse( PCULONG32 errCode, PCResponse *rsp, PCULONG32 *outLen ) {
rsp->rspResult = (BYTE) (errCode & 0xf0000000 ? PCRESULT_PCERROR: PCRESULT_NTERROR); rsp->rspError = errCode; // NT or PC error
rsp->rspDataItemCount = 0; // no data returned on error
rsp->rspDataItemLen = 0; // no data returned on error
*outLen = sizeof( *rsp ) - sizeof( rsp->rspData );
return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to process a name rules request and build a response in the output buffer //
// Input: Request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoNameRules( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
PCULONG32 err = PCERROR_SUCCESS; PCNameRule *rule = (PCNameRule *) req->reqData; rule->matchType = _totupper( rule->matchType );
switch ( req->reqOp ) { case PCOP_GET: req->reqFlags |= PCREQFLAG_DOLIST; // just treat as list flag set
break; case PCOP_ADD: if ( !PCValidName( rule->procName, ENTRY_COUNT(rule->procName) ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen ); if ( !PCValidMatchType( rule->matchType ) ) return ErrorResponse( PCERROR_INVALID_PARAMETER, rsp, outLen ); err = m_cDB.AddNameRule( rule, req->reqVersion, (PCULONG32) req->reqIndex, req->reqUpdCtr ); break; case PCOP_REP: if ( !PCValidName( rule->procName, ENTRY_COUNT(rule->procName) ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen ); if ( !PCValidMatchType( rule->matchType ) ) return ErrorResponse( PCERROR_INVALID_PARAMETER, rsp, outLen ); err = m_cDB.ReplNameRule( rule, req->reqVersion, (PCULONG32) req->reqIndex, req->reqUpdCtr ); break; case PCOP_DEL: err = m_cDB.DelNameRule( (PCULONG32) req->reqIndex, req->reqUpdCtr ); break; case PCOP_ORD: err = m_cDB.SwapNameRule( (PCULONG32) req->reqIndex, req->reqUpdCtr ); break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
if ( req->reqFlags & PCREQFLAG_DOLIST ) { if ( m_cDB.GetNameRules( req->reqFirst, // start from here
(PCNameRule *) rsp->rspData, req->reqCount, // put data here with max count
&rsp->rspDataItemLen, &rsp->rspDataItemCount, // put item len and count here
&rsp->rspUpdCtr ) ) // put updctr here
rsp->rspFlags |= PCRSPFLAG_MOREDATA; }
*outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen; return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to handle a process list request and build a response in the output buffer //
// Input: Request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
// Note: A process list consists of the names of all processes know to ProcCon: //
// 1) Process names appearing in name rules, //
// 2) Process names defined in ProcCon's database, //
// 3) Any processes currently running and visible to ProcCon. //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoProcList( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
PCProcListItem *start = (PCProcListItem *) req->reqData;
switch ( req->reqOp ) { case PCOP_GET: if ( !PCValidName( start->procName, ENTRY_COUNT(start->procName), TRUE ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
if ( m_cDB.GetProcList( start, (PCULONG32) req->reqIndex, // starting here with these flags
(PCProcListItem *) rsp->rspData, req->reqCount, // put data here with max count
&rsp->rspDataItemLen, &rsp->rspDataItemCount ) ) // put item len and count here
rsp->rspFlags |= PCRSPFLAG_MOREDATA; break; case PCOP_KILL: err = m_cPC.GetPCMgr()->KillProcess( (ULONG_PTR) req->reqIndex, *((TIME_VALUE *) req->reqData) ); break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
*outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to handle a job list request and build a response in the output buffer //
// Input: Request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
// Note: A job list consists of the names of all jobs know to ProcCon: //
// 1) Job names appearing in process definitions as "member of group", //
// 2) Job names defined in ProcCon's database, //
// 3) Any jobs currently running and visible to ProcCon. //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoJobList( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
PCJobListItem *start = (PCJobListItem *) req->reqData;
switch ( req->reqOp ) { case PCOP_GET: if ( !PCValidName( start->jobName, ENTRY_COUNT(start->jobName), TRUE ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen ); if ( m_cDB.GetJobList( start, (PCULONG32) req->reqIndex, // starting here with these flags
(PCJobListItem *) rsp->rspData, req->reqCount, // put data here with max count
&rsp->rspDataItemLen, &rsp->rspDataItemCount ) ) // put item len and count here
rsp->rspFlags |= PCRSPFLAG_MOREDATA; break; case PCOP_KILL: err = m_cPC.GetPCMgr()->KillJob( *((JOB_NAME *) req->reqData) ); break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
*outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to handle a process summary data request and build a response in the output buffer//
// Input: Request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoProcSummary( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
PCProcSummary *start = (PCProcSummary *) req->reqData;
switch ( req->reqOp ) { case PCOP_GET: if ( !PCValidName( start->procName, ENTRY_COUNT(start->procName), TRUE ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen ); if ( m_cDB.GetProcSummary( start, (PCULONG32) req->reqIndex, // starting here with these flags
(PCProcSummary *) rsp->rspData, req->reqCount, // put data here with max count
&rsp->rspDataItemLen, &rsp->rspDataItemCount ) ) // put item len and count here
rsp->rspFlags |= PCRSPFLAG_MOREDATA; break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
*outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen; return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to handle a job summary data request and build a response in the output buffer //
// Input: Request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoJobSummary( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
PCJobSummary *start = (PCJobSummary *) req->reqData;
switch ( req->reqOp ) { case PCOP_GET: if ( !PCValidName( start->jobName, ENTRY_COUNT(start->jobName), TRUE ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen ); if ( m_cDB.GetJobSummary( start, (PCULONG32) req->reqIndex, // starting here with these flags
(PCJobSummary *) rsp->rspData, req->reqCount, // put data here with max count
&rsp->rspDataItemLen, &rsp->rspDataItemCount ) ) // put item len and count here
rsp->rspFlags |= PCRSPFLAG_MOREDATA; break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
*outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen; return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to process a process detail data request and build a response in the output buf //
// Input: Request pointer, location to store output buffer and length //
// Returns: TRUE if output is to be written, else FALSE //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoProcDetail( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
PCProcDetail *reqDetail = (PCProcDetail *) req->reqData; PCProcDetail *rspDetail = (PCProcDetail *) rsp->rspData;
if ( !PCValidName( reqDetail->base.procName, ENTRY_COUNT(reqDetail->base.procName) ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
switch ( req->reqOp ) { case PCOP_GET: { // Set max length of variable data.
int maxVLen = req->maxReply - offsetof(PCProcDetail, vData); reqDetail->vLength = (PCINT16) max( 0, maxVLen ); // Get detail data and set number (always only 1) and length of returned item.
err = m_cDB.GetProcDetail( reqDetail, rspDetail, req->reqVersion, &rsp->rspUpdCtr ); rsp->rspDataItemCount = 1; rsp->rspDataItemLen = (PCINT16) (offsetof(PCProcDetail, vData) + rspDetail->vLength); break; } case PCOP_ADD: if ( !PCValidName( reqDetail->base.memberOfJobName, ENTRY_COUNT(reqDetail->base.memberOfJobName), TRUE ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen ); err = m_cDB.AddProcDetail( reqDetail, req->reqVersion); if ( err == PCERROR_SUCCESS || err == PCERROR_EXISTS ) GenerateJobDetail( reqDetail ); break; case PCOP_REP: if ( !PCValidName( reqDetail->base.memberOfJobName, ENTRY_COUNT(reqDetail->base.memberOfJobName), TRUE ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen ); err = m_cDB.ReplProcDetail( reqDetail, req->reqVersion, req->reqUpdCtr ); if ( err == PCERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND ) GenerateJobDetail( reqDetail ); break; case PCOP_DEL: err = m_cDB.DelProcDetail( &reqDetail->base, req->reqVersion); break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err == ERROR_MORE_DATA ) rsp->rspFlags |= PCRSPFLAG_MOREDATA; else if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
if ( req->reqFlags & PCREQFLAG_DOLIST ) m_cDB.GetProcSummary( (PCProcSummary *) req->reqData, PC_LIST_STARTING_WITH, // starting here
(PCProcSummary *) rsp->rspData, 1, // put data here with count = 1
&rsp->rspDataItemLen, &rsp->rspDataItemCount ); // put item len and count here
*outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen; return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to generate job detail if needed and it doesn't exist //
// Input: Process detail that may refer to a job //
// Returns: nothing //
//--------------------------------------------------------------------------------------------//
void CProcConClient::GenerateJobDetail( PCProcDetail *reqDetail ) { if ( *reqDetail->base.memberOfJobName ) { PCJobDetail jobDetail; memset( &jobDetail, 0, sizeof(jobDetail) );
memcpy( jobDetail.base.jobName, reqDetail->base.memberOfJobName, sizeof(jobDetail.base.jobName) ); jobDetail.base.mgmtParms.priority = reqDetail->base.mgmtParms.priority; jobDetail.base.mgmtParms.affinity = reqDetail->base.mgmtParms.affinity; jobDetail.base.mgmtParms.schedClass = 5;
m_cDB.AddJobDetail( &jobDetail, 1 ); } }
//--------------------------------------------------------------------------------------------//
// Function to process a job detail request and build a response in the output buffer //
// Input: Request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoJobDetail( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
PCJobDetail *reqDetail = (PCJobDetail *) req->reqData; PCJobDetail *rspDetail = (PCJobDetail *) rsp->rspData;
if ( !PCValidName( reqDetail->base.jobName, ENTRY_COUNT(reqDetail->base.jobName) ) ) return ErrorResponse( PCERROR_INVALID_NAME, rsp, outLen );
switch ( req->reqOp ) { case PCOP_GET: { // Set max length of variable data.
int maxVLen = req->maxReply - offsetof(PCJobDetail, vData); rspDetail->vLength = (PCINT16) max( 0, maxVLen ); // Get detail data and set number (always only 1) and length of returned item.
err = m_cDB.GetJobDetail( reqDetail, rspDetail, req->reqVersion, &rsp->rspUpdCtr ); rsp->rspDataItemCount = 1; rsp->rspDataItemLen = (PCINT16) (offsetof(PCJobDetail, vData) + rspDetail->vLength); break; } case PCOP_ADD: err = m_cDB.AddJobDetail( reqDetail, req->reqVersion); break; case PCOP_REP: err = m_cDB.ReplJobDetail( reqDetail, req->reqVersion, req->reqUpdCtr ); break; case PCOP_DEL: err = m_cDB.DelJobDetail( &reqDetail->base, req->reqVersion); break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err == ERROR_MORE_DATA ) rsp->rspFlags |= PCRSPFLAG_MOREDATA; else if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
if ( req->reqFlags & PCREQFLAG_DOLIST ) m_cDB.GetJobSummary( (PCJobSummary *) req->reqData, PC_LIST_STARTING_WITH, // starting here
(PCJobSummary *) rsp->rspData, 1, // put data here with count = 1
&rsp->rspDataItemLen, &rsp->rspDataItemCount ); // put item len and count here
*outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen; return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to handle a server information request and build a response in the output buffer //
// Input: Request and response pointers, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
// Note: Server info consists of version info and system parameters. //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoServerInfo( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
switch ( req->reqOp ) { case PCOP_GET: m_cPC.GetPCSystemInfo( (PCSystemInfo *) rsp->rspData, // put data here
&rsp->rspDataItemLen, &rsp->rspDataItemCount ); // put item len and count here
break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
*outLen = offsetof(PCResponse, rspData) + rsp->rspDataItemCount * rsp->rspDataItemLen;
return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to handle a server parameter request and build a response in the output buffer //
// Input: Request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
// Note: Server info consists of version info and system parameters. //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoServerParms( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
switch ( req->reqOp ) { case PCOP_REP: err = m_cDB.SetPollDelaySeconds( (PCUINT32) (((PCSystemParms *) req->reqData)->manageIntervalSeconds) ); if ( err == PCERROR_SUCCESS ) err = m_cUser.SetTimeout( (PCUINT32) (((PCSystemParms *) req->reqData)->timeoutValueMs) ); break; default: err = PCERROR_INVALID_REQUEST; break; } // end switch operation
if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
*outLen = offsetof(PCResponse, rspData);
return TRUE; }
//--------------------------------------------------------------------------------------------//
// Function to handle a server control request and build a response in the output buffer //
// Input: Request pointer, location to store output buffer length //
// Returns: TRUE if output is to be written, else FALSE //
// Note: Server control consists of a series of bit commands and one piece of data. //
//--------------------------------------------------------------------------------------------//
BOOL CProcConClient::DoControl( PCRequest *req, PCResponse *rsp, PCULONG32 *outLen ) {
INT32 err = PCERROR_SUCCESS;
if ( req->reqOp != PCOP_CTL || (req->reqIndex & PCCFLAG_SIGNATURE) != PCCFLAG_SIGNATURE || req->reqIndex & PCCFLAG_ANTI_SIGNATURE ) err = PCERROR_INVALID_REQUEST; else { if ( req->reqIndex & PCCFLAG_STOP_MEDIATOR ) err = m_cPC.StopMediator(); if ( err == PCERROR_SUCCESS && req->reqIndex & PCCFLAG_START_MEDIATOR ) err = m_cPC.StartMediator(); if ( err == PCERROR_SUCCESS && req->reqIndex & PCCFLAG_DELALL_NAME_RULES ) err = m_cDB.DeleteAllNameRules(); if ( err == PCERROR_SUCCESS && req->reqIndex & PCCFLAG_DELALL_PROC_DEFS ) err = m_cDB.DeleteAllProcDefs(); if ( err == PCERROR_SUCCESS && req->reqIndex & PCCFLAG_DELALL_JOB_DEFS ) err = m_cDB.DeleteAllJobDefs(); }
if ( err != PCERROR_SUCCESS ) return ErrorResponse( err, rsp, outLen );
*outLen = offsetof(PCResponse, rspData);
return TRUE; }
// End of CProcClient.cpp
//============================================================================J McDonald fecit====//
|