From 750d1a3c6f420b042ea5e1b0c8963648a6422b57 Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Wed, 1 Jan 2014 12:00:33 +0000 Subject: [PATCH] Added format_environment() and unformat_environment(). Added new functions to convert an environment block, with each KEY=value pair separated by NULL NULL, to and from a string, with the pairs separated by CRLF. --- gui.cpp | 43 +++++++++---------------------------------- registry.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ registry.h | 2 ++ 3 files changed, 70 insertions(+), 34 deletions(-) diff --git a/gui.cpp b/gui.cpp index d9b7011..85a7256 100644 --- a/gui.cpp +++ b/gui.cpp @@ -146,27 +146,15 @@ int nssm_gui(int resource, nssm_service_t *service) { } if (envlen) { - /* Replace NULL with CRLF. Leave NULL NULL as the end marker. */ - unsigned long i, j; - unsigned long newlen = envlen; - for (i = 0; i < envlen; i++) if (! env[i] && env[i + 1]) newlen++; - - TCHAR *formatted = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newlen * sizeof(TCHAR)); - if (formatted) { - for (i = 0, j = 0; i < envlen; i++) { - formatted[j] = env[i]; - if (! env[i]) { - if (env[i + 1]) { - formatted[j] = _T('\r'); - formatted[++j] = _T('\n'); - } - } - j++; - } + TCHAR *formatted; + unsigned long newlen; + if (format_environment(env, envlen, &formatted, &newlen)) { + popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()")); + } + else { SetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, formatted); HeapFree(GetProcessHeap(), 0, formatted); } - else popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()")); } if (service->envlen && service->env_extralen) popup_message(MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ENVIRONMENT); } @@ -483,28 +471,15 @@ int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service return 5; } - /* Strip CR and replace LF with NULL. */ - unsigned long newlen = 0; - unsigned long i, j; - for (i = 0; i < envlen; i++) if (env[i] != _T('\r')) newlen++; - /* Must end with two NULLs. */ - newlen += 2; - - TCHAR *newenv = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newlen * sizeof(TCHAR)); - if (! newenv) { + TCHAR *newenv; + unsigned long newlen; + if (unformat_environment(env, envlen, &newenv, &newlen)) { HeapFree(GetProcessHeap(), 0, env); popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()")); cleanup_nssm_service(service); return 5; } - for (i = 0, j = 0; i < envlen; i++) { - if (env[i] == _T('\r')) continue; - if (env[i] == _T('\n')) newenv[j] = _T('\0'); - else newenv[j] = env[i]; - j++; - } - HeapFree(GetProcessHeap(), 0, env); env = newenv; envlen = newlen; diff --git a/registry.cpp b/registry.cpp index 766f73b..cc871b7 100644 --- a/registry.cpp +++ b/registry.cpp @@ -204,6 +204,65 @@ int set_environment(TCHAR *service_name, HKEY key, TCHAR *value, TCHAR **env, un return 0; } +/* Replace NULL with CRLF. Leave NULL NULL as the end marker. */ +int format_environment(TCHAR *env, unsigned long envlen, TCHAR **formatted, unsigned long *newlen) { + unsigned long i, j; + *newlen = envlen; + + if (! *newlen) { + *formatted = 0; + return 0; + } + + for (i = 0; i < envlen; i++) if (! env[i] && env[i + 1]) ++*newlen; + + *formatted = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *newlen * sizeof(TCHAR)); + if (! *formatted) { + *newlen = 0; + return 1; + } + + for (i = 0, j = 0; i < envlen; i++) { + (*formatted)[j] = env[i]; + if (! env[i]) { + if (env[i + 1]) { + (*formatted)[j] = _T('\r'); + (*formatted)[++j] = _T('\n'); + } + } + j++; + } + + return 0; +} + +/* Strip CR and replace LF with NULL. */ +int unformat_environment(TCHAR *env, unsigned long envlen, TCHAR **unformatted, unsigned long *newlen) { + unsigned long i, j; + *newlen = 0; + + if (! envlen) { + *unformatted = 0; + return 0; + } + + for (i = 0; i < envlen; i++) if (env[i] != _T('\r')) ++*newlen; + /* Must end with two NULLs. */ + *newlen += 2; + + *unformatted = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *newlen * sizeof(TCHAR)); + if (! *unformatted) return 1; + + for (i = 0, j = 0; i < envlen; i++) { + if (env[i] == _T('\r')) continue; + if (env[i] == _T('\n')) (*unformatted)[j] = _T('\0'); + else (*unformatted)[j] = env[i]; + j++; + } + + return 0; +} + int expand_parameter(HKEY key, TCHAR *value, TCHAR *data, unsigned long datalen, bool sanitise, bool must_exist) { TCHAR *buffer = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, datalen); if (! buffer) { diff --git a/registry.h b/registry.h index 348c0c4..7af093c 100644 --- a/registry.h +++ b/registry.h @@ -31,6 +31,8 @@ int create_messages(); int create_parameters(nssm_service_t *, bool); int create_exit_action(TCHAR *, const TCHAR *, bool); int set_environment(TCHAR *, HKEY, TCHAR *, TCHAR **, unsigned long *); +int format_environment(TCHAR *, unsigned long, TCHAR **, unsigned long *); +int unformat_environment(TCHAR *, unsigned long, TCHAR **, unsigned long *); int expand_parameter(HKEY, TCHAR *, TCHAR *, unsigned long, bool, bool); int expand_parameter(HKEY, TCHAR *, TCHAR *, unsigned long, bool); int set_expand_string(HKEY, TCHAR *, TCHAR *); -- 2.7.4