2 * Unit test of the SHFileOperation function.
4 * Copyright 2002 Andriy Palamarchuk
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WINE_NOWINSOCK
29 #include "wine/test.h"
31 #ifndef FOF_NORECURSION
32 #define FOF_NORECURSION 0x1000
35 static CHAR CURR_DIR
[MAX_PATH
];
36 static const WCHAR UNICODE_PATH
[] = {'c',':','\\',0x00c4,'\0','\0'};
37 /* "c:\Ä", or "c:\A" with diaeresis */
38 /* Double-null termination needed for pFrom field of SHFILEOPSTRUCT */
40 static HMODULE hshell32
;
41 static int (WINAPI
*pSHCreateDirectoryExA
)(HWND
, LPCSTR
, LPSECURITY_ATTRIBUTES
);
42 static int (WINAPI
*pSHCreateDirectoryExW
)(HWND
, LPCWSTR
, LPSECURITY_ATTRIBUTES
);
43 static int (WINAPI
*pSHPathPrepareForWriteA
)(HWND
, IUnknown
*, LPCSTR
, DWORD
);
44 static int (WINAPI
*pSHPathPrepareForWriteW
)(HWND
, IUnknown
*, LPCWSTR
, DWORD
);
46 static void InitFunctionPointers(void)
48 hshell32
= GetModuleHandleA("shell32.dll");
49 pSHCreateDirectoryExA
= (void*)GetProcAddress(hshell32
, "SHCreateDirectoryExA");
50 pSHCreateDirectoryExW
= (void*)GetProcAddress(hshell32
, "SHCreateDirectoryExW");
51 pSHPathPrepareForWriteA
= (void*)GetProcAddress(hshell32
, "SHPathPrepareForWriteA");
52 pSHPathPrepareForWriteW
= (void*)GetProcAddress(hshell32
, "SHPathPrepareForWriteW");
55 /* creates a file with the specified name for tests */
56 static void createTestFile(const CHAR
*name
)
61 file
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
62 ok(file
!= INVALID_HANDLE_VALUE
, "Failure to open file %s\n", name
);
63 WriteFile(file
, name
, strlen(name
), &written
, NULL
);
64 WriteFile(file
, "\n", strlen("\n"), &written
, NULL
);
68 static void createTestFileW(const WCHAR
*name
)
72 file
= CreateFileW(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
73 ok(file
!= INVALID_HANDLE_VALUE
, "Failure to open file\n");
77 static BOOL
file_exists(const CHAR
*name
)
79 return GetFileAttributesA(name
) != INVALID_FILE_ATTRIBUTES
;
82 static BOOL
file_existsW(LPCWSTR name
)
84 return GetFileAttributesW(name
) != INVALID_FILE_ATTRIBUTES
;
87 static BOOL
file_has_content(const CHAR
*name
, const CHAR
*content
)
93 file
= CreateFileA(name
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
94 if (file
== INVALID_HANDLE_VALUE
)
96 ReadFile(file
, buf
, MAX_PATH
- 1, &read
, NULL
);
99 return strcmp(buf
, content
)==0;
102 /* initializes the tests */
103 static void init_shfo_tests(void)
107 GetCurrentDirectoryA(MAX_PATH
, CURR_DIR
);
108 len
= lstrlenA(CURR_DIR
);
110 if(len
&& (CURR_DIR
[len
-1] == '\\'))
113 createTestFile("test1.txt");
114 createTestFile("test2.txt");
115 createTestFile("test3.txt");
116 createTestFile("test_5.txt");
117 CreateDirectoryA("test4.txt", NULL
);
118 CreateDirectoryA("testdir2", NULL
);
119 CreateDirectoryA("testdir2\\nested", NULL
);
120 createTestFile("testdir2\\one.txt");
121 createTestFile("testdir2\\nested\\two.txt");
124 /* cleans after tests */
125 static void clean_after_shfo_tests(void)
127 DeleteFileA("test1.txt");
128 DeleteFileA("test2.txt");
129 DeleteFileA("test3.txt");
130 DeleteFileA("test_5.txt");
131 DeleteFileA("one.txt");
132 DeleteFileA("test4.txt\\test1.txt");
133 DeleteFileA("test4.txt\\test2.txt");
134 DeleteFileA("test4.txt\\test3.txt");
135 RemoveDirectoryA("test4.txt");
136 DeleteFileA("testdir2\\one.txt");
137 DeleteFileA("testdir2\\test1.txt");
138 DeleteFileA("testdir2\\test2.txt");
139 DeleteFileA("testdir2\\test3.txt");
140 DeleteFileA("testdir2\\test4.txt\\test1.txt");
141 DeleteFileA("testdir2\\nested\\two.txt");
142 RemoveDirectoryA("testdir2\\test4.txt");
143 RemoveDirectoryA("testdir2\\nested");
144 RemoveDirectoryA("testdir2");
145 RemoveDirectoryA("c:\\testdir3");
146 DeleteFileA("nonexistent\\notreal\\test2.txt");
147 RemoveDirectoryA("nonexistent\\notreal");
148 RemoveDirectoryA("nonexistent");
152 static void test_get_file_info(void)
155 SHFILEINFO shfi
, shfi2
;
156 char notepad
[MAX_PATH
];
158 /* Test some flag combinations that MSDN claims are not allowed,
159 * but which work anyway
161 shfi
.dwAttributes
=0xdeadbeef;
162 rc
=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY
,
164 SHGFI_ATTRIBUTES
| SHGFI_USEFILEATTRIBUTES
);
165 todo_wine
ok(rc
, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) failed\n");
167 ok(shfi
.dwAttributes
!= 0xdeadbeef, "dwFileAttributes is not set\n");
169 rc
=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY
,
171 SHGFI_EXETYPE
| SHGFI_USEFILEATTRIBUTES
);
172 todo_wine
ok(rc
== 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_EXETYPE) returned %d\n", rc
);
174 /* Test SHGFI_USEFILEATTRIBUTES support */
175 strcpy(shfi
.szDisplayName
, "dummy");
176 shfi
.iIcon
=0xdeadbeef;
177 rc
=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY
,
179 SHGFI_ICONLOCATION
| SHGFI_USEFILEATTRIBUTES
);
180 ok(rc
, "SHGetFileInfoA(c:\\nonexistent) failed\n");
183 ok(strcpy(shfi
.szDisplayName
, "dummy") != 0, "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n");
184 ok(shfi
.iIcon
!= 0xdeadbeef, "SHGetFileInfoA(c:\\nonexistent) iIcon is not set\n");
187 /* Wine does not have a default icon for text files, and Windows 98 fails
188 * if we give it an empty executable. So use notepad.exe as the test
190 if (SearchPath(NULL
, "notepad.exe", NULL
, sizeof(notepad
), notepad
, NULL
))
192 strcpy(shfi
.szDisplayName
, "dummy");
193 shfi
.iIcon
=0xdeadbeef;
194 rc
=SHGetFileInfoA(notepad
, GetFileAttributes(notepad
),
196 SHGFI_ICONLOCATION
| SHGFI_USEFILEATTRIBUTES
);
197 ok(rc
, "SHGetFileInfoA(%s, SHGFI_USEFILEATTRIBUTES) failed\n", notepad
);
198 strcpy(shfi2
.szDisplayName
, "dummy");
199 shfi2
.iIcon
=0xdeadbeef;
200 rc2
=SHGetFileInfoA(notepad
, 0,
201 &shfi2
, sizeof(shfi2
),
203 ok(rc2
, "SHGetFileInfoA(%s) failed\n", notepad
);
206 ok(lstrcmpi(shfi2
.szDisplayName
, shfi
.szDisplayName
) == 0, "wrong display name %s != %s\n", shfi
.szDisplayName
, shfi2
.szDisplayName
);
207 ok(shfi2
.iIcon
== shfi
.iIcon
, "wrong icon index %d != %d\n", shfi
.iIcon
, shfi2
.iIcon
);
211 /* with a directory now */
212 strcpy(shfi
.szDisplayName
, "dummy");
213 shfi
.iIcon
=0xdeadbeef;
214 rc
=SHGetFileInfoA("test4.txt", GetFileAttributes("test4.txt"),
216 SHGFI_ICONLOCATION
| SHGFI_USEFILEATTRIBUTES
);
217 ok(rc
, "SHGetFileInfoA(test4.txt/, SHGFI_USEFILEATTRIBUTES) failed\n");
218 strcpy(shfi2
.szDisplayName
, "dummy");
219 shfi2
.iIcon
=0xdeadbeef;
220 rc2
=SHGetFileInfoA("test4.txt", 0,
221 &shfi2
, sizeof(shfi2
),
223 ok(rc2
, "SHGetFileInfoA(test4.txt/) failed\n");
226 ok(lstrcmpi(shfi2
.szDisplayName
, shfi
.szDisplayName
) == 0, "wrong display name %s != %s\n", shfi
.szDisplayName
, shfi2
.szDisplayName
);
227 ok(shfi2
.iIcon
== shfi
.iIcon
, "wrong icon index %d != %d\n", shfi
.iIcon
, shfi2
.iIcon
);
233 puts into the specified buffer file names with current directory.
234 files - string with file names, separated by null characters. Ends on a double
237 static void set_curr_dir_path(CHAR
*buf
, const CHAR
* files
)
242 strcpy(buf
, CURR_DIR
);
247 buf
+= strlen(buf
) + 1;
248 files
+= strlen(files
) + 1;
254 /* tests the FO_DELETE action */
255 static void test_delete(void)
257 SHFILEOPSTRUCTA shfo
;
259 CHAR buf
[sizeof(CURR_DIR
)+sizeof("/test?.txt")+1];
261 sprintf(buf
, "%s\\%s", CURR_DIR
, "test?.txt");
262 buf
[strlen(buf
) + 1] = '\0';
265 shfo
.wFunc
= FO_DELETE
;
268 shfo
.fFlags
= FOF_FILESONLY
| FOF_NOCONFIRMATION
| FOF_SILENT
;
269 shfo
.hNameMappings
= NULL
;
270 shfo
.lpszProgressTitle
= NULL
;
272 ok(!SHFileOperationA(&shfo
), "Deletion was not successful\n");
273 ok(file_exists("test4.txt"), "Directory should not have been removed\n");
274 ok(!file_exists("test1.txt"), "File should have been removed\n");
276 ret
= SHFileOperationA(&shfo
);
277 ok(!ret
, "Directory exists, but is not removed, ret=%d\n", ret
);
278 ok(file_exists("test4.txt"), "Directory should not have been removed\n");
280 shfo
.fFlags
= FOF_NOCONFIRMATION
| FOF_SILENT
| FOF_NOERRORUI
;
282 ok(!SHFileOperationA(&shfo
), "Directory is not removed\n");
283 ok(!file_exists("test4.txt"), "Directory should have been removed\n");
285 ret
= SHFileOperationA(&shfo
);
286 ok(!ret
, "The requested file does not exist, ret=%d\n", ret
);
289 sprintf(buf
, "%s\\%s", CURR_DIR
, "test4.txt");
290 buf
[strlen(buf
) + 1] = '\0';
291 ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Filling the subdirectory failed\n");
292 ok(!SHFileOperationA(&shfo
), "Directory is not removed\n");
293 ok(!file_exists("test4.txt"), "Directory is not removed\n");
296 shfo
.pFrom
= "test1.txt\0test4.txt\0";
297 ok(!SHFileOperationA(&shfo
), "Directory and a file are not removed\n");
298 ok(!file_exists("test1.txt"), "The file should have been removed\n");
299 ok(!file_exists("test4.txt"), "Directory should have been removed\n");
300 ok(file_exists("test2.txt"), "This file should not have been removed\n");
302 /* FOF_FILESONLY does not delete a dir matching a wildcard */
304 shfo
.fFlags
|= FOF_FILESONLY
;
305 shfo
.pFrom
= "*.txt\0";
306 ok(!SHFileOperation(&shfo
), "Failed to delete files\n");
307 ok(!file_exists("test1.txt"), "test1.txt should have been removed\n");
308 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
309 ok(file_exists("test4.txt"), "test4.txt should not have been removed\n");
311 /* FOF_FILESONLY only deletes a dir if explicitly specified */
313 shfo
.pFrom
= "test_?.txt\0test4.txt\0";
314 ok(!SHFileOperation(&shfo
), "Failed to delete files and directory\n");
315 ok(!file_exists("test4.txt"), "test4.txt should have been removed\n");
316 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
317 ok(file_exists("test1.txt"), "test1.txt should not have been removed\n");
319 /* try to delete an invalid filename */
322 shfo
.fFlags
&= ~FOF_FILESONLY
;
323 shfo
.fAnyOperationsAborted
= FALSE
;
324 ret
= SHFileOperation(&shfo
);
325 ok(ret
== ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", ret
);
326 ok(!shfo
.fAnyOperationsAborted
, "Expected no aborted operations\n");
327 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
329 /* try an invalid function */
331 shfo
.pFrom
= "test1.txt\0";
333 ret
= SHFileOperation(&shfo
);
334 ok(ret
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret
);
335 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
337 /* try an invalid list, only one null terminator */
340 shfo
.wFunc
= FO_DELETE
;
341 ret
= SHFileOperation(&shfo
);
342 ok(ret
== ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", ret
);
343 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
345 /* delete a dir, and then a file inside the dir, same as
346 * deleting a nonexistent file
349 shfo
.pFrom
= "testdir2\0testdir2\\one.txt\0";
350 ret
= SHFileOperation(&shfo
);
351 ok(ret
== ERROR_PATH_NOT_FOUND
, "Expected ERROR_PATH_NOT_FOUND, got %d\n", ret
);
352 ok(!file_exists("testdir2"), "Expected testdir2 to not exist\n");
353 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
355 /* try the FOF_NORECURSION flag, continues deleting subdirs */
357 shfo
.pFrom
= "testdir2\0";
358 shfo
.fFlags
|= FOF_NORECURSION
;
359 ret
= SHFileOperation(&shfo
);
360 ok(ret
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", ret
);
361 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
362 ok(!file_exists("testdir2\\nested"), "Expected testdir2\\nested to exist\n");
365 /* tests the FO_RENAME action */
366 static void test_rename(void)
368 SHFILEOPSTRUCTA shfo
, shfo2
;
369 CHAR from
[5*MAX_PATH
];
374 shfo
.wFunc
= FO_RENAME
;
377 shfo
.fFlags
= FOF_NOCONFIRMATION
| FOF_SILENT
| FOF_NOERRORUI
;
378 shfo
.hNameMappings
= NULL
;
379 shfo
.lpszProgressTitle
= NULL
;
381 set_curr_dir_path(from
, "test1.txt\0");
382 set_curr_dir_path(to
, "test4.txt\0");
383 ok(SHFileOperationA(&shfo
), "File is not renamed moving to other directory "
384 "when specifying directory name only\n");
385 ok(file_exists("test1.txt"), "The file is removed\n");
387 set_curr_dir_path(from
, "test3.txt\0");
388 set_curr_dir_path(to
, "test4.txt\\test1.txt\0");
389 ok(!SHFileOperationA(&shfo
), "File is renamed moving to other directory\n");
390 ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
392 set_curr_dir_path(from
, "test1.txt\0test2.txt\0test4.txt\0");
393 set_curr_dir_path(to
, "test6.txt\0test7.txt\0test8.txt\0");
394 retval
= SHFileOperationA(&shfo
); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
395 ok(!retval
|| retval
== ERROR_GEN_FAILURE
|| retval
== ERROR_INVALID_TARGET_HANDLE
,
396 "Can't rename many files, retval = %d\n", retval
);
397 ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
399 memcpy(&shfo2
, &shfo
, sizeof(SHFILEOPSTRUCTA
));
400 shfo2
.fFlags
|= FOF_MULTIDESTFILES
;
402 set_curr_dir_path(from
, "test1.txt\0test2.txt\0test4.txt\0");
403 set_curr_dir_path(to
, "test6.txt\0test7.txt\0test8.txt\0");
404 retval
= SHFileOperationA(&shfo2
); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
405 ok(!retval
|| retval
== ERROR_GEN_FAILURE
|| retval
== ERROR_INVALID_TARGET_HANDLE
,
406 "Can't rename many files, retval = %d\n", retval
);
407 ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
409 set_curr_dir_path(from
, "test1.txt\0");
410 set_curr_dir_path(to
, "test6.txt\0");
411 retval
= SHFileOperationA(&shfo
);
412 ok(!retval
, "Rename file failed, retval = %d\n", retval
);
413 ok(!file_exists("test1.txt"), "The file is not renamed\n");
414 ok(file_exists("test6.txt"), "The file is not renamed\n");
416 set_curr_dir_path(from
, "test6.txt\0");
417 set_curr_dir_path(to
, "test1.txt\0");
418 retval
= SHFileOperationA(&shfo
);
419 ok(!retval
, "Rename file back failed, retval = %d\n", retval
);
421 set_curr_dir_path(from
, "test4.txt\0");
422 set_curr_dir_path(to
, "test6.txt\0");
423 retval
= SHFileOperationA(&shfo
);
424 ok(!retval
, "Rename dir failed, retval = %d\n", retval
);
425 ok(!file_exists("test4.txt"), "The dir is not renamed\n");
426 ok(file_exists("test6.txt"), "The dir is not renamed\n");
428 set_curr_dir_path(from
, "test6.txt\0");
429 set_curr_dir_path(to
, "test4.txt\0");
430 retval
= SHFileOperationA(&shfo
);
431 ok(!retval
, "Rename dir back failed, retval = %d\n", retval
);
433 /* try to rename more than one file to a single file */
434 shfo
.pFrom
= "test1.txt\0test2.txt\0";
435 shfo
.pTo
= "a.txt\0";
436 retval
= SHFileOperationA(&shfo
);
437 ok(retval
== ERROR_GEN_FAILURE
, "Expected ERROR_GEN_FAILURE, got %d\n", retval
);
438 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
439 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
441 /* pFrom doesn't exist */
442 shfo
.pFrom
= "idontexist\0";
443 shfo
.pTo
= "newfile\0";
444 retval
= SHFileOperationA(&shfo
);
445 ok(retval
== 1026, "Expected 1026, got %d\n", retval
);
446 ok(!file_exists("newfile"), "Expected newfile to not exist\n");
448 /* pTo already exist */
449 shfo
.pFrom
= "test1.txt\0";
450 shfo
.pTo
= "test2.txt\0";
451 retval
= SHFileOperationA(&shfo
);
452 ok(retval
== ERROR_ALREADY_EXISTS
, "Expected ERROR_ALREADY_EXISTS, got %d\n", retval
);
454 /* pFrom is valid, but pTo is empty */
455 shfo
.pFrom
= "test1.txt\0";
457 retval
= SHFileOperationA(&shfo
);
458 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
459 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
463 retval
= SHFileOperationA(&shfo
);
464 ok(retval
== ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", retval
);
466 /* pFrom is NULL, commented out because it crashes on nt 4.0 */
469 retval
= SHFileOperationA(&shfo
);
470 ok(retval
== ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", retval
);
474 /* tests the FO_COPY action */
475 static void test_copy(void)
477 SHFILEOPSTRUCTA shfo
, shfo2
;
478 CHAR from
[5*MAX_PATH
];
480 FILEOP_FLAGS tmp_flags
;
484 shfo
.wFunc
= FO_COPY
;
487 shfo
.fFlags
= FOF_NOCONFIRMATION
| FOF_SILENT
| FOF_NOERRORUI
;
488 shfo
.hNameMappings
= NULL
;
489 shfo
.lpszProgressTitle
= NULL
;
491 set_curr_dir_path(from
, "test1.txt\0test2.txt\0test4.txt\0");
492 set_curr_dir_path(to
, "test6.txt\0test7.txt\0test8.txt\0");
493 ok(SHFileOperationA(&shfo
), "Can't copy many files\n");
494 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
495 "specified as a target\n");
497 memcpy(&shfo2
, &shfo
, sizeof(SHFILEOPSTRUCTA
));
498 shfo2
.fFlags
|= FOF_MULTIDESTFILES
;
500 set_curr_dir_path(from
, "test1.txt\0test2.txt\0test4.txt\0");
501 set_curr_dir_path(to
, "test6.txt\0test7.txt\0test8.txt\0");
502 ok(!SHFileOperationA(&shfo2
), "Can't copy many files\n");
503 ok(file_exists("test6.txt"), "The file is copied - many files are "
504 "specified as a target\n");
505 DeleteFileA("test6.txt");
506 DeleteFileA("test7.txt");
507 RemoveDirectoryA("test8.txt");
509 /* number of sources do not correspond to number of targets */
510 set_curr_dir_path(from
, "test1.txt\0test2.txt\0test4.txt\0");
511 set_curr_dir_path(to
, "test6.txt\0test7.txt\0");
512 ok(SHFileOperationA(&shfo2
), "Can't copy many files\n");
513 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
514 "specified as a target\n");
516 set_curr_dir_path(from
, "test1.txt\0");
517 set_curr_dir_path(to
, "test4.txt\0");
518 ok(!SHFileOperationA(&shfo
), "Prepare test to check how directories are copied recursively\n");
519 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
521 set_curr_dir_path(from
, "test?.txt\0");
522 set_curr_dir_path(to
, "testdir2\0");
523 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
524 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
525 ok(!SHFileOperationA(&shfo
), "Files and directories are copied to directory\n");
526 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
527 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
528 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
529 clean_after_shfo_tests();
532 shfo
.fFlags
|= FOF_FILESONLY
;
533 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
534 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
535 ok(!SHFileOperationA(&shfo
), "Files are copied to other directory\n");
536 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
537 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
538 clean_after_shfo_tests();
541 set_curr_dir_path(from
, "test1.txt\0test2.txt\0");
542 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
543 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
544 ok(!SHFileOperationA(&shfo
), "Files are copied to other directory\n");
545 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
546 ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
547 clean_after_shfo_tests();
549 /* Copying multiple files with one not existing as source, fails the
550 entire operation in Win98/ME/2K/XP, but not in 95/NT */
552 tmp_flags
= shfo
.fFlags
;
553 set_curr_dir_path(from
, "test1.txt\0test10.txt\0test2.txt\0");
554 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
555 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
556 retval
= SHFileOperationA(&shfo
);
558 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
559 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
562 /* Win 98/ME/2K/XP fail the entire operation with return code 1026 if one source file does not exist */
563 ok(retval
== 1026, "Files are copied to other directory\n");
564 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
566 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
567 shfo
.fFlags
= tmp_flags
;
569 /* copy into a nonexistent directory */
571 shfo
.fFlags
= FOF_NOCONFIRMMKDIR
;
572 set_curr_dir_path(from
, "test1.txt\0");
573 set_curr_dir_path(to
, "nonexistent\\notreal\\test2.txt\0");
574 retval
= SHFileOperation(&shfo
);
575 ok(!retval
, "Error copying into nonexistent directory\n");
576 ok(file_exists("nonexistent"), "nonexistent not created\n");
577 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
578 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
579 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
581 /* a relative dest directory is OK */
582 clean_after_shfo_tests();
584 shfo
.pFrom
= "test1.txt\0test2.txt\0test3.txt\0";
585 shfo
.pTo
= "testdir2\0";
586 retval
= SHFileOperation(&shfo
);
587 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
588 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
590 /* try to copy files to a file */
591 clean_after_shfo_tests();
595 set_curr_dir_path(from
, "test1.txt\0test2.txt\0");
596 set_curr_dir_path(to
, "test3.txt\0");
597 retval
= SHFileOperation(&shfo
);
598 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
599 ok(shfo
.fAnyOperationsAborted
, "Expected aborted operations\n");
600 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
602 /* try to copy many files to nonexistent directory */
604 shfo
.fAnyOperationsAborted
= FALSE
;
605 retval
= SHFileOperation(&shfo
);
606 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
607 ok(DeleteFile("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
608 ok(DeleteFile("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
609 ok(RemoveDirectory(to
), "Expected test3.txt to exist\n");
611 /* send in FOF_MULTIDESTFILES with too many destination files */
613 shfo
.pFrom
= "test1.txt\0test2.txt\0test3.txt\0";
614 shfo
.pTo
= "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
615 shfo
.fFlags
|= FOF_NOERRORUI
| FOF_MULTIDESTFILES
;
616 retval
= SHFileOperation(&shfo
);
617 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
618 ok(shfo
.fAnyOperationsAborted
, "Expected aborted operations\n");
619 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
621 /* send in FOF_MULTIDESTFILES with too many destination files */
622 shfo
.pFrom
= "test1.txt\0test2.txt\0test3.txt\0";
623 shfo
.pTo
= "e.txt\0f.txt\0";
624 shfo
.fAnyOperationsAborted
= FALSE
;
625 retval
= SHFileOperation(&shfo
);
626 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
627 ok(shfo
.fAnyOperationsAborted
, "Expected aborted operations\n");
628 ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
630 /* use FOF_MULTIDESTFILES with files and a source directory */
631 shfo
.pFrom
= "test1.txt\0test2.txt\0test4.txt\0";
632 shfo
.pTo
= "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
633 shfo
.fAnyOperationsAborted
= FALSE
;
634 retval
= SHFileOperation(&shfo
);
635 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
636 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
637 ok(DeleteFile("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
638 ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
640 /* try many dest files without FOF_MULTIDESTFILES flag */
641 shfo
.pFrom
= "test1.txt\0test2.txt\0test3.txt\0";
642 shfo
.pTo
= "a.txt\0b.txt\0c.txt\0";
643 shfo
.fAnyOperationsAborted
= FALSE
;
644 shfo
.fFlags
&= ~FOF_MULTIDESTFILES
;
645 retval
= SHFileOperation(&shfo
);
646 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
647 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
650 shfo
.pFrom
= "test?.txt\0";
651 shfo
.pTo
= "testdir2\0";
652 shfo
.fFlags
&= ~FOF_MULTIDESTFILES
;
653 retval
= SHFileOperation(&shfo
);
654 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
655 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
657 /* try a glob with FOF_FILESONLY */
658 clean_after_shfo_tests();
660 shfo
.pFrom
= "test?.txt\0";
661 shfo
.fFlags
|= FOF_FILESONLY
;
662 retval
= SHFileOperation(&shfo
);
663 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
664 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
665 ok(!file_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
667 /* try a glob with FOF_MULTIDESTFILES and the same number
668 * of dest files that we would expect
670 clean_after_shfo_tests();
672 shfo
.pTo
= "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
673 shfo
.fFlags
&= ~FOF_FILESONLY
;
674 shfo
.fFlags
|= FOF_MULTIDESTFILES
;
675 retval
= SHFileOperation(&shfo
);
676 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
677 ok(shfo
.fAnyOperationsAborted
, "Expected aborted operations\n");
678 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
679 ok(!RemoveDirectory("b.txt"), "b.txt should not exist\n");
681 /* copy one file to two others, second is ignored */
682 clean_after_shfo_tests();
684 shfo
.pFrom
= "test1.txt\0";
685 shfo
.pTo
= "b.txt\0c.txt\0";
686 shfo
.fAnyOperationsAborted
= FALSE
;
687 retval
= SHFileOperation(&shfo
);
688 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
689 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
690 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
692 /* copy two file to three others, all fail */
693 shfo
.pFrom
= "test1.txt\0test2.txt\0";
694 shfo
.pTo
= "b.txt\0c.txt\0d.txt\0";
695 retval
= SHFileOperation(&shfo
);
696 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
697 ok(shfo
.fAnyOperationsAborted
, "Expected operations to be aborted\n");
698 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
700 /* copy one file and one directory to three others */
701 shfo
.pFrom
= "test1.txt\0test4.txt\0";
702 shfo
.pTo
= "b.txt\0c.txt\0d.txt\0";
703 shfo
.fAnyOperationsAborted
= FALSE
;
704 retval
= SHFileOperation(&shfo
);
705 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
706 ok(shfo
.fAnyOperationsAborted
, "Expected operations to be aborted\n");
707 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
708 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
710 /* copy a directory with a file beneath it, plus some files */
711 createTestFile("test4.txt\\a.txt");
712 shfo
.pFrom
= "test4.txt\0test1.txt\0";
713 shfo
.pTo
= "testdir2\0";
714 shfo
.fFlags
&= ~FOF_MULTIDESTFILES
;
715 shfo
.fAnyOperationsAborted
= FALSE
;
716 retval
= SHFileOperation(&shfo
);
717 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
718 ok(DeleteFile("testdir2\\test1.txt"), "Expected newdir\\test1.txt to exist\n");
719 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
720 ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
722 /* copy one directory and a file in that dir to another dir */
723 shfo
.pFrom
= "test4.txt\0test4.txt\\a.txt\0";
724 shfo
.pTo
= "testdir2\0";
725 retval
= SHFileOperation(&shfo
);
726 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
727 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
728 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
730 /* copy a file in a directory first, and then the directory to a nonexistent dir */
731 shfo
.pFrom
= "test4.txt\\a.txt\0test4.txt\0";
732 shfo
.pTo
= "nonexistent\0";
733 retval
= SHFileOperation(&shfo
);
734 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
735 ok(shfo
.fAnyOperationsAborted
, "Expected operations to be aborted\n");
736 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
737 DeleteFile("test4.txt\\a.txt");
739 /* destination is same as source file */
740 shfo
.pFrom
= "test1.txt\0test2.txt\0test3.txt\0";
741 shfo
.pTo
= "b.txt\0test2.txt\0c.txt\0";
742 shfo
.fAnyOperationsAborted
= FALSE
;
743 shfo
.fFlags
= FOF_NOERRORUI
| FOF_MULTIDESTFILES
;
744 retval
= SHFileOperation(&shfo
);
745 ok(retval
== ERROR_NO_MORE_SEARCH_HANDLES
,
746 "Expected ERROR_NO_MORE_SEARCH_HANDLES, got %d\n", retval
);
747 ok(!shfo
.fAnyOperationsAborted
, "Expected no operations to be aborted\n");
748 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
749 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
751 /* destination is same as source directory */
752 shfo
.pFrom
= "test1.txt\0test4.txt\0test3.txt\0";
753 shfo
.pTo
= "b.txt\0test4.txt\0c.txt\0";
754 shfo
.fAnyOperationsAborted
= FALSE
;
755 retval
= SHFileOperation(&shfo
);
756 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
757 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
758 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
760 /* copy a directory into itself, error displayed in UI */
761 shfo
.pFrom
= "test4.txt\0";
762 shfo
.pTo
= "test4.txt\\newdir\0";
763 shfo
.fFlags
&= ~FOF_MULTIDESTFILES
;
764 shfo
.fAnyOperationsAborted
= FALSE
;
765 retval
= SHFileOperation(&shfo
);
766 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
767 ok(!RemoveDirectory("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
769 /* copy a directory to itself, error displayed in UI */
770 shfo
.pFrom
= "test4.txt\0";
771 shfo
.pTo
= "test4.txt\0";
772 shfo
.fAnyOperationsAborted
= FALSE
;
773 retval
= SHFileOperation(&shfo
);
774 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
776 /* copy a file into a directory, and the directory into itself */
777 shfo
.pFrom
= "test1.txt\0test4.txt\0";
778 shfo
.pTo
= "test4.txt\0";
779 shfo
.fAnyOperationsAborted
= FALSE
;
780 shfo
.fFlags
|= FOF_NOCONFIRMATION
;
781 retval
= SHFileOperation(&shfo
);
782 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
783 ok(DeleteFile("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
785 /* copy a file to a file, and the directory into itself */
786 shfo
.pFrom
= "test1.txt\0test4.txt\0";
787 shfo
.pTo
= "test4.txt\\a.txt\0";
788 shfo
.fAnyOperationsAborted
= FALSE
;
789 retval
= SHFileOperation(&shfo
);
790 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
791 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
793 /* copy a nonexistent file to a nonexistent directory */
794 shfo
.pFrom
= "e.txt\0";
795 shfo
.pTo
= "nonexistent\0";
796 shfo
.fAnyOperationsAborted
= FALSE
;
797 retval
= SHFileOperation(&shfo
);
798 ok(retval
== 1026, "Expected 1026, got %d\n", retval
);
799 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
800 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
802 /* Overwrite tests */
803 clean_after_shfo_tests();
805 shfo
.fFlags
= FOF_NOCONFIRMATION
;
806 shfo
.pFrom
= "test1.txt\0";
807 shfo
.pTo
= "test2.txt\0";
808 shfo
.fAnyOperationsAborted
= FALSE
;
809 /* without FOF_NOCOFIRMATION the confirmation is Yes/No */
810 retval
= SHFileOperation(&shfo
);
811 ok(retval
== 0, "Expected 0, got %d\n", retval
);
812 ok(file_has_content("test2.txt", "test1.txt\n"), "The file was not copied\n");
814 shfo
.pFrom
= "test3.txt\0test1.txt\0";
815 shfo
.pTo
= "test2.txt\0one.txt\0";
816 shfo
.fFlags
= FOF_NOCONFIRMATION
| FOF_MULTIDESTFILES
;
817 /* without FOF_NOCOFIRMATION the confirmation is Yes/Yes to All/No/Cancel */
818 retval
= SHFileOperation(&shfo
);
819 ok(retval
== 0, "Expected 0, got %d\n", retval
);
820 ok(file_has_content("test2.txt", "test3.txt\n"), "The file was not copied\n");
822 shfo
.pFrom
= "one.txt\0";
823 shfo
.pTo
= "testdir2\0";
824 shfo
.fFlags
= FOF_NOCONFIRMATION
;
825 /* without FOF_NOCOFIRMATION the confirmation is Yes/No */
826 retval
= SHFileOperation(&shfo
);
827 ok(retval
== 0, "Expected 0, got %d\n", retval
);
828 ok(file_has_content("testdir2\\one.txt", "test1.txt\n"), "The file was not copied\n");
830 createTestFile("test4.txt\\test1.txt");
831 shfo
.pFrom
= "test4.txt\0";
832 shfo
.pTo
= "testdir2\0";
833 shfo
.fFlags
= FOF_NOCONFIRMATION
;
834 ok(!SHFileOperation(&shfo
), "First SHFileOperation failed\n");
835 createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */
836 /* without FOF_NOCOFIRMATION the confirmation is "This folder already contains a folder named ..." */
837 retval
= SHFileOperation(&shfo
);
838 ok(retval
== 0, "Expected 0, got %d\n", retval
);
839 ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
842 /* tests the FO_MOVE action */
843 static void test_move(void)
845 SHFILEOPSTRUCTA shfo
, shfo2
;
846 CHAR from
[5*MAX_PATH
];
851 shfo
.wFunc
= FO_MOVE
;
854 shfo
.fFlags
= FOF_NOCONFIRMATION
| FOF_SILENT
| FOF_NOERRORUI
;
855 shfo
.hNameMappings
= NULL
;
856 shfo
.lpszProgressTitle
= NULL
;
858 set_curr_dir_path(from
, "test1.txt\0");
859 set_curr_dir_path(to
, "test4.txt\0");
860 ok(!SHFileOperationA(&shfo
), "Prepare test to check how directories are moved recursively\n");
861 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
862 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
864 set_curr_dir_path(from
, "test?.txt\0");
865 set_curr_dir_path(to
, "testdir2\0");
866 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
867 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
868 ok(!SHFileOperationA(&shfo
), "Files and directories are moved to directory\n");
869 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
870 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
871 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
873 clean_after_shfo_tests();
876 memcpy(&shfo2
, &shfo
, sizeof(SHFILEOPSTRUCTA
));
877 shfo2
.fFlags
|= FOF_MULTIDESTFILES
;
879 set_curr_dir_path(from
, "test1.txt\0test2.txt\0test4.txt\0");
880 set_curr_dir_path(to
, "test6.txt\0test7.txt\0test8.txt\0");
881 ok(!SHFileOperationA(&shfo2
), "Move many files\n");
882 ok(file_exists("test6.txt"), "The file is moved - many files are "
883 "specified as a target\n");
884 DeleteFileA("test6.txt");
885 DeleteFileA("test7.txt");
886 RemoveDirectoryA("test8.txt");
890 /* number of sources do not correspond to number of targets */
891 set_curr_dir_path(from
, "test1.txt\0test2.txt\0test4.txt\0");
892 set_curr_dir_path(to
, "test6.txt\0test7.txt\0");
893 ok(SHFileOperationA(&shfo2
), "Can't move many files\n");
894 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
895 "specified as a target\n");
899 set_curr_dir_path(from
, "test3.txt\0");
900 set_curr_dir_path(to
, "test4.txt\\test1.txt\0");
901 ok(!SHFileOperationA(&shfo
), "File is moved moving to other directory\n");
902 ok(file_exists("test4.txt\\test1.txt"), "The file is moved\n");
904 set_curr_dir_path(from
, "test1.txt\0test2.txt\0test4.txt\0");
905 set_curr_dir_path(to
, "test6.txt\0test7.txt\0test8.txt\0");
906 ok(SHFileOperationA(&shfo
), "Cannot move many files\n");
907 ok(file_exists("test1.txt"), "The file is not moved. Many files are specified\n");
908 ok(file_exists("test4.txt"), "The directory is not moved. Many files are specified\n");
910 set_curr_dir_path(from
, "test1.txt\0");
911 set_curr_dir_path(to
, "test6.txt\0");
912 ok(!SHFileOperationA(&shfo
), "Move file\n");
913 ok(!file_exists("test1.txt"), "The file is moved\n");
914 ok(file_exists("test6.txt"), "The file is moved\n");
915 set_curr_dir_path(from
, "test6.txt\0");
916 set_curr_dir_path(to
, "test1.txt\0");
917 ok(!SHFileOperationA(&shfo
), "Move file back\n");
919 set_curr_dir_path(from
, "test4.txt\0");
920 set_curr_dir_path(to
, "test6.txt\0");
921 ok(!SHFileOperationA(&shfo
), "Move dir\n");
922 ok(!file_exists("test4.txt"), "The dir is moved\n");
923 ok(file_exists("test6.txt"), "The dir is moved\n");
924 set_curr_dir_path(from
, "test6.txt\0");
925 set_curr_dir_path(to
, "test4.txt\0");
926 ok(!SHFileOperationA(&shfo
), "Move dir back\n");
928 /* move one file to two others */
930 shfo
.pFrom
= "test1.txt\0";
931 shfo
.pTo
= "a.txt\0b.txt\0";
932 retval
= SHFileOperationA(&shfo
);
933 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
934 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
935 ok(DeleteFile("a.txt"), "Expected a.txt to exist\n");
936 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
938 /* move two files to one other */
939 shfo
.pFrom
= "test2.txt\0test3.txt\0";
940 shfo
.pTo
= "test1.txt\0";
941 retval
= SHFileOperationA(&shfo
);
942 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
943 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
944 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
945 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
947 /* move a directory into itself */
948 shfo
.pFrom
= "test4.txt\0";
949 shfo
.pTo
= "test4.txt\\b.txt\0";
950 retval
= SHFileOperationA(&shfo
);
951 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
952 ok(!RemoveDirectory("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
953 ok(file_exists("test4.txt"), "Expected test4.txt to exist\n");
955 /* move many files without FOF_MULTIDESTFILES */
956 shfo
.pFrom
= "test2.txt\0test3.txt\0";
957 shfo
.pTo
= "d.txt\0e.txt\0";
958 retval
= SHFileOperationA(&shfo
);
959 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
960 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
961 ok(!DeleteFile("e.txt"), "Expected e.txt to not exist\n");
963 /* number of sources != number of targets */
964 shfo
.pTo
= "d.txt\0";
965 shfo
.fFlags
|= FOF_MULTIDESTFILES
;
966 retval
= SHFileOperationA(&shfo
);
967 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
968 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
970 /* FO_MOVE does not create dest directories */
971 shfo
.pFrom
= "test2.txt\0";
972 shfo
.pTo
= "dir1\\dir2\\test2.txt\0";
973 retval
= SHFileOperationA(&shfo
);
974 ok(retval
== ERROR_CANCELLED
, "Expected ERROR_CANCELLED, got %d\n", retval
);
975 ok(!file_exists("dir1"), "Expected dir1 to not exist\n");
977 /* try to overwrite an existing file */
978 shfo
.pTo
= "test3.txt\0";
979 retval
= SHFileOperationA(&shfo
);
980 ok(retval
== ERROR_SUCCESS
, "Expected ERROR_SUCCESS, got %d\n", retval
);
981 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
982 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
985 static void test_sh_create_dir(void)
990 if(!pSHCreateDirectoryExA
)
992 trace("skipping SHCreateDirectoryExA tests\n");
996 set_curr_dir_path(path
, "testdir2\\test4.txt\0");
997 ret
= pSHCreateDirectoryExA(NULL
, path
, NULL
);
998 ok(ERROR_SUCCESS
== ret
, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret
);
999 ok(file_exists("testdir2"), "The first directory is not created\n");
1000 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
1002 ret
= pSHCreateDirectoryExA(NULL
, path
, NULL
);
1003 ok(ERROR_ALREADY_EXISTS
== ret
, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret
);
1005 ret
= pSHCreateDirectoryExA(NULL
, "c:\\testdir3", NULL
);
1006 ok(file_exists("c:\\testdir3"), "The directory is not created\n");
1009 static void test_sh_path_prepare(void)
1012 CHAR path
[MAX_PATH
];
1014 if(!pSHPathPrepareForWriteA
)
1016 trace("skipping SHPathPrepareForWriteA tests\n");
1020 /* directory exists, SHPPFW_NONE */
1021 set_curr_dir_path(path
, "\0");
1022 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_NONE
);
1023 ok(res
== S_OK
, "res == 0x%08x, expected S_OK\n", res
);
1025 /* directory exists, SHPPFW_IGNOREFILENAME */
1026 set_curr_dir_path(path
, "nonexistent\0");
1027 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_IGNOREFILENAME
);
1028 ok(res
== S_OK
, "res == 0x%08x, expected S_OK\n", res
);
1030 /* directory exists, SHPPFW_DIRCREATE */
1031 set_curr_dir_path(path
, "\0");
1032 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_DIRCREATE
);
1033 ok(res
== S_OK
, "res == 0x%08x, expected S_OK\n", res
);
1035 /* directory exists, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
1036 set_curr_dir_path(path
, "nonexistent\0");
1037 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_IGNOREFILENAME
|SHPPFW_DIRCREATE
);
1038 ok(res
== S_OK
, "res == 0x%08x, expected S_OK\n", res
);
1039 ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
1041 /* file exists, SHPPFW_NONE */
1042 set_curr_dir_path(path
, "test1.txt\0");
1043 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_NONE
);
1044 todo_wine
ok(res
== HRESULT_FROM_WIN32(ERROR_DIRECTORY
), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_DIRECTORY)\n", res
);
1046 /* file exists, SHPPFW_DIRCREATE */
1047 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_DIRCREATE
);
1048 todo_wine
ok(res
== HRESULT_FROM_WIN32(ERROR_DIRECTORY
), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_DIRECTORY)\n", res
);
1050 /* file exists, SHPPFW_NONE, trailing \ */
1051 set_curr_dir_path(path
, "test1.txt\\\0");
1052 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_NONE
);
1053 todo_wine
ok(res
== HRESULT_FROM_WIN32(ERROR_DIRECTORY
), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_DIRECTORY)\n", res
);
1055 /* relative path exists, SHPPFW_DIRCREATE */
1056 res
= pSHPathPrepareForWriteA(0, 0, ".\\testdir2", SHPPFW_DIRCREATE
);
1057 ok(res
== S_OK
, "res == 0x%08x, expected S_OK\n", res
);
1059 /* relative path doesn't exist, SHPPFW_DIRCREATE -- Windows does not create the directory in this case */
1060 res
= pSHPathPrepareForWriteA(0, 0, ".\\testdir2\\test4.txt", SHPPFW_DIRCREATE
);
1061 todo_wine
ok(res
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res
);
1062 ok(!file_exists(".\\testdir2\\test4.txt\\"), ".\\testdir2\\test4.txt\\ exists but shouldn't\n");
1064 /* directory doesn't exist, SHPPFW_NONE */
1065 set_curr_dir_path(path
, "nonexistent\0");
1066 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_NONE
);
1067 todo_wine
ok(res
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res
);
1069 /* directory doesn't exist, SHPPFW_IGNOREFILENAME */
1070 set_curr_dir_path(path
, "nonexistent\\notreal\0");
1071 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_IGNOREFILENAME
);
1072 todo_wine
ok(res
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res
);
1073 ok(!file_exists("nonexistent\\notreal"), "nonexistent\\notreal exists but shouldn't\n");
1074 ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
1076 /* directory doesn't exist, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
1077 set_curr_dir_path(path
, "testdir2\\test4.txt\\\0");
1078 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_IGNOREFILENAME
|SHPPFW_DIRCREATE
);
1079 ok(res
== S_OK
, "res == 0x%08x, expected S_OK\n", res
);
1080 todo_wine
ok(file_exists("testdir2\\test4.txt\\"), "testdir2\\test4.txt doesn't exist but should\n");
1082 /* nested directory doesn't exist, SHPPFW_DIRCREATE */
1083 set_curr_dir_path(path
, "nonexistent\\notreal\0");
1084 res
= pSHPathPrepareForWriteA(0, 0, path
, SHPPFW_DIRCREATE
);
1085 ok(res
== S_OK
, "res == 0x%08x, expected S_OK\n", res
);
1086 todo_wine
ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal doesn't exist but should\n");
1088 /* SHPPFW_ASKDIRCREATE, SHPPFW_NOWRITECHECK, and SHPPFW_MEDIACHECKONLY are untested */
1090 if(!pSHPathPrepareForWriteW
)
1092 skip("Skipping SHPathPrepareForWriteW tests\n");
1095 /* unicode directory doesn't exist, SHPPFW_NONE */
1096 res
= pSHPathPrepareForWriteW(0, 0, UNICODE_PATH
, SHPPFW_NONE
);
1097 todo_wine
ok(res
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), "res == %08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res
);
1098 ok(!file_existsW(UNICODE_PATH
), "unicode path was created but shouldn't be\n");
1099 RemoveDirectoryW(UNICODE_PATH
);
1101 /* unicode directory doesn't exist, SHPPFW_DIRCREATE */
1102 res
= pSHPathPrepareForWriteW(0, 0, UNICODE_PATH
, SHPPFW_DIRCREATE
);
1103 ok(res
== S_OK
, "res == %08x, expected S_OK\n", res
);
1104 todo_wine
ok(file_existsW(UNICODE_PATH
), "unicode path should've been created\n");
1106 /* unicode directory exists, SHPPFW_NONE */
1107 res
= pSHPathPrepareForWriteW(0, 0, UNICODE_PATH
, SHPPFW_NONE
);
1108 ok(res
== S_OK
, "ret == %08x, expected S_OK\n", res
);
1110 /* unicode directory exists, SHPPFW_DIRCREATE */
1111 res
= pSHPathPrepareForWriteW(0, 0, UNICODE_PATH
, SHPPFW_DIRCREATE
);
1112 ok(res
== S_OK
, "ret == %08x, expected S_OK\n", res
);
1113 RemoveDirectoryW(UNICODE_PATH
);
1116 static void test_unicode(void)
1118 SHFILEOPSTRUCTW shfoW
;
1123 shfoW
.wFunc
= FO_DELETE
;
1124 shfoW
.pFrom
= UNICODE_PATH
;
1126 shfoW
.fFlags
= FOF_NOCONFIRMATION
| FOF_SILENT
| FOF_NOERRORUI
;
1127 shfoW
.hNameMappings
= NULL
;
1128 shfoW
.lpszProgressTitle
= NULL
;
1130 /* Clean up before start test */
1131 DeleteFileW(UNICODE_PATH
);
1132 RemoveDirectoryW(UNICODE_PATH
);
1134 /* Make sure we are on a system that supports unicode */
1135 SetLastError(0xdeadbeef);
1136 file
= CreateFileW(UNICODE_PATH
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
1137 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED
)
1139 skip("Unicode tests skipped on non-unicode system\n");
1144 /* Try to delete a file with unicode filename */
1145 ok(file_existsW(UNICODE_PATH
), "The file does not exist\n");
1146 ret
= SHFileOperationW(&shfoW
);
1147 ok(!ret
, "File is not removed, ErrorCode: %d\n", ret
);
1148 ok(!file_existsW(UNICODE_PATH
), "The file should have been removed\n");
1150 /* Try to trash a file with unicode filename */
1151 createTestFileW(UNICODE_PATH
);
1152 shfoW
.fFlags
|= FOF_ALLOWUNDO
;
1153 ok(file_existsW(UNICODE_PATH
), "The file does not exist\n");
1154 ret
= SHFileOperationW(&shfoW
);
1155 ok(!ret
, "File is not removed, ErrorCode: %d\n", ret
);
1156 ok(!file_existsW(UNICODE_PATH
), "The file should have been removed\n");
1158 if(!pSHCreateDirectoryExW
)
1160 skip("Skipping SHCreateDirectoryExW tests\n");
1164 /* Try to delete a directory with unicode filename */
1165 ret
= pSHCreateDirectoryExW(NULL
, UNICODE_PATH
, NULL
);
1166 ok(!ret
, "SHCreateDirectoryExW returned %d\n", ret
);
1167 ok(file_existsW(UNICODE_PATH
), "The directory is not created\n");
1168 shfoW
.fFlags
&= ~FOF_ALLOWUNDO
;
1169 ret
= SHFileOperationW(&shfoW
);
1170 ok(!ret
, "Directory is not removed, ErrorCode: %d\n", ret
);
1171 ok(!file_existsW(UNICODE_PATH
), "The directory should have been removed\n");
1173 /* Try to trash a directory with unicode filename */
1174 ret
= pSHCreateDirectoryExW(NULL
, UNICODE_PATH
, NULL
);
1175 ok(!ret
, "SHCreateDirectoryExW returned %d\n", ret
);
1176 ok(file_existsW(UNICODE_PATH
), "The directory was not created\n");
1177 shfoW
.fFlags
|= FOF_ALLOWUNDO
;
1178 ret
= SHFileOperationW(&shfoW
);
1179 ok(!ret
, "Directory is not removed, ErrorCode: %d\n", ret
);
1180 ok(!file_existsW(UNICODE_PATH
), "The directory should have been removed\n");
1183 START_TEST(shlfileop
)
1185 InitFunctionPointers();
1187 clean_after_shfo_tests();
1190 test_get_file_info();
1191 clean_after_shfo_tests();
1195 clean_after_shfo_tests();
1199 clean_after_shfo_tests();
1203 clean_after_shfo_tests();
1207 clean_after_shfo_tests();
1209 test_sh_create_dir();
1210 clean_after_shfo_tests();
1213 test_sh_path_prepare();
1214 clean_after_shfo_tests();