4 #define WIN32_LEAN_AND_MEAN
9 //#include <tlhelp32.h>
11 extern char **environ;
16 TCHAR chNewEnv[BUFSIZE];
17 LPTSTR lpszCurrentVariable;
19 TCHAR szAppName[]=TEXT("ex3.exe");
21 PROCESS_INFORMATION pi;
23 // Copy environment strings into an environment block.
24 lpszCurrentVariable = (LPTSTR) chNewEnv;
25 if(FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("MySetting=A"))))
27 printf("String copy failed\n");
30 lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
31 if(FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, TEXT("MyVersion=2"))))
33 printf("String copy failed\n");
36 // Terminate the block with a NULL byte.
37 lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
38 *lpszCurrentVariable = (TCHAR)0;
39 // Create the child process, specifying a new environment block.
40 SecureZeroMemory(&si, sizeof(STARTUPINFO));
41 si.cb = sizeof(STARTUPINFO);
43 dwFlags = CREATE_UNICODE_ENVIRONMENT;
45 fSuccess = CreateProcess(szAppName, NULL, NULL, NULL, TRUE, dwFlags,
46 (LPVOID) chNewEnv, // new environment block
50 printf("CreateProcess failed (%d)\n", GetLastError());
53 WaitForSingleObject(pi.hProcess, INFINITE);
62 public class SystemEnvironment
64 property char * { get { return (char *)env; } } // This does not work: property char ** { get { return env; } }
65 private: // unresolved identifier __ecereProp_SystemEnvironment_char__PTR__PTR
78 void PrintCurrentEnvironment(char * headerLine)
80 EnvironmentVariables env { };
81 env.AddCurrentEnvVars();
89 public class EnvironmentVariables : Map<String, String>
95 MapNode<String, String> node;
96 for(node = this.root.minimum; node; node = node.next)
97 PrintLn(node.key, "=", node.value);
100 PrintLn("Empty environment!");
103 bool AddCurrentEnvVars()
105 // TODO: Test char type and unicode correct
107 char ** env = environ;
109 char * env = GetEnvironmentStrings(); // char * vs LPTCH // TODO: Call GetEnvironmentStringsW function #ifdef UNICODE or something
115 for(; var; *env++, var = *env)
117 char * var = env; // char * vs LPTSTR
118 for(; *var; var += strlen(var) + 1) // strlen vs lstrlen
121 char * equal = strstr(var, "=");
122 if(equal && equal != var)
124 // TODO: check this again, delete varName or not? this[CopyString(varName)] or not?
125 int nameLen = equal-var;
126 char * varName = new char[nameLen+1];
127 char * varVal = equal+1;
129 strncpy(varName, var, nameLen);
130 varName[nameLen] = '\0';
131 oldVar = this[varName];
134 this[varName] = CopyString(varVal);
139 FreeEnvironmentStrings(env);
145 void Merge(EnvironmentVariables vars, bool merge)
147 MapNode<String, String> node;
148 for(node = vars.root.minimum; node; node = node.next)
151 MergeVariableValue(node.key, node.value);
153 ReplaceVariableValue(node.key, node.value);
157 void ReplaceVariableValue(char * varName, char * varValue)
159 char * oldValue = this[varName];
161 this[varName] = CopyString(varValue);
164 void MergeVariableValue(char * varName, char * varValue)
166 int dollarStyleRefIdLen, percentStyleRefIdLen;
167 char * dollarStyleRefId, * dollarStyleRef, * percentStyleRefId, * percentStyleRef;
168 char * oldValue = CopyString(this[varName]);
170 dollarStyleRefIdLen = strlen(varName)+3;
171 dollarStyleRefId = new char[dollarStyleRefIdLen+1];
172 sprintf(dollarStyleRefId, "$(%s)", varName);
173 dollarStyleRef = strstr(varValue, dollarStyleRefId);
175 percentStyleRefIdLen = strlen(varName)+2;
176 percentStyleRefId = new char[percentStyleRefIdLen+1];
177 sprintf(percentStyleRefId, "%%%s%%", varName);
178 percentStyleRef = strstr(varValue, percentStyleRefId);
180 // TODO: Make this a loop to replace multiple instances of both dollar and percent style references
183 int beforeLen, oldValLen, afterLen;
185 beforeLen = dollarStyleRef - varValue;
186 dollarStyleRef += dollarStyleRefIdLen;
187 afterLen = strlen(dollarStyleRef);
188 oldValLen = oldValue ? strlen(oldValue) : 0;
189 mergedValue = new char[beforeLen + oldValLen + afterLen + 1];
190 strncpy(mergedValue, varValue, beforeLen);
191 mergedValue[beforeLen] = '\0';
193 strcat(mergedValue, oldValue);
194 strcat(mergedValue, dollarStyleRef);
195 this[varName] = mergedValue;
197 else if(percentStyleRef)
199 int beforeLen, oldValLen, afterLen;
201 beforeLen = percentStyleRef - varValue;
202 percentStyleRef += percentStyleRefIdLen;
203 afterLen = strlen(percentStyleRef);
204 oldValLen = oldValue ? strlen(oldValue) : 0;
205 mergedValue = new char[beforeLen + oldValLen + afterLen + 1];
206 strncpy(mergedValue, varValue, beforeLen);
207 mergedValue[beforeLen] = '\0';
209 strcat(mergedValue, oldValue);
210 strcat(mergedValue, percentStyleRef);
211 this[varName] = mergedValue;
214 this[varName] = CopyString(varValue);
216 delete dollarStyleRefId;
217 delete percentStyleRefId;
223 MapNode<String, String> node;
224 for(node = this.root.minimum; node; node = node.next)
225 SetEnvironment(node.key, node.value);
228 SystemEnvironment GetSystemEnvStrings(int * bufferSize)
230 MapNode<String, String> node;
231 SystemEnvironment output { };
233 char ** env = output.env = new char * [this.count+1];
234 for(node = this.root.minimum; node; node = node.next)
236 *env = new char [strlen(node.key) + strlen(node.value) + 2];
237 sprintf(*env, "%s=%s", node.key, node.value);
242 // TODO: Make sure len vs byte len, unicode and all that is correct
245 for(node = this.root.minimum; node; node = node.next)
246 len += strlen(node.key) + strlen(node.value) + 2;
250 output.env = (char **)new char[len];
251 string = (char *)output.env;
252 for(node = this.root.minimum; node; node = node.next)
254 sprintf(string, "%s=%s", node.key, node.value);
255 string += strlen(node.key) + strlen(node.value) + 2;
262 ~EnvironmentVariables()