From 135329c0790e6d33f658727be3e5439a167a7da8 Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Tue, 26 Nov 2013 17:21:27 +0000 Subject: [PATCH] Added test_environment(). 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 | 36 ++++++++++++++++++++++++++++++++++++ process.h | 1 + 2 files changed, 37 insertions(+) diff --git a/process.cpp b/process.cpp index 1cc6a73..69aea03 100644 --- a/process.cpp +++ b/process.cpp @@ -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; +} diff --git a/process.h b/process.h index 3489f54..a8f2989 100644 --- 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 -- 2.20.1