[v3 PATCH 1/4] shcore: Implement a bunch of string conversion functions.

Nikolay Sivov nsivov at codeweavers.com
Thu Nov 29 03:06:11 CST 2018


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/shcore/main.c         |  90 ++++++++++++++++++
 dlls/shcore/shcore.spec    |   8 +-
 dlls/shcore/tests/shcore.c | 182 +++++++++++++++++++++++++++++++++++++
 3 files changed, 276 insertions(+), 4 deletions(-)

diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c
index bf477aefcc..88c36ecf2d 100644
--- a/dlls/shcore/main.c
+++ b/dlls/shcore/main.c
@@ -1455,3 +1455,93 @@ HRESULT WINAPI SHStrDupA(const char *src, WCHAR **dest)
 
     return S_OK;
 }
+
+/*************************************************************************
+ * SHAnsiToAnsi        [SHCORE.@]
+ */
+DWORD WINAPI SHAnsiToAnsi(const char *src, char *dest, int dest_len)
+{
+    DWORD ret;
+
+    TRACE("(%s, %p, %d)\n", debugstr_a(src), dest, dest_len);
+
+    if (!src || !dest || dest_len <= 0)
+        return 0;
+
+    lstrcpynA(dest, src, dest_len);
+    ret = strlen(dest);
+
+    return src[ret] ? 0 : ret + 1;
+}
+
+/*************************************************************************
+ * SHUnicodeToAnsi        [SHCORE.@]
+ */
+DWORD WINAPI SHUnicodeToAnsi(const WCHAR *src, char *dest, int dest_len)
+{
+    int ret = 1;
+
+    TRACE("(%s, %p, %d)\n", debugstr_w(src), dest, dest_len);
+
+    if (!dest || !dest_len)
+        return 0;
+
+    if (src)
+    {
+        ret = WideCharToMultiByte(CP_ACP, 0, src, -1, dest, dest_len, NULL, NULL);
+        if (!ret)
+        {
+            dest[dest_len - 1] = 0;
+            ret = dest_len;
+        }
+    }
+    else
+        dest[0] = 0;
+
+    return ret;
+}
+
+/*************************************************************************
+ * SHUnicodeToUnicode        [SHCORE.@]
+ */
+DWORD WINAPI SHUnicodeToUnicode(const WCHAR *src, WCHAR *dest, int dest_len)
+{
+    DWORD ret;
+
+    TRACE("(%s, %p, %d)\n", debugstr_w(src), dest, dest_len);
+
+    if (!src || !dest || dest_len <= 0)
+        return 0;
+
+    lstrcpynW(dest, src, dest_len);
+    ret = strlenW(dest);
+
+    return src[ret] ? 0 : ret + 1;
+}
+
+/*************************************************************************
+ * SHAnsiToUnicode        [SHCORE.@]
+ */
+DWORD WINAPI SHAnsiToUnicode(const char *src, WCHAR *dest, int dest_len)
+{
+    int ret = 1;
+
+    TRACE("(%s, %p, %d)\n", debugstr_a(src), dest, dest_len);
+
+    if (!dest || !dest_len)
+        return 0;
+
+    if (src)
+    {
+        ret = MultiByteToWideChar(CP_ACP, 0, src, -1, dest, dest_len);
+        if (!ret)
+        {
+            dest[dest_len - 1] = 0;
+            ret = dest_len;
+        }
+    }
+    else
+        dest[0] = 0;
+
+    return ret;
+}
diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec
index 1473bf7b0a..918ba5595c 100644
--- a/dlls/shcore/shcore.spec
+++ b/dlls/shcore/shcore.spec
@@ -29,8 +29,8 @@
 @ stub RegisterScaleChangeEvent
 @ stub RegisterScaleChangeNotifications
 @ stub RevokeScaleChangeNotifications
-@ stdcall SHAnsiToAnsi(str ptr long) shlwapi.SHAnsiToAnsi
-@ stdcall SHAnsiToUnicode(str ptr long) shlwapi.SHAnsiToUnicode
+@ stdcall SHAnsiToAnsi(str ptr long)
+@ stdcall SHAnsiToUnicode(str ptr long)
 @ stdcall SHCopyKeyA(long str long long) shlwapi.SHCopyKeyA
 @ stdcall SHCopyKeyW(long wstr long long) shlwapi.SHCopyKeyW
 @ stdcall SHCreateMemStream(ptr long)
@@ -75,8 +75,8 @@
 @ stdcall SHSetValueW(long wstr wstr long ptr long) shlwapi.SHSetValueW
 @ stdcall SHStrDupA(str ptr)
 @ stdcall SHStrDupW(wstr ptr)
-@ stdcall SHUnicodeToAnsi(wstr ptr ptr) shlwapi.SHUnicodeToAnsi
-@ stdcall SHUnicodeToUnicode(wstr ptr long) shlwapi.SHUnicodeToUnicode
+@ stdcall SHUnicodeToAnsi(wstr ptr ptr)
+@ stdcall SHUnicodeToUnicode(wstr ptr long)
 @ stdcall SetCurrentProcessExplicitAppUserModelID(wstr)
 @ stdcall SetProcessDpiAwareness(long)
 @ stdcall SetProcessReference(ptr)
