[PATCH] msvcp140: Add _Copy_file and port tests.

Gijs Vermeulen gijsvrm at gmail.com
Mon Feb 11 11:02:48 CST 2019


Signed-off-by: Gijs Vermeulen <gijsvrm at gmail.com>
---
 dlls/msvcp140/msvcp140.spec    |  2 +-
 dlls/msvcp140/tests/msvcp140.c | 66 ++++++++++++++++++++++++++++++++++
 dlls/msvcp90/ios.c             |  6 ++++
 3 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec
index 6a4eb14c04..75ed8fb9a6 100644
--- a/dlls/msvcp140/msvcp140.spec
+++ b/dlls/msvcp140/msvcp140.spec
@@ -3632,7 +3632,7 @@
 @ cdecl _Cnd_timedwait(ptr ptr ptr)
 @ cdecl _Cnd_unregister_at_thread_exit(ptr)
 @ cdecl _Cnd_wait(ptr ptr)
-@ stub _Copy_file
+@ cdecl _Copy_file(wstr wstr long)
 @ stub _Cosh
 @ cdecl _Current_get(ptr)
 @ cdecl _Current_set(wstr) tr2_sys__Current_set_wchar
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c
index b2bdafa4ad..53fb0ebe9c 100644
--- a/dlls/msvcp140/tests/msvcp140.c
+++ b/dlls/msvcp140/tests/msvcp140.c
@@ -174,6 +174,7 @@ 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 int (__cdecl *p_Copy_file)(WCHAR const*, WCHAR const*, MSVCP_bool);
 static MSVCP_bool (__cdecl *p_Current_get)(WCHAR *);
 static MSVCP_bool (__cdecl *p_Current_set)(WCHAR const *);
 static int (__cdecl *p_Equivalent)(WCHAR const*, WCHAR const*);
@@ -266,6 +267,7 @@ static BOOL init(void)
     }
 
     SET(p_Close_dir, "_Close_dir");
+    SET(p_Copy_file, "_Copy_file");
     SET(p_Current_get, "_Current_get");
     SET(p_Current_set, "_Current_set");
     SET(p_Equivalent, "_Equivalent");
@@ -1428,6 +1430,69 @@ static void test_Equivalent(void)
     ok(SetCurrentDirectoryW(current_path), "SetCurrentDirectoryW failed\n");
 }
 
+static void test_Copy_file(void)
+{
+    HANDLE file;
+    int ret, i;
+    LARGE_INTEGER file_size;
+    static const WCHAR wine_test_dirW[] =
+            {'w','i','n','e','_','t','e','s','t','_','d','i','r',0};
+    static const WCHAR wine_test_dirW_copy[] =
+            {'w','i','n','e','_','t','e','s','t','_','d','i','r','_','c','o','p','y',0};
+    static const WCHAR f1W[] =
+            {'w','i','n','e','_','t','e','s','t','_','d','i','r','/','f','1',0};
+    static const WCHAR f1W_copy[] =
+            {'w','i','n','e','_','t','e','s','t','_','d','i','r','/','f','1','_','c','o','p','y',0};
+    static const WCHAR f1W_copy_backslash[] =
+            {'w','i','n','e','_','t','e','s','t','_','d','i','r','\\','f','1','_','c','o','p','y',0};
+    static const WCHAR not_existW[] =
+            {'n','o','t','_','e','x','i','s','t',0};
+    static const WCHAR not_exist_dir_backslash_f1_copyW[] =
+            {'n','o','t','_','e','x','i','s','t','_','d','i','r','\\','f','1','_','c','o','p','y',0};
+    static const struct {
+        const WCHAR *source;
+        const WCHAR *dest;
+        MSVCP_bool fail_if_exists;
+        int last_error;
+        int last_error2;
+    } tests[] = {
+        { f1W, f1W_copy, TRUE, ERROR_SUCCESS, ERROR_SUCCESS },
+        { f1W, f1W_copy_backslash, TRUE, ERROR_SUCCESS, ERROR_SUCCESS },
+        { f1W, f1W_copy_backslash, TRUE, ERROR_SUCCESS, ERROR_SUCCESS },
+        { f1W, f1W_copy_backslash, FALSE, ERROR_SUCCESS, ERROR_SUCCESS },
+        { wine_test_dirW, f1W, TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
+        { wine_test_dirW, wine_test_dirW_copy, TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
+        { not_existW, wine_test_dirW, TRUE, ERROR_FILE_NOT_FOUND, ERROR_FILE_NOT_FOUND },
+        { f1W, not_exist_dir_backslash_f1_copyW, TRUE, ERROR_PATH_NOT_FOUND, ERROR_FILE_NOT_FOUND },
+        { f1W, wine_test_dirW, TRUE, ERROR_ACCESS_DENIED, ERROR_FILE_EXISTS }
+    };
+
+    ret = p_Make_dir(wine_test_dirW);
+    ok(ret == 1, "_Make_dir(): expect 1 got %d\n", ret);
+    file = CreateFileW(f1W, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+    ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
+    file_size.QuadPart = 7;
+    ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
+    ok(SetEndOfFile(file), "SetEndOfFile failed\n");
+    CloseHandle(file);
+
+    for(i=0; i<ARRAY_SIZE(tests); i++) {
+        errno = 0xdeadbeef;
+        ret = p_Copy_file(tests[i].source, tests[i].dest, tests[i].fail_if_exists);
+        ok(ret == tests[i].last_error || ret == tests[i].last_error2,
+                "_Copy_file(): test %d expect: %d, got %d\n", i+1, tests[i].last_error, ret);
+        ok(errno == 0xdeadbeef, "_Copy_file(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
+        if(ret == ERROR_SUCCESS)
+            ok(p_File_size(tests[i].source) == p_File_size(tests[i].dest),
+                    "_Copy_file(): test %d failed, two files' size are not equal\n", i+1);
+    }
+
+    ok(DeleteFileW(f1W), "expect f1 to exist\n");
+    ok(DeleteFileW(f1W_copy), "expect f1_copy to exist\n");
+    ret = p_Remove_dir(wine_test_dirW);
+    ok(ret == 1, "_Remove_dir(): expect 1 got %d\n", ret);
+}
+
 START_TEST(msvcp140)
 {
     if(!init()) return;
@@ -1452,5 +1517,6 @@ START_TEST(msvcp140)
     test__Winerror_message();
     test__Winerror_map();
     test_Equivalent();
+    test_Copy_file();
     FreeLibrary(msvcp);
 }
diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c
index 7f792d6ef9..00854f4ab5 100644
--- a/dlls/msvcp90/ios.c
+++ b/dlls/msvcp90/ios.c
@@ -15693,6 +15693,12 @@ int __cdecl tr2_sys__Copy_file_wchar(WCHAR const* source, WCHAR const* dest, MSV
     return GetLastError();
 }
 
+/* _Copy_file, msvcp140 version. */
+int __cdecl _Copy_file(WCHAR const* source, WCHAR const* dest, MSVCP_bool fail_if_exists)
+{
+    return tr2_sys__Copy_file_wchar(source, dest, FALSE);
+}
+
 /* ?_Rename at sys@tr2 at std@@YAHPB_W0 at Z */
 /* ?_Rename at sys@tr2 at std@@YAHPEB_W0 at Z */
 int __cdecl tr2_sys__Rename_wchar(WCHAR const* old_path, WCHAR const* new_path)
-- 
2.20.1




More information about the wine-devel mailing list