Added test_environment().
authorIain Patterson <me@iain.cx>
Tue, 26 Nov 2013 17:21:27 +0000 (17:21 +0000)
committerIain Patterson <me@iain.cx>
Tue, 26 Nov 2013 20:38:06 +0000 (20:38 +0000)
New helper function to verify the environment by relaunching NSSM itself
with the candidate environment set.  Unless something goes horribly
wrong somewhere, CreateProcess() will succeed iff the environment is
valid.

process.cpp
process.h

index 1cc6a73..69aea03 100644 (file)
@@ -306,3 +306,39 @@ void kill_process_tree(nssm_service_t *service, unsigned long pid, unsigned long
 
   CloseHandle(process_handle);
 }
+
+/*
+  Verify an environment block.
+  Returns:  1 if environment is invalid.
+            0 if environment is OK.
+           -1 on error.
+*/
+int test_environment(TCHAR *env) {
+  TCHAR path[MAX_PATH];
+  GetModuleFileName(0, path, _countof(path));
+  STARTUPINFO si;
+  ZeroMemory(&si, sizeof(si));
+  si.cb = sizeof(si);
+  PROCESS_INFORMATION pi;
+  ZeroMemory(&pi, sizeof(pi));
+  unsigned long flags = CREATE_SUSPENDED;
+#ifdef UNICODE
+  flags |= CREATE_UNICODE_ENVIRONMENT;
+#endif
+
+  /*
+    Try to relaunch ourselves but with the candidate environment set.
+    Assuming no solar flare activity, the only reason this would fail is if
+    the environment were invalid.
+  */
+  if (CreateProcess(0, path, 0, 0, 0, flags, env, 0, &si, &pi)) {
+    TerminateProcess(pi.hProcess, 0);
+  }
+  else {
+    unsigned long error = GetLastError();
+    if (error == ERROR_INVALID_PARAMETER) return 1;
+    else return -1;
+  }
+
+  return 0;
+}
index 3489f54..a8f2989 100644 (file)
--- a/process.h
+++ b/process.h
@@ -17,5 +17,6 @@ int kill_threads(nssm_service_t *, kill_t *);
 int kill_console(nssm_service_t *);
 int kill_process(nssm_service_t *, HANDLE, unsigned long, unsigned long);
 void kill_process_tree(nssm_service_t *, unsigned long, unsigned long, unsigned long);
+int test_environment(TCHAR *);
 
 #endif