source: trunk/src/kernel32/environ.cpp@ 22018

Last change on this file since 22018 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 12.9 KB
Line 
1/* $Id: environ.cpp,v 1.15 2002-02-10 13:12:51 sandervl Exp $ */
2
3/*
4 * Win32 environment file functions for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 * Copyright 1998 Patrick Haller
8 * Copyright 1998 Peter Fitzsimmons
9 * Copyright 1998 Knut St. Osmundsen
10 *
11 * Parts based on Wine code (ExpandEnvironmentStringsA/W)
12 * (memory\environ.c; 991114)
13 *
14 * Copyright 1996, 1998 Alexandre Julliard
15 *
16 * Project Odin Software License can be found in LICENSE.TXT
17 *
18 */
19#include <odin.h>
20#include <odinwrap.h>
21#include <os2sel.h>
22
23#include <os2win.h>
24#include <winnt.h>
25#include <winnls.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <string.h>
29#include <heapstring.h>
30
31#include <misc.h>
32#include <unicode.h>
33
34#define DBG_LOCALLOG DBG_environ
35#include "dbglocal.h"
36
37
38ODINDEBUGCHANNEL(KERNEL32-ENVIRONMENT)
39
40
41//list of important OS/2 environment variables that must not be removed
42//when creating a new process
43static const char *lpReservedEnvStrings[] = {
44"HOSTNAME",
45"TZ",
46"USE_HOSTS_FIRST",
47"MMBASE",
48"USER_INI",
49"SYSTEM_INI",
50"DPATH",
51"LANG",
52"NCDEBUG",
53"NLSPATH",
54"TCPLANG",
55"DLSINI",
56"INIT_FILE_NAMES",
57"INIT_FILE_RANGES",
58"NWDBPATH",
59"ETC",
60"WP_OBJHANDLE",
61"SOMIR",
62"SOMDDIR",
63"TMP",
64"TEMP",
65};
66
67//******************************************************************************
68//******************************************************************************
69void InitEnvironment()
70{
71 CHAR szVar[512];
72 static BOOL fInit = FALSE;
73
74 if(fInit) return;
75
76 //TEMP is a standard environment variable in Windows, but is not always
77 //present in OS/2, so make sure it is.
78 if(GetEnvironmentVariableA("TEMP", szVar, sizeof(szVar)) == 0)
79 {
80 if(GetEnvironmentVariableA("TMP", szVar, sizeof(szVar)) == 0) {
81 //then we just use the windows directory for garbage
82 GetWindowsDirectoryA(szVar, sizeof(szVar));
83 }
84 SetEnvironmentVariableA("TEMP", szVar);
85 }
86}
87
88extern "C" {
89
90//******************************************************************************
91//******************************************************************************
92LPSTR WIN32API GetEnvironmentStringsA()
93{
94 InitEnvironment();
95 return (LPSTR) O32_GetEnvironmentStrings();
96}
97//******************************************************************************
98//******************************************************************************
99LPWSTR WIN32API GetEnvironmentStringsW()
100{
101 char *envstrings = (char *)O32_GetEnvironmentStrings();
102 char *tmp;
103 LPWSTR wenvstrings;
104 int len, i;
105
106 InitEnvironment();
107
108 if(envstrings == NULL)
109 return(NULL);
110
111 tmp = envstrings;
112 len = 0;
113 while(*tmp != 0)
114 {
115 len += strlen(tmp)+1;
116 tmp = envstrings + len;
117 }
118 len++; //terminating 0
119 wenvstrings = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
120 for(i=0;i<len;i++)
121 {
122 wenvstrings[i] = envstrings[i];
123 }
124 return(wenvstrings);
125}
126//******************************************************************************
127//******************************************************************************
128BOOL WIN32API FreeEnvironmentStringsA(LPSTR envstrings)
129{
130 return(TRUE);
131}
132//******************************************************************************
133//******************************************************************************
134BOOL WIN32API FreeEnvironmentStringsW(LPWSTR envstrings)
135{
136 HeapFree(GetProcessHeap(), 0, envstrings);
137 return(TRUE);
138}
139//******************************************************************************
140//******************************************************************************
141BOOL WIN32API SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue)
142{
143 dprintf(("KERNEL32: SetEnvironmentVariable %s to %s\n", lpName, lpValue));
144 return O32_SetEnvironmentVariable(lpName, lpValue);
145}
146//******************************************************************************
147//******************************************************************************
148BOOL WIN32API SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue)
149{
150 char *asciiname, *asciivalue;
151 BOOL rc;
152
153 asciiname = UnicodeToAsciiString((LPWSTR)lpName);
154 asciivalue = UnicodeToAsciiString((LPWSTR)lpValue);
155 dprintf(("KERNEL32: SetEnvironmentVariable %s to %s\n", asciiname, asciivalue));
156 rc = O32_SetEnvironmentVariable(asciiname, asciivalue);
157 FreeAsciiString(asciivalue);
158 FreeAsciiString(asciiname);
159 return(rc);
160}
161//******************************************************************************
162//******************************************************************************
163DWORD WIN32API GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer,
164 DWORD nSize)
165{
166 dprintf(("GetEnvironmentVariableA %s", lpName));
167 return O32_GetEnvironmentVariable(lpName, lpBuffer, nSize);
168}
169//******************************************************************************
170//******************************************************************************
171DWORD WIN32API GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer,
172 DWORD nSize)
173{
174 char *astring, *asciibuffer;
175 DWORD rc;
176
177 if (!lpName || !*lpName)
178 {
179 dprintf(("GetEnvironmentVariableW: invalid name!"));
180 SetLastError(ERROR_INVALID_PARAMETER);
181 return 0;
182 }
183
184 if(nSize) {
185 asciibuffer = (char *)malloc(nSize+1);
186 *asciibuffer = 0;
187 }
188 else asciibuffer = NULL;
189
190 astring = UnicodeToAsciiString((LPWSTR)lpName);
191
192 rc = GetEnvironmentVariableA(astring, asciibuffer, nSize);
193 if(asciibuffer)
194 AsciiToUnicode(asciibuffer, lpBuffer);
195 FreeAsciiString(astring);
196 if(asciibuffer)
197 free(asciibuffer);
198 return(rc);
199}
200/***********************************************************************
201 * ENV_FindVariable
202 *
203 * Find a variable in the environment and return a pointer to the value.
204 * Helper function for GetEnvironmentVariable and ExpandEnvironmentStrings.
205 */
206static LPCSTR ENV_FindVariable( LPCSTR env, LPCSTR name, INT len )
207{
208 while (*env)
209 {
210 if (!lstrncmpiA( name, env, len ) && (env[len] == '='))
211 return env + len + 1;
212 env += strlen(env) + 1;
213 }
214 return NULL;
215}
216/*****************************************************************************
217 * Name : DWORD WIN32API ExpandEnvironmentStringsA
218 * Purpose : The ExpandEnvironmentStringsA function expands environment-variable
219 * strings and replaces them with their defined values.
220 * Parameters: LPCSTR lpSrc pointer to string with environment variables
221 * LPSTR lpDst pointer to string with expanded environment variables
222 * DWORD nSize maximum characters in expanded string
223 * Variables :
224 * Result : If the function succeeds, the return value is the number of
225 * characters stored in the destination buffer. If the number of
226 * characters is greater than the size of the destination buffer,
227 * the return value is the size of the buffer required to hold
228 * the expanded strings.
229 * If the function fails, the return value is zero
230 * Remark :
231 * Status :
232 *
233 *****************************************************************************/
234
235DWORD WIN32API ExpandEnvironmentStringsA(LPCSTR src, LPSTR dst, DWORD count)
236{
237 DWORD len, total_size = 1; /* 1 for terminating '\0' */
238 LPCSTR p, var;
239
240 dprintf(("KERNEL32:ExpandEnvironmentStringsA '%s', %08x, %08x",
241 src, dst, count
242 ));
243
244 if (!count) dst = NULL;
245
246 while (*src)
247 {
248 if (*src != '%')
249 {
250 if ((p = strchr( src, '%' )) != NULL) len = p - src;
251 else len = strlen(src);
252 var = src;
253 src += len;
254 }
255 else /* we are at the start of a variable */
256 {
257 if ((p = strchr( src + 1, '%' )) != NULL)
258 {
259 len = p - src - 1; /* Length of the variable name */
260 if ((var = ENV_FindVariable( GetEnvironmentStringsA(),
261 src + 1, len )) != NULL)
262 {
263 src += len + 2; /* Skip the variable name */
264 len = strlen(var);
265 }
266 else
267 {
268 var = src; /* Copy original name instead */
269 len += 2;
270 src += len;
271 }
272 }
273 else /* unfinished variable name, ignore it */
274 {
275 var = src;
276 len = strlen(src); /* Copy whole string */
277 src += len;
278 }
279 }
280 total_size += len;
281 if (dst)
282 {
283 if (count < len) len = count;
284 memcpy( dst, var, len );
285 dst += len;
286 count -= len;
287 }
288 }
289
290 /* Null-terminate the string */
291 if (dst)
292 {
293 if (!count) dst--;
294 *dst = '\0';
295 }
296 return total_size;
297}
298
299/*****************************************************************************
300 * Name : DWORD WIN32API ExpandEnvironmentStringsW
301 * Purpose : The ExpandEnvironmentStringsA function expands environment-variable
302 * strings and replaces them with their defined values.
303 * Parameters: LPCWSTR lpSrc pointer to string with environment variables
304 * LPWSTR lpDst pointer to string with expanded environment variables
305 * DWORD nSize maximum characters in expanded string
306 * Variables :
307 * Result : If the function succeeds, the return value is the number of
308 * characters stored in the destination buffer. If the number of
309 * characters is greater than the size of the destination buffer,
310 * the return value is the size of the buffer required to hold
311 * the expanded strings.
312 * If the function fails, the return value is zero
313 * Remark :
314 * Status :
315 *
316 *****************************************************************************/
317
318DWORD WIN32API ExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst,
319 DWORD nSize)
320{
321 LPSTR srcA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpSrc );
322 LPSTR dstA = lpDst ? (LPSTR)HeapAlloc( GetProcessHeap(), 0, nSize ) : NULL;
323
324 dprintf(("KERNEL32:ExpandEnvironmentStringsW(%08x,%08x,%08x)", lpSrc, lpDst, nSize));
325
326 DWORD ret = ExpandEnvironmentStringsA( srcA, dstA, nSize );
327 if (dstA)
328 {
329 lstrcpyAtoW( lpDst, dstA );
330 HeapFree( GetProcessHeap(), 0, dstA );
331 }
332 HeapFree( GetProcessHeap(), 0, srcA );
333 return ret;
334}
335
336} // extern "C"
337
338//******************************************************************************
339// Create a new process environment block based on input from the application
340// Make sure important OS/2 variables are added or else some services might
341// fail in the child process. (gethostname relies on SET HOSTNAME)
342//******************************************************************************
343char *CreateNewEnvironment(char *lpEnvironment)
344{
345 char *tmpenvold = lpEnvironment;
346 char *tmpenvnew, *newenv;
347 int newsize = 0, len;
348
349 dprintf(("New environment:"));
350 while(*tmpenvold) {
351 dprintf(("%s", tmpenvold));
352 len = strlen(tmpenvold);
353 newsize += len+1;
354 tmpenvold += len+1;
355 }
356 newsize++; //extra null terminator
357
358 for(int i=0;i<sizeof(lpReservedEnvStrings)/sizeof(char *);i++) {
359 if(!ENV_FindVariable(lpEnvironment, lpReservedEnvStrings[i], strlen(lpReservedEnvStrings[i]))) {
360 len = GetEnvironmentVariableA(lpReservedEnvStrings[i], NULL, 0);
361 if(len) {
362 newsize += strlen(lpReservedEnvStrings[i]) + 1 + len+1; //var = value \0
363 }
364 }
365 }
366 newsize++; //extra 0 terminator
367
368 newenv = (char *)malloc(newsize);
369 if(newenv == NULL) {
370 DebugInt3();
371 return NULL;
372 }
373 memset(newenv, 0, newsize);
374 tmpenvold = (char *)lpEnvironment;
375 tmpenvnew = newenv;
376 while(*tmpenvold) {
377 strcat(tmpenvnew, tmpenvold);
378 len = strlen(tmpenvnew);
379 tmpenvnew += len+1;
380 tmpenvold += len+1;
381 }
382 int i;
383 for(i=0;i<sizeof(lpReservedEnvStrings)/sizeof(char *);i++) {
384 if(!ENV_FindVariable(lpEnvironment, lpReservedEnvStrings[i], strlen(lpReservedEnvStrings[i]))) {
385 len = GetEnvironmentVariableA(lpReservedEnvStrings[i], NULL, 0);
386 if(len) {
387 char *tmp = (char *)malloc(len+1);
388 len = GetEnvironmentVariableA(lpReservedEnvStrings[i], tmp, len+1);
389 if(len) {
390 sprintf(tmpenvnew, "%s=%s", lpReservedEnvStrings[i], tmp);
391 tmpenvnew += strlen(tmpenvnew) + 1;
392 }
393 free(tmp);
394 }
395 }
396 }
397 *tmpenvnew = 0; //final null terminator
398
399#ifdef DEBUG
400 tmpenvnew = newenv;
401 dprintf(("Combined new environment:"));
402 while(*tmpenvnew) {
403 dprintf(("%s", tmpenvnew));
404 len = strlen(tmpenvnew);
405 tmpenvnew += len+1;
406 }
407#endif
408 return newenv;
409}
410//******************************************************************************
411//******************************************************************************
Note: See TracBrowser for help on using the repository browser.