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);
348 retval = SHFileOperationA(&shfo);
349 ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", retval);
352 /* tests the FO_COPY action */
353 static void test_copy(void)
355 SHFILEOPSTRUCTA shfo, shfo2;
358 FILEOP_FLAGS tmp_flags;
362 shfo.wFunc = FO_COPY;
365 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
366 shfo.hNameMappings = NULL;
367 shfo.lpszProgressTitle = NULL;
369 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
370 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
371 ok(SHFileOperationA(&shfo), "Can't copy many files\n");
372 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
373 "specified as a target\n");
375 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
376 shfo2.fFlags |= FOF_MULTIDESTFILES;
378 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
379 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
380 ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
381 ok(file_exists("test6.txt"), "The file is copied - many files are "
382 "specified as a target\n");
383 DeleteFileA("test6.txt");
384 DeleteFileA("test7.txt");
385 RemoveDirectoryA("test8.txt");
387 /* number of sources do not correspond to number of targets */
388 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
389 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
390 ok(SHFileOperationA(&shfo2), "Can't copy many files\n");
391 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
392 "specified as a target\n");
394 set_curr_dir_path(from, "test1.txt\0");
395 set_curr_dir_path(to, "test4.txt\0");
396 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
397 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
399 set_curr_dir_path(from, "test?.txt\0");
400 set_curr_dir_path(to, "testdir2\0");
401 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
402 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
403 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
404 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
405 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
406 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
407 clean_after_shfo_tests();
410 shfo.fFlags |= FOF_FILESONLY;
411 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
412 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
413 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
414 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
415 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
416 clean_after_shfo_tests();
419 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
420 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
421 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
422 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
423 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
424 ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
425 clean_after_shfo_tests();
427 /* Copying multiple files with one not existing as source, fails the
428 entire operation in Win98/ME/2K/XP, but not in 95/NT */
430 tmp_flags = shfo.fFlags;
431 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
432 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
433 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
434 retval = SHFileOperationA(&shfo);
436 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
437 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
440 /* Win 98/ME/2K/XP fail the entire operation with return code 1026 if one source file does not exist */
441 ok(retval == 1026, "Files are copied to other directory\n");
442 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
444 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
445 shfo.fFlags = tmp_flags;
447 /* copy into a nonexistent directory */
449 shfo.fFlags = FOF_NOCONFIRMMKDIR;
450 set_curr_dir_path(from, "test1.txt\0");
451 set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
452 retval= SHFileOperation(&shfo);
453 ok(!retval, "Error copying into nonexistent directory\n");
454 ok(file_exists("nonexistent"), "nonexistent not created\n");
455 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
456 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
457 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
459 /* a relative dest directory is OK */
460 clean_after_shfo_tests();
462 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
463 shfo.pTo = "testdir2\0";
464 retval = SHFileOperation(&shfo);
465 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
466 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
468 /* try to copy files to a file */
469 clean_after_shfo_tests();
473 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
474 set_curr_dir_path(to, "test3.txt\0");
475 retval = SHFileOperation(&shfo);
476 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
477 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
478 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
480 /* try to copy many files to nonexistent directory */
482 shfo.fAnyOperationsAborted = FALSE;
483 retval = SHFileOperation(&shfo);
484 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
485 ok(DeleteFile("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
486 ok(DeleteFile("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
487 ok(RemoveDirectory(to), "Expected test3.txt to exist\n");
489 /* send in FOF_MULTIDESTFILES with too many destination files */
491 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
492 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
493 shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
494 retval = SHFileOperation(&shfo);
495 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
496 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
497 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
499 /* send in FOF_MULTIDESTFILES with too many destination files */
500 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
501 shfo.pTo = "e.txt\0f.txt\0";
502 shfo.fAnyOperationsAborted = FALSE;
503 retval = SHFileOperation(&shfo);
504 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
505 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
506 ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
508 /* use FOF_MULTIDESTFILES with files and a source directory */
509 shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
510 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
511 shfo.fAnyOperationsAborted = FALSE;
512 retval = SHFileOperation(&shfo);
513 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
514 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
515 ok(DeleteFile("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
516 ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
518 /* try many dest files without FOF_MULTIDESTFILES flag */
519 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
520 shfo.pTo = "a.txt\0b.txt\0c.txt\0";
521 shfo.fAnyOperationsAborted = FALSE;
522 shfo.fFlags &= ~FOF_MULTIDESTFILES;
523 retval = SHFileOperation(&shfo);
524 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
525 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
528 shfo.pFrom = "test?.txt\0";
529 shfo.pTo = "testdir2\0";
530 shfo.fFlags &= ~FOF_MULTIDESTFILES;
531 retval = SHFileOperation(&shfo);
532 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
533 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
535 /* try a glob with FOF_FILESONLY */
536 clean_after_shfo_tests();
538 shfo.pFrom = "test?.txt\0";
539 shfo.fFlags |= FOF_FILESONLY;
540 retval = SHFileOperation(&shfo);
541 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
542 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
543 ok(!file_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
545 /* try a glob with FOF_MULTIDESTFILES and the same number
546 * of dest files that we would expect
548 clean_after_shfo_tests();
550 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
551 shfo.fFlags &= ~FOF_FILESONLY;
552 shfo.fFlags |= FOF_MULTIDESTFILES;
553 retval = SHFileOperation(&shfo);
554 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
555 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
556 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
557 ok(!RemoveDirectory("b.txt"), "b.txt should not exist\n");
559 /* copy one file to two others, second is ignored */
560 clean_after_shfo_tests();
562 shfo.pFrom = "test1.txt\0";
563 shfo.pTo = "b.txt\0c.txt\0";
564 shfo.fAnyOperationsAborted = FALSE;
565 retval = SHFileOperation(&shfo);
566 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
567 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
568 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
570 /* copy two file to three others, all fail */
571 shfo.pFrom = "test1.txt\0test2.txt\0";
572 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
573 retval = SHFileOperation(&shfo);
574 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
575 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
576 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
578 /* copy one file and one directory to three others */
579 shfo.pFrom = "test1.txt\0test4.txt\0";
580 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
581 shfo.fAnyOperationsAborted = FALSE;
582 retval = SHFileOperation(&shfo);
583 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
584 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
585 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
586 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
588 /* copy a directory with a file beneath it, plus some files */
589 createTestFile("test4.txt\\a.txt");
590 shfo.pFrom = "test4.txt\0test1.txt\0";
591 shfo.pTo = "testdir2\0";
592 shfo.fFlags &= ~FOF_MULTIDESTFILES;
593 shfo.fAnyOperationsAborted = FALSE;
594 retval = SHFileOperation(&shfo);
595 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
596 ok(DeleteFile("testdir2\\test1.txt"), "Expected newdir\\test1.txt to exist\n");
597 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
598 ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
600 /* copy one directory and a file in that dir to another dir */
601 shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
602 shfo.pTo = "testdir2\0";
603 retval = SHFileOperation(&shfo);
604 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
605 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
606 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
608 /* copy a file in a directory first, and then the directory to a nonexistent dir */
609 shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
610 shfo.pTo = "nonexistent\0";
611 retval = SHFileOperation(&shfo);
612 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
613 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
614 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
615 DeleteFile("test4.txt\\a.txt");
617 /* destination is same as source file */
618 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
619 shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
620 shfo.fAnyOperationsAborted = FALSE;
621 shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
622 retval = SHFileOperation(&shfo);
623 ok(retval == ERROR_NO_MORE_SEARCH_HANDLES,
624 "Expected ERROR_NO_MORE_SEARCH_HANDLES, got %ld\n", retval);
625 ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
626 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
627 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
629 /* destination is same as source directory */
630 shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
631 shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
632 shfo.fAnyOperationsAborted = FALSE;
633 retval = SHFileOperation(&shfo);
634 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
635 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
636 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
638 /* copy a directory into itself, error displayed in UI */
639 shfo.pFrom = "test4.txt\0";
640 shfo.pTo = "test4.txt\\newdir\0";
641 shfo.fFlags &= ~FOF_MULTIDESTFILES;
642 shfo.fAnyOperationsAborted = FALSE;
643 retval = SHFileOperation(&shfo);
644 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
645 ok(!RemoveDirectory("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
647 /* copy a directory to itself, error displayed in UI */
648 shfo.pFrom = "test4.txt\0";
649 shfo.pTo = "test4.txt\0";
650 shfo.fAnyOperationsAborted = FALSE;
651 retval = SHFileOperation(&shfo);
652 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
654 /* copy a file into a directory, and the directory into itself */
655 shfo.pFrom = "test1.txt\0test4.txt\0";
656 shfo.pTo = "test4.txt\0";
657 shfo.fAnyOperationsAborted = FALSE;
658 shfo.fFlags |= FOF_NOCONFIRMATION;
659 retval = SHFileOperation(&shfo);
660 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
661 ok(DeleteFile("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
663 /* copy a file to a file, and the directory into itself */
664 shfo.pFrom = "test1.txt\0test4.txt\0";
665 shfo.pTo = "test4.txt\\a.txt\0";
666 shfo.fAnyOperationsAborted = FALSE;
667 retval = SHFileOperation(&shfo);
668 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
669 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
671 /* copy a nonexistent file to a nonexistent directory */
672 shfo.pFrom = "e.txt\0";
673 shfo.pTo = "nonexistent\0";
674 shfo.fAnyOperationsAborted = FALSE;
675 retval = SHFileOperation(&shfo);
676 ok(retval == 1026, "Expected 1026, got %ld\n", retval);
677 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
678 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
681 /* tests the FO_MOVE action */
682 static void test_move(void)
684 SHFILEOPSTRUCTA shfo, shfo2;
690 shfo.wFunc = FO_MOVE;
693 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
694 shfo.hNameMappings = NULL;
695 shfo.lpszProgressTitle = NULL;
697 set_curr_dir_path(from, "test1.txt\0");
698 set_curr_dir_path(to, "test4.txt\0");
699 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
700 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
701 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
703 set_curr_dir_path(from, "test?.txt\0");
704 set_curr_dir_path(to, "testdir2\0");
705 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
706 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
707 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
708 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
709 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
710 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
712 clean_after_shfo_tests();
715 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
716 shfo2.fFlags |= FOF_MULTIDESTFILES;
718 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
719 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
720 ok(!SHFileOperationA(&shfo2), "Move many files\n");
721 ok(file_exists("test6.txt"), "The file is moved - many files are "
722 "specified as a target\n");
723 DeleteFileA("test6.txt");
724 DeleteFileA("test7.txt");
725 RemoveDirectoryA("test8.txt");
729 /* number of sources do not correspond to number of targets */
730 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
731 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
732 ok(SHFileOperationA(&shfo2), "Can't move many files\n");
733 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
734 "specified as a target\n");
738 set_curr_dir_path(from, "test3.txt\0");
739 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
740 ok(!SHFileOperationA(&shfo), "File is moved moving to other directory\n");
741 ok(file_exists("test4.txt\\test1.txt"), "The file is moved\n");
743 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
744 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
745 ok(SHFileOperationA(&shfo), "Cannot move many files\n");
746 ok(file_exists("test1.txt"), "The file is not moved. Many files are specified\n");
747 ok(file_exists("test4.txt"), "The directory is not moved. Many files are specified\n");
749 set_curr_dir_path(from, "test1.txt\0");
750 set_curr_dir_path(to, "test6.txt\0");
751 ok(!SHFileOperationA(&shfo), "Move file\n");
752 ok(!file_exists("test1.txt"), "The file is moved\n");
753 ok(file_exists("test6.txt"), "The file is moved\n");
754 set_curr_dir_path(from, "test6.txt\0");
755 set_curr_dir_path(to, "test1.txt\0");
756 ok(!SHFileOperationA(&shfo), "Move file back\n");
758 set_curr_dir_path(from, "test4.txt\0");
759 set_curr_dir_path(to, "test6.txt\0");
760 ok(!SHFileOperationA(&shfo), "Move dir\n");
761 ok(!file_exists("test4.txt"), "The dir is moved\n");
762 ok(file_exists("test6.txt"), "The dir is moved\n");
763 set_curr_dir_path(from, "test6.txt\0");
764 set_curr_dir_path(to, "test4.txt\0");
765 ok(!SHFileOperationA(&shfo), "Move dir back\n");
767 /* move one file to two others */
769 shfo.pFrom = "test1.txt\0";
770 shfo.pTo = "a.txt\0b.txt\0";
771 retval = SHFileOperationA(&shfo);
772 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
773 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
774 ok(DeleteFile("a.txt"), "Expected a.txt to exist\n");
775 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
777 /* move two files to one other */
778 shfo.pFrom = "test2.txt\0test3.txt\0";
779 shfo.pTo = "test1.txt\0";
780 retval = SHFileOperationA(&shfo);
781 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
782 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
783 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
784 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
786 /* move a directory into itself */
787 shfo.pFrom = "test4.txt\0";
788 shfo.pTo = "test4.txt\\b.txt\0";
789 retval = SHFileOperationA(&shfo);
790 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
791 ok(!RemoveDirectory("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
792 ok(file_exists("test4.txt"), "Expected test4.txt to exist\n");
794 /* move many files without FOF_MULTIDESTFILES */
795 shfo.pFrom = "test2.txt\0test3.txt\0";
796 shfo.pTo = "d.txt\0e.txt\0";
797 retval = SHFileOperationA(&shfo);
798 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
799 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
800 ok(!DeleteFile("e.txt"), "Expected e.txt to not exist\n");
802 /* number of sources != number of targets */
803 shfo.pTo = "d.txt\0";
804 shfo.fFlags |= FOF_MULTIDESTFILES;
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");
809 /* FO_MOVE does not create dest directories */
810 shfo.pFrom = "test2.txt\0";
811 shfo.pTo = "dir1\\dir2\\test2.txt\0";
812 retval = SHFileOperationA(&shfo);
813 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %ld\n", retval);
814 ok(!file_exists("dir1"), "Expected dir1 to not exist\n");
816 /* try to overwrite an existing file */
817 shfo.pTo = "test3.txt\0";
818 retval = SHFileOperationA(&shfo);
819 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
820 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
821 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
824 static void test_sh_create_dir(void)
829 if(!pSHCreateDirectoryExA)
831 trace("skipping SHCreateDirectoryExA tests\n");
835 set_curr_dir_path(path, "testdir2\\test4.txt\0");
836 ret = pSHCreateDirectoryExA(NULL, path, NULL);
837 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
838 ok(file_exists("testdir2"), "The first directory is not created\n");
839 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
841 ret = pSHCreateDirectoryExA(NULL, path, NULL);
842 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
844 ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
845 ok(file_exists("c:\\testdir3"), "The directory is not created\n");
848 START_TEST(shlfileop)
850 InitFunctionPointers();
852 clean_after_shfo_tests();
856 clean_after_shfo_tests();
860 clean_after_shfo_tests();
864 clean_after_shfo_tests();
868 clean_after_shfo_tests();
870 test_sh_create_dir();
871 clean_after_shfo_tests();