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