diff --git a/dlls/shcore/tests/shcore.c b/dlls/shcore/tests/shcore.c
index 904d8264cd..f788afdd22 100644
--- a/dlls/shcore/tests/shcore.c
+++ b/dlls/shcore/tests/shcore.c
@@ -29,12 +29,20 @@
 static HRESULT (WINAPI *pGetProcessReference)(IUnknown **);
 static void (WINAPI *pSetProcessReference)(IUnknown *);
 static HRESULT (WINAPI *pSHGetInstanceExplorer)(IUnknown **);
+static int (WINAPI *pSHUnicodeToAnsi)(const WCHAR *, char *, int);
+static int (WINAPI *pSHAnsiToUnicode)(const char *, WCHAR *, int);
+static int (WINAPI *pSHAnsiToAnsi)(const char *, char *, int);
+static int (WINAPI *pSHUnicodeToUnicode)(const WCHAR *, WCHAR *, int);
 
 static void init(HMODULE hshcore)
 {
 #define X(f) p##f = (void*)GetProcAddress(hshcore, #f)
     X(GetProcessReference);
     X(SetProcessReference);
+    X(SHUnicodeToAnsi);
+    X(SHAnsiToUnicode);
+    X(SHAnsiToAnsi);
+    X(SHUnicodeToUnicode);
 #undef X
 }
 
@@ -122,6 +130,176 @@ static void test_process_reference(void)
     ok(test_unk2.refcount == 3, "Unexpected refcount %u.\n", test_unk2.refcount);
 }
 
