Save the environment.

Before the previous two commits we used to read the environment from the
registry and set it using an optimisation which modified the retrieved
block in-place.

Now we need to set the environment twice after querying the registry -
once in get_parameters() and once just before CreateProcess(), which
means we can't use the in-place optimisation and must copy the block
before operating on it.

Additionally, nssm_hook() cleans the environment so we have to reinstate
it immediately prior to launching the application.
master
Iain Patterson 10 years ago
parent ac3246ff80
commit f124b07b52

@ -234,8 +234,7 @@ int nssm_hook(hook_thread_t *hook_threads, nssm_service_t *service, TCHAR *hook_
EnterCriticalSection(&service->hook_section); EnterCriticalSection(&service->hook_section);
/* Set the environment. */ /* Set the environment. */
if (service->env) duplicate_environment(service->env); set_service_environment(service);
if (service->env_extra) set_environment_block(service->env_extra);
/* ABI version. */ /* ABI version. */
TCHAR number[16]; TCHAR number[16];
@ -327,7 +326,7 @@ int nssm_hook(hook_thread_t *hook_threads, nssm_service_t *service, TCHAR *hook_
TCHAR cmd[CMD_LENGTH]; TCHAR cmd[CMD_LENGTH];
if (get_hook(service->name, hook_event, hook_action, cmd, sizeof(cmd))) { if (get_hook(service->name, hook_event, hook_action, cmd, sizeof(cmd))) {
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_HOOK_FAILED, hook_event, hook_action, service->name, 0); log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_HOOK_FAILED, hook_event, hook_action, service->name, 0);
duplicate_environment_strings(service->initial_env); unset_service_environment(service);
LeaveCriticalSection(&service->hook_section); LeaveCriticalSection(&service->hook_section);
HeapFree(GetProcessHeap(), 0, hook); HeapFree(GetProcessHeap(), 0, hook);
return NSSM_HOOK_STATUS_ERROR; return NSSM_HOOK_STATUS_ERROR;
@ -335,7 +334,7 @@ int nssm_hook(hook_thread_t *hook_threads, nssm_service_t *service, TCHAR *hook_
/* No hook. */ /* No hook. */
if (! _tcslen(cmd)) { if (! _tcslen(cmd)) {
duplicate_environment_strings(service->initial_env); unset_service_environment(service);
LeaveCriticalSection(&service->hook_section); LeaveCriticalSection(&service->hook_section);
HeapFree(GetProcessHeap(), 0, hook); HeapFree(GetProcessHeap(), 0, hook);
return NSSM_HOOK_STATUS_NOTFOUND; return NSSM_HOOK_STATUS_NOTFOUND;
@ -389,7 +388,7 @@ int nssm_hook(hook_thread_t *hook_threads, nssm_service_t *service, TCHAR *hook_
} }
/* Restore our environment. */ /* Restore our environment. */
duplicate_environment_strings(service->initial_env); unset_service_environment(service);
LeaveCriticalSection(&service->hook_section); LeaveCriticalSection(&service->hook_section);

@ -275,8 +275,18 @@ static inline unsigned long throttle_milliseconds(unsigned long throttle) {
void set_service_environment(nssm_service_t *service) { void set_service_environment(nssm_service_t *service) {
if (! service) return; if (! service) return;
if (service->env) duplicate_environment(service->env);
if (service->env_extra) set_environment_block(service->env_extra); /*
We have to duplicate the block because this function will be called
multiple times between registry reads.
*/
if (service->env) duplicate_environment_strings(service->env);
if (! service->env_extra) return;
TCHAR *env_extra = copy_environment_block(service->env_extra);
if (! env_extra) return;
set_environment_block(env_extra);
HeapFree(GetProcessHeap(), 0, env_extra);
} }
void unset_service_environment(nssm_service_t *service) { void unset_service_environment(nssm_service_t *service) {
@ -1734,6 +1744,9 @@ int start_service(nssm_service_t *service) {
return stop_service(service, 4, true, true); return stop_service(service, 4, true, true);
} }
/* The pre-start hook will have cleaned the environment. */
set_service_environment(service);
bool inherit_handles = false; bool inherit_handles = false;
if (si.dwFlags & STARTF_USESTDHANDLES) inherit_handles = true; if (si.dwFlags & STARTF_USESTDHANDLES) inherit_handles = true;
unsigned long flags = service->priority & priority_mask(); unsigned long flags = service->priority & priority_mask();

Loading…
Cancel
Save