From ea0dbc753ff47104d04c1ee63736383cf2d4f66c Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Thu, 29 Nov 2018 12:06:11 +0300 Subject: [PATCH] shcore: Implement a bunch of string conversion functions. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- 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 bf477aefcc9..88c36ecf2d4 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 1473bf7b0a6..918ba5595c4 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 904d8264cdc..f788afdd22b 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(); }