#include "nssm.h"\r
\r
-/* Copy an environment block. */\r
-TCHAR *copy_environment_block(TCHAR *env) {\r
- unsigned long len;\r
-\r
- if (! env) return 0;\r
- for (len = 0; env[len]; len++) while (env[len]) len++;\r
- if (! len++) return 0;\r
-\r
- TCHAR *newenv = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR));\r
- if (! newenv) {\r
- log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("copy_environment_block()"), 0);\r
- return 0;\r
+/* Find the length in characters of an environment block. */\r
+size_t environment_length(TCHAR *env) {\r
+ size_t len = 0;\r
+\r
+ TCHAR *s;\r
+ for (s = env; ; s++) {\r
+ len++;\r
+ if (*s == _T('\0')) {\r
+ if (*(s + 1) == _T('\0')) {\r
+ len++;\r
+ break;\r
+ }\r
+ }\r
}\r
\r
- memmove(newenv, env, len * sizeof(TCHAR));\r
+ return len;\r
+}\r
+\r
+/* Copy an environment block. */\r
+TCHAR *copy_environment_block(TCHAR *env) {\r
+ TCHAR *newenv;\r
+ if (copy_double_null(env, (unsigned long) environment_length(env), &newenv)) return 0;\r
return newenv;\r
}\r
\r
FreeEnvironmentStrings(rawenv);\r
return env;\r
}\r
+\r
+/*\r
+ Create a new block with all the strings of the first block plus a new string.\r
+ If the key is already present its value will be overwritten in place.\r
+ If the key is blank or empty the new block will still be allocated and have\r
+ non-zero length.\r
+*/\r
+int append_to_environment_block(TCHAR *env, unsigned long envlen, TCHAR *string, TCHAR **newenv, unsigned long *newlen) {\r
+ size_t keylen = 0;\r
+ if (string && string[0]) {\r
+ for (; string[keylen]; keylen++) {\r
+ if (string[keylen] == _T('=')) {\r
+ keylen++;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ return append_to_double_null(env, envlen, newenv, newlen, string, keylen, false);\r
+}\r
+\r
+/*\r
+ Create a new block with all the strings of the first block minus the given\r
+ string.\r
+ If the key is not present the new block will be a copy of the original.\r
+ If the string is KEY=VALUE the key will only be removed if its value is\r
+ VALUE.\r
+ If the string is just KEY the key will unconditionally be removed.\r
+ If removing the string results in an empty list the new block will still be\r
+ allocated and have non-zero length.\r
+*/\r
+int remove_from_environment_block(TCHAR *env, unsigned long envlen, TCHAR *string, TCHAR **newenv, unsigned long *newlen) {\r
+ if (! string || ! string[0] || string[0] == _T('=')) return 1;\r
+\r
+ TCHAR *key = 0;\r
+ size_t len = _tcslen(string);\r
+ size_t i;\r
+ for (i = 0; i < len; i++) if (string[i] == _T('=')) break;\r
+\r
+ /* Rewrite KEY to KEY= but leave KEY=VALUE alone. */\r
+ size_t keylen = len;\r
+ if (i == len) keylen++;\r
+\r
+ key = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, (keylen + 1) * sizeof(TCHAR));\r
+ if (! key) {\r
+ log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("key"), _T("remove_from_environment_block()"), 0);\r
+ return 2;\r
+ }\r
+ memmove(key, string, len * sizeof(TCHAR));\r
+ if (keylen > len) key[keylen - 1] = _T('=');\r
+ key[keylen] = _T('\0');\r
+\r
+ int ret = remove_from_double_null(env, envlen, newenv, newlen, key, keylen, false);\r
+ HeapFree(GetProcessHeap(), 0, key);\r
+\r
+ return ret;\r
+}\r