From 403e7e2051ee3bd3e16a616cfca63b036481282b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 13 Dec 2015 23:39:18 +0000 Subject: Move reusable code out of bin directories. Allows tests to depend on lib/bbackupd instead of bin/bbackupd, which was always a hack, and really doesn't work with CMake. --- bin/bbackupd/Win32ServiceFunctions.cpp | 384 --------------------------------- 1 file changed, 384 deletions(-) delete mode 100644 bin/bbackupd/Win32ServiceFunctions.cpp (limited to 'bin/bbackupd/Win32ServiceFunctions.cpp') diff --git a/bin/bbackupd/Win32ServiceFunctions.cpp b/bin/bbackupd/Win32ServiceFunctions.cpp deleted file mode 100644 index 2df914a7..00000000 --- a/bin/bbackupd/Win32ServiceFunctions.cpp +++ /dev/null @@ -1,384 +0,0 @@ -//*************************************************************** -// From the book "Win32 System Services: The Heart of Windows 98 -// and Windows 2000" -// by Marshall Brain -// Published by Prentice Hall -// Copyright 1995 Prentice Hall. -// -// This code implements the Windows API Service interface -// for the Box Backup for Windows native port. -// Adapted for Box Backup by Nick Knight. -//*************************************************************** - -#ifdef WIN32 - -#include "Box.h" - -#ifdef HAVE_UNISTD_H - #include -#endif -#ifdef HAVE_PROCESS_H - #include -#endif - -extern void TerminateService(void); -extern unsigned int WINAPI RunService(LPVOID lpParameter); - -// Global variables - -TCHAR* gServiceName = TEXT("Box Backup Service"); -SERVICE_STATUS gServiceStatus; -SERVICE_STATUS_HANDLE gServiceStatusHandle = 0; -HANDLE gStopServiceEvent = 0; -DWORD gServiceReturnCode = 0; - -#define SERVICE_NAME "boxbackup" - -void ShowMessage(char *s) -{ - MessageBox(0, s, "Box Backup Message", - MB_OK | MB_SETFOREGROUND | MB_DEFAULT_DESKTOP_ONLY); -} - -void ErrorHandler(char *s, DWORD err) -{ - char buf[256]; - memset(buf, 0, sizeof(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); -} - -void WINAPI ServiceControlHandler( DWORD controlCode ) -{ - switch ( controlCode ) - { - case SERVICE_CONTROL_INTERROGATE: - break; - - case SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL_STOP: - Beep(1000,100); - TerminateService(); - gServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(gServiceStatusHandle, &gServiceStatus); - - SetEvent(gStopServiceEvent); - return; - - case SERVICE_CONTROL_PAUSE: - break; - - case SERVICE_CONTROL_CONTINUE: - break; - - default: - if ( controlCode >= 128 && controlCode <= 255 ) - // user defined control code - break; - else - // unrecognised control code - break; - } - - SetServiceStatus( gServiceStatusHandle, &gServiceStatus ); -} - -// ServiceMain is called when the SCM wants to -// start the service. When it returns, the service -// has stopped. It therefore waits on an event -// just before the end of the function, and -// that event gets set when it is time to stop. -// 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); - if (!gStopServiceEvent) - { - gServiceStatus.dwControlsAccepted &= - ~(SERVICE_ACCEPT_STOP | - SERVICE_ACCEPT_SHUTDOWN); - gServiceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(gServiceStatusHandle, &gServiceStatus); - return; - } - - HANDLE ourThread = (HANDLE)_beginthreadex( - NULL, - 0, - RunService, - spConfigFileName, - CREATE_SUSPENDED, - NULL); - - SetThreadPriority(ourThread, THREAD_PRIORITY_LOWEST); - ResumeThread(ourThread); - - // we are now running so tell the SCM - gServiceStatus.dwControlsAccepted |= - (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - gServiceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus(gServiceStatusHandle, &gServiceStatus); - - // do cleanup here - WaitForSingleObject(gStopServiceEvent, INFINITE); - CloseHandle(gStopServiceEvent); - gStopServiceEvent = 0; - - // service was stopped - gServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(gServiceStatusHandle, &gServiceStatus); - - // 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); - } -} - -int OurService(const char* pConfigFileName) -{ - spConfigFileName = strdup(pConfigFileName); - - SERVICE_TABLE_ENTRY serviceTable[] = - { - { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain }, - { NULL, NULL } - }; - BOOL success; - - // 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; -} - -int InstallService(const char* pConfigFileName, const std::string& rServiceName) -{ - if (pConfigFileName != NULL) - { - EMU_STRUCT_STAT st; - - if (emu_stat(pConfigFileName, &st) != 0) - { - BOX_LOG_SYS_ERROR("Failed to open configuration file " - "'" << pConfigFileName << "'"); - 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) - { - 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; - - std::string cmdWithArgs(cmd); - cmdWithArgs += " -s -S \"" + rServiceName + "\""; - - if (pConfigFileName != NULL) - { - cmdWithArgs += " \""; - cmdWithArgs += pConfigFileName; - cmdWithArgs += "\""; - } - - std::string serviceDesc = "Box Backup (" + rServiceName + ")"; - - SC_HANDLE newService = CreateService( - scm, - rServiceName.c_str(), - serviceDesc.c_str(), - SERVICE_ALL_ACCESS, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - cmdWithArgs.c_str(), - 0,0,0,0,0); - - DWORD err = GetLastError(); - CloseServiceHandle(scm); - - if (!newService) - { - 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; - } - - BOX_INFO("Created Box Backup service"); - - SERVICE_DESCRIPTION desc; - desc.lpDescription = "Backs up your data files over the Internet"; - - if (!ChangeServiceConfig2(newService, SERVICE_CONFIG_DESCRIPTION, - &desc)) - { - BOX_WARNING("Failed to set description for Box Backup " - "service: " << GetErrorMessage(GetLastError())); - } - - CloseServiceHandle(newService); - - return 0; -} - -int RemoveService(const std::string& rServiceName) -{ - SC_HANDLE scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); - - if (!scm) - { - BOX_ERROR("Failed to open service control manager: " << - GetErrorMessage(GetLastError())); - return 1; - } - - SC_HANDLE service = OpenService(scm, rServiceName.c_str(), - SERVICE_ALL_ACCESS|DELETE); - DWORD err = GetLastError(); - CloseServiceHandle(scm); - - if (!service) - { - 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)); - } - } - - BOOL deleted = DeleteService(service); - err = GetLastError(); - CloseServiceHandle(service); - - if (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 - { - BOX_ERROR("Failed to remove Box Backup service: " << - GetErrorMessage(err)); - } - - return 1; -} - -#endif // WIN32 -- cgit v1.2.3