// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2008 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . #if defined(__GNUG__) && !defined(__APPLE__) #pragma implementation "BOINCClientManager.h" #endif #include "stdwx.h" #include "diagnostics.h" #include "LogBOINC.h" #include "BOINCGUIApp.h" #include "MainDocument.h" #include "BOINCBaseFrame.h" #include "AdvancedFrame.h" #include "BOINCClientManager.h" #include "error_numbers.h" #include "procinfo.h" #include "filesys.h" #include "util.h" #ifdef __WXMAC__ enum { NewStyleDaemon = 1, OldStyleDaemon }; #elif defined(__WXMSW__) #include "win_util.h" #include "diagnostics_win.h" extern int diagnostics_get_process_information(PVOID* ppBuffer, PULONG pcbBuffer); EXTERN_C BOOL IsBOINCServiceInstalled(); EXTERN_C BOOL IsBOINCServiceStarting(); EXTERN_C BOOL IsBOINCServiceRunning(); EXTERN_C BOOL IsBOINCServiceStopping(); EXTERN_C BOOL IsBOINCServiceStopped(); EXTERN_C BOOL StartBOINCService(); EXTERN_C BOOL StopBOINCService(); #else #include #endif CBOINCClientManager::CBOINCClientManager() { wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::CBOINCClientManager - Function Begin")); m_bBOINCStartedByManager = false; m_lBOINCCoreProcessId = 0; #ifdef __WXMSW__ m_hBOINCCoreProcess = NULL; #endif wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::CBOINCClientManager - Function End")); } CBOINCClientManager::~CBOINCClientManager() { wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::~CBOINCClientManager - Function Begin")); wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::~CBOINCClientManager - Function End")); } bool CBOINCClientManager::AutoRestart() { if (IsBOINCCoreRunning()) return true; #ifndef __WXMAC__ // Mac can restart Client as a daemon if (! m_bBOINCStartedByManager) return false; #endif m_lBOINCCoreProcessId = 0; StartupBOINCCore(); return true; } bool CBOINCClientManager::IsSystemBooting() { bool bReturnValue = false; #if defined(__WXMSW__) if (GetTickCount() < (1000*60*5)) bReturnValue = true; // If system has been up for less than 5 minutes #elif defined(__WXMAC__) if (TickCount() < (120*60)) bReturnValue = true; // If system has been up for less than 2 minutes #endif return bReturnValue; } int CBOINCClientManager::IsBOINCConfiguredAsDaemon() { bool bReturnValue = false; #if defined(__WXMSW__) if (IsBOINCServiceInstalled()) bReturnValue = 1; #elif defined(__WXMAC__) if ( boinc_file_exists("/Library/LaunchDaemons/edu.berkeley.boinc.plist")) { bReturnValue = NewStyleDaemon; // New-style daemon uses launchd } if (boinc_file_exists("/Library/StartupItems/boinc/boinc") ) { bReturnValue = OldStyleDaemon; // Old-style daemon uses StartupItem } #endif return bReturnValue; } bool CBOINCClientManager::IsBOINCCoreRunning() { wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function Begin")); bool running = false; #ifdef __WXMSW__ char buf[MAX_PATH] = ""; if (IsBOINCServiceInstalled()) { running = (FALSE != IsBOINCServiceStarting()) || (FALSE != IsBOINCServiceRunning()); } else { // Global mutex on Win2k and later // if (IsWindows2000Compatible()) { strcpy(buf, "Global\\"); } strcat( buf, RUN_MUTEX); HANDLE h = CreateMutexA(NULL, true, buf); DWORD err = GetLastError(); if ((h==0) || (err == ERROR_ALREADY_EXISTS)) { running = true; } if (h) { CloseHandle(h); } } #elif defined(__WXMAC__) char path[1024]; static FILE_LOCK file_lock; sprintf(path, "%s/%s", (const char *)wxGetApp().GetDataDirectory().mb_str(), LOCK_FILE_NAME); if (boinc_file_exists(path)) { // If there is no lock file, core is not running if (file_lock.lock(path)) { running = true; } else { file_lock.unlock(path); } } #else std::vector piv; int retval; if (m_lBOINCCoreProcessId) { // Prevent client from being a zombie if (waitpid(m_lBOINCCoreProcessId, 0, WNOHANG) == m_lBOINCCoreProcessId) { m_lBOINCCoreProcessId = 0; } } // Look for BOINC Client in list of all running processes retval = procinfo_setup(piv); if (retval) return false; // Should never happen for (unsigned int i=0; iProcessId) { tstring strProcessName = pProcesses->ProcessName.Buffer; if (downcase_string(strProcessName) == tstring(_T("boinc.exe"))) { TerminateProcessById(pProcesses->ProcessId); break; } } // Move to the next structure if one exists if (!pProcesses->NextEntryDelta) { break; } pProcesses = (PSYSTEM_PROCESSES)(((LPBYTE)pProcesses) + pProcesses->NextEntryDelta); } while (pProcesses); // Release resources if (pBuffer) HeapFree(GetProcessHeap(), NULL, pBuffer); } #else void CBOINCClientManager::KillClient() { std::vector piv; int retval; if (m_lBOINCCoreProcessId) { kill_program(m_lBOINCCoreProcessId); return; } retval = procinfo_setup(piv); if (retval) return; // Should never happen for (unsigned int i=0; iGetConnectedComputerName(strConnectedCompter); if (!pDoc->IsComputerNameLocal(strConnectedCompter)) { RPC_CLIENT rpc; if (!rpc.init("localhost")) { pDoc->m_pNetworkConnection->GetLocalPassword(strPassword); rpc.authorize((const char*)strPassword.mb_str()); if (IsBOINCCoreRunning()) { rpc.quit(); for (iCount = 0; iCount <= 10; iCount++) { if (!bClientQuit && !IsBOINCCoreRunning()) { wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - (localhost) Application Exit Detected")); bClientQuit = true; break; } wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - (localhost) Application Exit NOT Detected, Sleeping...")); ::wxSleep(1); } } else { bClientQuit = true; } } rpc.close(); } else { if (IsBOINCCoreRunning()) { pDoc->CoreClientQuit(); for (iCount = 0; iCount <= 10; iCount++) { if (!bClientQuit && !IsBOINCCoreRunning()) { wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - Application Exit Detected")); bClientQuit = true; break; } wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - Application Exit NOT Detected, Sleeping...")); ::wxSleep(1); } } else { bClientQuit = true; } } } if (!bClientQuit) { KillClient(); } m_lBOINCCoreProcessId = 0; } wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::ShutdownBOINCCore - Function End")); }