Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/shcore/main.c | 102 +++++++++++++++++++++++++++++++++++++
dlls/shcore/shcore.spec | 8 +--
dlls/shcore/tests/shcore.c | 95 ++++++++++++++++++++++++++++++++++
3 files changed, 201 insertions(+), 4 deletions(-)
diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c
index bf477aefcc..2f32a741f4 100644
--- a/dlls/shcore/main.c
+++ b/dlls/shcore/main.c
@@ -1455,3 +1455,105 @@ 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 = 0;
+
+ TRACE("(%s, %p, %d)\n", debugstr_a(src), dest, dest_len);
+
+ if (!src || !dest || dest_len <= 0)
+ return 0;
+
+ while (dest_len > 1 && *src)
+ {
+ dest_len--;
+ *dest++ = *src++;
+ ret++;
+ }
+
+ if (dest_len)
+ {
+ *dest = 0;
+ ret++;
+ }
+
+ return ret;
+}
+
+/*************************************************************************
+ * SHUnicodeToAnsi [SHCORE.@]
+ */
+DWORD WINAPI SHUnicodeToAnsi(const WCHAR *src, char *dest, int dest_len)
+{
+ int required = 1;
+
+ TRACE("(%s, %p, %d)\n", debugstr_w(src), dest, dest_len);
+
+ if (!dest || !dest_len)
+ return 0;
+
+ if (src)
+ {
+ required = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
+ WideCharToMultiByte(CP_ACP, 0, src, -1, dest, dest_len, NULL, NULL);
+ }
+ dest_len = min(required, dest_len);
+
+ dest[dest_len - 1] = 0;
+ return dest_len;
+}
+
+/*************************************************************************
+ * SHUnicodeToUnicode [SHCORE.@]
+ */
+DWORD WINAPI SHUnicodeToUnicode(const WCHAR *src, WCHAR *dest, int dest_len)
+{
+ DWORD ret = 0;
+
+ TRACE("(%s, %p, %d)\n", debugstr_w(src), dest, dest_len);
+
+ if (!src || !dest || dest_len <= 0)
+ return 0;
+
+ while (dest_len > 1 && *src)
+ {
+ dest_len--;
+ *dest++ = *src++;
+ ret++;
+ }
+
+ if (dest_len)
+ {
+ *dest = 0;
+ ret++;
+ }
+
+ return ret;
+}
+
+/*************************************************************************
+ * SHAnsiToUnicode [SHCORE.@]
+ */
+DWORD WINAPI SHAnsiToUnicode(const char *src, WCHAR *dest, int dest_len)
+{
+ int required = 1;
+
+ TRACE("(%s, %p, %d)\n", debugstr_a(src), dest, dest_len);
+
+ if (!dest || !dest_len)
+ return 0;
+
+ if (src)
+ {
+ required = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
+ MultiByteToWideChar(CP_ACP, 0, src, -1, dest, dest_len);
+ }
+ dest_len = min(required, dest_len);
+
+ dest[dest_len - 1] = 0;
+ return dest_len;
+}
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..15fcda5449 100644
--- a/dlls/shcore/tests/shcore.c
+++ b/dlls/shcore/tests/shcore.c
@@ -29,12 +29,16 @@
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 void init(HMODULE hshcore)
{
#define X(f) p##f = (void*)GetProcAddress(hshcore, #f)
X(GetProcessReference);
X(SetProcessReference);
+ X(SHUnicodeToAnsi);
+ X(SHAnsiToUnicode);
#undef X
}
@@ -122,6 +126,95 @@ 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");
+}
+
START_TEST(shcore)
{
HMODULE hshcore = LoadLibraryA("shcore.dll");
@@ -135,4 +228,6 @@ START_TEST(shcore)
init(hshcore);
test_process_reference();
+ test_SHUnicodeToAnsi();
+ test_SHAnsiToUnicode();
}
--
2.19.2