Merge trunk HEAD (r44067)
[reactos.git] / reactos / 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 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 extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
44
45 static int __proc_attached = 0;
46
47 extern _PVFV *__onexitbegin;
48 extern _PVFV *__onexitend;
49
50 extern int mingw_app_type;
51
52 extern BOOL WINAPI DllMain (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved);
53
54 extern BOOL WINAPI DllEntryPoint (HANDLE, DWORD, LPVOID);
55
56 static int pre_c_init (void);
57
58 _CRTALLOC(".CRT$XIAA") _PIFV pcinit = pre_c_init;
59
60 static int
61 pre_c_init (void)
62 {
63 _PVFV *onexitbegin;
64
65 onexitbegin = (_PVFV *) malloc (32 * sizeof (_PVFV));
66 __onexitend = __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin);
67
68 if (onexitbegin == NULL)
69 return 1;
70 *onexitbegin = (_PVFV) NULL;
71 return 0;
72 }
73
74 BOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
75 {
76 if (dwReason == DLL_PROCESS_DETACH)
77 {
78 if (__proc_attached > 0)
79 __proc_attached--;
80 else
81 return FALSE;
82 }
83 if (dwReason == DLL_PROCESS_ATTACH)
84 {
85 void *lock_free = NULL;
86 void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase;
87 int nested = FALSE;
88
89 while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,
90 fiberid, 0)) != 0)
91 {
92 if (lock_free == fiberid)
93 {
94 nested = TRUE;
95 break;
96 }
97 Sleep(1000);
98 }
99 if (__native_startup_state != __uninitialized)
100 {
101 _amsg_exit(31);
102 }
103 else
104 {
105 __native_startup_state = __initializing;
106
107 _initterm ((_PVFV *) (void *) __xi_a, (_PVFV *) (void *) __xi_z);
108 _initterm (__xc_a,__xc_z);
109 __native_startup_state = __initialized;
110 }
111 if (! nested)
112 {
113 (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
114 }
115 if (__dyn_tls_init_callback != NULL)
116 {
117 __dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved);
118 }
119 __proc_attached++;
120 }
121 else if (dwReason == DLL_PROCESS_DETACH)
122 {
123 void *lock_free = NULL;
124 while ((lock_free = InterlockedCompareExchangePointer ((volatile PVOID *) &__native_startup_lock,(PVOID) 1, 0)) != 0)
125 {
126 Sleep(1000);
127 }
128 if(__native_startup_state!=__initialized)
129 {
130 _amsg_exit (31);
131 }
132 else
133 {
134 _PVFV * onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
135 if (onexitbegin)
136 {
137 _PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend);
138 while (--onexitend >= onexitbegin)
139 if (*onexitend != NULL)
140 (**onexitend) ();
141 free (onexitbegin);
142 __onexitbegin = __onexitend = (_PVFV *) NULL;
143 }
144 __native_startup_state = __uninitialized;
145 (void) InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
146 }
147 }
148 return TRUE;
149 }
150
151 static BOOL __DllMainCRTStartup (HANDLE, DWORD, LPVOID);
152
153 BOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID);
154 int __mingw_init_ehandler (void);
155
156 BOOL WINAPI
157 DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
158 {
159 mingw_app_type = 0;
160 if (dwReason == DLL_PROCESS_ATTACH)
161 {
162 __security_init_cookie ();
163 #ifdef _WIN64
164 __mingw_init_ehandler ();
165 #endif
166 }
167 return __DllMainCRTStartup (hDllHandle, dwReason, lpreserved);
168 }
169
170 __declspec(noinline) BOOL
171 __DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
172 {
173 BOOL retcode = TRUE;
174
175 __native_dllmain_reason = dwReason;
176 if (dwReason == DLL_PROCESS_DETACH && __proc_attached == 0)
177 {
178 retcode = FALSE;
179 goto i__leave;
180 }
181 if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH)
182 {
183 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved);
184 if (retcode)
185 retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved);
186 if (! retcode)
187 goto i__leave;
188 }
189 _pei386_runtime_relocator ();
190 if (retcode && dwReason == DLL_PROCESS_ATTACH)
191 __main ();
192 retcode = DllMain(hDllHandle,dwReason,lpreserved);
193 if ((dwReason == DLL_PROCESS_ATTACH) && ! retcode)
194 {
195 DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
196 _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
197 DllEntryPoint (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
198 }
199 if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
200 {
201 if (_CRT_INIT (hDllHandle, dwReason, lpreserved) == FALSE)
202 {
203 retcode = FALSE;
204 }
205 if (retcode)
206 {
207 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved);
208 }
209 }
210 i__leave:
211 __native_dllmain_reason = UINT_MAX;
212 return retcode ;
213 }
214 #endif