ReactOS 0.4.16-dev-835-gd769f56
initialization.cpp
Go to the documentation of this file.
1//
2// initialization.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// This file defines the main initialization and uninitialization routines for
7// the AppCRT, shared by both the static and dynamic AppCRT libraries. In the
8// dynamic AppCRT library, these are called by DllMain. In the static AppCRT
9// library, these are called by the initialization code.
10//
11#include <corecrt_internal.h>
13#include <stdlib.h>
14#include <stdio.h>
15
16extern "C" {
17
18
19
22extern void* __acrt_stdout_buffer;
23extern void* __acrt_stderr_buffer;
24
25
26
28{
30 return true;
31}
32
33
34
35#ifdef CRTDLL
36
37 static bool __cdecl initialize_c()
38 {
41
42 // Do C initialization:
43 if (_initterm_e(__xi_a, __xi_z) != 0)
44 {
45 return false;
46 }
47
48 // Do C++ initialization:
50 return true;
51 }
52
53 static bool __cdecl uninitialize_c(bool)
54 {
55 // Do pre-termination:
57
58 // Do termination:
60 return true;
61 }
62
63// C4505: unreferenced local function
64#pragma warning( suppress: 4505 )
66 {
68 {
69 return false;
70 }
71
73 {
74 return false;
75 }
76
77 return true;
78 }
79
80#else
81
82 static bool __cdecl initialize_c()
83 {
86 return true;
87 }
88
89 static bool __cdecl uninitialize_c(bool)
90 {
91 return true;
92 }
93
94// C4505: unreferenced local function
95#pragma warning( suppress: 4505 )
97 {
98 return true;
99 }
100
101#endif
102
103// C4505: unreferenced local function
104#pragma warning( suppress: 4505 )
105static bool __cdecl uninitialize_environment(bool const terminating)
106{
107 UNREFERENCED_PARAMETER(terminating);
108
109 #ifdef _DEBUG
110 if (terminating)
111 {
112 return true;
113 }
114 #endif
115
117 return true;
118}
119
120#ifdef _CRT_GLOBAL_STATE_ISOLATION
121
123 {
124 // Configure CRT's per-thread global state mode data
125 return __crt_state_management::initialize_global_state_isolation();
126 }
127
128 static bool __cdecl uninitialize_global_state_isolation(bool const terminating)
129 {
130 // Configure CRT's per-thread global state mode data
131 __crt_state_management::uninitialize_global_state_isolation(terminating);
132 return true;
133 }
134
135#else
136
138 {
139 return true;
140 }
141
142 static bool __cdecl uninitialize_global_state_isolation(bool const /* terminating */)
143 {
144 return true;
145 }
146
147#endif
148
149
150
152{
153 void* const encoded_null = __crt_fast_encode_pointer(nullptr);
155 __acrt_initialize_new_handler(encoded_null);
157 __acrt_initialize_user_matherr(encoded_null);
159 return true;
160}
161
162static bool __cdecl uninitialize_vcruntime(const bool /* terminating */)
163{
164 return __vcrt_uninitialize(false);
165}
166
167static bool __cdecl uninitialize_allocated_memory(bool const /* terminating */)
168{
169 __acrt_current_multibyte_data.uninitialize([](__crt_multibyte_data*& multibyte_data)
170 {
171 if (_InterlockedDecrement(&multibyte_data->refcount) == 0 &&
172 multibyte_data != &__acrt_initial_multibyte_data)
173 {
174 _free_crt(multibyte_data);
175 multibyte_data = &__acrt_initial_multibyte_data;
176 }
177 });
178
179 return true;
180}
181
182// C4505: unreferenced local function
183#pragma warning( suppress: 4505 )
184static bool __cdecl uninitialize_allocated_io_buffers(bool const /* terminating */)
185{
187 __acrt_stdout_buffer = nullptr;
188
190 __acrt_stderr_buffer = nullptr;
191
193 __argv = nullptr;
194
196 __wargv = nullptr;
197
198 return true;
199}
200
201static bool __cdecl report_memory_leaks(bool const /* terminating */)
202{
203 #ifdef _DEBUG
205 {
206 _CrtSetDumpClient(nullptr);
208 }
209 #endif
210
211 return true;
212}
213
214
215
216// This is the table of initializer/uninitializer pairs that is used to perform
217// AppCRT initialization. Initializers are run first-to-last during AppCRT
218// initialization, and uninitializers are run last-to-first during termination.
220{
221 // Init globals that can't be set at compile time because they have c'tors
222 { initialize_global_variables, nullptr },
223
224 // Global pointers are stored in encoded form; they must be dynamically
225 // initialized to the encoded nullptr value before they are used by the CRT.
226 { initialize_pointers, nullptr },
227 // Enclaves only require initializers for supported features.
228#ifndef _UCRT_ENCLAVE_BUILD
230#endif
231
232 // Configure CRT's global state isolation system. This system calls FlsAlloc
233 // and thus must occur after the initialize_pointers initialization, otherwise
234 // it will fall back to call TlsAlloc, then try to use the allocated TLS slot
235 // with the FLS functions. This does not turn out well. By running this
236 // initialization after the initialize_pointers step, we ensure that it can
237 // call FlsAlloc.
239
240 // The heap and locks must be initialized before most other initialization
241 // takes place, as other initialization steps rely on the heap and locks:
244
245 // During uninitialization, before the heap is uninitialized, the AppCRT
246 // needs to notify all VCRuntime instances in the process to allow them to
247 // release any memory that they allocated via the AppCRT heap.
248 //
249 // First, we notify all modules that registered for shutdown notification.
250 // This only occurs in the AppCRT DLL, because the static CRT is only ever
251 // used by a single module, so this notification is never required.
252 //
253 // Then, we notify our own VCRuntime instance. Note that after this point
254 // during uninitialization, no exception handling may take place in any
255 // CRT module.
256 { nullptr, uninitialize_vcruntime },
257
259 // Enclaves only require initializers for supported features.
260#ifndef _UCRT_ENCLAVE_BUILD
263#endif
264 { __acrt_initialize_multibyte, nullptr },
265 { nullptr, report_memory_leaks },
266 // Enclaves only require initializers for supported features.
267#ifndef _UCRT_ENCLAVE_BUILD
269#endif
271 // Enclaves only require initializers for supported features.
272#ifndef _UCRT_ENCLAVE_BUILD
274#endif
276};
277
278
279
280
282{
283 #if defined CRTDLL
285 #endif
286
290 );
291}
292
294{
295 UNREFERENCED_PARAMETER(terminating);
296
297 // If the process is terminating, there's no point in cleaning up, except
298 // in debug builds.
299 #ifndef _DEBUG
300 if (terminating) {
301 #ifndef _UCRT_ENCLAVE_BUILD
303 _flushall();
304 }
305 #endif
306 return TRUE;
307 }
308 #endif
309
313 );
314}
315
317{
318 __acrt_uninitialize_ptd(terminating);
319
320 #ifdef _CRT_GLOBAL_STATE_ISOLATION
322 #endif
323
324 return true;
325}
326
328{
329 // Create a per-thread data structure for this thread (getptd will attempt
330 // to create a new per-thread data structure if one does not already exist
331 // for this thread):
332 if (__acrt_getptd_noexit() == nullptr)
333 return false;
334
335 return true;
336}
337
339{
340 // Free the per-thread data structure for this thread:
342 return true;
343}
344
345}
#define __cdecl
Definition: accygwin.h:79
bool __cdecl __acrt_uninitialize_command_line(_In_ bool terminating)
bool __cdecl __acrt_uninitialize_lowio(_In_ bool terminating)
bool __cdecl __acrt_execute_initializers(_In_reads_(last - first) _In_ __acrt_initializer const *first, _In_reads_(0) __acrt_initializer const *last)
bool __cdecl __acrt_initialize_lowio(void)
Definition: ioinit.cpp:224
bool __cdecl __acrt_initialize_winapi_thunks(void)
void __cdecl __acrt_freeptd(void)
void __cdecl __acrt_initialize_invalid_parameter_handler(_In_opt_ void *encoded_null)
void __cdecl __acrt_initialize_user_matherr(void *encoded_null)
Definition: matherr.cpp:22
bool __cdecl __acrt_execute_uninitializers(_In_reads_(last - first) __acrt_initializer const *first, _In_reads_(0) __acrt_initializer const *last)
void __cdecl __acrt_initialize_signal_handlers(_In_opt_ void *encoded_null)
__crt_locale_data __acrt_initial_locale_data
Definition: nlsdata.cpp:92
bool __cdecl __acrt_uninitialize_locks(_In_ bool terminating)
bool __cdecl __acrt_initialize_multibyte(void)
Definition: mbctype.cpp:894
bool __cdecl __acrt_uninitialize_winapi_thunks(_In_ bool terminating)
void __cdecl __acrt_initialize_thread_local_exit_callback(_In_opt_ void *encoded_null)
__crt_multibyte_data __acrt_initial_multibyte_data
Definition: mbctype.cpp:42
bool __cdecl __acrt_initialize_ptd(void)
bool __cdecl __acrt_initialize_command_line(void)
Definition: argv_data.cpp:61
bool __cdecl __acrt_uninitialize_ptd(_In_ bool terminating)
bool __cdecl __acrt_initialize_locks(void)
Definition: locks.cpp:25
__acrt_ptd *__cdecl __acrt_getptd_noexit(void)
bool __acrt_stdio_is_initialized()
_ACRTIMP int __cdecl _initialize_onexit_table(_In_opt_ _onexit_table_t *_Table)
_ACRTIMP void __cdecl _initterm(_In_reads_(_Last - _First) _In_ _PVFV *_First, _In_ _PVFV *_Last)
int __CRTDECL _initialize_narrow_environment(void)
_ACRTIMP char **__cdecl _get_initial_narrow_environment(void)
_ACRTIMP int __cdecl _initterm_e(_In_reads_(_Last - _First) _PIFV *_First, _In_ _PIFV *_Last)
#define _CrtDumpMemoryLeaks()
Definition: crtdbg.h:258
#define _CRTDBG_LEAK_CHECK_DF
Definition: crtdbg.h:53
#define _CRTDBG_REPORT_FLAG
Definition: crtdbg.h:61
#define _CrtSetDbgFlag(f)
Definition: crtdbg.h:246
#define _CrtSetDumpClient(f)
Definition: crtdbg.h:252
#define TRUE
Definition: types.h:120
void __cdecl __dcrt_uninitialize_environments_nolock()
bool __cdecl __acrt_uninitialize_heap(bool const)
Definition: heap_handle.cpp:32
bool __cdecl __acrt_initialize_heap()
Definition: heap_handle.cpp:21
_Check_return_opt_ _CRTIMP int __cdecl _flushall(void)
Definition: file.c:893
#define __argv
Definition: stdlib.h:1154
#define __wargv
Definition: stdlib.h:1155
static bool __cdecl initialize_c()
__crt_bool __cdecl __acrt_uninitialize_critical(__crt_bool const terminating)
static bool __cdecl uninitialize_vcruntime(const bool)
_onexit_table_t __acrt_at_quick_exit_table
Definition: exit.cpp:15
static __acrt_initializer const __acrt_initializers[]
static bool __cdecl initialize_global_state_isolation()
static bool __cdecl uninitialize_c(bool)
static bool __cdecl report_memory_leaks(bool const)
void * __acrt_stdout_buffer
Definition: _sftbuf.cpp:26
_onexit_table_t __acrt_atexit_table
Definition: exit.cpp:14
__crt_bool __cdecl __acrt_thread_detach()
__crt_bool __cdecl __acrt_thread_attach()
__crt_bool __cdecl __acrt_uninitialize(__crt_bool const terminating)
static bool __cdecl uninitialize_allocated_memory(bool const)
void * __acrt_stderr_buffer
Definition: _sftbuf.cpp:27
static bool __cdecl uninitialize_environment(bool const terminating)
static bool __cdecl initialize_pointers()
static bool __cdecl uninitialize_allocated_io_buffers(bool const)
static bool __cdecl uninitialize_global_state_isolation(bool const)
__crt_bool __cdecl __acrt_initialize()
static bool __cdecl initialize_global_variables()
static bool __cdecl initialize_environment()
_PVFV __xp_z[]
#define _free_crt
_PVFV __xp_a[]
_PVFV __xc_a[]
_PVFV __xc_z[]
_PVFV __xt_a[]
_PVFV __xt_z[]
_PIFV __xi_z[]
_PIFV __xi_a[]
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
__crt_state_management::dual_state_global< __crt_multibyte_data * > __acrt_current_multibyte_data
Definition: mbctype.cpp:131
void __cdecl __acrt_initialize_new_handler(void *const encoded_null)
Definition: new_handler.cpp:18
__crt_state_management::dual_state_global< __crt_locale_data * > __acrt_current_locale_data
Definition: nlsdata.cpp:132
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define _countof(array)
Definition: sndvol32.h:70
_Bool __crt_bool
Definition: corecrt.h:274
__vcrt_bool __cdecl __vcrt_uninitialize(_In_ __vcrt_bool _Terminating)
Definition: __vcrt_init.c:28
int __cdecl __isa_available_init(void)