Переглянути джерело

Added get_service_startup().

New function to retrieve the service startup type.
Iain Patterson 10 роки тому
батько
коміт
4d0f8abd0f
2 змінених файлів з 52 додано та 39 видалено
  1. 51 39
      service.cpp
  2. 1 0
      service.h

+ 51 - 39
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) {

+ 1 - 0
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 **);