Author: tkreuzer Date: Mon Jun 21 19:57:36 2010 New Revision: 47822
URL: http://svn.reactos.org/svn/reactos?rev=47822&view=rev Log: [CRT] - Stubplement _controlfp_s, rand_s - Implement _invalid_parameter, _get_invalid_parameter_handler, _set_invalid_parameter_handler - Implement memmove_s, strncpy_s - sync heap.c with wine Patch by Samuel Serapion
Modified: trunk/reactos/lib/sdk/crt/crt.rbuild trunk/reactos/lib/sdk/crt/float/i386/cntrlfp.c trunk/reactos/lib/sdk/crt/math/rand.c trunk/reactos/lib/sdk/crt/misc/stubs.c trunk/reactos/lib/sdk/crt/stdlib/errno.c trunk/reactos/lib/sdk/crt/wine/heap.c
Modified: trunk/reactos/lib/sdk/crt/crt.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/crt.rbuild?rev=... ============================================================================== --- trunk/reactos/lib/sdk/crt/crt.rbuild [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/crt.rbuild [iso-8859-1] Mon Jun 21 19:57:36 2010 @@ -329,7 +329,6 @@ <file>gcvt.c</file> <file>getenv.c</file> <file>makepath.c</file> - <file>malloc.c</file> <file>mbtowc.c</file> <file>mbstowcs.c</file> <file>obsol.c</file>
Modified: trunk/reactos/lib/sdk/crt/float/i386/cntrlfp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/float/i386/cntr... ============================================================================== --- trunk/reactos/lib/sdk/crt/float/i386/cntrlfp.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/float/i386/cntrlfp.c [iso-8859-1] Mon Jun 21 19:57:36 2010 @@ -104,3 +104,25 @@
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 +}
Modified: trunk/reactos/lib/sdk/crt/math/rand.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/math/rand.c?rev... ============================================================================== --- trunk/reactos/lib/sdk/crt/math/rand.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/math/rand.c [iso-8859-1] Mon Jun 21 19:57:36 2010 @@ -1,6 +1,6 @@ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ #include <precomp.h> - +//#include <Ntsecapi.h> #include <internal/tls.h>
/* @@ -25,3 +25,18 @@
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; +}
Modified: trunk/reactos/lib/sdk/crt/misc/stubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/misc/stubs.c?re... ============================================================================== --- trunk/reactos/lib/sdk/crt/misc/stubs.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/misc/stubs.c [iso-8859-1] Mon Jun 21 19:57:36 2010 @@ -15,11 +15,6 @@ /* FIXME: This is probably data, not a function */ }
-void __p__amblksiz(void) -{ - FIXME("__p__amblksiz stub\n"); -} - void __fileinfo(void) { FIXME("__fileinfo stub\n");
Modified: trunk/reactos/lib/sdk/crt/stdlib/errno.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/stdlib/errno.c?... ============================================================================== --- trunk/reactos/lib/sdk/crt/stdlib/errno.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/stdlib/errno.c [iso-8859-1] Mon Jun 21 19:57:36 2010 @@ -8,7 +8,10 @@ */ #include <precomp.h> #include "doserrmap.h" +#include <errno.h> #include <internal/wine/msvcrt.h> + +static _invalid_parameter_handler invalid_parameter_handler = NULL;
/* * @implemented @@ -113,4 +116,36 @@ 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 */
Modified: trunk/reactos/lib/sdk/crt/wine/heap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/wine/heap.c?rev... ============================================================================== --- trunk/reactos/lib/sdk/crt/wine/heap.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/wine/heap.c [iso-8859-1] Mon Jun 21 19:57:36 2010 @@ -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 <precomp.h> +#include <malloc.h>
/* 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 *retval = malloc(size); +void* CDECL MSVCRT_operator_new(size_t 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 @@ /********************************************************************* * ?_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 @@ /********************************************************************* * ?_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 @@ /********************************************************************* * ?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 @@ /********************************************************************* * ?_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 @@ return old_mode; }
-int CDECL _callnewh(unsigned long size) -{ - if(MSVCRT_new_handler) - (*MSVCRT_new_handler)(size); - return 0; -} - -/********************************************************************* - * _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; -} - -/********************************************************************* - * _heapadd (MSVCRT.@) - */ -int _heapadd(void* mem, size_t size) -{ - TRACE("(%p,%d) unsupported in Win32\n", mem,size); +/********************************************************************* + * _callnewh (MSVCRT.@) + */ +int CDECL _callnewh(size_t size) +{ + if(MSVCRT_new_handler) + (*MSVCRT_new_handler)(size); + return 0; +} + +/********************************************************************* + * _expand (MSVCRT.@) + */ +void* CDECL _expand(void* mem, size_t size) +{ + return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, mem, size); +} + +/********************************************************************* + * _heapchk (MSVCRT.@) + */ +int CDECL _heapchk(void) +{ + if (!HeapValidate( GetProcessHeap(), 0, NULL)) + { + __set_errno(GetLastError()); + return _HEAPBADNODE; + } + return _HEAPOK; +} + +/********************************************************************* + * _heapmin (MSVCRT.@) + */ +int CDECL _heapmin(void) +{ + 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 @@ } }
+/********************************************************************* + * _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 @@ 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 @@
/* 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 @@
/* 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 @@
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 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 - - 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). - */ - +/* + 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 + + 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). +*/ 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<numberOfElements) + end = count; + else + end = numberOfElements-1; + + for(i=0; i<end && src[i]; i++) + dest[i] = src[i]; + + if(!src[i] || end==count || count==_TRUNCATE) { + dest[i] = '\0'; + return 0; + } + + _invalid_parameter(NULL, NULL, NULL, 0, 0); + dest[0] = '\0'; + *_errno() = EINVAL; + return EINVAL; +}