[HEADERS]
[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 InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
114 }
115 if (__dyn_tls_init_callback != NULL &&
116 _IsNonwritableInCurrentImage ((PBYTE) &__dyn_tls_init_callback))
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 InterlockedExchangePointer ((volatile PVOID *) &__native_startup_lock, 0);
147 }
148 }
149 return TRUE;
150 }
151
152 static BOOL __DllMainCRTStartup (HANDLE, DWORD, LPVOID);
153
154 BOOL WINAPI
155 DllMainCRTStartup(HANDLE hDllHandle,DWORD dwReason,LPVOID lpreserved)
156 {
157 mingw_app_type = 0;
158 if (dwReason == DLL_PROCESS_ATTACH)
159 {
160 __security_init_cookie ();
161 }
162 return __DllMainCRTStartup (hDllHandle, dwReason, lpreserved);
163 }
164
165 __declspec(noinline) BOOL
166 __DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
167 {
168 BOOL retcode = TRUE;
169
170 __native_dllmain_reason = dwReason;
171 if (dwReason == DLL_PROCESS_DETACH && __proc_attached == 0)
172 {
173 retcode = FALSE;
174 goto i__leave;
175 }
176 if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH)
177 {
178 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved);
179 if (retcode)
180 retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved);
181 if (! retcode)
182 goto i__leave;
183 }
184 _pei386_runtime_relocator ();
185 if (retcode && dwReason == DLL_PROCESS_ATTACH)
186 __main ();
187 retcode = DllMain(hDllHandle,dwReason,lpreserved);
188 if ((dwReason == DLL_PROCESS_ATTACH) && ! retcode)
189 {
190 DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
191 _CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
192 DllEntryPoint (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
193 }
194 if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
195 {
196 if (_CRT_INIT (hDllHandle, dwReason, lpreserved) == FALSE)
197 {
198 retcode = FALSE;
199 }
200 if (retcode)
201 {
202 retcode = DllEntryPoint (hDllHandle, dwReason, lpreserved);
203 }
204 }
205 i__leave:
206 __native_dllmain_reason = UINT_MAX;
207 return retcode ;
208 }
209 #endif