msvcrt: Added wctob implementation.
[wine] / dlls / msvcr90 / msvcr90.c
1 /*
2  * msvcr90 specific functions
3  *
4  * Copyright 2010 Detlef Riekenberg
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22 #include <stdarg.h>
23
24 #include "stdlib.h"
25 #include "errno.h"
26 #include "malloc.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wine/debug.h"
30 #include "sys/stat.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(msvcr90);
33
34 #ifdef __i386__  /* thiscall functions are i386-specific */
35
36 #define THISCALL(func) __thiscall_ ## func
37 #define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func)
38 #define __thiscall __stdcall
39 #define DEFINE_THISCALL_WRAPPER(func,args) \
40     extern void THISCALL(func)(void); \
41     __ASM_GLOBAL_FUNC(__thiscall_ ## func, \
42                       "popl %eax\n\t" \
43                       "pushl %ecx\n\t" \
44                       "pushl %eax\n\t" \
45                       "jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
46
47 #else /* __i386__ */
48
49 #define THISCALL(func) func
50 #define THISCALL_NAME(func) __ASM_NAME(#func)
51 #define __thiscall __cdecl
52 #define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
53
54 #endif /* __i386__ */
55
56 struct __type_info_node
57 {
58     void *memPtr;
59     struct __type_info_node* next;
60 };
61
62 typedef struct __type_info
63 {
64   const void *vtable;
65   char       *name;        /* Unmangled name, allocated lazily */
66   char        mangled[32]; /* Variable length, but we declare it large enough for static RTTI */
67 } type_info;
68
69 typedef void* (*__cdecl malloc_func_t)(size_t);
70 typedef void  (*__cdecl free_func_t)(void*);
71
72 extern char* __cdecl __unDName(char *,const char*,int,malloc_func_t,free_func_t,unsigned short int);
73
74 /*********************************************************************
75  *  msvcr90_stat64_to_stat32 [internal]
76  */
77 static void msvcr90_stat64_to_stat32(const struct _stat64 *buf64, struct _stat32 *buf)
78 {
79     buf->st_dev   = buf64->st_dev;
80     buf->st_ino   = buf64->st_ino;
81     buf->st_mode  = buf64->st_mode;
82     buf->st_nlink = buf64->st_nlink;
83     buf->st_uid   = buf64->st_uid;
84     buf->st_gid   = buf64->st_gid;
85     buf->st_rdev  = buf64->st_rdev;
86     buf->st_size  = buf64->st_size;
87     buf->st_atime = buf64->st_atime;
88     buf->st_mtime = buf64->st_mtime;
89     buf->st_ctime = buf64->st_ctime;
90 }
91
92 /*********************************************************************
93  *  DllMain (MSVCR90.@)
94  */
95 BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
96 {
97     switch (reason)
98     {
99     case DLL_WINE_PREATTACH:
100         return FALSE;  /* prefer native version */
101
102     case DLL_PROCESS_ATTACH:
103         DisableThreadLibraryCalls(hdll);
104     }
105     return TRUE;
106 }
107
108 /*********************************************************************
109  *  _decode_pointer (MSVCR90.@)
110  *
111  * cdecl version of DecodePointer
112  *
113  */
114 void * CDECL MSVCR90_decode_pointer(void * ptr)
115 {
116     return DecodePointer(ptr);
117 }
118
119 /*********************************************************************
120  *  _encode_pointer (MSVCR90.@)
121  *
122  * cdecl version of EncodePointer
123  *
124  */
125 void * CDECL MSVCR90_encode_pointer(void * ptr)
126 {
127     return EncodePointer(ptr);
128 }
129
130 /*********************************************************************
131  *  _encoded_null (MSVCR90.@)
132  */
133 void * CDECL _encoded_null(void)
134 {
135     TRACE("\n");
136
137     return MSVCR90_encode_pointer(NULL);
138 }
139
140 /*********************************************************************
141  * _invalid_parameter_noinfo (MSVCR90.@)
142  */
143 void CDECL _invalid_parameter_noinfo(void)
144 {
145     _invalid_parameter( NULL, NULL, NULL, 0, 0 );
146 }
147
148 /*********************************************************************
149  * __sys_nerr (MSVCR90.@)
150  */
151 int* CDECL __sys_nerr(void)
152 {
153         return (int*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_sys_nerr");
154 }
155
156 /*********************************************************************
157  *  __sys_errlist (MSVCR90.@)
158  */
159 char** CDECL __sys_errlist(void)
160 {
161     return (char**)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_sys_errlist");
162 }
163
164 /*********************************************************************
165  * __clean_type_info_names_internal (MSVCR90.@)
166  */
167 void CDECL __clean_type_info_names_internal(void *p)
168 {
169     FIXME("(%p) stub\n", p);
170 }
171
172 /*********************************************************************
173  * _recalloc (MSVCR90.@)
174  */
175 void* CDECL _recalloc(void* mem, size_t num, size_t size)
176 {
177     size_t old_size;
178     void *ret;
179
180     if(!mem)
181         return calloc(num, size);
182
183     size = num*size;
184     old_size = _msize(mem);
185
186     ret = realloc(mem, size);
187     if(!ret) {
188         *_errno() = ENOMEM;
189         return NULL;
190     }
191
192     if(size>old_size)
193         memset((BYTE*)mem+old_size, 0, size-old_size);
194     return ret;
195 }
196
197 /*********************************************************************
198  *  _fstat32 (MSVCR90.@)
199  */
200 int CDECL _fstat32(int fd, struct _stat32* buf)
201 {
202   int ret;
203   struct _stat64 buf64;
204
205   ret = _fstat64(fd, &buf64);
206   if (!ret)
207       msvcr90_stat64_to_stat32(&buf64, buf);
208   return ret;
209 }
210
211 /*********************************************************************
212  *  _stat32 (MSVCR90.@)
213  */
214 int CDECL _stat32(const char *path, struct _stat32* buf)
215 {
216   int ret;
217   struct _stat64 buf64;
218
219   ret = _stat64(path, &buf64);
220   if (!ret)
221       msvcr90_stat64_to_stat32(&buf64, buf);
222   return ret;
223 }
224
225 /*********************************************************************
226  *  _wstat32 (MSVCR90.@)
227  */
228 int CDECL _wstat32(const wchar_t *path, struct _stat32* buf)
229 {
230   int ret;
231   struct _stat64 buf64;
232
233   ret = _wstat64(path, &buf64);
234   if (!ret)
235       msvcr90_stat64_to_stat32(&buf64, buf);
236   return ret;
237 }
238
239 /*********************************************************************
240  *              _fstat64i32 (MSVCRT.@)
241  */
242
243 static void msvcrt_stat64_to_stat64i32(const struct _stat64 *buf64, struct _stat64i32 *buf)
244 {
245     buf->st_dev   = buf64->st_dev;
246     buf->st_ino   = buf64->st_ino;
247     buf->st_mode  = buf64->st_mode;
248     buf->st_nlink = buf64->st_nlink;
249     buf->st_uid   = buf64->st_uid;
250     buf->st_gid   = buf64->st_gid;
251     buf->st_rdev  = buf64->st_rdev;
252     buf->st_size  = buf64->st_size;
253     buf->st_atime = buf64->st_atime;
254     buf->st_mtime = buf64->st_mtime;
255     buf->st_ctime = buf64->st_ctime;
256 }
257
258 int CDECL _fstat64i32(int fd, struct _stat64i32* buf)
259 {
260   int ret;
261   struct _stat64 buf64;
262
263   ret = _fstat64(fd, &buf64);
264   if (!ret)
265       msvcrt_stat64_to_stat64i32(&buf64, buf);
266   return ret;
267 }
268
269 /*********************************************************************
270  *              _stat64i32 (MSVCRT.@)
271  */
272 int CDECL _stat64i32(const char* path, struct _stat64i32 * buf)
273 {
274   int ret;
275   struct _stat64 buf64;
276
277   ret = _stat64(path, &buf64);
278   if (!ret)
279     msvcrt_stat64_to_stat64i32(&buf64, buf);
280   return ret;
281 }
282
283 /*********************************************************************
284  *              _wstat64i32 (MSVCRT.@)
285  */
286 int CDECL _wstat64i32(const wchar_t *path, struct _stat64i32 *buf)
287 {
288     int ret;
289     struct _stat64 buf64;
290
291     ret = _wstat64(path, &buf64);
292     if (!ret)
293         msvcrt_stat64_to_stat64i32(&buf64, buf);
294     return ret;
295 }
296
297 /*********************************************************************
298  *              _atoflt  (MSVCR90.@)
299  */
300 int CDECL _atoflt( _CRT_FLOAT *value, char *str )
301 {
302     return _atoflt_l( value, str, NULL );
303 }
304
305 /*********************************************************************
306  * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR90.@)
307  */
308 DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name_internal_method,8)
309 const char * __thiscall MSVCRT_type_info_name_internal_method(type_info * _this, struct __type_info_node *node)
310 {
311     static int once;
312
313     if (node && !once++) FIXME("type_info_node parameter ignored\n");
314
315     if (!_this->name)
316     {
317       /* Create and set the demangled name */
318       /* Note: mangled name in type_info struct always starts with a '.', while
319        * it isn't valid for mangled name.
320        * Is this '.' really part of the mangled name, or has it some other meaning ?
321        */
322       char* name = __unDName(0, _this->mangled + 1, 0, malloc, free, 0x2800);
323       if (name)
324       {
325         unsigned int len = strlen(name);
326
327         /* It seems _unDName may leave blanks at the end of the demangled name */
328         while (len && name[--len] == ' ')
329           name[len] = '\0';
330
331         if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL))
332         {
333           /* Another thread set this member since we checked above - use it */
334           free(name);
335         }
336       }
337     }
338     TRACE("(%p) returning %s\n", _this, _this->name);
339     return _this->name;
340 }
341
342 /*********************************************************************
343  *              _CRT_RTC_INIT (MSVCR90.@)
344  */
345 void* CDECL _CRT_RTC_INIT(void *unk1, void *unk2, int unk3, int unk4, int unk5)
346 {
347     TRACE("%p %p %x %x %x\n", unk1, unk2, unk3, unk4, unk5);
348     return NULL;
349 }
350
351 /*********************************************************************
352  *              _CRT_RTC_INITW (MSVCR90.@)
353  */
354 void* CDECL _CRT_RTC_INITW(void *unk1, void *unk2, int unk3, int unk4, int unk5)
355 {
356     TRACE("%p %p %x %x %x\n", unk1, unk2, unk3, unk4, unk5);
357     return NULL;
358 }