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