diff --git a/reactos/lib/sdk/crt/crt.rbuild b/reactos/lib/sdk/crt/crt.rbuild index 0fd49d12b1c..7b4bc6fdc72 100644 --- a/reactos/lib/sdk/crt/crt.rbuild +++ b/reactos/lib/sdk/crt/crt.rbuild @@ -329,7 +329,6 @@ gcvt.c getenv.c makepath.c - malloc.c mbtowc.c mbstowcs.c obsol.c diff --git a/reactos/lib/sdk/crt/float/i386/cntrlfp.c b/reactos/lib/sdk/crt/float/i386/cntrlfp.c index 2cc46d8bf4b..75d5c0ad829 100644 --- a/reactos/lib/sdk/crt/float/i386/cntrlfp.c +++ b/reactos/lib/sdk/crt/float/i386/cntrlfp.c @@ -104,3 +104,25 @@ unsigned int CDECL _control87(unsigned int newval, unsigned int mask) return flags; } + +/********************************************************************* + * _controlfp_s (MSVCRT.@) + */ +int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask) +{ +#ifdef __i386__ + unsigned int flags; + + FIXME("(%p %u %u) semi-stub\n", cur, newval, mask); + + flags = _control87( newval, mask & ~_EM_DENORMAL ); + + if(cur) + *cur = flags; + + return 0; +#else + FIXME(":Not Implemented!\n"); + return 0; +#endif +} diff --git a/reactos/lib/sdk/crt/math/rand.c b/reactos/lib/sdk/crt/math/rand.c index f788ecf72ab..4d560a2aac4 100644 --- a/reactos/lib/sdk/crt/math/rand.c +++ b/reactos/lib/sdk/crt/math/rand.c @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include - +//#include #include /* @@ -25,3 +25,18 @@ srand(unsigned int seed) ThreadData->tnext = (ULONGLONG)seed; } + + /********************************************************************* + * rand_s (MSVCRT.@) + */ +int CDECL rand_s(unsigned int *pval) +{ +#if 0 + if (!pval || !RtlGenRandom(pval, sizeof(*pval))) + { + *_errno() = EINVAL; + return EINVAL; + } +#endif + return 0; +} diff --git a/reactos/lib/sdk/crt/misc/stubs.c b/reactos/lib/sdk/crt/misc/stubs.c index 00f4a2b0300..7eac2b0fef9 100644 --- a/reactos/lib/sdk/crt/misc/stubs.c +++ b/reactos/lib/sdk/crt/misc/stubs.c @@ -15,11 +15,6 @@ void MSVCRT_I10_OUTPUT(void) /* FIXME: This is probably data, not a function */ } -void __p__amblksiz(void) -{ - FIXME("__p__amblksiz stub\n"); -} - void __fileinfo(void) { FIXME("__fileinfo stub\n"); diff --git a/reactos/lib/sdk/crt/stdlib/errno.c b/reactos/lib/sdk/crt/stdlib/errno.c index 3a8d76e1be6..6cbd20acb18 100644 --- a/reactos/lib/sdk/crt/stdlib/errno.c +++ b/reactos/lib/sdk/crt/stdlib/errno.c @@ -8,8 +8,11 @@ */ #include #include "doserrmap.h" +#include #include +static _invalid_parameter_handler invalid_parameter_handler = NULL; + /* * @implemented */ @@ -113,4 +116,36 @@ void CDECL _seterrormode(int mode) SetErrorMode( mode ); } +/****************************************************************************** + * _invalid_parameter (MSVCRT.@) + */ +void __cdecl _invalid_parameter(const wchar_t *expr, const wchar_t *func, + const wchar_t *file, unsigned int line, uintptr_t arg) +{ + if (invalid_parameter_handler) invalid_parameter_handler( expr, func, file, line, arg ); + else + { + ERR( "%s:%u %s: %s %lx\n", debugstr_w(file), line, debugstr_w(func), debugstr_w(expr), arg ); + RaiseException( STATUS_INVALID_CRUNTIME_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, NULL ); + } +} + +/* _get_invalid_parameter_handler - not exported in native msvcrt, added in msvcr80 */ +_invalid_parameter_handler CDECL _get_invalid_parameter_handler(void) +{ + TRACE("\n"); + return invalid_parameter_handler; +} + +/* _set_invalid_parameter_handler - not exproted in native msvcrt, added in msvcr80 */ +_invalid_parameter_handler CDECL _set_invalid_parameter_handler( + _invalid_parameter_handler handler) +{ + _invalid_parameter_handler old = invalid_parameter_handler; + + TRACE("(%p)\n", handler); + + invalid_parameter_handler = handler; + return old; +} /* EOF */ diff --git a/reactos/lib/sdk/crt/wine/heap.c b/reactos/lib/sdk/crt/wine/heap.c index daabff8babb..08973706c2b 100644 --- a/reactos/lib/sdk/crt/wine/heap.c +++ b/reactos/lib/sdk/crt/wine/heap.c @@ -15,13 +15,14 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Note: Win32 heap operations are MT safe. We only lock the new * handler and non atomic heap operations */ #include +#include /* MT */ #define LOCK_HEAP _mlock( _HEAP_LOCK ) @@ -29,47 +30,60 @@ /* _aligned */ #define SAVED_PTR(x) ((void *)((DWORD_PTR)((char *)x - sizeof(void *)) & \ - ~(sizeof(void *) - 1))) + ~(sizeof(void *) - 1))) #define ALIGN_PTR(ptr, alignment, offset) ((void *) \ ((((DWORD_PTR)((char *)ptr + alignment + sizeof(void *) + offset)) & \ ~(alignment - 1)) - offset)) -typedef void (*MSVCRT_new_handler_func)(unsigned long size); +typedef void (*MSVCRT_new_handler_func)(size_t size); static MSVCRT_new_handler_func MSVCRT_new_handler; static int MSVCRT_new_mode; +/* FIXME - According to documentation it should be 8*1024, at runtime it returns 16 */ +static unsigned int MSVCRT_amblksiz = 16; /* FIXME - According to documentation it should be 480 bytes, at runtime default is 0 */ static size_t MSVCRT_sbh_threshold = 0; /********************************************************************* * ??2@YAPAXI@Z (MSVCRT.@) */ -void* MSVCRT_operator_new(unsigned long size) +void* CDECL MSVCRT_operator_new(size_t size) { - void *retval = malloc(size); + void *retval = HeapAlloc(GetProcessHeap(), 0, size); TRACE("(%ld) returning %p\n", size, retval); + if(retval) return retval; LOCK_HEAP; - if(!retval && MSVCRT_new_handler) + if(MSVCRT_new_handler) (*MSVCRT_new_handler)(size); UNLOCK_HEAP; return retval; } + +/********************************************************************* + * ??2@YAPAXIHPBDH@Z (MSVCRT.@) + */ +void* CDECL MSVCRT_operator_new_dbg(size_t size, int type, const char *file, int line) +{ + return MSVCRT_operator_new( size ); +} + + /********************************************************************* * ??3@YAXPAX@Z (MSVCRT.@) */ -void MSVCRT_operator_delete(void *mem) +void CDECL MSVCRT_operator_delete(void *mem) { TRACE("(%p)\n", mem); - free(mem); + HeapFree(GetProcessHeap(), 0, mem); } /********************************************************************* * ?_query_new_handler@@YAP6AHI@ZXZ (MSVCRT.@) */ -MSVCRT_new_handler_func MSVCRT__query_new_handler(void) +MSVCRT_new_handler_func CDECL MSVCRT__query_new_handler(void) { return MSVCRT_new_handler; } @@ -78,7 +92,7 @@ MSVCRT_new_handler_func MSVCRT__query_new_handler(void) /********************************************************************* * ?_query_new_mode@@YAHXZ (MSVCRT.@) */ -int MSVCRT__query_new_mode(void) +int CDECL MSVCRT__query_new_mode(void) { return MSVCRT_new_mode; } @@ -86,7 +100,7 @@ int MSVCRT__query_new_mode(void) /********************************************************************* * ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z (MSVCRT.@) */ -MSVCRT_new_handler_func MSVCRT__set_new_handler(MSVCRT_new_handler_func func) +MSVCRT_new_handler_func CDECL MSVCRT__set_new_handler(MSVCRT_new_handler_func func) { MSVCRT_new_handler_func old_handler; LOCK_HEAP; @@ -99,7 +113,7 @@ MSVCRT_new_handler_func MSVCRT__set_new_handler(MSVCRT_new_handler_func func) /********************************************************************* * ?set_new_handler@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) */ -MSVCRT_new_handler_func MSVCRT_set_new_handler(void *func) +MSVCRT_new_handler_func CDECL MSVCRT_set_new_handler(void *func) { TRACE("(%p)\n",func); MSVCRT__set_new_handler(NULL); @@ -109,7 +123,7 @@ MSVCRT_new_handler_func MSVCRT_set_new_handler(void *func) /********************************************************************* * ?_set_new_mode@@YAHH@Z (MSVCRT.@) */ -int MSVCRT__set_new_mode(int mode) +int CDECL MSVCRT__set_new_mode(int mode) { int old_mode; LOCK_HEAP; @@ -119,45 +133,216 @@ int MSVCRT__set_new_mode(int mode) return old_mode; } -int CDECL _callnewh(unsigned long size) +/********************************************************************* + * _callnewh (MSVCRT.@) + */ +int CDECL _callnewh(size_t size) { - if(MSVCRT_new_handler) - (*MSVCRT_new_handler)(size); - return 0; + if(MSVCRT_new_handler) + (*MSVCRT_new_handler)(size); + return 0; } /********************************************************************* - * _get_sbh_threshold (MSVCRT.@) + * _expand (MSVCRT.@) */ -size_t CDECL _get_sbh_threshold(void) +void* CDECL _expand(void* mem, size_t size) { - return MSVCRT_sbh_threshold; + return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, mem, size); } /********************************************************************* - * _set_sbh_threshold (MSVCRT.@) + * _heapchk (MSVCRT.@) */ -int CDECL _set_sbh_threshold(size_t threshold) +int CDECL _heapchk(void) { - if(threshold > 1016) - return 0; - else - MSVCRT_sbh_threshold = threshold; - return 1; + if (!HeapValidate( GetProcessHeap(), 0, NULL)) + { + __set_errno(GetLastError()); + return _HEAPBADNODE; + } + return _HEAPOK; } /********************************************************************* - * _heapadd (MSVCRT.@) + * _heapmin (MSVCRT.@) */ -int _heapadd(void* mem, size_t size) +int CDECL _heapmin(void) { - TRACE("(%p,%d) unsupported in Win32\n", mem,size); + if (!HeapCompact( GetProcessHeap(), 0 )) + { + if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + __set_errno(GetLastError()); + return -1; + } + return 0; +} + +/********************************************************************* + * _heapwalk (MSVCRT.@) + */ +int CDECL _heapwalk(_HEAPINFO* next) +{ + PROCESS_HEAP_ENTRY phe; + + LOCK_HEAP; + phe.lpData = next->_pentry; + phe.cbData = next->_size; + phe.wFlags = next->_useflag == _USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0; + + if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY && + !HeapValidate( GetProcessHeap(), 0, phe.lpData )) + { + UNLOCK_HEAP; + __set_errno(GetLastError()); + return _HEAPBADNODE; + } + + do + { + if (!HeapWalk( GetProcessHeap(), &phe )) + { + UNLOCK_HEAP; + if (GetLastError() == ERROR_NO_MORE_ITEMS) + return _HEAPEND; + __set_errno(GetLastError()); + if (!phe.lpData) + return _HEAPBADBEGIN; + return _HEAPBADNODE; + } + } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE)); + + UNLOCK_HEAP; + next->_pentry = phe.lpData; + next->_size = phe.cbData; + next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? _USEDENTRY : _FREEENTRY; + return _HEAPOK; +} + +/********************************************************************* + * _heapset (MSVCRT.@) + */ +int CDECL _heapset(unsigned int value) +{ + int retval; + _HEAPINFO heap; + + memset( &heap, 0, sizeof(heap) ); + LOCK_HEAP; + while ((retval = _heapwalk(&heap)) == _HEAPOK) + { + if (heap._useflag == _FREEENTRY) + memset(heap._pentry, value, heap._size); + } + UNLOCK_HEAP; + return retval == _HEAPEND? _HEAPOK : retval; +} + +/********************************************************************* + * _heapadd (MSVCRT.@) + */ +int CDECL _heapadd(void* mem, size_t size) +{ + TRACE("(%p,%ld) unsupported in Win32\n", mem,size); *_errno() = ENOSYS; return -1; } +/********************************************************************* + * _heapadd (MSVCRT.@) + */ +intptr_t CDECL _get_heap_handle(void) +{ + return (intptr_t)GetProcessHeap(); +} + +/********************************************************************* + * _msize (MSVCRT.@) + */ +size_t CDECL _msize(void* mem) +{ + size_t size = HeapSize(GetProcessHeap(),0,mem); + if (size == ~(size_t)0) + { + WARN(":Probably called with non wine-allocated memory, ret = -1\n"); + /* At least the Win32 crtdll/msvcrt also return -1 in this case */ + } + return size; +} + +/********************************************************************* + * calloc (MSVCRT.@) + */ +void* CDECL calloc(size_t size,size_t count) +{ + return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size * count ); +} + +/********************************************************************* + * free (MSVCRT.@) + */ +void CDECL free(void* ptr) +{ + HeapFree(GetProcessHeap(),0,ptr); +} + +/********************************************************************* + * malloc (MSVCRT.@) + */ +void* CDECL malloc(size_t size) +{ + void *ret = HeapAlloc(GetProcessHeap(),0,size); + if (!ret) + *_errno() = ENOMEM; + return ret; +} + +/********************************************************************* + * realloc (MSVCRT.@) + */ +void* CDECL realloc(void* ptr, size_t size) +{ + if (!ptr) return malloc(size); + if (size) return HeapReAlloc(GetProcessHeap(), 0, ptr, size); + free(ptr); + return NULL; +} + +/********************************************************************* + * __p__amblksiz (MSVCRT.@) + */ +unsigned int* CDECL __p__amblksiz(void) +{ + return &MSVCRT_amblksiz; +} + +/********************************************************************* + * _get_sbh_threshold (MSVCRT.@) + */ +size_t CDECL _get_sbh_threshold(void) +{ + return MSVCRT_sbh_threshold; +} + +/********************************************************************* + * _set_sbh_threshold (MSVCRT.@) + */ +int CDECL _set_sbh_threshold(size_t threshold) +{ + if(threshold > 1016) + return 0; + else + MSVCRT_sbh_threshold = threshold; + return 1; +} + +/********************************************************************* + * _aligned_free (MSVCRT.@) + */ void CDECL _aligned_free(void *memblock) { + TRACE("(%p)\n", memblock); + if (memblock) { void **saved = SAVED_PTR(memblock); @@ -165,9 +350,13 @@ void CDECL _aligned_free(void *memblock) } } +/********************************************************************* + * _aligned_offset_malloc (MSVCRT.@) + */ void * CDECL _aligned_offset_malloc(size_t size, size_t alignment, size_t offset) { void *memblock, *temp, **saved; + TRACE("(%lu, %lu, %lu)\n", size, alignment, offset); /* alignment must be a power of 2 */ if ((alignment & (alignment - 1)) != 0) @@ -204,16 +393,24 @@ void * CDECL _aligned_offset_malloc(size_t size, size_t alignment, size_t offset return memblock; } +/********************************************************************* + * _aligned_malloc (MSVCRT.@) + */ void * CDECL _aligned_malloc(size_t size, size_t alignment) { + TRACE("(%lu, %lu)\n", size, alignment); return _aligned_offset_malloc(size, alignment, 0); } +/********************************************************************* + * _aligned_offset_realloc (MSVCRT.@) + */ void * CDECL _aligned_offset_realloc(void *memblock, size_t size, size_t alignment, size_t offset) { void * temp, **saved; size_t old_padding, new_padding, old_size; + TRACE("(%p, %lu, %lu, %lu)\n", memblock, size, alignment, offset); if (!memblock) return _aligned_offset_malloc(size, alignment, offset); @@ -244,7 +441,6 @@ void * CDECL _aligned_offset_realloc(void *memblock, size_t size, /* make sure alignment and offset didn't change */ saved = SAVED_PTR(memblock); - if (memblock != ALIGN_PTR(*saved, alignment, offset)) { *_errno() = EINVAL; @@ -255,7 +451,7 @@ void * CDECL _aligned_offset_realloc(void *memblock, size_t size, /* Get previous size of block */ old_size = _msize(*saved); - if (old_size == (size_t)-1) + if (old_size == -1) { /* It seems this function was called with an invalid pointer. Bail out. */ return NULL; @@ -283,47 +479,116 @@ void * CDECL _aligned_offset_realloc(void *memblock, size_t size, new_padding = (char *)memblock - (char *)temp; - /* - Memory layout of old block is as follows: - +-------+---------------------+-+--------------------------+-----------+ - | ... | "old_padding" bytes | | ... "old_size" bytes ... | ... | - +-------+---------------------+-+--------------------------+-----------+ - ^ ^ ^ - | | | - *saved saved memblock +/* + Memory layout of old block is as follows: + +-------+---------------------+-+--------------------------+-----------+ + | ... | "old_padding" bytes | | ... "old_size" bytes ... | ... | + +-------+---------------------+-+--------------------------+-----------+ + ^ ^ ^ + | | | + *saved saved memblock + Memory layout of new block is as follows: + +-------+-----------------------------+-+----------------------+-------+ + | ... | "new_padding" bytes | | ... "size" bytes ... | ... | + +-------+-----------------------------+-+----------------------+-------+ + ^ ^ ^ + | | | + temp saved memblock - Memory layout of new block is as follows: - +-------+-----------------------------+-+----------------------+-------+ - | ... | "new_padding" bytes | | ... "size" bytes ... | ... | - +-------+-----------------------------+-+----------------------+-------+ - ^ ^ ^ - | | | - temp saved memblock + However, in the new block, actual data is still written as follows + (because it was copied by MSVCRT_realloc): + +-------+---------------------+--------------------------------+-------+ + | ... | "old_padding" bytes | ... "old_size" bytes ... | ... | + +-------+---------------------+--------------------------------+-------+ + ^ ^ ^ + | | | + temp saved memblock - However, in the new block, actual data is still written as follows - (because it was copied by MSVCRT_realloc): - +-------+---------------------+--------------------------------+-------+ - | ... | "old_padding" bytes | ... "old_size" bytes ... | ... | - +-------+---------------------+--------------------------------+-------+ - ^ ^ ^ - | | | - temp saved memblock - - Therefore, min(old_size,size) bytes of actual data have to be moved - from the offset they were at in the old block (temp + old_padding), - to the offset they have to be in the new block (temp + new_padding == memblock). - */ - + Therefore, min(old_size,size) bytes of actual data have to be moved + from the offset they were at in the old block (temp + old_padding), + to the offset they have to be in the new block (temp + new_padding == memblock). +*/ if (new_padding != old_padding) memmove((char *)memblock, (char *)temp + old_padding, (old_size < size) ? old_size : size); *saved = temp; return memblock; - } +} +/********************************************************************* + * _aligned_realloc (MSVCRT.@) + */ void * CDECL _aligned_realloc(void *memblock, size_t size, size_t alignment) { + TRACE("(%p, %lu, %lu)\n", memblock, size, alignment); return _aligned_offset_realloc(memblock, size, alignment, 0); } + +/********************************************************************* + * memmove_s (MSVCRT.@) + */ +int CDECL memmove_s(void *dest, size_t numberOfElements, const void *src, size_t count) +{ + TRACE("(%p %lu %p %lu)\n", dest, numberOfElements, src, count); + + if(!count) + return 0; + + if(!dest || !src) { + if(dest) + memset(dest, 0, numberOfElements); + + *_errno() = EINVAL; + return EINVAL; + } + + if(count > numberOfElements) { + memset(dest, 0, numberOfElements); + + *_errno() = ERANGE; + return ERANGE; + } + + memmove(dest, src, count); + return 0; +} + +/********************************************************************* + * strncpy_s (MSVCRT.@) + */ +int CDECL strncpy_s(char *dest, size_t numberOfElements, + const char *src, size_t count) +{ + size_t i, end; + + TRACE("(%s %lu %s %lu)\n", dest, numberOfElements, src, count); + + if(!count) + return 0; + + if(!dest || !src || !numberOfElements) { + _invalid_parameter(NULL, NULL, NULL, 0, 0); + *_errno() = EINVAL; + return EINVAL; + } + + if(count!=_TRUNCATE && count