ReactOS 0.4.16-dev-852-gcfcc8d8
environment_initialization.cpp File Reference
#include <corecrt_internal_traits.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for environment_initialization.cpp:

Go to the source code of this file.

Functions

char ***__cdecl __p__environ ()
 
wchar_t ***__cdecl __p__wenviron ()
 
static _Ret_opt_z_ char **& get_environment_nolock (char) throw ()
 
static _Ret_opt_z_ wchar_t **& get_environment_nolock (wchar_t) throw ()
 
static _Ret_opt_z_ char **&__cdecl get_initial_environment (char) throw ()
 
static _Ret_opt_z_ wchar_t **&__cdecl get_initial_environment (wchar_t) throw ()
 
static __crt_state_management::dual_state_global< char ** > & get_dual_state_environment_nolock (char) throw ()
 
static __crt_state_management::dual_state_global< wchar_t ** > & get_dual_state_environment_nolock (wchar_t) throw ()
 
template<typename Character >
static size_t const count_variables_in_environment_block (Character *const environment_block) throw ()
 
template<typename Character >
static void free_environment (Character **const environment) throw ()
 
template<typename Character >
static Character **const create_environment (Character *const environment_block) throw ()
 
static void pre_initialize (char) throw ()
 
template<typename Character >
static int __cdecl common_initialize_environment_nolock () throw ()
 
int __cdecl _initialize_narrow_environment ()
 
int __cdecl _initialize_wide_environment ()
 
template<typename Character >
static void __cdecl uninitialize_environment_internal (Character **&environment) throw ()
 
void __cdecl __dcrt_uninitialize_environments_nolock ()
 
template<typename Character >
static int __cdecl initialize_environment_by_cloning_nolock () throw ()
 
template<typename Character >
static _Deref_ret_opt_z_ Character **__cdecl common_get_or_create_environment_nolock () throw ()
 
char **__cdecl __dcrt_get_or_create_narrow_environment_nolock ()
 
wchar_t **__cdecl __dcrt_get_or_create_wide_environment_nolock ()
 
template<typename Character >
static Character **__cdecl common_get_initial_environment () throw ()
 
char **__cdecl _get_initial_narrow_environment ()
 
wchar_t **__cdecl _get_initial_wide_environment ()
 

Variables

char ** __dcrt_initial_narrow_environment = nullptr
 
wchar_t ** __dcrt_initial_wide_environment = nullptr
 
__crt_state_management::dual_state_global< char ** > _environ_table
 
__crt_state_management::dual_state_global< wchar_t ** > _wenviron_table
 
static void pre_initialize (wchar_t)
 

Function Documentation

◆ __dcrt_get_or_create_narrow_environment_nolock()

char **__cdecl __dcrt_get_or_create_narrow_environment_nolock ( void  )

Definition at line 306 of file environment_initialization.cpp.

307{
308 return common_get_or_create_environment_nolock<char>();
309}

◆ __dcrt_get_or_create_wide_environment_nolock()

wchar_t **__cdecl __dcrt_get_or_create_wide_environment_nolock ( void  )

Definition at line 311 of file environment_initialization.cpp.

312{
313 return common_get_or_create_environment_nolock<wchar_t>();
314}

◆ __dcrt_uninitialize_environments_nolock()

void __cdecl __dcrt_uninitialize_environments_nolock ( void  )

Definition at line 216 of file environment_initialization.cpp.

217{
218 _environ_table .uninitialize(uninitialize_environment_internal<char>);
219 _wenviron_table.uninitialize(uninitialize_environment_internal<wchar_t>);
220
223}
__crt_state_management::dual_state_global< wchar_t ** > _wenviron_table
__crt_state_management::dual_state_global< char ** > _environ_table
wchar_t ** __dcrt_initial_wide_environment
static void free_environment(Character **const environment)
char ** __dcrt_initial_narrow_environment

Referenced by uninitialize_environment().

◆ __p__environ()

char ***__cdecl __p__environ ( void  )

Definition at line 30 of file environment_initialization.cpp.

30{ return &_environ_table.value(); }

Referenced by getenv(), and Test__environ().

◆ __p__wenviron()

wchar_t ***__cdecl __p__wenviron ( void  )

Definition at line 31 of file environment_initialization.cpp.

31{ return &_wenviron_table.value(); }

Referenced by _wgetenv(), and Test__wenviron().

◆ _get_initial_narrow_environment()

char **__cdecl _get_initial_narrow_environment ( void  )

Definition at line 328 of file environment_initialization.cpp.

329{
330 return common_get_initial_environment<char>();
331}

Referenced by call_main< decltype(main)>().

◆ _get_initial_wide_environment()

wchar_t **__cdecl _get_initial_wide_environment ( void  )

Definition at line 333 of file environment_initialization.cpp.

334{
335 return common_get_initial_environment<wchar_t>();
336}

Referenced by call_main< decltype(wmain)>().

