*** empty log message ***

svn path=/trunk/boinc/; revision=3305
This commit is contained in:
Rom Walton 2004-04-29 00:57:26 +00:00
parent 5868ba20d1
commit 66eb385634
7 changed files with 105 additions and 45 deletions

View File

@ -11814,9 +11814,9 @@ Rom April 28 2004
/
set-version
/client
client/
Makefile.am
/client/win
client/win/
*.rc
update* (deleted)
@ -11825,3 +11825,20 @@ David April 28 2004
client/
hostinfo_unix.C
Rom April 28 2004
- Fixup Windows service controls so that pause/resume/start/stop work as
expected, when running as a service log to the Windows event log.
- When attempting to change the service description use runtime dynamic
linking for the call to ChangeServiceConfig2 so that we will work even
on NT 4.0 systems.
- Some of these fixes were based on code from Mathias Walter
client/
cs_cmdline.C
main.C
client/win/
win_service.cpp, .h
win_build/
boinc_cli.vcproj

View File

@ -39,7 +39,7 @@ static void print_options(char* prog) {
" -install install boinc as a Windows Service\n"
" -uninstall uninstall boinc as a Windows Service\n"
#endif
" -show_projects show attached projects\n"
" -show_projects show attached projects\n"
" -detach_project URL detach from a project\n"
" -reset_project URL reset (clear) a project\n"
" -attach_project attach to a project (will prompt for URL, account key)\n"
@ -117,8 +117,6 @@ void CLIENT_STATE::parse_cmdline(int argc, char** argv) {
else pers_giveup = atoi(argv[++i]);
} else if (ARG(debug_fake_exponential_backoff)) {
debug_fake_exponential_backoff = true;
} else if (ARG(win_service)) {
executing_as_windows_service = true;
// the above options are private (i.e. not shown by -help)
// Public options follow.

View File

@ -156,7 +156,7 @@ int add_new_project() {
}
void quit_client(int a) {
gstate.requested_exit = true;
gstate.cleanup_and_exit();
}
void susp_client(int a) {
@ -306,6 +306,11 @@ int main(int argc, char** argv) {
} else if ( _stricmp( "uninstall", argv[1]+1 ) == 0 ) {
CmdUninstallService();
} else if ( _stricmp( "win_service", argv[1]+1 ) == 0 ) {
// allow the system to know it is running as a Windows service
// and adjust it's diagnostics schemes accordingly.
gstate.executing_as_windows_service = true;
printf( "\nStartServiceCtrlDispatcher being called.\n" );
printf( "This may take several seconds. Please wait.\n" );

View File

@ -22,15 +22,18 @@
#include "stdafx.h"
#include "diagnostics.h"
#include "win_service.h"
#include "util.h"
// internal variables
SERVICE_STATUS ssStatus; // current status of the service
SERVICE_STATUS_HANDLE sshStatusHandle;
DWORD dwErr = 0;
TCHAR szErr[1024];
// define the execution engine start point
extern int boinc_main_loop(int argc, char** argv);
extern void quit_client(int a);
@ -38,9 +41,8 @@ extern void susp_client(int a);
extern void resume_client(int a);
// internal function prototypes not defined in the header
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
// Define API's that are going to be used through LoadLibrary calls.
typedef WINADVAPI BOOL (WINAPI *PROCCHANGESERVICECONFIG2)(SC_HANDLE, DWORD, LPCVOID);
//
@ -62,36 +64,49 @@ LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
//
void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
TCHAR szPath[MAX_PATH-1];
// SERVICE_STATUS members that don't change in example
//
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwControlsAccepted =
SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;
ssStatus.dwControlsAccepted = SERVICE_ACCEPTED_ACTIONS;
ssStatus.dwServiceSpecificExitCode = 0;
// register our service control handler:
//
sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
if (!sshStatusHandle)
goto cleanup;
if (!ReportStatus(
if (!ReportStatus(
SERVICE_RUNNING, // service state
ERROR_SUCCESS, // exit code
0)) // wait hint
goto cleanup;
// change the current directory to the boinc install directory
if (!GetModuleFileName(NULL, szPath, (sizeof(szPath)/sizeof(TCHAR))))
goto cleanup;
TCHAR *pszProg = strrchr(szPath, '\\');
if (pszProg) {
szPath[pszProg - szPath + 1] = 0;
SetCurrentDirectory(szPath);
}
dwErr = boinc_main_loop(dwArgc, lpszArgv);
cleanup:
// try to report the stopped status to the service control manager.
//
if (sshStatusHandle)
(VOID)ReportStatus(
SERVICE_STOPPED,
SERVICE_STOPPED,
dwErr,
0);
}
@ -125,11 +140,6 @@ VOID WINAPI service_ctrl(DWORD dwCtrlCode)
// which may result in a 1053 - The Service did not respond...
// error.
case SERVICE_CONTROL_STOP:
ReportStatus(SERVICE_STOP_PENDING, ERROR_SUCCESS, 10000);
quit_client(NULL);
ReportStatus(SERVICE_STOPPED, ERROR_SUCCESS, 10000);
return;
case SERVICE_CONTROL_SHUTDOWN:
ReportStatus(SERVICE_STOP_PENDING, ERROR_SUCCESS, 10000);
quit_client(NULL);
@ -148,7 +158,7 @@ VOID WINAPI service_ctrl(DWORD dwCtrlCode)
//
case SERVICE_CONTROL_CONTINUE:
ReportStatus(SERVICE_CONTINUE_PENDING, ERROR_SUCCESS, 10000);
susp_client(NULL);
resume_client(NULL);
ReportStatus(SERVICE_RUNNING, ERROR_SUCCESS, 10000);
return;
@ -195,10 +205,7 @@ BOOL ReportStatus(DWORD dwCurrentState,
if (dwCurrentState == SERVICE_START_PENDING)
ssStatus.dwControlsAccepted = 0;
else
ssStatus.dwControlsAccepted =
SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;
ssStatus.dwControlsAccepted = SERVICE_ACCEPTED_ACTIONS;
ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
@ -254,7 +261,7 @@ VOID LogEventErrorMessage(LPTSTR lpszMsg)
ReportEvent(hEventSource, // handle of event source
EVENTLOG_ERROR_TYPE, // event type
0, // event category
0, // event ID
1, // event ID
NULL, // current user's SID
2, // strings in lpszStrings
0, // no bytes of raw data
@ -263,7 +270,7 @@ VOID LogEventErrorMessage(LPTSTR lpszMsg)
(VOID) DeregisterEventSource(hEventSource);
}
}
}
//
@ -299,7 +306,7 @@ VOID LogEventWarningMessage(LPTSTR lpszMsg)
ReportEvent(hEventSource, // handle of event source
EVENTLOG_WARNING_TYPE,// event type
0, // event category
0, // event ID
1, // event ID
NULL, // current user's SID
2, // strings in lpszStrings
0, // no bytes of raw data
@ -344,7 +351,7 @@ VOID LogEventInfoMessage(LPTSTR lpszMsg)
ReportEvent(hEventSource, // handle of event source
EVENTLOG_INFORMATION_TYPE,// event type
0, // event category
0, // event ID
1, // event ID
NULL, // current user's SID
2, // strings in lpszStrings
0, // no bytes of raw data
@ -370,14 +377,16 @@ VOID LogEventInfoMessage(LPTSTR lpszMsg)
//
void CmdInstallService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
SC_HANDLE schService;
SC_HANDLE schSCManager;
HINSTANCE hinstAdvAPI32;
PROCCHANGESERVICECONFIG2 ProcChangeServiceConfig2;
TCHAR szPath[512];
if ( GetModuleFileName( NULL, szPath, 512 ) == 0 )
{
_tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), windows_error_string(szErr, sizeof(szErr)));
_tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), windows_error_string(szErr, (sizeof(szErr)/sizeof(TCHAR))));
return;
}
@ -435,23 +444,48 @@ void CmdInstallService()
SERVICE_DESCRIPTION sdDescription;
sdDescription.lpDescription = TEXT(SZSERVICEDESCRIPTION);
if ( ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdDescription) ){
_tprintf(TEXT("%s service description installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
} else {
_tprintf(TEXT("ChangeServiceConfig2 failed - %s\n"), windows_error_string(szErr, sizeof(szErr)));
}
hinstAdvAPI32 = LoadLibrary("ADVAPI32");
// If the handle is valid, try to get the function address.
if ( NULL != hinstAdvAPI32 )
{
#ifdef _UNICODE
ProcChangeServiceConfig2 = (PROCCHANGESERVICECONFIG2)GetProcAddress(
hinstAdvAPI32,
TEXT("ChangeServiceConfig2W")
);
#else
ProcChangeServiceConfig2 = (PROCCHANGESERVICECONFIG2)GetProcAddress(
hinstAdvAPI32,
TEXT("ChangeServiceConfig2A")
);
#endif
// If the function address is valid, call the function.
if ( NULL != ProcChangeServiceConfig2 )
{
if ( ProcChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdDescription) ){
_tprintf(TEXT("%s service description installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
} else {
_tprintf(TEXT("ChangeServiceConfig2 failed - %s\n"), windows_error_string(szErr, (sizeof(szErr)/sizeof(TCHAR))));
}
}
// Free the DLL module
FreeLibrary( hinstAdvAPI32 );
}
CloseServiceHandle(schService);
}
else
{
_tprintf(TEXT("CreateService failed - %s\n"), windows_error_string(szErr, sizeof(szErr)));
_tprintf(TEXT("CreateService failed - %s\n"), windows_error_string(szErr, (sizeof(szErr)/sizeof(TCHAR))));
}
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s\n"), windows_error_string(szErr,sizeof(szErr)));
_tprintf(TEXT("OpenSCManager failed - %s\n"), windows_error_string(szErr, (sizeof(szErr)/sizeof(TCHAR))));
}
@ -513,18 +547,18 @@ void CmdUninstallService()
if( DeleteService(schService) )
_tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
else
_tprintf(TEXT("DeleteService failed - %s\n"), windows_error_string(szErr,sizeof(szErr)));
_tprintf(TEXT("DeleteService failed - %s\n"), windows_error_string(szErr, (sizeof(szErr)/sizeof(TCHAR))));
CloseServiceHandle(schService);
}
else
_tprintf(TEXT("OpenService failed - %s\n"), windows_error_string(szErr,sizeof(szErr)));
_tprintf(TEXT("OpenService failed - %s\n"), windows_error_string(szErr, (sizeof(szErr)/sizeof(TCHAR))));
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s\n"), windows_error_string(szErr,sizeof(szErr)));
_tprintf(TEXT("OpenSCManager failed - %s\n"), windows_error_string(szErr, (sizeof(szErr)/sizeof(TCHAR))));
}

