[CMAKE]
[reactos.git] / lib / 3rdparty / mingw / crtdll.c
1 /**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the w64 mingw-runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7 #ifdef CRTDLL
8 #undef CRTDLL
9 #ifndef _DLL
10 #define _DLL
11 #endif
12
13 #include <oscalls.h>
14 #include <internal.h>
15 #include <stdlib.h>
16 #include <windows.h>
17 #define _DECL_DLLMAIN
18 #include <process.h>
19 #include <crtdbg.h>
20
21 #ifndef _CRTIMP
22 #ifdef CRTDLL
23 #define _CRTIMP __declspec(dllexport)
24 #else
25 #ifdef _DLL
26 #define _CRTIMP __declspec(dllimport)
27 #else
28 #define _CRTIMP
29 #endif
30 #endif
31 #endif
32 #include <sect_attribs.h>
33 #include <locale.h>
34
35 extern void __cdecl _initterm(_PVFV *,_PVFV *);
36 extern void __main ();
37 extern void _pei386_runtime_relocator (void);
38 extern _CRTALLOC(".CRT$XIA") _PIFV __xi_a[];
39 extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[];
40 extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
41 extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];
42
43 /* TLS initialization hook. */
44 extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
45
46 static int __proc_attached = 0;
47
48 extern _PVFV *__onexitbegin;
49 extern _PVFV *__onexitend;
50
51 extern int mingw_app_type;
52
53 extern WINBOOL WINAPI DllMain (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved);
54
55 extern WINBOOL WINAPI DllEntryPoint (HANDLE, DWORD, LPVOID);
56
57 static int pre_c_init (void);
58
59 _CRTALLOC(".CRT$XIAA") _PIFV pcinit = pre_c_init;
60
61 static int
62 pre_c_init (void)
63 {
64 _PVFV *onexitbegin;
65
66 onexitbegin = (_PVFV *) malloc (32 * sizeof (_PVFV));
67 __onexitend = __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin);
68
69 if (onexitbegin == NULL)
70 return 1;
71 *onexitbegin = (_PVFV) NULL;
72 return 0;
73 }
74
75 WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
76 {
77 if (dwReason == DLL_PROCESS_DETACH)
78 {
79 if (__proc_attached > 0)
80 __proc_attached--;
81 else
82 return FALSE;
83 }
84 if (dwReason == DLL_PROCESS_ATTACH)
85 {
86 void *lock_free = NULL;
87 void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase;
88 int nested = FALSE;
89
90 while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,
91 fiberid, 0)) != 0)
92 {
93 if (lock_free == fiberid)
94 {
95 nested = TRUE;
96 break;
97 }
98 Sleep(1000);
99 }
100 if (__native_startup_state != __uninitialized)
101 {
102 _amsg_exit(31);
103 }
104 else
105 {
106 __native_startup_state = __initializing;
107
108 _initterm ((_PVFV *) (void *) __xi_a, (_PVFV *) (void *) __xi_z);
109 _initterm (__xc_a,__xc_z);
110 __native_startup_state = __initialized;
111 }
112 if (! nested)
113 {
114 (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
115 }
116 if (__dyn_tls_init_callback != NULL)
117 {
118 __dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved);
119 }
120 __proc_attached++;
121 }
122 else if (dwReason == DLL_PROCESS_DETACH)
123 {
124 void *lock_free = NULL;
125 while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,(PVOID) 1, 0)) != 0)
126 {
127 Sleep(1000);
128 }
129 if(__native_startup_state!=__initialized)
130 {
131 _amsg_exit (31);
132 }
133 else
134 {
135 _PVFV * onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
136 if (onexitbegin)
137 {
138 _PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend);
139 while (--onexitend >= onexitbegin)
140 if (*onexitend != NULL)
141 (**onexitend) ();
142 free (onexitbegin);
143 __onexitbegin = __onexitend = (_PVFV *) NULL;
144 }
145 __native_startup_state = __uninitialized;
146 (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
147 }
148 }
149 return TRUE;
150 }
151
152 static WINBOOL __DllMainCRTStartup (HANDLE, DWORD, LPVOID);
153
154 WINBOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID);
155 int __mingw_init_ehandler (void);
156
157 WINBOOL WINAPI
158 DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
159 {
160 mingw_app_type = 0;
161 if (dwReason == DLL_PROCESS_ATTACH)
162 {
163 __security_init_cookie ();
164 #ifdef _WIN64
165 __mingw_init_ehandler ();
166 #endif
167 }
168 return __DllMainCRTStartup (hDllHandle, dwReason, lpreserved);
169 }
170
171 __declspec(noinline) WINBOOL
172 __DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
173 {
174 WINBOOL retcode = TRUE;
175
176 __native_dllmain_reason = dwReason;
177 if (dwReason == DLL_PROCESS_DETACH && __proc_attached == 0)
178 {
179 retcode = FALSE;
180 goto i__leave;
181 }
182 _pei386_runtime_relocator ();
183 if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH)
184 {
185 retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved);
186 if (!retcode)
187 goto i__leave;
188 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved);
189 if (! retcode)
190 {
191 if (dwReason == DLL_PROCESS_ATTACH)
192 _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
193 goto i__leave;
194 }
195 }
196 if (dwReason == DLL_PROCESS_ATTACH)
197 __main ();
198 retcode = DllMain(hDllHandle,dwReason,lpreserved);
199 if (dwReason == DLL_PROCESS_ATTACH && ! retcode)
200 {
201 DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
202 DllEntryPoint (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
203 _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
204 }
205 if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
206 {
207 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved);
208 if (_CRT_INIT (hDllHandle, dwReason, lpreserved) == FALSE)
209 retcode = FALSE;
210 }
211 i__leave:
212 __native_dllmain_reason = UINT_MAX;
213 return retcode ;
214 }
215 #endif