From: Iain Patterson Date: Wed, 16 Feb 2011 23:51:22 +0000 (+0000) Subject: Fix event logging. X-Git-Tag: v2.8~7 X-Git-Url: http://git.iain.cx/?p=nssm.git;a=commitdiff_plain;h=e9d9b2fa71473e96650fe3fc4ee0d5535c6725d8 Fix event logging. Some messages weren't being logged properly. One common reason was that one or more arguments to log_event() were longs but were interpreted as strings. Create a temporary buffer and sprintf the numbers to fix that. The other reason was that GetLastError() returns a long where a string was expected. Restore the previously removed error_string() function to convert it into an error message. --- diff --git a/event.cpp b/event.cpp index 661761d..bd43be3 100644 --- a/event.cpp +++ b/event.cpp @@ -1,5 +1,15 @@ #include "nssm.h" +static char error_message[65535]; + +/* Convert error code to error string - must call LocalFree() on return value */ +char *error_string(unsigned long error) { + if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &error_message, sizeof(error_message), 0)) { + if (_snprintf(error_message, sizeof(error_message), "system error %lu", error) < 0) return 0; + } + return error_message; +} + /* Log a message to the Event Log */ void log_event(unsigned short type, unsigned long id, ...) { va_list arg; diff --git a/event.h b/event.h index 3c977a3..2c79521 100644 --- a/event.h +++ b/event.h @@ -1,6 +1,7 @@ #ifndef EVENT_H #define EVENT_H +char *error_string(unsigned long); void log_event(unsigned short, unsigned long, ...); #endif diff --git a/nssm.cpp b/nssm.cpp index 08b9432..3ba473f 100644 --- a/nssm.cpp +++ b/nssm.cpp @@ -45,7 +45,7 @@ int main(int argc, char **argv) { /* Start service magic */ SERVICE_TABLE_ENTRY table[] = { { NSSM, service_main }, { 0, 0 } }; if (! StartServiceCtrlDispatcher(table)) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_DISPATCHER_FAILED, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_DISPATCHER_FAILED, error_string(GetLastError()), 0); return 100; } diff --git a/process.cpp b/process.cpp index 528b981..84d2e9a 100644 --- a/process.cpp +++ b/process.cpp @@ -33,7 +33,7 @@ int kill_threads(char *service_name, kill_t *k) { /* Get a snapshot of all threads in the system. */ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (! snapshot) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATETOOLHELP32SNAPSHOT_THREAD_FAILED, service_name, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATETOOLHELP32SNAPSHOT_THREAD_FAILED, service_name, error_string(GetLastError()), 0); return 0; } @@ -42,7 +42,7 @@ int kill_threads(char *service_name, kill_t *k) { te.dwSize = sizeof(te); if (! Thread32First(snapshot, &te)) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_THREAD_ENUMERATE_FAILED, service_name, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_THREAD_ENUMERATE_FAILED, service_name, error_string(GetLastError()), 0); return 0; } @@ -56,7 +56,7 @@ int kill_threads(char *service_name, kill_t *k) { if (! Thread32Next(snapshot, &te)) { unsigned long error = GetLastError(); if (error == ERROR_NO_MORE_FILES) break; - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_THREAD_ENUMERATE_FAILED, service_name, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_THREAD_ENUMERATE_FAILED, service_name, error_string(GetLastError()), 0); return ret; } @@ -99,15 +99,18 @@ int kill_process(char *service_name, HANDLE process_handle, unsigned long pid, u } void kill_process_tree(char *service_name, unsigned long pid, unsigned long exitcode, unsigned long ppid) { - log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILLING, service_name, pid, exitcode, 0); - - /* Shouldn't happen. */ + /* Shouldn't happen unless the service failed to start. */ if (! pid) return; + char pid_string[16], code[16]; + _snprintf(pid_string, sizeof(pid_string), "%d", pid); + _snprintf(code, sizeof(code), "%d", exitcode); + log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILLING, service_name, pid_string, code, 0); + /* Get a snapshot of all processes in the system. */ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (! snapshot) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATETOOLHELP32SNAPSHOT_PROCESS_FAILED, service_name, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATETOOLHELP32SNAPSHOT_PROCESS_FAILED, service_name, error_string(GetLastError()), 0); return; } @@ -116,7 +119,7 @@ void kill_process_tree(char *service_name, unsigned long pid, unsigned long exit pe.dwSize = sizeof(pe); if (! Process32First(snapshot, &pe)) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PROCESS_ENUMERATE_FAILED, service_name, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PROCESS_ENUMERATE_FAILED, service_name, error_string(GetLastError()), 0); return; } @@ -128,7 +131,7 @@ void kill_process_tree(char *service_name, unsigned long pid, unsigned long exit if (! Process32Next(snapshot, &pe)) { unsigned long ret = GetLastError(); if (ret == ERROR_NO_MORE_FILES) break; - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PROCESS_ENUMERATE_FAILED, service_name, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PROCESS_ENUMERATE_FAILED, service_name, error_string(GetLastError()), 0); return; } @@ -138,13 +141,15 @@ void kill_process_tree(char *service_name, unsigned long pid, unsigned long exit /* We will need a process handle in order to call TerminateProcess() later. */ HANDLE process_handle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, false, pid); if (! process_handle) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENPROCESS_FAILED, pid, service_name, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENPROCESS_FAILED, pid_string, service_name, error_string(GetLastError()), 0); return; } - log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILL_PROCESS_TREE, pid, ppid, service_name, 0); + char ppid_string[16]; + _snprintf(ppid_string, sizeof(ppid_string), "%d", ppid); + log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILL_PROCESS_TREE, pid_string, ppid_string, service_name, 0); if (! kill_process(service_name, process_handle, pid, exitcode)) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_TERMINATEPROCESS_FAILED, pid, service_name, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_TERMINATEPROCESS_FAILED, pid_string, service_name, error_string(GetLastError()), 0); return; } } diff --git a/registry.cpp b/registry.cpp index f82e1bf..15ee152 100644 --- a/registry.cpp +++ b/registry.cpp @@ -10,7 +10,7 @@ int create_messages() { } if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, 0) != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0); return 2; } @@ -37,25 +37,25 @@ int create_parameters(char *service_name, char *exe, char *flags, char *dir) { /* Try to open the registry */ HKEY key; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, 0) != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0); return 2; } /* Try to create the parameters */ if (RegSetValueEx(key, NSSM_REG_EXE, 0, REG_EXPAND_SZ, (const unsigned char *) exe, strlen(exe) + 1) != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_EXE, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_EXE, error_string(GetLastError()), 0); RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY); RegCloseKey(key); return 3; } if (RegSetValueEx(key, NSSM_REG_FLAGS, 0, REG_EXPAND_SZ, (const unsigned char *) flags, strlen(flags) + 1) != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_FLAGS, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_FLAGS, error_string(GetLastError()), 0); RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY); RegCloseKey(key); return 4; } if (RegSetValueEx(key, NSSM_REG_DIR, 0, REG_EXPAND_SZ, (const unsigned char *) dir, strlen(dir) + 1) != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_DIR, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_DIR, error_string(GetLastError()), 0); RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY); RegCloseKey(key); return 5; @@ -79,7 +79,7 @@ int create_exit_action(char *service_name, const char *action_string) { HKEY key; unsigned long disposition; if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, &disposition) != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0); return 2; } @@ -91,7 +91,7 @@ int create_exit_action(char *service_name, const char *action_string) { /* Create the default value */ if (RegSetValueEx(key, 0, 0, REG_SZ, (const unsigned char *) action_string, strlen(action_string) + 1) != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_EXIT, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_EXIT, error_string(GetLastError()), 0); RegCloseKey(key); return 3; } @@ -114,7 +114,7 @@ int expand_parameter(HKEY key, char *value, char *data, unsigned long datalen, b unsigned long ret = RegQueryValueEx(key, value, 0, &type, buffer, &buflen); if (ret != ERROR_SUCCESS) { - if (ret != ERROR_FILE_NOT_FOUND) log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, GetLastError(), 0); + if (ret != ERROR_FILE_NOT_FOUND) log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(GetLastError()), 0); HeapFree(GetProcessHeap(), 0, buffer); return 2; } @@ -133,7 +133,7 @@ int expand_parameter(HKEY key, char *value, char *data, unsigned long datalen, b ret = ExpandEnvironmentStrings((char *) buffer, data, datalen); if (! ret || ret > datalen) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_EXPANDENVIRONMENTSTRINGS_FAILED, value, buffer, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_EXPANDENVIRONMENTSTRINGS_FAILED, value, buffer, error_string(GetLastError()), 0); HeapFree(GetProcessHeap(), 0, buffer); return 3; } @@ -153,7 +153,7 @@ int get_parameters(char *service_name, char *exe, int exelen, char *flags, int f /* Try to open the registry */ HKEY key; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, registry, 0, KEY_READ, &key) != ERROR_SUCCESS) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0); return 2; } @@ -211,7 +211,7 @@ int get_exit_action(char *service_name, unsigned long *ret, unsigned char *actio HKEY key; long error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, registry, 0, KEY_READ, &key); if (error != ERROR_SUCCESS && error != ERROR_FILE_NOT_FOUND) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0); return 2; } diff --git a/service.cpp b/service.cpp index 395e76e..a90d508 100644 --- a/service.cpp +++ b/service.cpp @@ -194,7 +194,7 @@ void WINAPI service_main(unsigned long argc, char **argv) { /* Register control handler */ service_handle = RegisterServiceCtrlHandlerEx(NSSM, service_control_handler, 0); if (! service_handle) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_REGISTERSERVICECTRLHANDER_FAILED, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_REGISTERSERVICECTRLHANDER_FAILED, error_string(GetLastError()), 0); return; } @@ -254,7 +254,7 @@ int monitor_service() { /* Monitor service service */ if (! RegisterWaitForSingleObject(&wait_handle, process_handle, end_service, (void *) pid, INFINITE, WT_EXECUTEONLYONCE | WT_EXECUTELONGFUNCTION)) { - log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_REGISTERWAITFORSINGLEOBJECT_FAILED, service_name, exe, GetLastError(), 0); + log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_REGISTERWAITFORSINGLEOBJECT_FAILED, service_name, exe, error_string(GetLastError()), 0); } return 0; @@ -314,7 +314,7 @@ int start_service() { throttle_restart(); if (! CreateProcess(0, cmd, 0, 0, false, 0, 0, dir, &si, &pi)) { - log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service_name, exe, GetLastError(), 0); + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service_name, exe, error_string(GetLastError()), 0); return stop_service(3, true, true); } process_handle = pi.hProcess;