ReactOS  0.4.14-dev-49-gfb4591c
environ.c
Go to the documentation of this file.
1 /*
2  * environ.c
3  *
4  * ReactOS MSVCRT.DLL Compatibility Library
5  */
6 
7 #include <precomp.h>
8 #include <internal/wine/msvcrt.h>
9 
10 unsigned int _osplatform = 0;
11 unsigned int _osver = 0;
12 unsigned int _winminor = 0;
13 unsigned int _winmajor = 0;
14 unsigned int _winver = 0;
15 
16 unsigned int __setlc_active = 0;
17 unsigned int __unguarded_readlc_active = 0;
18 char *_acmdln = NULL; /* pointer to ascii command line */
19 wchar_t *_wcmdln = NULL; /* pointer to wide character command line */
20 #undef _environ
21 #undef _wenviron
22 char **_environ = NULL; /* pointer to environment block */
23 wchar_t **_wenviron = NULL; /* pointer to environment block */
24 char **__initenv = NULL; /* pointer to initial environment block */
25 wchar_t **__winitenv = NULL; /* pointer to initial environment block */
26 #undef _pgmptr
27 char *_pgmptr = NULL; /* pointer to program name */
28 #undef _wpgmptr
29 wchar_t *_wpgmptr = NULL; /* pointer to program name */
30 int __app_type = _UNKNOWN_APP; /* application type */
32 
33 
35 {
36  char *ptr, *environment_strings;
37  char **envptr;
38  int count = 1;
39  size_t len;
40 
41  TRACE("BlockEnvToEnvironA()\n");
42 
43  environment_strings = GetEnvironmentStringsA();
44  if (environment_strings == NULL) {
45  return -1;
46  }
47 
48  for (ptr = environment_strings; *ptr; ptr += len)
49  {
50  len = strlen(ptr) + 1;
51  /* Skip drive letter settings. */
52  if (*ptr != '=')
53  count++;
54  }
55 
56  __initenv = _environ = malloc(count * sizeof(char*));
57  if (_environ)
58  {
59  for (ptr = environment_strings, envptr = _environ; count > 1; ptr += len)
60  {
61  len = strlen(ptr) + 1;
62  /* Skip drive letter settings. */
63  if (*ptr != '=')
64  {
65  if ((*envptr = malloc(len)) == NULL)
66  {
67  for (envptr--; envptr >= _environ; envptr--)
68  free(*envptr);
69  FreeEnvironmentStringsA(environment_strings);
70  free(_environ);
72  return -1;
73  }
74  memcpy(*envptr++, ptr, len);
75  count--;
76  }
77  }
78  /* Add terminating NULL entry. */
79  *envptr = NULL;
80  }
81 
82  FreeEnvironmentStringsA(environment_strings);
83  return _environ ? 0 : -1;
84 }
85 
87 {
88  wchar_t *ptr, *environment_strings;
89  wchar_t **envptr;
90  int count = 1;
91  size_t len;
92 
93  TRACE("BlockEnvToEnvironW()\n");
94 
95  environment_strings = GetEnvironmentStringsW();
96  if (environment_strings == NULL) {
97  return -1;
98  }
99 
100  for (ptr = environment_strings; *ptr; ptr += len)
101  {
102  len = wcslen(ptr) + 1;
103  /* Skip drive letter settings. */
104  if (*ptr != '=')
105  count++;
106  }
107 
108  __winitenv = _wenviron = malloc(count * sizeof(wchar_t*));
109  if (_wenviron)
110  {
111  for (ptr = environment_strings, envptr = _wenviron; count > 1; ptr += len)
112  {
113  len = wcslen(ptr) + 1;
114  /* Skip drive letter settings. */
115  if (*ptr != '=')
116  {
117  if ((*envptr = malloc(len * sizeof(wchar_t))) == NULL)
118  {
119  for (envptr--; envptr >= _wenviron; envptr--)
120  free(*envptr);
121  FreeEnvironmentStringsW(environment_strings);
122  free(_wenviron);
124  return -1;
125  }
126  memcpy(*envptr++, ptr, len * sizeof(wchar_t));
127  count--;
128  }
129  }
130  /* Add terminating NULL entry. */
131  *envptr = NULL;
132  }
133 
134  FreeEnvironmentStringsW(environment_strings);
135  return _wenviron ? 0 : -1;
136 }
137 
151 char **DuplicateEnvironment(char **original_environment, int wide)
152 {
153  int count = 1;
154  char **envptr, **newenvptr, **newenv;
155 
156  for (envptr = original_environment; *envptr != NULL; envptr++, count++)
157  ;
158 
159  newenvptr = newenv = malloc(count * sizeof(char*));
160  if (newenv == NULL)
161  return original_environment;
162 
163  for (envptr = original_environment; count > 1; newenvptr++, count--)
164  {
165  if (wide)
166  *newenvptr = (char*)_wcsdup((wchar_t*)*envptr++);
167  else
168  *newenvptr = _strdup(*envptr++);
169  if (*newenvptr == NULL)
170  {
171  for (newenvptr--; newenvptr >= newenv; newenvptr--)
172  free(*newenvptr);
173  free(newenv);
174  return original_environment;
175  }
176  }
177  *newenvptr = NULL;
178 
179  return newenv;
180 }
181 
190 void FreeEnvironment(char **environment)
191 {
192  char **envptr;
193  for (envptr = environment; *envptr != NULL; envptr++)
194  free(*envptr);
195  free(environment);
196 }
197 
210 int SetEnv(const wchar_t *option)
211 {
212  wchar_t *epos, *name;
213  wchar_t **wenvptr;
214  wchar_t *woption;
215  char *mboption;
216  int remove, index, count, size, result = 0, found = 0;
217  wchar_t **wnewenv;
218  char **mbnewenv;
219 
220  if (option == NULL || (epos = wcschr(option, L'=')) == NULL)
221  return -1;
222  remove = (epos[1] == 0);
223 
224  /* Duplicate environment if needed. */
225  if (_environ == __initenv)
226  {
228  return -1;
229  }
230  if (_wenviron == __winitenv)
231  {
232  if ((_wenviron = (wchar_t**)DuplicateEnvironment((char**)_wenviron, 1)) ==
233  __winitenv)
234  return -1;
235  }
236 
237  /* Create a copy of the option name. */
238  name = malloc((epos - option + 1) * sizeof(wchar_t));
239  if (name == NULL)
240  return -1;
241  memcpy(name, option, (epos - option) * sizeof(wchar_t));
242  name[epos - option] = 0;
243 
244  /* Find the option we're trying to modify. */
245  for (index = 0, wenvptr = _wenviron; *wenvptr != NULL; wenvptr++, index++)
246  {
247  if (!_wcsnicmp(*wenvptr, option, epos - option))
248  {
249  found = 1;
250  break;
251  }
252  }
253 
254  if (remove)
255  {
256  if (!found)
257  {
258  free(name);
259  return 0;
260  }
261 
262  /* Remove the option from wide character environment. */
263  free(*wenvptr);
264  for (count = index; *wenvptr != NULL; wenvptr++, count++)
265  *wenvptr = *(wenvptr + 1);
266  wnewenv = realloc(_wenviron, count * sizeof(wchar_t*));
267  if (wnewenv != NULL)
268  _wenviron = wnewenv;
269 
270  /* Remove the option from multibyte environment. We assume
271  * the environments are in sync and the option is at the
272  * same position. */
273  free(_environ[index]);
274  memmove(&_environ[index], &_environ[index+1], (count - index) * sizeof(char*));
275  mbnewenv = realloc(_environ, count * sizeof(char*));
276  if (mbnewenv != NULL)
277  _environ = mbnewenv;
278 
280  }
281  else
282  {
283  /* Make a copy of the option that we will store in the environment block. */
284  woption = _wcsdup((wchar_t*)option);
285  if (woption == NULL)
286  {
287  free(name);
288  return -1;
289  }
290 
291  /* Create a multibyte copy of the option. */
293  mboption = malloc(size);
294  if (mboption == NULL)
295  {
296  free(name);
297  free(woption);
298  return -1;
299  }
300  WideCharToMultiByte(CP_ACP, 0, option, -1, mboption, size, NULL, NULL);
301 
302  if (found)
303  {
304  /* Replace the current entry. */
305  free(*wenvptr);
306  *wenvptr = woption;
307  free(_environ[index]);
308  _environ[index] = mboption;
309  }
310  else
311  {
312  /* Get the size of the original environment. */
313  for (count = index; *wenvptr != NULL; wenvptr++, count++)
314  ;
315 
316  /* Create a new entry. */
317  if ((wnewenv = realloc(_wenviron, (count + 2) * sizeof(wchar_t*))) == NULL)
318  {
319  free(name);
320  free(mboption);
321  free(woption);
322  return -1;
323  }
324  _wenviron = wnewenv;
325  if ((mbnewenv = realloc(_environ, (count + 2) * sizeof(char*))) == NULL)
326  {
327  free(name);
328  free(mboption);
329  free(woption);
330  return -1;
331  }
332  _environ = mbnewenv;
333 
334  /* Set the last entry to our option. */
335  _wenviron[count] = woption;
336  _environ[count] = mboption;
337  _wenviron[count + 1] = NULL;
338  _environ[count + 1] = NULL;
339  }
340 
341  /* And finally update the OS environment. */
342  result = SetEnvironmentVariableW(name, epos + 1) ? 0 : -1;
343  }
344  free(name);
345 
346  return result;
347 }
348 
349 /*
350  * @implemented
351  */
352 int *__p__commode(void) // not exported by NTDLL
353 {
354  return &_commode;
355 }
356 
357 /*
358  * @implemented
359  */
360 void __set_app_type(int app_type)
361 {
362  __app_type = app_type;
363 }
364 
365 /*
366  * @implemented
367  */
368 char **__p__acmdln(void)
369 {
370  return &_acmdln;
371 }
372 
373 /*
374  * @implemented
375  */
376 wchar_t **__p__wcmdln(void)
377 {
378  return &_wcmdln;
379 }
380 
381 /*
382  * @implemented
383  */
384 char ***__p__environ(void)
385 {
386  return &_environ;
387 }
388 
389 /*
390  * @implemented
391  */
392 wchar_t ***__p__wenviron(void)
393 {
394  return &_wenviron;
395 }
396 
397 /*
398  * @implemented
399  */
400 char ***__p___initenv(void)
401 {
402  return &__initenv;
403 }
404 
405 /*
406  * @implemented
407  */
408 wchar_t ***__p___winitenv(void)
409 {
410  return &__winitenv;
411 }
412 
413 /*
414  * @implemented
415  */
416 errno_t _get_osplatform(unsigned int *pValue)
417 {
418  if (!MSVCRT_CHECK_PMT(pValue != NULL)) {
419  *_errno() = EINVAL;
420  return EINVAL;
421  }
422 
423  *pValue = _osplatform;
424  return 0;
425 }
426 
427 /*
428  * @implemented
429  */
431 {
432  return &get_locinfo()->mb_cur_max;
433 }
434 
435 /*********************************************************************
436  * ___mb_cur_max_func(MSVCRT.@)
437  */
439 {
440  return get_locinfo()->mb_cur_max;
441 }
442 
443 /*
444  * @implemented
445  */
446 unsigned int *__p__osver(void)
447 {
448  return &_osver;
449 }
450 
451 /*
452  * @implemented
453  */
454 char **__p__pgmptr(void)
455 {
456  return &_pgmptr;
457 }
458 
459 /*
460  * @implemented
461  */
462 int _get_pgmptr(char** p)
463 {
464  if (!MSVCRT_CHECK_PMT(p))
465  {
466  *_errno() = EINVAL;
467  return EINVAL;
468  }
469 
470  *p = _pgmptr;
471  return 0;
472 }
473 
474 /*
475  * @implemented
476  */
477 wchar_t **__p__wpgmptr(void)
478 {
479  return &_wpgmptr;
480 }
481 
482 /*
483  * @implemented
484  */
486 {
487  if (!MSVCRT_CHECK_PMT(p))
488  {
489  *_errno() = EINVAL;
490  return EINVAL;
491  }
492 
493  *p = _wpgmptr;
494  return 0;
495 }
496 
497 /*
498  * @implemented
499  */
500 unsigned int *__p__winmajor(void)
501 {
502  return &_winmajor;
503 }
504 
505 /*
506  * @implemented
507  */
508 unsigned int *__p__winminor(void)
509 {
510  return &_winminor;
511 }
512 
513 /*
514  * @implemented
515  */
516 unsigned int *__p__winver(void)
517 {
518  return &_winver;
519 }
520 
521 /* EOF */
#define realloc
Definition: debug_ros.c:6
unsigned int * __p__winminor(void)
Definition: environ.c:508
wchar_t * _wcmdln
Definition: environ.c:19
char *** __p___initenv(void)
Definition: environ.c:400
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
unsigned int * __p__winmajor(void)
Definition: environ.c:500
#define WideCharToMultiByte
Definition: compat.h:101
unsigned int _osplatform
Definition: environ.c:10
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int BlockEnvToEnvironW(void)
Definition: environ.c:86
#define CP_ACP
Definition: compat.h:99
Definition: arc.h:39
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define free
Definition: debug_ros.c:5
wchar_t *** __p__wenviron(void)
Definition: environ.c:392
wchar_t * _wpgmptr
Definition: environ.c:29
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
BOOL WINAPI FreeEnvironmentStringsA(IN LPSTR EnvironmentStrings)
Definition: environ.c:379
char ** DuplicateEnvironment(char **original_environment, int wide)
Definition: environ.c:151
#define _strdup
Definition: debug_ros.c:7
char ** _environ
Definition: environ.c:22
char ** __initenv
Definition: environ.c:24
char ** __p__pgmptr(void)
Definition: environ.c:454
int * __p__commode(void)
Definition: environ.c:352
unsigned int __setlc_active
Definition: environ.c:16
char *** __p__environ(void)
Definition: environ.c:384
int _get_wpgmptr(WCHAR **p)
Definition: environ.c:485
static PVOID ptr
Definition: dispmode.c:27
int CDECL ___mb_cur_max_func(void)
Definition: environ.c:438
#define _IOCOMMIT
Definition: msvcrt.h:69
smooth NULL
Definition: ftsmooth.c:416
Definition: getopt.h:108
char * _pgmptr
Definition: environ.c:27
#define get_locinfo()
Definition: winesup.h:25
int BlockEnvToEnvironA(void)
Definition: environ.c:34
GLuint index
Definition: glext.h:6031
int errno_t
Definition: crtdefs.h:353
errno_t _get_osplatform(unsigned int *pValue)
Definition: environ.c:416
GLuint GLenum option
Definition: glext.h:11211
int _get_pgmptr(char **p)
Definition: environ.c:462
wchar_t ** _wenviron
Definition: environ.c:23
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
void FreeEnvironment(char **environment)
Definition: environ.c:190
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
__wchar_t WCHAR
Definition: xmlstorage.h:180
int _commode
Definition: environ.c:31
#define _UNKNOWN_APP
Definition: misc.h:5
char ** __p__acmdln(void)
Definition: environ.c:368
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:19
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1250
int __app_type
Definition: environ.c:30
#define MSVCRT_CHECK_PMT(x)
Definition: mbstowcs_s.c:26
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned int _winminor
Definition: environ.c:12
unsigned int * __p__winver(void)
Definition: environ.c:516
LPSTR WINAPI GetEnvironmentStringsA(VOID)
Definition: environ.c:293
#define CDECL
Definition: compat.h:21
char * _acmdln
Definition: environ.c:18
unsigned int _osver
Definition: environ.c:11
int SetEnv(const wchar_t *option)
Definition: environ.c:210
unsigned int __unguarded_readlc_active
Definition: environ.c:17
LPWSTR WINAPI GetEnvironmentStringsW(VOID)
Definition: environ.c:344
wchar_t ** __winitenv
Definition: environ.c:25
unsigned int _winver
Definition: environ.c:14
Definition: name.c:36
int * __p___mb_cur_max(void)
Definition: environ.c:430
#define malloc
Definition: debug_ros.c:4
GLfloat GLfloat p
Definition: glext.h:8902
wchar_t ** __p__wcmdln(void)
Definition: environ.c:376
wchar_t ** __p__wpgmptr(void)
Definition: environ.c:477
_Check_return_ _CRTIMP wchar_t *__cdecl _wcsdup(_In_z_ const wchar_t *_Str)
int remove
Definition: msacm.c:1353
unsigned int * __p__osver(void)
Definition: environ.c:446
unsigned int _winmajor
Definition: environ.c:13
GLuint64EXT * result
Definition: glext.h:11304
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
void __set_app_type(int app_type)
Definition: environ.c:360
wchar_t *** __p___winitenv(void)
Definition: environ.c:408
GLuint const GLchar * name
Definition: glext.h:6031