Fix event logging.
authorIain Patterson <me@iain.cx>
Wed, 16 Feb 2011 23:51:22 +0000 (23:51 +0000)
committerIain Patterson <me@iain.cx>
Wed, 16 Feb 2011 23:51:22 +0000 (23:51 +0000)
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.

event.cpp
event.h
nssm.cpp
process.cpp
registry.cpp
service.cpp

index 661761d..bd43be3 100644 (file)
--- a/event.cpp
+++ b/event.cpp
@@ -1,5 +1,15 @@
 #include "nssm.h"\r
 \r
+static char error_message[65535];\r
+\r
+/* Convert error code to error string - must call LocalFree() on return value */\r
+char *error_string(unsigned long error) {\r
+  if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &error_message, sizeof(error_message), 0)) {\r
+    if (_snprintf(error_message, sizeof(error_message), "system error %lu", error) < 0) return 0;\r
+  }\r
+  return error_message;\r
+}\r
+\r
 /* Log a message to the Event Log */\r
 void log_event(unsigned short type, unsigned long id, ...) {\r
   va_list arg;\r
diff --git a/event.h b/event.h
index 3c977a3..2c79521 100644 (file)
--- a/event.h
+++ b/event.h
@@ -1,6 +1,7 @@
 #ifndef EVENT_H\r
 #define EVENT_H\r
 \r
+char *error_string(unsigned long);\r
 void log_event(unsigned short, unsigned long, ...);\r
 \r
 #endif\r
index 08b9432..3ba473f 100644 (file)
--- a/nssm.cpp
+++ b/nssm.cpp
@@ -45,7 +45,7 @@ int main(int argc, char **argv) {
   /* Start service magic */\r
   SERVICE_TABLE_ENTRY table[] = { { NSSM, service_main }, { 0, 0 } };\r
   if (! StartServiceCtrlDispatcher(table)) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_DISPATCHER_FAILED, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_DISPATCHER_FAILED, error_string(GetLastError()), 0);\r
     return 100;\r
   }\r
 \r
index 528b981..84d2e9a 100644 (file)
@@ -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;
   }
 }
index f82e1bf..15ee152 100644 (file)
@@ -10,7 +10,7 @@ int create_messages() {
   }\r
 \r
   if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, 0) != ERROR_SUCCESS) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0);\r
     return 2;\r
   }\r
 \r
@@ -37,25 +37,25 @@ int create_parameters(char *service_name, char *exe, char *flags, char *dir) {
   /* Try to open the registry */\r
   HKEY key;\r
   if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, 0) != ERROR_SUCCESS) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0);\r
     return 2;\r
   }\r
 \r
   /* Try to create the parameters */\r
   if (RegSetValueEx(key, NSSM_REG_EXE, 0, REG_EXPAND_SZ, (const unsigned char *) exe, strlen(exe) + 1) != ERROR_SUCCESS) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_EXE, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_EXE, error_string(GetLastError()), 0);\r
     RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY);\r
     RegCloseKey(key);\r
     return 3;\r
   }\r
   if (RegSetValueEx(key, NSSM_REG_FLAGS, 0, REG_EXPAND_SZ, (const unsigned char *) flags, strlen(flags) + 1) != ERROR_SUCCESS) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_FLAGS, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_FLAGS, error_string(GetLastError()), 0);\r
     RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY);\r
     RegCloseKey(key);\r
     return 4;\r
   }\r
   if (RegSetValueEx(key, NSSM_REG_DIR, 0, REG_EXPAND_SZ, (const unsigned char *) dir, strlen(dir) + 1) != ERROR_SUCCESS) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_DIR, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_DIR, error_string(GetLastError()), 0);\r
     RegDeleteKey(HKEY_LOCAL_MACHINE, NSSM_REGISTRY);\r
     RegCloseKey(key);\r
     return 5;\r
@@ -79,7 +79,7 @@ int create_exit_action(char *service_name, const char *action_string) {
   HKEY key;\r
   unsigned long disposition;\r
   if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &key, &disposition) != ERROR_SUCCESS) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0);\r
     return 2;\r
   }\r
 \r
