/*======================================================================================// | // |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; }