◆ _initialize_narrow_environment()

int __cdecl _initialize_narrow_environment ( void  )

Definition at line 192 of file environment_initialization.cpp.

193{
194 return common_initialize_environment_nolock<char>();
195}

◆ _initialize_wide_environment()

int __cdecl _initialize_wide_environment ( void  )

Definition at line 197 of file environment_initialization.cpp.

198{
199 return common_initialize_environment_nolock<wchar_t>();
200}

◆ common_get_initial_environment()

template<typename Character >
static Character **__cdecl common_get_initial_environment ( )
throw (
)
static

Definition at line 317 of file environment_initialization.cpp.

318{
319 Character**& initial_environment = get_initial_environment(Character());
320 if (!initial_environment)
321 {
322 initial_environment = common_get_or_create_environment_nolock<Character>();
323 }
324
325 return initial_environment;
326}
static _Ret_opt_z_ char **&__cdecl get_initial_environment(char)

◆ common_get_or_create_environment_nolock()

template<typename Character >
static _Deref_ret_opt_z_ Character **__cdecl common_get_or_create_environment_nolock ( )
throw (
)
static

Definition at line 279 of file environment_initialization.cpp.

280{
281 typedef __crt_char_traits<Character> traits;
282 typedef typename traits::other_char_type other_char_type;
283
284 // Check to see if the required environment already exists:
285 Character** const existing_environment = get_environment_nolock(Character());
286 if (existing_environment)
287 return existing_environment;
288
289 // Check to see if the other environment exists. We will only initialize
290 // the environment here if the other environment was already initialized.
291 other_char_type** const other_environment = get_environment_nolock(other_char_type());
292 if (!other_environment)
293 return nullptr;
294
295 if (common_initialize_environment_nolock<Character>() != 0)
296 {
297 if (initialize_environment_by_cloning_nolock<Character>() != 0)
298 {
299 return nullptr;
300 }
301 }
302
303 return get_environment_nolock(Character());
304}
static _Ret_opt_z_ char **& get_environment_nolock(char)

◆ common_initialize_environment_nolock()

template<typename Character >
static int __cdecl common_initialize_environment_nolock ( )
throw (
)
static

Definition at line 167 of file environment_initialization.cpp.

168{
169 typedef __crt_char_traits<Character> traits;
170
171 // We only initialize the environment once. Once the environment has been
172 // initialized, all updates and modifications go through the other functions
173 // that manipulate the environment.
174 if (get_environment_nolock(Character()))
175 return 0;
176
177 pre_initialize(Character());
178
179 __crt_unique_heap_ptr<Character> const os_environment(traits::get_environment_from_os());
180 if (!os_environment)
181 return -1;
182
183 __crt_unique_heap_ptr<Character*> crt_environment(create_environment(os_environment.get()));
184 if (!crt_environment)
185 return -1;
186
187 get_initial_environment(Character()) = crt_environment.get();
188 get_dual_state_environment_nolock(Character()).initialize(crt_environment.detach());
189 return 0;
190}
static Character **const create_environment(Character *const environment_block)
static void pre_initialize(wchar_t)
static __crt_state_management::dual_state_global< char ** > & get_dual_state_environment_nolock(char)

◆ count_variables_in_environment_block()

template<typename Character >
static size_t const count_variables_in_environment_block ( Character *const  environment_block)
throw (
)
static

Definition at line 56 of file environment_initialization.cpp.

57{
58 typedef __crt_char_traits<Character> traits;
59
60 // Count the number of variables in the environment block, ignoring drive
61 // letter settings, which begin with '=':
62 size_t count = 0;
63
64 Character* it = environment_block;
65 while (*it != '\0')
66 {
67 if (*it != '=')
68 ++count;
69
70 // This advances the iterator to the next string:
71 it += traits::tcslen(it) + 1;
72 }
73
74 return count;
75}
GLuint GLuint GLsizei count
Definition: gl.h:1545

Referenced by create_environment().

◆ create_environment()

template<typename Character >
static Character **const create_environment ( Character *const  environment_block)
throw (
)
static

Definition at line 109 of file environment_initialization.cpp.

110{
111 typedef __crt_char_traits<Character> traits;
112
113 size_t const variable_count = count_variables_in_environment_block(environment_block);
114
115 __crt_unique_heap_ptr<Character*> environment(_calloc_crt_t(Character*, variable_count + 1));
116 if (!environment)
117 return nullptr;
118
119 Character* source_it = environment_block;
120 Character** result_it = environment.get();
121
122 while (*source_it != '\0')
123 {
124 size_t const required_count = traits::tcslen(source_it) + 1;
125
126 // Don't copy drive letter settings, which start with '=':
127 if (*source_it != '=')
128 {
129 __crt_unique_heap_ptr<Character> variable(_calloc_crt_t(Character, required_count));
130 if (!variable)
131 {
132 free_environment(environment.detach());
133 return nullptr;
134 }
135
136 _ERRCHECK(traits::tcscpy_s(variable.get(), required_count, source_it));
137 *result_it++ = variable.detach();
138 }
139
140 // This advances the iterator to the next string:
141 source_it += required_count;
142 }
143
144 // The sequence of pointers is already null-terminated; return it:
145 return environment.detach();
146}
#define _ERRCHECK(e)
static size_t const count_variables_in_environment_block(Character *const environment_block)
GLenum GLenum variable
Definition: glext.h:9031

