|
|
/*======================================================================================//
| //
|Copyright (c) 1998, 1999 Sequent Computer Systems, Incorporated. All rights reserved. //
| //
|Description: //
| //
| Windows 2000 Process Control 'mediator' process. Holds handles and completion port //
| for created jobs so that their names are not lost if the ProcCon service is stopped //
| or goes away. //
| //
|Created: //
| //
| Jarl McDonald 04-99 //
| //
|Revision History: //
| //
|=======================================================================================*/ #include "..\SERVICE\ProcConSvc.h"
//=======================================================================================
// Main...
//=======================================================================================
int _cdecl main( void ) {
// Load our strings so we have proper reporting, etc.
PCLoadStrings(); CVersion *versionInfo = new CVersion( GetModuleHandle( NULL ) );
static const TCHAR * const msgs[] = { PROCCON_MEDIATOR_DISP_NAME, PROCCON_SVC_DISP_NAME };
// Make sure we're not already running and set up mutual exclusion...
if ( !PCSetIsRunning( PC_MEDIATOR_EXCLUSION, PROCCON_MEDIATOR_DISP_NAME ) ) return 1;
// Get our event -- it must already exist (created by the service) or we quit...
HANDLE hSvcEvent = CreateEvent( NULL, FALSE, FALSE, PC_MEDIATOR_EVENT ); if ( !hSvcEvent ) { PCLogUnExError( PC_MEDIATOR_EVENT, TEXT("MediatorCreateEvent") ); return 1; } else if ( GetLastError() != ERROR_ALREADY_EXISTS ) { PCLogMessage( PC_MEDIATE_SVC_NEVER_STARTED, EVENTLOG_ERROR_TYPE, ENTRY_COUNT(msgs), msgs ); CloseHandle( hSvcEvent ); return 1; }
// Get our file mapping object -- it must already exist (created by the service) or we quit...
HANDLE hSvcJobMap = CreateFileMapping( HANDLE_FF_64, NULL, PAGE_READWRITE, 0, sizeof(PCMediateHdr), PC_MEDIATOR_FILEMAP ); if ( !hSvcJobMap ) { PCLogUnExError( PC_MEDIATOR_FILEMAP, TEXT("MediatorCreateMapping") ); CloseHandle( hSvcEvent ); return 1; } else if ( GetLastError() != ERROR_ALREADY_EXISTS ) { PCLogMessage( PC_MEDIATE_SVC_NEVER_STARTED, EVENTLOG_ERROR_TYPE, ENTRY_COUNT(msgs), msgs ); CloseHandle( hSvcJobMap ); CloseHandle( hSvcEvent ); return 1; }
// Get our data pointer -- quit if we can't since we'd have nothing to do.
PCMediateHdr *jobData = (PCMediateHdr *) MapViewOfFile( hSvcJobMap, FILE_MAP_WRITE, 0, 0, 0 ); if ( !jobData ) { PCLogUnExError( PC_MEDIATOR_FILEMAP, TEXT("MediatorMapJobData") ); CloseHandle( hSvcJobMap ); CloseHandle( hSvcEvent ); return 1; }
// Update data about us in case we restarted...
jobData->medProcessInfo.dwProcessId = GetCurrentProcessId(); jobData->medProcessInfo.dwThreadId = GetCurrentThreadId();
_tcsncpy( jobData->medFileVersion, versionInfo->GetFileVersion(), VERSION_STRING_LEN ); _tcsncpy( jobData->medProductVersion, versionInfo->GetProductVersion(), VERSION_STRING_LEN ); _tcsncpy( jobData->medFileFlags, versionInfo->GetFileFlags(), VERSION_STRING_LEN );
// Duplicate ProcCon's completion port handle here to preserve it...
HANDLE hServiceProc = OpenProcess( PROCESS_DUP_HANDLE, FALSE, (DWORD) jobData->svcPID ); // truncation of PID to 32-bit
if ( !hServiceProc ) { PCLogUnExError( jobData->svcPID, TEXT("MediatorOpenSvcPID") ); CloseHandle( hSvcJobMap ); CloseHandle( hSvcEvent ); return 1; }
if ( !DuplicateHandle( hServiceProc, jobData->svcPortHandle, GetCurrentProcess(), &jobData->medPortHandle, NULL, FALSE, DUPLICATE_SAME_ACCESS ) ) PCLogUnExError( TEXT("ComplPort"), TEXT("MediatorDupHandle") );
CloseHandle( hServiceProc );
// We're ready to run. On the first pass we'll open all jobs. Otherwise just the new jobs.
ResetEvent( hSvcEvent ); // don't need to be signalled for first pass
for ( BOOL firstPass = TRUE; ; firstPass = FALSE ) { // duplicate all chained block handles as needed...
jobData->MedChainBlocks( firstPass ); // duplicate all job object handles in chain as needed...
for ( PCMediateBlock *blk = &jobData->groupBlock; blk; blk = jobData->NextBlock( blk ) ) { for ( PCULONG32 grp = 0; grp < blk->groupCount; ++grp ) { if ( firstPass && !(blk->group[grp].groupFlags & PCMEDIATE_CLOSE_ME) ) { blk->group[grp].mediatorHandle = OpenJobObject( JOB_OBJECT_QUERY, FALSE, blk->group[grp].groupName ); if ( !blk->group[grp].mediatorHandle ) PCLogUnExError( blk->group[grp].groupName, TEXT("MediatorOpenJob1") ); } else if ( blk->group[grp].groupFlags & PCMEDIATE_CLOSE_ME ) { if ( blk->group[grp].mediatorHandle && !CloseHandle( blk->group[grp].mediatorHandle ) ) PCLogUnExError( blk->group[grp].groupName, TEXT("MediatorCloseJob") ); blk->group[grp].mediatorHandle = NULL; } else if ( !blk->group[grp].mediatorHandle ) { blk->group[grp].mediatorHandle = OpenJobObject( JOB_OBJECT_QUERY, FALSE, blk->group[grp].groupName ); if ( !blk->group[grp].mediatorHandle ) PCLogUnExError( blk->group[grp].groupName, TEXT("MediatorOpenJob2") ); } } } // Wait for signal that a new job exists.
// If the wait fails, just exit, else we reprocess job list...
if ( WAIT_OBJECT_0 != WaitForSingleObject( hSvcEvent, INFINITE ) ) break; }
CloseHandle( hSvcJobMap ); CloseHandle( hSvcEvent ); return 0; }
|