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

Last change on this file since 21302 was 21302, checked in by ydario, 16 years ago

Kernel32 updates.

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 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//******************************************************************************
88//******************************************************************************
89LPSTR WIN32API GetEnvironmentStringsA()
90{
91 InitEnvironment();
92 return (LPSTR) O32_GetEnvironmentStrings();
93}
94//******************************************************************************
95//******************************************************************************
96LPWSTR WIN32API GetEnvironmentStringsW()
97{
98 char *envstrings = (char *)O32_GetEnvironmentStrings();
99 char *tmp;
100 LPWSTR wenvstrings;
101 int len, i;
102
103 InitEnvironment();
104
105 if(envstrings == NULL)
106 return(NULL);
107
108 tmp = envstrings;
109 len = 0;
110 while(*tmp != 0)
111 {
112 len += strlen(tmp)+1;
113 tmp = envstrings + len;
114 }
115 len++; //terminating 0
116 wenvstrings = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
117 for(i=0;i<len;i++)
118 {
119 wenvstrings[i] = envstrings[i];
120 }
121 return(wenvstrings);
122}
123//******************************************************************************
124//******************************************************************************
125BOOL WIN32API FreeEnvironmentStringsA(LPSTR envstrings)
126{
127 return(TRUE);
128}
129//******************************************************************************
130//******************************************************************************
131BOOL WIN32API FreeEnvironmentStringsW(LPWSTR envstrings)
132{
133 HeapFree(GetProcessHeap(), 0, envstrings);
134 return(TRUE);
135}
136//******************************************************************************
137//******************************************************************************
138BOOL WIN32API SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue)
139{
140 dprintf(("KERNEL32: SetEnvironmentVariable %s to %s\n", lpName, lpValue));
141 return O32_SetEnvironmentVariable(lpName, lpValue);
142}
143//******************************************************************************
144//******************************************************************************
145BOOL WIN32API SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue)
146{
147 char *asciiname, *asciivalue;
148 BOOL rc;
149
150 asciiname = UnicodeToAsciiString((LPWSTR)lpName);
151 asciivalue = UnicodeToAsciiString((LPWSTR)lpValue);
152 dprintf(("KERNEL32: SetEnvironmentVariable %s to %s\n", asciiname, asciivalue));
153 rc = O32_SetEnvironmentVariable(asciiname, asciivalue);
154 FreeAsciiString(asciivalue);
155 FreeAsciiString(asciiname);
156 return(rc);
157}
158//******************************************************************************
159//******************************************************************************
160DWORD WIN32API GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer,
161 DWORD nSize)
162{
163 dprintf(("GetEnvironmentVariableA %s", lpName));
164 return O32_GetEnvironmentVariable(lpName, lpBuffer, nSize);
165}
166//******************************************************************************
167//******************************************************************************
168DWORD WIN32API GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer,
169 DWORD nSize)
170{
171 char *astring, *asciibuffer;
172 DWORD rc;
173
174 if (!lpName || !*lpName)
175 {
176 dprintf(("GetEnvironmentVariableW: invalid name!"));
177 SetLastError(ERROR_INVALID_PARAMETER);
178 return 0;
179 }
180
181 if(nSize) {
182 asciibuffer = (char *)malloc(nSize+1);
183 *asciibuffer = 0;
184 }
185 else asciibuffer = NULL;
186
187 astring = UnicodeToAsciiString((LPWSTR)lpName);
188
189 rc = GetEnvironmentVariableA(astring, asciibuffer, nSize);
190 if(asciibuffer)
191 AsciiToUnicode(asciibuffer, lpBuffer);
192 FreeAsciiString(astring);
193 if(asciibuffer)
194 free(asciibuffer);
195 return(rc);
196}
197/***********************************************************************
198 * ENV_FindVariable
199 *
200 * Find a variable in the environment and return a pointer to the value.
201 * Helper function for GetEnvironmentVariable and ExpandEnvironmentStrings.
202 */
203static LPCSTR ENV_FindVariable( LPCSTR env, LPCSTR name, INT len )
204{
205 while (*env)
206 {
207 if (!lstrncmpiA( name, env, len ) && (env[len] == '='))
208 return env + len + 1;
209 env += strlen(env) + 1;
210 }
211 return NULL;
212}
213/*****************************************************************************
214 * Name : DWORD WIN32API ExpandEnvironmentStringsA
215 * Purpose : The ExpandEnvironmentStringsA function expands environment-variable
216 * strings and replaces them with their defined values.
217 * Parameters: LPCSTR lpSrc pointer to string with environment variables
218 * LPSTR lpDst pointer to string with expanded environment variables
219 * DWORD nSize maximum characters in expanded string
220 * Variables :
221 * Result : If the function succeeds, the return value is the number of
222 * characters stored in the destination buffer. If the number of
223 * characters is greater than the size of the destination buffer,
224 * the return value is the size of the buffer required to hold
225 * the expanded strings.
226 * If the function fails, the return value is zero
227 * Remark :
228 * Status :
229 *
230 *****************************************************************************/
231
232DWORD WIN32API ExpandEnvironmentStringsA(LPCSTR src, LPSTR dst, DWORD count)
233{
234 DWORD len, total_size = 1; /* 1 for terminating '\0' */
235 LPCSTR p, var;
236
237 dprintf(("KERNEL32:ExpandEnvironmentStringsA '%s', %08x, %08x",
238 src, dst, count
239 ));
240
241 if (!count) dst = NULL;
242
243 while (*src)
244 {
245 if (*src != '%')
246 {
247 if ((p = strchr( src, '%' ))) len = p - src;
248 else len = strlen(src);
249 var = src;
250 src += len;
251 }
252 else /* we are at the start of a variable */
253 {
254 if ((p = strchr( src + 1, '%' )))
255 {
256 len = p - src - 1; /* Length of the variable name */
257 if ((var = ENV_FindVariable( GetEnvironmentStringsA(),
258 src + 1, len )))
259 {
260 src += len + 2; /* Skip the variable name */
261 len = strlen(var);
262 }
263 else
264 {
265 var = src; /* Copy original name instead */
266 len += 2;
267 src += len;
268 }
269 }
270 else /* unfinished variable name, ignore it */
271 {
272 var = src;
273 len = strlen(src); /* Copy whole string */
274 src += len;
275 }
276 }
277 total_size += len;
278 if (dst)
279 {
280 if (count < len) len = count;
281 memcpy( dst, var, len );
282 dst += len;
283 count -= len;
284 }
285 }
286
287 /* Null-terminate the string */
288 if (dst)
289 {
290 if (!count) dst--;
291 *dst = '\0';
292 }
293 return total_size;
294}
295
296/*****************************************************************************
297 * Name : DWORD WIN32API ExpandEnvironmentStringsW
298 * Purpose : The ExpandEnvironmentStringsA function expands environment-variable
299 * strings and replaces them with their defined values.
300 * Parameters: LPCWSTR lpSrc pointer to string with environment variables
301 * LPWSTR lpDst pointer to string with expanded environment variables
302 * DWORD nSize maximum characters in expanded string
303 * Variables :
304 * Result : If the function succeeds, the return value is the number of
305 * characters stored in the destination buffer. If the number of
306 * characters is greater than the size of the destination buffer,
307 * the return value is the size of the buffer required to hold
308 * the expanded strings.
309 * If the function fails, the return value is zero
310 * Remark :
311 * Status :
312 *
313 *****************************************************************************/
314
315DWORD WIN32API ExpandEnvironmentStringsW(LPCWSTR lpSrc, LPWSTR lpDst,
316 DWORD nSize)
317{
318 LPSTR srcA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpSrc );
319 LPSTR dstA = lpDst ? (LPSTR)HeapAlloc( GetProcessHeap(), 0, nSize ) : NULL;
320
321 dprintf(("KERNEL32:ExpandEnvironmentStringsW(%08x,%08x,%08x)", lpSrc, lpDst, nSize));
322
323 DWORD ret = ExpandEnvironmentStringsA( srcA, dstA, nSize );
324 if (dstA)
325 {
326 lstrcpyAtoW( lpDst, dstA );
327 HeapFree( GetProcessHeap(), 0, dstA );
328 }
329 HeapFree( GetProcessHeap(), 0, srcA );
330 return ret;
331}
332//******************************************************************************
333// Create a new process environment block based on input from the application
334// Make sure important OS/2 variables are added or else some services might
335// fail in the child process. (gethostname relies on SET HOSTNAME)
336//******************************************************************************
337char *CreateNewEnvironment(char *lpEnvironment)
338{
339 char *tmpenvold = lpEnvironment;
340 char *tmpenvnew, *newenv;
341 int newsize = 0, len;
342
343 dprintf(("New environment:"));
344 while(*tmpenvold) {
345 dprintf(("%s", tmpenvold));
346 len = strlen(tmpenvold);
347 newsize += len+1;
348 tmpenvold += len+1;
349 }
350 newsize++; //extra null terminator
351
352 for(int i=0;i<sizeof(lpReservedEnvStrings)/sizeof(char *);i++) {
353 if(!ENV_FindVariable(lpEnvironment, lpReservedEnvStrings[i], strlen(lpReservedEnvStrings[i]))) {
354 len = GetEnvironmentVariableA(lpReservedEnvStrings[i], NULL, 0);
355 if(len) {
356 newsize += strlen(lpReservedEnvStrings[i]) + 1 + len+1; //var = value \0
357 }
358 }
359 }
360 newsize++; //extra 0 terminator
361
362 newenv = (char *)malloc(newsize);
363 if(newenv == NULL) {
364 DebugInt3();
365 return NULL;
366 }
367 memset(newenv, 0, newsize);
368 tmpenvold = (char *)lpEnvironment;
369 tmpenvnew = newenv;
370 while(*tmpenvold) {
371 strcat(tmpenvnew, tmpenvold);
372 len = strlen(tmpenvnew);
373 tmpenvnew += len+1;
374 tmpenvold += len+1;
375 }
376 for(i=0;i<sizeof(lpReservedEnvStrings)/sizeof(char *);i++) {
377 if(!ENV_FindVariable(lpEnvironment, lpReservedEnvStrings[i], strlen(lpReservedEnvStrings[i]))) {
378 len = GetEnvironmentVariableA(lpReservedEnvStrings[i], NULL, 0);
379 if(len) {
380 char *tmp = (char *)malloc(len+1);
381 len = GetEnvironmentVariableA(lpReservedEnvStrings[i], tmp, len+1);
382 if(len) {
383 sprintf(tmpenvnew, "%s=%s", lpReservedEnvStrings[i], tmp);
384 tmpenvnew += strlen(tmpenvnew) + 1;
385 }
386 free(tmp);
387 }
388 }
389 }
390 *tmpenvnew = 0; //final null terminator
391
392#ifdef DEBUG
393 tmpenvnew = newenv;
394 dprintf(("Combined new environment:"));
395 while(*tmpenvnew) {
396 dprintf(("%s", tmpenvnew));
397 len = strlen(tmpenvnew);
398 tmpenvnew += len+1;
399 }
400#endif
401 return newenv;
402}
403//******************************************************************************
404//******************************************************************************
Note: See TracBrowser for help on using the repository browser.