| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | 
							- #include "nssm.h"
 
- /* Copy an environment block. */
 
- TCHAR *copy_environment_block(TCHAR *env) {
 
-   unsigned long len;
 
-   if (! env) return 0;
 
-   for (len = 0; env[len]; len++) while (env[len]) len++;
 
-   if (! len++) return 0;
 
-   TCHAR *newenv = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR));
 
-   if (! newenv) {
 
-     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("copy_environment_block()"), 0);
 
-     return 0;
 
-   }
 
-   memmove(newenv, env, len * sizeof(TCHAR));
 
-   return newenv;
 
- }
 
- /*
 
-   The environment block starts with variables of the form
 
-   =C:=C:\Windows\System32 which we ignore.
 
- */
 
- TCHAR *useful_environment(TCHAR *rawenv) {
 
-   TCHAR *env = rawenv;
 
-   if (env) {
 
-     while (*env == _T('=')) {
 
-       for ( ; *env; env++);
 
-       env++;
 
-     }
 
-   }
 
-   return env;
 
- }
 
- /* Expand an environment variable.  Must call HeapFree() on the result. */
 
- TCHAR *expand_environment_string(TCHAR *string) {
 
-   unsigned long len;
 
-   len = ExpandEnvironmentStrings(string, 0, 0);
 
-   if (! len) {
 
-     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_EXPANDENVIRONMENTSTRINGS_FAILED, string, error_string(GetLastError()), 0);
 
-     return 0;
 
-   }
 
-   TCHAR *ret = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR));
 
-   if (! ret) {
 
-     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("ExpandEnvironmentStrings()"), _T("expand_environment_string"), 0);
 
-     return 0;
 
-   }
 
-   if (! ExpandEnvironmentStrings(string, ret, len)) {
 
-     log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_EXPANDENVIRONMENTSTRINGS_FAILED, string, error_string(GetLastError()), 0);
 
-     HeapFree(GetProcessHeap(), 0, ret);
 
-     return 0;
 
-   }
 
-   return ret;
 
- }
 
- /*
 
-   Set all the environment variables from an environment block in the current
 
-   environment or remove all the variables in the block from the current
 
-   environment.
 
- */
 
- static int set_environment_block(TCHAR *env, bool set) {
 
-   int ret = 0;
 
-   TCHAR *s, *t;
 
-   for (s = env; *s; s++) {
 
-     for (t = s; *t && *t != _T('='); t++);
 
-     if (*t == _T('=')) {
 
-       *t = _T('\0');
 
-       if (set) {
 
-         TCHAR *expanded = expand_environment_string(++t);
 
-         if (expanded) {
 
-           if (! SetEnvironmentVariable(s, expanded)) ret++;
 
-           HeapFree(GetProcessHeap(), 0, expanded);
 
-         }
 
-         else {
 
-           if (! SetEnvironmentVariable(s, t)) ret++;
 
-         }
 
-       }
 
-       else {
 
-         if (! SetEnvironmentVariable(s, NULL)) ret++;
 
-       }
 
-       for (t++; *t; t++);
 
-     }
 
-     s = t;
 
-   }
 
-   return ret;
 
- }
 
- int set_environment_block(TCHAR *env) {
 
-   return set_environment_block(env, true);
 
- }
 
- static int unset_environment_block(TCHAR *env) {
 
-   return set_environment_block(env, false);
 
- }
 
- /* Remove all variables from the process environment. */
 
- int clear_environment() {
 
-   TCHAR *rawenv = GetEnvironmentStrings();
 
-   TCHAR *env = useful_environment(rawenv);
 
-   int ret = unset_environment_block(env);
 
-   if (rawenv) FreeEnvironmentStrings(rawenv);
 
-   return ret;
 
- }
 
- /* Set the current environment to exactly duplicate an environment block. */
 
- int duplicate_environment(TCHAR *rawenv) {
 
-   int ret = clear_environment();
 
-   TCHAR *env = useful_environment(rawenv);
 
-   ret += set_environment_block(env);
 
-   return ret;
 
- }
 
- /*
 
-   Verify an environment block.
 
-   Returns:  1 if environment is invalid.
 
-             0 if environment is OK.
 
-            -1 on error.
 
- */
 
- int test_environment(TCHAR *env) {
 
-   TCHAR *path = (TCHAR *) nssm_imagepath();
 
-   STARTUPINFO si;
 
-   ZeroMemory(&si, sizeof(si));
 
-   si.cb = sizeof(si);
 
-   PROCESS_INFORMATION pi;
 
-   ZeroMemory(&pi, sizeof(pi));
 
-   unsigned long flags = CREATE_SUSPENDED;
 
- #ifdef UNICODE
 
-   flags |= CREATE_UNICODE_ENVIRONMENT;
 
- #endif
 
-   /*
 
-     Try to relaunch ourselves but with the candidate environment set.
 
-     Assuming no solar flare activity, the only reason this would fail is if
 
-     the environment were invalid.
 
-   */
 
-   if (CreateProcess(0, path, 0, 0, 0, flags, env, 0, &si, &pi)) {
 
-     TerminateProcess(pi.hProcess, 0);
 
-   }
 
-   else {
 
-     unsigned long error = GetLastError();
 
-     if (error == ERROR_INVALID_PARAMETER) return 1;
 
-     else return -1;
 
-   }
 
-   return 0;
 
- }
 
- /*
 
-   Duplicate an environment block returned by GetEnvironmentStrings().
 
-   Since such a block is by definition readonly, and duplicate_environment()
 
-   modifies its inputs, this function takes a copy of the input and operates
 
-   on that.
 
- */
 
- void duplicate_environment_strings(TCHAR *env) {
 
-   TCHAR *newenv = copy_environment_block(env);
 
-   if (! newenv) return;
 
-   duplicate_environment(newenv);
 
-   HeapFree(GetProcessHeap(), 0, newenv);
 
- }
 
- /* Safely get a copy of the current environment. */
 
- TCHAR *copy_environment() {
 
-   TCHAR *rawenv = GetEnvironmentStrings();
 
-   if (! rawenv) return NULL;
 
-   TCHAR *env = copy_environment_block(rawenv);
 
-   FreeEnvironmentStrings(rawenv);
 
-   return env;
 
- }
 
 
  |