From: Daniel Lehman dlehman25@gmail.com
--- dlls/msvcp140/tests/msvcp140.c | 137 +++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+)
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c index faf4c214801..413d157de70 100644 --- a/dlls/msvcp140/tests/msvcp140.c +++ b/dlls/msvcp140/tests/msvcp140.c @@ -22,6 +22,8 @@ #include "windef.h" #include "winbase.h" #include "winnls.h" +#include "share.h" +#include "locale.h"
#include "wine/test.h" #include "winbase.h" @@ -253,6 +255,23 @@ static ULONG (__cdecl *p__Winerror_message)(ULONG, char*, ULONG); static int (__cdecl *p__Winerror_map)(int); static const char* (__cdecl *p__Syserror_map)(int err);
+typedef enum { + OPENMODE_in = 0x01, + OPENMODE_out = 0x02, + OPENMODE_ate = 0x04, + OPENMODE_app = 0x08, + OPENMODE_trunc = 0x10, + OPENMODE__Nocreate = 0x40, + OPENMODE__Noreplace = 0x80, + OPENMODE_binary = 0x20, + OPENMODE_mask = 0xff +} IOSB_openmode; +static FILE* (__cdecl *p__Fiopen_wchar)(const wchar_t*, int, int); +static FILE* (__cdecl *p__Fiopen)(const char*, int, int); + +static char* (__cdecl *p_setlocale)(int, const char*); +static int (__cdecl *p_fclose)(FILE*); + static BOOLEAN (WINAPI *pCreateSymbolicLinkW)(const WCHAR *, const WCHAR *, DWORD);
static HMODULE msvcp; @@ -291,6 +310,9 @@ static BOOL init(void) SET(p__Release_chore, "?_Release_chore@details@Concurrency@@YAXPEAU_Threadpool_chore@12@@Z"); SET(p__Winerror_message, "?_Winerror_message@std@@YAKKPEADK@Z"); SET(p__Syserror_map, "?_Syserror_map@std@@YAPEBDH@Z"); + + SET(p__Fiopen_wchar, "?_Fiopen@std@@YAPEAU_iobuf@@PEB_WHH@Z"); + SET(p__Fiopen, "?_Fiopen@std@@YAPEAU_iobuf@@PEBDHH@Z"); } else { #ifdef __arm__ SET(p_task_continuation_context_ctor, "??0task_continuation_context@Concurrency@@AAA@XZ"); @@ -322,6 +344,9 @@ static BOOL init(void) SET(p__Release_chore, "?_Release_chore@details@Concurrency@@YAXPAU_Threadpool_chore@12@@Z"); SET(p__Winerror_message, "?_Winerror_message@std@@YAKKPADK@Z"); SET(p__Syserror_map, "?_Syserror_map@std@@YAPBDH@Z"); + + SET(p__Fiopen_wchar, "?_Fiopen@std@@YAPAU_iobuf@@PB_WHH@Z"); + SET(p__Fiopen, "?_Fiopen@std@@YAPAU_iobuf@@PBDHH@Z"); }
SET(p__Mtx_init, "_Mtx_init"); @@ -362,6 +387,10 @@ static BOOL init(void) SET(p_To_wide, "_To_wide"); SET(p_Unlink, "_Unlink");
+ hdll = GetModuleHandleA("ucrtbase.dll"); + p_setlocale = (void*)GetProcAddress(hdll, "setlocale"); + p_fclose = (void*)GetProcAddress(hdll, "fclose"); + hdll = GetModuleHandleA("kernel32.dll"); pCreateSymbolicLinkW = (void*)GetProcAddress(hdll, "CreateSymbolicLinkW");
@@ -1670,6 +1699,113 @@ static void test__Mtx(void) p__Mtx_destroy(mtx); }
+static void test__Fiopen(void) +{ + int i; + FILE *f; + char apath[MAX_PATH]; + wchar_t wpath[MAX_PATH]; + static const struct { + const char *loc; + UINT cp; + const WCHAR *path; + int is_todo; + } tests[] = { + { "German.utf8", 0, L"t\x00e4\x00cf\x00f6\x00df.txt", TRUE }, + { "Polish.utf8", 0, L"t\x0119\x015b\x0107.txt", TRUE }, + { "Turkish.utf8", 0, L"t\x00c7\x011e\x0131\x0130\x015e.txt", TRUE }, + { "Arabic.utf8", 0, L"t\x062a\x0686.txt", TRUE }, + { "Japanese.utf8", 0, L"t\x30af\x30e4.txt", TRUE }, + { "Chinese.utf8", 0, L"t\x4e02\x9f6b.txt", TRUE }, + + { "German.1252", 1252, L"t\x00e4\x00cf\x00f6\x00df.txt" }, + { "Polish.1250", 1250, L"t\x0119\x015b\x0107.txt" }, + { "Turkish.1254", 1254, L"t\x00c7\x011e\x0131\x0130\x015e.txt" }, + { "Arabic.1256", 1256, L"t\x062a\x0686.txt" }, + { "Japanese.932", 932, L"t\x30af\x30e4.txt" }, + { "Chinese.936", 936, L"t\x4e02\x9f6b.txt" }, + }; + static const struct { + const char *loc; + UINT cp; + const char *path; + } tests_a[] = { + { "German.utf8", 0, "t\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt" }, + { "Polish.utf8", 0, "t\xc4\x99\xc5\x9b\xc4\x87.txt" }, + { "Turkish.utf8", 0, "t\xc3\x87\xc4\x9e\xc4\xb1\xc4\xb0\xc5\x9e.txt" }, + { "Arabic.utf8", 0, "t\xd8\xaa\xda\x86.txt" }, + { "Japanese.utf8", 0, "t\xe3\x82\xaf\xe3\x83\xa4.txt" }, + { "Chinese.utf8", 0, "t\xe4\xb8\x82\xe9\xbd\xab.txt" }, + + { "German.1252", 1252, "t\xe4\xcf\xf6\xdf.txt" }, + { "Polish.1250", 1250, "t\xea\x9c\xe6.txt" }, + { "Turkish.1254", 1254, "t\xd0\xf0\xdd\xde\xfd\xfe.txt" }, + { "Arabic.1256", 1256, "t\xca\x8c.txt" }, + { "Japanese.932", 932, "t\xb8\xd5.txt" }, + { "Chinese.936", 936, "t\x81\x40\xfd\x71.txt" }, + }; + + /* w -> a */ + for(i=0; i<ARRAY_SIZE(tests); i++) { + if(tests[i].cp && GetACP() != tests[i].cp) { + skip("skipping test for %u (current %u)\n", tests[i].cp, GetACP()); + continue; + } + if(!p_setlocale(LC_ALL, tests[i].loc)) { + win_skip("skipping locale %s\n", tests[i].loc); + continue; + } + if(!WideCharToMultiByte(tests[i].cp ? CP_ACP : CP_UTF8, 0, tests[i].path, -1, + apath, sizeof(apath), NULL, NULL)) { + win_skip("failed to convert %s with locale %s\n", + wine_dbgstr_w(tests[i].path), tests[i].loc); + continue; + } + + f = p__Fiopen_wchar(tests[i].path, OPENMODE_out, SH_DENYNO); + ok(!!f, "failed to create %s with locale %s\n", + wine_dbgstr_w(tests[i].path), tests[i].loc); + p_fclose(f); + + f = p__Fiopen(apath, OPENMODE_in, SH_DENYNO); + todo_wine_if(tests[i].is_todo) + ok(!!f, "failed to read %s with locale %s\n", apath, tests[i].loc); + if(f) p_fclose(f); + + DeleteFileW(tests[i].path); + } + + /* a -> w */ + for(i=0; i<ARRAY_SIZE(tests_a); i++) { + if(tests_a[i].cp && tests_a[i].cp != GetACP()) { + skip("skipping test for %u (current %u)\n", tests_a[i].cp, GetACP()); + continue; + } + if(!p_setlocale(LC_ALL, tests_a[i].loc)) { + win_skip("skipping locale %s\n", tests_a[i].loc); + continue; + } + if(!MultiByteToWideChar(tests_a[i].cp ? CP_ACP : CP_UTF8, 0, tests_a[i].path, -1, + wpath, ARRAY_SIZE(wpath))) { + win_skip("failed to convert %s with locale %s\n", + tests_a[i].path, tests_a[i].loc); + continue; + } + + f = p__Fiopen(tests_a[i].path, OPENMODE_out, SH_DENYNO); + ok(!!f, "failed to create %s with locale %s\n", tests_a[i].path, tests_a[i].loc); + p_fclose(f); + + f = p__Fiopen_wchar(wpath, OPENMODE_in, SH_DENYNO); + todo_wine_if(tests[i].is_todo) + ok(!!f, "failed to read %s with locale %s\n", wine_dbgstr_w(wpath), tests_a[i].loc); + if(f) p_fclose(f); + + DeleteFileA(tests_a[i].path); + } + p_setlocale(LC_ALL, "C"); +} + START_TEST(msvcp140) { if(!init()) return; @@ -1698,5 +1834,6 @@ START_TEST(msvcp140) test_cnd(); test_Copy_file(); test__Mtx(); + test__Fiopen(); FreeLibrary(msvcp); }