Added get_service_startup().
authorIain Patterson <me@iain.cx>
Mon, 30 Dec 2013 11:50:20 +0000 (11:50 +0000)
committerIain Patterson <me@iain.cx>
Wed, 1 Jan 2014 12:41:54 +0000 (12:41 +0000)
New function to retrieve the service startup type.

service.cpp
service.h

index abe745a..e3824ff 100644 (file)
@@ -65,6 +65,50 @@ QUERY_SERVICE_CONFIG *query_service_config(const TCHAR *service_name, SC_HANDLE
   return qsc;\r
 }\r
 \r
+int get_service_startup(const TCHAR *service_name, SC_HANDLE service_handle, const QUERY_SERVICE_CONFIG *qsc, unsigned long *startup) {\r
+  if (! qsc) return 1;\r
+\r
+  switch (qsc->dwStartType) {\r
+    case SERVICE_DEMAND_START: *startup = NSSM_STARTUP_MANUAL; break;\r
+    case SERVICE_DISABLED: *startup = NSSM_STARTUP_DISABLED; break;\r
+    default: *startup = NSSM_STARTUP_AUTOMATIC;\r
+  }\r
+\r
+  if (*startup != NSSM_STARTUP_AUTOMATIC) return 0;\r
+\r
+  /* Check for delayed start. */\r
+  unsigned long bufsize;\r
+  unsigned long error;\r
+  QueryServiceConfig2(service_handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, 0, 0, &bufsize);\r
+  error = GetLastError();\r
+  if (error == ERROR_INSUFFICIENT_BUFFER) {\r
+    SERVICE_DELAYED_AUTO_START_INFO *info = (SERVICE_DELAYED_AUTO_START_INFO *) HeapAlloc(GetProcessHeap(), 0, bufsize);\r
+    if (! info) {\r
+      print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("SERVICE_DELAYED_AUTO_START_INFO"), _T("get_service_startup()"));\r
+      return 2;\r
+    }\r
+\r
+    if (QueryServiceConfig2(service_handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, (unsigned char *) info, bufsize, &bufsize)) {\r
+      if (info->fDelayedAutostart) *startup = NSSM_STARTUP_DELAYED;\r
+      HeapFree(GetProcessHeap(), 0, info);\r
+      return 0;\r
+    }\r
+    else {\r
+      error = GetLastError();\r
+      if (error != ERROR_INVALID_LEVEL) {\r
+        print_message(stderr, NSSM_MESSAGE_QUERYSERVICECONFIG2_FAILED, service_name, _T("SERVICE_CONFIG_DELAYED_AUTO_START_INFO"), error_string(error));\r
+        return 3;\r
+      }\r
+    }\r
+  }\r
+  else if (error != ERROR_INVALID_LEVEL) {\r
+    print_message(stderr, NSSM_MESSAGE_QUERYSERVICECONFIG2_FAILED, service_name, _T("SERVICE_DELAYED_AUTO_START_INFO"), error_string(error));\r
+    return 3;\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
 static int grant_logon_as_service(const TCHAR *username) {\r
   if (str_equiv(username, NSSM_LOCALSYSTEM_ACCOUNT)) return 0;\r
 \r
@@ -341,11 +385,13 @@ int pre_edit_service(int argc, TCHAR **argv) {
     return 3;\r
   }\r
 \r
-  switch (qsc->dwStartType) {\r
-    case SERVICE_DEMAND_START: service->startup = NSSM_STARTUP_MANUAL; break;\r
-    case SERVICE_DISABLED: service->startup = NSSM_STARTUP_DISABLED; break;\r
-    default: service->startup = NSSM_STARTUP_AUTOMATIC;\r
+  if (get_service_startup(service->name, service->handle, qsc, &service->startup)) {\r
+    HeapFree(GetProcessHeap(), 0, qsc);\r
+    CloseHandle(service->handle);\r
+    CloseServiceHandle(services);\r
+    return 4;\r
   }\r
+\r
   if (! str_equiv(qsc->lpServiceStartName, NSSM_LOCALSYSTEM_ACCOUNT)) {\r
     size_t len = _tcslen(qsc->lpServiceStartName);\r
     service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR));\r
@@ -358,7 +404,7 @@ int pre_edit_service(int argc, TCHAR **argv) {
       CloseHandle(service->handle);\r
       CloseServiceHandle(services);\r
       print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("username"), _T("pre_edit_service()"));\r
-      return 4;\r
+      return 5;\r
     }\r
   }\r
   _sntprintf_s(service->displayname, _countof(service->displayname), _TRUNCATE, _T("%s"), qsc->lpDisplayName);\r
@@ -372,40 +418,6 @@ int pre_edit_service(int argc, TCHAR **argv) {
   HeapFree(GetProcessHeap(), 0, qsc);\r
 \r
   /* Get extended system details. */\r
-  if (service->startup == NSSM_STARTUP_AUTOMATIC) {\r
-    QueryServiceConfig2(service->handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, 0, 0, &bufsize);\r
-    error = GetLastError();\r
-    if (error == ERROR_INSUFFICIENT_BUFFER) {\r
-      SERVICE_DELAYED_AUTO_START_INFO *info = (SERVICE_DELAYED_AUTO_START_INFO *) HeapAlloc(GetProcessHeap(), 0, bufsize);\r
-      if (! info) {\r
-        CloseHandle(service->handle);\r
-        CloseServiceHandle(services);\r
-        print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("SERVICE_DELAYED_AUTO_START_INFO"), _T("pre_edit_service()"));\r
-        return 5;\r
-      }\r
-\r
-      if (QueryServiceConfig2(service->handle, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, (unsigned char *) info, bufsize, &bufsize)) {\r
-        if (info->fDelayedAutostart) service->startup = NSSM_STARTUP_DELAYED;\r
-        HeapFree(GetProcessHeap(), 0, info);\r
-      }\r
-      else {\r
-        error = GetLastError();\r
-        if (error != ERROR_INVALID_LEVEL) {\r
-          CloseHandle(service->handle);\r
-          CloseServiceHandle(services);\r
-          print_message(stderr, NSSM_MESSAGE_QUERYSERVICECONFIG2_FAILED, service->name, _T("SERVICE_CONFIG_DELAYED_AUTO_START_INFO"), error_string(error));\r
-          return 5;\r
-        }\r
-      }\r
-    }\r
-    else if (error != ERROR_INVALID_LEVEL) {\r
-      CloseHandle(service->handle);\r
-      CloseServiceHandle(services);\r
-      print_message(stderr, NSSM_MESSAGE_QUERYSERVICECONFIG2_FAILED, service->name, _T("SERVICE_DELAYED_AUTO_START_INFO"), error_string(error));\r
-      return 5;\r
-    }\r
-  }\r
-\r
   QueryServiceConfig2(service->handle, SERVICE_CONFIG_DESCRIPTION, 0, 0, &bufsize);\r
   error = GetLastError();\r
   if (error == ERROR_INSUFFICIENT_BUFFER) {\r
index 596b82b..ca06a2e 100644 (file)
--- 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 *);\r
 SC_HANDLE open_service_manager();\r
 QUERY_SERVICE_CONFIG *query_service_config(const TCHAR *, SC_HANDLE);\r
+int get_service_startup(const TCHAR *, SC_HANDLE, const QUERY_SERVICE_CONFIG *, unsigned long *);\r
 int pre_install_service(int, TCHAR **);\r
 int pre_remove_service(int, TCHAR **);\r
 int pre_edit_service(int, TCHAR **);\r