Added an unknown VxD error code.
[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/stdio.h"
9
10
11 DEFAULT_DEBUG_CHANNEL(msvcrt);
12
13 /* Index to TLS */
14 DWORD MSVCRT_tls_index;
15
16 /* MT locks */
17 CRITICAL_SECTION MSVCRT_heap_cs;
18 CRITICAL_SECTION MSVCRT_file_cs;
19 CRITICAL_SECTION MSVCRT_exit_cs;
20 CRITICAL_SECTION MSVCRT_console_cs;
21 CRITICAL_SECTION MSVCRT_locale_cs;
22
23 static inline BOOL msvcrt_init_tls(void);
24 static inline BOOL msvcrt_free_tls(void);
25 static inline void msvcrt_init_critical_sections(void);
26 static inline void msvcrt_free_critical_sections(void);
27 const char* msvcrt_get_reason(DWORD reason) WINE_UNUSED;
28
29 void msvcrt_init_io(void);
30 void msvcrt_init_console(void);
31 void msvcrt_free_console(void);
32 void msvcrt_init_args(void);
33 void msvcrt_free_args(void);
34 void msvcrt_init_vtables(void);
35 char* MSVCRT_setlocale(int category, const char* locale);
36
37
38 /*********************************************************************
39  *                  Init
40  */
41 BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
42 {
43   MSVCRT_thread_data *tls;
44
45   TRACE("(0x%08x, %s, %p) pid(%ld), tid(%ld), tls(%ld)\n",
46         hinstDLL, msvcrt_get_reason(fdwReason), lpvReserved,
47         (long)GetCurrentProcessId(), (long)GetCurrentThreadId(),
48         (long)MSVCRT_tls_index);
49
50   switch (fdwReason)
51   {
52   case DLL_PROCESS_ATTACH:
53     if (!msvcrt_init_tls())
54       return FALSE;
55     msvcrt_init_vtables();
56     msvcrt_init_critical_sections();
57     msvcrt_init_io();
58     msvcrt_init_console();
59     msvcrt_init_args();
60     MSVCRT_setlocale(0, "C");
61     TRACE("finished process init\n");
62     /* FALL THROUGH for Initial TLS allocation!! */
63   case DLL_THREAD_ATTACH:
64     TRACE("starting thread init\n");
65     /* Create TLS */
66     tls = (MSVCRT_thread_data*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
67                                           sizeof(MSVCRT_thread_data));
68     if (!tls || !TlsSetValue(MSVCRT_tls_index, tls))
69     {
70       ERR("TLS init failed! error = %ld\n", GetLastError());
71       return FALSE;
72     }
73     TRACE("finished thread init\n");
74     break;
75   case DLL_PROCESS_DETACH:
76     msvcrt_free_critical_sections();
77     _fcloseall();
78     msvcrt_free_console();
79     msvcrt_free_args();
80     if (!msvcrt_free_tls())
81       return FALSE;
82     TRACE("finished process free\n");
83     break;
84   case DLL_THREAD_DETACH:
85     /* Free TLS */
86     tls = TlsGetValue(MSVCRT_tls_index);
87
88     if (!tls)
89     {
90       ERR("TLS free failed! error = %ld\n", GetLastError());
91       return FALSE;
92     }
93     HeapFree(GetProcessHeap(), 0, tls);
94     TRACE("finished thread free\n");
95     break;
96   }
97   return TRUE;
98 }
99
100 static inline BOOL msvcrt_init_tls(void)
101 {
102   MSVCRT_tls_index = TlsAlloc();
103
104   if (MSVCRT_tls_index == TLS_OUT_OF_INDEXES)
105   {
106     ERR("TlsAlloc() failed!\n");
107     return FALSE;
108   }
109   return TRUE;
110 }
111
112 static inline BOOL msvcrt_free_tls(void)
113 {
114   if (!TlsFree(MSVCRT_tls_index))
115   {
116     ERR("TlsFree() failed!\n");
117     return FALSE;
118   }
119   return TRUE;
120 }
121
122 static inline void msvcrt_init_critical_sections(void)
123 {
124   InitializeCriticalSectionAndSpinCount(&MSVCRT_heap_cs, 4000);
125   InitializeCriticalSection(&MSVCRT_file_cs);
126   InitializeCriticalSection(&MSVCRT_exit_cs);
127   InitializeCriticalSection(&MSVCRT_console_cs);
128   InitializeCriticalSection(&MSVCRT_locale_cs);
129 }
130
131 static inline void msvcrt_free_critical_sections(void)
132 {
133   DeleteCriticalSection(&MSVCRT_locale_cs);
134   DeleteCriticalSection(&MSVCRT_console_cs);
135   DeleteCriticalSection(&MSVCRT_exit_cs);
136   DeleteCriticalSection(&MSVCRT_file_cs);
137   DeleteCriticalSection(&MSVCRT_heap_cs);
138 }
139
140 const char* msvcrt_get_reason(DWORD reason)
141 {
142   switch (reason)
143   {
144   case DLL_PROCESS_ATTACH: return "DLL_PROCESS_ATTACH";
145   case DLL_PROCESS_DETACH: return "DLL_PROCESS_DETACH";
146   case DLL_THREAD_ATTACH:  return "DLL_THREAD_ATTACH";
147   case DLL_THREAD_DETACH:  return "DLL_THREAD_DETACH";
148   }
149   return "UNKNOWN";
150 }
151
152
153 /*********************************************************************
154  *                  Fixup functions
155  *
156  * Anything not really understood but needed to make the DLL work
157  */
158 void MSVCRT_I10_OUTPUT(void)
159 {
160   /* FIXME: This is probably data, not a function */
161 }
162
163 void MSVCRT___unDName(void)
164 {
165   /* Called by all VC compiled progs on startup. No idea what it does */
166 }
167
168 void MSVCRT___unDNameEx(void)
169 {
170   /* As above */
171 }
172