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
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 RemoveDirectoryA("c:\\testdir3");
107 DeleteFileA("nonexistent\\notreal\\test2.txt");
108 RemoveDirectoryA("nonexistent\\notreal");
109 RemoveDirectoryA("nonexistent");
113 puts into the specified buffer file names with current directory.
114 files - string with file names, separated by null characters. Ends on a double
117 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
122 strcpy(buf, CURR_DIR);
127 buf += strlen(buf) + 1;
128 files += strlen(files) + 1;
134 /* tests the FO_DELETE action */
135 static void test_delete(void)
137 SHFILEOPSTRUCTA shfo;
141 sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
142 buf[strlen(buf) + 1] = '\0';
145 shfo.wFunc = FO_DELETE;
148 shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
149 shfo.hNameMappings = NULL;
150 shfo.lpszProgressTitle = NULL;
152 ok(!SHFileOperationA(&shfo), "Deletion was successful\n");
153 ok(file_exists("test4.txt"), "Directory should not be removed\n");
154 ok(!file_exists("test1.txt"), "File should be removed\n");
156 ret = SHFileOperationA(&shfo);
157 ok(!ret, "Directory exists, but is not removed, ret=%ld\n", ret);
158 ok(file_exists("test4.txt"), "Directory should not be removed\n");
160 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
162 ok(!SHFileOperationA(&shfo), "Directory removed\n");
163 ok(!file_exists("test4.txt"), "Directory should be removed\n");
165 ret = SHFileOperationA(&shfo);
166 ok(!ret, "The requested file does not exist, ret=%ld\n", ret);
169 sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
170 buf[strlen(buf) + 1] = '\0';
171 ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Fill the subdirectory\n");
172 ok(!SHFileOperationA(&shfo), "Directory removed\n");
173 ok(!file_exists("test4.txt"), "Directory is removed\n");
176 shfo.pFrom = "test1.txt\0test4.txt\0";
177 ok(!SHFileOperationA(&shfo), "Directory and a file removed\n");
178 ok(!file_exists("test1.txt"), "The file should be removed\n");
179 ok(!file_exists("test4.txt"), "Directory should be removed\n");
180 ok(file_exists("test2.txt"), "This file should not be removed\n");
182 /* FOF_FILESONLY does not delete a dir matching a wildcard */
184 shfo.fFlags |= FOF_FILESONLY;
185 shfo.pFrom = "*.txt\0";
186 ok(!SHFileOperation(&shfo), "Failed to delete files\n");
187 ok(!file_exists("test1.txt"), "test1.txt should be removed\n");
188 ok(!file_exists("test_5.txt"), "test_5.txt should be removed\n");
189 ok(file_exists("test4.txt"), "test4.txt should not be removed\n");
191 /* FOF_FILESONLY only deletes a dir if explicitly specified */
193 shfo.pFrom = "test_?.txt\0test4.txt\0";
194 ok(!SHFileOperation(&shfo), "Failed to delete files\n");
195 ok(!file_exists("test4.txt"), "test4.txt should be removed\n");
196 ok(!file_exists("test_5.txt"), "test_5.txt should be removed\n");
197 ok(file_exists("test1.txt"), "test1.txt should not be removed\n");
199 /* try to delete an invalid filename */
202 shfo.fFlags &= ~FOF_FILESONLY;
203 shfo.fAnyOperationsAborted = FALSE;
204 ret = SHFileOperation(&shfo);
205 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", ret);
206 ok(!shfo.fAnyOperationsAborted, "Expected no aborted operations\n");
207 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
209 /* try an invalid function */
211 shfo.pFrom = "test1.txt\0";
213 ret = SHFileOperation(&shfo);
214 ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret);
215 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
217 /* try an invalid list, only one null terminator */
220 shfo.wFunc = FO_DELETE;
221 ret = SHFileOperation(&shfo);
222 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", ret);
223 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
225 /* delete a dir, and then a file inside the dir, same as
226 * deleting a nonexistent file
229 shfo.pFrom = "testdir2\0testdir2\\one.txt\0";
230 ret = SHFileOperation(&shfo);
231 ok(ret == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %ld\n", ret);
232 ok(!file_exists("testdir2"), "Expected testdir2 to not exist\n");
233 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
235 /* try the FOF_NORECURSION flag, continues deleting subdirs */
237 shfo.pFrom = "testdir2\0";
238 shfo.fFlags |= FOF_NORECURSION;
239 ret = SHFileOperation(&shfo);
240 ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret);
241 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
242 ok(!file_exists("testdir2\\nested"), "Expected testdir2\\nested to exist\n");
245 /* tests the FO_RENAME action */
246 static void test_rename(void)
248 SHFILEOPSTRUCTA shfo, shfo2;
254 shfo.wFunc = FO_RENAME;
257 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
258 shfo.hNameMappings = NULL;
259 shfo.lpszProgressTitle = NULL;
261 set_curr_dir_path(from, "test1.txt\0");
262 set_curr_dir_path(to, "test4.txt\0");
263 ok(SHFileOperationA(&shfo), "File is not renamed moving to other directory "
264 "when specifying directory name only\n");
265 ok(file_exists("test1.txt"), "The file is removed\n");
267 set_curr_dir_path(from, "test3.txt\0");
268 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
269 ok(!SHFileOperationA(&shfo), "File is renamed moving to other directory\n");
270 ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
272 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
273 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
274 retval = SHFileOperationA(&shfo); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
275 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
276 "Can't rename many files, retval = %ld\n", retval);
277 ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
279 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
280 shfo2.fFlags |= FOF_MULTIDESTFILES;
282 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
283 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
284 retval = SHFileOperationA(&shfo2); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
285 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
286 "Can't rename many files, retval = %ld\n", retval);
287 ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
289 set_curr_dir_path(from, "test1.txt\0");
290 set_curr_dir_path(to, "test6.txt\0");
291 retval = SHFileOperationA(&shfo);
292 ok(!retval, "Rename file failed, retval = %ld\n", retval);
293 ok(!file_exists("test1.txt"), "The file is not renamed\n");
294 ok(file_exists("test6.txt"), "The file is not renamed\n");
296 set_curr_dir_path(from, "test6.txt\0");
297 set_curr_dir_path(to, "test1.txt\0");
298 retval = SHFileOperationA(&shfo);
299 ok(!retval, "Rename file back failed, retval = %ld\n", retval);
301 set_curr_dir_path(from, "test4.txt\0");
302 set_curr_dir_path(to, "test6.txt\0");
303 retval = SHFileOperationA(&shfo);
304 ok(!retval, "Rename dir failed, retval = %ld\n", retval);
305 ok(!file_exists("test4.txt"), "The dir is not renamed\n");
306 ok(file_exists("test6.txt"), "The dir is not renamed\n");
308 set_curr_dir_path(from, "test6.txt\0");
309 set_curr_dir_path(to, "test4.txt\0");
310 retval = SHFileOperationA(&shfo);
311 ok(!retval, "Rename dir back failed, retval = %ld\n", retval);
313 /* try to rename more than one file to a single file */
314 shfo.pFrom = "test1.txt\0test2.txt\0";
315 shfo.pTo = "a.txt\0";
316 retval = SHFileOperationA(&shfo);
317 ok(retval == ERROR_GEN_FAILURE, "Expected ERROR_GEN_FAILURE, got %ld\n", retval);
318 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
319 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
321 /* pFrom doesn't exist */
322 shfo.pFrom = "idontexist\0";
323 shfo.pTo = "newfile\0";
324 retval = SHFileOperationA(&shfo);
325 ok(retval == 1026, "Expected 1026, got %ld\n", retval);
326 ok(!file_exists("newfile"), "Expected newfile to not exist\n");
328 /* pTo already exist */
329 shfo.pFrom = "test1.txt\0";
330 shfo.pTo = "test2.txt\0";
331 retval = SHFileOperationA(&shfo);
332 ok(retval == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %ld\n", retval);
334 /* pFrom is valid, but pTo is empty */
335 shfo.pFrom = "test1.txt\0";
337 retval = SHFileOperationA(&shfo);
338 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
339 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
343 retval = SHFileOperationA(&shfo);
344 ok(retval == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", retval);
346 /* pFrom is NULL, commented out because it crashes on nt 4.0 */
349 retval = SHFileOperationA(&shfo);
350 ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", retval);
354 /* tests the FO_COPY action */
355 static void test_copy(void)
357 SHFILEOPSTRUCTA shfo, shfo2;
360 FILEOP_FLAGS tmp_flags;
364 shfo.wFunc = FO_COPY;
367 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
368 shfo.hNameMappings = NULL;
369 shfo.lpszProgressTitle = NULL;
371 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
372 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
373 ok(SHFileOperationA(&shfo), "Can't copy many files\n");
374 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
375 "specified as a target\n");
377 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
378 shfo2.fFlags |= FOF_MULTIDESTFILES;
380 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
381 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
382 ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
383 ok(file_exists("test6.txt"), "The file is copied - many files are "
384 "specified as a target\n");
385 DeleteFileA("test6.txt");
386 DeleteFileA("test7.txt");
387 RemoveDirectoryA("test8.txt");
389 /* number of sources do not correspond to number of targets */
390 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
391 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
392 ok(SHFileOperationA(&shfo2), "Can't copy many files\n");
393 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
394 "specified as a target\n");
396 set_curr_dir_path(from, "test1.txt\0");
397 set_curr_dir_path(to, "test4.txt\0");
398 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
399 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
401 set_curr_dir_path(from, "test?.txt\0");
402 set_curr_dir_path(to, "testdir2\0");
403 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
404 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
405 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
406 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
407 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
408 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
409 clean_after_shfo_tests();
412 shfo.fFlags |= FOF_FILESONLY;
413 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
414 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
415 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
416 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
417 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
418 clean_after_shfo_tests();
421 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
422 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
423 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
424 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
425 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
426 ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
427 clean_after_shfo_tests();
429 /* Copying multiple files with one not existing as source, fails the
430 entire operation in Win98/ME/2K/XP, but not in 95/NT */
432 tmp_flags = shfo.fFlags;
433 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
434 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
435 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
436 retval = SHFileOperationA(&shfo);
438 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
439 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
442 /* Win 98/ME/2K/XP fail the entire operation with return code 1026 if one source file does not exist */
443 ok(retval == 1026, "Files are copied to other directory\n");
444 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
446 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
447 shfo.fFlags = tmp_flags;
449 /* copy into a nonexistent directory */
451 shfo.fFlags = FOF_NOCONFIRMMKDIR;
452 set_curr_dir_path(from, "test1.txt\0");
453 set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
454 retval= SHFileOperation(&shfo);
455 ok(!retval, "Error copying into nonexistent directory\n");
456 ok(file_exists("nonexistent"), "nonexistent not created\n");
457 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
458 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
459 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
461 /* a relative dest directory is OK */
462 clean_after_shfo_tests();
464 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
465 shfo.pTo = "testdir2\0";
466 retval = SHFileOperation(&shfo);
467 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
468 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
470 /* try to copy files to a file */
471 clean_after_shfo_tests();
475 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
476 set_curr_dir_path(to, "test3.txt\0");
477 retval = SHFileOperation(&shfo);
478 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
479 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
480 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
482 /* try to copy many files to nonexistent directory */
484 shfo.fAnyOperationsAborted = FALSE;
485 retval = SHFileOperation(&shfo);
486 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
487 ok(DeleteFile("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
488 ok(DeleteFile("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
489 ok(RemoveDirectory(to), "Expected test3.txt to exist\n");
491 /* send in FOF_MULTIDESTFILES with too many destination files */
493 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
494 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
495 shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
496 retval = SHFileOperation(&shfo);
497 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
498 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
499 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
501 /* send in FOF_MULTIDESTFILES with too many destination files */
502 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
503 shfo.pTo = "e.txt\0f.txt\0";
504 shfo.fAnyOperationsAborted = FALSE;
505 retval = SHFileOperation(&shfo);
506 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
507 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
508 ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
510 /* use FOF_MULTIDESTFILES with files and a source directory */
511 shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
512 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
513 shfo.fAnyOperationsAborted = FALSE;
514 retval = SHFileOperation(&shfo);
515 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
516 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
517 ok(DeleteFile("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
518 ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
520 /* try many dest files without FOF_MULTIDESTFILES flag */
521 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
522 shfo.pTo = "a.txt\0b.txt\0c.txt\0";
523 shfo.fAnyOperationsAborted = FALSE;
524 shfo.fFlags &= ~FOF_MULTIDESTFILES;
525 retval = SHFileOperation(&shfo);
526 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
527 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
530 shfo.pFrom = "test?.txt\0";
531 shfo.pTo = "testdir2\0";
532 shfo.fFlags &= ~FOF_MULTIDESTFILES;
533 retval = SHFileOperation(&shfo);
534 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
535 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
537 /* try a glob with FOF_FILESONLY */
538 clean_after_shfo_tests();
540 shfo.pFrom = "test?.txt\0";
541 shfo.fFlags |= FOF_FILESONLY;
542 retval = SHFileOperation(&shfo);
543 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
544 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
545 ok(!file_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
547 /* try a glob with FOF_MULTIDESTFILES and the same number
548 * of dest files that we would expect
550 clean_after_shfo_tests();
552 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
553 shfo.fFlags &= ~FOF_FILESONLY;
554 shfo.fFlags |= FOF_MULTIDESTFILES;
555 retval = SHFileOperation(&shfo);
556 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
557 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
558 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
559 ok(!RemoveDirectory("b.txt"), "b.txt should not exist\n");
561 /* copy one file to two others, second is ignored */
562 clean_after_shfo_tests();
564 shfo.pFrom = "test1.txt\0";
565 shfo.pTo = "b.txt\0c.txt\0";
566 shfo.fAnyOperationsAborted = FALSE;
567 retval = SHFileOperation(&shfo);
568 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
569 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
570 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
572 /* copy two file to three others, all fail */
573 shfo.pFrom = "test1.txt\0test2.txt\0";
574 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
575 retval = SHFileOperation(&shfo);
576 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
577 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
578 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
580 /* copy one file and one directory to three others */
581 shfo.pFrom = "test1.txt\0test4.txt\0";
582 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
583 shfo.fAnyOperationsAborted = FALSE;
584 retval = SHFileOperation(&shfo);
585 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
586 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
587 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
588 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
590 /* copy a directory with a file beneath it, plus some files */
591 createTestFile("test4.txt\\a.txt");
592 shfo.pFrom = "test4.txt\0test1.txt\0";
593 shfo.pTo = "testdir2\0";
594 shfo.fFlags &= ~FOF_MULTIDESTFILES;
595 shfo.fAnyOperationsAborted = FALSE;
596 retval = SHFileOperation(&shfo);
597 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
598 ok(DeleteFile("testdir2\\test1.txt"), "Expected newdir\\test1.txt to exist\n");
599 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
600 ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
602 /* copy one directory and a file in that dir to another dir */
603 shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
604 shfo.pTo = "testdir2\0";
605 retval = SHFileOperation(&shfo);
606 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
607 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
608 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
610 /* copy a file in a directory first, and then the directory to a nonexistent dir */
611 shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
612 shfo.pTo = "nonexistent\0";
613 retval = SHFileOperation(&shfo);
614 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
615 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
616 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
617 DeleteFile("test4.txt\\a.txt");
619 /* destination is same as source file */
620 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
621 shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
622 shfo.fAnyOperationsAborted = FALSE;
623 shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
624 retval = SHFileOperation(&shfo);
625 ok(retval == ERROR_NO_MORE_SEARCH_HANDLES,
626 "Expected ERROR_NO_MORE_SEARCH_HANDLES, got %ld\n", retval);
627 ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
628 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
629 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
631 /* destination is same as source directory */
632 shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
633 shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
634 shfo.fAnyOperationsAborted = FALSE;
635 retval = SHFileOperation(&shfo);
636 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
637 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
638 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
640 /* copy a directory into itself, error displayed in UI */
641 shfo.pFrom = "test4.txt\0";
642 shfo.pTo = "test4.txt\\newdir\0";
643 shfo.fFlags &= ~FOF_MULTIDESTFILES;
644 shfo.fAnyOperationsAborted = FALSE;
645 retval = SHFileOperation(&shfo);
646 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
647 ok(!RemoveDirectory("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
649 /* copy a directory to itself, error displayed in UI */
650 shfo.pFrom = "test4.txt\0";
651 shfo.pTo = "test4.txt\0";
652 shfo.fAnyOperationsAborted = FALSE;
653 retval = SHFileOperation(&shfo);
654 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
656 /* copy a file into a directory, and the directory into itself */
657 shfo.pFrom = "test1.txt\0test4.txt\0";
658 shfo.pTo = "test4.txt\0";
659 shfo.fAnyOperationsAborted = FALSE;
660 shfo.fFlags |= FOF_NOCONFIRMATION;
661 retval = SHFileOperation(&shfo);
662 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
663 ok(DeleteFile("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
665 /* copy a file to a file, and the directory into itself */
666 shfo.pFrom = "test1.txt\0test4.txt\0";
667 shfo.pTo = "test4.txt\\a.txt\0";
668 shfo.fAnyOperationsAborted = FALSE;
669 retval = SHFileOperation(&shfo);
670 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
671 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
673 /* copy a nonexistent file to a nonexistent directory */
674 shfo.pFrom = "e.txt\0";
675 shfo.pTo = "nonexistent\0";
676 shfo.fAnyOperationsAborted = FALSE;
677 retval = SHFileOperation(&shfo);
678 ok(retval == 1026, "Expected 1026, got %ld\n", retval);
679 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
680 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
683 /* tests the FO_MOVE action */
684 static void test_move(void)
686 SHFILEOPSTRUCTA shfo, shfo2;
692 shfo.wFunc = FO_MOVE;
695 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
696 shfo.hNameMappings = NULL;
697 shfo.lpszProgressTitle = NULL;
699 set_curr_dir_path(from, "test1.txt\0");
700 set_curr_dir_path(to, "test4.txt\0");
701 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
702 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
703 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
705 set_curr_dir_path(from, "test?.txt\0");
706 set_curr_dir_path(to, "testdir2\0");
707 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
708 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
709 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
710 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
711 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
712 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
714 clean_after_shfo_tests();
717 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
718 shfo2.fFlags |= FOF_MULTIDESTFILES;
720 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
721 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
722 ok(!SHFileOperationA(&shfo2), "Move many files\n");
723 ok(file_exists("test6.txt"), "The file is moved - many files are "
724 "specified as a target\n");
725 DeleteFileA("test6.txt");
726 DeleteFileA("test7.txt");
727 RemoveDirectoryA("test8.txt");
731 /* number of sources do not correspond to number of targets */
732 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
733 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
734 ok(SHFileOperationA(&shfo2), "Can't move many files\n");
735 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
736 "specified as a target\n");
740 set_curr_dir_path(from, "test3.txt\0");
741 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
742 ok(!SHFileOperationA(&shfo), "File is moved moving to other directory\n");
743 ok(file_exists("test4.txt\\test1.txt"), "The file is moved\n");
745 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
746 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
747 ok(SHFileOperationA(&shfo), "Cannot move many files\n");
748 ok(file_exists("test1.txt"), "The file is not moved. Many files are specified\n");
749 ok(file_exists("test4.txt"), "The directory is not moved. Many files are specified\n");
751 set_curr_dir_path(from, "test1.txt\0");
752 set_curr_dir_path(to, "test6.txt\0");
753 ok(!SHFileOperationA(&shfo), "Move file\n");
754 ok(!file_exists("test1.txt"), "The file is moved\n");
755 ok(file_exists("test6.txt"), "The file is moved\n");
756 set_curr_dir_path(from, "test6.txt\0");
757 set_curr_dir_path(to, "test1.txt\0");
758 ok(!SHFileOperationA(&shfo), "Move file back\n");
760 set_curr_dir_path(from, "test4.txt\0");
761 set_curr_dir_path(to, "test6.txt\0");
762 ok(!SHFileOperationA(&shfo), "Move dir\n");
763 ok(!file_exists("test4.txt"), "The dir is moved\n");
764 ok(file_exists("test6.txt"), "The dir is moved\n");
765 set_curr_dir_path(from, "test6.txt\0");
766 set_curr_dir_path(to, "test4.txt\0");
767 ok(!SHFileOperationA(&shfo), "Move dir back\n");
769 /* move one file to two others */
771 shfo.pFrom = "test1.txt\0";
772 shfo.pTo = "a.txt\0b.txt\0";
773 retval = SHFileOperationA(&shfo);
774 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
775 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
776 ok(DeleteFile("a.txt"), "Expected a.txt to exist\n");
777 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
779 /* move two files to one other */
780 shfo.pFrom = "test2.txt\0test3.txt\0";
781 shfo.pTo = "test1.txt\0";
782 retval = SHFileOperationA(&shfo);
783 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
784 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
785 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
786 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
788 /* move a directory into itself */
789 shfo.pFrom = "test4.txt\0";
790 shfo.pTo = "test4.txt\\b.txt\0";
791 retval = SHFileOperationA(&shfo);
792 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
793 ok(!RemoveDirectory("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
794 ok(file_exists("test4.txt"), "Expected test4.txt to exist\n");
796 /* move many files without FOF_MULTIDESTFILES */
797 shfo.pFrom = "test2.txt\0test3.txt\0";
798 shfo.pTo = "d.txt\0e.txt\0";
799 retval = SHFileOperationA(&shfo);
800 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
801 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
802 ok(!DeleteFile("e.txt"), "Expected e.txt to not exist\n");
804 /* number of sources != number of targets */
805 shfo.pTo = "d.txt\0";
806 shfo.fFlags |= FOF_MULTIDESTFILES;
807 retval = SHFileOperationA(&shfo);
808 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
809 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
811 /* FO_MOVE does not create dest directories */
812 shfo.pFrom = "test2.txt\0";
813 shfo.pTo = "dir1\\dir2\\test2.txt\0";
814 retval = SHFileOperationA(&shfo);
815 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
816 ok(!file_exists("dir1"), "Expected dir1 to not exist\n");
818 /* try to overwrite an existing file */
819 shfo.pTo = "test3.txt\0";
820 retval = SHFileOperationA(&shfo);
821 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
822 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
823 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
826 static void test_sh_create_dir(void)
831 if(!pSHCreateDirectoryExA)
833 trace("skipping SHCreateDirectoryExA tests\n");
837 set_curr_dir_path(path, "testdir2\\test4.txt\0");
838 ret = pSHCreateDirectoryExA(NULL, path, NULL);
839 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
840 ok(file_exists("testdir2"), "The first directory is not created\n");
841 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
843 ret = pSHCreateDirectoryExA(NULL, path, NULL);
844 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
846 ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
847 ok(file_exists("c:\\testdir3"), "The directory is not created\n");
850 START_TEST(shlfileop)
852 InitFunctionPointers();
854 clean_after_shfo_tests();
858 clean_after_shfo_tests();
862 clean_after_shfo_tests();
866 clean_after_shfo_tests();
870 clean_after_shfo_tests();
872 test_sh_create_dir();
873 clean_after_shfo_tests();