=?UTF-8?Q?Stefan=20D=C3=B6singer=20?=: msvcp140: Implement _To_wide.

Alexandre Julliard julliard at winehq.org
Tue May 30 16:05:12 CDT 2017


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri May 26 14:52:08 2017 +0200

msvcp140: Implement _To_wide.

Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcp140/msvcp140.spec    |  2 +-
 dlls/msvcp140/tests/msvcp140.c | 55 ++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcp90/locale.c          | 10 ++++++++
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec
index f13ec56..284f674 100644
--- a/dlls/msvcp140/msvcp140.spec
+++ b/dlls/msvcp140/msvcp140.spec
@@ -3732,7 +3732,7 @@
 @ cdecl _Thrd_start(ptr ptr ptr) _Thrd_start
 @ cdecl _Thrd_yield() _Thrd_yield
 @ stub _To_byte
-@ stub _To_wide
+@ cdecl _To_wide(str ptr)
 @ cdecl _Tolower(long ptr) _Tolower
 @ cdecl _Toupper(long ptr) _Toupper
 @ cdecl _Towlower(long ptr) _Towlower
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c
index c964613..f3dd4a0 100644
--- a/dlls/msvcp140/tests/msvcp140.c
+++ b/dlls/msvcp140/tests/msvcp140.c
@@ -18,6 +18,10 @@
 
 #include <stdio.h>
 
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+
 #include "wine/test.h"
 #include "winbase.h"
 
@@ -148,6 +152,8 @@ static int (__cdecl *p__Schedule_chore)(_Threadpool_chore*);
 static int (__cdecl *p__Reschedule_chore)(const _Threadpool_chore*);
 static void (__cdecl *p__Release_chore)(_Threadpool_chore*);
 
+static int (__cdecl *p_To_wide)(const char *src, WCHAR *dst);
+
 static HMODULE msvcp;
 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
@@ -209,6 +215,8 @@ static BOOL init(void)
         SET(p__Release_chore, "?_Release_chore at details@Concurrency@@YAXPAU_Threadpool_chore at 12@@Z");
     }
 
+    SET(p_To_wide, "_To_wide");
+
     init_thiscall_thunk();
     return TRUE;
 }
@@ -461,6 +469,52 @@ static void test_chore(void)
     p__Release_chore(&chore);
 }
 
+static void test_to_wide(void)
+{
+     /* öäü߀Ÿ.A.B in cp1252, the two . are an undefined value and delete.
+      * With a different system codepage it will produce different results, so do not hardcode the
+      * expected output but convert it with MultiByteToWideChar. */
+    static const char special_input[] = {0xf6, 0xe4, 0xfc, 0xdf, 0x80, 0x9f, 0x81, 0x41, 0x7f, 0x42, 0};
+    static const char *tests[] = {"Testtest", special_input};
+    WCHAR dst[MAX_PATH + 4] = {'A', 'B', 'C', 0, 'X', 'X', 'X', 'X', 'X', 'X', 'X'};
+    WCHAR compare[MAX_PATH + 4] = {'A', 'B', 'C', 0, 'X', 'X', 'X', 'X', 'X', 'X', 'X'};
+    int ret, expected;
+    unsigned int i;
+    char longstr[MAX_PATH + 3];
+
+    ret = p_To_wide(NULL, NULL);
+    ok(!ret, "Got unexpected result %d\n", ret);
+    ret = p_To_wide(tests[0], NULL);
+    ok(!ret, "Got unexpected result %d\n", ret);
+    ret = p_To_wide(NULL, dst);
+    ok(!ret, "Got unexpected result %d\n", ret);
+    ok(!memcmp(dst, compare, sizeof(compare)), "Destination was modified: %s\n", wine_dbgstr_w(dst));
+
+    for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
+    {
+        ret = p_To_wide(tests[i], dst);
+        expected = MultiByteToWideChar(CP_ACP, 0, tests[i], -1, compare, sizeof(compare) / sizeof(*compare));
+        ok(ret == expected,  "Got unexpected result %d, expected %d, test case %u\n", ret, expected, i);
+        ok(!memcmp(dst, compare, sizeof(compare)), "Got unexpected output %s, test case %u\n",
+                wine_dbgstr_w(dst), i);
+    }
+
+    /* Output length is limited to MAX_PATH.*/
+    for (i = MAX_PATH - 2; i < MAX_PATH + 2; ++i)
+    {
+        memset(longstr, 'A', sizeof(longstr));
+        longstr[i] = 0;
+        memset(dst, 0xff, sizeof(dst));
+        memset(compare, 0xff, sizeof(compare));
+
+        ret = p_To_wide(longstr, dst);
+        expected = MultiByteToWideChar(CP_ACP, 0, longstr, -1, compare, MAX_PATH);
+        ok(ret == expected,  "Got unexpected result %d, expected %d, length %u\n", ret, expected, i);
+        ok(!memcmp(dst, compare, sizeof(compare)), "Got unexpected output %s, length %u\n",
+                wine_dbgstr_w(dst), i);
+    }
+}
+
 START_TEST(msvcp140)
 {
     if(!init()) return;
@@ -470,5 +524,6 @@ START_TEST(msvcp140)
     test__ContextCallback();
     test__TaskEventLogger();
     test_chore();
+    test_to_wide();
     FreeLibrary(msvcp);
 }
diff --git a/dlls/msvcp90/locale.c b/dlls/msvcp90/locale.c
index d2fce47..8847ac2 100644
--- a/dlls/msvcp90/locale.c
+++ b/dlls/msvcp90/locale.c
@@ -11224,6 +11224,16 @@ size_t __cdecl wcsrtombs(char *dst, const wchar_t **pstr, size_t n, mbstate_t *s
 }
 #endif
 
+int __cdecl _To_wide(const char *src, wchar_t *dst)
+{
+    TRACE("(%s %p)\n", debugstr_a(src), dst);
+
+    if (!src || !dst)
+        return 0;
+
+    return MultiByteToWideChar(CP_ACP, 0, src, -1, dst, MAX_PATH);
+}
+
 DEFINE_RTTI_DATA0(_Facet_base, 0, ".?AV_Facet_base at std@@")
 DEFINE_RTTI_DATA0(locale_facet, 0, ".?AVfacet at locale@std@@")
 DEFINE_RTTI_DATA1(locale__Locimp, 0, &locale_facet_rtti_base_descriptor, ".?AV_Locimp at locale@std@@")




More information about the wine-cvs mailing list