msvcrt: Added memmove_s and memcpy_s implementation.
This commit is contained in:
parent
72d9aaa6e5
commit
8fc18b6b48
|
@ -1335,9 +1335,9 @@
|
|||
@ cdecl memchr(ptr long long) msvcrt.memchr
|
||||
@ cdecl memcmp(ptr ptr long) msvcrt.memcmp
|
||||
@ cdecl memcpy(ptr ptr long) msvcrt.memcpy
|
||||
@ stub memcpy_s
|
||||
@ cdecl memcpy_s(ptr long ptr long) msvcrt.memcpy_s
|
||||
@ cdecl memmove(ptr ptr long) msvcrt.memmove
|
||||
@ stub memmove_s
|
||||
@ cdecl memmove_s(ptr long ptr long) msvcrt.memmove_s
|
||||
@ cdecl memset(ptr long long) msvcrt.memset
|
||||
@ cdecl modf(double ptr) msvcrt.modf
|
||||
@ cdecl perror(str) msvcrt.perror
|
||||
|
|
|
@ -1319,9 +1319,9 @@
|
|||
@ cdecl memchr(ptr long long) msvcrt.memchr
|
||||
@ cdecl memcmp(ptr ptr long) msvcrt.memcmp
|
||||
@ cdecl memcpy(ptr ptr long) msvcrt.memcpy
|
||||
@ stub memcpy_s
|
||||
@ cdecl memcpy_s(ptr long ptr long) msvcrt.memcpy_s
|
||||
@ cdecl memmove(ptr ptr long) msvcrt.memmove
|
||||
@ stub memmove_s
|
||||
@ cdecl memmove_s(ptr long ptr long) msvcrt.memmove_s
|
||||
@ cdecl memset(ptr long long) msvcrt.memset
|
||||
@ cdecl modf(double ptr) msvcrt.modf
|
||||
@ cdecl perror(str) msvcrt.perror
|
||||
|
|
|
@ -511,3 +511,32 @@ void * CDECL _aligned_realloc(void *memblock, MSVCRT_size_t size, MSVCRT_size_t
|
|||
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, MSVCRT_size_t numberOfElements, const void *src, MSVCRT_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);
|
||||
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return MSVCRT_EINVAL;
|
||||
}
|
||||
|
||||
if(count > numberOfElements) {
|
||||
memset(dest, 0, numberOfElements);
|
||||
|
||||
*MSVCRT__errno() = MSVCRT_ERANGE;
|
||||
return MSVCRT_ERANGE;
|
||||
}
|
||||
|
||||
memmove(dest, src, count);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1267,9 +1267,9 @@
|
|||
@ cdecl memchr(ptr long long) ntdll.memchr
|
||||
@ cdecl memcmp(ptr ptr long) ntdll.memcmp
|
||||
@ cdecl memcpy(ptr ptr long) ntdll.memcpy
|
||||
# stub memcpy_s
|
||||
@ cdecl memcpy_s(ptr long ptr long) memmove_s
|
||||
@ cdecl memmove(ptr ptr long) ntdll.memmove
|
||||
# stub memmove_s
|
||||
@ cdecl memmove_s(ptr long ptr long)
|
||||
@ cdecl memset(ptr long long) ntdll.memset
|
||||
@ cdecl mktime(ptr) MSVCRT_mktime
|
||||
@ cdecl modf(double ptr) MSVCRT_modf
|
||||
|
|
|
@ -20,14 +20,17 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
#include <errno.h>
|
||||
#include "msvcrt.h"
|
||||
|
||||
static int (__cdecl *prand_s)(unsigned int *);
|
||||
static int (__cdecl *memcpy_s)(void *, MSVCRT_size_t, void*, MSVCRT_size_t);
|
||||
|
||||
static void init(void)
|
||||
{
|
||||
HMODULE hmod = GetModuleHandleA("msvcrt.dll");
|
||||
|
||||
prand_s = (void *)GetProcAddress(hmod, "rand_s");
|
||||
memcpy_s = (void*)GetProcAddress(hmod, "memcpy_s");
|
||||
}
|
||||
|
||||
static void test_rand_s(void)
|
||||
|
@ -50,9 +53,61 @@ static void test_rand_s(void)
|
|||
ok(ret == 0, "Expected rand_s to return 0, got %d\n", ret);
|
||||
}
|
||||
|
||||
static void test_memcpy_s(void)
|
||||
{
|
||||
static char data[] = "data\0to\0be\0copied";
|
||||
static char dest[32];
|
||||
int ret;
|
||||
|
||||
if(!memcpy_s)
|
||||
{
|
||||
win_skip("memcpy_s in not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
errno = 0xdeadbeef;
|
||||
ret = memcpy_s(NULL, 0, NULL, 0);
|
||||
ok(ret == 0, "ret = %x\n", ret);
|
||||
ok(errno == 0xdeadbeef, "errno = %x\n", errno);
|
||||
|
||||
errno = 0xdeadbeef;
|
||||
dest[0] = 'x';
|
||||
ret = memcpy_s(dest, 10, NULL, 0);
|
||||
ok(ret == 0, "ret = %x\n", ret);
|
||||
ok(errno == 0xdeadbeef, "errno = %x\n", errno);
|
||||
ok(dest[0] == 'x', "dest[0] != \'x\'\n");
|
||||
|
||||
errno = 0xdeadbeef;
|
||||
ret = memcpy_s(NULL, 10, data, 10);
|
||||
ok(ret == EINVAL, "ret = %x\n", ret);
|
||||
ok(errno == EINVAL, "errno = %x\n", errno);
|
||||
|
||||
errno = 0xdeadbeef;
|
||||
dest[7] = 'x';
|
||||
ret = memcpy_s(dest, 10, data, 5);
|
||||
ok(ret == 0, "ret = %x\n", ret);
|
||||
ok(errno == 0xdeadbeef, "errno = %x\n", errno);
|
||||
ok(memcmp(dest, data, 10), "All data copied\n");
|
||||
ok(!memcmp(dest, data, 5), "First five bytes are different\n");
|
||||
|
||||
errno = 0xdeadbeef;
|
||||
ret = memcpy_s(data, 10, data, 10);
|
||||
ok(ret == 0, "ret = %x\n", ret);
|
||||
ok(errno == 0xdeadbeef, "errno = %x\n", errno);
|
||||
ok(!memcmp(dest, data, 5), "data was destroyed during overwritting\n");
|
||||
|
||||
errno = 0xdeadbeef;
|
||||
dest[0] = 'x';
|
||||
ret = memcpy_s(dest, 5, data, 10);
|
||||
ok(ret == ERANGE, "ret = %x\n", ret);
|
||||
ok(errno == ERANGE, "errno = %x\n", errno);
|
||||
ok(dest[0] == '\0', "dest[0] != \'\\0\'\n");
|
||||
}
|
||||
|
||||
START_TEST(misc)
|
||||
{
|
||||
init();
|
||||
|
||||
test_rand_s();
|
||||
test_memcpy_s();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue