From 4d0f8abd0f891348080589ffacd1b9f1fd3faf41 Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Mon, 30 Dec 2013 11:50:20 +0000 Subject: [PATCH] Added get_service_startup(). New function to retrieve the service startup type. --- service.cpp | 90 ++++++++++++++++++++++++++++++++++--------------------------- service.h | 1 + 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/service.cpp b/service.cpp index abe745a..e3824ff 100644 --- a/service.cpp +++ b/service.cpp @@ -65,6 +65,50 @@ QUERY_SERVICE_CONFIG *query_service_config(const TCHAR *service_name, SC_HANDLE return qsc; } +int get_service_startup(const TCHAR *service_name, SC_HANDLE service_handle, const QUERY_SERVICE_CONFIG *qsc, unsigned long *startup) { + if (! qsc) return 1; + + switch (qsc->dwStartType) { + case SERVICE_DEMAND_START: *startup = NSSM_STARTUP_MANUAL; break; + case SERVICE_DISABLED: *startup = NSSM_STARTUP_DISABLED; break; + default: *startup = NSSM_STARTUP_AUTOMATIC; + } + + if (*startup != NSSM_STARTUP_AUTOMATIC) return 0; + + /* Check for delayed start. */ + unsigned long bufsize; + unsigned long error; + QueryServiceConfig2(service_handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, 0, 0, &bufsize); + error = GetLastError(); + if (error == ERROR_INSUFFICIENT_BUFFER) { + SERVICE_DELAYED_AUTO_START_INFO *info = (SERVICE_DELAYED_AUTO_START_INFO *) HeapAlloc(GetProcessHeap(), 0, bufsize); + if (! info) { + print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("SERVICE_DELAYED_AUTO_START_INFO"), _T("get_service_startup()")); + return 2; + } + + if (QueryServiceConfig2(service_handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, (unsigned char *) info, bufsize, &bufsize)) { + if (info->fDelayedAutostart) *startup = NSSM_STARTUP_DELAYED; + HeapFree(GetProcessHeap(), 0, info); + return 0; + } + else { + error = GetLastError(); + if (error != ERROR_INVALID_LEVEL) { + print_message(stderr, NSSM_MESSAGE_QUERYSERVICECONFIG2_FAILED, service_name, _T("SERVICE_CONFIG_DELAYED_AUTO_START_INFO"), error_string(error)); + return 3; + } + } + } + else if (error != ERROR_INVALID_LEVEL) { + print_message(stderr, NSSM_MESSAGE_QUERYSERVICECONFIG2_FAILED, service_name, _T("SERVICE_DELAYED_AUTO_START_INFO"), error_string(error)); + return 3; + } + + return 0; +} + static int grant_logon_as_service(const TCHAR *username) { if (str_equiv(username, NSSM_LOCALSYSTEM_ACCOUNT)) return 0; @@ -341,11 +385,13 @@ int pre_edit_service(int argc, TCHAR **argv) { return 3; } - switch (qsc->dwStartType) { - case SERVICE_DEMAND_START: service->startup = NSSM_STARTUP_MANUAL; break; - case SERVICE_DISABLED: service->startup = NSSM_STARTUP_DISABLED; break; - default: service->startup = NSSM_STARTUP_AUTOMATIC; + if (get_service_startup(service->name, service->handle, qsc, &service->startup)) { + HeapFree(GetProcessHeap(), 0, qsc); + CloseHandle(service->handle); + CloseServiceHandle(services); + return 4; } + if (! str_equiv(qsc->lpServiceStartName, NSSM_LOCALSYSTEM_ACCOUNT)) { size_t len = _tcslen(qsc->lpServiceStartName); service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR)); @@ -358,7 +404,7 @@ int pre_edit_service(int argc, TCHAR **argv) { CloseHandle(service->handle); CloseServiceHandle(services); print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("username"), _T("pre_edit_service()")); - return 4; + return 5; } } _sntprintf_s(service->displayname, _countof(service->displayname), _TRUNCATE, _T("%s"), qsc->lpDisplayName); @@ -372,40 +418,6 @@ int pre_edit_service(int argc, TCHAR **argv) { HeapFree(GetProcessHeap(), 0, qsc); /* Get extended system details. */ - if (service->startup == NSSM_STARTUP_AUTOMATIC) { - QueryServiceConfig2(service->handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, 0, 0, &bufsize); - error = GetLastError(); - if (error == ERROR_INSUFFICIENT_BUFFER) { - SERVICE_DELAYED_AUTO_START_INFO *info = (SERVICE_DELAYED_AUTO_START_INFO *) HeapAlloc(GetProcessHeap(), 0, bufsize); - if (! info) { - CloseHandle(service->handle); - CloseServiceHandle(services); - print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("SERVICE_DELAYED_AUTO_START_INFO"), _T("pre_edit_service()")); - return 5; - } - - if (QueryServiceConfig2(service->handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, (unsigned char *) info, bufsize, &bufsize)) { - if (info->fDelayedAutostart) service->startup = NSSM_STARTUP_DELAYED; - HeapFree(GetProcessHeap(), 0, info); - } - else { - error = GetLastError(); - if (error != ERROR_INVALID_LEVEL) { - CloseHandle(service->handle); - CloseServiceHandle(services); - print_message(stderr, NSSM_MESSAGE_QUERYSERVICECONFIG2_FAILED, service->name, _T("SERVICE_CONFIG_DELAYED_AUTO_START_INFO"), error_string(error)); - return 5; - } - } - } - else if (error != ERROR_INVALID_LEVEL) { - CloseHandle(service->handle); - CloseServiceHandle(services); - print_message(stderr, NSSM_MESSAGE_QUERYSERVICECONFIG2_FAILED, service->name, _T("SERVICE_DELAYED_AUTO_START_INFO"), error_string(error)); - return 5; - } - } - QueryServiceConfig2(service->handle, SERVICE_CONFIG_DESCRIPTION, 0, 0, &bufsize); error = GetLastError(); if (error == ERROR_INSUFFICIENT_BUFFER) { diff --git a/service.h b/service.h index 596b82b..ca06a2e 100644 --- a/service.h +++ b/service.h @@ -90,6 +90,7 @@ void set_nssm_service_defaults(nssm_service_t *); void cleanup_nssm_service(nssm_service_t *); SC_HANDLE open_service_manager(); QUERY_SERVICE_CONFIG *query_service_config(const TCHAR *, SC_HANDLE); +int get_service_startup(const TCHAR *, SC_HANDLE, const QUERY_SERVICE_CONFIG *, unsigned long *); int pre_install_service(int, TCHAR **); int pre_remove_service(int, TCHAR **); int pre_edit_service(int, TCHAR **); -- 2.7.4