diff options
author | Reinhard Tartler <siretart@tauware.de> | 2008-01-19 15:08:54 +0100 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2008-01-19 15:08:54 +0100 |
commit | 2733267954e91e394fbb512ea3abb4c497c0752f (patch) | |
tree | d6cdebd8776bceba06a2fb5e4ed06a4744bc1b57 /bin/bbackupd/Win32ServiceFunctions.cpp | |
parent | 1d56581c644c53f1b9a182c6574bc2fc5243d4d1 (diff) |
import version 0.11rc1
This commit has been made by 'bzr import'. I used the upstream tarball
of Version 0.11rc1 for creating it. It has the md5sum:
75608d8bb72dff9a556850ccd0ae8cb9
Diffstat (limited to 'bin/bbackupd/Win32ServiceFunctions.cpp')
-rw-r--r-- | bin/bbackupd/Win32ServiceFunctions.cpp | 241 |
1 files changed, 175 insertions, 66 deletions
diff --git a/bin/bbackupd/Win32ServiceFunctions.cpp b/bin/bbackupd/Win32ServiceFunctions.cpp index 07791af3..276d004f 100644 --- a/bin/bbackupd/Win32ServiceFunctions.cpp +++ b/bin/bbackupd/Win32ServiceFunctions.cpp @@ -1,4 +1,4 @@ -// distribution boxbackup-0.10 (svn version: 494) +// distribution boxbackup-0.11rc1 (svn version: 2023_2024) // // Copyright (c) 2003 - 2006 // Ben Summers and contributors. All rights reserved. @@ -68,6 +68,7 @@ TCHAR* gServiceName = TEXT("Box Backup Service"); SERVICE_STATUS gServiceStatus; SERVICE_STATUS_HANDLE gServiceStatusHandle = 0; HANDLE gStopServiceEvent = 0; +DWORD gServiceReturnCode = 0; #define SERVICE_NAME "boxbackup" @@ -81,8 +82,9 @@ void ErrorHandler(char *s, DWORD err) { char buf[256]; memset(buf, 0, sizeof(buf)); - _snprintf(buf, sizeof(buf)-1, "%s (%d)", s, err); - ::syslog(LOG_ERR, "%s", buf); + _snprintf(buf, sizeof(buf)-1, "%s: %s", s, + GetErrorMessage(err).c_str()); + BOX_ERROR(buf); MessageBox(0, buf, "Error", MB_OK | MB_SETFOREGROUND | MB_DEFAULT_DESKTOP_ONLY); ExitProcess(err); @@ -131,28 +133,30 @@ void WINAPI ServiceControlHandler( DWORD controlCode ) // It also returns on any error because the // service cannot start if there is an eror. +static char* spConfigFileName; + VOID ServiceMain(DWORD argc, LPTSTR *argv) { - // initialise service status - gServiceStatus.dwServiceType = SERVICE_WIN32; - gServiceStatus.dwCurrentState = SERVICE_STOPPED; - gServiceStatus.dwControlsAccepted = 0; - gServiceStatus.dwWin32ExitCode = NO_ERROR; - gServiceStatus.dwServiceSpecificExitCode = NO_ERROR; - gServiceStatus.dwCheckPoint = 0; - gServiceStatus.dwWaitHint = 0; - - gServiceStatusHandle = RegisterServiceCtrlHandler(gServiceName, - ServiceControlHandler); - - if (gServiceStatusHandle) - { - // service is starting - gServiceStatus.dwCurrentState = SERVICE_START_PENDING; - SetServiceStatus(gServiceStatusHandle, &gServiceStatus); - - // do initialisation here - gStopServiceEvent = CreateEvent( 0, TRUE, FALSE, 0 ); + // initialise service status + gServiceStatus.dwServiceType = SERVICE_WIN32; + gServiceStatus.dwCurrentState = SERVICE_STOPPED; + gServiceStatus.dwControlsAccepted = 0; + gServiceStatus.dwWin32ExitCode = NO_ERROR; + gServiceStatus.dwServiceSpecificExitCode = NO_ERROR; + gServiceStatus.dwCheckPoint = 0; + gServiceStatus.dwWaitHint = 0; + + gServiceStatusHandle = RegisterServiceCtrlHandler(gServiceName, + ServiceControlHandler); + + if (gServiceStatusHandle) + { + // service is starting + gServiceStatus.dwCurrentState = SERVICE_START_PENDING; + SetServiceStatus(gServiceStatusHandle, &gServiceStatus); + + // do initialisation here + gStopServiceEvent = CreateEvent(0, TRUE, FALSE, 0); if (!gStopServiceEvent) { gServiceStatus.dwControlsAccepted &= @@ -167,7 +171,7 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv) NULL, 0, RunService, - 0, + spConfigFileName, CREATE_SUSPENDED, NULL); @@ -176,7 +180,7 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv) // we are now running so tell the SCM gServiceStatus.dwControlsAccepted |= - (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); gServiceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(gServiceStatusHandle, &gServiceStatus); @@ -192,13 +196,23 @@ VOID ServiceMain(DWORD argc, LPTSTR *argv) // service is now stopped gServiceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + gServiceStatus.dwCurrentState = SERVICE_STOPPED; + + if (gServiceReturnCode != 0) + { + gServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; + gServiceStatus.dwServiceSpecificExitCode = gServiceReturnCode; + } + SetServiceStatus(gServiceStatusHandle, &gServiceStatus); - } + } } -void OurService(void) +int OurService(const char* pConfigFileName) { + spConfigFileName = strdup(pConfigFileName); + SERVICE_TABLE_ENTRY serviceTable[] = { { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain }, @@ -209,54 +223,119 @@ void OurService(void) // Register with the SCM success = StartServiceCtrlDispatcher(serviceTable); + free(spConfigFileName); + spConfigFileName = NULL; + if (!success) { ErrorHandler("Failed to start service. Did you start " "Box Backup from the Service Control Manager? " "(StartServiceCtrlDispatcher)", GetLastError()); + return 1; } + + return 0; } -void InstallService(void) +int InstallService(const char* pConfigFileName, const std::string& rServiceName) { - SC_HANDLE newService, scm; + if (pConfigFileName != NULL) + { + struct stat st; - scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); + if (emu_stat(pConfigFileName, &st) != 0) + { + BOX_ERROR("Failed to open configuration file '" << + pConfigFileName << "': " << strerror(errno)); + return 1; + } + + if (!(st.st_mode & S_IFREG)) + { + + BOX_ERROR("Failed to open configuration file '" << + pConfigFileName << "': not a file"); + return 1; + } + } + + SC_HANDLE scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); if (!scm) { - syslog(LOG_ERR, "Failed to open service control manager: " - "error %d", GetLastError()); - return; + BOX_ERROR("Failed to open service control manager: " << + GetErrorMessage(GetLastError())); + return 1; } char cmd[MAX_PATH]; GetModuleFileName(NULL, cmd, sizeof(cmd)-1); cmd[sizeof(cmd)-1] = 0; - char cmd_args[MAX_PATH]; - _snprintf(cmd_args, sizeof(cmd_args)-1, "%s --service", cmd); - cmd_args[sizeof(cmd_args)-1] = 0; + std::string cmdWithArgs(cmd); + cmdWithArgs += " -s -S \"" + rServiceName + "\""; - newService = CreateService( + if (pConfigFileName != NULL) + { + cmdWithArgs += " \""; + cmdWithArgs += pConfigFileName; + cmdWithArgs += "\""; + } + + std::string serviceDesc = "Box Backup (" + rServiceName + ")"; + + SC_HANDLE newService = CreateService( scm, - SERVICE_NAME, - "Box Backup", + rServiceName.c_str(), + serviceDesc.c_str(), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, - cmd_args, + cmdWithArgs.c_str(), 0,0,0,0,0); + DWORD err = GetLastError(); + CloseServiceHandle(scm); + if (!newService) { - ::syslog(LOG_ERR, "Failed to create Box Backup service: " - "error %d", GetLastError()); - return; + switch (err) + { + case ERROR_SERVICE_EXISTS: + { + BOX_ERROR("Failed to create Box Backup " + "service: it already exists"); + } + break; + + case ERROR_SERVICE_MARKED_FOR_DELETE: + { + BOX_ERROR("Failed to create Box Backup " + "service: it is waiting to be deleted"); + } + break; + + case ERROR_DUPLICATE_SERVICE_NAME: + { + BOX_ERROR("Failed to create Box Backup " + "service: a service with this name " + "already exists"); + } + break; + + default: + { + BOX_ERROR("Failed to create Box Backup " + "service: error " << + GetErrorMessage(GetLastError())); + } + } + + return 1; } - ::syslog(LOG_INFO, "Created Box Backup service"); + BOX_INFO("Created Box Backup service"); SERVICE_DESCRIPTION desc; desc.lpDescription = "Backs up your data files over the Internet"; @@ -264,50 +343,80 @@ void InstallService(void) if (!ChangeServiceConfig2(newService, SERVICE_CONFIG_DESCRIPTION, &desc)) { - ::syslog(LOG_WARNING, "Failed to set description for " - "Box Backup service: error %d", GetLastError()); + BOX_WARNING("Failed to set description for Box Backup " + "service: " << GetErrorMessage(GetLastError())); } CloseServiceHandle(newService); - CloseServiceHandle(scm); + + return 0; } -void RemoveService(void) +int RemoveService(const std::string& rServiceName) { - SC_HANDLE service, scm; - SERVICE_STATUS status; - - scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); + SC_HANDLE scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); if (!scm) { - syslog(LOG_ERR, "Failed to open service control manager: " - "error %d", GetLastError()); - return; + BOX_ERROR("Failed to open service control manager: " << + GetErrorMessage(GetLastError())); + return 1; } - service = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS|DELETE); - ControlService(service, SERVICE_CONTROL_STOP, &status); + SC_HANDLE service = OpenService(scm, rServiceName.c_str(), + SERVICE_ALL_ACCESS|DELETE); + DWORD err = GetLastError(); + CloseServiceHandle(scm); if (!service) { - syslog(LOG_ERR, "Failed to open Box Backup service: " - "error %d", GetLastError()); - return; + if (err == ERROR_SERVICE_DOES_NOT_EXIST || + err == ERROR_IO_PENDING) + // hello microsoft? anyone home? + { + BOX_ERROR("Failed to open Box Backup service: " + "not installed or not found"); + } + else + { + BOX_ERROR("Failed to open Box Backup service: " << + GetErrorMessage(err)); + } + return 1; + } + + SERVICE_STATUS status; + if (!ControlService(service, SERVICE_CONTROL_STOP, &status)) + { + err = GetLastError(); + if (err != ERROR_SERVICE_NOT_ACTIVE) + { + BOX_WARNING("Failed to stop Box Backup service: " << + GetErrorMessage(err)); + } } - if (DeleteService(service)) + BOOL deleted = DeleteService(service); + err = GetLastError(); + CloseServiceHandle(service); + + if (deleted) { - syslog(LOG_INFO, "Box Backup service deleted"); + BOX_INFO("Box Backup service deleted"); + return 0; + } + else if (err == ERROR_SERVICE_MARKED_FOR_DELETE) + { + BOX_ERROR("Failed to remove Box Backup service: " + "it is already being deleted"); } else { - syslog(LOG_ERR, "Failed to remove Box Backup service: " - "error %d", GetLastError()); + BOX_ERROR("Failed to remove Box Backup service: " << + GetErrorMessage(err)); } - CloseServiceHandle(service); - CloseServiceHandle(scm); + return 1; } #endif // WIN32 |