push 63c1876572cbb61a874995ad42ef27c14590d232
[wine/hacks.git] / dlls / shell32 / tests / shlfileop.c
blob1cedcfbccacd0acb96e276de0503793f7531f1bb
1 /*
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
21 #include <stdarg.h>
22 #include <stdio.h>
24 #define WINE_NOWINSOCK
25 #include <windows.h>
26 #include "shellapi.h"
27 #include "shlobj.h"
29 #include "wine/test.h"
31 #ifndef FOF_NORECURSION
32 #define FOF_NORECURSION 0x1000
33 #endif
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 *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
44 static int (WINAPI *pSHPathPrepareForWriteA)(HWND, IUnknown*, LPCSTR, DWORD);
45 static int (WINAPI *pSHPathPrepareForWriteW)(HWND, IUnknown*, LPCWSTR, DWORD);
47 static void InitFunctionPointers(void)
49 hshell32 = GetModuleHandleA("shell32.dll");
50 pSHCreateDirectoryExA = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExA");
51 pSHCreateDirectoryExW = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExW");
52 pSHFileOperationW = (void*)GetProcAddress(hshell32, "SHFileOperationW");
53 pSHPathPrepareForWriteA = (void*)GetProcAddress(hshell32, "SHPathPrepareForWriteA");
54 pSHPathPrepareForWriteW = (void*)GetProcAddress(hshell32, "SHPathPrepareForWriteW");
57 /* creates a file with the specified name for tests */
58 static void createTestFile(const CHAR *name)
60 HANDLE file;
61 DWORD written;
63 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
64 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
65 WriteFile(file, name, strlen(name), &written, NULL);
66 WriteFile(file, "\n", strlen("\n"), &written, NULL);
67 CloseHandle(file);
70 static void createTestFileW(const WCHAR *name)
72 HANDLE file;
74 file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
75 ok(file != INVALID_HANDLE_VALUE, "Failure to open file\n");
76 CloseHandle(file);
79 static BOOL file_exists(const CHAR *name)
81 return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
84 static BOOL file_existsW(LPCWSTR name)
86 return GetFileAttributesW(name) != INVALID_FILE_ATTRIBUTES;
89 static BOOL file_has_content(const CHAR *name, const CHAR *content)
91 CHAR buf[MAX_PATH];
92 HANDLE file;
93 DWORD read;
95 file = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
96 if (file == INVALID_HANDLE_VALUE)
97 return FALSE;
98 ReadFile(file, buf, MAX_PATH - 1, &read, NULL);
99 buf[read] = 0;
100 CloseHandle(file);
101 return strcmp(buf, content)==0;
104 /* initializes the tests */
105 static void init_shfo_tests(void)
107 int len;
109 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
110 len = lstrlenA(CURR_DIR);
112 if(len && (CURR_DIR[len-1] == '\\'))
113 CURR_DIR[len-1] = 0;
115 createTestFile("test1.txt");
116 createTestFile("test2.txt");
117 createTestFile("test3.txt");
118 createTestFile("test_5.txt");
119 CreateDirectoryA("test4.txt", NULL);
120 CreateDirectoryA("testdir2", NULL);
121 CreateDirectoryA("testdir2\\nested", NULL);
122 createTestFile("testdir2\\one.txt");
123 createTestFile("testdir2\\nested\\two.txt");
126 /* cleans after tests */
127 static void clean_after_shfo_tests(void)
129 DeleteFileA("test1.txt");
130 DeleteFileA("test2.txt");
131 DeleteFileA("test3.txt");
132 DeleteFileA("test_5.txt");
133 DeleteFileA("one.txt");
134 DeleteFileA("test4.txt\\test1.txt");
135 DeleteFileA("test4.txt\\test2.txt");
136 DeleteFileA("test4.txt\\test3.txt");
137 RemoveDirectoryA("test4.txt");
138 DeleteFileA("testdir2\\one.txt");
139 DeleteFileA("testdir2\\test1.txt");
140 DeleteFileA("testdir2\\test2.txt");
141 DeleteFileA("testdir2\\test3.txt");
142 DeleteFileA("testdir2\\test4.txt\\test1.txt");
143 DeleteFileA("testdir2\\nested\\two.txt");
144 RemoveDirectoryA("testdir2\\test4.txt");
145 RemoveDirectoryA("testdir2\\nested");
146 RemoveDirectoryA("testdir2");
147 RemoveDirectoryA("c:\\testdir3");
148 DeleteFileA("nonexistent\\notreal\\test2.txt");
149 RemoveDirectoryA("nonexistent\\notreal");
150 RemoveDirectoryA("nonexistent");
154 static void test_get_file_info(void)
156 DWORD rc, rc2;
157 SHFILEINFOA shfi, shfi2;
158 SHFILEINFOW shfiw;
159 char notepad[MAX_PATH];
161 /* Test whether fields of SHFILEINFOA are always cleared */
162 memset(&shfi, 0xcf, sizeof(shfi));
163 rc=SHGetFileInfoA("", 0, &shfi, sizeof(shfi), 0);
164 ok(rc, "SHGetFileInfoA('' | 0) should not fail\n");
165 todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA('' | 0) did not clear hIcon\n");
166 todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szDisplayName[0]\n");
167 todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szTypeName[0]\n");
168 ok(shfi.iIcon == 0xcfcfcfcf, "SHGetFileInfoA('' | 0) should not clear iIcon\n");
169 ok(shfi.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoA('' | 0) should not clear dwAttributes\n");
171 /* Test whether fields of SHFILEINFOW are always cleared */
172 memset(&shfiw, 0xcf, sizeof(shfiw));
173 rc=SHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0);
174 todo_wine ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n");
175 ok(shfiw.hIcon == (HANDLE) 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear hIcon\n");
176 todo_wine ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n");
177 todo_wine ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n");
178 todo_wine ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n");
179 ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear dwAttributes\n");
182 /* Test some flag combinations that MSDN claims are not allowed,
183 * but which work anyway
185 memset(&shfi, 0xcf, sizeof(shfi));
186 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
187 &shfi, sizeof(shfi),
188 SHGFI_ATTRIBUTES | SHGFI_USEFILEATTRIBUTES);
189 todo_wine ok(rc, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) failed\n");
190 if (rc)
191 ok(shfi.dwAttributes != 0xcfcfcfcf, "dwFileAttributes is not set\n");
192 todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear hIcon\n");
193 todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szDisplayName[0]\n");
194 todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szTypeName[0]\n");
195 ok(shfi.iIcon == 0xcfcfcfcf, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) should not clear iIcon\n");
197 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
198 &shfi, sizeof(shfi),
199 SHGFI_EXETYPE | SHGFI_USEFILEATTRIBUTES);
200 todo_wine ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_EXETYPE) returned %d\n", rc);
202 /* Test SHGFI_USEFILEATTRIBUTES support */
203 strcpy(shfi.szDisplayName, "dummy");
204 shfi.iIcon=0xdeadbeef;
205 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
206 &shfi, sizeof(shfi),
207 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
208 ok(rc, "SHGetFileInfoA(c:\\nonexistent) failed\n");
209 if (rc)
211 ok(strcpy(shfi.szDisplayName, "dummy") != 0, "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n");
212 ok(shfi.iIcon != 0xdeadbeef, "SHGetFileInfoA(c:\\nonexistent) iIcon is not set\n");
215 /* Wine does not have a default icon for text files, and Windows 98 fails
216 * if we give it an empty executable. So use notepad.exe as the test
218 if (SearchPath(NULL, "notepad.exe", NULL, sizeof(notepad), notepad, NULL))
220 strcpy(shfi.szDisplayName, "dummy");
221 shfi.iIcon=0xdeadbeef;
222 rc=SHGetFileInfoA(notepad, GetFileAttributes(notepad),
223 &shfi, sizeof(shfi),
224 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
225 ok(rc, "SHGetFileInfoA(%s, SHGFI_USEFILEATTRIBUTES) failed\n", notepad);
226 strcpy(shfi2.szDisplayName, "dummy");
227 shfi2.iIcon=0xdeadbeef;
228 rc2=SHGetFileInfoA(notepad, 0,
229 &shfi2, sizeof(shfi2),
230 SHGFI_ICONLOCATION);
231 ok(rc2, "SHGetFileInfoA(%s) failed\n", notepad);
232 if (rc && rc2)
234 ok(lstrcmpi(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
235 ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
239 /* with a directory now */
240 strcpy(shfi.szDisplayName, "dummy");
241 shfi.iIcon=0xdeadbeef;
242 rc=SHGetFileInfoA("test4.txt", GetFileAttributes("test4.txt"),
243 &shfi, sizeof(shfi),
244 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
245 ok(rc, "SHGetFileInfoA(test4.txt/, SHGFI_USEFILEATTRIBUTES) failed\n");
246 strcpy(shfi2.szDisplayName, "dummy");
247 shfi2.iIcon=0xdeadbeef;
248 rc2=SHGetFileInfoA("test4.txt", 0,
249 &shfi2, sizeof(shfi2),
250 SHGFI_ICONLOCATION);
251 ok(rc2, "SHGetFileInfoA(test4.txt/) failed\n");
252 if (rc && rc2)
254 ok(lstrcmpi(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
255 ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
259 static void test_get_file_info_iconlist(void)
261 /* Test retrieving a handle to the system image list, and
262 * what that returns for hIcon
264 HRESULT hr;
265 HIMAGELIST hSysImageList;
266 LPITEMIDLIST pidList;
267 SHFILEINFOA shInfoa;
268 SHFILEINFOW shInfow;
270 hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidList);
271 if (!SUCCEEDED(hr)) {
272 skip("can't get desktop pidl\n");
273 return;
276 memset(&shInfoa, 0xcf, sizeof(shInfoa));
277 hSysImageList = (HIMAGELIST) SHGetFileInfoA((const char *)pidList, 0,
278 &shInfoa, sizeof(shInfoa),
279 SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
280 ok(hSysImageList != INVALID_HANDLE_VALUE, "Can't get handle for CSIDL_DESKTOP imagelist\n");
281 todo_wine ok(shInfoa.hIcon == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
282 todo_wine ok(shInfoa.szTypeName[0] == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
283 ok(shInfoa.iIcon != 0xcfcfcfcf, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
284 ok(shInfoa.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should not change dwAttributes\n");
285 CloseHandle(hSysImageList);
287 memset(&shInfow, 0xcf, sizeof(shInfow));
288 hSysImageList = (HIMAGELIST) SHGetFileInfoW((const WCHAR *)pidList, 0,
289 &shInfow, sizeof(shInfow),
290 SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
291 ok(hSysImageList != INVALID_HANDLE_VALUE, "Can't get handle for CSIDL_DESKTOP imagelist\n");
292 todo_wine ok(shInfow.hIcon == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
293 ok(shInfow.szTypeName[0] == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
294 ok(shInfow.iIcon != 0xcfcfcfcf, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
295 ok(shInfow.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should not change dwAttributes\n");
296 CloseHandle(hSysImageList);
298 ILFree(pidList);
303 puts into the specified buffer file names with current directory.
304 files - string with file names, separated by null characters. Ends on a double
305 null characters
307 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
309 buf[0] = 0;
310 while (files[0])
312 strcpy(buf, CURR_DIR);
313 buf += strlen(buf);
314 buf[0] = '\\';
315 buf++;
316 strcpy(buf, files);
317 buf += strlen(buf) + 1;
318 files += strlen(files) + 1;
320 buf[0] = 0;
324 /* tests the FO_DELETE action */
325 static void test_delete(void)
327 SHFILEOPSTRUCTA shfo;
328 DWORD ret;
329 CHAR buf[sizeof(CURR_DIR)+sizeof("/test?.txt")+1];
331 sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
332 buf[strlen(buf) + 1] = '\0';
334 shfo.hwnd = NULL;
335 shfo.wFunc = FO_DELETE;
336 shfo.pFrom = buf;
337 shfo.pTo = "\0";
338 shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
339 shfo.hNameMappings = NULL;
340 shfo.lpszProgressTitle = NULL;
342 ok(!SHFileOperationA(&shfo), "Deletion was not successful\n");
343 ok(file_exists("test4.txt"), "Directory should not have been removed\n");
344 ok(!file_exists("test1.txt"), "File should have been removed\n");
346 ret = SHFileOperationA(&shfo);
347 ok(!ret, "Directory exists, but is not removed, ret=%d\n", ret);
348 ok(file_exists("test4.txt"), "Directory should not have been removed\n");
350 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
352 ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
353 ok(!file_exists("test4.txt"), "Directory should have been removed\n");
355 ret = SHFileOperationA(&shfo);
356 ok(!ret, "The requested file does not exist, ret=%d\n", ret);
358 init_shfo_tests();
359 sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
360 buf[strlen(buf) + 1] = '\0';
361 ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Filling the subdirectory failed\n");
362 ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
363 ok(!file_exists("test4.txt"), "Directory is not removed\n");
365 init_shfo_tests();
366 shfo.pFrom = "test1.txt\0test4.txt\0";
367 ok(!SHFileOperationA(&shfo), "Directory and a file are not removed\n");
368 ok(!file_exists("test1.txt"), "The file should have been removed\n");
369 ok(!file_exists("test4.txt"), "Directory should have been removed\n");
370 ok(file_exists("test2.txt"), "This file should not have been removed\n");
372 /* FOF_FILESONLY does not delete a dir matching a wildcard */
373 init_shfo_tests();
374 shfo.fFlags |= FOF_FILESONLY;
375 shfo.pFrom = "*.txt\0";
376 ok(!SHFileOperation(&shfo), "Failed to delete files\n");
377 ok(!file_exists("test1.txt"), "test1.txt should have been removed\n");
378 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
379 ok(file_exists("test4.txt"), "test4.txt should not have been removed\n");
381 /* FOF_FILESONLY only deletes a dir if explicitly specified */
382 init_shfo_tests();
383 shfo.pFrom = "test_?.txt\0test4.txt\0";
384 ok(!SHFileOperation(&shfo), "Failed to delete files and directory\n");
385 ok(!file_exists("test4.txt"), "test4.txt should have been removed\n");
386 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
387 ok(file_exists("test1.txt"), "test1.txt should not have been removed\n");
389 /* try to delete an invalid filename */
390 if (0) {
391 /* this crashes on win9x */
392 init_shfo_tests();
393 shfo.pFrom = "\0";
394 shfo.fFlags &= ~FOF_FILESONLY;
395 shfo.fAnyOperationsAborted = FALSE;
396 ret = SHFileOperation(&shfo);
397 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", ret);
398 ok(!shfo.fAnyOperationsAborted, "Expected no aborted operations\n");
399 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
402 /* try an invalid function */
403 init_shfo_tests();
404 shfo.pFrom = "test1.txt\0";
405 shfo.wFunc = 0;
406 ret = SHFileOperation(&shfo);
407 ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret);
408 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
410 /* try an invalid list, only one null terminator */
411 if (0) {
412 /* this crashes on win9x */
413 init_shfo_tests();
414 shfo.pFrom = "";
415 shfo.wFunc = FO_DELETE;
416 ret = SHFileOperation(&shfo);
417 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", ret);
418 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
421 /* delete a dir, and then a file inside the dir, same as
422 * deleting a nonexistent file
424 init_shfo_tests();
425 shfo.pFrom = "testdir2\0testdir2\\one.txt\0";
426 shfo.wFunc = FO_DELETE;
427 ret = SHFileOperation(&shfo);
428 ok(ret == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", ret);
429 ok(!file_exists("testdir2"), "Expected testdir2 to not exist\n");
430 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
432 /* try the FOF_NORECURSION flag, continues deleting subdirs */
433 init_shfo_tests();
434 shfo.pFrom = "testdir2\0";
435 shfo.fFlags |= FOF_NORECURSION;
436 ret = SHFileOperation(&shfo);
437 ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
438 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
439 ok(!file_exists("testdir2\\nested"), "Expected testdir2\\nested to exist\n");
442 /* tests the FO_RENAME action */
443 static void test_rename(void)
445 SHFILEOPSTRUCTA shfo, shfo2;
446 CHAR from[5*MAX_PATH];
447 CHAR to[5*MAX_PATH];
448 DWORD retval;
450 shfo.hwnd = NULL;
451 shfo.wFunc = FO_RENAME;
452 shfo.pFrom = from;
453 shfo.pTo = to;
454 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
455 shfo.hNameMappings = NULL;
456 shfo.lpszProgressTitle = NULL;
458 set_curr_dir_path(from, "test1.txt\0");
459 set_curr_dir_path(to, "test4.txt\0");
460 ok(SHFileOperationA(&shfo), "File is not renamed moving to other directory "
461 "when specifying directory name only\n");
462 ok(file_exists("test1.txt"), "The file is removed\n");
464 set_curr_dir_path(from, "test3.txt\0");
465 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
466 ok(!SHFileOperationA(&shfo), "File is renamed moving to other directory\n");
467 ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
469 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
470 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
471 retval = SHFileOperationA(&shfo); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
472 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
473 "Can't rename many files, retval = %d\n", retval);
474 ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
476 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
477 shfo2.fFlags |= FOF_MULTIDESTFILES;
479 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
480 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
481 retval = SHFileOperationA(&shfo2); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
482 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
483 "Can't rename many files, retval = %d\n", retval);
484 ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
486 set_curr_dir_path(from, "test1.txt\0");
487 set_curr_dir_path(to, "test6.txt\0");
488 retval = SHFileOperationA(&shfo);
489 ok(!retval, "Rename file failed, retval = %d\n", retval);
490 ok(!file_exists("test1.txt"), "The file is not renamed\n");
491 ok(file_exists("test6.txt"), "The file is not renamed\n");
493 set_curr_dir_path(from, "test6.txt\0");
494 set_curr_dir_path(to, "test1.txt\0");
495 retval = SHFileOperationA(&shfo);
496 ok(!retval, "Rename file back failed, retval = %d\n", retval);
498 set_curr_dir_path(from, "test4.txt\0");
499 set_curr_dir_path(to, "test6.txt\0");
500 retval = SHFileOperationA(&shfo);
501 ok(!retval, "Rename dir failed, retval = %d\n", retval);
502 ok(!file_exists("test4.txt"), "The dir is not renamed\n");
503 ok(file_exists("test6.txt"), "The dir is not renamed\n");
505 set_curr_dir_path(from, "test6.txt\0");
506 set_curr_dir_path(to, "test4.txt\0");
507 retval = SHFileOperationA(&shfo);
508 ok(!retval, "Rename dir back failed, retval = %d\n", retval);
510 /* try to rename more than one file to a single file */
511 shfo.pFrom = "test1.txt\0test2.txt\0";
512 shfo.pTo = "a.txt\0";
513 retval = SHFileOperationA(&shfo);
514 ok(retval == ERROR_GEN_FAILURE, "Expected ERROR_GEN_FAILURE, got %d\n", retval);
515 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
516 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
518 /* pFrom doesn't exist */
519 shfo.pFrom = "idontexist\0";
520 shfo.pTo = "newfile\0";
521 retval = SHFileOperationA(&shfo);
522 ok(retval == 1026, "Expected 1026, got %d\n", retval);
523 ok(!file_exists("newfile"), "Expected newfile to not exist\n");
525 /* pTo already exist */
526 shfo.pFrom = "test1.txt\0";
527 shfo.pTo = "test2.txt\0";
528 retval = SHFileOperationA(&shfo);
529 ok(retval == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %d\n", retval);
531 /* pFrom is valid, but pTo is empty */
532 shfo.pFrom = "test1.txt\0";
533 shfo.pTo = "\0";
534 retval = SHFileOperationA(&shfo);
535 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
536 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
538 /* pFrom is empty */
539 shfo.pFrom = "\0";
540 retval = SHFileOperationA(&shfo);
541 ok(retval == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", retval);
543 /* pFrom is NULL, commented out because it crashes on nt 4.0 */
544 #if 0
545 shfo.pFrom = NULL;
546 retval = SHFileOperationA(&shfo);
547 ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", retval);
548 #endif
551 /* tests the FO_COPY action */
552 static void test_copy(void)
554 SHFILEOPSTRUCTA shfo, shfo2;
555 CHAR from[5*MAX_PATH];
556 CHAR to[5*MAX_PATH];
557 FILEOP_FLAGS tmp_flags;
558 DWORD retval;
559 LPSTR ptr;
561 shfo.hwnd = NULL;
562 shfo.wFunc = FO_COPY;
563 shfo.pFrom = from;
564 shfo.pTo = to;
565 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
566 shfo.hNameMappings = NULL;
567 shfo.lpszProgressTitle = NULL;
569 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
570 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
571 ok(SHFileOperationA(&shfo), "Can't copy many files\n");
572 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
573 "specified as a target\n");
575 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
576 shfo2.fFlags |= FOF_MULTIDESTFILES;
578 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
579 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
580 ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
581 ok(file_exists("test6.txt"), "The file is copied - many files are "
582 "specified as a target\n");
583 DeleteFileA("test6.txt");
584 DeleteFileA("test7.txt");
585 RemoveDirectoryA("test8.txt");
587 /* number of sources do not correspond to number of targets */
588 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
589 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
590 ok(SHFileOperationA(&shfo2), "Can't copy many files\n");
591 ok(!file_exists("test6.txt"), "The file is not copied - many files are "
592 "specified as a target\n");
594 set_curr_dir_path(from, "test1.txt\0");
595 set_curr_dir_path(to, "test4.txt\0");
596 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
597 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
599 set_curr_dir_path(from, "test?.txt\0");
600 set_curr_dir_path(to, "testdir2\0");
601 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
602 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
603 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
604 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
605 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
606 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
607 clean_after_shfo_tests();
609 init_shfo_tests();
610 shfo.fFlags |= FOF_FILESONLY;
611 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
612 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
613 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
614 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
615 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
616 clean_after_shfo_tests();
618 init_shfo_tests();
619 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
620 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
621 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
622 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
623 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
624 ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
625 clean_after_shfo_tests();
627 /* Copying multiple files with one not existing as source, fails the
628 entire operation in Win98/ME/2K/XP, but not in 95/NT */
629 init_shfo_tests();
630 tmp_flags = shfo.fFlags;
631 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
632 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
633 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
634 retval = SHFileOperationA(&shfo);
635 if (!retval)
636 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
637 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
638 else
640 /* Win 98/ME/2K/XP fail the entire operation with return code 1026 if one source file does not exist */
641 ok(retval == 1026, "Files are copied to other directory\n");
642 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
644 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
645 shfo.fFlags = tmp_flags;
647 /* copy into a nonexistent directory */
648 init_shfo_tests();
649 shfo.fFlags = FOF_NOCONFIRMMKDIR;
650 set_curr_dir_path(from, "test1.txt\0");
651 set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
652 retval= SHFileOperation(&shfo);
653 ok(!retval, "Error copying into nonexistent directory\n");
654 ok(file_exists("nonexistent"), "nonexistent not created\n");
655 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
656 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
657 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
659 /* a relative dest directory is OK */
660 clean_after_shfo_tests();
661 init_shfo_tests();
662 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
663 shfo.pTo = "testdir2\0";
664 retval = SHFileOperation(&shfo);
665 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
666 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
668 /* try to copy files to a file */
669 clean_after_shfo_tests();
670 init_shfo_tests();
671 shfo.pFrom = from;
672 shfo.pTo = to;
673 /* suppress the error-dialog in win9x here */
674 shfo.fFlags |= FOF_NOERRORUI;
675 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
676 set_curr_dir_path(to, "test3.txt\0");
677 retval = SHFileOperation(&shfo);
678 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
679 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
680 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
682 /* try to copy many files to nonexistent directory */
683 DeleteFile(to);
684 shfo.fFlags &= ~FOF_NOERRORUI;
685 shfo.fAnyOperationsAborted = FALSE;
686 retval = SHFileOperation(&shfo);
687 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
688 ok(DeleteFile("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
689 ok(DeleteFile("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
690 ok(RemoveDirectory(to), "Expected test3.txt to exist\n");
692 /* send in FOF_MULTIDESTFILES with too many destination files */
693 init_shfo_tests();
694 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
695 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
696 shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
697 retval = SHFileOperation(&shfo);
698 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
699 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
700 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
702 /* send in FOF_MULTIDESTFILES with too many destination files */
703 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
704 shfo.pTo = "e.txt\0f.txt\0";
705 shfo.fAnyOperationsAborted = FALSE;
706 retval = SHFileOperation(&shfo);
707 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
708 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
709 ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
711 /* use FOF_MULTIDESTFILES with files and a source directory */
712 shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
713 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
714 shfo.fAnyOperationsAborted = FALSE;
715 retval = SHFileOperation(&shfo);
716 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
717 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
718 ok(DeleteFile("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
719 ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
721 /* try many dest files without FOF_MULTIDESTFILES flag */
722 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
723 shfo.pTo = "a.txt\0b.txt\0c.txt\0";
724 shfo.fAnyOperationsAborted = FALSE;
725 shfo.fFlags &= ~FOF_MULTIDESTFILES;
726 retval = SHFileOperation(&shfo);
727 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
728 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
730 /* try a glob */
731 shfo.pFrom = "test?.txt\0";
732 shfo.pTo = "testdir2\0";
733 shfo.fFlags &= ~FOF_MULTIDESTFILES;
734 retval = SHFileOperation(&shfo);
735 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
736 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
738 /* try a glob with FOF_FILESONLY */
739 clean_after_shfo_tests();
740 init_shfo_tests();
741 shfo.pFrom = "test?.txt\0";
742 shfo.fFlags |= FOF_FILESONLY;
743 retval = SHFileOperation(&shfo);
744 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
745 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
746 ok(!file_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
748 /* try a glob with FOF_MULTIDESTFILES and the same number
749 * of dest files that we would expect
751 clean_after_shfo_tests();
752 init_shfo_tests();
753 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
754 shfo.fFlags &= ~FOF_FILESONLY;
755 shfo.fFlags |= FOF_MULTIDESTFILES;
756 retval = SHFileOperation(&shfo);
757 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
758 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
759 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
760 ok(!RemoveDirectory("b.txt"), "b.txt should not exist\n");
762 /* copy one file to two others, second is ignored */
763 clean_after_shfo_tests();
764 init_shfo_tests();
765 shfo.pFrom = "test1.txt\0";
766 shfo.pTo = "b.txt\0c.txt\0";
767 shfo.fAnyOperationsAborted = FALSE;
768 retval = SHFileOperation(&shfo);
769 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
770 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
771 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
773 /* copy two file to three others, all fail */
774 shfo.pFrom = "test1.txt\0test2.txt\0";
775 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
776 retval = SHFileOperation(&shfo);
777 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
778 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
779 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
781 /* copy one file and one directory to three others */
782 shfo.pFrom = "test1.txt\0test4.txt\0";
783 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
784 shfo.fAnyOperationsAborted = FALSE;
785 retval = SHFileOperation(&shfo);
786 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
787 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
788 ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
789 ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
791 /* copy a directory with a file beneath it, plus some files */
792 createTestFile("test4.txt\\a.txt");
793 shfo.pFrom = "test4.txt\0test1.txt\0";
794 shfo.pTo = "testdir2\0";
795 shfo.fFlags &= ~FOF_MULTIDESTFILES;
796 shfo.fAnyOperationsAborted = FALSE;
797 retval = SHFileOperation(&shfo);
798 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
799 ok(DeleteFile("testdir2\\test1.txt"), "Expected newdir\\test1.txt to exist\n");
800 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
801 ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
803 /* copy one directory and a file in that dir to another dir */
804 shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
805 shfo.pTo = "testdir2\0";
806 retval = SHFileOperation(&shfo);
807 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
808 ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
809 ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
811 /* copy a file in a directory first, and then the directory to a nonexistent dir */
812 shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
813 shfo.pTo = "nonexistent\0";
814 retval = SHFileOperation(&shfo);
815 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
816 ok(shfo.fAnyOperationsAborted, "Expected operations to be aborted\n");
817 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
818 DeleteFile("test4.txt\\a.txt");
820 /* destination is same as source file */
821 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
822 shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
823 shfo.fAnyOperationsAborted = FALSE;
824 shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
825 retval = SHFileOperation(&shfo);
826 ok(retval == ERROR_NO_MORE_SEARCH_HANDLES,
827 "Expected ERROR_NO_MORE_SEARCH_HANDLES, got %d\n", retval);
828 ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
829 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
830 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
832 /* destination is same as source directory */
833 shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
834 shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
835 shfo.fAnyOperationsAborted = FALSE;
836 retval = SHFileOperation(&shfo);
837 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
838 ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
839 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
841 /* copy a directory into itself, error displayed in UI */
842 shfo.pFrom = "test4.txt\0";
843 shfo.pTo = "test4.txt\\newdir\0";
844 shfo.fFlags &= ~FOF_MULTIDESTFILES;
845 shfo.fAnyOperationsAborted = FALSE;
846 retval = SHFileOperation(&shfo);
847 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
848 ok(!RemoveDirectory("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
850 /* copy a directory to itself, error displayed in UI */
851 shfo.pFrom = "test4.txt\0";
852 shfo.pTo = "test4.txt\0";
853 shfo.fAnyOperationsAborted = FALSE;
854 retval = SHFileOperation(&shfo);
855 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
857 /* copy a file into a directory, and the directory into itself */
858 shfo.pFrom = "test1.txt\0test4.txt\0";
859 shfo.pTo = "test4.txt\0";
860 shfo.fAnyOperationsAborted = FALSE;
861 shfo.fFlags |= FOF_NOCONFIRMATION;
862 retval = SHFileOperation(&shfo);
863 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
864 ok(DeleteFile("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
866 /* copy a file to a file, and the directory into itself */
867 shfo.pFrom = "test1.txt\0test4.txt\0";
868 shfo.pTo = "test4.txt\\a.txt\0";
869 shfo.fAnyOperationsAborted = FALSE;
870 retval = SHFileOperation(&shfo);
871 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
872 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
874 /* copy a nonexistent file to a nonexistent directory */
875 shfo.pFrom = "e.txt\0";
876 shfo.pTo = "nonexistent\0";
877 shfo.fAnyOperationsAborted = FALSE;
878 retval = SHFileOperation(&shfo);
879 ok(retval == 1026, "Expected 1026, got %d\n", retval);
880 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
881 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
883 /* Overwrite tests */
884 clean_after_shfo_tests();
885 init_shfo_tests();
886 shfo.fFlags = FOF_NOCONFIRMATION;
887 shfo.pFrom = "test1.txt\0";
888 shfo.pTo = "test2.txt\0";
889 shfo.fAnyOperationsAborted = FALSE;
890 /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
891 retval = SHFileOperation(&shfo);
892 ok(retval == 0, "Expected 0, got %d\n", retval);
893 ok(file_has_content("test2.txt", "test1.txt\n"), "The file was not copied\n");
895 shfo.pFrom = "test3.txt\0test1.txt\0";
896 shfo.pTo = "test2.txt\0one.txt\0";
897 shfo.fFlags = FOF_NOCONFIRMATION | FOF_MULTIDESTFILES;
898 /* without FOF_NOCONFIRMATION the confirmation is Yes/Yes to All/No/Cancel */
899 retval = SHFileOperation(&shfo);
900 ok(retval == 0, "Expected 0, got %d\n", retval);
901 ok(file_has_content("test2.txt", "test3.txt\n"), "The file was not copied\n");
903 shfo.pFrom = "one.txt\0";
904 shfo.pTo = "testdir2\0";
905 shfo.fFlags = FOF_NOCONFIRMATION;
906 /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
907 retval = SHFileOperation(&shfo);
908 ok(retval == 0, "Expected 0, got %d\n", retval);
909 ok(file_has_content("testdir2\\one.txt", "test1.txt\n"), "The file was not copied\n");
911 createTestFile("test4.txt\\test1.txt");
912 shfo.pFrom = "test4.txt\0";
913 shfo.pTo = "testdir2\0";
914 shfo.fFlags = FOF_NOCONFIRMATION;
915 ok(!SHFileOperation(&shfo), "First SHFileOperation failed\n");
916 createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */
917 /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */
918 retval = SHFileOperation(&shfo);
919 ok(retval == 0, "Expected 0, got %d\n", retval);
920 ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
922 createTestFile("one.txt");
924 /* pFrom contains bogus 2nd name longer than MAX_PATH */
925 memset(from, 'a', MAX_PATH*2);
926 memset(from+MAX_PATH*2, 0, 2);
927 lstrcpyA(from, "one.txt");
928 shfo.pFrom = from;
929 shfo.pTo = "two.txt\0";
930 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
931 retval = SHFileOperation(&shfo);
932 ok(retval == 1148 || retval == 1026, "Expected 1148 or 1026, got %d\n", retval);
933 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
934 ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
936 createTestFile("one.txt");
938 /* pTo contains bogus 2nd name longer than MAX_PATH */
939 memset(to, 'a', MAX_PATH*2);
940 memset(to+MAX_PATH*2, 0, 2);
941 lstrcpyA(to, "two.txt");
942 shfo.pFrom = "one.txt\0";
943 shfo.pTo = to;
944 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
945 retval = SHFileOperation(&shfo);
946 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
947 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
948 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
950 createTestFile("one.txt");
952 /* no FOF_MULTIDESTFILES, two files in pTo */
953 shfo.pFrom = "one.txt\0";
954 shfo.pTo = "two.txt\0three.txt\0";
955 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
956 retval = SHFileOperation(&shfo);
957 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
958 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
959 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
961 createTestFile("one.txt");
963 /* both pFrom and pTo contain bogus 2nd names longer than MAX_PATH */
964 memset(from, 'a', MAX_PATH*2);
965 memset(from+MAX_PATH*2, 0, 2);
966 memset(to, 'a', MAX_PATH*2);
967 memset(to+MAX_PATH*2, 0, 2);
968 lstrcpyA(from, "one.txt");
969 lstrcpyA(to, "two.txt");
970 shfo.pFrom = from;
971 shfo.pTo = to;
972 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
973 retval = SHFileOperation(&shfo);
974 ok(retval == 1148 || retval == 1026, "Expected 1148 or 1026, got %d\n", retval);
975 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
976 ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
978 createTestFile("one.txt");
980 /* pTo contains bogus 2nd name longer than MAX_PATH, FOF_MULTIDESTFILES */
981 memset(to, 'a', MAX_PATH*2);
982 memset(to+MAX_PATH*2, 0, 2);
983 lstrcpyA(to, "two.txt");
984 shfo.pFrom = "one.txt\0";
985 shfo.pTo = to;
986 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
987 FOF_SILENT | FOF_NOERRORUI;
988 retval = SHFileOperation(&shfo);
989 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
990 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
991 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
993 createTestFile("one.txt");
994 createTestFile("two.txt");
996 /* pTo contains bogus 2nd name longer than MAX_PATH,
997 * multiple source files,
998 * dest directory does not exist
1000 memset(to, 'a', 2 * MAX_PATH);
1001 memset(to+MAX_PATH*2, 0, 2);
1002 lstrcpyA(to, "threedir");
1003 shfo.pFrom = "one.txt\0two.txt\0";
1004 shfo.pTo = to;
1005 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1006 retval = SHFileOperation(&shfo);
1007 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
1008 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1009 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1010 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1011 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1012 ok(!DeleteFileA("threedir"), "Expected file to not exist\n");
1013 ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1015 createTestFile("one.txt");
1016 createTestFile("two.txt");
1017 CreateDirectoryA("threedir", NULL);
1019 /* pTo contains bogus 2nd name longer than MAX_PATH,
1020 * multiple source files,
1021 * dest directory does exist
1023 memset(to, 'a', 2 * MAX_PATH);
1024 memset(to+MAX_PATH*2, 0, 2);
1025 lstrcpyA(to, "threedir");
1026 shfo.pFrom = "one.txt\0two.txt\0";
1027 shfo.pTo = to;
1028 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1029 retval = SHFileOperation(&shfo);
1030 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1031 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1032 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1033 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1034 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1035 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1037 if (0) {
1038 /* this crashes on win9x */
1039 createTestFile("one.txt");
1040 createTestFile("two.txt");
1042 /* pTo contains bogus 2nd name longer than MAX_PATH,
1043 * multiple source files, FOF_MULTIDESTFILES
1044 * dest dir does not exist
1047 memset(to, 'a', 2 * MAX_PATH);
1048 memset(to+MAX_PATH*2, 0, 2);
1049 lstrcpyA(to, "threedir");
1050 shfo.pFrom = "one.txt\0two.txt\0";
1051 shfo.pTo = to;
1052 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1053 FOF_SILENT | FOF_NOERRORUI;
1054 retval = SHFileOperation(&shfo);
1055 ok(retval == ERROR_CANCELLED ||
1056 retval == ERROR_SUCCESS, /* win2k3 */
1057 "Expected ERROR_CANCELLED or ERROR_SUCCESS, got %d\n", retval);
1058 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1059 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1060 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1061 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1062 ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1064 /* file exists in win2k */
1065 DeleteFileA("threedir");
1069 createTestFile("one.txt");
1070 createTestFile("two.txt");
1071 CreateDirectoryA("threedir", NULL);
1073 /* pTo contains bogus 2nd name longer than MAX_PATH,
1074 * multiple source files, FOF_MULTIDESTFILES
1075 * dest dir does exist
1077 memset(to, 'a', 2 * MAX_PATH);
1078 memset(to+MAX_PATH*2, 0, 2);
1079 lstrcpyA(to, "threedir");
1080 ptr = to + lstrlenA(to) + 1;
1081 lstrcpyA(ptr, "fourdir");
1082 shfo.pFrom = "one.txt\0two.txt\0";
1083 shfo.pTo = to;
1084 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1085 FOF_SILENT | FOF_NOERRORUI;
1086 retval = SHFileOperation(&shfo);
1087 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1088 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1089 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1090 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1091 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1092 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1093 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1094 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1096 createTestFile("one.txt");
1097 createTestFile("two.txt");
1098 CreateDirectoryA("threedir", NULL);
1100 /* multiple source files, FOF_MULTIDESTFILES
1101 * multiple dest files, but first dest dir exists
1102 * num files in lists is equal
1104 shfo.pFrom = "one.txt\0two.txt\0";
1105 shfo.pTo = "threedir\0fourdir\0";
1106 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1107 FOF_SILENT | FOF_NOERRORUI;
1108 retval = SHFileOperation(&shfo);
1109 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
1110 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1111 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1112 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1113 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1114 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1115 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1116 ok(!RemoveDirectoryA("fourdir"), "Expected dit to not exist\n");
1118 createTestFile("one.txt");
1119 createTestFile("two.txt");
1120 CreateDirectoryA("threedir", NULL);
1122 /* multiple source files, FOF_MULTIDESTFILES
1123 * multiple dest files, but first dest dir exists
1124 * num files in lists is not equal
1126 shfo.pFrom = "one.txt\0two.txt\0";
1127 shfo.pTo = "threedir\0fourdir\0five\0";
1128 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1129 FOF_SILENT | FOF_NOERRORUI;
1130 retval = SHFileOperation(&shfo);
1131 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1132 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1133 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1134 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1135 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1136 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1137 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1138 ok(!RemoveDirectoryA("fourdir"), "Expected dit to not exist\n");
1139 ok(!DeleteFileA("five"), "Expected file to not exist\n");
1140 ok(!RemoveDirectoryA("five"), "Expected dit to not exist\n");
1142 createTestFile("aa.txt");
1143 createTestFile("ab.txt");
1144 CreateDirectoryA("one", NULL);
1145 CreateDirectoryA("two", NULL);
1147 /* pFrom has a glob, pTo has more than one dest */
1148 shfo.pFrom = "a*.txt\0";
1149 shfo.pTo = "one\0two\0";
1150 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1151 retval = SHFileOperation(&shfo);
1152 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1153 ok(DeleteFileA("one\\aa.txt"), "Expected file to exist\n");
1154 ok(DeleteFileA("one\\ab.txt"), "Expected file to exist\n");
1155 ok(!DeleteFileA("two\\aa.txt"), "Expected file to not exist\n");
1156 ok(!DeleteFileA("two\\ab.txt"), "Expected file to not exist\n");
1157 ok(DeleteFileA("aa.txt"), "Expected file to exist\n");
1158 ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
1159 ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
1160 ok(RemoveDirectoryA("two"), "Expected dir to exist\n");
1163 /* tests the FO_MOVE action */
1164 static void test_move(void)
1166 SHFILEOPSTRUCTA shfo, shfo2;
1167 CHAR from[5*MAX_PATH];
1168 CHAR to[5*MAX_PATH];
1169 DWORD retval;
1171 shfo.hwnd = NULL;
1172 shfo.wFunc = FO_MOVE;
1173 shfo.pFrom = from;
1174 shfo.pTo = to;
1175 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1176 shfo.hNameMappings = NULL;
1177 shfo.lpszProgressTitle = NULL;
1179 set_curr_dir_path(from, "test1.txt\0");
1180 set_curr_dir_path(to, "test4.txt\0");
1181 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
1182 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
1183 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
1185 set_curr_dir_path(from, "test?.txt\0");
1186 set_curr_dir_path(to, "testdir2\0");
1187 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
1188 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
1189 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
1190 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
1191 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
1192 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
1194 clean_after_shfo_tests();
1195 init_shfo_tests();
1197 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
1198 shfo2.fFlags |= FOF_MULTIDESTFILES;
1200 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
1201 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
1202 ok(!SHFileOperationA(&shfo2), "Move many files\n");
1203 ok(file_exists("test6.txt"), "The file is moved - many files are "
1204 "specified as a target\n");
1205 DeleteFileA("test6.txt");
1206 DeleteFileA("test7.txt");
1207 RemoveDirectoryA("test8.txt");
1209 init_shfo_tests();
1211 /* number of sources do not correspond to number of targets */
1212 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
1213 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
1214 ok(SHFileOperationA(&shfo2), "Can't move many files\n");
1215 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
1216 "specified as a target\n");
1218 init_shfo_tests();
1220 set_curr_dir_path(from, "test3.txt\0");
1221 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
1222 ok(!SHFileOperationA(&shfo), "File is moved moving to other directory\n");
1223 ok(file_exists("test4.txt\\test1.txt"), "The file is moved\n");
1225 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
1226 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
1227 ok(SHFileOperationA(&shfo), "Cannot move many files\n");
1228 ok(file_exists("test1.txt"), "The file is not moved. Many files are specified\n");
1229 ok(file_exists("test4.txt"), "The directory is not moved. Many files are specified\n");
1231 set_curr_dir_path(from, "test1.txt\0");
1232 set_curr_dir_path(to, "test6.txt\0");
1233 ok(!SHFileOperationA(&shfo), "Move file\n");
1234 ok(!file_exists("test1.txt"), "The file is moved\n");
1235 ok(file_exists("test6.txt"), "The file is moved\n");
1236 set_curr_dir_path(from, "test6.txt\0");
1237 set_curr_dir_path(to, "test1.txt\0");
1238 ok(!SHFileOperationA(&shfo), "Move file back\n");
1240 set_curr_dir_path(from, "test4.txt\0");
1241 set_curr_dir_path(to, "test6.txt\0");
1242 ok(!SHFileOperationA(&shfo), "Move dir\n");
1243 ok(!file_exists("test4.txt"), "The dir is moved\n");
1244 ok(file_exists("test6.txt"), "The dir is moved\n");
1245 set_curr_dir_path(from, "test6.txt\0");
1246 set_curr_dir_path(to, "test4.txt\0");
1247 ok(!SHFileOperationA(&shfo), "Move dir back\n");
1249 /* move one file to two others */
1250 init_shfo_tests();
1251 shfo.pFrom = "test1.txt\0";
1252 shfo.pTo = "a.txt\0b.txt\0";
1253 retval = SHFileOperationA(&shfo);
1254 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1255 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
1256 ok(DeleteFile("a.txt"), "Expected a.txt to exist\n");
1257 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1259 /* move two files to one other */
1260 shfo.pFrom = "test2.txt\0test3.txt\0";
1261 shfo.pTo = "test1.txt\0";
1262 retval = SHFileOperationA(&shfo);
1263 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
1264 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
1265 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
1266 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
1268 /* move a directory into itself */
1269 shfo.pFrom = "test4.txt\0";
1270 shfo.pTo = "test4.txt\\b.txt\0";
1271 retval = SHFileOperationA(&shfo);
1272 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1273 ok(!RemoveDirectory("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
1274 ok(file_exists("test4.txt"), "Expected test4.txt to exist\n");
1276 /* move many files without FOF_MULTIDESTFILES */
1277 shfo.pFrom = "test2.txt\0test3.txt\0";
1278 shfo.pTo = "d.txt\0e.txt\0";
1279 retval = SHFileOperationA(&shfo);
1280 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
1281 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
1282 ok(!DeleteFile("e.txt"), "Expected e.txt to not exist\n");
1284 /* number of sources != number of targets */
1285 shfo.pTo = "d.txt\0";
1286 shfo.fFlags |= FOF_MULTIDESTFILES;
1287 retval = SHFileOperationA(&shfo);
1288 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
1289 ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
1291 /* FO_MOVE does not create dest directories */
1292 shfo.pFrom = "test2.txt\0";
1293 shfo.pTo = "dir1\\dir2\\test2.txt\0";
1294 retval = SHFileOperationA(&shfo);
1295 ok(retval == ERROR_CANCELLED, "Expected ERROR_CANCELLED, got %d\n", retval);
1296 ok(!file_exists("dir1"), "Expected dir1 to not exist\n");
1298 /* try to overwrite an existing file */
1299 shfo.pTo = "test3.txt\0";
1300 retval = SHFileOperationA(&shfo);
1301 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1302 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
1303 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
1306 static void test_sh_create_dir(void)
1308 CHAR path[MAX_PATH];
1309 int ret;
1311 if(!pSHCreateDirectoryExA)
1313 trace("skipping SHCreateDirectoryExA tests\n");
1314 return;
1317 set_curr_dir_path(path, "testdir2\\test4.txt\0");
1318 ret = pSHCreateDirectoryExA(NULL, path, NULL);
1319 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
1320 ok(file_exists("testdir2"), "The first directory is not created\n");
1321 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
1323 ret = pSHCreateDirectoryExA(NULL, path, NULL);
1324 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
1326 ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
1327 ok(file_exists("c:\\testdir3"), "The directory is not created\n");
1330 static void test_sh_path_prepare(void)
1332 HRESULT res;
1333 CHAR path[MAX_PATH];
1335 if(!pSHPathPrepareForWriteA)
1337 trace("skipping SHPathPrepareForWriteA tests\n");
1338 return;
1341 /* directory exists, SHPPFW_NONE */
1342 set_curr_dir_path(path, "testdir2\0");
1343 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
1344 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1346 /* directory exists, SHPPFW_IGNOREFILENAME */
1347 set_curr_dir_path(path, "testdir2\\test4.txt\0");
1348 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
1349 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1351 /* directory exists, SHPPFW_DIRCREATE */
1352 set_curr_dir_path(path, "testdir2\0");
1353 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
1354 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1356 /* directory exists, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
1357 set_curr_dir_path(path, "testdir2\\test4.txt\0");
1358 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
1359 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1360 ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
1362 /* file exists, SHPPFW_NONE */
1363 set_curr_dir_path(path, "test1.txt\0");
1364 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
1365 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_DIRECTORY)\n", res);
1367 /* file exists, SHPPFW_DIRCREATE */
1368 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
1369 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_DIRECTORY)\n", res);
1371 /* file exists, SHPPFW_NONE, trailing \ */
1372 set_curr_dir_path(path, "test1.txt\\\0");
1373 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
1374 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_DIRECTORY)\n", res);
1376 /* relative path exists, SHPPFW_DIRCREATE */
1377 res = pSHPathPrepareForWriteA(0, 0, ".\\testdir2", SHPPFW_DIRCREATE);
1378 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1380 /* relative path doesn't exist, SHPPFW_DIRCREATE -- Windows does not create the directory in this case */
1381 res = pSHPathPrepareForWriteA(0, 0, ".\\testdir2\\test4.txt", SHPPFW_DIRCREATE);
1382 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
1383 ok(!file_exists(".\\testdir2\\test4.txt\\"), ".\\testdir2\\test4.txt\\ exists but shouldn't\n");
1385 /* directory doesn't exist, SHPPFW_NONE */
1386 set_curr_dir_path(path, "nonexistent\0");
1387 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
1388 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
1390 /* directory doesn't exist, SHPPFW_IGNOREFILENAME */
1391 set_curr_dir_path(path, "nonexistent\\notreal\0");
1392 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
1393 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
1394 ok(!file_exists("nonexistent\\notreal"), "nonexistent\\notreal exists but shouldn't\n");
1395 ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
1397 /* directory doesn't exist, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
1398 set_curr_dir_path(path, "testdir2\\test4.txt\\\0");
1399 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
1400 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1401 ok(file_exists("testdir2\\test4.txt\\"), "testdir2\\test4.txt doesn't exist but should\n");
1403 /* nested directory doesn't exist, SHPPFW_DIRCREATE */
1404 set_curr_dir_path(path, "nonexistent\\notreal\0");
1405 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
1406 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1407 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal doesn't exist but should\n");
1409 /* SHPPFW_ASKDIRCREATE, SHPPFW_NOWRITECHECK, and SHPPFW_MEDIACHECKONLY are untested */
1411 if(!pSHPathPrepareForWriteW)
1413 skip("Skipping SHPathPrepareForWriteW tests\n");
1414 return;
1416 /* unicode directory doesn't exist, SHPPFW_NONE */
1417 res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
1418 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == %08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
1419 ok(!file_existsW(UNICODE_PATH), "unicode path was created but shouldn't be\n");
1420 RemoveDirectoryW(UNICODE_PATH);
1422 /* unicode directory doesn't exist, SHPPFW_DIRCREATE */
1423 res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
1424 ok(res == S_OK, "res == %08x, expected S_OK\n", res);
1425 ok(file_existsW(UNICODE_PATH), "unicode path should've been created\n");
1427 /* unicode directory exists, SHPPFW_NONE */
1428 res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
1429 ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
1431 /* unicode directory exists, SHPPFW_DIRCREATE */
1432 res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
1433 ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
1434 RemoveDirectoryW(UNICODE_PATH);
1437 static void test_unicode(void)
1439 SHFILEOPSTRUCTW shfoW;
1440 int ret;
1441 HANDLE file;
1443 if (!pSHFileOperationW)
1445 skip("SHFileOperationW() is missing\n");
1446 return;
1449 shfoW.hwnd = NULL;
1450 shfoW.wFunc = FO_DELETE;
1451 shfoW.pFrom = UNICODE_PATH;
1452 shfoW.pTo = '\0';
1453 shfoW.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1454 shfoW.hNameMappings = NULL;
1455 shfoW.lpszProgressTitle = NULL;
1457 /* Clean up before start test */
1458 DeleteFileW(UNICODE_PATH);
1459 RemoveDirectoryW(UNICODE_PATH);
1461 /* Make sure we are on a system that supports unicode */
1462 SetLastError(0xdeadbeef);
1463 file = CreateFileW(UNICODE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1464 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
1466 skip("Unicode tests skipped on non-unicode system\n");
1467 return;
1469 CloseHandle(file);
1471 /* Try to delete a file with unicode filename */
1472 ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
1473 ret = pSHFileOperationW(&shfoW);
1474 ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
1475 ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
1477 /* Try to trash a file with unicode filename */
1478 createTestFileW(UNICODE_PATH);
1479 shfoW.fFlags |= FOF_ALLOWUNDO;
1480 ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
1481 ret = pSHFileOperationW(&shfoW);
1482 ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
1483 ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
1485 if(!pSHCreateDirectoryExW)
1487 skip("Skipping SHCreateDirectoryExW tests\n");
1488 return;
1491 /* Try to delete a directory with unicode filename */
1492 ret = pSHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
1493 ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
1494 ok(file_existsW(UNICODE_PATH), "The directory is not created\n");
1495 shfoW.fFlags &= ~FOF_ALLOWUNDO;
1496 ret = pSHFileOperationW(&shfoW);
1497 ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
1498 ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
1500 /* Try to trash a directory with unicode filename */
1501 ret = pSHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
1502 ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
1503 ok(file_existsW(UNICODE_PATH), "The directory was not created\n");
1504 shfoW.fFlags |= FOF_ALLOWUNDO;
1505 ret = pSHFileOperationW(&shfoW);
1506 ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
1507 ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
1510 START_TEST(shlfileop)
1512 InitFunctionPointers();
1514 clean_after_shfo_tests();
1516 init_shfo_tests();
1517 test_get_file_info();
1518 test_get_file_info_iconlist();
1519 clean_after_shfo_tests();
1521 init_shfo_tests();
1522 test_delete();
1523 clean_after_shfo_tests();
1525 init_shfo_tests();
1526 test_rename();
1527 clean_after_shfo_tests();
1529 init_shfo_tests();
1530 test_copy();
1531 clean_after_shfo_tests();
1533 init_shfo_tests();
1534 test_move();
1535 clean_after_shfo_tests();
1537 test_sh_create_dir();
1538 clean_after_shfo_tests();
1540 init_shfo_tests();
1541 test_sh_path_prepare();
1542 clean_after_shfo_tests();
1544 test_unicode();