Call the registered exit functions if the dll is unloaded.
[reactos.git] / reactos / lib / crtdll / dllmain.c
1 /* $Id: dllmain.c 12852 2005-01-06 13:58:04Z mf $
2 *
3 * dllmain.c
4 *
5 * ReactOS MSVCRT.DLL Compatibility Library
6 *
7 * THIS SOFTWARE IS NOT COPYRIGHTED
8 *
9 * This source code is offered for use in the public domain. You may
10 * use, modify or distribute it freely.
11 *
12 * This code is distributed in the hope that it will be useful but
13 * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
14 * DISCLAMED. This includes but is not limited to warrenties of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * $Revision: 1.24 $
18 * $Author: mf $
19 * $Date: 2005-01-06 14:58:04 +0100 (Thu, 06 Jan 2005) $
20 *
21 */
22
23 #include <precomp.h>
24 #include <stdio.h>
25 #include <internal/tls.h>
26 #include <stdlib.h>
27 #include <internal/wine/msvcrt.h>
28 #include <sys/stat.h>
29
30 #define NDEBUG
31 #include <internal/debug.h>
32
33
34 /* EXTERNAL PROTOTYPES ********************************************************/
35
36 //void __fileno_init(void);
37 extern BOOL __fileno_init(void);
38 extern int BlockEnvToEnvironA(void);
39 extern int BlockEnvToEnvironW(void);
40 extern void FreeEnvironment(char **environment);
41 extern void _atexit_cleanup(void);
42
43 extern unsigned int _osver;
44 extern unsigned int _winminor;
45 extern unsigned int _winmajor;
46 extern unsigned int _winver;
47
48 unsigned int CRTDLL__basemajor_dll;
49 unsigned int CRTDLL__baseminor_dll;
50 unsigned int CRTDLL__baseversion_dll;
51 unsigned int CRTDLL__cpumode_dll;
52 unsigned int CRTDLL__osmajor_dll;
53 unsigned int CRTDLL__osminor_dll;
54 unsigned int CRTDLL__osmode_dll;
55 unsigned int CRTDLL__osversion_dll;
56
57 extern char* _acmdln; /* pointer to ascii command line */
58 extern wchar_t* _wcmdln; /* pointer to wide character command line */
59 #undef _environ
60 extern char** _environ; /* pointer to environment block */
61 extern char** __initenv; /* pointer to initial environment block */
62 extern wchar_t** _wenviron; /* pointer to environment block */
63 extern wchar_t** __winitenv; /* pointer to initial environment block */
64
65
66
67 /* dev_t is a short in crtdll but an unsigned int in msvcrt */
68 typedef short crtdll_dev_t;
69
70 struct crtdll_stat
71 {
72 crtdll_dev_t st_dev;
73 _ino_t st_ino;
74 unsigned short st_mode;
75 short st_nlink;
76 short st_uid;
77 short st_gid;
78 crtdll_dev_t st_rdev;
79 _off_t st_size;
80 time_t st_atime;
81 time_t st_mtime;
82 time_t st_ctime;
83 };
84
85 /* convert struct _stat from crtdll format to msvcrt format */
86 static void convert_struct_stat( struct crtdll_stat *dst, const struct _stat *src )
87 {
88 dst->st_dev = src->st_dev;
89 dst->st_ino = src->st_ino;
90 dst->st_mode = src->st_mode;
91 dst->st_nlink = src->st_nlink;
92 dst->st_uid = src->st_uid;
93 dst->st_gid = src->st_gid;
94 dst->st_rdev = src->st_rdev;
95 dst->st_size = src->st_size;
96 dst->st_atime = src->st_atime;
97 dst->st_mtime = src->st_mtime;
98 dst->st_ctime = src->st_ctime;
99 }
100
101 /* from msvcrt */
102 extern void __getmainargs( int *argc, char ***argv, char ***envp,
103 int expand_wildcards, int *new_mode );
104
105 /* LIBRARY GLOBAL VARIABLES ***************************************************/
106
107 HANDLE hHeap = NULL; /* handle for heap */
108
109
110 /* LIBRARY ENTRY POINT ********************************************************/
111
112 BOOL
113 STDCALL
114 DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved)
115 {
116 switch (dwReason)
117 {
118 case DLL_PROCESS_ATTACH://1
119 /* initialize version info */
120 DPRINT("Attach %d\n", nAttachCount);
121
122 _osver = GetVersion();
123
124 CRTDLL__basemajor_dll = (_osver >> 24) & 0xFF;
125 CRTDLL__baseminor_dll = (_osver >> 16) & 0xFF;
126 CRTDLL__baseversion_dll = (_osver >> 16);
127 CRTDLL__cpumode_dll = 1; /* FIXME */
128 CRTDLL__osmajor_dll = (_osver >>8) & 0xFF;
129 CRTDLL__osminor_dll = (_osver & 0xFF);
130 CRTDLL__osmode_dll = 1; /* FIXME */
131 CRTDLL__osversion_dll = (_osver & 0xFFFF);
132
133 _winmajor = (_osver >> 8) & 0xFF;
134 _winminor = _osver & 0xFF;
135 _winver = (_winmajor << 8) + _winminor;
136 _osver = (_osver >> 16) & 0xFFFF;
137 hHeap = HeapCreate(0, 100000, 0);
138 if (hHeap == NULL)
139 return FALSE;
140 if (!__fileno_init())
141 return FALSE;
142
143 /* create tls stuff */
144 if (!CreateThreadData())
145 return FALSE;
146
147 if (BlockEnvToEnvironA() < 0)
148 return FALSE;
149
150 if (BlockEnvToEnvironW() < 0)
151 {
152 FreeEnvironment((char**)_wenviron);
153 return FALSE;
154 }
155
156 _acmdln = _strdup(GetCommandLineA());
157 _wcmdln = _wcsdup(GetCommandLineW());
158
159 /* FIXME: more initializations... */
160
161 /* FIXME: Initialization of the WINE code */
162 msvcrt_init_mt_locks();
163
164 DPRINT("Attach done\n");
165 break;
166
167 case DLL_THREAD_ATTACH://2
168 break;
169
170 case DLL_THREAD_DETACH://4
171 FreeThreadData(NULL);
172 break;
173
174 case DLL_PROCESS_DETACH://0
175 DPRINT("Detach %d\n", nAttachCount);
176 /* FIXME: more cleanup... */
177 _fcloseall();
178 _atexit_cleanup();
179
180 /* destroy tls stuff */
181 DestroyThreadData();
182
183 if (__winitenv && __winitenv != _wenviron)
184 FreeEnvironment((char**)__winitenv);
185 if (_wenviron)
186 FreeEnvironment((char**)_wenviron);
187
188 if (__initenv && __initenv != _environ)
189 FreeEnvironment(__initenv);
190 if (_environ)
191 FreeEnvironment(_environ);
192
193 /* destroy heap */
194 HeapDestroy(hHeap);
195
196 DPRINT("Detach done\n");
197 break;
198 }
199
200 return TRUE;
201 }
202
203
204
205
206 /*********************************************************************
207 * __GetMainArgs (CRTDLL.@)
208 */
209 void __GetMainArgs( int *argc, char ***argv, char ***envp, int expand_wildcards )
210 {
211 int new_mode = 0;
212 __getmainargs( argc, argv, envp, expand_wildcards, &new_mode );
213 }
214
215
216 /*********************************************************************
217 * _fstat (CRTDLL.@)
218 */
219 int CRTDLL__fstat(int fd, struct crtdll_stat* buf)
220 {
221 extern int _fstat(int,struct _stat*);
222 struct _stat st;
223 int ret;
224
225 if (!(ret = _fstat( fd, &st ))) convert_struct_stat( buf, &st );
226 return ret;
227 }
228
229
230 /*********************************************************************
231 * _stat (CRTDLL.@)
232 */
233 int CRTDLL__stat(const char* path, struct crtdll_stat * buf)
234 {
235 extern int _stat(const char*,struct _stat*);
236 struct _stat st;
237 int ret;
238
239 if (!(ret = _stat( path, &st ))) convert_struct_stat( buf, &st );
240 return ret;
241 }
242
243
244 /*********************************************************************
245 * _strdec (CRTDLL.@)
246 */
247 char *_strdec(const char *str1, const char *str2)
248 {
249 return (char *)(str2 - 1);
250 }
251
252
253 /*********************************************************************
254 * _strinc (CRTDLL.@)
255 */
256 char *_strinc(const char *str)
257 {
258 return (char *)(str + 1);
259 }
260
261
262 /*********************************************************************
263 * _strncnt (CRTDLL.@)
264 */
265 size_t _strncnt(const char *str, size_t maxlen)
266 {
267 size_t len = strlen(str);
268 return (len > maxlen) ? maxlen : len;
269 }
270
271
272 /*********************************************************************
273 * _strnextc (CRTDLL.@)
274 */
275 unsigned int _strnextc(const char *str)
276 {
277 return (unsigned int)str[0];
278 }
279
280
281 /*********************************************************************
282 * _strninc (CRTDLL.@)
283 */
284 char *_strninc(const char *str, size_t len)
285 {
286 return (char *)(str + len);
287 }
288
289
290 /*********************************************************************
291 * _strspnp (CRTDLL.@)
292 */
293 char *_strspnp( const char *str1, const char *str2)
294 {
295 str1 += strspn( str1, str2 );
296 return *str1 ? (char*)str1 : NULL;
297 }
298
299 /* EOF */