@@ -91,7 +91,7 @@ int create_exit_action(char *service_name, const char *action_string) {
 \r
   /* Create the default value */\r
   if (RegSetValueEx(key, 0, 0, REG_SZ, (const unsigned char *) action_string, strlen(action_string) + 1) != ERROR_SUCCESS) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_EXIT, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_SETVALUE_FAILED, NSSM_REG_EXIT, error_string(GetLastError()), 0);\r
     RegCloseKey(key);\r
     return 3;\r
   }\r
@@ -114,7 +114,7 @@ int expand_parameter(HKEY key, char *value, char *data, unsigned long datalen, b
 \r
   unsigned long ret = RegQueryValueEx(key, value, 0, &type, buffer, &buflen);\r
   if (ret != ERROR_SUCCESS) {\r
-    if (ret != ERROR_FILE_NOT_FOUND) log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, GetLastError(), 0);\r
+    if (ret != ERROR_FILE_NOT_FOUND) log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_QUERYVALUE_FAILED, value, error_string(GetLastError()), 0);\r
     HeapFree(GetProcessHeap(), 0, buffer);\r
     return 2;\r
   }\r
@@ -133,7 +133,7 @@ int expand_parameter(HKEY key, char *value, char *data, unsigned long datalen, b
 \r
   ret = ExpandEnvironmentStrings((char *) buffer, data, datalen);\r
   if (! ret || ret > datalen) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_EXPANDENVIRONMENTSTRINGS_FAILED, value, buffer, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_EXPANDENVIRONMENTSTRINGS_FAILED, value, buffer, error_string(GetLastError()), 0);\r
     HeapFree(GetProcessHeap(), 0, buffer);\r
     return 3;\r
   }\r
@@ -153,7 +153,7 @@ int get_parameters(char *service_name, char *exe, int exelen, char *flags, int f
   /* Try to open the registry */\r
   HKEY key;\r
   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, registry, 0, KEY_READ, &key) != ERROR_SUCCESS) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0);\r
     return 2;\r
   }\r
 \r
@@ -211,7 +211,7 @@ int get_exit_action(char *service_name, unsigned long *ret, unsigned char *actio
   HKEY key;\r
   long error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, registry, 0, KEY_READ, &key);\r
   if (error != ERROR_SUCCESS && error != ERROR_FILE_NOT_FOUND) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0);\r
     return 2;\r
   }\r
 \r
index 395e76e..a90d508 100644 (file)
@@ -194,7 +194,7 @@ void WINAPI service_main(unsigned long argc, char **argv) {
   /* Register control handler */\r
   service_handle = RegisterServiceCtrlHandlerEx(NSSM, service_control_handler, 0);\r
   if (! service_handle) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_REGISTERSERVICECTRLHANDER_FAILED, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_REGISTERSERVICECTRLHANDER_FAILED, error_string(GetLastError()), 0);\r
     return;\r
   }\r
 \r
@@ -254,7 +254,7 @@ int monitor_service() {
 \r
   /* Monitor service service */\r
   if (! RegisterWaitForSingleObject(&wait_handle, process_handle, end_service, (void *) pid, INFINITE, WT_EXECUTEONLYONCE | WT_EXECUTELONGFUNCTION)) {\r
-    log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_REGISTERWAITFORSINGLEOBJECT_FAILED, service_name, exe, GetLastError(), 0);\r
+    log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_REGISTERWAITFORSINGLEOBJECT_FAILED, service_name, exe, error_string(GetLastError()), 0);\r
   }\r
 \r
   return 0;\r
@@ -314,7 +314,7 @@ int start_service() {
   throttle_restart();\r
 \r
   if (! CreateProcess(0, cmd, 0, 0, false, 0, 0, dir, &si, &pi)) {\r
-    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service_name, exe, GetLastError(), 0);\r
+    log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service_name, exe, error_string(GetLastError()), 0);\r
     return stop_service(3, true, true);\r
   }\r
   process_handle = pi.hProcess;\r