4 The environment block starts with variables of the form
5 =C:=C:\Windows\System32 which we ignore.
7 TCHAR *useful_environment(TCHAR *rawenv) {
11 while (*env == _T('=')) {
20 /* Expand an environment variable. Must call HeapFree() on the result. */
21 TCHAR *expand_environment_string(TCHAR *string) {
24 len = ExpandEnvironmentStrings(string, 0, 0);
26 log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_EXPANDENVIRONMENTSTRINGS_FAILED, string, error_string(GetLastError()), 0);
30 TCHAR *ret = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR));
32 log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("ExpandEnvironmentStrings()"), _T("expand_environment_string"), 0);
36 if (! ExpandEnvironmentStrings(string, ret, len)) {
37 log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_EXPANDENVIRONMENTSTRINGS_FAILED, string, error_string(GetLastError()), 0);
38 HeapFree(GetProcessHeap(), 0, ret);
46 Set all the environment variables from an environment block in the current
47 environment or remove all the variables in the block from the current
50 static int set_environment_block(TCHAR *env, bool set) {
54 for (s = env; *s; s++) {
55 for (t = s; *t && *t != _T('='); t++);
59 TCHAR *expanded = expand_environment_string(++t);
61 if (! SetEnvironmentVariable(s, expanded)) ret++;
62 HeapFree(GetProcessHeap(), 0, expanded);
65 if (! SetEnvironmentVariable(s, t)) ret++;
69 if (! SetEnvironmentVariable(s, NULL)) ret++;
79 int set_environment_block(TCHAR *env) {
80 return set_environment_block(env, true);
83 static int unset_environment_block(TCHAR *env) {
84 return set_environment_block(env, false);
87 /* Remove all variables from the process environment. */
88 int clear_environment() {
89 TCHAR *rawenv = GetEnvironmentStrings();
90 TCHAR *env = useful_environment(rawenv);
92 int ret = unset_environment_block(env);
94 if (rawenv) FreeEnvironmentStrings(rawenv);
99 /* Set the current environment to exactly duplicate an environment block. */
100 int duplicate_environment(TCHAR *rawenv) {
101 int ret = clear_environment();
102 TCHAR *env = useful_environment(rawenv);
103 ret += set_environment_block(env);
108 Verify an environment block.
109 Returns: 1 if environment is invalid.
110 0 if environment is OK.
113 int test_environment(TCHAR *env) {
114 TCHAR path[PATH_LENGTH];
115 GetModuleFileName(0, path, _countof(path));
117 ZeroMemory(&si, sizeof(si));
119 PROCESS_INFORMATION pi;
120 ZeroMemory(&pi, sizeof(pi));
121 unsigned long flags = CREATE_SUSPENDED;
123 flags |= CREATE_UNICODE_ENVIRONMENT;
127 Try to relaunch ourselves but with the candidate environment set.
128 Assuming no solar flare activity, the only reason this would fail is if
129 the environment were invalid.
131 if (CreateProcess(0, path, 0, 0, 0, flags, env, 0, &si, &pi)) {
132 TerminateProcess(pi.hProcess, 0);
135 unsigned long error = GetLastError();
136 if (error == ERROR_INVALID_PARAMETER) return 1;