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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define WINE_NOWINSOCK
31 #include "wine/test.h"
33 CHAR CURR_DIR[MAX_PATH];
35 static HMODULE hshell32;
36 static int (WINAPI *pSHCreateDirectoryExA)(HWND, LPCSTR, LPSECURITY_ATTRIBUTES);
38 static void InitFunctionPointers(void)
40 hshell32 = GetModuleHandleA("shell32.dll");
43 pSHCreateDirectoryExA = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExA");
46 /* creates a file with the specified name for tests */
47 static void createTestFile(const CHAR *name)
52 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
53 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
54 WriteFile(file, name, strlen(name), &written, NULL);
55 WriteFile(file, "\n", strlen("\n"), &written, NULL);
59 static BOOL file_exists(const CHAR *name)
61 return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
64 /* initializes the tests */
65 static void init_shfo_tests(void)
69 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
70 len = lstrlenA(CURR_DIR);
72 if(len && (CURR_DIR[len-1] == '\\'))
75 createTestFile("test1.txt");
76 createTestFile("test2.txt");
77 createTestFile("test3.txt");
78 createTestFile("test_5.txt");
79 CreateDirectoryA("test4.txt", NULL);
80 CreateDirectoryA("testdir2", NULL);
81 CreateDirectoryA("testdir2\\nested", NULL);
82 createTestFile("testdir2\\one.txt");
83 createTestFile("testdir2\\nested\\two.txt");
86 /* cleans after tests */
87 static void clean_after_shfo_tests(void)
89 DeleteFileA("test1.txt");
90 DeleteFileA("test2.txt");
91 DeleteFileA("test3.txt");
92 DeleteFileA("test_5.txt");
93 DeleteFileA("test4.txt\\test1.txt");
94 DeleteFileA("test4.txt\\test2.txt");
95 DeleteFileA("test4.txt\\test3.txt");
96 RemoveDirectoryA("test4.txt");
97 DeleteFileA("testdir2\\one.txt");
98 DeleteFileA("testdir2\\test1.txt");
99 DeleteFileA("testdir2\\test2.txt");
100 DeleteFileA("testdir2\\test3.txt");
101 DeleteFileA("testdir2\\test4.txt\\test1.txt");
102 DeleteFileA("testdir2\\nested\\two.txt");
103 RemoveDirectoryA("testdir2\\test4.txt");
104 RemoveDirectoryA("testdir2\\nested");
105 RemoveDirectoryA("testdir2");
106 DeleteFileA("nonexistent\\notreal\\test2.txt");
107 RemoveDirectoryA("nonexistent\\notreal");
108 RemoveDirectoryA("nonexistent");
112 puts into the specified buffer file names with current directory.
113 files - string with file names, separated by null characters. Ends on a double
116 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
121 strcpy(buf, CURR_DIR);
126 buf += strlen(buf) + 1;
127 files += strlen(files) + 1;
133 /* tests the FO_DELETE action */
134 static void test_delete(void)
136 SHFILEOPSTRUCTA shfo;
140 sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
141 buf[strlen(buf) + 1] = '\0';
144 shfo.wFunc = FO_DELETE;
147 shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
148 shfo.hNameMappings = NULL;
149 shfo.lpszProgressTitle = NULL;
151 ok(!SHFileOperationA(&shfo), "Deletion was successful\n");
152 ok(file_exists("test4.txt"), "Directory should not be removed\n");
153 ok(!file_exists("test1.txt"), "File should be removed\n");
155 ret = SHFileOperationA(&shfo);
156 ok(!ret, "Directory exists, but is not removed, ret=%ld\n", ret);
157 ok(file_exists("test4.txt"), "Directory should not be removed\n");
159 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
161 ok(!SHFileOperationA(&shfo), "Directory removed\n");
162 ok(!file_exists("test4.txt"), "Directory should be removed\n");
164 ret = SHFileOperationA(&shfo);
165 ok(!ret, "The requested file does not exist, ret=%ld\n", ret);
168 sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
169 buf[strlen(buf) + 1] = '\0';
170 ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Fill the subdirectory\n");
171 ok(!SHFileOperationA(&shfo), "Directory removed\n");
172 ok(!file_exists("test4.txt"), "Directory is removed\n");
175 shfo.pFrom = "test1.txt\0test4.txt\0";
176 ok(!SHFileOperationA(&shfo), "Directory and a file removed\n");
177 ok(!file_exists("test1.txt"), "The file should be removed\n");
178 ok(!file_exists("test4.txt"), "Directory should be removed\n");
179 ok(file_exists("test2.txt"), "This file should not be removed\n");
181 /* FOF_FILESONLY does not delete a dir matching a wildcard */
183 shfo.fFlags |= FOF_FILESONLY;
184 shfo.pFrom = "*.txt\0";
185 ok(!SHFileOperation(&shfo), "Failed to delete files\n");
186 ok(!file_exists("test1.txt"), "test1.txt should be removed\n");
187 ok(!file_exists("test_5.txt"), "test_5.txt should be removed\n");
188 ok(file_exists("test4.txt"), "test4.txt should not be removed\n");
190 /* FOF_FILESONLY only deletes a dir if explicitly specified */
192 shfo.pFrom = "test_?.txt\0test4.txt\0";
193 ok(!SHFileOperation(&shfo), "Failed to delete files\n");
194 ok(!file_exists("test4.txt"), "test4.txt should be removed\n");
195 ok(!file_exists("test_5.txt"), "test_5.txt should be removed\n");
196 ok(file_exists("test1.txt"), "test1.txt should not be removed\n");
198 /* try to delete an invalid filename */
201 shfo.fFlags &= ~FOF_FILESONLY;
202 shfo.fAnyOperationsAborted = FALSE;
203 ret = SHFileOperation(&shfo);
204 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", ret);
205 ok(!shfo.fAnyOperationsAborted, "Expected no aborted operations\n");
206 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
208 /* try an invalid function */
210 shfo.pFrom = "test1.txt\0";
212 ret = SHFileOperation(&shfo);
213 ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret);
214 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
216 /* try an invalid list, only one null terminator */
219 shfo.wFunc = FO_DELETE;
220 ret = SHFileOperation(&shfo);
221 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", ret);
222 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
224 /* delete a dir, and then a file inside the dir, same as
225 * deleting a nonexistent file
228 shfo.pFrom = "testdir2\0testdir2\\one.txt\0";
229 ret = SHFileOperation(&shfo);
230 ok(ret == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %ld\n", ret);
231 ok(!file_exists("testdir2"), "Expected testdir2 to not exist\n");
232 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
234 /* try the FOF_NORECURSION flag, continues deleting subdirs */
236 shfo.pFrom = "testdir2\0";
237 shfo.fFlags |= FOF_NORECURSION;
238 ret = SHFileOperation(&shfo);
239 ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret);
240 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
241 ok(!file_exists("testdir2\\nested"), "Expected testdir2\\nested to exist\n");
244 /* tests the FO_RENAME action */
245 static void test_rename(void)
247 SHFILEOPSTRUCTA shfo, shfo2;
253 shfo.wFunc = FO_RENAME;
256 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
257 shfo.hNameMappings = NULL;
258 shfo.lpszProgressTitle = NULL;
260 set_curr_dir_path(from, "test1.txt\0");
261 set_curr_dir_path(to, "test4.txt\0");
262 ok(SHFileOperationA(&shfo), "File is not renamed moving to other directory "
263 "when specifying directory name only\n");
264 ok(file_exists("test1.txt"), "The file is removed\n");
266 set_curr_dir_path(from, "test3.txt\0");
267 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
268 ok(!SHFileOperationA(&shfo), "File is renamed moving to other directory\n");
269 ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
271 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
272 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
273 retval = SHFileOperationA(&shfo); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
274 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
275 "Can't rename many files, retval = %ld\n", retval);
276 ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
278 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
279 shfo2.fFlags |= FOF_MULTIDESTFILES;
281 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
282 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
283 retval = SHFileOperationA(&shfo2); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
284 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
285 "Can't rename many files, retval = %ld\n", retval);
286 ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
288 set_curr_dir_path(from, "test1.txt\0");
289 set_curr_dir_path(to, "test6.txt\0");
290 retval = SHFileOperationA(&shfo);
291 ok(!retval, "Rename file failed, retval = %ld\n", retval);
292 ok(!file_exists("test1.txt"), "The file is not renamed\n");
293 ok(file_exists("test6.txt"), "The file is not renamed\n");
295 set_curr_dir_path(from, "test6.txt\0");
296 set_curr_dir_path(to, "test1.txt\0");
297 retval = SHFileOperationA(&shfo);
298 ok(!retval, "Rename file back failed, retval = %ld\n", retval);
300 set_curr_dir_path(from, "test4.txt\0");
301 set_curr_dir_path(to, "test6.txt\0");
302 retval = SHFileOperationA(&shfo);
303 ok(!retval, "Rename dir failed, retval = %ld\n", retval);
304 ok(!file_exists("test4.txt"), "The dir is not renamed\n");
305 ok(file_exists("test6.txt"), "The dir is not renamed\n");
307 set_curr_dir_path(from, "test6.txt\0");
308 set_curr_dir_path(to, "test4.txt\0");
309 retval = SHFileOperationA(&shfo);
310 ok(!retval, "Rename dir back failed, retval = %ld\n", retval);
312 /* try to rename more than one file to a single file */
313 shfo.pFrom = "test1.txt\0test2.txt\0";
314 shfo.pTo = "a.txt\0";
315 retval = SHFileOperationA(&shfo);
316 ok(retval == ERROR_GEN_FAILURE, "Expected ERROR_GEN_FAILURE, got %ld\n", retval);
317 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
318 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
320 /* pFrom doesn't exist */
321 shfo.pFrom = "idontexist\0";
322 shfo.pTo = "newfile\0";
323 retval = SHFileOperationA(&shfo);
324 ok(retval == 1026, "Expected 1026, got %ld\n", retval);
325 ok(!file_exists("newfile"), "Expected newfile to not exist\n");
327 /* pTo already exist */
328 shfo.pFrom = "test1.txt\0";
329 shfo.pTo = "test2.txt\0";
330 retval = SHFileOperationA(&shfo);
331 ok(retval == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %ld\n", retval);
333 /* pFrom is valid, but pTo is empty */
334 shfo.pFrom = "test1.txt\0";
336 retval = SHFileOperationA(&shfo);
337 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
338 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
342 retval = SHFileOperationA(&shfo);
343 ok(retval == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", retval);
347 retval = SHFileOperationA(&shfo);
348 ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", retval);
351 /* tests the FO_COPY action */
352 static void test_copy(void)
354 SHFILEOPSTRUCTA shfo, shfo2;
357 FILEOP_FLAGS tmp_flags;
361 shfo.wFunc = FO_COPY;
364 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
365 shfo.hNameMappings = NULL;
366 shfo.lpszProgressTitle = NULL;
368 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
369 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
370 ok(SHFileOperationA(&shfo), "Can't copy many files\n");
371 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
372 "specified as a target\n");
374 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
375 shfo2.fFlags |= FOF_MULTIDESTFILES;
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(&shfo2), "Can't copy many files\n");
380 ok(file_exists("test6.txt"), "The file is copied - many files are "
381 "specified as a target\n");
382 DeleteFileA("test6.txt");
383 DeleteFileA("test7.txt");
384 RemoveDirectoryA("test8.txt");
386 /* number of sources do not correspond to number of targets */
387 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
388 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
389 ok(SHFileOperationA(&shfo2), "Can't copy many files\n");
390 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
391 "specified as a target\n");
393 set_curr_dir_path(from, "test1.txt\0");
394 set_curr_dir_path(to, "test4.txt\0");
395 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
396 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
398 set_curr_dir_path(from, "test?.txt\0");
399 set_curr_dir_path(to, "testdir2\0");
400 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
401 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
402 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
403 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
404 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
405 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
406 clean_after_shfo_tests();
409 shfo.fFlags |= FOF_FILESONLY;
410 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
411 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
412 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
413 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
414 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
415 clean_after_shfo_tests();
418 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
419 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
420 ok(!file_exists("testdir2\\test2.txt"), "The file 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\\test2.txt"), "The file is copied\n");
424 clean_after_shfo_tests();
426 /* Copying multiple files with one not existing as source, fails the
427 entire operation in Win98/ME/2K/XP, but not in 95/NT */
429 tmp_flags = shfo.fFlags;
430 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
431 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
432 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
433 retval = SHFileOperationA(&shfo);
435 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
436 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
439 /* Win 98/ME/2K/XP fail the entire operation with return code 1026 if one source file does not exist */
440 ok(retval == 1026, "Files are copied to other directory\n");
441 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
443 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
444 shfo.fFlags = tmp_flags;
446 /* copy into a nonexistent directory */
448 shfo.fFlags = FOF_NOCONFIRMMKDIR;
449 set_curr_dir_path(from, "test1.txt\0");
450 set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
451 retval= SHFileOperation(&shfo);
452 ok(!retval, "Error copying into nonexistent directory\n");
453 ok(file_exists("nonexistent"), "nonexistent not created\n");
454 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
455 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
456 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
458 /* a relative dest directory is OK */
459 clean_after_shfo_tests();
461 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
462 shfo.pTo = "testdir2\0";
463 retval = SHFileOperation(&shfo);
464 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
465 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
467 /* try to copy files to a file */
468 clean_after_shfo_tests();
472 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
473 set_curr_dir_path(to, "test3.txt\0");
474 retval = SHFileOperation(&shfo);
475 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
476 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
477 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
479 /* try to copy many files to nonexistent directory */
481 shfo.fAnyOperationsAborted = FALSE;
482 retval = SHFileOperation(&shfo);
483 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
484 ok(DeleteFile("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
485 ok(DeleteFile("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
486 ok(RemoveDirectory(to), "Expected test3.txt to exist\n");
488 /* send in FOF_MULTIDESTFILES with too many destination files */
490 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
491 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
492 shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
493 retval = SHFileOperation(&shfo);
494 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
495 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
496 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
498 /* send in FOF_MULTIDESTFILES with too many destination files */
499 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
500 shfo.pTo = "e.txt\0f.txt\0";
501 shfo.fAnyOperationsAborted = FALSE;
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("e.txt"), "Expected e.txt to not exist\n");
507 /* use FOF_MULTIDESTFILES with files and a source directory */
508 shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
509 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
510 shfo.fAnyOperationsAborted = FALSE;
511 retval = SHFileOperation(&shfo);
512 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
513 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
514 ok(DeleteFile("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
515 ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
517 /* try many dest files without FOF_MULTIDESTFILES flag */
518 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
519 shfo.pTo = "a.txt\0b.txt\0c.txt\0";
520 shfo.fAnyOperationsAborted = FALSE;
521 shfo.fFlags &= ~FOF_MULTIDESTFILES;
522 retval = SHFileOperation(&shfo);
523 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
524 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
527 shfo.pFrom = "test?.txt\0";
528 shfo.pTo = "testdir2\0";
529 shfo.fFlags &= ~FOF_MULTIDESTFILES;
530 retval = SHFileOperation(&shfo);
531 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
532 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
534 /* try a glob with FOF_FILESONLY */
535 clean_after_shfo_tests();
537 shfo.pFrom = "test?.txt\0";
538 shfo.fFlags |= FOF_FILESONLY;
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");
542 ok(!file_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
544 /* try a glob with FOF_MULTIDESTFILES and the same number
545 * of dest files that we would expect
547 clean_after_shfo_tests();
549 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
550 shfo.fFlags &= ~FOF_FILESONLY;
551 shfo.fFlags |= FOF_MULTIDESTFILES;
552 retval = SHFileOperation(&shfo);
553 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
554 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
555 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
556 ok(!RemoveDirectory("b.txt"), "b.txt should not exist\n");
558 /* copy one file to two others, second is ignored */
559 clean_after_shfo_tests();
561 shfo.pFrom = "test1.txt\0";
562 shfo.pTo = "b.txt\0c.txt\0";
563 shfo.fAnyOperationsAborted = FALSE;
564 retval = SHFileOperation(&shfo);
565 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
566 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
567 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
569 /* copy two file to three others, all fail */
570 shfo.pFrom = "test1.txt\0test2.txt\0";
571 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
572 retval = SHFileOperation(&shfo);
573 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
574 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
575 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
577 /* copy one file and one directory to three others */
578 shfo.pFrom = "test1.txt\0test4.txt\0";
579 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
580 shfo.fAnyOperationsAborted = FALSE;
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");
585 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
587 /* copy a directory with a file beneath it, plus some files */
588 createTestFile("test4.txt\\a.txt");
589 shfo.pFrom = "test4.txt\0test1.txt\0";
590 shfo.pTo = "testdir2\0";
591 shfo.fFlags &= ~FOF_MULTIDESTFILES;
592 shfo.fAnyOperationsAborted = FALSE;
593 retval = SHFileOperation(&shfo);
594 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
595 ok(DeleteFile("testdir2\\test1.txt"), "Expected newdir\\test1.txt to exist\n");
596 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
597 ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
599 /* copy one directory and a file in that dir to another dir */
600 shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
601 shfo.pTo = "testdir2\0";
602 retval = SHFileOperation(&shfo);
603 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
604 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
605 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
607 /* copy a file in a directory first, and then the directory to a nonexistent dir */
608 shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
609 shfo.pTo = "nonexistent\0";
610 retval = SHFileOperation(&shfo);
611 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
612 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
613 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
614 DeleteFile("test4.txt\\a.txt");
616 /* destination is same as source file */
617 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
618 shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
619 shfo.fAnyOperationsAborted = FALSE;
620 shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
621 retval = SHFileOperation(&shfo);
622 ok(retval == ERROR_NO_MORE_SEARCH_HANDLES,
623 "Expected ERROR_NO_MORE_SEARCH_HANDLES, got %ld\n", retval);
624 ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
625 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
626 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
628 /* destination is same as source directory */
629 shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
630 shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
631 shfo.fAnyOperationsAborted = FALSE;
632 retval = SHFileOperation(&shfo);
633 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
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 /* copy a directory into itself, error displayed in UI */
638 shfo.pFrom = "test4.txt\0";
639 shfo.pTo = "test4.txt\\newdir\0";
640 shfo.fFlags &= ~FOF_MULTIDESTFILES;
641 shfo.fAnyOperationsAborted = FALSE;
642 retval = SHFileOperation(&shfo);
643 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
644 ok(!RemoveDirectory("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
646 /* copy a directory to itself, error displayed in UI */
647 shfo.pFrom = "test4.txt\0";
648 shfo.pTo = "test4.txt\0";
649 shfo.fAnyOperationsAborted = FALSE;
650 retval = SHFileOperation(&shfo);
651 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
653 /* copy a file into a directory, and the directory into itself */
654 shfo.pFrom = "test1.txt\0test4.txt\0";
655 shfo.pTo = "test4.txt\0";
656 shfo.fAnyOperationsAborted = FALSE;
657 shfo.fFlags |= FOF_NOCONFIRMATION;
658 retval = SHFileOperation(&shfo);
659 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
660 ok(DeleteFile("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
662 /* copy a file to a file, and the directory into itself */
663 shfo.pFrom = "test1.txt\0test4.txt\0";
664 shfo.pTo = "test4.txt\\a.txt\0";
665 shfo.fAnyOperationsAborted = FALSE;
666 retval = SHFileOperation(&shfo);
667 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
668 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
670 /* copy a nonexistent file to a nonexistent directory */
671 shfo.pFrom = "e.txt\0";
672 shfo.pTo = "nonexistent\0";
673 shfo.fAnyOperationsAborted = FALSE;
674 retval = SHFileOperation(&shfo);
675 ok(retval == 1026, "Expected 1026, got %ld\n", retval);
676 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
677 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
680 /* tests the FO_MOVE action */
681 static void test_move(void)
683 SHFILEOPSTRUCTA shfo, shfo2;
689 shfo.wFunc = FO_MOVE;
692 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
693 shfo.hNameMappings = NULL;
694 shfo.lpszProgressTitle = NULL;
696 set_curr_dir_path(from, "test1.txt\0");
697 set_curr_dir_path(to, "test4.txt\0");
698 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
699 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
700 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
702 set_curr_dir_path(from, "test?.txt\0");
703 set_curr_dir_path(to, "testdir2\0");
704 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
705 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
706 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
707 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
708 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
709 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
711 clean_after_shfo_tests();
714 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
715 shfo2.fFlags |= FOF_MULTIDESTFILES;
717 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
718 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
719 ok(!SHFileOperationA(&shfo2), "Move many files\n");
720 ok(file_exists("test6.txt"), "The file is moved - many files are "
721 "specified as a target\n");
722 DeleteFileA("test6.txt");
723 DeleteFileA("test7.txt");
724 RemoveDirectoryA("test8.txt");
728 /* number of sources do not correspond to number of targets */
729 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
730 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
731 ok(SHFileOperationA(&shfo2), "Can't move many files\n");
732 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
733 "specified as a target\n");
737 set_curr_dir_path(from, "test3.txt\0");
738 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
739 ok(!SHFileOperationA(&shfo), "File is moved moving to other directory\n");
740 ok(file_exists("test4.txt\\test1.txt"), "The file is moved\n");
742 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
743 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
744 ok(SHFileOperationA(&shfo), "Cannot move many files\n");
745 ok(file_exists("test1.txt"), "The file is not moved. Many files are specified\n");
746 ok(file_exists("test4.txt"), "The directory is not moved. Many files are specified\n");
748 set_curr_dir_path(from, "test1.txt\0");
749 set_curr_dir_path(to, "test6.txt\0");
750 ok(!SHFileOperationA(&shfo), "Move file\n");
751 ok(!file_exists("test1.txt"), "The file is moved\n");
752 ok(file_exists("test6.txt"), "The file is moved\n");
753 set_curr_dir_path(from, "test6.txt\0");
754 set_curr_dir_path(to, "test1.txt\0");
755 ok(!SHFileOperationA(&shfo), "Move file back\n");
757 set_curr_dir_path(from, "test4.txt\0");
758 set_curr_dir_path(to, "test6.txt\0");
759 ok(!SHFileOperationA(&shfo), "Move dir\n");
760 ok(!file_exists("test4.txt"), "The dir is moved\n");
761 ok(file_exists("test6.txt"), "The dir is moved\n");
762 set_curr_dir_path(from, "test6.txt\0");
763 set_curr_dir_path(to, "test4.txt\0");
764 ok(!SHFileOperationA(&shfo), "Move dir back\n");
766 /* move one file to two others */
768 shfo.pFrom = "test1.txt\0";
769 shfo.pTo = "a.txt\0b.txt\0";
770 retval = SHFileOperationA(&shfo);
771 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
772 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
773 ok(DeleteFile("a.txt"), "Expected a.txt to exist\n");
774 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
776 /* move two files to one other */
777 shfo.pFrom = "test2.txt\0test3.txt\0";
778 shfo.pTo = "test1.txt\0";
779 retval = SHFileOperationA(&shfo);
780 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
781 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
782 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
783 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
785 /* move a directory into itself */
786 shfo.pFrom = "test4.txt\0";
787 shfo.pTo = "test4.txt\\b.txt\0";
788 retval = SHFileOperationA(&shfo);
789 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
790 ok(!RemoveDirectory("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
791 ok(file_exists("test4.txt"), "Expected test4.txt to exist\n");
793 /* move many files without FOF_MULTIDESTFILES */
794 shfo.pFrom = "test2.txt\0test3.txt\0";
795 shfo.pTo = "d.txt\0e.txt\0";
796 retval = SHFileOperationA(&shfo);
797 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
798 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
799 ok(!DeleteFile("e.txt"), "Expected e.txt to not exist\n");
801 /* number of sources != number of targets */
802 shfo.pTo = "d.txt\0";
803 shfo.fFlags |= FOF_MULTIDESTFILES;
804 retval = SHFileOperationA(&shfo);
805 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
806 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
808 /* FO_MOVE does not create dest directories */
809 shfo.pFrom = "test2.txt\0";
810 shfo.pTo = "dir1\\dir2\\test2.txt\0";
811 retval = SHFileOperationA(&shfo);
812 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
813 ok(!file_exists("dir1"), "Expected dir1 to not exist\n");
815 /* try to overwrite an existing file */
816 shfo.pTo = "test3.txt\0";
817 retval = SHFileOperationA(&shfo);
818 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
819 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
820 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
823 static void test_sh_create_dir(void)
828 if(!pSHCreateDirectoryExA)
830 trace("skipping SHCreateDirectoryExA tests\n");
834 set_curr_dir_path(path, "testdir2\\test4.txt\0");
835 ret = pSHCreateDirectoryExA(NULL, path, NULL);
836 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
837 ok(file_exists("testdir2"), "The first directory is not created\n");
838 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
840 ret = pSHCreateDirectoryExA(NULL, path, NULL);
841 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
844 START_TEST(shlfileop)
846 InitFunctionPointers();
848 clean_after_shfo_tests();
852 clean_after_shfo_tests();
856 clean_after_shfo_tests();
860 clean_after_shfo_tests();
864 clean_after_shfo_tests();
866 test_sh_create_dir();
867 clean_after_shfo_tests();