Authors: Jon Griffiths <jon_p_griffiths@yahoo.com>, François Gouget <fgouget@codeweav...
[wine] / dlls / msvcrt / main.c
1 /*
2  * msvcrt.dll initialisation functions
3  *
4  * Copyright 2000 Jon Griffiths
5  */
6 #include "msvcrt.h"
7
8 #include "msvcrt/locale.h"
9 #include "msvcrt/stdio.h"
10
11
12 DEFAULT_DEBUG_CHANNEL(msvcrt);
13
14 /* Index to TLS */
15 DWORD MSVCRT_tls_index;
16
17 /* MT locks */
18 CRITICAL_SECTION MSVCRT_heap_cs;
19 CRITICAL_SECTION MSVCRT_file_cs;
20 CRITICAL_SECTION MSVCRT_exit_cs;
21 CRITICAL_SECTION MSVCRT_console_cs;
22 CRITICAL_SECTION MSVCRT_locale_cs;
23
24 static inline BOOL msvcrt_init_tls(void);
25 static inline BOOL msvcrt_free_tls(void);
26 static inline void msvcrt_init_critical_sections(void);
27 static inline void msvcrt_free_critical_sections(void);
28 const char* msvcrt_get_reason(DWORD reason) WINE_UNUSED;
29
30 void msvcrt_init_io(void);
31 void msvcrt_init_console(void);
32 void msvcrt_free_console(void);
33 void msvcrt_init_args(void);
34 void msvcrt_free_args(void);
35 void msvcrt_init_vtables(void);
36
37 typedef void* (*MSVCRT_malloc_func)(unsigned int);
38 typedef void (*MSVCRT_free_func)(void*);
39
40 /*********************************************************************
41  *                  Init
42  */
43 BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
44 {
45   MSVCRT_thread_data *tls;
46
47   TRACE("(0x%08x, %s, %p) pid(%ld), tid(%ld), tls(%ld)\n",
48         hinstDLL, msvcrt_get_reason(fdwReason), lpvReserved,
49         (long)GetCurrentProcessId(), (long)GetCurrentThreadId(),
50         (long)MSVCRT_tls_index);
51
52   switch (fdwReason)
53   {
54   case DLL_PROCESS_ATTACH:
55     if (!msvcrt_init_tls())
56       return FALSE;
57     msvcrt_init_vtables();
58     msvcrt_init_critical_sections();
59     msvcrt_init_io();
60     msvcrt_init_console();
61     msvcrt_init_args();
62     MSVCRT_setlocale(0, "C");
63     TRACE("finished process init\n");
64     /* FALL THROUGH for Initial TLS allocation!! */
65   case DLL_THREAD_ATTACH:
66     TRACE("starting thread init\n");
67     /* Create TLS */
68     tls = (MSVCRT_thread_data*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
69                                           sizeof(MSVCRT_thread_data));
70     if (!tls || !TlsSetValue(MSVCRT_tls_index, tls))
71     {
72       ERR("TLS init failed! error = %ld\n", GetLastError());
73       return FALSE;
74     }
75     TRACE("finished thread init\n");
76     break;
77   case DLL_PROCESS_DETACH:
78     msvcrt_free_critical_sections();
79     _fcloseall();
80     msvcrt_free_console();
81     msvcrt_free_args();
82     if (!msvcrt_free_tls())
83       return FALSE;
84     TRACE("finished process free\n");
85     break;
86   case DLL_THREAD_DETACH:
87     /* Free TLS */
88     tls = TlsGetValue(MSVCRT_tls_index);
89
90     if (!tls)
91     {
92       ERR("TLS free failed! error = %ld\n", GetLastError());
93       return FALSE;
94     }
95     HeapFree(GetProcessHeap(), 0, tls);
96     TRACE("finished thread free\n");
97     break;
98   }
99   return TRUE;
100 }
101
102 static inline BOOL msvcrt_init_tls(void)
103 {
104   MSVCRT_tls_index = TlsAlloc();
105
106   if (MSVCRT_tls_index == TLS_OUT_OF_INDEXES)
107   {
108     ERR("TlsAlloc() failed!\n");
109     return FALSE;
110   }
111   return TRUE;
112 }
113
114 static inline BOOL msvcrt_free_tls(void)
115 {
116   if (!TlsFree(MSVCRT_tls_index))
117   {
118     ERR("TlsFree() failed!\n");
119     return FALSE;
120   }
121   return TRUE;
122 }
123
124 static inline void msvcrt_init_critical_sections(void)
125 {
126   InitializeCriticalSectionAndSpinCount(&MSVCRT_heap_cs, 4000);
127   InitializeCriticalSection(&MSVCRT_file_cs);
128   InitializeCriticalSection(&MSVCRT_exit_cs);
129   InitializeCriticalSection(&MSVCRT_console_cs);
130   InitializeCriticalSection(&MSVCRT_locale_cs);
131 }
132
133 static inline void msvcrt_free_critical_sections(void)
134 {
135   DeleteCriticalSection(&MSVCRT_locale_cs);
136   DeleteCriticalSection(&MSVCRT_console_cs);
137   DeleteCriticalSection(&MSVCRT_exit_cs);
138   DeleteCriticalSection(&MSVCRT_file_cs);
139   DeleteCriticalSection(&MSVCRT_heap_cs);
140 }
141
142 const char* msvcrt_get_reason(DWORD reason)
143 {
144   switch (reason)
145   {
146   case DLL_PROCESS_ATTACH: return "DLL_PROCESS_ATTACH";
147   case DLL_PROCESS_DETACH: return "DLL_PROCESS_DETACH";
148   case DLL_THREAD_ATTACH:  return "DLL_THREAD_ATTACH";
149   case DLL_THREAD_DETACH:  return "DLL_THREAD_DETACH";
150   }
151   return "UNKNOWN";
152 }
153
154
155 /*********************************************************************
156  *              $I10_OUTPUT (MSVCRT.@)
157  * Function not really understood but needed to make the DLL work
158  */
159 void MSVCRT_I10_OUTPUT(void)
160 {
161   /* FIXME: This is probably data, not a function */
162 }
163
164
165 /*********************************************************************
166  *              __unDName (MSVCRT.@)
167  * Function not really understood but needed to make the DLL work
168  */
169 char* MSVCRT___unDName(int unknown, const char* mangled,
170                        MSVCRT_malloc_func memget,
171                        MSVCRT_free_func memfree,
172                        unsigned int flags)
173 {
174   char* ret;
175
176   FIXME("(%d,%s,%p,%p,%x) stub!\n", unknown, mangled, memget, memfree, flags);
177
178   /* Experimentation reveals the following flag meanings when set:
179    * 0x0001 - Dont show __ in calling convention
180    * 0x0002 - Dont show calling convention at all
181    * 0x0004 - Dont show function/method return value
182    * 0x0010 - Same as 0x1
183    * 0x0080 - Dont show access specifier (public/protected/private)
184    * 0x0200 - Dont show static specifier
185    * 0x1000 - Only report the variable/class name
186    */
187   /* Duplicate the mangled name; for comparisons it doesn't matter anyway */
188   ret = memget(strlen(mangled) + 1);
189   strcpy(ret, mangled);
190   return ret;
191 }
192
193
194 /*********************************************************************
195  *              __unDNameEx (MSVCRT.@)
196  * Function not really understood but needed to make the DLL work
197  */
198 char* MSVCRT___unDNameEx(void)
199 {
200    return NULL;
201 }