/* Make sure service recovery actions are taken where necessary */ void set_service_recovery(SC_HANDLE service, char *service_name) { SC_HANDLE services = 0; if (! service) { services = open_service_manager(); if (! services) return; service = OpenService(services, service_name, SC_MANAGER_ALL_ACCESS); if (! service) return; } SERVICE_FAILURE_ACTIONS_FLAG flag; ZeroMemory(&flag, sizeof(flag)); flag.fFailureActionsOnNonCrashFailures = true; /* This functionality was added in Vista so the call may fail */ if (! ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, &flag)) { unsigned long error = GetLastError(); /* Pre-Vista we expect to fail with ERROR_INVALID_LEVEL */ if (error != ERROR_INVALID_LEVEL) { log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CHANGESERVICECONFIG2_FAILED, service_name, error_string(error), 0); } } if (services) { CloseServiceHandle(service); CloseServiceHandle(services); } }
/* Remove the service */ int remove_service(char *name) { /* Open service manager */ SC_HANDLE services = open_service_manager(); if (! services) { print_message(stderr, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED); return 2; } /* Try to open the service */ SC_HANDLE service = OpenService(services, name, SC_MANAGER_ALL_ACCESS); if (! service) { print_message(stderr, NSSM_MESSAGE_OPENSERVICE_FAILED); CloseServiceHandle(services); return 3; } /* Try to delete the service */ if (! DeleteService(service)) { print_message(stderr, NSSM_MESSAGE_DELETESERVICE_FAILED); CloseServiceHandle(service); CloseServiceHandle(services); return 4; } /* Cleanup */ CloseServiceHandle(service); CloseServiceHandle(services); print_message(stdout, NSSM_MESSAGE_SERVICE_REMOVED, name); return 0; }
/* Install the service */ int install_service(char *name, char *exe, char *flags) { /* Open service manager */ SC_HANDLE services = open_service_manager(); if (! services) { print_message(stderr, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED); return 2; } /* Get path of this program */ char path[MAX_PATH]; GetModuleFileName(0, path, MAX_PATH); /* Construct command */ char command[CMD_LENGTH]; size_t pathlen = strlen(path); if (pathlen + 1 >= VALUE_LENGTH) { print_message(stderr, NSSM_MESSAGE_PATH_TOO_LONG, NSSM); return 3; } if (_snprintf(command, sizeof(command), "\"%s\"", path) < 0) { print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY_FOR_IMAGEPATH); return 4; } /* Work out directory name */ size_t len = strlen(exe); size_t i; for (i = len; i && exe[i] != '\\' && exe[i] != '/'; i--); char dir[MAX_PATH]; memmove(dir, exe, i); dir[i] = '\0'; /* Create the service */ SC_HANDLE service = CreateService(services, name, name, SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, command, 0, 0, 0, 0, 0); if (! service) { print_message(stderr, NSSM_MESSAGE_CREATESERVICE_FAILED); CloseServiceHandle(services); return 5; } /* Now we need to put the parameters into the registry */ if (create_parameters(name, exe, flags, dir)) { print_message(stderr, NSSM_MESSAGE_CREATE_PARAMETERS_FAILED); DeleteService(service); CloseServiceHandle(services); return 6; } set_service_recovery(service, name); /* Cleanup */ CloseServiceHandle(service); CloseServiceHandle(services); print_message(stdout, NSSM_MESSAGE_SERVICE_INSTALLED, name); return 0; }
static int CmdInstallService(int argc, char *argv[]) { char fullfilename[MAX_PATH]; /* Pick up our full path and file name. */ if (!GetModuleFileName(NULL, fullfilename, sizeof(fullfilename))) return service_error(GetLastError(), "Cannot locate full filename"); /* Open a handle to the Service Control Manager. */ if (open_service_manager()) return TRUE; /* Now create the service definition. */ service = CreateService(SCmanager, THIS_SERVICE, THIS_SERVICE_DISPLAY, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, fullfilename, NULL, /* no load ordering group */ NULL, /* no tag identifier */ NULL, /* no dependencies */ NULL, /* LocalSystem account */ NULL); /* no password */ if (!service) return service_error(GetLastError(), "Unable to create service"); close_service_handles(); fprintf(stderr, "Service successfully installed\n"); return FALSE; } /* end of CmdInstallService */