33 static SERVICE_STATUS_HANDLE service_status_handle = 0;
35 static int service_argc = 0;
37 static char **service_argv = NULL;
39 static int service_initialized = 0;
41 int main(
int argc,
char **argv);
46 int SCRunningAsService(
void)
48 HANDLE h = INVALID_HANDLE_VALUE;
49 if ((h = CreateFile(
"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) {
61 static void SCAtExitHandler(
void)
63 SERVICE_STATUS status = {
66 SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN,
76 if (!SetServiceStatus(service_status_handle, &status)) {
77 SCLogWarning(
"Can't set service status: %d", (
int)GetLastError());
79 SCLogInfo(
"Service status set to: SERVICE_STOPPED");
86 static DWORD WINAPI SCServiceCtrlHandlerEx(DWORD code, DWORD etype, LPVOID edata, LPVOID context)
88 if (code == SERVICE_CONTROL_SHUTDOWN || code == SERVICE_CONTROL_STOP) {
89 SERVICE_STATUS status = {
92 SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN,
99 SCLogInfo(
"Service control handler called with %s control code.",
100 ((code == SERVICE_CONTROL_SHUTDOWN) ? (
"SERVICE_CONTROL_SHUTDOWN") : (
"SERVICE_CONTROL_STOP")));
103 if (!SetServiceStatus(service_status_handle, &status)) {
104 SCLogWarning(
"Can't set service status: %d", (
int)GetLastError());
106 SCLogInfo(
"Service status set to: SERVICE_STOP_PENDING");
115 return ERROR_CALL_NOT_IMPLEMENTED;
121 static void WINAPI SCServiceMain(uint32_t argc,
char** argv)
123 SERVICE_STATUS status = {
126 SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN,
133 if ((service_status_handle = RegisterServiceCtrlHandlerEx((
char *)
PROG_NAME, SCServiceCtrlHandlerEx, NULL)) == (SERVICE_STATUS_HANDLE)0) {
134 SCLogError(
"Can't register service control handler: %d", (
int)GetLastError());
139 if (atexit(SCAtExitHandler)) {
140 SCLogWarning(
"Can't register exit handler: %d", (
int)GetLastError());
144 if (!SetServiceStatus(service_status_handle, &status)) {
145 SCLogWarning(
"Can't set service status: %d", (
int)GetLastError());
147 SCLogInfo(
"Service status set to: SERVICE_RUNNING");
153 main(service_argc, service_argv);
158 status.dwCurrentState = SERVICE_STOPPED;
160 if (!SetServiceStatus(service_status_handle, &status)) {
161 SCLogWarning(
"Can't set service status: %d", (
int)GetLastError());
163 SCLogInfo(
"Service status set to: SERVICE_STOPPED");
173 int SCServiceInit(
int argc,
char **argv)
175 SERVICE_TABLE_ENTRY DispatchTable[] = {
176 {(
char *)
PROG_NAME, (LPSERVICE_MAIN_FUNCTION) SCServiceMain},
181 if (service_initialized) {
190 service_initialized = 1;
192 SCLogInfo(
"Entering service control dispatcher...");
194 if (!StartServiceCtrlDispatcher(DispatchTable)) {
199 SCLogInfo(
"Leaving service control dispatcher.");
211 int SCServiceInstall(
int argc,
char **argv)
214 SC_HANDLE service = NULL;
215 SC_HANDLE scm = NULL;
220 memset(path, 0,
sizeof(path));
223 if (GetModuleFileName(NULL, path + 1,
sizeof(path) - 1) == 0) {
224 SCLogError(
"Can't get path to service binary: %d", (
int)GetLastError());
227 if (
strlcat(path,
"\"",
sizeof(path)) >=
sizeof(path)) {
228 SCLogError(
"failed to construct service path string: path truncated: %s", path);
233 for (i = 1; i < argc; i++) {
234 if ((strlen(argv[i]) <= strlen(
"--service-install")) && (strncmp(
"--service-install", argv[i], strlen(argv[i])) == 0)) {
237 if (
strlcat(path,
" ",
sizeof(path)) >=
sizeof(path)) {
238 SCLogError(
"failed to construct service path string: path truncated: %s", path);
241 if (
strlcat(path, argv[i],
sizeof(path)) >=
sizeof(path)) {
242 SCLogError(
"failed to construct service path string: path truncated: %s", path);
247 if ((scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL) {
248 SCLogError(
"Can't open SCM: %d", (
int)GetLastError());
252 service = CreateService(
257 SERVICE_WIN32_OWN_PROCESS,
258 SERVICE_DEMAND_START,
259 SERVICE_ERROR_NORMAL,
267 if (service == NULL) {
268 SCLogError(
"Can't create service: %d", (
int)GetLastError());
277 CloseServiceHandle(service);
281 CloseServiceHandle(scm);
293 int SCServiceRemove(
void)
295 SERVICE_STATUS status;
296 SC_HANDLE service = NULL;
297 SC_HANDLE scm = NULL;
301 if ((scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL) {
302 SCLogError(
"Can't open SCM: %d", (
int)GetLastError());
306 if ((service = OpenService(scm,
PROG_NAME, SERVICE_ALL_ACCESS)) == NULL) {
307 SCLogError(
"Can't open service: %d", (
int)GetLastError());
311 if (!QueryServiceStatus(service, &status)) {
312 SCLogError(
"Can't query service status: %d", (
int)GetLastError());
316 if (status.dwCurrentState != SERVICE_STOPPED) {
317 SCLogError(
"Service isn't in stopped state: %d", (
int)GetLastError());
321 if (!DeleteService(service)) {
322 SCLogError(
"Can't delete service: %d", (
int)GetLastError());
331 CloseServiceHandle(service);
335 CloseServiceHandle(scm);
347 int SCServiceChangeParams(
int argc,
char **argv)
350 SC_HANDLE service = NULL;
351 SC_HANDLE scm = NULL;
356 memset(path, 0,
sizeof(path));
359 if (GetModuleFileName(NULL, path + 1,
sizeof(path) - 1) == 0) {
360 SCLogError(
"Can't get path to service binary: %d", (
int)GetLastError());
363 if (
strlcat(path,
"\"",
sizeof(path)) >=
sizeof(path)) {
364 SCLogError(
"failed to construct service path string: path truncated: %s", path);
369 for (i = 1; i < argc; i++) {
370 if ((strlen(argv[i]) <= strlen(
"--service-change-params")) && (strncmp(
"--service-change-params", argv[i], strlen(argv[i])) == 0)) {
373 if (
strlcat(path,
" ",
sizeof(path)) >=
sizeof(path)) {
374 SCLogError(
"failed to construct service path string: path truncated: %s", path);
377 if (
strlcat(path, argv[i],
sizeof(path)) >=
sizeof(path)) {
378 SCLogError(
"failed to construct service path string: path truncated: %s", path);
383 if ((scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL) {
384 SCLogError(
"Can't open SCM: %d", (
int)GetLastError());
388 if ((service = OpenService(scm,
PROG_NAME, SERVICE_ALL_ACCESS)) == NULL) {
389 SCLogError(
"Can't open service: %d", (
int)GetLastError());
393 if (!ChangeServiceConfig(
395 SERVICE_WIN32_OWN_PROCESS,
396 SERVICE_DEMAND_START,
397 SERVICE_ERROR_NORMAL,
406 SCLogError(
"Can't change service configuration: %d", (
int)GetLastError());