X-Git-Url: http://git.iain.cx/?a=blobdiff_plain;f=settings.cpp;h=3ed5ec4dc880c89b58d4d18381533ce3db733963;hb=3e92dce8716991c7100ea55f0b5e202a05c1b56d;hp=7d08e134850f0fd568d12e8f2df9f05bbac0b563;hpb=6adc886e1fa296f67aacef0c01994e302e8caf86;p=nssm.git diff --git a/settings.cpp b/settings.cpp index 7d08e13..3ed5ec4 100644 --- a/settings.cpp +++ b/settings.cpp @@ -339,17 +339,54 @@ static int setting_set_environment(const TCHAR *service_name, void *param, const HKEY key = (HKEY) param; if (! param) return -1; - if (! value || ! value->string || ! value->string[0]) { + TCHAR *string = 0; + TCHAR *unformatted = 0; + unsigned long envlen; + unsigned long newlen = 0; + int op = 0; + if (value && value->string && value->string[0]) { + string = value->string; + switch (string[0]) { + case _T('+'): op = 1; break; + case _T('-'): op = -1; break; + case _T(':'): string++; break; + } + } + + if (op) { + string++; + TCHAR *env = 0; + if (get_environment((TCHAR *) service_name, key, (TCHAR *) name, &env, &envlen)) return -1; + if (env) { + int ret; + if (op > 0) ret = append_to_environment_block(env, envlen, string, &unformatted, &newlen); + else ret = remove_from_environment_block(env, envlen, string, &unformatted, &newlen); + if (envlen) HeapFree(GetProcessHeap(), 0, env); + if (ret) return -1; + + string = unformatted; + } + else { + /* + No existing environment. + We can't remove from an empty environment so just treat an add + operation as setting a new string. + */ + if (op < 0) return 0; + op = 0; + } + } + + if (! string || ! string[0]) { long error = RegDeleteValue(key, name); if (error == ERROR_SUCCESS || error == ERROR_FILE_NOT_FOUND) return 0; print_message(stderr, NSSM_MESSAGE_REGDELETEVALUE_FAILED, name, service_name, error_string(error)); return -1; } - unsigned long envlen = (unsigned long) _tcslen(value->string) + 1; - TCHAR *unformatted = 0; - unsigned long newlen; - if (unformat_double_null(value->string, envlen, &unformatted, &newlen)) return -1; + if (! op) { + if (unformat_double_null(string, (unsigned long) _tcslen(string), &unformatted, &newlen)) return -1; + } if (test_environment(unformatted)) { HeapFree(GetProcessHeap(), 0, unformatted); @@ -452,7 +489,9 @@ static int setting_get_priority(const TCHAR *service_name, void *param, const TC unsigned long constant; switch (get_number(key, (TCHAR *) name, &constant, false)) { - case 0: return value_from_string(name, value, (const TCHAR *) default_value); + case 0: + if (value_from_string(name, value, (const TCHAR *) default_value) == -1) return -1; + return 0; case -1: return -1; } @@ -727,20 +766,20 @@ int native_get_displayname(const TCHAR *service_name, void *param, const TCHAR * } int native_set_environment(const TCHAR *service_name, void *param, const TCHAR *name, void *default_value, value_t *value, const TCHAR *additional) { - HKEY key = open_service_registry(service_name, KEY_SET_VALUE, false); + HKEY key = open_service_registry(service_name, KEY_SET_VALUE, true); if (! key) return -1; - int ret = setting_set_environment(service_name, (void *) key, NSSM_NATIVE_ENVIRONMENT, default_value, value, additional); + int ret = setting_set_environment(service_name, (void *) key, name, default_value, value, additional); RegCloseKey(key); return ret; } int native_get_environment(const TCHAR *service_name, void *param, const TCHAR *name, void *default_value, value_t *value, const TCHAR *additional) { - HKEY key = open_service_registry(service_name, KEY_READ, false); + HKEY key = open_service_registry(service_name, KEY_READ, true); if (! key) return -1; ZeroMemory(value, sizeof(value_t)); - int ret = setting_get_environment(service_name, (void *) key, NSSM_NATIVE_ENVIRONMENT, default_value, value, additional); + int ret = setting_get_environment(service_name, (void *) key, name, default_value, value, additional); RegCloseKey(key); return ret; }