From 812ad5cfca0e92b3c1f6dd5702666cb0f5a40c63 Mon Sep 17 00:00:00 2001 From: Rom Walton Date: Fri, 7 Jan 2005 07:32:23 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=5011 --- checkin_notes | 21 ++ client/main.C | 35 ++- client/win/hostinfo_win.cpp | 5 +- client/win/win_idle_tracker.cpp | 401 ++++++++++++++++++++++++++++---- client/win/win_idle_tracker.def | 2 +- client/win/win_idle_tracker.h | 2 +- clientgui/BOINCGUIApp.cpp | 86 ++++--- clientgui/BOINCGUIApp.h | 4 +- clientgui/BOINCTaskBar.cpp | 8 + clientgui/BOINCTaskBar.h | 1 + clientgui/MainFrame.cpp | 2 + clientgui/MainFrame.h | 2 +- 12 files changed, 493 insertions(+), 76 deletions(-) diff --git a/checkin_notes b/checkin_notes index 50fbba4035..b02f746a94 100755 --- a/checkin_notes +++ b/checkin_notes @@ -22148,3 +22148,24 @@ Rom 6 Jan 2005 clientgui/msw/ taskbarex.cpp +Rom 6 Jan 2005 + - Bug Fix: On Windows 2000 machines or better use the GetLastInputInfo + API to determine if the system is idle or not instead of hooking + into each process space. This will fix the possible warnings + that key logging detection tools throw with BOINC is started up. + - Bug Fix: Detect system idle properties across the terminal services + boundry. Thanks to Eric Youngdale for the patch. + - Bug Fix: Detect the condition where the system tick count may have + looped back to zero. + + client/ + main.C + client/win/ + hostinfo_win.cpp + win_idle_tracker.cpp, .h, .def + clientgui/ + BOINCGUIApp.cpp, .h + BOINCTaskBar.cpp, .h + MainFrame.cpp, .h + + \ No newline at end of file diff --git a/client/main.C b/client/main.C index 39fe655c3d..c6e07a209d 100644 --- a/client/main.C +++ b/client/main.C @@ -28,6 +28,10 @@ #include "boinc_win.h" #include "win_service.h" #include "win_net.h" + +typedef BOOL (CALLBACK* IdleTrackerInit)(); +typedef void (CALLBACK* IdleTrackerTerm)(); + #endif #ifndef _WIN32 @@ -237,8 +241,8 @@ int boinc_main_loop(int argc, char** argv) { | BOINC_DIAG_HEAPCHECKENABLED | BOINC_DIAG_TRACETOSTDERR #ifdef _WIN32 - | BOINC_DIAG_REDIRECTSTDERR - | BOINC_DIAG_REDIRECTSTDOUT + //| BOINC_DIAG_REDIRECTSTDERR + //| BOINC_DIAG_REDIRECTSTDOUT #endif ); @@ -338,6 +342,25 @@ int main(int argc, char** argv) { ); } + if(g_hIdleDetectionDll) + { + IdleTrackerInit fnIdleTrackerInit; + fnIdleTrackerInit = (IdleTrackerInit)GetProcAddress(g_hIdleDetectionDll, _T("IdleTrackerInit")); + if(!fnIdleTrackerInit) + { + FreeLibrary(g_hIdleDetectionDll); + g_hIdleDetectionDll = NULL; + } + else + { + if(!fnIdleTrackerInit()) + { + FreeLibrary(g_hIdleDetectionDll); + g_hIdleDetectionDll = NULL; + } + } + } + SERVICE_TABLE_ENTRY dispatchTable[] = { { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main }, @@ -364,9 +387,14 @@ int main(int argc, char** argv) { retval = boinc_main_loop(argc, argv); } - if(g_hIdleDetectionDll) { + IdleTrackerTerm fnIdleTrackerTerm; + fnIdleTrackerTerm = (IdleTrackerTerm)GetProcAddress(g_hIdleDetectionDll, _T("IdleTrackerTerm")); + if(fnIdleTrackerTerm) + { + fnIdleTrackerTerm(); + } if(!FreeLibrary(g_hIdleDetectionDll)) { printf( @@ -374,6 +402,7 @@ int main(int argc, char** argv) { "Failed to cleanup the BOINC Idle Detection Interface\n" ); } + g_hIdleDetectionDll = NULL; } if ( WinsockCleanup() != 0 ) { diff --git a/client/win/hostinfo_win.cpp b/client/win/hostinfo_win.cpp index dcb83dfb45..ce58684309 100755 --- a/client/win/hostinfo_win.cpp +++ b/client/win/hostinfo_win.cpp @@ -22,6 +22,7 @@ #include "client_types.h" #include "filesys.h" #include "util.h" +#include "client_msgs.h" #include "hostinfo_network.h" #include "hostinfo.h" @@ -375,11 +376,11 @@ bool HOST_INFO::host_is_running_on_batteries() { bool HOST_INFO::users_idle(bool check_all_logins, double idle_time_to_run) { typedef DWORD (CALLBACK* GetFn)(); - static GetFn fn = (GetFn)GetProcAddress(g_hIdleDetectionDll, "IdleTrackerGetLastTickCount"); + static GetFn fn = (GetFn)GetProcAddress(g_hIdleDetectionDll, "IdleTrackerGetIdleTickCount"); if (g_hIdleDetectionDll) { if (fn) { - return (GetTickCount() - fn()) / 1000 > 60 * idle_time_to_run; + return (fn() / 1000) > 60 * idle_time_to_run; } } diff --git a/client/win/win_idle_tracker.cpp b/client/win/win_idle_tracker.cpp index 2c379cffb6..475555075b 100644 --- a/client/win/win_idle_tracker.cpp +++ b/client/win/win_idle_tracker.cpp @@ -15,30 +15,209 @@ * Version: 1.0 **/ +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. +#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. +#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0400 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 5.01 or later. +#define _WIN32_IE 0x0501 // Change this to the appropriate value to target IE 6.0 or later. +#endif + #include #include +/** + * The following global data is only shared in this instance of the DLL + **/ +HINSTANCE g_hInstance = NULL; // global instance handle +HMODULE g_hUser32 = NULL; +HANDLE g_hMemoryMappedData = NULL; +BOOL g_bIsWindows2000Compatible = FALSE; +BOOL g_bIsTerminalServicesEnabled = FALSE; + /** * The following global data is SHARED among all instances of the DLL - * (processes); i.e., these are system-wide globals. + * (processes) within a terminal services session. **/ #pragma data_seg(".IdleTrac") // you must define as SHARED in .def HHOOK g_hHkKeyboard = NULL; // handle to the keyboard hook -HHOOK g_hHkMouse = NULL; // handle to the mouse hook -DWORD g_dwLastTick = 0; // tick time of last input event -LONG g_mouseLocX = -1; // x-location of mouse position -LONG g_mouseLocY = -1; // y-location of mouse position +HHOOK g_hHkMouse = NULL; // handle to the mouse hook +LONG g_mouseLocX = -1; // x-location of mouse position +LONG g_mouseLocY = -1; // y-location of mouse position #pragma data_seg() #pragma comment(linker, "/section:.IdleTrac,rws") -HINSTANCE g_hInstance = NULL; // global instance handle +/** + * The following global data is SHARED among all instances of the DLL + * (processes); i.e., these are system-wide globals. + **/ +struct SystemWideIdleData +{ + DWORD dwLastTick; // tick time of last input event +}; + +struct SystemWideIdleData* g_pSystemWideIdleData = NULL; /** - * Get tick count of last keyboard or mouse event + * Define stuff that only exists on Windows 2000 compatible machines **/ -__declspec(dllexport) DWORD IdleTrackerGetLastTickCount() +typedef struct tagLASTINPUTINFO { + UINT cbSize; + DWORD dwTime; +} LASTINPUTINFO, *PLASTINPUTINFO; + +typedef BOOL (WINAPI *GETLASTINPUTINFO)(PLASTINPUTINFO); + +GETLASTINPUTINFO g_fnGetLastInputInfo = NULL; + +/** + * Find out if we are on a Windows 2000 compatible system + **/ +BOOL IsWindows2000Compatible() { - return g_dwLastTick; + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) + return FALSE; + + return (osvi.dwMajorVersion >= 5); +} + +/** + * This function compares the passed in "suite name" string + * to the product suite information stored in the registry. + * This only works on the Terminal Server 4.0 platform. + **/ +BOOL ValidateProductSuite (LPSTR SuiteName) +{ + BOOL rVal = FALSE; + LONG Rslt; + HKEY hKey = NULL; + DWORD Type = 0; + DWORD Size = 0; + LPSTR ProductSuite = NULL; + LPSTR p; + + Rslt = RegOpenKeyA( + HKEY_LOCAL_MACHINE, + "System\\CurrentControlSet\\Control\\ProductOptions", + &hKey + ); + + if (Rslt != ERROR_SUCCESS) + goto exit; + + Rslt = RegQueryValueExA( hKey, "ProductSuite", NULL, &Type, NULL, &Size ); + if (Rslt != ERROR_SUCCESS || !Size) + goto exit; + + ProductSuite = (LPSTR) LocalAlloc( LPTR, Size ); + if (!ProductSuite) + goto exit; + + Rslt = RegQueryValueExA( hKey, "ProductSuite", NULL, &Type, + (LPBYTE) ProductSuite, &Size ); + if (Rslt != ERROR_SUCCESS || Type != REG_MULTI_SZ) + goto exit; + + p = ProductSuite; + while (*p) + { + if (lstrcmpA( p, SuiteName ) == 0) + { + rVal = TRUE; + break; + } + p += (lstrlenA( p ) + 1); + } + +exit: + if (ProductSuite) + LocalFree( ProductSuite ); + + if (hKey) + RegCloseKey( hKey ); + + return rVal; +} + +/** + * This function performs the basic check to see if + * the platform on which it is running is Terminal + * services enabled. Note, this code is compatible on + * all Win32 platforms. For the Windows 2000 platform + * we perform a "lazy" bind to the new product suite + * APIs that were first introduced on that platform. + **/ +BOOL IsTerminalServicesEnabled() +{ + BOOL bResult = FALSE; // assume Terminal Services is not enabled + + DWORD dwVersion; + OSVERSIONINFOEXA osVersionInfo; + DWORDLONG dwlConditionMask = 0; + HMODULE hmodK32 = NULL; + HMODULE hmodNtDll = NULL; + typedef ULONGLONG (WINAPI *PFnVerSetConditionMask)(ULONGLONG,ULONG,UCHAR); + typedef BOOL (WINAPI *PFnVerifyVersionInfoA)(POSVERSIONINFOEXA, DWORD, DWORDLONG); + PFnVerSetConditionMask pfnVerSetConditionMask; + PFnVerifyVersionInfoA pfnVerifyVersionInfoA; + + dwVersion = GetVersion(); + + // are we running NT ? + if (!(dwVersion & 0x80000000)) + { + // Is it Windows 2000 (NT 5.0) or greater ? + if (LOBYTE(LOWORD(dwVersion)) > 4) + { + // In Windows 2000 we need to use the Product Suite APIs + // Don't static link because it won't load on non-Win2000 systems + hmodNtDll = GetModuleHandleA("NTDLL.DLL"); + if (hmodNtDll != NULL) + { + pfnVerSetConditionMask = (PFnVerSetConditionMask )GetProcAddress( hmodNtDll, "VerSetConditionMask"); + if (pfnVerSetConditionMask != NULL) + { + dwlConditionMask = (*pfnVerSetConditionMask)( dwlConditionMask, VER_SUITENAME, VER_AND ); + hmodK32 = GetModuleHandleA( "KERNEL32.DLL" ); + if (hmodK32 != NULL) + { + pfnVerifyVersionInfoA = (PFnVerifyVersionInfoA)GetProcAddress( hmodK32, "VerifyVersionInfoA") ; + if (pfnVerifyVersionInfoA != NULL) + { + ZeroMemory(&osVersionInfo, sizeof(osVersionInfo)); + osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo); + osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL | VER_SUITE_SINGLEUSERTS; + bResult = (*pfnVerifyVersionInfoA)( + &osVersionInfo, + VER_SUITENAME, + dwlConditionMask); + } + } + } + } + } + else + { + // This is NT 4.0 or older + bResult = ValidateProductSuite( "Terminal Server" ); + } + } + + return bResult; } /** @@ -46,8 +225,9 @@ __declspec(dllexport) DWORD IdleTrackerGetLastTickCount() **/ LRESULT CALLBACK KeyboardTracker(int code, WPARAM wParam, LPARAM lParam) { - if (code==HC_ACTION) { - g_dwLastTick = GetTickCount(); + if (code==HC_ACTION) + { + g_pSystemWideIdleData->dwLastTick = GetTickCount(); } return ::CallNextHookEx(g_hHkKeyboard, code, wParam, lParam); } @@ -57,40 +237,164 @@ LRESULT CALLBACK KeyboardTracker(int code, WPARAM wParam, LPARAM lParam) **/ LRESULT CALLBACK MouseTracker(int code, WPARAM wParam, LPARAM lParam) { - if (code==HC_ACTION) { + if (code==HC_ACTION) + { MOUSEHOOKSTRUCT* pStruct = (MOUSEHOOKSTRUCT*)lParam; //we will assume that any mouse msg with the same locations as spurious if (pStruct->pt.x != g_mouseLocX || pStruct->pt.y != g_mouseLocY) { g_mouseLocX = pStruct->pt.x; g_mouseLocY = pStruct->pt.y; - g_dwLastTick = GetTickCount(); + g_pSystemWideIdleData->dwLastTick = GetTickCount(); } } return ::CallNextHookEx(g_hHkMouse, code, wParam, lParam); } +/** + * Get tick count of last keyboard or mouse event + **/ +__declspec(dllexport) DWORD IdleTrackerGetIdleTickCount() +{ + DWORD dwCurrentTickCount = GetTickCount(); + + if ( g_bIsWindows2000Compatible ) + { + LASTINPUTINFO lii; + ZeroMemory( &lii, sizeof(lii) ); + lii.cbSize = sizeof(lii); + g_fnGetLastInputInfo( &lii ); + + /** + * If both values are greater than the system tick count then + * the system must have looped back to the begining. + **/ + if ( ( dwCurrentTickCount < lii.dwTime ) && + ( dwCurrentTickCount < g_pSystemWideIdleData->dwLastTick ) ) + { + lii.dwTime = dwCurrentTickCount; + g_pSystemWideIdleData->dwLastTick = dwCurrentTickCount; + } + + if ( lii.dwTime > g_pSystemWideIdleData->dwLastTick ) + g_pSystemWideIdleData->dwLastTick = lii.dwTime; + } + + return (dwCurrentTickCount - g_pSystemWideIdleData->dwLastTick); +} + /** * Initialize DLL: install kbd/mouse hooks. **/ __declspec(dllexport) BOOL IdleTrackerInit() { - if (g_hHkKeyboard == NULL) { - g_hHkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardTracker, g_hInstance, 0); - } - if (g_hHkMouse == NULL) { - g_hHkMouse = SetWindowsHookEx(WH_MOUSE, MouseTracker, g_hInstance, 0); - } + BOOL bExists = FALSE; + BOOL bResult = FALSE; + SECURITY_ATTRIBUTES sec_attr; + SECURITY_DESCRIPTOR sd; - _ASSERT(g_hHkKeyboard); - _ASSERT(g_hHkMouse); + if ( !IsWindows2000Compatible() ) + { + if ( NULL == g_hHkKeyboard ) + { + g_hHkKeyboard = SetWindowsHookEx( WH_KEYBOARD, KeyboardTracker, g_hInstance, 0 ); + } + if ( NULL == g_hHkMouse ) + { + g_hHkMouse = SetWindowsHookEx( WH_MOUSE, MouseTracker, g_hInstance, 0 ); + } - g_dwLastTick = GetTickCount(); // init count + _ASSERT( g_hHkKeyboard ); + _ASSERT( g_hHkMouse ); + } + else + { + g_hUser32 = LoadLibrary("user32.dll"); + if (g_hUser32) + g_fnGetLastInputInfo = (GETLASTINPUTINFO)GetProcAddress(g_hUser32, "GetLastInputInfo"); + } - if (!g_hHkKeyboard || !g_hHkMouse) - return FALSE; - else - return TRUE; + + g_bIsWindows2000Compatible = IsWindows2000Compatible(); + g_bIsTerminalServicesEnabled = IsTerminalServicesEnabled(); + + + /* + * Create a security descriptor that will allow + * everyone full access. + */ + InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ); + SetSecurityDescriptorDacl( &sd, TRUE, NULL, FALSE ); + + sec_attr.nLength = sizeof(sec_attr); + sec_attr.bInheritHandle = TRUE; + sec_attr.lpSecurityDescriptor = &sd; + + /* + * Create a filemap object that is global for everyone, + * including users logged in via terminal services. + */ + if( g_bIsTerminalServicesEnabled ) + { + g_hMemoryMappedData = + CreateFileMapping( + INVALID_HANDLE_VALUE, + &sec_attr, + PAGE_READWRITE, + 0, + 4096, + "Global\\BoincIdleTracker" + ); + } + else + { + g_hMemoryMappedData = + CreateFileMapping( + INVALID_HANDLE_VALUE, + &sec_attr, + PAGE_READWRITE, + 0, + 4096, + "BoincIdleTracker" + ); + } + + if( NULL != g_hMemoryMappedData ) + { + if( ERROR_ALREADY_EXISTS == GetLastError() ) + bExists = TRUE; + + g_pSystemWideIdleData = (struct SystemWideIdleData*) + MapViewOfFile( + g_hMemoryMappedData, + FILE_MAP_ALL_ACCESS, + 0, + 0, + 0 + ); + } + + if( !bExists ) + { + g_pSystemWideIdleData->dwLastTick = GetTickCount(); + } + + if ( !g_bIsWindows2000Compatible ) + { + if ( !g_hHkKeyboard || !g_hHkMouse ) + bResult = FALSE; + else + bResult = TRUE; + } + else + { + if ( !g_hUser32 || !g_fnGetLastInputInfo || !g_hMemoryMappedData || !g_pSystemWideIdleData ) + bResult = FALSE; + else + bResult = TRUE; + } + + return bResult; } /** @@ -98,19 +402,33 @@ __declspec(dllexport) BOOL IdleTrackerInit() **/ __declspec(dllexport) void IdleTrackerTerm() { - BOOL bResult; - if (g_hHkKeyboard) - { - bResult = UnhookWindowsHookEx(g_hHkKeyboard); - _ASSERT(bResult); - g_hHkKeyboard = NULL; - } - if (g_hHkMouse) - { - bResult = UnhookWindowsHookEx(g_hHkMouse); - _ASSERT(bResult); - g_hHkMouse = NULL; - } + if ( !g_bIsWindows2000Compatible ) + { + BOOL bResult; + if ( g_hHkKeyboard ) + { + bResult = UnhookWindowsHookEx( g_hHkKeyboard ); + _ASSERT( bResult ); + g_hHkKeyboard = NULL; + } + if ( g_hHkMouse ) + { + bResult = UnhookWindowsHookEx(g_hHkMouse); + _ASSERT( bResult ); + g_hHkMouse = NULL; + } + } + else + { + if ( NULL != g_hUser32 ) + FreeLibrary(g_hUser32); + } + + if( NULL != g_pSystemWideIdleData ) + { + UnmapViewOfFile(g_pSystemWideIdleData); + CloseHandle(g_hMemoryMappedData); + } } /** @@ -118,11 +436,12 @@ __declspec(dllexport) void IdleTrackerTerm() **/ int WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { - switch(dwReason) { + switch(dwReason) + { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstance); g_hInstance = hInstance; - break; + break; } return TRUE; } diff --git a/client/win/win_idle_tracker.def b/client/win/win_idle_tracker.def index cc147b0088..beaf825bb0 100644 --- a/client/win/win_idle_tracker.def +++ b/client/win/win_idle_tracker.def @@ -6,4 +6,4 @@ EXPORTS ; Explicit exports can go here IdleTrackerInit IdleTrackerTerm - IdleTrackerGetLastTickCount + IdleTrackerGetIdleTickCount diff --git a/client/win/win_idle_tracker.h b/client/win/win_idle_tracker.h index 4313ce1147..d423f82278 100644 --- a/client/win/win_idle_tracker.h +++ b/client/win/win_idle_tracker.h @@ -17,4 +17,4 @@ __declspec(dllimport) BOOL IdleTrackerInit(); __declspec(dllimport) void IdleTrackerTerm(); -__declspec(dllimport) DWORD IdleTrackerGetLastTickCount(); +__declspec(dllimport) DWORD IdleTrackerGetIdleTickCount(); diff --git a/clientgui/BOINCGUIApp.cpp b/clientgui/BOINCGUIApp.cpp index 27e7628f98..a7436c5549 100644 --- a/clientgui/BOINCGUIApp.cpp +++ b/clientgui/BOINCGUIApp.cpp @@ -34,6 +34,7 @@ #ifdef __WXMSW__ typedef BOOL (CALLBACK* IdleTrackerInit)(); typedef void (CALLBACK* IdleTrackerTerm)(); +typedef DWORD (CALLBACK* IdleTrackerGetIdleTickCount)(); #endif @@ -313,25 +314,37 @@ void CBOINCGUIApp::ShutdownBOINCCore() if ( m_bBOINCStartedByManager ) { +#ifdef __WXMSW__ + DWORD dwExitCode; + if ( GetExitCodeProcess( m_hBOINCCoreProcess, &dwExitCode ) ) + { + if ( STILL_ACTIVE == dwExitCode ) + { +#else if ( wxProcess::Exists( m_lBOINCCoreProcessId ) ) { - m_pDocument->CoreClientQuit(); - for ( iCount = 0; iCount <= 10; iCount++ ) - { -#ifdef __WXMSW__ - DWORD dwExitCode; - if ( !bClientQuit && GetExitCodeProcess( m_hBOINCCoreProcess, &dwExitCode ) ) - { - if ( STILL_ACTIVE != dwExitCode ) - { - bClientQuit = true; - continue; - } - } #endif - ::wxSleep(1); + m_pDocument->CoreClientQuit(); + for ( iCount = 0; iCount <= 10; iCount++ ) + { +#ifdef __WXMSW__ + if ( !bClientQuit && GetExitCodeProcess( m_hBOINCCoreProcess, &dwExitCode ) ) + { + if ( STILL_ACTIVE != dwExitCode ) + { + bClientQuit = true; + continue; + } + } +#endif + ::wxSleep(1); + } +#ifdef __WXMSW } - + } +#else + } +#endif if ( !bClientQuit ) ::wxKill( m_lBOINCCoreProcessId ); } @@ -343,23 +356,23 @@ wxInt32 CBOINCGUIApp::StartupSystemIdleDetection() { #ifdef __WXMSW__ // load dll and start idle detection - m_hIdleDll = LoadLibrary("boinc.dll"); - if(m_hIdleDll) + m_hIdleDetectionDll = LoadLibrary("boinc.dll"); + if(m_hIdleDetectionDll) { IdleTrackerInit fn; - fn = (IdleTrackerInit)GetProcAddress(m_hIdleDll, wxT("IdleTrackerInit")); + fn = (IdleTrackerInit)GetProcAddress(m_hIdleDetectionDll, wxT("IdleTrackerInit")); if(!fn) { - FreeLibrary(m_hIdleDll); - m_hIdleDll = NULL; + FreeLibrary(m_hIdleDetectionDll); + m_hIdleDetectionDll = NULL; return -1; } else { if(!fn()) { - FreeLibrary(m_hIdleDll); - m_hIdleDll = NULL; + FreeLibrary(m_hIdleDetectionDll); + m_hIdleDetectionDll = NULL; return -1; } } @@ -372,9 +385,32 @@ wxInt32 CBOINCGUIApp::StartupSystemIdleDetection() wxInt32 CBOINCGUIApp::ShutdownSystemIdleDetection() { #ifdef __WXMSW__ - if(m_hIdleDll) { + if(m_hIdleDetectionDll) { IdleTrackerTerm fn; - fn = (IdleTrackerTerm)GetProcAddress(m_hIdleDll, wxT("IdleTrackerTerm")); + fn = (IdleTrackerTerm)GetProcAddress(m_hIdleDetectionDll, wxT("IdleTrackerTerm")); + if(fn) + { + fn(); + } + else + { + return -1; + } + FreeLibrary(m_hIdleDetectionDll); + m_hIdleDetectionDll = NULL; + } +#endif + return 0; +} + + +wxInt32 CBOINCGUIApp::UpdateSystemIdleDetection() +{ +#ifdef __WXMSW__ + if (m_hIdleDetectionDll) + { + IdleTrackerGetIdleTickCount fn; + fn = (IdleTrackerGetIdleTickCount)GetProcAddress(m_hIdleDetectionDll, wxT("IdleTrackerGetIdleTickCount")); if(fn) { fn(); @@ -383,8 +419,6 @@ wxInt32 CBOINCGUIApp::ShutdownSystemIdleDetection() { return -1; } - FreeLibrary(m_hIdleDll); - m_hIdleDll = NULL; } #endif return 0; diff --git a/clientgui/BOINCGUIApp.h b/clientgui/BOINCGUIApp.h index e78036651a..49dd6bdba3 100644 --- a/clientgui/BOINCGUIApp.h +++ b/clientgui/BOINCGUIApp.h @@ -72,7 +72,7 @@ protected: #ifdef __WXMSW__ HANDLE m_hBOINCCoreProcess; - HINSTANCE m_hIdleDll; + HINSTANCE m_hIdleDetectionDll; #endif wxString m_strDefaultWindowStation; @@ -82,6 +82,8 @@ public: bool OnInit(); + wxInt32 UpdateSystemIdleDetection(); + CMainFrame* GetFrame() { return m_pFrame; }; CMainDocument* GetDocument() { return m_pDocument; }; #ifndef NOTASKBAR diff --git a/clientgui/BOINCTaskBar.cpp b/clientgui/BOINCTaskBar.cpp index 4e931778bf..a085cf58f7 100644 --- a/clientgui/BOINCTaskBar.cpp +++ b/clientgui/BOINCTaskBar.cpp @@ -42,6 +42,7 @@ BEGIN_EVENT_TABLE (CTaskBarIcon, wxTaskBarIconEx) EVT_MENU_RANGE(ID_TB_NETWORKRUNALWAYS, ID_TB_NETWORKSUSPEND, CTaskBarIcon::OnNetworkSelection) EVT_MENU(wxID_ABOUT, CTaskBarIcon::OnAbout) EVT_MENU(wxID_EXIT, CTaskBarIcon::OnExit) + EVT_IDLE(CTaskBarIcon::OnIdle) EVT_CLOSE(CTaskBarIcon::OnClose) EVT_TASKBAR_MOVE(CTaskBarIcon::OnMouseMove) EVT_TASKBAR_LEFT_DCLICK(CTaskBarIcon::OnLButtonDClick) @@ -162,6 +163,13 @@ void CTaskBarIcon::OnExit( wxCommandEvent& WXUNUSED(event) ) } +void CTaskBarIcon::OnIdle( wxIdleEvent& event ) +{ + wxGetApp().UpdateSystemIdleDetection(); + event.Skip(); +} + + void CTaskBarIcon::OnClose( wxCloseEvent& event ) { ResetTaskBar(); diff --git a/clientgui/BOINCTaskBar.h b/clientgui/BOINCTaskBar.h index 124ca7c3c2..88d53f58b4 100644 --- a/clientgui/BOINCTaskBar.h +++ b/clientgui/BOINCTaskBar.h @@ -49,6 +49,7 @@ public: void OnAbout( wxCommandEvent& event ); void OnExit( wxCommandEvent& event ); + void OnIdle( wxIdleEvent& event ); void OnClose( wxCloseEvent& event ); void OnMouseMove( wxTaskBarIconEvent& event ); diff --git a/clientgui/MainFrame.cpp b/clientgui/MainFrame.cpp index fbfea4d413..92ebaefe92 100644 --- a/clientgui/MainFrame.cpp +++ b/clientgui/MainFrame.cpp @@ -822,6 +822,8 @@ void CMainFrame::OnIdle( wxIdleEvent& event ) { wxLogTrace(wxT("Function Start/End"), wxT("CMainFrame::OnIdle - Function Begin")); + wxGetApp().UpdateSystemIdleDetection(); + CMainDocument* pDoc = wxGetApp().GetDocument(); if ( NULL != pDoc ) diff --git a/clientgui/MainFrame.h b/clientgui/MainFrame.h index 22979855fd..760684c2ee 100644 --- a/clientgui/MainFrame.h +++ b/clientgui/MainFrame.h @@ -53,7 +53,7 @@ public: void OnUpdateActivitySelection( wxUpdateUIEvent& event ); void OnUpdateNetworkSelection( wxUpdateUIEvent& event ); - void OnIdle ( wxIdleEvent& event ); + void OnIdle( wxIdleEvent& event ); void OnClose( wxCloseEvent& event ); void OnSize( wxSizeEvent& event ); void OnChar( wxKeyEvent& event );