Piotr Caban : msvcrt: Added memmove_s and memcpy_s implementation.

Alexandre Julliard julliard at winehq.org
Tue Apr 13 11:24:39 CDT 2010


Module: wine
Branch: master
Commit: 8fc18b6b4801efc0098f20a6ed4cacf6172e986f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8fc18b6b4801efc0098f20a6ed4cacf6172e986f

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Apr 12 15:35:31 2010 +0200

msvcrt: Added memmove_s and memcpy_s implementation.

---

 dlls/msvcr80/msvcr80.spec |    4 +-
 dlls/msvcr90/msvcr90.spec |    4 +-
 dlls/msvcrt/heap.c        |   29 +++++++++++++++++++++++
 dlls/msvcrt/msvcrt.spec   |    4 +-
 dlls/msvcrt/tests/misc.c  |   55 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 90 insertions(+), 6 deletions(-)

diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index d7d0395..7d170a9 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -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
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 9bfa23d..3eae9a0 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -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
diff --git a/dlls/msvcrt/heap.c b/dlls/msvcrt/heap.c
index e40a0c9..7adaf90 100644
--- a/dlls/msvcrt/heap.c
+++ b/dlls/msvcrt/heap.c
@@ -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;
+}
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index eac8f46..08b330f 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -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
diff --git a/dlls/msvcrt/tests/misc.c b/dlls/msvcrt/tests/misc.c
index 1f069fa..d8b1b88 100644
--- a/dlls/msvcrt/tests/misc.c
+++ b/dlls/msvcrt/tests/misc.c
@@ -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();
 }




More information about the wine-cvs mailing list