Referenced by common_initialize_environment_nolock().

◆ free_environment()

template<typename Character >
static void free_environment ( Character **const  environment)
throw (
)
static

Definition at line 90 of file environment_initialization.cpp.

91{
92 if (!environment)
93 return;
94
95 for (Character** it = environment; *it; ++it)
96 _free_crt(*it);
97
98 _free_crt(environment);
99}
#define _free_crt

Referenced by __dcrt_uninitialize_environments_nolock(), create_environment(), and uninitialize_environment_internal().

◆ get_dual_state_environment_nolock() [1/2]

static __crt_state_management::dual_state_global< char ** > & get_dual_state_environment_nolock ( char  )
throw (
)
static

Definition at line 48 of file environment_initialization.cpp.

48{ return _environ_table; }

Referenced by common_initialize_environment_nolock().

◆ get_dual_state_environment_nolock() [2/2]

static __crt_state_management::dual_state_global< wchar_t ** > & get_dual_state_environment_nolock ( wchar_t  )
throw (
)
static

Definition at line 49 of file environment_initialization.cpp.

49{ return _wenviron_table; }

◆ get_environment_nolock() [1/2]

static _Ret_opt_z_ char **& get_environment_nolock ( char  )
throw (
)
static

◆ get_environment_nolock() [2/2]

static _Ret_opt_z_ wchar_t **& get_environment_nolock ( wchar_t  )
throw (
)
static

Definition at line 40 of file environment_initialization.cpp.

40{ return _wenviron_table.value(); }

◆ get_initial_environment() [1/2]

static _Ret_opt_z_ char **&__cdecl get_initial_environment ( char  )
throw (
)
static

◆ get_initial_environment() [2/2]

static _Ret_opt_z_ wchar_t **&__cdecl get_initial_environment ( wchar_t  )
throw (
)
static

Definition at line 46 of file environment_initialization.cpp.

◆ initialize_environment_by_cloning_nolock()

template<typename Character >
static int __cdecl initialize_environment_by_cloning_nolock ( )
throw (
)
static

Definition at line 241 of file environment_initialization.cpp.

242{
243 typedef __crt_char_traits<Character> traits;
244 typedef typename traits::other_char_type other_char_type;
245
246 other_char_type** const other_environment = get_environment_nolock(other_char_type());
247 if (!other_environment)
248 return -1;
249
250 for (other_char_type** it = other_environment; *it; ++it)
251 {
252 size_t const required_count = __crt_compute_required_transform_buffer_count(CP_ACP, *it);
253 if (required_count == 0)
254 return -1;
255
256 __crt_unique_heap_ptr<Character> buffer(_calloc_crt_t(Character, required_count));
257 if (!buffer)
258 return -1;
259
260 size_t const actual_count = __crt_transform_string(CP_ACP, *it, buffer.get(), required_count);
261 if (actual_count == 0)
262 return -1;
263
264 // Ignore a failed attempt to set a variable; continue with the rest...
265 traits::set_variable_in_environment_nolock(buffer.detach(), 0);
266 }
267
268 return 0;
269}
size_t __crt_compute_required_transform_buffer_count(unsigned const code_page, _In_z_ char const *const string)
#define CP_ACP
Definition: compat.h:109
GLuint buffer
Definition: glext.h:5915

◆ pre_initialize()

static void pre_initialize ( char  )
throw (
)
static

Definition at line 157 of file environment_initialization.cpp.

bool __cdecl __acrt_initialize_multibyte(void)
Definition: mbctype.cpp:894

◆ uninitialize_environment_internal()

template<typename Character >
static void __cdecl uninitialize_environment_internal ( Character **&  environment)
throw (
)
static

Definition at line 206 of file environment_initialization.cpp.

207{
208 if (environment == get_initial_environment(Character()))
209 {
210 return;
211 }
212
213 free_environment(environment);
214}

Variable Documentation

◆ __dcrt_initial_narrow_environment

char** __dcrt_initial_narrow_environment = nullptr

◆ __dcrt_initial_wide_environment

wchar_t** __dcrt_initial_wide_environment = nullptr

◆ _environ_table

◆ _wenviron_table

◆ pre_initialize

void pre_initialize(wchar_t) ( wchar_t  )
static

Definition at line 158 of file environment_initialization.cpp.

158{ /* no-op */ }

Referenced by common_initialize_environment_nolock().