- 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

svn path=/trunk/boinc/; revision=15767
This commit is contained in:
Rom Walton 2008-08-07 16:59:52 +00:00
parent b5b3fd43b7
commit a2771e5d33
10 changed files with 278 additions and 33 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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();

View File

@ -55,6 +55,8 @@ protected:
#endif
int ClientLibraryStartup();
int IdleTrackerAttach();
int IdleTrackerDetach();
int ClientLibraryShutdown();
wxConfig* m_pConfig;

View File

@ -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$";

View File

@ -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();
}

View File

@ -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();

View File

@ -42,6 +42,7 @@ protected:
HANDLE m_hDataManagementThread;
BOOL m_bClientLibraryInitialized;
BOOL m_bIdleTrackerInitialized;
};
#endif

View File

@ -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

View File

@ -676,18 +676,10 @@
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\clientlib\win\IdleTracker.cpp"
>
</File>
<File
RelativePath="..\clienttray\tray_win.cpp"
>
</File>
<File
RelativePath="..\lib\win_util.C"
>
</File>
</Filter>
<Filter
Name="Header Files"
@ -697,18 +689,10 @@
RelativePath="..\clienttray\boinc_tray.h"
>
</File>
<File
RelativePath="..\clientlib\win\IdleTracker.h"
>
</File>
<File
RelativePath="..\clienttray\tray_win.h"
>
</File>
<File
RelativePath="..\lib\win_util.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"