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