Commit 8fc18b6b authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msvcrt: Added memmove_s and memcpy_s implementation.

parent 72d9aaa6
......@@ -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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment