120 lines
2.9 KiB
C++
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);
|
|
}
|