X-Git-Url: http://git.iain.cx/?a=blobdiff_plain;f=registry.cpp;h=de3127fc9ca8428699430d4d4eacd222683d74d5;hb=32a1d0fab47a050086106aac346342c70f4d985b;hp=42c542590ad7a25ee71bd97e73fcc7dbe892b8e4;hpb=f7f20a0b3ecbb0e1a2eb59f95b50f0625b37c671;p=nssm.git diff --git a/registry.cpp b/registry.cpp index 42c5425..de3127f 100644 --- a/registry.cpp +++ b/registry.cpp @@ -457,7 +457,7 @@ void override_milliseconds(TCHAR *service_name, HKEY key, TCHAR *value, unsigned if (! ok) *buffer = default_value; } -HKEY open_registry(const TCHAR *service_name, const TCHAR *sub, REGSAM sam) { +HKEY open_registry(const TCHAR *service_name, const TCHAR *sub, REGSAM sam, bool must_exist) { /* Get registry */ TCHAR registry[KEY_LENGTH]; HKEY key; @@ -470,14 +470,16 @@ HKEY open_registry(const TCHAR *service_name, const TCHAR *sub, REGSAM sam) { return 0; } - if (sam & KEY_WRITE) { + if (sam & KEY_SET_VALUE) { if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, registry, 0, 0, REG_OPTION_NON_VOLATILE, sam, 0, &key, 0) != ERROR_SUCCESS) { log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0); return 0; } } else { - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, registry, 0, sam, &key) != ERROR_SUCCESS) { + long error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, registry, 0, sam, &key); + if (error != ERROR_SUCCESS) { + if (error == ERROR_FILE_NOT_FOUND && ! must_exist) return 0; log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENKEY_FAILED, registry, error_string(GetLastError()), 0); return 0; } @@ -486,8 +488,12 @@ HKEY open_registry(const TCHAR *service_name, const TCHAR *sub, REGSAM sam) { return key; } +HKEY open_registry(const TCHAR *service_name, const TCHAR *sub, REGSAM sam) { + return open_registry(service_name, sub, sam, true); +} + HKEY open_registry(const TCHAR *service_name, REGSAM sam) { - return open_registry(service_name, 0, sam); + return open_registry(service_name, 0, sam, true); } int get_io_parameters(nssm_service_t *service, HKEY key) { @@ -525,6 +531,14 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) { /* Don't expand parameters when retrieving for the GUI. */ bool expand = si ? true : false; + /* Try to get environment variables - may fail */ + get_environment(service->name, key, NSSM_REG_ENV, &service->env, &service->envlen); + /* Environment variables to add to existing rather than replace - may fail. */ + get_environment(service->name, key, NSSM_REG_ENV_EXTRA, &service->env_extra, &service->env_extralen); + + /* Set environment if we are starting the service. */ + if (si) set_service_environment(service); + /* Try to get executable file - MUST succeed */ if (get_string(key, NSSM_REG_EXE, service->exe, sizeof(service->exe), expand, false, true)) { RegCloseKey(key); @@ -579,11 +593,6 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) { } } - /* Try to get environment variables - may fail */ - get_environment(service->name, key, NSSM_REG_ENV, &service->env, &service->envlen); - /* Environment variables to add to existing rather than replace - may fail. */ - get_environment(service->name, key, NSSM_REG_ENV_EXTRA, &service->env_extra, &service->env_extralen); - /* Try to get priority - may fail. */ unsigned long priority; if (get_number(key, NSSM_REG_PRIORITY, &priority, false) == 1) { @@ -729,3 +738,57 @@ int get_exit_action(const TCHAR *service_name, unsigned long *ret, TCHAR *action return 0; } + +int set_hook(const TCHAR *service_name, const TCHAR *hook_event, const TCHAR *hook_action, TCHAR *cmd) { + /* Try to open the registry */ + TCHAR registry[KEY_LENGTH]; + if (_sntprintf_s(registry, _countof(registry), _TRUNCATE, _T("%s\\%s"), NSSM_REG_HOOK, hook_event) < 0) { + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("hook registry"), _T("set_hook()"), 0); + return 1; + } + + HKEY key; + long error; + + /* Don't create keys needlessly. */ + if (! _tcslen(cmd)) { + key = open_registry(service_name, registry, KEY_READ, false); + if (! key) return 0; + error = RegQueryValueEx(key, hook_action, 0, 0, 0, 0); + RegCloseKey(key); + if (error == ERROR_FILE_NOT_FOUND) return 0; + } + + key = open_registry(service_name, registry, KEY_WRITE); + if (! key) return 1; + + int ret = 1; + if (_tcslen(cmd)) ret = set_string(key, (TCHAR *) hook_action, cmd, true); + else { + error = RegDeleteValue(key, hook_action); + if (error == ERROR_SUCCESS || error == ERROR_FILE_NOT_FOUND) ret = 0; + } + + /* Close registry */ + RegCloseKey(key); + + return ret; +} + +int get_hook(const TCHAR *service_name, const TCHAR *hook_event, const TCHAR *hook_action, TCHAR *buffer, unsigned long buflen) { + /* Try to open the registry */ + TCHAR registry[KEY_LENGTH]; + if (_sntprintf_s(registry, _countof(registry), _TRUNCATE, _T("%s\\%s"), NSSM_REG_HOOK, hook_event) < 0) { + log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("hook registry"), _T("get_hook()"), 0); + return 1; + } + HKEY key = open_registry(service_name, registry, KEY_READ, false); + if (! key) return 1; + + int ret = expand_parameter(key, (TCHAR *) hook_action, buffer, buflen, true, false); + + /* Close registry */ + RegCloseKey(key); + + return ret; +}