Răsfoiți Sursa

Tweaks for NANO server.

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.
Iain Patterson 9 ani în urmă
părinte
comite
95640f3042
3 a modificat fișierele cu 12 adăugiri și 11 ștergeri
  1. 1 0
      README.txt
  2. 2 2
      nssm.cpp
  3. 9 9
      service.cpp

+ 1 - 0
README.txt

@@ -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.
 Thanks to Nicolas Ducrocq for suggesting timestamping redirected output.
 Thanks to Meang Akira Tanaka for suggestion and initial implementation of
 Thanks to Meang Akira Tanaka for suggestion and initial implementation of
 the statuscode command.
 the statuscode command.
+Thanks to Kirill Kovalenko for reporting a crash with NANO server.
 
 
 Licence
 Licence
 -------
 -------

+ 2 - 2
nssm.cpp

@@ -158,8 +158,8 @@ void strip_basename(TCHAR *buffer) {
 
 
 /* How to use me correctly */
 /* How to use me correctly */
 int usage(int ret) {
 int usage(int ret) {
-  if (GetConsoleWindow()) print_message(stderr, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);
-  else popup_message(0, MB_OK, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);
+  if ((! GetConsoleWindow() || ! GetStdHandle(STD_OUTPUT_HANDLE)) && GetProcessWindowStation()) popup_message(0, MB_OK, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);
+  else print_message(stderr, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);
   return(ret);
   return(ret);
 }
 }
 
 

+ 9 - 9
service.cpp

@@ -359,29 +359,29 @@ SC_HANDLE open_service(SC_HANDLE services, TCHAR *service_name, unsigned long ac
 
 
   unsigned long bufsize, required, count, i;
   unsigned long bufsize, required, count, i;
   unsigned long resume = 0;
   unsigned long resume = 0;
-  EnumServicesStatus(services, SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, 0, 0, &required, &count, &resume);
+  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);
   error = GetLastError();
   error = GetLastError();
   if (error != ERROR_MORE_DATA) {
   if (error != ERROR_MORE_DATA) {
     print_message(stderr, NSSM_MESSAGE_ENUMSERVICESSTATUS_FAILED, error_string(GetLastError()));
     print_message(stderr, NSSM_MESSAGE_ENUMSERVICESSTATUS_FAILED, error_string(GetLastError()));
     return 0;
     return 0;
   }
   }
 
 
-  ENUM_SERVICE_STATUS *status = (ENUM_SERVICE_STATUS *) HeapAlloc(GetProcessHeap(), 0, required);
+  ENUM_SERVICE_STATUS_PROCESS *status = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, required);
   if (! status) {
   if (! status) {
-    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("ENUM_SERVICE_STATUS"), _T("open_service()"));
+    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("ENUM_SERVICE_STATUS_PROCESS"), _T("open_service()"));
     return 0;
     return 0;
   }
   }
 
 
   bufsize = required;
   bufsize = required;
   while (true) {
   while (true) {
     /*
     /*
-      EnumServicesStatus() returns:
+      EnumServicesStatusEx() returns:
       1 when it retrieved data and there's no more data to come.
       1 when it retrieved data and there's no more data to come.
       0 and sets last error to ERROR_MORE_DATA when it retrieved data and
       0 and sets last error to ERROR_MORE_DATA when it retrieved data and
         there's more data to come.
         there's more data to come.
       0 and sets last error to something else on error.
       0 and sets last error to something else on error.
     */
     */
-    int ret = EnumServicesStatus(services, SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, status, bufsize, &required, &count, &resume);
+    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);
     if (! ret) {
     if (! ret) {
       error = GetLastError();
       error = GetLastError();
       if (error != ERROR_MORE_DATA) {
       if (error != ERROR_MORE_DATA) {
@@ -2275,22 +2275,22 @@ int list_nssm_services(int argc, TCHAR **argv) {
 
 
   unsigned long bufsize, required, count, i;
   unsigned long bufsize, required, count, i;
   unsigned long resume = 0;
   unsigned long resume = 0;
-  EnumServicesStatus(services, SERVICE_WIN32, SERVICE_STATE_ALL, 0, 0, &required, &count, &resume);
+  EnumServicesStatusEx(services, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, 0, 0, &required, &count, &resume, 0);
   unsigned long error = GetLastError();
   unsigned long error = GetLastError();
   if (error != ERROR_MORE_DATA) {
   if (error != ERROR_MORE_DATA) {
     print_message(stderr, NSSM_MESSAGE_ENUMSERVICESSTATUS_FAILED, error_string(GetLastError()));
     print_message(stderr, NSSM_MESSAGE_ENUMSERVICESSTATUS_FAILED, error_string(GetLastError()));
     return 2;
     return 2;
   }
   }
 
 
-  ENUM_SERVICE_STATUS *status = (ENUM_SERVICE_STATUS *) HeapAlloc(GetProcessHeap(), 0, required);
+  ENUM_SERVICE_STATUS_PROCESS *status = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, required);
   if (! status) {
   if (! status) {
-    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("ENUM_SERVICE_STATUS"), _T("list_nssm_services()"));
+    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("ENUM_SERVICE_STATUS_PROCESS"), _T("list_nssm_services()"));
     return 3;
     return 3;
   }
   }
 
 
   bufsize = required;
   bufsize = required;
   while (true) {
   while (true) {
-    int ret = EnumServicesStatus(services, SERVICE_WIN32, SERVICE_STATE_ALL, status, bufsize, &required, &count, &resume);
+    int ret = EnumServicesStatusEx(services, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE) status, bufsize, &required, &count, &resume, 0);
     if (! ret) {
     if (! ret) {
       error = GetLastError();
       error = GetLastError();
       if (error != ERROR_MORE_DATA) {
       if (error != ERROR_MORE_DATA) {