ReactOS 0.4.16-dev-2104-gb84fa49
environ.c
Go to the documentation of this file.
1/*
2 * msvcrt.dll environment functions
3 *
4 * Copyright 1996,1998 Marcus Meissner
5 * Copyright 1996 Jukka Iivonen
6 * Copyright 1997,2000 Uwe Bonnes
7 * Copyright 2000 Jon Griffiths
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23#include "msvcrt.h"
24#include "mtdll.h"
25#include <winnls.h>
26#include "wine/debug.h"
27
29
30int env_init(BOOL unicode, BOOL modif)
31{
32 if (!unicode && !MSVCRT___initenv)
33 {
34 char *environ_strings = GetEnvironmentStringsA();
35 int count = 1, len = 1, i = 0; /* keep space for the trailing NULLS */
36 char *ptr;
37
38 for (ptr = environ_strings; *ptr; ptr += strlen(ptr) + 1)
39 {
40 /* Don't count environment variables starting with '=' which are command shell specific */
41 if (*ptr != '=') count++;
42 len += strlen(ptr) + 1;
43 }
46 {
47 FreeEnvironmentStringsA(environ_strings);
48 return -1;
49 }
50
51 memcpy(&MSVCRT___initenv[count], environ_strings, len);
52 for (ptr = (char *)&MSVCRT___initenv[count]; *ptr; ptr += strlen(ptr) + 1)
53 {
54 /* Skip special environment strings set by the command shell */
55 if (*ptr != '=') MSVCRT___initenv[i++] = ptr;
56 }
58 FreeEnvironmentStringsA(environ_strings);
59
61 }
62
63 if (!unicode && modif && MSVCRT__environ == MSVCRT___initenv)
64 {
65 int i = 0;
66
67 while(MSVCRT___initenv[i]) i++;
68 MSVCRT__environ = malloc((i + 1) * sizeof(char *));
69 if (!MSVCRT__environ) return -1;
70 for (i = 0; MSVCRT___initenv[i]; i++)
73 }
74
75 if (unicode && !MSVCRT___winitenv)
76 {
77 wchar_t *wenviron_strings = GetEnvironmentStringsW();
78 int count = 1, len = 1, i = 0; /* keep space for the trailing NULLS */
79 wchar_t *wptr;
80
81 for (wptr = wenviron_strings; *wptr; wptr += wcslen(wptr) + 1)
82 {
83 /* Don't count environment variables starting with '=' which are command shell specific */
84 if (*wptr != '=') count++;
85 len += wcslen(wptr) + 1;
86 }
87 MSVCRT___winitenv = malloc(count * sizeof(*MSVCRT___winitenv) + len * sizeof(wchar_t));
89 {
90 FreeEnvironmentStringsW(wenviron_strings);
91 return -1;
92 }
93
94 memcpy(&MSVCRT___winitenv[count], wenviron_strings, len * sizeof(wchar_t));
95 for (wptr = (wchar_t *)&MSVCRT___winitenv[count]; *wptr; wptr += wcslen(wptr) + 1)
96 {
97 /* Skip special environment strings set by the command shell */
98 if (*wptr != '=') MSVCRT___winitenv[i++] = wptr;
99 }
101 FreeEnvironmentStringsW(wenviron_strings);
102
104 }
105
106 if (unicode && modif && MSVCRT__wenviron == MSVCRT___winitenv)
107 {
108 int i = 0;
109
110 while(MSVCRT___winitenv[i]) i++;
111 MSVCRT__wenviron = malloc((i + 1) * sizeof(wchar_t *));
112 if (!MSVCRT__wenviron) return -1;
113 for (i = 0; MSVCRT___winitenv[i]; i++)
116 }
117
118 return 0;
119}
120
121static int env_get_index(const char *name)
122{
123 int i, len;
124
125 len = strlen(name);
126 for (i = 0; MSVCRT__environ[i]; i++)
127 {
128 if (!strnicmp(name, MSVCRT__environ[i], len) && MSVCRT__environ[i][len] == '=')
129 return i;
130 }
131 return i;
132}
133
134static int wenv_get_index(const wchar_t *name)
135{
136 int i, len;
137
138 len = wcslen(name);
139 for (i = 0; MSVCRT__wenviron[i]; i++)
140 {
142 return i;
143 }
144 return i;
145}
146
147static int env_set(char **env, wchar_t **wenv)
148{
149 wchar_t *weq = wcschr(*wenv, '=');
150 char *eq = strchr(*env, '=');
151 int idx;
152
153 *weq = 0;
154 if (!SetEnvironmentVariableW(*wenv, weq[1] ? weq + 1 : NULL) &&
156 return -1;
157
158 if (env_init(FALSE, TRUE)) return -1;
159 *eq = 0;
161 *eq = '=';
162 if (!eq[1])
163 {
165 for(; MSVCRT__environ[idx]; idx++)
167 }
168 else if (MSVCRT__environ[idx])
169 {
172 *env = NULL;
173 }
174 else
175 {
176 char **new_env = realloc(MSVCRT__environ, (idx + 2) * sizeof(*MSVCRT__environ));
177 if (!new_env) return -1;
178 MSVCRT__environ = new_env;
180 MSVCRT__environ[idx + 1] = NULL;
181 *env = NULL;
182 }
183
184 if (!MSVCRT__wenviron) return 0;
186 if (env_init(TRUE, TRUE)) return -1;
187 idx = wenv_get_index(*wenv);
188 *weq = '=';
189 if (!weq[1])
190 {
192 for(; MSVCRT__wenviron[idx]; idx++)
194 }
195 else if (MSVCRT__wenviron[idx])
196 {
198 MSVCRT__wenviron[idx] = *wenv;
199 *wenv = NULL;
200 }
201 else
202 {
203 wchar_t **new_env = realloc(MSVCRT__wenviron, (idx + 2) * sizeof(*MSVCRT__wenviron));
204 if (!new_env) return -1;
205 MSVCRT__wenviron = new_env;
206 MSVCRT__wenviron[idx] = *wenv;
208 *wenv = NULL;
209 }
210 return 0;
211}
212
213static char * getenv_helper(const char *name)
214{
215 int idx;
216
217 if (!name) return NULL;
218
220 if (!MSVCRT__environ[idx]) return NULL;
221 return strchr(MSVCRT__environ[idx], '=') + 1;
222}
223
224/*********************************************************************
225 * getenv (MSVCRT.@)
226 */
227char * CDECL getenv(const char *name)
228{
229 char *ret;
230
231 if (!MSVCRT_CHECK_PMT(name != NULL)) return NULL;
232
236 return ret;
237}
238
239static wchar_t * wgetenv_helper(const wchar_t *name)
240{
241 int idx;
242
243 if (!name) return NULL;
244 if (env_init(TRUE, FALSE)) return NULL;
245
247 if (!MSVCRT__wenviron[idx]) return NULL;
248 return wcschr(MSVCRT__wenviron[idx], '=') + 1;
249}
250
251/*********************************************************************
252 * _wgetenv (MSVCRT.@)
253 */
254wchar_t * CDECL _wgetenv(const wchar_t *name)
255{
256 wchar_t *ret;
257
258 if (!MSVCRT_CHECK_PMT(name != NULL)) return NULL;
259
263 return ret;
264}
265
266static int putenv_helper(const char *name, const char *val, const char *eq)
267{
268 wchar_t *wenv;
269 char *env;
270 int r;
271
272 if (eq)
273 {
274 env = strdup(name);
275 if (!env) return -1;
276 }
277 else
278 {
279 int name_len = strlen(name);
280
281 r = strlen(val);
282 env = malloc(name_len + r + 2);
283 if (!env) return -1;
284 memcpy(env, name, name_len);
285 env[name_len] = '=';
286 strcpy(env + name_len + 1, val);
287 }
288
289 wenv = msvcrt_wstrdupa(env);
290 if (!wenv)
291 {
292 free(env);
293 return -1;
294 }
295
297 r = env_set(&env, &wenv);
299 free(env);
300 free(wenv);
301 return r;
302}
303
304static char *msvcrt_astrdupw(const wchar_t *wstr)
305{
306 const unsigned int len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
307 char *str = malloc(len * sizeof(char));
308
309 if (!str)
310 return NULL;
311 WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
312 return str;
313}
314
315
316static int wputenv_helper(const wchar_t *name, const wchar_t *val, const wchar_t *eq)
317{
318 wchar_t *wenv;
319 char *env;
320 int r;
321
323 r = env_init(TRUE, TRUE);
325 if (r) return -1;
326
327 if (eq)
328 {
329 wenv = wcsdup(name);
330 if (!wenv) return -1;
331 }
332 else
333 {
334 int name_len = wcslen(name);
335
336 r = wcslen(val);
337 wenv = malloc((name_len + r + 2) * sizeof(wchar_t));
338 if (!wenv) return -1;
339 memcpy(wenv, name, name_len * sizeof(wchar_t));
340 wenv[name_len] = '=';
341 wcscpy(wenv + name_len + 1, val);
342 }
343
344 env = msvcrt_astrdupw(wenv);
345 if (!env)
346 {
347 free(wenv);
348 return -1;
349 }
350
352 r = env_set(&env, &wenv);
354 free(env);
355 free(wenv);
356 return r;
357}
358
359/*********************************************************************
360 * _putenv (MSVCRT.@)
361 */
362int CDECL _putenv(const char *str)
363{
364 const char *eq;
365
366 TRACE("%s\n", debugstr_a(str));
367
368 if (!str || !(eq = strchr(str, '=')))
369 return -1;
370
371 return putenv_helper(str, NULL, eq);
372}
373
374/*********************************************************************
375 * _wputenv (MSVCRT.@)
376 */
377int CDECL _wputenv(const wchar_t *str)
378{
379 const wchar_t *eq;
380
381 TRACE("%s\n", debugstr_w(str));
382
383 if (!str || !(eq = wcschr(str, '=')))
384 return -1;
385
386 return wputenv_helper(str, NULL, eq);
387}
388
389/*********************************************************************
390 * _putenv_s (MSVCRT.@)
391 */
392errno_t CDECL _putenv_s(const char *name, const char *value)
393{
394 errno_t ret = 0;
395
396 TRACE("%s %s\n", debugstr_a(name), debugstr_a(value));
397
398 if (!MSVCRT_CHECK_PMT(name != NULL)) return EINVAL;
399 if (!MSVCRT_CHECK_PMT(value != NULL)) return EINVAL;
400
401 if (putenv_helper(name, value, NULL) < 0)
402 {
404 ret = *_errno();
405 }
406
407 return ret;
408}
409
410/*********************************************************************
411 * _wputenv_s (MSVCRT.@)
412 */
413errno_t CDECL _wputenv_s(const wchar_t *name, const wchar_t *value)
414{
415 errno_t ret = 0;
416
417 TRACE("%s %s\n", debugstr_w(name), debugstr_w(value));
418
419 if (!MSVCRT_CHECK_PMT(name != NULL)) return EINVAL;
420 if (!MSVCRT_CHECK_PMT(value != NULL)) return EINVAL;
421
422 if (wputenv_helper(name, value, NULL) < 0)
423 {
425 ret = *_errno();
426 }
427
428 return ret;
429}
430
431#if _MSVCR_VER>=80
432
433/******************************************************************
434 * _dupenv_s (MSVCR80.@)
435 */
436int CDECL _dupenv_s(char **buffer, size_t *numberOfElements, const char *varname)
437{
438 char *e;
439 size_t sz;
440
441 if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
442 if (!MSVCRT_CHECK_PMT(varname != NULL)) return EINVAL;
443
445 if (!(e = getenv(varname)))
446 {
448 *buffer = NULL;
450 return 0;
451 }
452
453 sz = strlen(e) + 1;
454 *buffer = malloc(sz);
455 if (*buffer) strcpy(*buffer, e);
457
458 if (!*buffer)
459 {
461 return *_errno() = ENOMEM;
462 }
464 return 0;
465}
466
467/******************************************************************
468 * _wdupenv_s (MSVCR80.@)
469 */
470int CDECL _wdupenv_s(wchar_t **buffer, size_t *numberOfElements,
471 const wchar_t *varname)
472{
473 wchar_t *e;
474 size_t sz;
475
476 if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
477 if (!MSVCRT_CHECK_PMT(varname != NULL)) return EINVAL;
478
480 if (!(e = _wgetenv(varname)))
481 {
483 *buffer = NULL;
485 return 0;
486 }
487
488 sz = wcslen(e) + 1;
489 *buffer = malloc(sz * sizeof(wchar_t));
490 if (*buffer) wcscpy(*buffer, e);
492
493 if (!*buffer)
494 {
496 return *_errno() = ENOMEM;
497 }
499 return 0;
500}
501
502#endif /* _MSVCR_VER>=80 */
503
504/******************************************************************
505 * getenv_s (MSVCRT.@)
506 */
507int CDECL getenv_s(size_t *ret_len, char* buffer, size_t len, const char *varname)
508{
509 char *e;
510
511 if (!MSVCRT_CHECK_PMT(ret_len != NULL)) return EINVAL;
512 *ret_len = 0;
513 if (!MSVCRT_CHECK_PMT((buffer && len > 0) || (!buffer && !len))) return EINVAL;
514 if (buffer) buffer[0] = 0;
515
517 e = getenv_helper(varname);
518 if (e)
519 {
520 *ret_len = strlen(e) + 1;
521 if (len >= *ret_len) strcpy(buffer, e);
522 }
524
525 if (!e || !len) return 0;
526 if (len < *ret_len) return ERANGE;
527 return 0;
528}
529
530/******************************************************************
531 * _wgetenv_s (MSVCRT.@)
532 */
533int CDECL _wgetenv_s(size_t *ret_len, wchar_t *buffer, size_t len,
534 const wchar_t *varname)
535{
536 wchar_t *e;
537
538 if (!MSVCRT_CHECK_PMT(ret_len != NULL)) return EINVAL;
539 *ret_len = 0;
540 if (!MSVCRT_CHECK_PMT((buffer && len > 0) || (!buffer && !len))) return EINVAL;
541 if (buffer) buffer[0] = 0;
542
544 e = wgetenv_helper(varname);
545 if (e)
546 {
547 *ret_len = wcslen(e) + 1;
548 if (len >= *ret_len) wcscpy(buffer, e);
549 }
551
552 if (!e || !len) return 0;
553 if (len < *ret_len) return ERANGE;
554 return 0;
555}
556
557/*********************************************************************
558 * _get_environ (MSVCRT.@)
559 */
560void CDECL _get_environ(char ***ptr)
561{
563}
564
565/*********************************************************************
566 * _get_wenviron (MSVCRT.@)
567 */
568void CDECL _get_wenviron(wchar_t ***ptr)
569{
571}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:171
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
#define CDECL
Definition: compat.h:29
#define wcschr
Definition: compat.h:17
#define wcsnicmp
Definition: compat.h:14
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
BOOL WINAPI FreeEnvironmentStringsA(IN LPSTR EnvironmentStrings)
Definition: environ.c:379
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259
LPWSTR WINAPI DECLSPEC_HOTPATCH GetEnvironmentStringsW(void)
Definition: process.c:1538
wchar_t * msvcrt_wstrdupa(const char *str)
Definition: data.c:373
wchar_t ** MSVCRT___winitenv
Definition: data.c:58
char ** MSVCRT___initenv
Definition: data.c:57
wchar_t ** MSVCRT__wenviron
Definition: data.c:56
char ** MSVCRT__environ
Definition: data.c:55
void CDECL _get_environ(char ***ptr)
Definition: environ.c:560
static int env_set(char **env, wchar_t **wenv)
Definition: environ.c:147
int CDECL _putenv(const char *str)
Definition: environ.c:362
int env_init(BOOL unicode, BOOL modif)
Definition: environ.c:30
static wchar_t * wgetenv_helper(const wchar_t *name)
Definition: environ.c:239
errno_t CDECL _wputenv_s(const wchar_t *name, const wchar_t *value)
Definition: environ.c:413
wchar_t *CDECL _wgetenv(const wchar_t *name)
Definition: environ.c:254
static int env_get_index(const char *name)
Definition: environ.c:121
static int putenv_helper(const char *name, const char *val, const char *eq)
Definition: environ.c:266
static int wputenv_helper(const wchar_t *name, const wchar_t *val, const wchar_t *eq)
Definition: environ.c:316
static int wenv_get_index(const wchar_t *name)
Definition: environ.c:134
int CDECL _wputenv(const wchar_t *str)
Definition: environ.c:377
void CDECL _get_wenviron(wchar_t ***ptr)
Definition: environ.c:568
int CDECL getenv_s(size_t *ret_len, char *buffer, size_t len, const char *varname)
Definition: environ.c:507
int CDECL _wgetenv_s(size_t *ret_len, wchar_t *buffer, size_t len, const wchar_t *varname)
Definition: environ.c:533
static char * getenv_helper(const char *name)
Definition: environ.c:213
static char * msvcrt_astrdupw(const wchar_t *wstr)
Definition: environ.c:304
char *CDECL getenv(const char *name)
Definition: environ.c:227
errno_t CDECL _putenv_s(const char *name, const char *value)
Definition: environ.c:392
int *CDECL _errno(void)
Definition: errno.c:215
int errno_t
Definition: corecrt.h:249
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define EINVAL
Definition: errno.h:44
#define ENOMEM
Definition: errno.h:35
#define ERANGE
Definition: errno.h:55
_ACRTIMP char *__cdecl strchr(const char *, int)
Definition: string.c:3286
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
static char * strdup(const char *buf)
Definition: string.h:83
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
void CDECL _lock(int locknum)
Definition: lock.c:85
void CDECL _unlock(int locknum)
Definition: lock.c:114
#define MSVCRT_CHECK_PMT(x)
Definition: msvcrt.h:378
#define _ENV_LOCK
Definition: mtdll.h:36
return ret
Definition: mutex.c:146
unsigned int BOOL
Definition: ntddk_ex.h:94
errno_t __cdecl _wdupenv_s(wchar_t **const buffer_pointer, size_t *const buffer_count, wchar_t const *const name)
Definition: getenv.cpp:294
errno_t __cdecl _dupenv_s(char **const buffer_pointer, size_t *const buffer_count, char const *const name)
Definition: getenv.cpp:285
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint buffer
Definition: glext.h:5915
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define e
Definition: ke_i.h:82
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define eq(received, expected, label, type)
Definition: locale.c:144
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:79
static size_t numberOfElements
Definition: string.c:98
const WCHAR * str
wcscpy
strcpy
Definition: string.h:131
#define msvcrt_set_errno
Definition: heap.c:50
#define TRACE(s)
Definition: solgame.cpp:4
Definition: name.c:39
Definition: pdh_main.c:96
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GetEnvironmentStringsA
Definition: winbase.h:3562
#define ERROR_ENVVAR_NOT_FOUND
Definition: winerror.h:383
#define strnicmp
Definition: xmlstorage.h:206