View File

@ -27,6 +27,7 @@
extern "C" {
#endif
// internal name of the service
#define SZSERVICENAME "BOINC"
@ -36,6 +37,12 @@ extern "C" {
// displayed description of the service
#define SZSERVICEDESCRIPTION "Berkeley Open Infrastructure for Network Computing"
// Service Accepted Actions
#define SERVICE_ACCEPTED_ACTIONS ( \
SERVICE_ACCEPT_STOP | \
SERVICE_ACCEPT_PAUSE_CONTINUE | \
SERVICE_ACCEPT_SHUTDOWN )
// Service Control Manager Routines
VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
VOID WINAPI service_ctrl(DWORD dwCtrlCode);

View File

@ -28,6 +28,7 @@ Sebastian Masch,
Stephen Pellicer,
Jens Seidler,
Christian Soettrup,
Mathias Walter,
Rom Walton,
Oliver Wang
</p>

View File

@ -26,6 +26,7 @@
PreprocessorDefinitions="WIN32;_DEBUG;_MT;_WINDOWS;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeTypeInfo="FALSE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="../client/StdAfx.h"
PrecompiledHeaderFile=".\Build\Debug\boinc_cli\obj/boinc_cli.pch"
@ -1129,9 +1130,6 @@
<File
RelativePath="..\client\scheduler_op.h">
</File>
<File
RelativePath="..\client\speed_stats.h">
</File>
<File
RelativePath="..\client\ss_logic.h">
</File>