From: Daniel Lehman dlehman25@gmail.com
--- dlls/msvcp140/tests/msvcp140.c | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c index faf4c214801..44f999fb838 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,40 @@ static void test__Mtx(void) p__Mtx_destroy(mtx); }
+static void test__Fiopen(void) +{ + int i; + FILE *f; + char *oldloc; + static const struct { + const char *loc; + const WCHAR *wpath; + const char *apath; + int is_todo; + } tests[] = { + { "C", L"utf_\x00e4\x00cf\x00f6\x00df.txt", "utf_\xe4\xcf\xf6\xdf.txt" }, + { "de_DE", L"utf_\x00e4\x00cf\x00f6\x00df.txt", "utf_\xe4\xcf\xf6\xdf.txt" }, + { "de_DE.utf8", L"utf_\x00e4\x00cf\x00f6\x00df.txt", "utf_\xc3\xa4\xc3\x8f\xc3\xb6\xc3\x9f.txt", TRUE }, + }; + + oldloc = p_setlocale(LC_ALL, NULL); + for(i=0; i<ARRAY_SIZE(tests); i++) { + if(!p_setlocale(LC_ALL, tests[i].loc)) { + win_skip("skipping locale %s\n", tests[i].loc); + continue; + } + f = p__Fiopen_wchar(tests[i].wpath, OPENMODE_out, SH_DENYNO); + ok(!!f, "failed to create %s with locale %s\n", wine_dbgstr_w(tests[i].wpath), tests[i].loc); + if(f) p_fclose(f); + f = p__Fiopen(tests[i].apath, OPENMODE_in, SH_DENYNO); + todo_wine_if(tests[i].is_todo) + ok(!!f, "failed to read %s with locale %s\n", tests[i].apath, tests[i].loc); + if(f) p_fclose(f); + DeleteFileW(tests[i].wpath); + } + p_setlocale(LC_ALL, oldloc); +} + START_TEST(msvcp140) { if(!init()) return; @@ -1698,5 +1761,6 @@ START_TEST(msvcp140) test_cnd(); test_Copy_file(); test__Mtx(); + test__Fiopen(); FreeLibrary(msvcp); }