Added regedit unit test, a couple minor changes to regedit.
[wine] / dlls / msvcrt / main.c
1 /*
2  * msvcrt.dll initialisation functions
3  *
4  * Copyright 2000 Jon Griffiths
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include "msvcrt.h"
21
22 #include "msvcrt/locale.h"
23 #include "msvcrt/stdio.h"
24
25 #include "wine/debug.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
28
29 /* Index to TLS */
30 DWORD MSVCRT_tls_index;
31
32 static inline BOOL msvcrt_init_tls(void);
33 static inline BOOL msvcrt_free_tls(void);
34 const char* msvcrt_get_reason(DWORD reason) WINE_UNUSED;
35
36 void msvcrt_init_io(void);
37 void msvcrt_init_console(void);
38 void msvcrt_free_console(void);
39 void msvcrt_init_args(void);
40 void msvcrt_free_args(void);
41 void msvcrt_init_vtables(void);
42
43 typedef void* (*MSVCRT_malloc_func)(unsigned int);
44 typedef void (*MSVCRT_free_func)(void*);
45
46 /*********************************************************************
47  *                  Init
48  */
49 BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
50 {
51   MSVCRT_thread_data *tls;
52
53   TRACE("(0x%08x, %s, %p) pid(%ld), tid(%ld), tls(%ld)\n",
54         hinstDLL, msvcrt_get_reason(fdwReason), lpvReserved,
55         (long)GetCurrentProcessId(), (long)GetCurrentThreadId(),
56         (long)MSVCRT_tls_index);
57
58   switch (fdwReason)
59   {
60   case DLL_PROCESS_ATTACH:
61     if (!msvcrt_init_tls())
62       return FALSE;
63     msvcrt_init_mt_locks();
64     msvcrt_init_vtables();
65     msvcrt_init_io();
66     msvcrt_init_console();
67     msvcrt_init_args();
68     MSVCRT_setlocale(0, "C");
69     TRACE("finished process init\n");
70     /* FALL THROUGH for Initial TLS allocation!! */
71   case DLL_THREAD_ATTACH:
72     TRACE("starting thread init\n");
73     /* Create TLS */
74     tls = (MSVCRT_thread_data*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
75                                           sizeof(MSVCRT_thread_data));
76     if (!tls || !TlsSetValue(MSVCRT_tls_index, tls))
77     {
78       ERR("TLS init failed! error = %ld\n", GetLastError());
79       return FALSE;
80     }
81     TRACE("finished thread init\n");
82     break;
83   case DLL_PROCESS_DETACH:
84     msvcrt_free_mt_locks();
85     _fcloseall();
86     msvcrt_free_console();
87     msvcrt_free_args();
88     if (!msvcrt_free_tls())
89       return FALSE;
90     TRACE("finished process free\n");
91     break;
92   case DLL_THREAD_DETACH:
93     /* Free TLS */
94     tls = TlsGetValue(MSVCRT_tls_index);
95
96     if (!tls)
97     {
98       ERR("TLS free failed! error = %ld\n", GetLastError());
99       return FALSE;
100     }
101     HeapFree(GetProcessHeap(), 0, tls);
102     TRACE("finished thread free\n");
103     break;
104   }
105   return TRUE;
106 }
107
108 static inline BOOL msvcrt_init_tls(void)
109 {
110   MSVCRT_tls_index = TlsAlloc();
111
112   if (MSVCRT_tls_index == TLS_OUT_OF_INDEXES)
113   {
114     ERR("TlsAlloc() failed!\n");
115     return FALSE;
116   }
117   return TRUE;
118 }
119
120 static inline BOOL msvcrt_free_tls(void)
121 {
122   if (!TlsFree(MSVCRT_tls_index))
123   {
124     ERR("TlsFree() failed!\n");
125     return FALSE;
126   }
127   return TRUE;
128 }
129
130 const char* msvcrt_get_reason(DWORD reason)
131 {
132   switch (reason)
133   {
134   case DLL_PROCESS_ATTACH: return "DLL_PROCESS_ATTACH";
135   case DLL_PROCESS_DETACH: return "DLL_PROCESS_DETACH";
136   case DLL_THREAD_ATTACH:  return "DLL_THREAD_ATTACH";
137   case DLL_THREAD_DETACH:  return "DLL_THREAD_DETACH";
138   }
139   return "UNKNOWN";
140 }
141
142
143 /*********************************************************************
144  *              $I10_OUTPUT (MSVCRT.@)
145  * Function not really understood but needed to make the DLL work
146  */
147 void MSVCRT_I10_OUTPUT(void)
148 {
149   /* FIXME: This is probably data, not a function */
150 }
151
152
153 /*********************************************************************
154  *              __unDName (MSVCRT.@)
155  * Function not really understood but needed to make the DLL work
156  */
157 char* MSVCRT___unDName(int unknown, const char* mangled,
158                        MSVCRT_malloc_func memget,
159                        MSVCRT_free_func memfree,
160                        unsigned int flags)
161 {
162   char* ret;
163
164   FIXME("(%d,%s,%p,%p,%x) stub!\n", unknown, mangled, memget, memfree, flags);
165
166   /* Experimentation reveals the following flag meanings when set:
167    * 0x0001 - Dont show __ in calling convention
168    * 0x0002 - Dont show calling convention at all
169    * 0x0004 - Dont show function/method return value
170    * 0x0010 - Same as 0x1
171    * 0x0080 - Dont show access specifier (public/protected/private)
172    * 0x0200 - Dont show static specifier
173    * 0x1000 - Only report the variable/class name
174    */
175   /* Duplicate the mangled name; for comparisons it doesn't matter anyway */
176   ret = memget(strlen(mangled) + 1);
177   strcpy(ret, mangled);
178   return ret;
179 }
180
181
182 /*********************************************************************
183  *              __unDNameEx (MSVCRT.@)
184  * Function not really understood but needed to make the DLL work
185  */
186 char* MSVCRT___unDNameEx(void)
187 {
188    return NULL;
189 }