Refactor kill functions to be independent of services.
[nssm.git] / env.cpp
diff --git a/env.cpp b/env.cpp
index 5b5f34a..063b60f 100644 (file)
--- a/env.cpp
+++ b/env.cpp
@@ -1,5 +1,23 @@
 #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.
@@ -104,65 +122,6 @@ int duplicate_environment(TCHAR *rawenv) {
   return ret;
 }
 
-/* Replace NULL with CRLF. Leave NULL NULL as the end marker. */
-int format_environment(TCHAR *env, unsigned long envlen, TCHAR **formatted, unsigned long *newlen) {
-  unsigned long i, j;
-  *newlen = envlen;
-
-  if (! *newlen) {
-    *formatted = 0;
-    return 0;
-  }
-
-  for (i = 0; i < envlen; i++) if (! env[i] && env[i + 1]) ++*newlen;
-
-  *formatted = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *newlen * sizeof(TCHAR));
-  if (! *formatted) {
-    *newlen = 0;
-    return 1;
-  }
-
-  for (i = 0, j = 0; i < envlen; i++) {
-    (*formatted)[j] = env[i];
-    if (! env[i]) {
-      if (env[i + 1]) {
-        (*formatted)[j] = _T('\r');
-        (*formatted)[++j] = _T('\n');
-      }
-    }
-    j++;
-  }
-
-  return 0;
-}
-
-/* Strip CR and replace LF with NULL. */
-int unformat_environment(TCHAR *env, unsigned long envlen, TCHAR **unformatted, unsigned long *newlen) {
-  unsigned long i, j;
-  *newlen = 0;
-
-  if (! envlen) {
-    *unformatted = 0;
-    return 0;
-  }
-
-  for (i = 0; i < envlen; i++) if (env[i] != _T('\r')) ++*newlen;
-  /* Must end with two NULLs. */
-  *newlen += 2;
-
-  *unformatted = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *newlen * sizeof(TCHAR));
-  if (! *unformatted) return 1;
-
-  for (i = 0, j = 0; i < envlen; i++) {
-    if (env[i] == _T('\r')) continue;
-    if (env[i] == _T('\n')) (*unformatted)[j] = _T('\0');
-    else (*unformatted)[j] = env[i];
-    j++;
-  }
-
-  return 0;
-}
-
 /*
   Verify an environment block.
   Returns:  1 if environment is invalid.
@@ -198,3 +157,17 @@ int test_environment(TCHAR *env) {
 
   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);
+}