From: Ziqing Hui zhui@codeweavers.com
--- dlls/shell32/tests/shlfileop.c | 356 +++++++++++---------------------- 1 file changed, 113 insertions(+), 243 deletions(-)
diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c index d69995d06eb..46d32390c8c 100644 --- a/dlls/shell32/tests/shlfileop.c +++ b/dlls/shell32/tests/shlfileop.c @@ -913,16 +913,10 @@ static void test_rename(void) static void test_copy(void) { char from[5 * MAX_PATH], to[5 * MAX_PATH]; - SHFILEOPSTRUCTA shfo; DWORD retval; LPSTR ptr; BOOL ret;
- shfo.hwnd = NULL; - shfo.wFunc = FO_COPY; - shfo.hNameMappings = NULL; - shfo.lpszProgressTitle = NULL; - /* Sources and targets have the same number, no FOF_MULTIDESTFILES. */ set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0"); set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0"); @@ -1180,14 +1174,11 @@ static void test_copy(void) RemoveDirectoryA("c.txt"); }
- /* copy a directory with a file beneath it, plus some files */ + /* Copy a file and a dir containing file to another dir. */ createTestFile("test4.txt\a.txt"); - shfo.pFrom = "test4.txt\0test1.txt\0"; - shfo.pTo = "testdir2\0"; - shfo.fFlags &= ~FOF_MULTIDESTFILES; - shfo.fAnyOperationsAborted = FALSE; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI, + "test4.txt\0test1.txt\0", "testdir2\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("testdir2\test1.txt"), "Expected testdir2\test1.txt to exist\n"); ok(DeleteFileA("testdir2\test4.txt\a.txt"), "Expected a.txt to exist\n"); ok(RemoveDirectoryA("testdir2\test4.txt"), "Expected testdir2\test4.txt to exist\n"); @@ -1210,214 +1201,146 @@ static void test_copy(void) RemoveDirectoryA("nonexistent"); DeleteFileA("test4.txt\a.txt");
- /* destination is same as source file */ - shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0"; - shfo.pTo = "b.txt\0test2.txt\0c.txt\0"; - shfo.fAnyOperationsAborted = FALSE; - shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES; - retval = SHFileOperationA(&shfo); - ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %ld\n", retval); + /* Target file is same as source file. */ + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, + "test1.txt\0test2.txt\0test3.txt\0", "b.txt\0test2.txt\0c.txt\0", + DE_SAMEFILE, FALSE, FALSE, FALSE); ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n"); - ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n"); ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
- /* destination is same as source directory */ - shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0"; - shfo.pTo = "b.txt\0test4.txt\0c.txt\0"; - shfo.fAnyOperationsAborted = FALSE; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %ld\n", retval); + /* Target dir is same as source dir. */ + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, + "test1.txt\0test4.txt\0test3.txt\0", "b.txt\0test4.txt\0c.txt\0", + DE_DESTSAMETREE, FALSE, TRUE, FALSE); ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n"); ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
- /* copy a directory into itself, error displayed in UI */ - shfo.pFrom = "test4.txt\0"; - shfo.pTo = "test4.txt\newdir\0"; - shfo.fFlags &= ~FOF_MULTIDESTFILES; - shfo.fAnyOperationsAborted = FALSE; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == DE_DESTSUBTREE, "Expected DE_DESTSUBTREE, got %ld\n", retval); + /* Copy a dir into it's subdir. */ + check_file_operation(FO_COPY, FOF_NO_UI, + "test4.txt\0", "test4.txt\newdir\0", + DE_DESTSUBTREE, FALSE, TRUE, FALSE); ok(!RemoveDirectoryA("test4.txt\newdir"), "Expected test4.txt\newdir to not exist\n");
- /* copy a directory to itself, error displayed in UI */ - shfo.pFrom = "test4.txt\0"; - shfo.pTo = "test4.txt\0"; - shfo.fAnyOperationsAborted = FALSE; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == DE_DESTSUBTREE, "Expected DE_DESTSUBTREE, got %ld\n", retval); + /* Copy a dir into itself. */ + check_file_operation(FO_COPY, FOF_NO_UI, "test4.txt\0", "test4.txt\0", + DE_DESTSUBTREE, FALSE, TRUE, FALSE);
- /* copy a file into a directory, and the directory into itself */ - shfo.pFrom = "test1.txt\0test4.txt\0"; - shfo.pTo = "test4.txt\0"; - shfo.fAnyOperationsAborted = FALSE; - shfo.fFlags |= FOF_NOCONFIRMATION; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == DE_DESTSUBTREE, "Expected DE_DESTSUBTREE, got %ld\n", retval); + /* Copy a file into a dir, and the dir into itself. */ + check_file_operation(FO_COPY, FOF_NO_UI, + "test1.txt\0test4.txt\0", "test4.txt\0", + DE_DESTSUBTREE, FALSE, TRUE, FALSE); ok(DeleteFileA("test4.txt\test1.txt"), "Expected test4.txt\test1.txt to exist\n");
- /* copy a file to a file, and the directory into itself */ - shfo.pFrom = "test1.txt\0test4.txt\0"; - shfo.pTo = "test4.txt\a.txt\0"; - shfo.fAnyOperationsAborted = FALSE; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == DE_DESTSUBTREE, "Expected DE_DESTSUBTREE, got %ld\n", retval); + /* Copy a file to a file, and the dir into it's subdir. */ + check_file_operation(FO_COPY, FOF_NO_UI, + "test1.txt\0test4.txt\0", "test4.txt\a.txt\0", + DE_DESTSUBTREE, FALSE, TRUE, TRUE); todo_wine ok(DeleteFileA("test4.txt\a.txt\test1.txt"), "Expected test4.txt\a.txt\test1.txt to exist\n"); RemoveDirectoryA("test4.txt\a.txt");
- /* copy a nonexistent file to a nonexistent directory */ - shfo.pFrom = "e.txt\0"; - shfo.pTo = "nonexistent\0"; - shfo.fAnyOperationsAborted = FALSE; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", retval); + /* Copy a nonexistent file to a nonexistent dir. */ + check_file_operation(FO_COPY, FOF_NO_UI, "e.txt\0", "nonexistent\0", + ERROR_FILE_NOT_FOUND, FALSE, TRUE, FALSE); ok(!file_exists("nonexistent\e.txt"), "Expected nonexistent\e.txt to not exist\n"); ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
/* Overwrite tests */ clean_after_shfo_tests(); init_shfo_tests(); - shfo.fFlags = FOF_NOCONFIRMATION; - shfo.pFrom = "test1.txt\0"; - shfo.pTo = "test2.txt\0"; - shfo.fAnyOperationsAborted = 0xdeadbeef; - /* without FOF_NOCONFIRMATION the confirmation is Yes/No */ - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); - ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n"); + + /* Without FOF_NOCONFIRMATION the confirmation is Yes/No. */ + check_file_operation(FO_COPY, FOF_NOCONFIRMATION, "test1.txt\0", "test2.txt\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(file_has_content("test2.txt", "test1.txt\n"), "The file was not copied\n");
- shfo.pFrom = "test3.txt\0test1.txt\0"; - shfo.pTo = "test2.txt\0one.txt\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_MULTIDESTFILES; - /* without FOF_NOCONFIRMATION the confirmation is Yes/Yes to All/No/Cancel */ - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + /* Without FOF_NOCONFIRMATION the confirmation is Yes/Yes to All/No/Cancel */ + check_file_operation(FO_COPY, FOF_NOCONFIRMATION | FOF_MULTIDESTFILES, + "test3.txt\0test1.txt\0", "test2.txt\0one.txt\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(file_has_content("test2.txt", "test3.txt\n"), "The file was not copied\n");
- shfo.pFrom = "one.txt\0"; - shfo.pTo = "testdir2\0"; - shfo.fFlags = FOF_NOCONFIRMATION; - /* without FOF_NOCONFIRMATION the confirmation is Yes/No */ - retval = SHFileOperationA(&shfo); - ok(retval == 0, "Expected 0, got %ld\n", retval); + /* Without FOF_NOCONFIRMATION the confirmation is Yes/No */ + check_file_operation(FO_COPY, FOF_NOCONFIRMATION, "one.txt\0", "testdir2\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(file_has_content("testdir2\one.txt", "test1.txt\n"), "The file was not copied\n");
createTestFile("test4.txt\test1.txt"); - shfo.pFrom = "test4.txt\0"; - shfo.pTo = "testdir2\0"; - /* WinMe needs FOF_NOERRORUI */ - shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); - shfo.fFlags = FOF_NOCONFIRMATION; - if (ERROR_SUCCESS) - { - createTestFile("test4.txt\.\test1.txt"); /* modify the content of the file */ - /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */ - retval = SHFileOperationA(&shfo); - ok(retval == 0, "Expected 0, got %ld\n", retval); - ok(file_has_content("testdir2\test4.txt\test1.txt", "test4.txt\.\test1.txt\n"), "The file was not copied\n"); - } + check_file_operation(FO_COPY, FOF_NOCONFIRMATION, "test4.txt\0", "testdir2\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE);
- createTestFile("one.txt"); + createTestFile("test4.txt\.\test1.txt"); /* Modify the content of the file. */ + /* Without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ...". */ + check_file_operation(FO_COPY, FOF_NOCONFIRMATION, "test4.txt\0", "testdir2\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); + ok(file_has_content("testdir2\test4.txt\test1.txt", "test4.txt\.\test1.txt\n"), "The file was not copied\n");
/* pFrom contains bogus 2nd name longer than MAX_PATH */ + createTestFile("one.txt"); memset(from, 'a', MAX_PATH*2); memset(from+MAX_PATH*2, 0, 2); lstrcpyA(from, "one.txt"); - shfo.pFrom = from; - shfo.pTo = "two.txt\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == DE_INVALIDFILES, "Unexpected return value, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI, from, "two.txt\0", + DE_INVALIDFILES, FALSE, TRUE, FALSE); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); todo_wine ok(RemoveDirectoryA("two.txt"), "Expected two.txt to exist\n");
+ /* pTo contains bogus 2nd name longer than MAX_PATH, no FOF_MULTIDESTFILES. */ createTestFile("one.txt"); - - /* pTo contains bogus 2nd name longer than MAX_PATH */ memset(to, 'a', MAX_PATH*2); memset(to+MAX_PATH*2, 0, 2); lstrcpyA(to, "two.txt"); - shfo.pFrom = "one.txt\0"; - shfo.pTo = to; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI, "one.txt\0", to, + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ /* Copy one file to two files, no FOF_MULTIDESTFILES. */ createTestFile("one.txt"); - - /* no FOF_MULTIDESTFILES, two files in pTo */ - shfo.pFrom = "one.txt\0"; - shfo.pTo = "two.txt\0three.txt\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI, + "one.txt\0", "two.txt\0three.txt\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); - - createTestFile("one.txt"); + ok(!DeleteFileA("three.txt"), "Expected file to not exist.\n");
/* both pFrom and pTo contain bogus 2nd names longer than MAX_PATH */ + createTestFile("one.txt"); memset(from, 'a', MAX_PATH*2); memset(from+MAX_PATH*2, 0, 2); memset(to, 'a', MAX_PATH*2); memset(to+MAX_PATH*2, 0, 2); lstrcpyA(from, "one.txt"); lstrcpyA(to, "two.txt"); - shfo.pFrom = from; - shfo.pTo = to; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == DE_INVALIDFILES, "Unexpected return value, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI, from, to, + DE_INVALIDFILES, FALSE, TRUE, FALSE); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); todo_wine ok(RemoveDirectoryA("two.txt"), "Expected two.txt to exist\n");
+ /* pTo contains bogus 2nd name longer than MAX_PATH, with FOF_MULTIDESTFILES. */ createTestFile("one.txt"); - - /* pTo contains bogus 2nd name longer than MAX_PATH, FOF_MULTIDESTFILES */ memset(to, 'a', MAX_PATH*2); memset(to+MAX_PATH*2, 0, 2); lstrcpyA(to, "two.txt"); - shfo.pFrom = "one.txt\0"; - shfo.pTo = to; - shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | - FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "one.txt\0", to, + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); ok(DeleteFileA("one.txt"), "Expected file to exist\n");
+ /* pTo contains bogus 2nd name longer than MAX_PATH, + * multiple source files, nonexistent target dir, no FOF_MULTIDESTFILES. */ createTestFile("one.txt"); createTestFile("two.txt"); - - /* pTo contains bogus 2nd name longer than MAX_PATH, - * multiple source files, - * dest directory does not exist - */ memset(to, 'a', 2 * MAX_PATH); memset(to+MAX_PATH*2, 0, 2); lstrcpyA(to, "threedir"); - shfo.pFrom = "one.txt\0two.txt\0"; - shfo.pTo = to; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); + check_file_operation(FO_COPY, FOF_NO_UI, + "one.txt\0two.txt\0", to, + ERROR_SUCCESS, FALSE, TRUE, TRUE); todo_wine { - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld.\n", retval); ok(DeleteFileA("threedir\one.txt"), "Expected threedir\one.txt to exist.\n"); ok(DeleteFileA("threedir\two.txt"), "Expected threedir\one.txt to exist.\n"); ok(RemoveDirectoryA("threedir"), "Expected threedir to exist.\n"); @@ -1425,71 +1348,52 @@ static void test_copy(void) ok(DeleteFileA("one.txt"), "Expected file to exist\n"); ok(DeleteFileA("two.txt"), "Expected file to exist\n");
+ /* pTo contains bogus 2nd name longer than MAX_PATH, + * multiple source files, target dir exists, no FOF_MULTIDESTFILES. */ createTestFile("one.txt"); createTestFile("two.txt"); CreateDirectoryA("threedir", NULL); - - /* pTo contains bogus 2nd name longer than MAX_PATH, - * multiple source files, - * dest directory does exist - */ memset(to, 'a', 2 * MAX_PATH); memset(to+MAX_PATH*2, 0, 2); lstrcpyA(to, "threedir"); - shfo.pFrom = "one.txt\0two.txt\0"; - shfo.pTo = to; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI, + "one.txt\0two.txt\0", to, + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("threedir\one.txt"), "Expected file to exist\n"); ok(DeleteFileA("threedir\two.txt"), "Expected file to exist\n"); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
+ /* pTo contains bogus 2nd name longer than MAX_PATH, + * multiple source files, nonexistent target dir, with FOF_MULTIDESTFILES. */ createTestFile("one.txt"); createTestFile("two.txt"); - - /* pTo contains bogus 2nd name longer than MAX_PATH, - * multiple source files, FOF_MULTIDESTFILES - * dest dir does not exist - */ memset(to, 'a', 2 * MAX_PATH); memset(to+MAX_PATH*2, 0, 2); lstrcpyA(to, "threedir"); - shfo.pFrom = "one.txt\0two.txt\0"; - shfo.pTo = to; - shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | - FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, + "one.txt\0two.txt\0", to, + ERROR_ACCESS_DENIED, FALSE, TRUE, TRUE); ok(!DeleteFileA("threedir\one.txt"), "Expected file to not exist\n"); ok(!DeleteFileA("threedir\two.txt"), "Expected file to not exist\n"); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
+ /* pTo contains bogus 2nd name longer than MAX_PATH, + * multiple source files, target dir exists, with FOF_MULTIDESTFILES. */ createTestFile("one.txt"); createTestFile("two.txt"); CreateDirectoryA("threedir", NULL); - - /* pTo contains bogus 2nd name longer than MAX_PATH, - * multiple source files, FOF_MULTIDESTFILES - * dest dir does exist - */ memset(to, 'a', 2 * MAX_PATH); memset(to+MAX_PATH*2, 0, 2); lstrcpyA(to, "threedir"); ptr = to + lstrlenA(to) + 1; lstrcpyA(ptr, "fourdir"); - shfo.pFrom = "one.txt\0two.txt\0"; - shfo.pTo = to; - shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | - FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, + "one.txt\0two.txt\0", to, + ERROR_SUCCESS, FALSE, TRUE, TRUE); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); todo_wine @@ -1501,21 +1405,13 @@ static void test_copy(void) todo_wine ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
+ /* Same number sources and targets, first target dir exists, with FOF_MULTIDESTFILES. */ createTestFile("one.txt"); createTestFile("two.txt"); CreateDirectoryA("threedir", NULL); - - /* multiple source files, FOF_MULTIDESTFILES - * multiple dest files, but first dest dir exists - * num files in lists is equal - */ - shfo.pFrom = "one.txt\0two.txt\0"; - shfo.pTo = "threedir\0fourdir\0"; - shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | - FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == DE_FILEDESTISFLD, "Expected DE_FILEDESTISFLD. got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, + "one.txt\0two.txt\0", "threedir\0fourdir\0", + DE_FILEDESTISFLD, FALSE, TRUE, FALSE); ok(!DeleteFileA("threedir\one.txt"), "Expected file to not exist\n"); ok(!DeleteFileA("threedir\two.txt"), "Expected file to not exist\n"); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); @@ -1526,21 +1422,13 @@ static void test_copy(void) ok(!DeleteFileA("fourdir"), "Expected file to not exist\n"); ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
+ /* Targets outnumber sources, first target dir exists, with FOF_MULTIDESTFILES. */ createTestFile("one.txt"); createTestFile("two.txt"); CreateDirectoryA("threedir", NULL); - - /* multiple source files, FOF_MULTIDESTFILES - * multiple dest files, but first dest dir exists - * num files in lists is not equal - */ - shfo.pFrom = "one.txt\0two.txt\0"; - shfo.pTo = "threedir\0fourdir\0five\0"; - shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION | - FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - todo_wine - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, + "one.txt\0two.txt\0", "threedir\0fourdir\0five\0", + ERROR_SUCCESS, FALSE, TRUE, TRUE); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); todo_wine @@ -1561,31 +1449,25 @@ static void test_copy(void) CreateDirectoryA("two", NULL);
/* Test with FOF_MULTIDESTFILES with a wildcard in pFrom and single output directory. */ - shfo.pFrom = "a*.txt\0"; - shfo.pTo = "one\0"; - shfo.fFlags |= FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_MULTIDESTFILES; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, + "a*.txt\0", "one\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("one\aa.txt"), "Expected file to exist\n"); ok(DeleteFileA("one\ab.txt"), "Expected file to exist\n");
- /* pFrom has a glob, pTo has more than one dest */ - shfo.pFrom = "a*.txt\0"; - shfo.pTo = "one\0two\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + /* pFrom has a glob, pTo has more than one dest, no FOF_MULTIDESTFILES. */ + check_file_operation(FO_COPY, FOF_NO_UI, + "a*.txt\0", "one\0two\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("one\aa.txt"), "Expected file to exist\n"); ok(DeleteFileA("one\ab.txt"), "Expected file to exist\n"); ok(!DeleteFileA("two\aa.txt"), "Expected file to not exist\n"); ok(!DeleteFileA("two\ab.txt"), "Expected file to not exist\n");
/* pFrom has more than one glob, pTo has more than one dest, without FOF_MULTIDESTFILES. */ - shfo.pFrom = "a*.txt\0*b.txt\0"; - shfo.pTo = "one\0two\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI, + "a*.txt\0*b.txt\0", "one\0two\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("one\aa.txt"), "Expected file to exist\n"); ok(DeleteFileA("one\ab.txt"), "Expected file to exist\n"); ok(DeleteFileA("one\bb.txt"), "Expected file to exist\n"); @@ -1593,13 +1475,11 @@ static void test_copy(void) ok(!DeleteFileA("two\bb.txt"), "Expected file to exist\n");
/* pFrom has more than one glob, pTo has more than one dest, with FOF_MULTIDESTFILES. */ - shfo.pFrom = "a*.txt\0*b.txt\0"; - shfo.pTo = "one\0two\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_MULTIDESTFILES; - retval = SHFileOperationA(&shfo); + check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, + "a*.txt\0*b.txt\0", "one\0two\0", + ERROR_SUCCESS, FALSE, TRUE, TRUE); todo_wine { - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); ok(DeleteFileA("one\aa.txt"), "Expected file to exist\n"); ok(DeleteFileA("one\ab.txt"), "Expected file to exist\n"); ok(DeleteFileA("two\ab.txt"), "Expected file to exist\n"); @@ -1668,36 +1548,26 @@ static void test_copy(void) /* Check last error after a successful file operation. */ clean_after_shfo_tests(); init_shfo_tests(); - shfo.pFrom = "test1.txt\0"; - shfo.pTo = "testdir2\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; SetLastError(0xdeadbeef); - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "File copy failed with %ld\n", retval); - ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n"); + check_file_operation(FO_COPY, FOF_NO_UI, "test1.txt\0", "testdir2\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError());
/* Check last error after a failed file operation. */ clean_after_shfo_tests(); init_shfo_tests(); - shfo.pFrom = "nonexistent\0"; - shfo.pTo = "testdir2\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; SetLastError(0xdeadbeef); - retval = SHFileOperationA(&shfo); - ok(retval != ERROR_SUCCESS, "Unexpected ERROR_SUCCESS\n"); - ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n"); + check_file_operation(FO_COPY, FOF_NO_UI, "nonexistence\0", "testdir2\0", + ERROR_FILE_NOT_FOUND, FALSE, TRUE, FALSE); ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError());
/* test with / */ CreateDirectoryA("dir", NULL); CreateDirectoryA("dir\subdir", NULL); createTestFile("dir\subdir\aa.txt"); - shfo.pFrom = "dir/subdir/aa.txt\0"; - shfo.pTo = "dir\destdir/aa.txt\0"; - shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT | FOF_NOERRORUI; - retval = SHFileOperationA(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval); + check_file_operation(FO_COPY, FOF_NO_UI, + "dir/subdir/aa.txt\0", "dir\destdir/aa.txt\0", + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("dir\destdir\aa.txt"), "Expected file to exist\n"); ok(RemoveDirectoryA("dir\destdir"), "Expected dir to exist\n"); ok(DeleteFileA("dir\subdir\aa.txt"), "Expected file to exist\n");
From: Ziqing Hui zhui@codeweavers.com
--- dlls/shell32/shlfileop.c | 5 +++-- dlls/shell32/tests/shlfileop.c | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c index d71eb6b968d..cc7944a2851 100644 --- a/dlls/shell32/shlfileop.c +++ b/dlls/shell32/shlfileop.c @@ -1543,8 +1543,6 @@ static DWORD rename_files(SHFILEOPSTRUCTW *op, const FILE_LIST *from, const FILE if (!to->dwNumFiles) return DE_DIFFDIR; entry_to = &to->feFiles[0]; - if (entry_to->bFromWildcard) - return ERROR_INVALID_NAME;
if (wcscmp(entry_from->szDirectory, entry_to->szDirectory) != 0) return DE_DIFFDIR; @@ -1596,6 +1594,9 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) op.bManyItems = (flFrom.dwNumFiles > 1); lpFileOp->fAnyOperationsAborted = FALSE;
+ if (flTo.bAnyFromWildcard) + return ERROR_INVALID_NAME; + switch (lpFileOp->wFunc) { case FO_COPY: diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c index 46d32390c8c..25c502a73b8 100644 --- a/dlls/shell32/tests/shlfileop.c +++ b/dlls/shell32/tests/shlfileop.c @@ -1486,6 +1486,11 @@ static void test_copy(void) ok(DeleteFileA("two\bb.txt"), "Expected file to exist\n"); }
+ /* Wildcard target. */ + check_file_operation(FO_COPY, FOF_NO_UI, "aa.txt\0", "tw?\0", + ERROR_INVALID_NAME, FALSE, FALSE, FALSE); + ok(!file_exists("two\aa.txt"), "Expected file to not exist\n"); + ok(DeleteFileA("aa.txt"), "Expected file to exist\n"); ok(DeleteFileA("ab.txt"), "Expected file to exist\n"); ok(DeleteFileA("bb.txt"), "Expected file to exist\n"); @@ -1586,7 +1591,7 @@ static void test_move(void) set_curr_dir_path(from, "testdir2\*.*\0"); set_curr_dir_path(to, "test4.txt\*.*\0"); check_file_operation(FO_MOVE, FOF_NO_UI, from, to, - ERROR_INVALID_NAME, FALSE, TRUE, FALSE); + ERROR_INVALID_NAME, FALSE, FALSE, FALSE);
ok(file_exists("testdir2"), "dir should not be moved\n"); ok(file_exists("testdir2\one.txt"), "file should not be moved\n");
From: Ziqing Hui zhui@codeweavers.com
--- dlls/shell32/shlfileop.c | 71 ++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 29 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c index cc7944a2851..0e6e88b22e9 100644 --- a/dlls/shell32/shlfileop.c +++ b/dlls/shell32/shlfileop.c @@ -943,17 +943,12 @@ static inline void grow_list(FILE_LIST *list) list->num_alloc *= 2; }
-static void add_file_entry(FILE_LIST *file_list, DWORD index, +static void file_entry_init(FILE_ENTRY *file_entry, const WCHAR *file_name, DWORD attributes, BOOL from_relative, BOOL from_wildcard) { size_t file_name_len = wcslen(file_name) + 1; - FILE_ENTRY *file_entry; const WCHAR *ptr;
- if (index >= file_list->num_alloc) - grow_list(file_list); - file_entry = &file_list->feFiles[index]; - file_entry->szFullPath = malloc(file_name_len * sizeof(WCHAR)); wcscpy(file_entry->szFullPath, file_name);
@@ -973,6 +968,30 @@ static void add_file_entry(FILE_LIST *file_list, DWORD index, file_entry->bFromRelative = from_relative; file_entry->bFromWildcard = from_wildcard; file_entry->bExists = (attributes != INVALID_FILE_ATTRIBUTES); +} + +static void file_entry_destroy(FILE_ENTRY *file_entry) +{ + if (!file_entry) + return; + if (file_entry->szDirectory) + free(file_entry->szDirectory); + if(file_entry->szFilename) + free(file_entry->szFilename); + if (file_entry->szFullPath) + free(file_entry->szFullPath); +} + +static void file_list_add_entry(FILE_LIST *file_list, DWORD index, + const WCHAR *file_name, DWORD attributes, BOOL from_relative, BOOL from_wildcard) +{ + FILE_ENTRY *file_entry; + + if (index >= file_list->num_alloc) + grow_list(file_list); + file_entry = &file_list->feFiles[index]; + + file_entry_init(file_entry, file_name, attributes, from_relative, from_wildcard);
if (IsAttribDir(attributes)) file_list->bAnyDirectories = TRUE; @@ -982,6 +1001,18 @@ static void add_file_entry(FILE_LIST *file_list, DWORD index, file_list->bAnyDontExist = TRUE; }
+static void file_list_destroy(FILE_LIST *flList) +{ + DWORD i; + + if (!flList || !flList->feFiles) + return; + + for (i = 0; i < flList->dwNumFiles; i++) + file_entry_destroy(&flList->feFiles[i]); + free(flList->feFiles); +} + static LPWSTR wildcard_to_file(LPCWSTR szWildCard, LPCWSTR szFileName) { LPCWSTR ptr; @@ -1013,7 +1044,7 @@ static void parse_wildcard_files(FILE_LIST *flList, LPCWSTR szFile, LPDWORD pdwL { if (IsDotDir(wfd.cFileName)) continue; szFullPath = wildcard_to_file(szFile, wfd.cFileName); - add_file_entry(flList, (*pdwListIndex)++, szFullPath, wfd.dwFileAttributes, from_relative, TRUE); + file_list_add_entry(flList, (*pdwListIndex)++, szFullPath, wfd.dwFileAttributes, from_relative, TRUE); free(szFullPath); }
@@ -1068,7 +1099,7 @@ static HRESULT parse_file_list(FILE_LIST *flList, LPCWSTR szFiles, BOOL parse_wi } else { - add_file_entry(flList, i, szCurFile, GetFileAttributesW(szCurFile), from_relative, from_wildcard); + file_list_add_entry(flList, i, szCurFile, GetFileAttributesW(szCurFile), from_relative, from_wildcard); }
/* advance to the next string */ @@ -1080,24 +1111,6 @@ static HRESULT parse_file_list(FILE_LIST *flList, LPCWSTR szFiles, BOOL parse_wi return S_OK; }
-/* free the FILE_LIST */ -static void destroy_file_list(FILE_LIST *flList) -{ - DWORD i; - - if (!flList || !flList->feFiles) - return; - - for (i = 0; i < flList->dwNumFiles; i++) - { - free(flList->feFiles[i].szDirectory); - free(flList->feFiles[i].szFilename); - free(flList->feFiles[i].szFullPath); - } - - free(flList->feFiles); -} - static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath) { WCHAR szFrom[MAX_PATH], szTo[MAX_PATH]; @@ -1205,7 +1218,7 @@ static int copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, FILE_LIST *fl GetCurrentDirectoryW(MAX_PATH, curdir); curdir[lstrlenW(curdir)+1] = 0;
- destroy_file_list(flTo); + file_list_destroy(flTo); ZeroMemory(flTo, sizeof(FILE_LIST)); parse_file_list(flTo, curdir, FALSE); fileDest = &flTo->feFiles[0]; @@ -1616,10 +1629,10 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) break; }
- destroy_file_list(&flFrom); + file_list_destroy(&flFrom);
if (lpFileOp->wFunc != FO_DELETE) - destroy_file_list(&flTo); + file_list_destroy(&flTo);
if (ret == ERROR_CANCELLED) lpFileOp->fAnyOperationsAborted = TRUE;
From: Ziqing Hui zhui@codeweavers.com
--- dlls/shell32/shlfileop.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c index 0e6e88b22e9..d21af483b6f 100644 --- a/dlls/shell32/shlfileop.c +++ b/dlls/shell32/shlfileop.c @@ -982,14 +982,14 @@ static void file_entry_destroy(FILE_ENTRY *file_entry) free(file_entry->szFullPath); }
-static void file_list_add_entry(FILE_LIST *file_list, DWORD index, +static void file_list_add_entry(FILE_LIST *file_list, const WCHAR *file_name, DWORD attributes, BOOL from_relative, BOOL from_wildcard) { FILE_ENTRY *file_entry;
- if (index >= file_list->num_alloc) + if (file_list->dwNumFiles >= file_list->num_alloc) grow_list(file_list); - file_entry = &file_list->feFiles[index]; + file_entry = &file_list->feFiles[file_list->dwNumFiles++];
file_entry_init(file_entry, file_name, attributes, from_relative, from_wildcard);
@@ -1031,7 +1031,7 @@ static LPWSTR wildcard_to_file(LPCWSTR szWildCard, LPCWSTR szFileName) return szFullPath; }
-static void parse_wildcard_files(FILE_LIST *flList, LPCWSTR szFile, LPDWORD pdwListIndex, BOOL from_relative) +static void parse_wildcard_files(FILE_LIST *file_list, LPCWSTR szFile, BOOL from_relative) { WIN32_FIND_DATAW wfd; HANDLE hFile = FindFirstFileW(szFile, &wfd); @@ -1044,7 +1044,7 @@ static void parse_wildcard_files(FILE_LIST *flList, LPCWSTR szFile, LPDWORD pdwL { if (IsDotDir(wfd.cFileName)) continue; szFullPath = wildcard_to_file(szFile, wfd.cFileName); - file_list_add_entry(flList, (*pdwListIndex)++, szFullPath, wfd.dwFileAttributes, from_relative, TRUE); + file_list_add_entry(file_list, szFullPath, wfd.dwFileAttributes, from_relative, TRUE); free(szFullPath); }
@@ -1057,7 +1057,6 @@ static HRESULT parse_file_list(FILE_LIST *flList, LPCWSTR szFiles, BOOL parse_wi LPCWSTR ptr = szFiles; WCHAR szCurFile[MAX_PATH]; WCHAR *p; - DWORD i = 0;
if (!szFiles) return ERROR_INVALID_PARAMETER; @@ -1093,20 +1092,13 @@ static HRESULT parse_file_list(FILE_LIST *flList, LPCWSTR szFiles, BOOL parse_wi
/* parse wildcard files if they are in the filename */ if (from_wildcard && parse_wildcard) - { - parse_wildcard_files(flList, szCurFile, &i, from_relative); - i--; - } + parse_wildcard_files(flList, szCurFile, from_relative); else - { - file_list_add_entry(flList, i, szCurFile, GetFileAttributesW(szCurFile), from_relative, from_wildcard); - } + file_list_add_entry(flList, szCurFile, GetFileAttributesW(szCurFile), from_relative, from_wildcard);
/* advance to the next string */ ptr += lstrlenW(ptr) + 1; - i++; } - flList->dwNumFiles = i;
return S_OK; }
From: Ziqing Hui zhui@codeweavers.com
--- dlls/shell32/shlfileop.c | 269 +++++++++++++-------------------- dlls/shell32/tests/shlfileop.c | 84 +++------- 2 files changed, 128 insertions(+), 225 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c index d21af483b6f..545568828ba 100644 --- a/dlls/shell32/shlfileop.c +++ b/dlls/shell32/shlfileop.c @@ -935,6 +935,7 @@ typedef struct BOOL bAnyDontExist; } FILE_LIST;
+static DWORD do_copy(FILE_OPERATION *op, const FILE_ENTRY *from, const FILE_ENTRY *to, BOOL append_file_name);
static inline void grow_list(FILE_LIST *list) { @@ -997,7 +998,7 @@ static void file_list_add_entry(FILE_LIST *file_list, file_list->bAnyDirectories = TRUE; if (from_wildcard) file_list->bAnyFromWildcard = TRUE; - if (!file_entry->bExists) + if (!file_entry->bExists && !file_entry->bFromWildcard) file_list->bAnyDontExist = TRUE; }
@@ -1103,76 +1104,6 @@ static HRESULT parse_file_list(FILE_LIST *flList, LPCWSTR szFiles, BOOL parse_wi return S_OK; }
-static void copy_dir_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, LPCWSTR szDestPath) -{ - WCHAR szFrom[MAX_PATH], szTo[MAX_PATH]; - SHFILEOPSTRUCTW fileOp; - - if (IsDotDir(feFrom->szFilename)) - return; - - if (PathFileExistsW(szDestPath)) - PathCombineW(szTo, szDestPath, feFrom->szFilename); - else - lstrcpyW(szTo, szDestPath); - - if (!(op->req->fFlags & FOF_NOCONFIRMATION) && PathFileExistsW(szTo)) { - if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FOLDER, feFrom->szFilename, op)) - { - /* Vista returns an ERROR_CANCELLED even if user pressed "No" */ - if (!op->bManyItems) - op->bCancelled = TRUE; - return; - } - } - - szTo[lstrlenW(szTo) + 1] = '\0'; - SHNotifyCreateDirectoryW(szTo, NULL); - - PathCombineW(szFrom, feFrom->szFullPath, L"*.*"); - szFrom[lstrlenW(szFrom) + 1] = '\0'; - - fileOp = *op->req; - fileOp.pFrom = szFrom; - fileOp.pTo = szTo; - fileOp.fFlags &= ~FOF_MULTIDESTFILES; /* we know we're copying to one dir */ - - /* Don't ask the user about overwriting files when he accepted to overwrite the - folder. FIXME: this is not exactly what Windows does - e.g. there would be - an additional confirmation for a nested folder */ - fileOp.fFlags |= FOF_NOCONFIRMATION; - - SHFileOperationW(&fileOp); -} - -static BOOL copy_file_to_file(FILE_OPERATION *op, const WCHAR *szFrom, const WCHAR *szTo) -{ - if (!(op->req->fFlags & FOF_NOCONFIRMATION) && PathFileExistsW(szTo)) - { - if (!SHELL_ConfirmDialogW(op->req->hwnd, ASK_OVERWRITE_FILE, PathFindFileNameW(szTo), op)) - return FALSE; - } - - return SHNotifyCopyFileW(szFrom, szTo, FALSE) == 0; -} - -/* copy a file or directory to another directory */ -static void copy_to_dir(FILE_OPERATION *op, const FILE_ENTRY *feFrom, const FILE_ENTRY *feTo) -{ - if (!PathFileExistsW(feTo->szFullPath)) - SHNotifyCreateDirectoryW(feTo->szFullPath, NULL); - - if (IsAttribFile(feFrom->attributes)) - { - WCHAR szDestPath[MAX_PATH]; - - PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename); - copy_file_to_file(op, feFrom->szFullPath, szDestPath); - } - else if (!(op->req->fFlags & FOF_FILESONLY && feFrom->bFromWildcard)) - copy_dir_to_dir(op, feFrom, feTo->szFullPath); -} - static void create_dest_dirs(LPCWSTR szDestDir) { WCHAR dir[MAX_PATH]; @@ -1192,130 +1123,135 @@ static void create_dest_dirs(LPCWSTR szDestDir) SHNotifyCreateDirectoryW(szDestDir, NULL); }
-/* the FO_COPY operation */ -static int copy_files(FILE_OPERATION *op, const FILE_LIST *flFrom, FILE_LIST *flTo) +static DWORD copy_wildcard(FILE_OPERATION *op, const FILE_ENTRY *from, const FILE_ENTRY *to) { - DWORD i; - const FILE_ENTRY *entryToCopy; - const FILE_ENTRY *fileDest = &flTo->feFiles[0]; + WCHAR buffer[MAX_PATH + 1] = {}; + FILE_LIST from_files; + DWORD i, ret;
- if (flFrom->bAnyDontExist) - return ERROR_SHELL_INTERNAL_FILE_NOT_FOUND; + wcscpy(buffer, from->szFullPath); + if ((ret = parse_file_list(&from_files, buffer, TRUE)) != ERROR_SUCCESS) + return ret;
- if (flTo->dwNumFiles == 0) + for (i = 0; i < from_files.dwNumFiles; ++i) { - /* If the destination is empty, SHFileOperation should use the current directory */ - WCHAR curdir[MAX_PATH+1]; + if ((ret = do_copy(op, &from_files.feFiles[i], to, TRUE)) != ERROR_SUCCESS) + break; + }
- GetCurrentDirectoryW(MAX_PATH, curdir); - curdir[lstrlenW(curdir)+1] = 0; + file_list_destroy(&from_files); + return ret; +}
- file_list_destroy(flTo); - ZeroMemory(flTo, sizeof(FILE_LIST)); - parse_file_list(flTo, curdir, FALSE); - fileDest = &flTo->feFiles[0]; - } +static DWORD copy_dir(FILE_OPERATION *op, const WCHAR *dir, const WCHAR *target) +{ + WCHAR buffer[MAX_PATH] = {}; + FILE_ENTRY from_dir, to_dir; + DWORD ret;
- if (op->req->fFlags & FOF_MULTIDESTFILES && flTo->dwNumFiles > 1) - { - if (flFrom->bAnyFromWildcard) - return ERROR_CANCELLED; + if (op->req->fFlags & FOF_FILESONLY) + return ERROR_SUCCESS;
- if (flFrom->dwNumFiles != flTo->dwNumFiles) - { - if (flFrom->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes)) - return ERROR_CANCELLED; + PathCombineW(buffer, dir, L"*.*"); + file_entry_init(&from_dir, buffer, INVALID_FILE_ATTRIBUTES, FALSE, TRUE); + file_entry_init(&to_dir, target, GetFileAttributesW(target), FALSE, FALSE);
- /* Free all but the first entry. */ - for (i = 1; i < flTo->dwNumFiles; i++) - { - free(flTo->feFiles[i].szDirectory); - free(flTo->feFiles[i].szFilename); - free(flTo->feFiles[i].szFullPath); - } + ret = do_copy(op, &from_dir, &to_dir, TRUE);
- flTo->dwNumFiles = 1; - } - else if (IsAttribDir(fileDest->attributes)) - { - for (i = 1; i < flTo->dwNumFiles; i++) - if (!IsAttribDir(flTo->feFiles[i].attributes) || - !IsAttribDir(flFrom->feFiles[i].attributes)) - { - return ERROR_CANCELLED; - } - } - } - else if (flFrom->dwNumFiles != 1) - { - if (flTo->dwNumFiles != 1 && !IsAttribDir(fileDest->attributes)) - return ERROR_CANCELLED; + file_entry_destroy(&to_dir); + file_entry_destroy(&from_dir); + return ret; +}
- if (PathFileExistsW(fileDest->szFullPath) && - IsAttribFile(fileDest->attributes)) - { - return ERROR_CANCELLED; - } +static DWORD do_copy(FILE_OPERATION *op, const FILE_ENTRY *from, const FILE_ENTRY *to, BOOL append_file_name) +{ + WCHAR target[MAX_PATH], target_dir[MAX_PATH];
- if (flTo->dwNumFiles == 1 && fileDest->bFromRelative && - !PathFileExistsW(fileDest->szFullPath)) - { - return ERROR_CANCELLED; - } + TRACE("Copying %s to %s, flags %#x, append_file_name %d.\n", + debugstr_w(from->szFullPath), debugstr_w(to->szFullPath), op->req->fFlags, append_file_name); + + /* Determine target path. */ + wcscpy(target_dir, to->szDirectory); + wcscpy(target, to->szFullPath); + if (append_file_name) + { + PathAppendW(target_dir, to->szFilename); + PathAppendW(target, from->szFilename); }
- for (i = 0; i < flFrom->dwNumFiles; i++) + /* Fail if target is illegal. */ + if (PathFileExistsW(target)) { - entryToCopy = &flFrom->feFiles[i]; + BOOL target_is_dir = !!PathIsDirectoryW(target); + if (target_is_dir != IsAttribDir(from->attributes)) + return target_is_dir ? DE_FILEDESTISFLD : DE_FLDDESTISFILE; + if (wcscmp(target, from->szFullPath) == 0) + return target_is_dir ? DE_DESTSAMETREE : DE_SAMEFILE; + } + if (PathIsPrefixW(from->szFullPath, to->szFullPath)) + return DE_DESTSUBTREE;
- if ((op->req->fFlags & FOF_MULTIDESTFILES) && - flTo->dwNumFiles > 1) - { - fileDest = &flTo->feFiles[i]; - } + /* Create target dir. */ + if (!PathFileExistsW(target_dir)) + SHCreateDirectoryExW(NULL, target_dir, NULL);
- if (IsAttribDir(entryToCopy->attributes) && - !lstrcmpiW(entryToCopy->szFullPath, fileDest->szDirectory)) - { - return ERROR_SUCCESS; - } + /* Source contains wildcard. */ + if (!!wcspbrk(from->szFullPath, L"*?")) + return copy_wildcard(op, from, to);
- create_dest_dirs(fileDest->szDirectory); + /* Source is a dir. */ + if (IsAttribDir(from->attributes)) + return copy_dir(op, from->szFullPath, target);
- if (!lstrcmpiW(entryToCopy->szFullPath, fileDest->szFullPath)) - { - if (IsAttribFile(entryToCopy->attributes)) - return ERROR_NO_MORE_SEARCH_HANDLES; - else - return ERROR_SUCCESS; - } + /* Source is a single file. */ + return SHNotifyCopyFileW(from->szFullPath, target, FALSE); +}
- if ((flFrom->dwNumFiles > 1 && flTo->dwNumFiles == 1) || - IsAttribDir(fileDest->attributes)) - { - copy_to_dir(op, entryToCopy, fileDest); - } - else if (IsAttribDir(entryToCopy->attributes)) +/* The FO_COPY operation. */ +static DWORD copy_files(FILE_OPERATION *op, const FILE_LIST *from, FILE_LIST *to) +{ + BOOL append_file_name, multi_dst, multi_src; + FILE_ENTRY current = {}, *target; + DWORD ret = ERROR_SUCCESS, i; + + if (from->bAnyDontExist) + return ERROR_FILE_NOT_FOUND; + + multi_src = from->dwNumFiles > 1; + multi_dst = op->req->fFlags & FOF_MULTIDESTFILES; + + /* Do copy operation for each source file. */ + for (i = 0; i < from->dwNumFiles; ++i) + { + DWORD target_index = multi_dst ? i : 0; + + if (target_index < to->dwNumFiles && to->feFiles[target_index].szFullPath[0] != '\0') { - copy_dir_to_dir(op, entryToCopy, fileDest->szFullPath); + target = &to->feFiles[target_index]; } else { - if (!copy_file_to_file(op, entryToCopy->szFullPath, fileDest->szFullPath)) + /* Empty target, use current directory. */ + if (!current.szFullPath) { - op->req->fAnyOperationsAborted = TRUE; - return ERROR_CANCELLED; + WCHAR buffer[MAX_PATH]; + GetCurrentDirectoryW(MAX_PATH, buffer); + file_entry_init(¤t, buffer, GetFileAttributesW(buffer), FALSE, FALSE); } + target = ¤t; }
- /* Vista return code. XP would return e.g. ERROR_FILE_NOT_FOUND, ERROR_ALREADY_EXISTS */ - if (op->bCancelled) - return ERROR_CANCELLED; + append_file_name = from->bAnyFromWildcard + || ((multi_src || IsAttribDir(target->attributes)) + && (!multi_dst || from->dwNumFiles != to->dwNumFiles)); + + /* Do copy operation. */ + if ((ret = do_copy(op, &from->feFiles[i], target, append_file_name)) != ERROR_SUCCESS) + break; }
- /* Vista return code. On XP if the used pressed "No" for the last item, - * ERROR_ARENA_TRASHED would be returned */ - return ERROR_SUCCESS; + file_entry_destroy(¤t); + return ret; }
static BOOL confirm_delete_list(HWND hWnd, DWORD fFlags, BOOL fTrash, const FILE_LIST *flFrom) @@ -1576,6 +1512,7 @@ static void check_flags(FILEOP_FLAGS fFlags) */ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) { + BOOL parse_wildcard = (lpFileOp->wFunc != FO_RENAME && lpFileOp->wFunc != FO_COPY); FILE_OPERATION op; FILE_LIST flFrom, flTo; int ret = 0; @@ -1588,7 +1525,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp) ZeroMemory(&flFrom, sizeof(FILE_LIST)); ZeroMemory(&flTo, sizeof(FILE_LIST));
- if ((ret = parse_file_list(&flFrom, lpFileOp->pFrom, lpFileOp->wFunc != FO_RENAME))) + if ((ret = parse_file_list(&flFrom, lpFileOp->pFrom, parse_wildcard))) return ret;
if (lpFileOp->wFunc != FO_DELETE) diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c index 25c502a73b8..ff27ff06d42 100644 --- a/dlls/shell32/tests/shlfileop.c +++ b/dlls/shell32/tests/shlfileop.c @@ -921,10 +921,8 @@ static void test_copy(void) set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0"); set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0"); check_file_operation(FO_COPY, FOF_NO_UI, from, to, - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("test6.txt\test1.txt"), "test6.txt\test1.txt is not copied.\n"); - todo_wine ok(DeleteFileA("test6.txt\test2.txt"), "test6.txt\test2.txt is not copied.\n"); RemoveDirectoryA("test6.txt\test4.txt"); RemoveDirectoryA("test6.txt"); @@ -944,11 +942,9 @@ static void test_copy(void) set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0"); set_curr_dir_path(to, "test6.txt\0test7.txt\0"); check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, from, to, - DE_DESTSAMETREE, FALSE, TRUE, TRUE); - todo_wine + DE_DESTSAMETREE, FALSE, FALSE, FALSE); ok(DeleteFileA("test6.txt\test1.txt"), "The file is not copied.\n"); RemoveDirectoryA("test6.txt"); - todo_wine ok(DeleteFileA("test7.txt\test2.txt"), "The file is not copied.\n"); RemoveDirectoryA("test7.txt");
@@ -988,7 +984,7 @@ static void test_copy(void) set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0"); set_curr_dir_path(to, "testdir2\0"); check_file_operation(FO_COPY, FOF_NO_UI, from, to, - ERROR_FILE_NOT_FOUND, FALSE, TRUE, FALSE); + ERROR_FILE_NOT_FOUND, FALSE, FALSE, FALSE); ok(!file_exists("testdir2\test1.txt"), "The file is copied\n"); ok(!file_exists("testdir2\test2.txt"), "The file is copied\n"); clean_after_shfo_tests(); @@ -1030,7 +1026,7 @@ static void test_copy(void) set_curr_dir_path(from, "test1.txt\0test2.txt\0"); set_curr_dir_path(to, "test3.txt\0"); check_file_operation(FO_COPY, FOF_NO_UI, from, to, - DE_INVALIDFILES, FALSE, TRUE, TRUE); + DE_INVALIDFILES, FALSE, TRUE, FALSE); ok(!file_exists("test3.txt\test2.txt"), "Expected test3.txt\test2.txt to not exist\n");
/* Copy many files to a nonexistent directory. */ @@ -1048,15 +1044,12 @@ static void test_copy(void) check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "test1.txt\0test2.txt\0test3.txt\0", "testdir2\a.txt\0testdir2\b.txt\0testdir2\c.txt\0testdir2\d.txt\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine - { + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("testdir2\a.txt\test1.txt"), "Expected testdir2\a.txt\test1.txt to exist\n"); RemoveDirectoryA("testdir2\a.txt"); ok(DeleteFileA("testdir2\b.txt\test2.txt"), "Expected testdir2\b.txt\test2.txt to exist\n"); RemoveDirectoryA("testdir2\b.txt"); ok(DeleteFileA("testdir2\c.txt\test3.txt"), "Expected testdir2\c.txt\test3.txt to exist\n"); - } RemoveDirectoryA("testdir2\c.txt"); ok(!file_exists("testdir2\d.txt"), "Expected testdir2\d.txt to not exist\n");
@@ -1064,14 +1057,11 @@ static void test_copy(void) check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "test1.txt\0test2.txt\0test3.txt\0", "e.txt\0f.txt\0", - DE_SAMEFILE, FALSE, TRUE, TRUE); - todo_wine - { + DE_SAMEFILE, FALSE, FALSE, FALSE); ok(DeleteFileA("e.txt\test1.txt"), "Expected e.txt\test1.txt to exist\n"); RemoveDirectoryA("e.txt"); ok(DeleteFileA("f.txt\test2.txt"), "Expected f.txt\test2.txt to exist\n"); RemoveDirectoryA("f.txt"); - }
/* Sources and targets have the same number, with FOF_MULTIDESTFILES. */ check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, @@ -1086,13 +1076,10 @@ static void test_copy(void) check_file_operation(FO_COPY, FOF_NO_UI, "test1.txt\0test2.txt\0test3.txt\0", "a.txt\0b.txt\0c.txt\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine - { + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("a.txt\test1.txt"), "Expected a.txt\test1.txt to exist\n"); ok(DeleteFileA("a.txt\test2.txt"), "Expected a.txt\test2.txt to exist\n"); ok(DeleteFileA("a.txt\test3.txt"), "Expected a.txt\test3.txt to exist\n"); - } ok(!dir_exists("b.txt"), "Expected b.txt directory to not exist.\n"); ok(!dir_exists("c.txt"), "Expected c.txt directory to not exist.\n"); RemoveDirectoryA("a.txt"); @@ -1101,13 +1088,10 @@ static void test_copy(void) check_file_operation(FO_COPY, FOF_NO_UI, "test1.txt\0test2.txt\0test3.txt\0", "a.txt\0b.txt\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine - { + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("a.txt\test1.txt"), "Expected a.txt\test1.txt to exist\n"); ok(DeleteFileA("a.txt\test2.txt"), "Expected a.txt\test2.txt to exist\n"); ok(DeleteFileA("a.txt\test3.txt"), "Expected a.txt\test3.txt to exist\n"); - } ok(!dir_exists("b.txt"), "Expected b.txt directory to not exist.\n"); RemoveDirectoryA("a.txt");
@@ -1130,14 +1114,11 @@ static void test_copy(void) init_shfo_tests(); check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "test?.txt\0", "testdir2\a.txt\0testdir2\b.txt\0testdir2\c.txt\0testdir2\d.txt\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine - { + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("testdir2\a.txt\test1.txt"), "Expected testdir2\a.txt\test1.txt to exist\n"); ok(DeleteFileA("testdir2\a.txt\test2.txt"), "Expected testdir2\a.txt\test2.txt to exist\n"); ok(DeleteFileA("testdir2\a.txt\test3.txt"), "Expected testdir2\a.txt\test3.txt to exist\n"); ok(RemoveDirectoryA("testdir2\a.txt\test4.txt"), "Expected testdir2\a.txt\test4.txt to exist\n"); - } RemoveDirectoryA("testdir2\a.txt"); ok(!RemoveDirectoryA("b.txt"), "b.txt should not exist\n");
@@ -1153,26 +1134,20 @@ static void test_copy(void) /* Copy two file to three others. */ check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "test1.txt\0test2.txt\0", "b.txt\0c.txt\0d.txt\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine - { + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("b.txt\test1.txt"), "Expected b.txt\test1.txt to exist\n"); RemoveDirectoryA("b.txt"); ok(DeleteFileA("c.txt\test2.txt"), "Expected c.txt\test2.txt to exist\n"); - } RemoveDirectoryA("c.txt");
/* Copy one file and one directory to three others. */ check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "test1.txt\0test4.txt\0", "b.txt\0c.txt\0d.txt\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine - { + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("b.txt\test1.txt"), "Expected b.txt\test1.txt to exist\n"); RemoveDirectoryA("b.txt"); ok(RemoveDirectoryA("c.txt\test4.txt"), "Expected c.txt\test4.txt to exist\n"); RemoveDirectoryA("c.txt"); - }
/* Copy a file and a dir containing file to another dir. */ createTestFile("test4.txt\a.txt"); @@ -1192,11 +1167,9 @@ static void test_copy(void)
check_file_operation(FO_COPY, FOF_NO_UI, "test4.txt\a.txt\0test4.txt\0", "nonexistent\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("nonexistent\test4.txt\a.txt"), "Expected nonexistent\test4.txt\a.txt to exist\n"); RemoveDirectoryA("nonexistent\test4.txt"); - todo_wine ok(DeleteFileA("nonexistent\a.txt"), "Expected nonexistent\a.txt to exist\n"); RemoveDirectoryA("nonexistent"); DeleteFileA("test4.txt\a.txt"); @@ -1211,37 +1184,36 @@ static void test_copy(void) /* Target dir is same as source dir. */ check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "test1.txt\0test4.txt\0test3.txt\0", "b.txt\0test4.txt\0c.txt\0", - DE_DESTSAMETREE, FALSE, TRUE, FALSE); + DE_DESTSAMETREE, FALSE, FALSE, FALSE); ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n"); ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
/* Copy a dir into it's subdir. */ check_file_operation(FO_COPY, FOF_NO_UI, "test4.txt\0", "test4.txt\newdir\0", - DE_DESTSUBTREE, FALSE, TRUE, FALSE); + DE_DESTSUBTREE, FALSE, FALSE, FALSE); ok(!RemoveDirectoryA("test4.txt\newdir"), "Expected test4.txt\newdir to not exist\n");
/* Copy a dir into itself. */ check_file_operation(FO_COPY, FOF_NO_UI, "test4.txt\0", "test4.txt\0", - DE_DESTSUBTREE, FALSE, TRUE, FALSE); + DE_DESTSUBTREE, FALSE, FALSE, FALSE);
/* Copy a file into a dir, and the dir into itself. */ check_file_operation(FO_COPY, FOF_NO_UI, "test1.txt\0test4.txt\0", "test4.txt\0", - DE_DESTSUBTREE, FALSE, TRUE, FALSE); + DE_DESTSUBTREE, FALSE, FALSE, FALSE); ok(DeleteFileA("test4.txt\test1.txt"), "Expected test4.txt\test1.txt to exist\n");
/* Copy a file to a file, and the dir into it's subdir. */ check_file_operation(FO_COPY, FOF_NO_UI, "test1.txt\0test4.txt\0", "test4.txt\a.txt\0", - DE_DESTSUBTREE, FALSE, TRUE, TRUE); - todo_wine + DE_DESTSUBTREE, FALSE, FALSE, FALSE); ok(DeleteFileA("test4.txt\a.txt\test1.txt"), "Expected test4.txt\a.txt\test1.txt to exist\n"); RemoveDirectoryA("test4.txt\a.txt");
/* Copy a nonexistent file to a nonexistent dir. */ check_file_operation(FO_COPY, FOF_NO_UI, "e.txt\0", "nonexistent\0", - ERROR_FILE_NOT_FOUND, FALSE, TRUE, FALSE); + ERROR_FILE_NOT_FOUND, FALSE, FALSE, FALSE); ok(!file_exists("nonexistent\e.txt"), "Expected nonexistent\e.txt to not exist\n"); ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
@@ -1338,13 +1310,10 @@ static void test_copy(void) lstrcpyA(to, "threedir"); check_file_operation(FO_COPY, FOF_NO_UI, "one.txt\0two.txt\0", to, - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine - { + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("threedir\one.txt"), "Expected threedir\one.txt to exist.\n"); ok(DeleteFileA("threedir\two.txt"), "Expected threedir\one.txt to exist.\n"); ok(RemoveDirectoryA("threedir"), "Expected threedir to exist.\n"); - } ok(DeleteFileA("one.txt"), "Expected file to exist\n"); ok(DeleteFileA("two.txt"), "Expected file to exist\n");
@@ -1374,7 +1343,7 @@ static void test_copy(void) lstrcpyA(to, "threedir"); check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "one.txt\0two.txt\0", to, - ERROR_ACCESS_DENIED, FALSE, TRUE, TRUE); + ERROR_ACCESS_DENIED, FALSE, TRUE, FALSE); ok(!DeleteFileA("threedir\one.txt"), "Expected file to not exist\n"); ok(!DeleteFileA("threedir\two.txt"), "Expected file to not exist\n"); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); @@ -1393,7 +1362,7 @@ static void test_copy(void) lstrcpyA(ptr, "fourdir"); check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "one.txt\0two.txt\0", to, - ERROR_SUCCESS, FALSE, TRUE, TRUE); + ERROR_SUCCESS, FALSE, TRUE, FALSE); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); todo_wine @@ -1428,7 +1397,7 @@ static void test_copy(void) CreateDirectoryA("threedir", NULL); check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "one.txt\0two.txt\0", "threedir\0fourdir\0five\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); + ERROR_SUCCESS, FALSE, TRUE, FALSE); ok(DeleteFileA("one.txt"), "Expected file to exist\n"); ok(DeleteFileA("two.txt"), "Expected file to exist\n"); todo_wine @@ -1477,14 +1446,11 @@ static void test_copy(void) /* pFrom has more than one glob, pTo has more than one dest, with FOF_MULTIDESTFILES. */ check_file_operation(FO_COPY, FOF_NO_UI | FOF_MULTIDESTFILES, "a*.txt\0*b.txt\0", "one\0two\0", - ERROR_SUCCESS, FALSE, TRUE, TRUE); - todo_wine - { + ERROR_SUCCESS, FALSE, FALSE, FALSE); ok(DeleteFileA("one\aa.txt"), "Expected file to exist\n"); ok(DeleteFileA("one\ab.txt"), "Expected file to exist\n"); ok(DeleteFileA("two\ab.txt"), "Expected file to exist\n"); ok(DeleteFileA("two\bb.txt"), "Expected file to exist\n"); - }
/* Wildcard target. */ check_file_operation(FO_COPY, FOF_NO_UI, "aa.txt\0", "tw?\0", @@ -1511,7 +1477,7 @@ static void test_copy(void) ok(RemoveDirectoryA("nested"), "Expected dir to exist\n"); check_file_operation(FO_COPY, FOF_NO_UI, "nonexistence\0", "\0", - ERROR_FILE_NOT_FOUND, FALSE, TRUE, FALSE); + ERROR_FILE_NOT_FOUND, FALSE, FALSE, FALSE); check_file_operation(FO_COPY, FOF_NO_UI, "\0", "testdir2\0", ERROR_SUCCESS, FALSE, TRUE, TRUE); @@ -1563,7 +1529,7 @@ static void test_copy(void) init_shfo_tests(); SetLastError(0xdeadbeef); check_file_operation(FO_COPY, FOF_NO_UI, "nonexistence\0", "testdir2\0", - ERROR_FILE_NOT_FOUND, FALSE, TRUE, FALSE); + ERROR_FILE_NOT_FOUND, FALSE, FALSE, FALSE); ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError());
/* test with / */