From 95640f304295257c6d1bb18c806f9d1feb714d61 Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Sun, 11 Sep 2016 22:59:35 +0100 Subject: [PATCH] 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. --- README.txt | 1 + nssm.cpp | 4 ++-- service.cpp | 18 +++++++++--------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/README.txt b/README.txt index 34bacc0..e6d3d50 100644 --- a/README.txt +++ b/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 Meang Akira Tanaka for suggestion and initial implementation of the statuscode command. +Thanks to Kirill Kovalenko for reporting a crash with NANO server. Licence ------- diff --git a/nssm.cpp b/nssm.cpp index 1f9e0ed..6147b90 100644 --- a/nssm.cpp +++ b/nssm.cpp @@ -158,8 +158,8 @@ void strip_basename(TCHAR *buffer) { /* How to use me correctly */ 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); } diff --git a/service.cpp b/service.cpp index dbac12b..a18684e 100644 --- a/service.cpp +++ b/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 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(); if (error != ERROR_MORE_DATA) { print_message(stderr, NSSM_MESSAGE_ENUMSERVICESSTATUS_FAILED, error_string(GetLastError())); 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) { - 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; } bufsize = required; while (true) { /* - EnumServicesStatus() returns: + EnumServicesStatusEx() returns: 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 there's more data to come. 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) { error = GetLastError(); 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 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(); if (error != ERROR_MORE_DATA) { print_message(stderr, NSSM_MESSAGE_ENUMSERVICESSTATUS_FAILED, error_string(GetLastError())); 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) { - 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; } bufsize = required; 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) { error = GetLastError(); if (error != ERROR_MORE_DATA) { -- 2.20.1