Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
7.1 KiB

  1. /***
  2. *stdenvp.c - standard _setenvp routine
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * This module is called by the C start-up routine to set up "_environ".
  8. * Its sets up an array of pointers to strings in the environment.
  9. * The global symbol "_environ" is set to point to this array.
  10. *
  11. *Revision History:
  12. * 11-07-84 GFW initial version
  13. * 01-08-86 SKS Modified for OS/2
  14. * 05-21-86 SKS Call _stdalloc to get memory for strings
  15. * 09-04-86 SKS Added check to skip the "*C_FILE_INFO" string
  16. * 10-21-86 SKS Improved check for "*C_FILE_INFO"/"_C_FILE_INFO"
  17. * 02-19-88 SKS Handle case where environment starts with a single null
  18. * 05-10-88 JCR Modified code to accept far pointer from _stdalloc
  19. * 06-01-88 PHG Merged DLL and normal versions
  20. * 07-12-88 JCR Largely re-written: (1) split mem allocation into two
  21. * seperate malloc() calls to help simplify putenv(),
  22. * (2) stdalloc() no longer robs from stack, (3) cProc/cEnd
  23. * sequence, (4) misc cleanup
  24. * 09-20-88 WAJ Initial 386 version
  25. * 12-13-88 JCR Use rterr.inc parameters for runtime errors
  26. * 04-09-90 GJF Added #include <cruntime.h>. Made the calling type
  27. * _CALLTYPE1. Also, fixed the copyright and cleaned up
  28. * up the formatting a bit.
  29. * 06-05-90 GJF Changed error message interface.
  30. * 10-08-90 GJF New-style function declarator.
  31. * 10-31-90 GJF Fixed statement appending the final NULL (Stevewo
  32. * found the bug).
  33. * 12-11-90 SRW Changed to include <oscalls.h> and setup _environ
  34. * correctly for Win32
  35. * 01-21-91 GJF ANSI naming.
  36. * 02-07-91 SRW Change _WIN32_ specific code to allocate static copy
  37. * 02-18-91 SRW Change _WIN32_ specific code to allocate copy of
  38. * variable strings as well [_WIN32_]
  39. * 07-25-91 GJF Changed strupr to _strupr.
  40. * 03-31-92 DJM POSIX support.
  41. * 04-20-92 GJF Removed conversion to upper-case code for Win32.
  42. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  43. * 11-24-93 CFW Rip out Cruiser and filter out "=c:\foo" type.
  44. * 11-29-93 CFW Remove unused POSIX stuff, wide char enable.
  45. * 12-07-93 CFW Change _TCHAR to _TSCHAR.
  46. * 01-10-95 CFW Debug CRT allocs.
  47. * 04-07-95 CFW Free environment block on demand.
  48. * 07-03-95 GJF Always free environment block.
  49. * 02-20-96 SKS Set _aenvptr/_wenvptr to NULL after freeing what it
  50. * points to (a copy of environment strings).
  51. * 06-30-97 GJF Added explicit, conditional init. of the mbctype table.
  52. * Set __env_initialized flag. Also detab-ed.
  53. * 01-04-99 GJF Changes for 64-bit size_t.
  54. * 03-05-01 PML Don't AV if _aenvptr is NULL (vs7#174755).
  55. * 03-27-01 PML Return error instead of calling amsg_exit (vs7#231220)
  56. * 11-06-01 GB Code Cleaning
  57. *
  58. *******************************************************************************/
  59. #include <cruntime.h>
  60. #include <string.h>
  61. #include <stdlib.h>
  62. #include <internal.h>
  63. #include <rterr.h>
  64. #include <oscalls.h>
  65. #include <tchar.h>
  66. #include <dbgint.h>
  67. #ifndef CRTDLL
  68. #ifdef _MBCS
  69. /*
  70. * Flag to ensure multibyte ctype table is only initialized once
  71. */
  72. extern int __mbctype_initialized;
  73. #endif
  74. /*
  75. * Flag checked by getenv() and _putenv() to determine if the environment has
  76. * been initialized.
  77. */
  78. extern int __env_initialized;
  79. #endif
  80. /***
  81. *_setenvp - set up "envp" for C programs
  82. *
  83. *Purpose:
  84. * Reads the environment and build the envp array for C programs.
  85. *
  86. *Entry:
  87. * The environment strings occur at _aenvptr.
  88. * The list of environment strings is terminated by an extra null
  89. * byte. Thus two null bytes in a row indicate the end of the
  90. * last environment string and the end of the environment, resp.
  91. *
  92. *Exit:
  93. * "environ" points to a null-terminated list of pointers to ASCIZ
  94. * strings, each of which is of the form "VAR=VALUE". The strings
  95. * are copied from the environment area. This array of pointers will
  96. * be malloc'ed. The block pointed to by _aenvptr is deallocated.
  97. *
  98. *Uses:
  99. * Allocates space on the heap for the environment pointers.
  100. *
  101. *Exceptions:
  102. * If space cannot be allocated, program is terminated.
  103. *
  104. *******************************************************************************/
  105. #ifdef WPRFLAG
  106. #define _tsetenvp _wsetenvp
  107. #define _tenvptr _wenvptr
  108. #else
  109. #define _tsetenvp _setenvp
  110. #define _tenvptr _aenvptr
  111. #endif
  112. int __cdecl _tsetenvp (
  113. void
  114. )
  115. {
  116. _TSCHAR *p;
  117. _TSCHAR **env; /* _environ ptr traversal pointer */
  118. int numstrings; /* number of environment strings */
  119. int cchars;
  120. #if !defined(CRTDLL) && defined(_MBCS)
  121. /* If necessary, initialize the multibyte ctype table. */
  122. if ( __mbctype_initialized == 0 )
  123. __initmbctable();
  124. #endif
  125. numstrings = 0;
  126. p = _tenvptr;
  127. /*
  128. * We called __crtGetEnvironmentStrings[AW] just before this,
  129. * so if _[aw]envptr is NULL, we failed to get the environment.
  130. * Return an error.
  131. */
  132. if (p == NULL)
  133. return -1;
  134. /*
  135. * NOTE: starting with single null indicates no environ.
  136. * Count the number of strings. Skip drive letter settings
  137. * ("=C:=C:\foo" type) by skipping all environment variables
  138. * that begin with '=' character.
  139. */
  140. while (*p != _T('\0')) {
  141. /* don't count "=..." type */
  142. if (*p != _T('='))
  143. ++numstrings;
  144. p += _tcslen(p) + 1;
  145. }
  146. /* need pointer for each string, plus one null ptr at end */
  147. if ( (_tenviron = env = (_TSCHAR **)
  148. _malloc_crt((numstrings+1) * sizeof(_TSCHAR *))) == NULL )
  149. return -1;
  150. /* copy strings to malloc'd memory and save pointers in _environ */
  151. for ( p = _tenvptr ; *p != L'\0' ; p += cchars )
  152. {
  153. cchars = (int)_tcslen(p) + 1;
  154. /* don't copy "=..." type */
  155. if (*p != _T('=')) {
  156. if ( (*env = (_TSCHAR *)_malloc_crt(cchars * sizeof(_TSCHAR)))
  157. == NULL )
  158. {
  159. _free_crt(_tenviron);
  160. _tenviron = NULL;
  161. return -1;
  162. }
  163. _tcscpy(*env, p);
  164. env++;
  165. }
  166. }
  167. _free_crt(_tenvptr);
  168. _tenvptr = NULL;
  169. /* and a final NULL pointer */
  170. *env = NULL;
  171. #ifndef CRTDLL
  172. /*
  173. * Set flag for getenv() and _putenv() to know the environment
  174. * has been set up.
  175. */
  176. __env_initialized = 1;
  177. #endif
  178. return 0;
  179. }