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