Index: rostests/apitests/kernel32/MultiByteToWideChar.c =================================================================== --- rostests/apitests/kernel32/MultiByteToWideChar.c (revision 74717) +++ rostests/apitests/kernel32/MultiByteToWideChar.c (working copy) @@ -2,7 +2,8 @@ * PROJECT: ReactOS api tests * LICENSE: GPLv2+ - See COPYING in the top level directory * PURPOSE: Test for MultiByteToWideChar - * PROGRAMMER: Mike "tamlin" Nordell + * PROGRAMMERS: Mike "tamlin" Nordell + * Katayama Hirofumi MZ */ #include @@ -9,13 +10,196 @@ #include +/* + * Fixes definition of Wine's ok_err + */ +#undef ok_err +#define ok_err(error) \ + ok(GetLastError() == (error), "Wrong last error. Expected %lu, got %lu\n", (DWORD)(error), GetLastError()) + START_TEST(MultiByteToWideChar) { int ret; + WCHAR buffer[4]; + /* "日" in UTF-8 */ + static const char UTF8_Japanese1[] = "\xE6\x97\xA5"; + /* "日本語" in UTF-8 */ + static const char UTF8_Japanese2[] = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"; + /* + * normal without buffer + */ + ret = MultiByteToWideChar(CP_UTF8, 0, "a", 1, 0, 0); + ok_int(ret, 1); + ret = MultiByteToWideChar(CP_UTF8, 0, "a", sizeof("a"), 0, 0); - ok(ret == 2, "ret should be 2, is %d\n", ret); + ok_int(ret, 2); ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "a", sizeof("a"), 0, 0); - ok(ret == 2, "ret should be 2, is %d\n", ret); + ok_int(ret, 2); + + /* + * normal with buffer + */ + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, 0, "a", 1, buffer, 1); + ok_int(ret, 1); + ok_int(buffer[0], L'a'); + ok_int(buffer[1], 0x7F7F); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, 0, "a", sizeof("a"), buffer, 4); + ok_int(ret, 2); + ok_int(buffer[0], L'a'); + ok_int(buffer[1], 0); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "a", sizeof("a"), buffer, 4); + ok_int(ret, 2); + ok_int(buffer[0], L'a'); + ok_int(buffer[1], 0); + + /* + * short buffer + */ + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, 0, "a", sizeof("a"), buffer, 1); + ok_int(ret, 0); + ok_err(ERROR_INSUFFICIENT_BUFFER); + ok_int(buffer[0], L'a'); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "a", sizeof("a"), buffer, 1); + ok_int(ret, 0); + ok_err(ERROR_INSUFFICIENT_BUFFER); + ok_int(buffer[0], L'a'); + + /* + * invalid flags without buffer + */ + ret = MultiByteToWideChar(CP_UTF8, MB_COMPOSITE, "a", sizeof("a"), 0, 0); + ok_int(ret, 0); + ok_err(ERROR_INVALID_FLAGS); + + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS | MB_PRECOMPOSED, "a", sizeof("a"), 0, 0); + ok_int(ret, 0); + ok_err(ERROR_INVALID_FLAGS); + + /* + * invalid flags with buffer + */ + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_COMPOSITE, "a", sizeof("a"), buffer, 4); + ok_int(ret, 0); + ok_err(ERROR_INVALID_FLAGS); + ok_int(buffer[0], 0x7F7F); + ok_int(buffer[1], 0x7F7F); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS | MB_PRECOMPOSED, "a", sizeof("a"), buffer, 4); + ok_int(ret, 0); + ok_err(ERROR_INVALID_FLAGS); + ok_int(buffer[0], 0x7F7F); + ok_int(buffer[1], 0x7F7F); + + /* + * same pointer + */ + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, 0, (char *)buffer, sizeof(buffer), buffer, 1); + ok_int(ret, 0); + ok_err(ERROR_INVALID_PARAMETER); + ok_int(buffer[0], 0x7F7F); + ok_int(buffer[1], 0x7F7F); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, (char *)buffer, sizeof(buffer), buffer, 1); + ok_int(ret, 0); + ok_err(ERROR_INVALID_PARAMETER); + ok_int(buffer[0], 0x7F7F); + ok_int(buffer[1], 0x7F7F); + + /* + * invalid UTF-8 sequences without buffer + */ + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", sizeof("\xC0"), 0, 0); + ok_int(ret, 0); + ok_err(ERROR_NO_UNICODE_TRANSLATION); + + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", sizeof("\xC0\xC0\x80"), 0, 0); + ok_int(ret, 0); + ok_err(ERROR_NO_UNICODE_TRANSLATION); + + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", sizeof("\xE0\xC0"), 0, 0); + ok_int(ret, 0); + ok_err(ERROR_NO_UNICODE_TRANSLATION); + + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", sizeof("\xE0\x20\xC0"), 0, 0); + ok_int(ret, 0); + ok_err(ERROR_NO_UNICODE_TRANSLATION); + + /* + * invalid UTF-8 sequences with buffer + */ + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0", sizeof("\xC0"), buffer, 4); + ok_int(ret, 0); + ok_err(ERROR_NO_UNICODE_TRANSLATION); + ok_int(buffer[0], 0xFFFD); + ok_int(buffer[1], 0); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "\xC0\xC0\x80", sizeof("\xC0\xC0\x80"), buffer, 4); + ok_int(ret, 0); + ok_err(ERROR_NO_UNICODE_TRANSLATION); + ok_int(buffer[0], 0xFFFD); + ok_int(buffer[1], 0xFFFD); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\xC0", sizeof("\xE0\xC0"), buffer, 4); + ok_int(ret, 0); + ok_err(ERROR_NO_UNICODE_TRANSLATION); + ok_int(buffer[0], 0xFFFD); + ok_int(buffer[1], 0xFFFD); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, "\xE0\x20\xC0", sizeof("\xE0\x20\xC0"), buffer, 4); + ok_int(ret, 0); + ok_err(ERROR_NO_UNICODE_TRANSLATION); + ok_int(buffer[0], 0xFFFD); + ok_int(buffer[1], 0x0020); + + /* + * Japanese UTF-8 without buffer + */ + ret = MultiByteToWideChar(CP_UTF8, 0, UTF8_Japanese2, sizeof(UTF8_Japanese2), 0, 0); + ok_int(ret, 4); + + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese2, sizeof(UTF8_Japanese2), 0, 0); + ok_int(ret, 4); + + /* + * Japanese UTF-8 with buffer + */ + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, 0, UTF8_Japanese1, sizeof(UTF8_Japanese1), buffer, 2); + ok_int(ret, 2); + ok_int(buffer[0], 0x65E5); + ok_int(buffer[1], 0); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, 0, UTF8_Japanese2, sizeof(UTF8_Japanese2), buffer, 4); + ok_int(ret, 4); + ok_int(buffer[0], 0x65E5); + ok_int(buffer[1], 0x672C); + ok_int(buffer[2], 0x8A9E); + ok_int(buffer[3], 0); + + FillMemory(buffer, sizeof(buffer), 0x7F); + ret = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, UTF8_Japanese2, sizeof(UTF8_Japanese2), buffer, 4); + ok_int(ret, 4); + ok_int(buffer[0], 0x65E5); + ok_int(buffer[1], 0x672C); + ok_int(buffer[2], 0x8A9E); + ok_int(buffer[3], 0); }