Jelajahi Sumber

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.
Iain Patterson 13 tahun lalu
induk
melakukan
e9d9b2fa71
6 mengubah file dengan 43 tambahan dan 27 penghapusan
  1. 10 0
      event.cpp
  2. 1 0
      event.h
  3. 1 1
      nssm.cpp
  4. 17 12
      process.cpp
  5. 11 11
      registry.cpp
  6. 3 3
      service.cpp

+ 10 - 0
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;

+ 1 - 0
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

+ 1 - 1
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;
   }
 

+ 17 - 12
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;
   }
 }

+ 11 - 11
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;
   }
 

+ 3 - 3
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;