Tweaks for NANO server.
authorIain Patterson <me@iain.cx>
Sun, 11 Sep 2016 21:59:35 +0000 (22:59 +0100)
committerIain Patterson <me@iain.cx>
Sun, 11 Sep 2016 22:05:12 +0000 (23:05 +0100)
Try to detect if we're running in a Powershell remote session, in which
case we have neither a console nor a window station.  If that's the case
it's appropriate to print the usage message to stdout rather than
attempt to display a popup.

Use EnumServicesStatusEx() instead of EnumServicesStatus().  The latter
crashes on NANO when used in the same way that works correctly on other
versions of Windows.

Thanks Kirill Kovalenko.

README.txt
nssm.cpp
service.cpp

index 34bacc0..e6d3d50 100644 (file)
@@ -1042,6 +1042,7 @@ Thanks to Marcin Lewandowski for spotting a bug appending to large files.
 Thanks to Nicolas Ducrocq for suggesting timestamping redirected output.\r
 Thanks to Meang Akira Tanaka for suggestion and initial implementation of\r
 the statuscode command.\r
+Thanks to Kirill Kovalenko for reporting a crash with NANO server.\r
 \r
 Licence\r
 -------\r
index 1f9e0ed..6147b90 100644 (file)
--- a/nssm.cpp
+++ b/nssm.cpp
@@ -158,8 +158,8 @@ void strip_basename(TCHAR *buffer) {
 \r
 /* How to use me correctly */\r
 int usage(int ret) {\r
-  if (GetConsoleWindow()) print_message(stderr, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);\r
-  else popup_message(0, MB_OK, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);\r
+  if ((! GetConsoleWindow() || ! GetStdHandle(STD_OUTPUT_HANDLE)) && GetProcessWindowStation()) popup_message(0, MB_OK, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);\r
+  else print_message(stderr, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);\r
   return(ret);\r
 }\r
 \r
index dbac12b..a18684e 100644 (file)
@@ -359,29 +359,29 @@ SC_HANDLE open_service(SC_HANDLE services, TCHAR *service_name, unsigned long ac
 \r
   unsigned long bufsize, required, count, i;\r
   unsigned long resume = 0;\r
-  EnumServicesStatus(services, SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, 0, 0, &required, &count, &resume);\r
+  EnumServicesStatusEx(services, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, 0, 0, &required, &count, &resume, 0);\r
   error = GetLastError();\r
   if (error != ERROR_MORE_DATA) {\r
     print_message(stderr, NSSM_MESSAGE_ENUMSERVICESSTATUS_FAILED, error_string(GetLastError()));\r
     return 0;\r
   }\r
 \r
-  ENUM_SERVICE_STATUS *status = (ENUM_SERVICE_STATUS *) HeapAlloc(GetProcessHeap(), 0, required);\r
+  ENUM_SERVICE_STATUS_PROCESS *status = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, required);\r
   if (! status) {\r
-    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("ENUM_SERVICE_STATUS"), _T("open_service()"));\r
+    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("ENUM_SERVICE_STATUS_PROCESS"), _T("open_service()"));\r
     return 0;\r
   }\r
 \r
   bufsize = required;\r
   while (true) {\r
     /*\r
-      EnumServicesStatus() returns:\r
+      EnumServicesStatusEx() returns:\r
       1 when it retrieved data and there's no more data to come.\r
       0 and sets last error to ERROR_MORE_DATA when it retrieved data and\r
         there's more data to come.\r
       0 and sets last error to something else on error.\r
     */\r
-    int ret = EnumServicesStatus(services, SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, status, bufsize, &required, &count, &resume);\r
+    int ret = EnumServicesStatusEx(services, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE) status, bufsize, &required, &count, &resume, 0);\r
     if (! ret) {\r
       error = GetLastError();\r
       if (error != ERROR_MORE_DATA) {\r
@@ -2275,22 +2275,22 @@ int list_nssm_services(int argc, TCHAR **argv) {
 \r
   unsigned long bufsize, required, count, i;\r
   unsigned long resume = 0;\r
-  EnumServicesStatus(services, SERVICE_WIN32, SERVICE_STATE_ALL, 0, 0, &required, &count, &resume);\r
+  EnumServicesStatusEx(services, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, 0, 0, &required, &count, &resume, 0);\r
   unsigned long error = GetLastError();\r
   if (error != ERROR_MORE_DATA) {\r
     print_message(stderr, NSSM_MESSAGE_ENUMSERVICESSTATUS_FAILED, error_string(GetLastError()));\r
     return 2;\r
   }\r
 \r
-  ENUM_SERVICE_STATUS *status = (ENUM_SERVICE_STATUS *) HeapAlloc(GetProcessHeap(), 0, required);\r
+  ENUM_SERVICE_STATUS_PROCESS *status = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, required);\r
   if (! status) {\r
-    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("ENUM_SERVICE_STATUS"), _T("list_nssm_services()"));\r
+    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("ENUM_SERVICE_STATUS_PROCESS"), _T("list_nssm_services()"));\r
     return 3;\r
   }\r
 \r
   bufsize = required;\r
   while (true) {\r
-    int ret = EnumServicesStatus(services, SERVICE_WIN32, SERVICE_STATE_ALL, status, bufsize, &required, &count, &resume);\r
+    int ret = EnumServicesStatusEx(services, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE) status, bufsize, &required, &count, &resume, 0);\r
     if (! ret) {\r
       error = GetLastError();\r
       if (error != ERROR_MORE_DATA) {\r