[PATCH 2/2] msvcp140: Return the correct file type from _Read_dir and _Open_dir.

Stefan Dösinger stefan at codeweavers.com
Thu Jul 13 10:40:28 CDT 2017


Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
---
 dlls/msvcp140/msvcp140.spec    |   4 +-
 dlls/msvcp140/tests/msvcp140.c | 122 +++++++++++++++++++++++++++++++++++++++++
 dlls/msvcp90/ios.c             |  44 +++++++++++++++
 3 files changed, 168 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec
index afada991d3..ac2599a851 100644
--- a/dlls/msvcp140/msvcp140.spec
+++ b/dlls/msvcp140/msvcp140.spec
@@ -3689,10 +3689,10 @@
 @ stub _Mtxlock
 @ stub _Mtxunlock
 @ extern _Nan _Nan
-@ cdecl _Open_dir(ptr wstr long long) tr2_sys__Open_dir_wchar
+@ cdecl _Open_dir(ptr wstr long long)
 @ cdecl -ret64 _Query_perf_counter()
 @ cdecl -ret64 _Query_perf_frequency()
-@ cdecl _Read_dir(ptr ptr ptr) tr2_sys__Read_dir_wchar
+@ cdecl _Read_dir(ptr ptr ptr)
 @ stub _Remove_dir
 @ stub _Rename
 @ stub _Resize
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c
index 000d727f76..f6b7b9c8ac 100644
--- a/dlls/msvcp140/tests/msvcp140.c
+++ b/dlls/msvcp140/tests/msvcp140.c
@@ -158,10 +158,13 @@ static int (__cdecl *p__Schedule_chore)(_Threadpool_chore*);
 static int (__cdecl *p__Reschedule_chore)(const _Threadpool_chore*);
 static void (__cdecl *p__Release_chore)(_Threadpool_chore*);
 
+static void (__cdecl *p_Close_dir)(void*);
 static MSVCP_bool (__cdecl *p_Current_get)(WCHAR *);
 static MSVCP_bool (__cdecl *p_Current_set)(WCHAR const *);
 static ULONGLONG (__cdecl *p_File_size)(WCHAR const *);
 static enum file_type (__cdecl *p_Lstat)(WCHAR const *, int *);
+static void* (__cdecl *p_Open_dir)(WCHAR*, WCHAR const*, int *, enum file_type*);
+static WCHAR* (__cdecl *p_Read_dir)(WCHAR*, void*, enum file_type*);
 static enum file_type (__cdecl *p_Stat)(WCHAR const *, int *);
 static int (__cdecl *p_To_byte)(const WCHAR *src, char *dst);
 static int (__cdecl *p_To_wide)(const char *src, WCHAR *dst);
@@ -231,10 +234,13 @@ static BOOL init(void)
         SET(p__Release_chore, "?_Release_chore at details@Concurrency@@YAXPAU_Threadpool_chore at 12@@Z");
     }
 
+    SET(p_Close_dir, "_Close_dir");
     SET(p_Current_get, "_Current_get");
     SET(p_Current_set, "_Current_set");
     SET(p_File_size, "_File_size");
     SET(p_Lstat, "_Lstat");
+    SET(p_Open_dir, "_Open_dir");
+    SET(p_Read_dir, "_Read_dir");
     SET(p_Stat, "_Stat");
     SET(p_To_byte, "_To_byte");
     SET(p_To_wide, "_To_wide");
@@ -823,6 +829,121 @@ static void test_Stat(void)
     ok(SetCurrentDirectoryW(origin_path), "SetCurrentDirectoryW to origin_path failed\n");
 }
 
