summaryrefslogtreecommitdiff
path: root/bin/bbackupd/Win32ServiceFunctions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'bin/bbackupd/Win32ServiceFunctions.cpp')
-rw-r--r--bin/bbackupd/Win32ServiceFunctions.cpp384
1 files changed, 0 insertions, 384 deletions
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 <unistd.h>
-#endif
-#ifdef HAVE_PROCESS_H
- #include <process.h>
-#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