2 * Unit test of the SHFileOperation function.
4 * Copyright 2002 Andriy Palamarchuk
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WINE_NOWINSOCK
29 #include "wine/test.h"
31 #ifndef INVALID_FILE_ATTRIBUTES
32 #define INVALID_FILE_ATTRIBUTES 0xffffffff
35 #ifndef FOF_NORECURSION
36 #define FOF_NORECURSION 0x1000
39 CHAR CURR_DIR[MAX_PATH];
41 static HMODULE hshell32;
42 static int (WINAPI *pSHCreateDirectoryExA)(HWND, LPCSTR, LPSECURITY_ATTRIBUTES);
44 static void InitFunctionPointers(void)
46 hshell32 = GetModuleHandleA("shell32.dll");
49 pSHCreateDirectoryExA = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExA");
52 /* creates a file with the specified name for tests */
53 static void createTestFile(const CHAR *name)
58 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
59 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
60 WriteFile(file, name, strlen(name), &written, NULL);
61 WriteFile(file, "\n", strlen("\n"), &written, NULL);
65 static BOOL file_exists(const CHAR *name)
67 return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
70 /* initializes the tests */
71 static void init_shfo_tests(void)
75 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
76 len = lstrlenA(CURR_DIR);
78 if(len && (CURR_DIR[len-1] == '\\'))
81 createTestFile("test1.txt");
82 createTestFile("test2.txt");
83 createTestFile("test3.txt");
84 createTestFile("test_5.txt");
85 CreateDirectoryA("test4.txt", NULL);
86 CreateDirectoryA("testdir2", NULL);
87 CreateDirectoryA("testdir2\\nested", NULL);
88 createTestFile("testdir2\\one.txt");
89 createTestFile("testdir2\\nested\\two.txt");
92 /* cleans after tests */
93 static void clean_after_shfo_tests(void)
95 DeleteFileA("test1.txt");
96 DeleteFileA("test2.txt");
97 DeleteFileA("test3.txt");
98 DeleteFileA("test_5.txt");
99 DeleteFileA("test4.txt\\test1.txt");
100 DeleteFileA("test4.txt\\test2.txt");
101 DeleteFileA("test4.txt\\test3.txt");
102 RemoveDirectoryA("test4.txt");
103 DeleteFileA("testdir2\\one.txt");
104 DeleteFileA("testdir2\\test1.txt");
105 DeleteFileA("testdir2\\test2.txt");
106 DeleteFileA("testdir2\\test3.txt");
107 DeleteFileA("testdir2\\test4.txt\\test1.txt");
108 DeleteFileA("testdir2\\nested\\two.txt");
109 RemoveDirectoryA("testdir2\\test4.txt");
110 RemoveDirectoryA("testdir2\\nested");
111 RemoveDirectoryA("testdir2");
112 RemoveDirectoryA("c:\\testdir3");
113 DeleteFileA("nonexistent\\notreal\\test2.txt");
114 RemoveDirectoryA("nonexistent\\notreal");
115 RemoveDirectoryA("nonexistent");
119 puts into the specified buffer file names with current directory.
120 files - string with file names, separated by null characters. Ends on a double
123 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
128 strcpy(buf, CURR_DIR);
133 buf += strlen(buf) + 1;
134 files += strlen(files) + 1;
140 /* tests the FO_DELETE action */
141 static void test_delete(void)
143 SHFILEOPSTRUCTA shfo;
147 sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
148 buf[strlen(buf) + 1] = '\0';
151 shfo.wFunc = FO_DELETE;
154 shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
155 shfo.hNameMappings = NULL;
156 shfo.lpszProgressTitle = NULL;
158 ok(!SHFileOperationA(&shfo), "Deletion was successful\n");
159 ok(file_exists("test4.txt"), "Directory should not be removed\n");
160 ok(!file_exists("test1.txt"), "File should be removed\n");
162 ret = SHFileOperationA(&shfo);
163 ok(!ret, "Directory exists, but is not removed, ret=%ld\n", ret);
164 ok(file_exists("test4.txt"), "Directory should not be removed\n");
166 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
168 ok(!SHFileOperationA(&shfo), "Directory removed\n");
169 ok(!file_exists("test4.txt"), "Directory should be removed\n");
171 ret = SHFileOperationA(&shfo);
172 ok(!ret, "The requested file does not exist, ret=%ld\n", ret);
175 sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
176 buf[strlen(buf) + 1] = '\0';
177 ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Fill the subdirectory\n");
178 ok(!SHFileOperationA(&shfo), "Directory removed\n");
179 ok(!file_exists("test4.txt"), "Directory is removed\n");
182 shfo.pFrom = "test1.txt\0test4.txt\0";
183 ok(!SHFileOperationA(&shfo), "Directory and a file removed\n");
184 ok(!file_exists("test1.txt"), "The file should be removed\n");
185 ok(!file_exists("test4.txt"), "Directory should be removed\n");
186 ok(file_exists("test2.txt"), "This file should not be removed\n");
188 /* FOF_FILESONLY does not delete a dir matching a wildcard */
190 shfo.fFlags |= FOF_FILESONLY;
191 shfo.pFrom = "*.txt\0";
192 ok(!SHFileOperation(&shfo), "Failed to delete files\n");
193 ok(!file_exists("test1.txt"), "test1.txt should be removed\n");
194 ok(!file_exists("test_5.txt"), "test_5.txt should be removed\n");
195 ok(file_exists("test4.txt"), "test4.txt should not be removed\n");
197 /* FOF_FILESONLY only deletes a dir if explicitly specified */
199 shfo.pFrom = "test_?.txt\0test4.txt\0";
200 ok(!SHFileOperation(&shfo), "Failed to delete files\n");
201 ok(!file_exists("test4.txt"), "test4.txt should be removed\n");
202 ok(!file_exists("test_5.txt"), "test_5.txt should be removed\n");
203 ok(file_exists("test1.txt"), "test1.txt should not be removed\n");
205 /* try to delete an invalid filename */
208 shfo.fFlags &= ~FOF_FILESONLY;
209 shfo.fAnyOperationsAborted = FALSE;
210 ret = SHFileOperation(&shfo);
211 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", ret);
212 ok(!shfo.fAnyOperationsAborted, "Expected no aborted operations\n");
213 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
215 /* try an invalid function */
217 shfo.pFrom = "test1.txt\0";
219 ret = SHFileOperation(&shfo);
220 ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret);
221 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
223 /* try an invalid list, only one null terminator */
226 shfo.wFunc = FO_DELETE;
227 ret = SHFileOperation(&shfo);
228 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", ret);
229 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
231 /* delete a dir, and then a file inside the dir, same as
232 * deleting a nonexistent file
235 shfo.pFrom = "testdir2\0testdir2\\one.txt\0";
236 ret = SHFileOperation(&shfo);
237 ok(ret == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %ld\n", ret);
238 ok(!file_exists("testdir2"), "Expected testdir2 to not exist\n");
239 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
241 /* try the FOF_NORECURSION flag, continues deleting subdirs */
243 shfo.pFrom = "testdir2\0";
244 shfo.fFlags |= FOF_NORECURSION;
245 ret = SHFileOperation(&shfo);
246 ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret);
247 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
248 ok(!file_exists("testdir2\\nested"), "Expected testdir2\\nested to exist\n");
251 /* tests the FO_RENAME action */
252 static void test_rename(void)
254 SHFILEOPSTRUCTA shfo, shfo2;
260 shfo.wFunc = FO_RENAME;
263 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
264 shfo.hNameMappings = NULL;
265 shfo.lpszProgressTitle = NULL;
267 set_curr_dir_path(from, "test1.txt\0");
268 set_curr_dir_path(to, "test4.txt\0");
269 ok(SHFileOperationA(&shfo), "File is not renamed moving to other directory "
270 "when specifying directory name only\n");
271 ok(file_exists("test1.txt"), "The file is removed\n");
273 set_curr_dir_path(from, "test3.txt\0");
274 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
275 ok(!SHFileOperationA(&shfo), "File is renamed moving to other directory\n");
276 ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
278 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
279 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
280 retval = SHFileOperationA(&shfo); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
281 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
282 "Can't rename many files, retval = %ld\n", retval);
283 ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
285 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
286 shfo2.fFlags |= FOF_MULTIDESTFILES;
288 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
289 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
290 retval = SHFileOperationA(&shfo2); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
291 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
292 "Can't rename many files, retval = %ld\n", retval);
293 ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
295 set_curr_dir_path(from, "test1.txt\0");
296 set_curr_dir_path(to, "test6.txt\0");
297 retval = SHFileOperationA(&shfo);
298 ok(!retval, "Rename file failed, retval = %ld\n", retval);
299 ok(!file_exists("test1.txt"), "The file is not renamed\n");
300 ok(file_exists("test6.txt"), "The file is not renamed\n");
302 set_curr_dir_path(from, "test6.txt\0");
303 set_curr_dir_path(to, "test1.txt\0");
304 retval = SHFileOperationA(&shfo);
305 ok(!retval, "Rename file back failed, retval = %ld\n", retval);
307 set_curr_dir_path(from, "test4.txt\0");
308 set_curr_dir_path(to, "test6.txt\0");
309 retval = SHFileOperationA(&shfo);
310 ok(!retval, "Rename dir failed, retval = %ld\n", retval);
311 ok(!file_exists("test4.txt"), "The dir is not renamed\n");
312 ok(file_exists("test6.txt"), "The dir is not renamed\n");
314 set_curr_dir_path(from, "test6.txt\0");
315 set_curr_dir_path(to, "test4.txt\0");
316 retval = SHFileOperationA(&shfo);
317 ok(!retval, "Rename dir back failed, retval = %ld\n", retval);
319 /* try to rename more than one file to a single file */
320 shfo.pFrom = "test1.txt\0test2.txt\0";
321 shfo.pTo = "a.txt\0";
322 retval = SHFileOperationA(&shfo);
323 ok(retval == ERROR_GEN_FAILURE, "Expected ERROR_GEN_FAILURE, got %ld\n", retval);
324 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
325 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
327 /* pFrom doesn't exist */
328 shfo.pFrom = "idontexist\0";
329 shfo.pTo = "newfile\0";
330 retval = SHFileOperationA(&shfo);
331 ok(retval == 1026, "Expected 1026, got %ld\n", retval);
332 ok(!file_exists("newfile"), "Expected newfile to not exist\n");
334 /* pTo already exist */
335 shfo.pFrom = "test1.txt\0";
336 shfo.pTo = "test2.txt\0";
337 retval = SHFileOperationA(&shfo);
338 ok(retval == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %ld\n", retval);
340 /* pFrom is valid, but pTo is empty */
341 shfo.pFrom = "test1.txt\0";
343 retval = SHFileOperationA(&shfo);
344 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
345 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
349 retval = SHFileOperationA(&shfo);
350 ok(retval == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", retval);
352 /* pFrom is NULL, commented out because it crashes on nt 4.0 */
355 retval = SHFileOperationA(&shfo);
356 ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", retval);
360 /* tests the FO_COPY action */
361 static void test_copy(void)
363 SHFILEOPSTRUCTA shfo, shfo2;
366 FILEOP_FLAGS tmp_flags;
370 shfo.wFunc = FO_COPY;
373 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
374 shfo.hNameMappings = NULL;
375 shfo.lpszProgressTitle = NULL;
377 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
378 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
379 ok(SHFileOperationA(&shfo), "Can't copy many files\n");
380 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
381 "specified as a target\n");
383 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
384 shfo2.fFlags |= FOF_MULTIDESTFILES;
386 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
387 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
388 ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
389 ok(file_exists("test6.txt"), "The file is copied - many files are "
390 "specified as a target\n");
391 DeleteFileA("test6.txt");
392 DeleteFileA("test7.txt");
393 RemoveDirectoryA("test8.txt");
395 /* number of sources do not correspond to number of targets */
396 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
397 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
398 ok(SHFileOperationA(&shfo2), "Can't copy many files\n");
399 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
400 "specified as a target\n");
402 set_curr_dir_path(from, "test1.txt\0");
403 set_curr_dir_path(to, "test4.txt\0");
404 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
405 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
407 set_curr_dir_path(from, "test?.txt\0");
408 set_curr_dir_path(to, "testdir2\0");
409 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
410 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
411 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
412 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
413 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
414 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
415 clean_after_shfo_tests();
418 shfo.fFlags |= FOF_FILESONLY;
419 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
420 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
421 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
422 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
423 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
424 clean_after_shfo_tests();
427 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
428 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
429 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
430 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
431 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
432 ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
433 clean_after_shfo_tests();
435 /* Copying multiple files with one not existing as source, fails the
436 entire operation in Win98/ME/2K/XP, but not in 95/NT */
438 tmp_flags = shfo.fFlags;
439 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
440 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
441 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
442 retval = SHFileOperationA(&shfo);
444 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
445 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
448 /* Win 98/ME/2K/XP fail the entire operation with return code 1026 if one source file does not exist */
449 ok(retval == 1026, "Files are copied to other directory\n");
450 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
452 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
453 shfo.fFlags = tmp_flags;
455 /* copy into a nonexistent directory */
457 shfo.fFlags = FOF_NOCONFIRMMKDIR;
458 set_curr_dir_path(from, "test1.txt\0");
459 set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
460 retval= SHFileOperation(&shfo);
461 ok(!retval, "Error copying into nonexistent directory\n");
462 ok(file_exists("nonexistent"), "nonexistent not created\n");
463 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
464 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
465 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
467 /* a relative dest directory is OK */
468 clean_after_shfo_tests();
470 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
471 shfo.pTo = "testdir2\0";
472 retval = SHFileOperation(&shfo);
473 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
474 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
476 /* try to copy files to a file */
477 clean_after_shfo_tests();
481 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
482 set_curr_dir_path(to, "test3.txt\0");
483 retval = SHFileOperation(&shfo);
484 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
485 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
486 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
488 /* try to copy many files to nonexistent directory */
490 shfo.fAnyOperationsAborted = FALSE;
491 retval = SHFileOperation(&shfo);
492 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
493 ok(DeleteFile("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
494 ok(DeleteFile("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
495 ok(RemoveDirectory(to), "Expected test3.txt to exist\n");
497 /* send in FOF_MULTIDESTFILES with too many destination files */
499 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
500 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
501 shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
502 retval = SHFileOperation(&shfo);
503 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
504 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
505 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
507 /* send in FOF_MULTIDESTFILES with too many destination files */
508 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
509 shfo.pTo = "e.txt\0f.txt\0";
510 shfo.fAnyOperationsAborted = FALSE;
511 retval = SHFileOperation(&shfo);
512 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
513 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
514 ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
516 /* use FOF_MULTIDESTFILES with files and a source directory */
517 shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
518 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
519 shfo.fAnyOperationsAborted = FALSE;
520 retval = SHFileOperation(&shfo);
521 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
522 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
523 ok(DeleteFile("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
524 ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
526 /* try many dest files without FOF_MULTIDESTFILES flag */
527 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
528 shfo.pTo = "a.txt\0b.txt\0c.txt\0";
529 shfo.fAnyOperationsAborted = FALSE;
530 shfo.fFlags &= ~FOF_MULTIDESTFILES;
531 retval = SHFileOperation(&shfo);
532 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
533 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
536 shfo.pFrom = "test?.txt\0";
537 shfo.pTo = "testdir2\0";
538 shfo.fFlags &= ~FOF_MULTIDESTFILES;
539 retval = SHFileOperation(&shfo);
540 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
541 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
543 /* try a glob with FOF_FILESONLY */
544 clean_after_shfo_tests();
546 shfo.pFrom = "test?.txt\0";
547 shfo.fFlags |= FOF_FILESONLY;
548 retval = SHFileOperation(&shfo);
549 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
550 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
551 ok(!file_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
553 /* try a glob with FOF_MULTIDESTFILES and the same number
554 * of dest files that we would expect
556 clean_after_shfo_tests();
558 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
559 shfo.fFlags &= ~FOF_FILESONLY;
560 shfo.fFlags |= FOF_MULTIDESTFILES;
561 retval = SHFileOperation(&shfo);
562 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
563 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
564 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
565 ok(!RemoveDirectory("b.txt"), "b.txt should not exist\n");
567 /* copy one file to two others, second is ignored */
568 clean_after_shfo_tests();
570 shfo.pFrom = "test1.txt\0";
571 shfo.pTo = "b.txt\0c.txt\0";
572 shfo.fAnyOperationsAborted = FALSE;
573 retval = SHFileOperation(&shfo);
574 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
575 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
576 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
578 /* copy two file to three others, all fail */
579 shfo.pFrom = "test1.txt\0test2.txt\0";
580 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
581 retval = SHFileOperation(&shfo);
582 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
583 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
584 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
586 /* copy one file and one directory to three others */
587 shfo.pFrom = "test1.txt\0test4.txt\0";
588 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
589 shfo.fAnyOperationsAborted = FALSE;
590 retval = SHFileOperation(&shfo);
591 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
592 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
593 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
594 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
596 /* copy a directory with a file beneath it, plus some files */
597 createTestFile("test4.txt\\a.txt");
598 shfo.pFrom = "test4.txt\0test1.txt\0";
599 shfo.pTo = "testdir2\0";
600 shfo.fFlags &= ~FOF_MULTIDESTFILES;
601 shfo.fAnyOperationsAborted = FALSE;
602 retval = SHFileOperation(&shfo);
603 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
604 ok(DeleteFile("testdir2\\test1.txt"), "Expected newdir\\test1.txt to exist\n");
605 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
606 ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
608 /* copy one directory and a file in that dir to another dir */
609 shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
610 shfo.pTo = "testdir2\0";
611 retval = SHFileOperation(&shfo);
612 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
613 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
614 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
616 /* copy a file in a directory first, and then the directory to a nonexistent dir */
617 shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
618 shfo.pTo = "nonexistent\0";
619 retval = SHFileOperation(&shfo);
620 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
621 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
622 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
623 DeleteFile("test4.txt\\a.txt");
625 /* destination is same as source file */
626 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
627 shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
628 shfo.fAnyOperationsAborted = FALSE;
629 shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
630 retval = SHFileOperation(&shfo);
631 ok(retval == ERROR_NO_MORE_SEARCH_HANDLES,
632 "Expected ERROR_NO_MORE_SEARCH_HANDLES, got %ld\n", retval);
633 ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
634 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
635 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
637 /* destination is same as source directory */
638 shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
639 shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
640 shfo.fAnyOperationsAborted = FALSE;
641 retval = SHFileOperation(&shfo);
642 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
643 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
644 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
646 /* copy a directory into itself, error displayed in UI */
647 shfo.pFrom = "test4.txt\0";
648 shfo.pTo = "test4.txt\\newdir\0";
649 shfo.fFlags &= ~FOF_MULTIDESTFILES;
650 shfo.fAnyOperationsAborted = FALSE;
651 retval = SHFileOperation(&shfo);
652 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
653 ok(!RemoveDirectory("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
655 /* copy a directory to itself, error displayed in UI */
656 shfo.pFrom = "test4.txt\0";
657 shfo.pTo = "test4.txt\0";
658 shfo.fAnyOperationsAborted = FALSE;
659 retval = SHFileOperation(&shfo);
660 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
662 /* copy a file into a directory, and the directory into itself */
663 shfo.pFrom = "test1.txt\0test4.txt\0";
664 shfo.pTo = "test4.txt\0";
665 shfo.fAnyOperationsAborted = FALSE;
666 shfo.fFlags |= FOF_NOCONFIRMATION;
667 retval = SHFileOperation(&shfo);
668 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
669 ok(DeleteFile("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
671 /* copy a file to a file, and the directory into itself */
672 shfo.pFrom = "test1.txt\0test4.txt\0";
673 shfo.pTo = "test4.txt\\a.txt\0";
674 shfo.fAnyOperationsAborted = FALSE;
675 retval = SHFileOperation(&shfo);
676 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
677 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
679 /* copy a nonexistent file to a nonexistent directory */
680 shfo.pFrom = "e.txt\0";
681 shfo.pTo = "nonexistent\0";
682 shfo.fAnyOperationsAborted = FALSE;
683 retval = SHFileOperation(&shfo);
684 ok(retval == 1026, "Expected 1026, got %ld\n", retval);
685 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
686 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
689 /* tests the FO_MOVE action */
690 static void test_move(void)
692 SHFILEOPSTRUCTA shfo, shfo2;
698 shfo.wFunc = FO_MOVE;
701 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
702 shfo.hNameMappings = NULL;
703 shfo.lpszProgressTitle = NULL;
705 set_curr_dir_path(from, "test1.txt\0");
706 set_curr_dir_path(to, "test4.txt\0");
707 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
708 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
709 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
711 set_curr_dir_path(from, "test?.txt\0");
712 set_curr_dir_path(to, "testdir2\0");
713 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
714 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
715 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
716 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
717 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
718 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
720 clean_after_shfo_tests();
723 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
724 shfo2.fFlags |= FOF_MULTIDESTFILES;
726 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
727 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
728 ok(!SHFileOperationA(&shfo2), "Move many files\n");
729 ok(file_exists("test6.txt"), "The file is moved - many files are "
730 "specified as a target\n");
731 DeleteFileA("test6.txt");
732 DeleteFileA("test7.txt");
733 RemoveDirectoryA("test8.txt");
737 /* number of sources do not correspond to number of targets */
738 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
739 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
740 ok(SHFileOperationA(&shfo2), "Can't move many files\n");
741 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
742 "specified as a target\n");
746 set_curr_dir_path(from, "test3.txt\0");
747 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
748 ok(!SHFileOperationA(&shfo), "File is moved moving to other directory\n");
749 ok(file_exists("test4.txt\\test1.txt"), "The file is moved\n");
751 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
752 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
753 ok(SHFileOperationA(&shfo), "Cannot move many files\n");
754 ok(file_exists("test1.txt"), "The file is not moved. Many files are specified\n");
755 ok(file_exists("test4.txt"), "The directory is not moved. Many files are specified\n");
757 set_curr_dir_path(from, "test1.txt\0");
758 set_curr_dir_path(to, "test6.txt\0");
759 ok(!SHFileOperationA(&shfo), "Move file\n");
760 ok(!file_exists("test1.txt"), "The file is moved\n");
761 ok(file_exists("test6.txt"), "The file is moved\n");
762 set_curr_dir_path(from, "test6.txt\0");
763 set_curr_dir_path(to, "test1.txt\0");
764 ok(!SHFileOperationA(&shfo), "Move file back\n");
766 set_curr_dir_path(from, "test4.txt\0");
767 set_curr_dir_path(to, "test6.txt\0");
768 ok(!SHFileOperationA(&shfo), "Move dir\n");
769 ok(!file_exists("test4.txt"), "The dir is moved\n");
770 ok(file_exists("test6.txt"), "The dir is moved\n");
771 set_curr_dir_path(from, "test6.txt\0");
772 set_curr_dir_path(to, "test4.txt\0");
773 ok(!SHFileOperationA(&shfo), "Move dir back\n");
775 /* move one file to two others */
777 shfo.pFrom = "test1.txt\0";
778 shfo.pTo = "a.txt\0b.txt\0";
779 retval = SHFileOperationA(&shfo);
780 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
781 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
782 ok(DeleteFile("a.txt"), "Expected a.txt to exist\n");
783 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
785 /* move two files to one other */
786 shfo.pFrom = "test2.txt\0test3.txt\0";
787 shfo.pTo = "test1.txt\0";
788 retval = SHFileOperationA(&shfo);
789 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
790 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
791 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
792 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
794 /* move a directory into itself */
795 shfo.pFrom = "test4.txt\0";
796 shfo.pTo = "test4.txt\\b.txt\0";
797 retval = SHFileOperationA(&shfo);
798 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
799 ok(!RemoveDirectory("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
800 ok(file_exists("test4.txt"), "Expected test4.txt to exist\n");
802 /* move many files without FOF_MULTIDESTFILES */
803 shfo.pFrom = "test2.txt\0test3.txt\0";
804 shfo.pTo = "d.txt\0e.txt\0";
805 retval = SHFileOperationA(&shfo);
806 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
807 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
808 ok(!DeleteFile("e.txt"), "Expected e.txt to not exist\n");
810 /* number of sources != number of targets */
811 shfo.pTo = "d.txt\0";
812 shfo.fFlags |= FOF_MULTIDESTFILES;
813 retval = SHFileOperationA(&shfo);
814 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
815 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
817 /* FO_MOVE does not create dest directories */
818 shfo.pFrom = "test2.txt\0";
819 shfo.pTo = "dir1\\dir2\\test2.txt\0";
820 retval = SHFileOperationA(&shfo);
821 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
822 ok(!file_exists("dir1"), "Expected dir1 to not exist\n");
824 /* try to overwrite an existing file */
825 shfo.pTo = "test3.txt\0";
826 retval = SHFileOperationA(&shfo);
827 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
828 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
829 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
832 static void test_sh_create_dir(void)
837 if(!pSHCreateDirectoryExA)
839 trace("skipping SHCreateDirectoryExA tests\n");
843 set_curr_dir_path(path, "testdir2\\test4.txt\0");
844 ret = pSHCreateDirectoryExA(NULL, path, NULL);
845 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
846 ok(file_exists("testdir2"), "The first directory is not created\n");
847 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
849 ret = pSHCreateDirectoryExA(NULL, path, NULL);
850 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
852 ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
853 ok(file_exists("c:\\testdir3"), "The directory is not created\n");
856 START_TEST(shlfileop)
858 InitFunctionPointers();
860 clean_after_shfo_tests();
864 clean_after_shfo_tests();
868 clean_after_shfo_tests();
872 clean_after_shfo_tests();
876 clean_after_shfo_tests();
878 test_sh_create_dir();
879 clean_after_shfo_tests();