- Migrate CRTDLL to MSVCRT.
[wine] / dlls / msvcrt / main.c
1 /*
2  * msvcrt.dll initialisation functions
3  *
4  * Copyright 2000 Jon Griffiths
5  */
6 #include "msvcrt.h"
7
8 DEFAULT_DEBUG_CHANNEL(msvcrt);
9
10 /* Index to TLS */
11 DWORD MSVCRT_tls_index;
12
13 /* MT locks */
14 CRITICAL_SECTION MSVCRT_heap_cs;
15 CRITICAL_SECTION MSVCRT_file_cs;
16 CRITICAL_SECTION MSVCRT_exit_cs;
17 CRITICAL_SECTION MSVCRT_console_cs;
18 CRITICAL_SECTION MSVCRT_locale_cs;
19
20 static inline BOOL MSVCRT_init_tls(void);
21 static inline BOOL MSVCRT_free_tls(void);
22 static inline void MSVCRT_init_critical_sections(void);
23 static inline void MSVCRT_free_critical_sections(void);
24 #ifdef __GNUC__
25 const char *MSVCRT_get_reason(DWORD reason) __attribute__((unused));
26 #else
27 const char *MSVCRT_get_reason(DWORD reason);
28 #endif
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 char *__cdecl MSVCRT_setlocale(int category, const char *locale);
37
38
39 /*********************************************************************
40  *                  Init
41  */
42 BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
43 {
44   MSVCRT_thread_data *tls;
45
46   TRACE("(0x%08x, %s, %p) pid(%ld), tid(%ld), tls(%ld)\n",
47         hinstDLL, MSVCRT_get_reason(fdwReason), lpvReserved,
48         (long)GetCurrentProcessId(), (long)GetCurrentThreadId(),
49         (long)MSVCRT_tls_index);
50
51   switch (fdwReason)
52   {
53   case DLL_PROCESS_ATTACH:
54     if (!MSVCRT_init_tls())
55       return FALSE;
56     MSVCRT_init_vtables();
57     MSVCRT_init_critical_sections();
58     MSVCRT_init_io();
59     MSVCRT_init_console();
60     MSVCRT_init_args();
61     MSVCRT_setlocale(0, "C");
62     TRACE("finished process init\n");
63     /* FALL THROUGH for Initial TLS allocation!! */
64   case DLL_THREAD_ATTACH:
65     TRACE("starting thread init\n");
66     /* Create TLS */
67     tls = (MSVCRT_thread_data*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
68                                           sizeof(MSVCRT_thread_data));
69     if (!tls || !TlsSetValue(MSVCRT_tls_index, tls))
70     {
71       ERR("TLS init failed! error = %ld\n", GetLastError());
72       return FALSE;
73     }
74     TRACE("finished thread init\n");
75     break;
76   case DLL_PROCESS_DETACH:
77     MSVCRT_free_critical_sections();
78     MSVCRT__fcloseall();
79     MSVCRT_free_console();
80     MSVCRT_free_args();
81     if (!MSVCRT_free_tls())
82       return FALSE;
83     TRACE("finished process free\n");
84     break;
85   case DLL_THREAD_DETACH:
86     /* Free TLS */
87     tls = TlsGetValue(MSVCRT_tls_index);
88
89     if (!tls)
90     {
91       ERR("TLS free failed! error = %ld\n", GetLastError());
92       return FALSE;
93     }
94     HeapFree(GetProcessHeap(), 0, tls);
95     TRACE("finished thread free\n");
96     break;
97   }
98   return TRUE;
99 }
100
101 static inline BOOL MSVCRT_init_tls(void)
102 {
103   MSVCRT_tls_index = TlsAlloc();
104
105   if (MSVCRT_tls_index == TLS_OUT_OF_INDEXES)
106   {
107     ERR("TlsAlloc() failed!\n");
108     return FALSE;
109   }
110   return TRUE;
111 }
112
113 static inline BOOL MSVCRT_free_tls(void)
114 {
115   if (!TlsFree(MSVCRT_tls_index))
116   {
117     ERR("TlsFree() failed!\n");
118     return FALSE;
119   }
120   return TRUE;
121 }
122
123 static inline void MSVCRT_init_critical_sections(void)
124 {
125   InitializeCriticalSectionAndSpinCount(&MSVCRT_heap_cs, 4000);
126   InitializeCriticalSection(&MSVCRT_file_cs);
127   InitializeCriticalSection(&MSVCRT_exit_cs);
128   InitializeCriticalSection(&MSVCRT_console_cs);
129   InitializeCriticalSection(&MSVCRT_locale_cs);
130 }
131
132 static inline void MSVCRT_free_critical_sections(void)
133 {
134   DeleteCriticalSection(&MSVCRT_locale_cs);
135   DeleteCriticalSection(&MSVCRT_console_cs);
136   DeleteCriticalSection(&MSVCRT_exit_cs);
137   DeleteCriticalSection(&MSVCRT_file_cs);
138   DeleteCriticalSection(&MSVCRT_heap_cs);
139 }
140
141 const char *MSVCRT_get_reason(DWORD reason)
142 {
143   switch (reason)
144   {
145   case DLL_PROCESS_ATTACH: return "DLL_PROCESS_ATTACH";
146   case DLL_PROCESS_DETACH: return "DLL_PROCESS_DETACH";
147   case DLL_THREAD_ATTACH:  return "DLL_THREAD_ATTACH";
148   case DLL_THREAD_DETACH:  return "DLL_THREAD_DETACH";
149   }
150   return "UNKNOWN";
151 }
152
153
154 /*********************************************************************
155  *                  Fixup functions
156  *
157  * Anything 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 void MSVCRT___unDName(void)
165 {
166   /* Called by all VC compiled progs on startup. No idea what it does */
167 }
168
169 void MSVCRT___unDNameEx(void)
170 {
171   /* As above */
172 }
173