+static void test_SHUnicodeToAnsi(void)
+{
+    static const WCHAR testW[] = {'t','e','s','t',0};
+    static const WCHAR emptyW[] = { 0 };
+    char buff[16];
+    int ret;
+
+    ret = pSHUnicodeToAnsi(NULL, NULL, 0);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+
+    strcpy(buff, "abc");
+    ret = pSHUnicodeToAnsi(NULL, buff, 2);
+    ok(ret == 1, "Unexpected return value %d.\n", ret);
+    ok(buff[0] == 0 && buff[1] == 'b', "Unexpected buffer contents.\n");
+
+    buff[0] = 1;
+    ret = pSHUnicodeToAnsi(NULL, buff, 0);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+    ok(buff[0] == 1, "Unexpected buffer contents.\n");
+
+    buff[0] = 1;
+    strcpy(buff, "test");
+    ret = pSHUnicodeToAnsi(emptyW, buff, 1);
+    ok(ret == 1, "Unexpected return value %d.\n", ret);
+    ok(*buff == 0, "Unexpected buffer contents.\n");
+
+    buff[0] = 1;
+    ret = pSHUnicodeToAnsi(testW, buff, 0);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+    ok(buff[0] == 1, "Unexpected buffer contents.\n");
+
+    buff[0] = 1;
+    ret = pSHUnicodeToAnsi(testW, buff, 1);
+    ok(ret == 1, "Unexpected return value %d.\n", ret);
+    ok(*buff == 0, "Unexpected buffer contents.\n");
+
+    ret = pSHUnicodeToAnsi(testW, buff, 16);
+    ok(ret == 5, "Unexpected return value %d.\n", ret);
+    ok(!strcmp(buff, "test"), "Unexpected buffer contents.\n");
+
+    ret = pSHUnicodeToAnsi(testW, buff, 2);
+    ok(ret == 2, "Unexpected return value %d.\n", ret);
+    ok(!strcmp(buff, "t"), "Unexpected buffer contents.\n");
+}
+
+static void test_SHAnsiToUnicode(void)
+{
+    static const WCHAR testW[] = {'t','e','s','t',0};
+    WCHAR buffW[16];
+    int ret;
+
+    ret = pSHAnsiToUnicode(NULL, NULL, 0);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+
+    buffW[0] = 1;
+    buffW[1] = 2;
+    ret = pSHAnsiToUnicode(NULL, buffW, 2);
+    ok(ret == 1, "Unexpected return value %d.\n", ret);
+    ok(buffW[0] == 0 && buffW[1] == 2, "Unexpected buffer contents.\n");
+
+    buffW[0] = 1;
+    ret = pSHAnsiToUnicode(NULL, buffW, 0);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+    ok(buffW[0] == 1, "Unexpected buffer contents.\n");
+
+    buffW[0] = 1;
+    ret = pSHAnsiToUnicode("", buffW, 1);
+    ok(ret == 1, "Unexpected return value %d.\n", ret);
+    ok(*buffW == 0, "Unexpected buffer contents.\n");
+
+    buffW[0] = 1;
+    ret = pSHAnsiToUnicode("test", buffW, 0);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+    ok(buffW[0] == 1, "Unexpected buffer contents.\n");
+
+    buffW[0] = 1;
+    ret = pSHAnsiToUnicode("test", buffW, 1);
+    ok(ret == 1, "Unexpected return value %d.\n", ret);
+    ok(*buffW == 0, "Unexpected buffer contents.\n");
+
+    ret = pSHAnsiToUnicode("test", buffW, 16);
+    ok(ret == 5, "Unexpected return value %d.\n", ret);
+    ok(!lstrcmpW(buffW, testW), "Unexpected buffer contents.\n");
+
+    ret = pSHAnsiToUnicode("test", buffW, 2);
+    ok(ret == 2, "Unexpected return value %d.\n", ret);
+    ok(buffW[0] == 't' && buffW[1] == 0, "Unexpected buffer contents.\n");
+}
+
+static void test_SHAnsiToAnsi(void)
+{
+    char buff[16];
+    int ret;
+
+    ret = pSHAnsiToAnsi(NULL, NULL, 0);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+
+    strcpy(buff, "abcdefghijklm");
+    ret = pSHAnsiToAnsi("test", buff, 3);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+    ok(!strcmp(buff, "te"), "Unexpected buffer contents.\n");
+    ok(buff[3] == 'd', "Unexpected buffer contents.\n");
+
+    strcpy(buff, "abcdefghijklm");
+    ret = pSHAnsiToAnsi("", buff, 3);
+    ok(ret == 1, "Unexpected return value %d.\n", ret);
+    ok(!*buff, "Unexpected buffer contents.\n");
+    ok(buff[3] == 'd', "Unexpected buffer contents.\n");
+
+    strcpy(buff, "abcdefghijklm");
+    ret = pSHAnsiToAnsi("test", buff, 4);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+    ok(!strcmp(buff, "tes"), "Unexpected buffer contents.\n");
+    ok(buff[4] == 'e', "Unexpected buffer contents.\n");
+
+    strcpy(buff, "abcdefghijklm");
+    ret = pSHAnsiToAnsi("test", buff, 5);
+    ok(ret == 5, "Unexpected return value %d.\n", ret);
+    ok(!strcmp(buff, "test"), "Unexpected buffer contents.\n");
+    ok(buff[5] == 'f', "Unexpected buffer contents.\n");
+
+    strcpy(buff, "abcdefghijklm");
+    ret = pSHAnsiToAnsi("test", buff, 6);
+    ok(ret == 5, "Unexpected return value %d.\n", ret);
+    ok(!strcmp(buff, "test"), "Unexpected buffer contents.\n");
+    ok(buff[5] == 'f', "Unexpected buffer contents.\n");
+}
+
+static void test_SHUnicodeToUnicode(void)
+{
+    static const WCHAR testW[] = {'t','e','s','t',0};
+    static const WCHAR strW[] = {'a','b','c','d','e','f','g','h','i','k','l','m',0};
+    static const WCHAR emptyW[] = { 0 };
+    WCHAR buff[16];
+    int ret;
+
+    ret = pSHUnicodeToUnicode(NULL, NULL, 0);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+
+    lstrcpyW(buff, strW);
+    ret = pSHUnicodeToUnicode(testW, buff, 3);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+    ok(!memcmp(buff, testW, 2 * sizeof(WCHAR)) && !buff[2], "Unexpected buffer contents.\n");
+    ok(buff[3] == 'd', "Unexpected buffer contents.\n");
+
+    lstrcpyW(buff, strW);
+    ret = pSHUnicodeToUnicode(emptyW, buff, 3);
+    ok(ret == 1, "Unexpected return value %d.\n", ret);
+    ok(!*buff, "Unexpected buffer contents.\n");
+    ok(buff[3] == 'd', "Unexpected buffer contents.\n");
+
+    lstrcpyW(buff, strW);
+    ret = pSHUnicodeToUnicode(testW, buff, 4);
+    ok(ret == 0, "Unexpected return value %d.\n", ret);
+    ok(!memcmp(buff, testW, 3 * sizeof(WCHAR)) && !buff[3], "Unexpected buffer contents.\n");
+    ok(buff[4] == 'e', "Unexpected buffer contents.\n");
+
+    lstrcpyW(buff, strW);
+    ret = pSHUnicodeToUnicode(testW, buff, 5);
+    ok(ret == 5, "Unexpected return value %d.\n", ret);
+    ok(!lstrcmpW(buff, testW), "Unexpected buffer contents.\n");
+    ok(buff[5] == 'f', "Unexpected buffer contents.\n");
+
+    lstrcpyW(buff, strW);
+    ret = pSHUnicodeToUnicode(testW, buff, 6);
+    ok(ret == 5, "Unexpected return value %d.\n", ret);
+    ok(!lstrcmpW(buff, testW), "Unexpected buffer contents.\n");
+    ok(buff[5] == 'f', "Unexpected buffer contents.\n");
+}
+
 START_TEST(shcore)
 {
     HMODULE hshcore = LoadLibraryA("shcore.dll");
@@ -135,4 +313,8 @@ START_TEST(shcore)
     init(hshcore);
 
     test_process_reference();
+    test_SHUnicodeToAnsi();
+    test_SHAnsiToUnicode();
+    test_SHAnsiToAnsi();
+    test_SHUnicodeToUnicode();
 }
-- 
2.19.2




More information about the wine-devel mailing list