//---------------------------------------------------------------------------- // // Copyright (C) Intel Corporation, 2006 - 2007. // // File: main.cpp // // Contents: The main() function. // // Notes: //---------------------------------------------------------------------------- //=================================================== // INCLUDES //=================================================== #include #include #if defined (ACE_HAS_WINCE) # include "ace/ACE.h" #endif /* ACE_HAS_WINCE */ // Configuration related includes #include "Options.h" #include "OptionsUtils.h" #ifdef _SERVICE #include #include "MPSEventLogger.h" #endif /* _SERVICE */ ACE_String_Base absolutePath; ACE_TString logFileNameFull; // Not currently supported in Linux #ifdef ACE_WIN32 ACE_DLL _SOCKS_AUTH_DLL; ACE_DLL _AMT_AUTH_DLL; SOAP_Authenticate _socks_auth_func; SOAP_Authenticate _amt_auth_func; enum Dll_to_be_loaded { SOCKS_DLL = 0, AMT_DLL }; #endif /* ACE_WIN32 */ #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE) MPSEventLoggerWrapper m_pLogger; #endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/ #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined(_SERVICE) #include "MPSService.h" #define SLEEP_TIMEOUT 2 #define RUNNING_ITERATIONS 10 #include "tlhelp32.h" typedef enum {NOANOTHERMPS, ANOTHERMPS, ANOTHERMPSERROR} ANOTHERMPSRC; // Check if the another MPS.exe process is already running. ANOTHERMPSRC IsAnotherMPSRunning() { HANDLE hProcessSnap = NULL; ANOTHERMPSRC Ret = NOANOTHERMPS; PROCESSENTRY32 pe32 = {0}; // Take a snapshot of all processes in the system. hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hProcessSnap == INVALID_HANDLE_VALUE) { ACE_DEBUG((MY_ERROR ACE_TEXT("CreateToolhelp32Snapshot failed err=%d\n"), GetLastError())); return (ANOTHERMPSERROR); } // Fill in the size of the structure before using it. pe32.dwSize = sizeof(PROCESSENTRY32); // Walk the snapshot of the processes, and for each process, // display information. if (Process32First(hProcessSnap, &pe32)) { do { if ((strcmp(pe32.szExeFile,"MPS.exe")==0) && (GetCurrentProcessId()!=pe32.th32ProcessID)) { Ret = ANOTHERMPS; OutputDebugString("AnotherMPSRunning\n"); break; } } while (Process32Next(hProcessSnap, &pe32)); } else { Ret = ANOTHERMPSERROR; // could not walk the list of processes ACE_DEBUG((MY_ERROR ACE_TEXT("could not walk the list of processes \n") )); } // Do not forget to clean up the snapshot object. CloseHandle (hProcessSnap); return (Ret); } int runMPSService(int argc, ACE_TCHAR *argv[]) { // CREATING THE main service MPSService service(MPS_NAME); // CALLING THE INITIALIZATION FUNTION service.InitializeService(SERVICE_WIN32_OWN_PROCESS,SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN,0); // RUNNING THE DISPATCHER. service.StartDispatcher(); return 0; } #endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/ //================================================ // Local Functions //================================================ // Not currently supported in Linux #ifdef ACE_WIN32 STATUS loadDllsAuthFunctions(Dll_to_be_loaded toLoad); bool loadDllAuthFunc(ACE_DLL& dll, SOAP_Authenticate& func , const char* dll_name ); #endif /* ACE_WIN32 */ int run_main (int argc, ACE_TCHAR *argv[]); //int mps_init (int argc, ACE_TCHAR *argv[]); STATUS fillCommonElements(); //================================================ // main //================================================ int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { #if defined(ACE_WIN32) && defined(_SERVICE) // Check first that the MPS process isn't running already: // give it RUNNING_ITERATIONS*SLEEP_TIMEOUT to finish run bool isRunning=true; ANOTHERMPSRC rc; for (int i=0;i<=RUNNING_ITERATIONS;i++) { rc=IsAnotherMPSRunning(); if (rc==NOANOTHERMPS) { isRunning=false; break; } else { if (rc==ANOTHERMPS) { Sleep(2000); } else { // general error, on last iteration set that no another MPS if (i==RUNNING_ITERATIONS) { m_pLogger.LogErrorEvent(MPS_ERROR, MPS_TWO_RUNS_GENERAL_WINDOWS_ERROR); isRunning=false; break; } } } } if (isRunning) { m_pLogger.LogErrorEvent(MPS_ERROR, MPS_TWO_RUNS_FAILURE); return -1; } #endif #if defined(ACE_WIN32) && defined(_SERVICE) ACE_LOG_MSG->priority_mask(LM_ERROR, ACE_Log_Msg::PROCESS); // Set up absolute path TCHAR szPath[MAXPATHLEN]; const char * pszModuleName = NULL; /*if pszModuleName is NULL, GetModuleHandle() will return the handle of the current process*/ if( GetModuleFileName(GetModuleHandle(pszModuleName), szPath, MAXPATHLEN-1 ) == 0 ) { return -1; } absolutePath = szPath; size_t index = absolutePath.rfind('\\'); absolutePath = absolutePath.substr(0, index+1); #else absolutePath = ""; #endif ACE_TString staticConfigFile; staticConfigFile += absolutePath; staticConfigFile += STATIC_CONFIG_FILENAME; ACE_TString dynamicConfigFile; dynamicConfigFile += absolutePath; dynamicConfigFile += DYNAMIC_CONFIG_FILENAME; // Set up Options if ( (Options::createInstance( staticConfigFile.c_str(), dynamicConfigFile.c_str(), ConfigFormats::instance() -> getFormat(STATIC_MANDATORY), ConfigFormats::instance() -> getFormat(STATIC_OPTIONAL), ConfigFormats::instance() -> getFormat(DYNAMIC_MANDATORY), ConfigFormats::instance() -> getFormat(DYNAMIC_OPTIONAL)) != STATUS_SUCCESS) || (Options::instance() == NULL) || (!Options::instance()->isInit())) { ACE_ERROR ((MY_ERROR ACE_TEXT ("Error in initializing configuration file.\n"))); #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE) m_pLogger.LogErrorEvent(MPS_ERROR, MPS_CONFIG_INIT_FAIL_MESSAGE); #endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/ return -1; } // Already checked that Options::instance() is not null if (Options::instance() -> read_static_file() == STATUS_FAILURE) { ACE_ERROR ((MY_ERROR ACE_TEXT ("Error while reading static configuration file.\n"))); #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE) m_pLogger.LogErrorEvent(MPS_ERROR, MPS_CONFIG_STATIC_FAIL_MESSAGE); #endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/ return -1; } if(fillCommonElements() != STATUS_SUCCESS) { ACE_ERROR ((MY_ERROR ACE_TEXT ("Error while filling common elements.\n"))); return -1; } if (Options::instance() -> read_dynamic_file() == STATUS_FAILURE) { #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE) m_pLogger.LogErrorEvent(MPS_ERROR, MPS_CONFIG_DYNAMIC_FAIL_MESSAGE); #endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/ ACE_ERROR_RETURN ((MY_ERROR ACE_TEXT ("Error while reading dynamic configuration file.\n")), -1); } // Not currently supported in Linux #ifdef ACE_WIN32 // Load authentication dll - SOCKS if (loadDllsAuthFunctions(SOCKS_DLL) != STATUS_SUCCESS) { #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE) m_pLogger.LogErrorEvent(MPS_ERROR, MPS_READING_AUTHENTICATION_SOCKS_DLL_FAIL_MESSAGE); #endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/ ACE_ERROR_RETURN((MY_ERROR ACE_TEXT ("Failed loading Socks authentication dll - exit\n")),-1); } // Load authentication dll - AMT if (loadDllsAuthFunctions(AMT_DLL) != STATUS_SUCCESS) { #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE) m_pLogger.LogErrorEvent(MPS_ERROR, MPS_READING_AUTHENTICATION_AMT_DLL_FAIL_MESSAGE); #endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/ ACE_ERROR_RETURN((MY_ERROR ACE_TEXT ("Failed loading AMT authentication dll - exit\n")),-1); } #endif /* ACE_WIN32 */ int retValue; #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE) retValue = runMPSService(argc, argv); #else retValue = run_main (argc, argv); #endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/ // Not currently supported in Linux #ifdef ACE_WIN32 _SOCKS_AUTH_DLL.close(); _AMT_AUTH_DLL.close(); #endif /* ACE_WIN32 */ return retValue; } // Not currently supported in Linux #ifdef ACE_WIN32 STATUS loadDllsAuthFunctions(Dll_to_be_loaded toLoad) { if (toLoad == SOCKS_DLL) { //loading SOCKS Authentication function: const bool* needAuthenticationPtr = getSocksNeedAuthentication(); const ACE_TString* socksDllNamePtr = getSocksDllName(); const ACE_TString* socksDllParametersPtr = getSocksDllParameters(); if (needAuthenticationPtr == NULL || socksDllNamePtr == NULL || socksDllParametersPtr == NULL) { ACE_DEBUG((MY_DEBUG ACE_TEXT("Failed to get SOCKS Authentication details\n"))); return STATUS_FAILURE; } Authentication_Param socks_auth_params( *needAuthenticationPtr, *socksDllNamePtr, *socksDllParametersPtr); if (socks_auth_params._authenticate) { if (loadDllAuthFunc(_SOCKS_AUTH_DLL, _socks_auth_func, socks_auth_params._dllName.c_str() ) == false) { ACE_DEBUG((MY_ERROR ACE_TEXT("Failed loading SOCKS authentication dll = %s. \n"), socks_auth_params._dllName.c_str())); return STATUS_FAILURE; } } else { ACE_DEBUG((MY_NOTICE ACE_TEXT("NOT configures SOCKS authentication - going to accept all SOCKS connections\n"))); _socks_auth_func = NULL; } } else { //loading AMT Authentication function: const bool* needAuthenticationPtr = getAmtNeedAuthentication(); const ACE_TString* amtDllNamePtr = getAmtDllName(); const ACE_TString* amtDllParametersPtr = getAmtDllParameters(); if (needAuthenticationPtr == NULL || amtDllNamePtr == NULL || amtDllParametersPtr == NULL) { ACE_DEBUG((MY_DEBUG ACE_TEXT("Failed to get SOCKS Authentication details\n"))); return STATUS_FAILURE; } Authentication_Param amt_auth_params(*needAuthenticationPtr, *amtDllNamePtr, *amtDllParametersPtr); if (amt_auth_params._authenticate) { if (loadDllAuthFunc(_AMT_AUTH_DLL, _amt_auth_func, amt_auth_params._dllName.c_str() ) == false) { ACE_DEBUG((MY_ERROR ACE_TEXT("Failed loading AMT authentication dll = %s. \n"), amt_auth_params._dllName.c_str())); return STATUS_FAILURE; } } else { ACE_DEBUG((MY_NOTICE ACE_TEXT("APF authentication is not configured- going to accept all APF connections\n"))); _amt_auth_func = NULL; } } return STATUS_SUCCESS; } bool loadDllAuthFunc(ACE_DLL& dll, SOAP_Authenticate& func, const char* dll_name ) { int retval = dll.open (ACE_TEXT(dll_name)); if (retval != 0) { ACE_ERROR_RETURN ((MY_DEBUG,"%s.open", dll_name),false ); } // Cast the void* to function* with a long as intermediate. void *void_ptr = dll.symbol (AUTH_DLL_FUNC_NAME); ptrdiff_t tmp = reinterpret_cast (void_ptr); func = reinterpret_cast (tmp); if (func == 0) { ACE_ERROR_RETURN ((MY_DEBUG ACE_TEXT ("%p\n"), dll.error ()), false); } return true; } #endif /* ACE_WIN32 */