spectrum2/spectrum/src/win32/ServiceWrapper.cpp
2012-12-19 11:42:00 +04:00

120 lines
2.9 KiB
C++

#include "ServiceWrapper.h"
LPSTR ServiceName;
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
bool doAction (int action, int desiredAccess, LPSTR path = NULL);
enum actions {
DO_INSTALL, DO_DELETE, DO_CHECK
};
ServiceWrapper::ServiceWrapper(LPSTR serviceName)
{
ServiceName = serviceName;
ServiceStatusHandle = 0;
}
ServiceWrapper::~ServiceWrapper(void)
{
}
bool ServiceWrapper::Install(LPSTR commandLine) {
return doAction(DO_INSTALL, SC_MANAGER_ALL_ACCESS, commandLine);
}
bool ServiceWrapper::UnInstall() {
return doAction(DO_DELETE, SC_MANAGER_ALL_ACCESS);
}
bool ServiceWrapper::IsInstalled() {
return doAction(DO_CHECK, SC_MANAGER_CONNECT);
}
bool doAction(int action, int desiredAccess, LPSTR path) {
SC_HANDLE scm = OpenSCManager(NULL, NULL, desiredAccess);
SC_HANDLE service = NULL;
if (!scm) return FALSE;
switch(action) {
case DO_INSTALL:
service = CreateServiceA(
scm,
ServiceName,
ServiceName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
path,
NULL,
NULL,
NULL,
NULL,
NULL
);
return (service != NULL);
break;
case DO_DELETE:
service = OpenServiceA(scm, ServiceName, DELETE);
if (service == NULL)
return FALSE;
if (DeleteService(service))
return TRUE;
break;
case DO_CHECK:
service = OpenServiceA(scm, ServiceName, SERVICE_QUERY_STATUS);
return (service != NULL);
default:
return FALSE;
}
CloseServiceHandle(service);
CloseServiceHandle(scm);
return FALSE;
}
void WINAPI ServiceControlHandler(DWORD controlCode) {
switch (controlCode) {
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_STOP:
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
break;
default:
break;
}
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
spectrum_control_handler(CTRL_CLOSE_EVENT);
}
void WINAPI ServiceMain(DWORD argc, LPSTR *argv) {
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwServiceSpecificExitCode = NO_ERROR;
ServiceStatusHandle = RegisterServiceCtrlHandlerA(ServiceName, ServiceControlHandler);
if (ServiceStatusHandle) {
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
ServiceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
mainloop();
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
ServiceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
}
}
void ServiceWrapper::RunService() {
SERVICE_TABLE_ENTRYA serviceTable[] = {
{ ServiceName, ServiceMain },
{ NULL, NULL}
};
StartServiceCtrlDispatcherA(serviceTable);
}