+static void test_dir_operation(void)
+{
+    WCHAR *file_name, first_file_name[MAX_PATH], dest[MAX_PATH], longer_path[MAX_PATH];
+    WCHAR origin_path[MAX_PATH], temp_path[MAX_PATH];
+    HANDLE file, result_handle;
+    enum file_type type;
+    int err, num_of_f1 = 0, num_of_f2 = 0, num_of_sub_dir = 0, num_of_other_files = 0;
+    WCHAR test_dirW[] = {'w','i','n','e','_','t','e','s','t','_','d','i','r',0};
+    WCHAR test_f1W[] = {'w','i','n','e','_','t','e','s','t','_','d','i','r','/','f','1',0};
+    WCHAR test_f2W[] = {'w','i','n','e','_','t','e','s','t','_','d','i','r','/','f','2',0};
+    WCHAR test_sub_dirW[] = {'w','i','n','e','_','t','e','s','t','_','d','i','r','/','s','u','b','_','d','i','r',0};
+    WCHAR test_sub_dir_f1W[] = {'w','i','n','e','_','t','e','s','t','_','d','i','r',
+            '/','s','u','b','_','d','i','r','/','f','1',0};
+    WCHAR backslashW[] = {'\\',0};
+    WCHAR sW[] = {'s',0};
+    WCHAR f1W[] = {'f','1',0};
+    WCHAR f2W[] = {'f','2',0};
+    WCHAR sub_dirW[] = {'s','u','b','_','d','i','r',0};
+    WCHAR not_existW[] = {'n','o','t','_','e','x','i','s','t',0};
+    WCHAR emtpy_dirW[] = {'e','m','p','t','y','_','d','i','r',0};
+
+    memset(origin_path, 0, sizeof(origin_path));
+    memset(origin_path, 0, sizeof(temp_path));
+    GetCurrentDirectoryW(MAX_PATH, origin_path);
+    GetTempPathW(MAX_PATH, temp_path);
+    ok(SetCurrentDirectoryW(temp_path), "SetCurrentDirectoryW to temp_path failed\n");
+
+    CreateDirectoryW(test_dirW, NULL);
+    file = CreateFileW(test_f1W, 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
+    ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
+    CloseHandle(file);
+    file = CreateFileW(test_f2W, 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
+    ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
+    CloseHandle(file);
+    CreateDirectoryW(test_sub_dirW, NULL);
+    file = CreateFileW(test_sub_dir_f1W, 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
+    ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
+    CloseHandle(file);
+
+    memcpy(longer_path, temp_path, sizeof(longer_path));
+    wcscat(longer_path, backslashW);
+    wcscat(longer_path, test_dirW);
+    wcscat(longer_path, backslashW);
+    while(lstrlenW(longer_path) < MAX_PATH-1)
+        wcscat(longer_path, sW);
+    memset(first_file_name, 0, sizeof(first_file_name));
+    type = err =  0xdeadbeef;
+    result_handle = NULL;
+    result_handle = p_Open_dir(first_file_name, longer_path, &err, &type);
+    ok(result_handle == NULL, "_Open_dir(): expect NULL, got %p\n", result_handle);
+    ok(!*first_file_name, "_Open_dir(): expect: 0, got %s\n", wine_dbgstr_w(first_file_name));
+    ok(err == ERROR_BAD_PATHNAME, "_Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
+    ok((int)type == 0xdeadbeef, "_Open_dir(): expect 0xdeadbeef, got %d\n", type);
+
+    memset(first_file_name, 0, sizeof(first_file_name));
+    memset(dest, 0, sizeof(dest));
+    err = type = 0xdeadbeef;
+    result_handle = NULL;
+    result_handle = p_Open_dir(first_file_name, test_dirW, &err, &type);
+    ok(result_handle != NULL, "_Open_dir(): expect: not NULL, got %p\n", result_handle);
+    ok(err == ERROR_SUCCESS, "_Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
+    file_name = first_file_name;
+    while(*file_name) {
+        if (!wcscmp(file_name, f1W)) {
+            ++num_of_f1;
+            ok(type == file_type_regular, "expect file_type_regular, got %d\n", type);
+        }else if(!wcscmp(file_name, f2W)) {
+            ++num_of_f2;
+            ok(type == file_type_regular, "expect file_type_regular, got %d\n", type);
+        }else if(!wcscmp(file_name, sub_dirW)) {
+            ++num_of_sub_dir;
+            ok(type == file_type_directory, "expect file_type_directory, got %d\n", type);
+        }else {
+            ++num_of_other_files;
+        }
+        file_name = p_Read_dir(dest, result_handle, &type);
+    }
+    p_Close_dir(result_handle);
+    ok(result_handle != NULL, "_Open_dir(): expect: not NULL, got %p\n", result_handle);
+    ok(num_of_f1 == 1, "found f1 %d times\n", num_of_f1);
+    ok(num_of_f2 == 1, "found f2 %d times\n", num_of_f2);
+    ok(num_of_sub_dir == 1, "found sub_dir %d times\n", num_of_sub_dir);
+    ok(num_of_other_files == 0, "found %d other files\n", num_of_other_files);
+
+    memset(first_file_name, 0, sizeof(first_file_name));
+    err = type = 0xdeadbeef;
+    result_handle = file;
+    result_handle = p_Open_dir(first_file_name, not_existW, &err, &type);
+    ok(result_handle == NULL, "_Open_dir(): expect: NULL, got %p\n", result_handle);
+    todo_wine ok(err == ERROR_BAD_PATHNAME, "_Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
+    ok((int)type == 0xdeadbeef, "_Open_dir(): expect: 0xdeadbeef, got %d\n", type);
+    ok(!*first_file_name, "_Open_dir(): expect: 0, got %s\n", wine_dbgstr_w(first_file_name));
+
+    CreateDirectoryW(emtpy_dirW, NULL);
+    memset(first_file_name, 0, sizeof(first_file_name));
+    err = type = 0xdeadbeef;
+    result_handle = file;
+    result_handle = p_Open_dir(first_file_name, emtpy_dirW, &err, &type);
+    ok(result_handle == NULL, "_Open_dir(): expect: NULL, got %p\n", result_handle);
+    ok(err == ERROR_SUCCESS, "_Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
+    ok(type == file_type_unknown, "_Open_dir(): expect: file_type_unknown, got %d\n", type);
+    ok(!*first_file_name, "_Open_dir(): expect: 0, got %s\n", wine_dbgstr_w(first_file_name));
+    p_Close_dir(result_handle);
+    ok(result_handle == NULL, "_Open_dir(): expect: NULL, got %p\n", result_handle);
+
+    ok(RemoveDirectoryW(emtpy_dirW), "expect empty_dir to exist\n");
+    ok(DeleteFileW(test_sub_dir_f1W), "expect wine_test_dir/sub_dir/sub_f1 to exist\n");
+    ok(RemoveDirectoryW(test_sub_dirW), "expect wine_test_dir/sub_dir to exist\n");
+    ok(DeleteFileW(test_f1W), "expect wine_test_dir/f1 to exist\n");
+    ok(DeleteFileW(test_f2W), "expect wine_test_dir/f2 to exist\n");
+    ok(RemoveDirectoryW(test_dirW), "expect wine_test_dir to exist\n");
+
+    ok(SetCurrentDirectoryW(origin_path), "SetCurrentDirectoryW to origin_path failed\n");
+}
+
 START_TEST(msvcp140)
 {
     if(!init()) return;
@@ -838,5 +959,6 @@ START_TEST(msvcp140)
     test_Current_get();
     test_Current_set();
     test_Stat();
+    test_dir_operation();
     FreeLibrary(msvcp);
 }
diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c
index 1c499b6561..362cd26a55 100644
--- a/dlls/msvcp90/ios.c
+++ b/dlls/msvcp90/ios.c
@@ -355,6 +355,27 @@ enum msvcp140_file_type {
     msvcp140_file_type_character, msvcp140_file_type_fifo, msvcp140_file_type_socket, msvcp140_file_type_unknown
 };
 
+static enum msvcp140_file_type file_type_120_to_140(enum file_type in)
+{
+    switch (in)
+    {
+        case status_unknown: return msvcp140_file_type_unknown;
+        case file_not_found: return msvcp140_file_type_not_found;
+        case regular_file: return msvcp140_file_type_regular;
+        case directory_file: return msvcp140_file_type_directory;
+        case symlink_file: return msvcp140_file_type_symlink;
+        case block_file: return msvcp140_file_type_block;
+        case character_file: return msvcp140_file_type_character;
+        case fifo_file: return msvcp140_file_type_fifo;
+        case socket_file: return msvcp140_file_type_socket;
+        default:
+            ERR("Unexpected msvcp120 file type %d\n", in);
+            /* Drop through */
+        case type_unknown:
+            return msvcp140_file_type_unknown;
+    }
+}
+
 #if _MSVCP_VER >= 110
 #define BASIC_IOS_VTORDISP 1
 #define INIT_BASIC_IOS_VTORDISP(basic_ios) ((int*)basic_ios)[-1] = 0
@@ -14941,6 +14962,18 @@ void* __cdecl tr2_sys__Open_dir_wchar(wchar_t* target, wchar_t const* dest, int*
     return handle;
 }
 
+/* _Open_dir, msvcp140 version. Different file_type enum. */
+void* __cdecl _Open_dir(wchar_t* target, wchar_t const* dest, int* err_code, enum msvcp140_file_type* type)
+{
+    enum file_type type120;
+    void* ret;
+
+    ret = tr2_sys__Open_dir_wchar(target, dest, err_code, &type120);
+    if (*err_code == ERROR_SUCCESS)
+        *type = file_type_120_to_140(type120);
+    return ret;
+}
+
 /* ?_Open_dir at sys@tr2 at std@@YAPAXAAY0BAE at DPBDAAHAAW4file_type@123@@Z */
 /* ?_Open_dir at sys@tr2 at std@@YAPEAXAEAY0BAE at DPEBDAEAHAEAW4file_type@123@@Z */
 void* __cdecl tr2_sys__Open_dir(char* target, char const* dest, int* err_code, enum file_type* type)
@@ -14992,6 +15025,17 @@ wchar_t* __cdecl tr2_sys__Read_dir_wchar(wchar_t* target, void* handle, enum fil
     return target;
 }
 
+/* _Read_dir, msvcp140 version. Different file_type enum. */
+wchar_t* __cdecl _Read_dir(wchar_t* target, void* handle, enum msvcp140_file_type* type)
+{
+    enum file_type type120;
+    void* ret;
+
+    ret = tr2_sys__Read_dir_wchar(target, handle, &type120);
+    *type = file_type_120_to_140(type120);
+    return ret;
+}
+
 /* ?_Read_dir at sys@tr2 at std@@YAPADAAY0BAE at DPAXAAW4file_type@123@@Z */
 /* ?_Read_dir at sys@tr2 at std@@YAPEADAEAY0BAE at DPEAXAEAW4file_type@123@@Z */
 char* __cdecl tr2_sys__Read_dir(char* target, void* handle, enum file_type* type)
-- 
2.13.0




More information about the wine-patches mailing list