diff --git a/checkin_notes b/checkin_notes
index 1fc7e6a281..9de35e9dfb 100644
--- a/checkin_notes
+++ b/checkin_notes
@@ -6241,3 +6241,34 @@ David 6 Aug 2008
sched/
sched_config.C,h
sched_result.C
+
+Rom 7 Aug 2008
+ - CLIENT/MGR/TRAY: When installed on Vista and UAC is turned on
+ the user by default cannot create globally shared objects. This
+ becomes a problem when protected application mode is turned off
+ for keyboard and mouse detection. Basically all of the components
+ would start up and fail to create the shared memory segment
+ and report the error through stderr which most people don't look
+ at by default.
+
+ The client is now the only component that is allowed to create the
+ shared memory segment, if creating the global segment fails it'll
+ create a local one instead. Both the tray and manager now just attach
+ to the existing segment, first trying the global one then the local
+ one.
+
+
+ client/
+ main.C
+ clientgui/
+ BOINCGUIApp.cpp, .h
+ clientlib/win/
+ boinc_dll.cpp
+ IdleTracker.cpp
+ clienttray/
+ tray_win.cpp, .h
+ win_build/
+ boinc.sln
+ boinctray.vcproj
+
+
\ No newline at end of file
diff --git a/client/main.C b/client/main.C
index 6ad1623802..62d6ae8788 100644
--- a/client/main.C
+++ b/client/main.C
@@ -33,6 +33,8 @@ static bool requested_suspend = false;
static bool requested_resume = false;
typedef BOOL (CALLBACK* ClientLibraryStartup)();
+typedef BOOL (CALLBACK* IdleTrackerStartup)();
+typedef void (CALLBACK* IdleTrackerShutdown)();
typedef void (CALLBACK* ClientLibraryShutdown)();
#ifndef _T
#define _T(X) X
@@ -410,9 +412,28 @@ int initialize() {
#ifdef _WIN32
if(g_hClientLibraryDll) {
ClientLibraryStartup fnClientLibraryStartup;
+ IdleTrackerStartup fnIdleTrackerStartup;
+
fnClientLibraryStartup = (ClientLibraryStartup)GetProcAddress(g_hClientLibraryDll, _T("ClientLibraryStartup"));
if(fnClientLibraryStartup) {
if(!fnClientLibraryStartup()) {
+ stprintf(event_message,
+ TEXT("BOINC Core Client Error Message\n"
+ "Failed to initialize the BOINC Client Library Interface.\n"
+ "BOINC will not be able to determine if the user is idle or not...\n"
+ "Load failed: %s\n"), windows_error_string(event_message, sizeof(event_message))
+ );
+ if (!gstate.executing_as_daemon) {
+ fprintf(stderr, event_message);
+ } else {
+ LogEventErrorMessage(event_message);
+ }
+ }
+ }
+
+ fnIdleTrackerStartup = (IdleTrackerStartup)GetProcAddress(g_hClientLibraryDll, _T("IdleTrackerStartup"));
+ if(fnIdleTrackerStartup) {
+ if(!fnIdleTrackerStartup()) {
stprintf(event_message,
TEXT("BOINC Core Client Error Message\n"
"Failed to initialize the BOINC Idle Detection Interface.\n"
@@ -427,6 +448,7 @@ int initialize() {
}
}
}
+
#endif
return 0;
}
@@ -514,11 +536,19 @@ int finalize() {
#ifdef _WIN32
if(g_hClientLibraryDll) {
+ IdleTrackerShutdown fnIdleTrackerShutdown;
ClientLibraryShutdown fnClientLibraryShutdown;
+
+ fnIdleTrackerShutdown = (IdleTrackerShutdown)GetProcAddress(g_hClientLibraryDll, _T("IdleTrackerShutdown"));
+ if(fnIdleTrackerShutdown) {
+ fnIdleTrackerShutdown();
+ }
+
fnClientLibraryShutdown = (ClientLibraryShutdown)GetProcAddress(g_hClientLibraryDll, _T("ClientLibraryShutdown"));
if(fnClientLibraryShutdown) {
fnClientLibraryShutdown();
}
+
if(!FreeLibrary(g_hClientLibraryDll)) {
stprintf(event_message,
TEXT("BOINC Core Client Error Message\n"
@@ -527,12 +557,14 @@ int finalize() {
),
windows_error_string(event_message, sizeof(event_message))
);
+
if (!gstate.executing_as_daemon) {
fprintf(stderr, event_message);
} else {
LogEventErrorMessage(event_message);
}
}
+
g_hClientLibraryDll = NULL;
}
diff --git a/clientgui/BOINCGUIApp.cpp b/clientgui/BOINCGUIApp.cpp
index 1d2e5ee9f1..4b2f0a29ce 100644
--- a/clientgui/BOINCGUIApp.cpp
+++ b/clientgui/BOINCGUIApp.cpp
@@ -55,6 +55,8 @@ static bool s_bSkipExitConfirmation = false;
#ifdef __WXMSW__
EXTERN_C BOOL ClientLibraryStartup();
+EXTERN_C BOOL IdleTrackerAttach();
+EXTERN_C void IdleTrackerDetach();
EXTERN_C void ClientLibraryShutdown();
EXTERN_C DWORD BOINCGetIdleTickCount();
#endif
@@ -397,6 +399,7 @@ bool CBOINCGUIApp::OnInit() {
// Startup the System Idle Detection code
ClientLibraryStartup();
+ IdleTrackerAttach();
#ifdef __WXMAC__
s_bSkipExitConfirmation = false;
@@ -450,6 +453,7 @@ bool CBOINCGUIApp::OnInit() {
int CBOINCGUIApp::OnExit() {
// Shutdown the System Idle Detection code
+ IdleTrackerDetach();
ClientLibraryShutdown();
if (m_pDocument) {
@@ -613,6 +617,22 @@ int CBOINCGUIApp::ClientLibraryStartup() {
}
+int CBOINCGUIApp::IdleTrackerAttach() {
+#ifdef __WXMSW__
+ ::IdleTrackerAttach();
+#endif
+ return 0;
+}
+
+
+int CBOINCGUIApp::IdleTrackerDetach() {
+#ifdef __WXMSW__
+ ::IdleTrackerDetach();
+#endif
+ return 0;
+}
+
+
int CBOINCGUIApp::ClientLibraryShutdown() {
#ifdef __WXMSW__
::ClientLibraryShutdown();
diff --git a/clientgui/BOINCGUIApp.h b/clientgui/BOINCGUIApp.h
index 2949d94b01..0652be0dc6 100644
--- a/clientgui/BOINCGUIApp.h
+++ b/clientgui/BOINCGUIApp.h
@@ -55,6 +55,8 @@ protected:
#endif
int ClientLibraryStartup();
+ int IdleTrackerAttach();
+ int IdleTrackerDetach();
int ClientLibraryShutdown();
wxConfig* m_pConfig;
diff --git a/clientlib/win/IdleTracker.cpp b/clientlib/win/IdleTracker.cpp
index c86f46a36e..10720aabec 100644
--- a/clientlib/win/IdleTracker.cpp
+++ b/clientlib/win/IdleTracker.cpp
@@ -136,10 +136,11 @@ EXTERN_C __declspec(dllexport) DWORD BOINCGetIdleTickCount()
return (dwCurrentTickCount - dwLastTickCount);
}
+
/**
* Initialize DLL: install kbd/mouse hooks.
**/
-BOOL IdleTrackerStartup()
+EXTERN_C __declspec(dllexport) BOOL IdleTrackerStartup()
{
BOOL bExists = FALSE;
BOOL bResult = FALSE;
@@ -206,6 +207,18 @@ BOOL IdleTrackerStartup()
4096,
"Global\\BoincIdleTracker"
);
+ if( NULL == g_hMemoryMappedData )
+ {
+ g_hMemoryMappedData =
+ CreateFileMapping(
+ INVALID_HANDLE_VALUE,
+ &sec_attr,
+ PAGE_READWRITE,
+ 0,
+ 4096,
+ "BoincIdleTracker"
+ );
+ }
if( NULL != g_hMemoryMappedData )
{
@@ -249,10 +262,131 @@ BOOL IdleTrackerStartup()
return bResult;
}
+
+/**
+ * Initialize DLL: install kbd/mouse hooks.
+ **/
+EXTERN_C __declspec(dllexport) BOOL IdleTrackerAttach()
+{
+ BOOL bExists = FALSE;
+ BOOL bResult = FALSE;
+ SECURITY_ATTRIBUTES sec_attr;
+ SECURITY_DESCRIPTOR sd;
+
+
+ g_bIsWindows2000Compatible = IsWindows2000Compatible();
+ g_bIsTerminalServicesEnabled = IsTerminalServicesEnabled();
+
+
+ if ( !g_bIsWindows2000Compatible )
+ {
+ if ( NULL == g_hHkKeyboard )
+ {
+ g_hHkKeyboard = SetWindowsHookEx(
+ WH_KEYBOARD,
+ KeyboardTracker,
+ g_hModule,
+ 0
+ );
+ }
+ if ( NULL == g_hHkMouse )
+ {
+ g_hHkMouse = SetWindowsHookEx(
+ WH_MOUSE,
+ MouseTracker,
+ g_hModule,
+ 0
+ );
+ }
+
+ _ASSERT( g_hHkKeyboard );
+ _ASSERT( g_hHkMouse );
+ }
+ else
+ {
+ g_hUser32 = LoadLibrary("user32.dll");
+ if (g_hUser32)
+ g_fnGetLastInputInfo = (GETLASTINPUTINFO)GetProcAddress(g_hUser32, "GetLastInputInfo");
+
+
+ /*
+ * 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.
+ */
+ g_hMemoryMappedData =
+ OpenFileMapping(
+ FILE_MAP_READ | FILE_MAP_WRITE,
+ FALSE,
+ "Global\\BoincIdleTracker"
+ );
+ if( NULL == g_hMemoryMappedData )
+ {
+ g_hMemoryMappedData =
+ OpenFileMapping(
+ FILE_MAP_READ | FILE_MAP_WRITE,
+ FALSE,
+ "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
+ );
+
+ _ASSERT( g_pSystemWideIdleData );
+ }
+
+ if( !bExists && g_pSystemWideIdleData )
+ {
+ 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;
+}
+
+
/**
* Terminate DLL: remove hooks.
**/
-void IdleTrackerShutdown()
+EXTERN_C __declspec(dllexport) void IdleTrackerDetach()
{
if ( !g_bIsWindows2000Compatible )
{
@@ -283,4 +417,40 @@ void IdleTrackerShutdown()
}
}
+
+/**
+ * Terminate DLL: remove hooks.
+ **/
+EXTERN_C __declspec(dllexport) void IdleTrackerShutdown()
+{
+ 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_pSystemWideIdleData )
+ {
+ UnmapViewOfFile(g_pSystemWideIdleData);
+ CloseHandle(g_hMemoryMappedData);
+ }
+
+ if ( NULL != g_hUser32 )
+ FreeLibrary(g_hUser32);
+ }
+}
+
+
const char *BOINC_RCSID_14d432d5b3 = "$Id$";
diff --git a/clientlib/win/boinc_dll.cpp b/clientlib/win/boinc_dll.cpp
index 294fc130c1..89f7f6ab6d 100644
--- a/clientlib/win/boinc_dll.cpp
+++ b/clientlib/win/boinc_dll.cpp
@@ -44,14 +44,10 @@ BOOL APIENTRY DllMain(
EXTERN_C __declspec(dllexport) BOOL ClientLibraryStartup()
{
- if (!IdleTrackerStartup())
- return FALSE;
-
return TRUE;
}
EXTERN_C __declspec(dllexport) void ClientLibraryShutdown()
{
- IdleTrackerShutdown();
}
diff --git a/clienttray/tray_win.cpp b/clienttray/tray_win.cpp
index 74b106421f..bfaf1defdf 100644
--- a/clienttray/tray_win.cpp
+++ b/clienttray/tray_win.cpp
@@ -22,9 +22,11 @@
#include "tray_win.h"
- BOOL IdleTrackerStartup();
+EXTERN_C BOOL ClientLibraryStartup();
+EXTERN_C BOOL IdleTrackerAttach();
+EXTERN_C void IdleTrackerDetach();
+EXTERN_C void ClientLibraryShutdown();
EXTERN_C DWORD BOINCGetIdleTickCount();
- void IdleTrackerShutdown();
HMODULE g_hModule = NULL;
static CBOINCTray* gspBOINCTray = NULL;
@@ -41,6 +43,7 @@ CBOINCTray::CBOINCTray() {
gspBOINCTray = this;
m_hDataManagementThread = NULL;
m_bClientLibraryInitialized = FALSE;
+ m_bIdleTrackerInitialized = FALSE;
}
@@ -48,9 +51,6 @@ CBOINCTray::CBOINCTray() {
//
INT CBOINCTray::Run( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
- // Initialize the BOINC client library to setup the idle tracking system.
- m_bClientLibraryInitialized = IdleTrackerStartup();
-
if (!hPrevInstance) {
// Register an appropriate window class for the primary window
WNDCLASS cls;
@@ -87,7 +87,8 @@ INT CBOINCTray::Run( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
// Cleanup and shutdown the BOINC client library idle tracking system.
- IdleTrackerShutdown();
+ IdleTrackerDetach();
+ ClientLibraryShutdown();
return msg.wParam;
}
@@ -132,12 +133,17 @@ BOOL CBOINCTray::DestroyDataManagementThread() {
//
DWORD WINAPI CBOINCTray::DataManagementProc() {
while (true) {
- if (!m_bClientLibraryInitialized) {
+ if (!m_bClientLibraryInitialized || !m_bIdleTrackerInitialized) {
// On Vista systems, only elevated processes can create shared memory
// area's across various user sessions. In this case we need to wait
// for BOINC to create the shared memory area and then boinctray can
// successfully attach to it. What a PITA.
- m_bClientLibraryInitialized = IdleTrackerStartup();
+ if (!m_bClientLibraryInitialized) {
+ m_bClientLibraryInitialized = ClientLibraryStartup();
+ }
+ if (m_bClientLibraryInitialized && !m_bIdleTrackerInitialized) {
+ m_bIdleTrackerInitialized = IdleTrackerAttach();
+ }
}
BOINCGetIdleTickCount();
diff --git a/clienttray/tray_win.h b/clienttray/tray_win.h
index 7177ed4821..6cb07de53c 100644
--- a/clienttray/tray_win.h
+++ b/clienttray/tray_win.h
@@ -42,6 +42,7 @@ protected:
HANDLE m_hDataManagementThread;
BOOL m_bClientLibraryInitialized;
+ BOOL m_bIdleTrackerInitialized;
};
#endif
diff --git a/win_build/boinc.sln b/win_build/boinc.sln
index 3b0277d224..715681bea8 100644
--- a/win_build/boinc.sln
+++ b/win_build/boinc.sln
@@ -2,8 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boinc", "boinc_cli_curl.vcproj", "{C04F0FCC-BB5D-4627-8656-6173B28BD69E}"
ProjectSection(ProjectDependencies) = postProject
- {E8F6BD7E-461A-4733-B7D8-37B09A099ED8} = {E8F6BD7E-461A-4733-B7D8-37B09A099ED8}
{B06280CB-82A4-46DE-8956-602643078BDF} = {B06280CB-82A4-46DE-8956-602643078BDF}
+ {E8F6BD7E-461A-4733-B7D8-37B09A099ED8} = {E8F6BD7E-461A-4733-B7D8-37B09A099ED8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boinc_dll", "boinc_dll.vcproj", "{B06280CB-82A4-46DE-8956-602643078BDF}"
@@ -12,14 +12,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boinc_ss", "boinc_ss.vcproj
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boinccmd", "boinccmd.vcproj", "{8F37E1F3-3A68-4A1D-9579-A1210BDD055E}"
ProjectSection(ProjectDependencies) = postProject
- {E8F6BD7E-461A-4733-B7D8-37B09A099ED8} = {E8F6BD7E-461A-4733-B7D8-37B09A099ED8}
{C04F0FCC-BB5D-4627-8656-6173B28BD69E} = {C04F0FCC-BB5D-4627-8656-6173B28BD69E}
+ {E8F6BD7E-461A-4733-B7D8-37B09A099ED8} = {E8F6BD7E-461A-4733-B7D8-37B09A099ED8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boincmgr", "boincmgr_curl.vcproj", "{06113715-AC51-4E91-8B9D-C987CABE0920}"
ProjectSection(ProjectDependencies) = postProject
- {B06280CB-82A4-46DE-8956-602643078BDF} = {B06280CB-82A4-46DE-8956-602643078BDF}
{C04F0FCC-BB5D-4627-8656-6173B28BD69E} = {C04F0FCC-BB5D-4627-8656-6173B28BD69E}
+ {B06280CB-82A4-46DE-8956-602643078BDF} = {B06280CB-82A4-46DE-8956-602643078BDF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libboinc", "libboinc.vcproj", "{E8F6BD7E-461A-4733-B7D8-37B09A099ED8}"
@@ -32,6 +32,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boincsim", "sim.vcproj", "{B950E31B-C075-4F6D-8A2B-25EAE9D46C93}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boinctray", "boinctray.vcproj", "{4A2C5963-6A8D-4DA1-A312-C3D749B2EA81}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B06280CB-82A4-46DE-8956-602643078BDF} = {B06280CB-82A4-46DE-8956-602643078BDF}
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/win_build/boinctray.vcproj b/win_build/boinctray.vcproj
index eda40baecf..a129b4dcaf 100644
--- a/win_build/boinctray.vcproj
+++ b/win_build/boinctray.vcproj
@@ -676,18 +676,10 @@
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
-
-
-
-
-
-
-
-