2 * msvcr100 specific functions
4 * Copyright 2010 Detlef Riekenberg
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.
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.
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
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt
);
36 #define INVALID_PMT(x,err) (*_errno() = (err), _invalid_parameter(NULL, NULL, NULL, 0, 0))
37 #define CHECK_PMT_ERR(x,err) ((x) || (INVALID_PMT( 0, (err) ), FALSE))
38 #define CHECK_PMT(x) CHECK_PMT_ERR((x), EINVAL)
40 #ifdef __i386__ /* thiscall functions are i386-specific */
42 #define THISCALL(func) __thiscall_ ## func
43 #define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func)
44 #define __thiscall __stdcall
45 #define DEFINE_THISCALL_WRAPPER(func,args) \
46 extern void THISCALL(func)(void); \
47 __ASM_GLOBAL_FUNC(__thiscall_ ## func, \
51 "jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
55 #define THISCALL(func) func
56 #define THISCALL_NAME(func) __ASM_NAME(#func)
57 #define __thiscall __cdecl
58 #define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
62 struct __type_info_node
65 struct __type_info_node
* next
;
68 typedef struct __type_info
71 char *name
; /* Unmangled name, allocated lazily */
72 char mangled
[32]; /* Variable length, but we declare it large enough for static RTTI */
75 typedef void* (__cdecl
*malloc_func_t
)(size_t);
76 typedef void (__cdecl
*free_func_t
)(void*);
78 extern char* __cdecl
__unDName(char *,const char*,int,malloc_func_t
,free_func_t
,unsigned short int);
80 /*********************************************************************
81 * * stat64_to_stat32 [internal]
83 static void stat64_to_stat32(const struct _stat64
*buf64
, struct _stat32
*buf
)
85 buf
->st_dev
= buf64
->st_dev
;
86 buf
->st_ino
= buf64
->st_ino
;
87 buf
->st_mode
= buf64
->st_mode
;
88 buf
->st_nlink
= buf64
->st_nlink
;
89 buf
->st_uid
= buf64
->st_uid
;
90 buf
->st_gid
= buf64
->st_gid
;
91 buf
->st_rdev
= buf64
->st_rdev
;
92 buf
->st_size
= buf64
->st_size
;
93 buf
->st_atime
= buf64
->st_atime
;
94 buf
->st_mtime
= buf64
->st_mtime
;
95 buf
->st_ctime
= buf64
->st_ctime
;
98 /*********************************************************************
99 * wmemcpy_s (MSVCR100.@)
101 int CDECL
wmemcpy_s(wchar_t *dest
, size_t numberOfElements
, const wchar_t *src
, size_t count
)
103 TRACE("(%p %lu %p %lu)\n", dest
, (unsigned long)numberOfElements
, src
, (unsigned long)count
);
108 if (!CHECK_PMT(dest
!= NULL
)) return EINVAL
;
110 if (!CHECK_PMT(src
!= NULL
)) {
111 memset(dest
, 0, numberOfElements
*sizeof(wchar_t));
114 if (!CHECK_PMT_ERR(count
<= numberOfElements
, ERANGE
)) {
115 memset(dest
, 0, numberOfElements
*sizeof(wchar_t));
119 memcpy(dest
, src
, sizeof(wchar_t)*count
);
123 /*********************************************************************
124 * wmemmove_s (MSVCR100.@)
126 int CDECL
wmemmove_s(wchar_t *dest
, size_t numberOfElements
, const wchar_t *src
, size_t count
)
128 TRACE("(%p %lu %p %lu)\n", dest
, (unsigned long)numberOfElements
, src
, (unsigned long)count
);
133 /* Native does not seem to conform to 6.7.1.2.3 in
134 * http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1225.pdf
135 * in that it does not zero the output buffer on constraint violation.
137 if (!CHECK_PMT(dest
!= NULL
)) return EINVAL
;
138 if (!CHECK_PMT(src
!= NULL
)) return EINVAL
;
139 if (!CHECK_PMT_ERR(count
<= numberOfElements
, ERANGE
)) return ERANGE
;
141 memmove(dest
, src
, sizeof(wchar_t)*count
);
145 /*********************************************************************
146 * _encoded_null (MSVCR100.@)
148 void * CDECL
_encoded_null(void)
152 return EncodePointer(NULL
);
155 /*********************************************************************
156 * _invalid_parameter_noinfo (MSVCR100.@)
158 void CDECL
_invalid_parameter_noinfo(void)
160 _invalid_parameter( NULL
, NULL
, NULL
, 0, 0 );
163 /*********************************************************************
164 * __sys_nerr (MSVCR100.@)
166 int* CDECL
__sys_nerr(void)
168 return (int*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_sys_nerr");
171 /*********************************************************************
172 * __sys_errlist (MSVCR100.@)
174 char** CDECL
__sys_errlist(void)
176 return (char**)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_sys_errlist");
179 /*********************************************************************
180 * __clean_type_info_names_internal (MSVCR100.@)
182 void CDECL
__clean_type_info_names_internal(void *p
)
184 FIXME("(%p) stub\n", p
);
187 /*********************************************************************
188 * _recalloc (MSVCR100.@)
190 void* CDECL
_recalloc(void* mem
, size_t num
, size_t size
)
196 return calloc(num
, size
);
199 old_size
= _msize(mem
);
201 ret
= realloc(mem
, size
);
208 memset((BYTE
*)ret
+old_size
, 0, size
-old_size
);
212 /*********************************************************************
213 * _fstat32 (MSVCR100.@)
215 int CDECL
_fstat32(int fd
, struct _stat32
* buf
)
218 struct _stat64 buf64
;
220 ret
= _fstat64(fd
, &buf64
);
222 stat64_to_stat32(&buf64
, buf
);
226 /*********************************************************************
227 * _stat32 (MSVCR100.@)
229 int CDECL
_stat32(const char *path
, struct _stat32
* buf
)
232 struct _stat64 buf64
;
234 ret
= _stat64(path
, &buf64
);
236 stat64_to_stat32(&buf64
, buf
);
240 /*********************************************************************
241 * _wstat32 (MSVCR100.@)
243 int CDECL
_wstat32(const wchar_t *path
, struct _stat32
* buf
)
246 struct _stat64 buf64
;
248 ret
= _wstat64(path
, &buf64
);
250 stat64_to_stat32(&buf64
, buf
);
254 static void stat64_to_stat32i64(const struct _stat64
*buf64
, struct _stat32i64
*buf
)
256 buf
->st_dev
= buf64
->st_dev
;
257 buf
->st_ino
= buf64
->st_ino
;
258 buf
->st_mode
= buf64
->st_mode
;
259 buf
->st_nlink
= buf64
->st_nlink
;
260 buf
->st_uid
= buf64
->st_uid
;
261 buf
->st_gid
= buf64
->st_gid
;
262 buf
->st_rdev
= buf64
->st_rdev
;
263 buf
->st_size
= buf64
->st_size
;
264 buf
->st_atime
= buf64
->st_atime
;
265 buf
->st_mtime
= buf64
->st_mtime
;
266 buf
->st_ctime
= buf64
->st_ctime
;
269 /*********************************************************************
270 * _stat32i64 (MSVCR100.@)
272 int CDECL
_stat32i64(const char *path
, struct _stat32i64
* buf
)
275 struct _stat64 buf64
;
277 ret
= _stat64(path
, &buf64
);
279 stat64_to_stat32i64(&buf64
, buf
);
283 /*********************************************************************
284 * _wstat32i64 (MSVCR100.@)
286 int CDECL
_wstat32i64(const wchar_t *path
, struct _stat32i64
* buf
)
289 struct _stat64 buf64
;
291 ret
= _wstat64(path
, &buf64
);
293 stat64_to_stat32i64(&buf64
, buf
);
297 static void stat64_to_stat64i32(const struct _stat64
*buf64
, struct _stat64i32
*buf
)
299 buf
->st_dev
= buf64
->st_dev
;
300 buf
->st_ino
= buf64
->st_ino
;
301 buf
->st_mode
= buf64
->st_mode
;
302 buf
->st_nlink
= buf64
->st_nlink
;
303 buf
->st_uid
= buf64
->st_uid
;
304 buf
->st_gid
= buf64
->st_gid
;
305 buf
->st_rdev
= buf64
->st_rdev
;
306 buf
->st_size
= buf64
->st_size
;
307 buf
->st_atime
= buf64
->st_atime
;
308 buf
->st_mtime
= buf64
->st_mtime
;
309 buf
->st_ctime
= buf64
->st_ctime
;
312 /*********************************************************************
313 * _fstat64i32 (MSVCR100.@)
315 int CDECL
_fstat64i32(int fd
, struct _stat64i32
* buf
)
318 struct _stat64 buf64
;
320 ret
= _fstat64(fd
, &buf64
);
322 stat64_to_stat64i32(&buf64
, buf
);
326 /*********************************************************************
327 * _stat64i32 (MSVCR100.@)
329 int CDECL
_stat64i32(const char* path
, struct _stat64i32
* buf
)
332 struct _stat64 buf64
;
334 ret
= _stat64(path
, &buf64
);
336 stat64_to_stat64i32(&buf64
, buf
);
340 /*********************************************************************
341 * _wstat64i32 (MSVCR100.@)
343 int CDECL
_wstat64i32(const wchar_t *path
, struct _stat64i32
*buf
)
346 struct _stat64 buf64
;
348 ret
= _wstat64(path
, &buf64
);
350 stat64_to_stat64i32(&buf64
, buf
);
354 /*********************************************************************
355 * _atoflt (MSVCR100.@)
357 int CDECL
_atoflt( _CRT_FLOAT
*value
, char *str
)
359 return _atoflt_l( value
, str
, NULL
);
362 /*********************************************************************
363 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@)
365 DEFINE_THISCALL_WRAPPER(type_info_name_internal_method
,8)
366 const char * __thiscall
type_info_name_internal_method(type_info
* _this
, struct __type_info_node
*node
)
370 if (node
&& !once
++) FIXME("type_info_node parameter ignored\n");
374 /* Create and set the demangled name */
375 /* Note: mangled name in type_info struct always starts with a '.', while
376 * it isn't valid for mangled name.
377 * Is this '.' really part of the mangled name, or has it some other meaning ?
379 char* name
= __unDName(0, _this
->mangled
+ 1, 0, malloc
, free
, 0x2800);
382 unsigned int len
= strlen(name
);
384 /* It seems _unDName may leave blanks at the end of the demangled name */
385 while (len
&& name
[--len
] == ' ')
388 if (InterlockedCompareExchangePointer((void**)&_this
->name
, name
, NULL
))
390 /* Another thread set this member since we checked above - use it */
395 TRACE("(%p) returning %s\n", _this
, _this
->name
);
399 /*********************************************************************
400 * _CRT_RTC_INIT (MSVCR100.@)
402 void* CDECL
_CRT_RTC_INIT(void *unk1
, void *unk2
, int unk3
, int unk4
, int unk5
)
404 TRACE("%p %p %x %x %x\n", unk1
, unk2
, unk3
, unk4
, unk5
);
408 /*********************************************************************
409 * _CRT_RTC_INITW (MSVCR100.@)
411 void* CDECL
_CRT_RTC_INITW(void *unk1
, void *unk2
, int unk3
, int unk4
, int unk5
)
413 TRACE("%p %p %x %x %x\n", unk1
, unk2
, unk3
, unk4
, unk5
);
417 /*********************************************************************
418 * _vswprintf_p (MSVCR100.@)
420 int CDECL
_vswprintf_p(wchar_t *buffer
, size_t length
, const wchar_t *format
, __ms_va_list args
)
422 return _vswprintf_p_l(buffer
, length
, format
, NULL
, args
);
425 /*********************************************************************
426 * _byteswap_ushort (MSVCR100.@)
428 unsigned short CDECL
_byteswap_ushort(unsigned short s
)
430 return (s
<<8) + (s
>>8);
433 /*********************************************************************
434 * _byteswap_ulong (MSVCR100.@)
436 ULONG CDECL
_byteswap_ulong(ULONG l
)
438 return (l
<<24) + ((l
<<8)&0xFF0000) + ((l
>>8)&0xFF00) + (l
>>24);
441 /*********************************************************************
442 * _byteswap_uint64 (MSVCR100.@)
444 unsigned __int64 CDECL
_byteswap_uint64(unsigned __int64 i
)
446 return (i
<<56) + ((i
&0xFF00)<<40) + ((i
&0xFF0000)<<24) + ((i
&0xFF000000)<<8) +
447 ((i
>>8)&0xFF000000) + ((i
>>24)&0xFF0000) + ((i
>>40)&0xFF00) + (i
>>56);
450 /*********************************************************************
451 * fread_s (MSVCR100.@)
453 size_t CDECL
fread_s(void *buf
, size_t buf_size
, size_t elem_size
, size_t count
, FILE *stream
)
455 size_t bytes_left
, buf_pos
;
457 TRACE("(%p %lu %lu %lu %p\n", buf
, (unsigned long)buf_size
,
458 (unsigned long)elem_size
, (unsigned long)count
, stream
);
461 if(!CHECK_PMT(stream
!= NULL
)) {
463 memset(buf
, 0, buf_size
);
466 if(!elem_size
|| !count
) return 0;
467 if(!CHECK_PMT(buf
!= NULL
)) return 0;
468 if(!CHECK_PMT(SIZE_MAX
/count
>= elem_size
)) return 0;
470 bytes_left
= elem_size
*count
;
473 if(stream
->_cnt
> 0) {
474 size_t size
= bytes_left
<stream
->_cnt
? bytes_left
: stream
->_cnt
;
476 if(!CHECK_PMT_ERR(size
<= buf_size
-buf_pos
, ERANGE
)) {
477 memset(buf
, 0, buf_size
);
481 fread((char*)buf
+buf_pos
, 1, size
, stream
);
485 int c
= _filbuf(stream
);
490 if(!CHECK_PMT_ERR(buf_size
-buf_pos
> 0, ERANGE
)) {
491 memset(buf
, 0, buf_size
);
495 ((char*)buf
)[buf_pos
++] = c
;
500 return buf_pos
/elem_size
;
503 /*********************************************************************
504 * _sprintf_p (MSVCR100.@)
506 int CDECL
_sprintf_p(char *buffer
, size_t length
, const char *format
, ...)
511 __ms_va_start(valist
, format
);
512 r
= _vsprintf_p_l(buffer
, length
, format
, NULL
, valist
);
518 /*********************************************************************
519 * _get_timezone (MSVCR100.@)
521 int CDECL
_get_timezone(LONG
*timezone
)
523 if(!CHECK_PMT(timezone
!= NULL
)) return EINVAL
;
525 *timezone
= *(LONG
*)GetProcAddress(GetModuleHandleA("msvcrt.dll"), "_timezone");
529 /* copied from dlls/msvcrt/heap.c */
530 #define SAVED_PTR(x) ((void *)((DWORD_PTR)((char *)x - sizeof(void *)) & \
531 ~(sizeof(void *) - 1)))
533 /*********************************************************************
534 * _aligned_msize (MSVCR100.@)
536 size_t CDECL
_aligned_msize(void *p
, size_t alignment
, size_t offset
)
540 if(!CHECK_PMT(p
)) return -1;
542 if(alignment
< sizeof(void*))
543 alignment
= sizeof(void*);
545 alloc_ptr
= SAVED_PTR(p
);
546 return _msize(*alloc_ptr
)-alignment
-sizeof(void*);
549 /*********************************************************************
550 * DllMain (MSVCR100.@)
552 BOOL WINAPI
DllMain(HINSTANCE hdll
, DWORD reason
, LPVOID reserved
)
556 case DLL_WINE_PREATTACH
:
557 return FALSE
; /* prefer native version */
559 case DLL_PROCESS_ATTACH
:
560 DisableThreadLibraryCalls(hdll
);
561 _set_printf_count_output(0);