shell32/tests: Fix some test failures on NT4 (FO_COPY).
[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 /* Error codes could be pre-Win32 */
36 #define DE_SAMEFILE     0x71
37 #define DE_MANYSRC1DEST 0x72
38 #define DE_OPCANCELLED  0x75
39 #define DE_DESTSUBTREE  0x76
40 #define DE_INVALIDFILES 0x7C
41 #define DE_DESTSAMETREE 0x7D
42 #define expect_retval(ret, ret_prewin32)\
43     ok(retval == ret ||\
44        broken(retval == ret_prewin32),\
45        "Expected %d, got %d\n", ret, retval)
46
47 static CHAR CURR_DIR[MAX_PATH];
48 static const WCHAR UNICODE_PATH[] = {'c',':','\\',0x00c4,'\0','\0'};
49     /* "c:\Ä", or "c:\A" with diaeresis */
50     /* Double-null termination needed for pFrom field of SHFILEOPSTRUCT */
51
52 static HMODULE hshell32;
53 static int (WINAPI *pSHCreateDirectoryExA)(HWND, LPCSTR, LPSECURITY_ATTRIBUTES);
54 static int (WINAPI *pSHCreateDirectoryExW)(HWND, LPCWSTR, LPSECURITY_ATTRIBUTES);
55 static int (WINAPI *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
56 static DWORD_PTR (WINAPI *pSHGetFileInfoW)(LPCWSTR, DWORD , SHFILEINFOW*, UINT, UINT);
57 static int (WINAPI *pSHPathPrepareForWriteA)(HWND, IUnknown*, LPCSTR, DWORD);
58 static int (WINAPI *pSHPathPrepareForWriteW)(HWND, IUnknown*, LPCWSTR, DWORD);
59
60 static void InitFunctionPointers(void)
61 {
62     hshell32 = GetModuleHandleA("shell32.dll");
63     pSHCreateDirectoryExA = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExA");
64     pSHCreateDirectoryExW = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExW");
65     pSHFileOperationW = (void*)GetProcAddress(hshell32, "SHFileOperationW");
66     pSHGetFileInfoW = (void*)GetProcAddress(hshell32, "SHGetFileInfoW");
67     pSHPathPrepareForWriteA = (void*)GetProcAddress(hshell32, "SHPathPrepareForWriteA");
68     pSHPathPrepareForWriteW = (void*)GetProcAddress(hshell32, "SHPathPrepareForWriteW");
69 }
70
71 /* creates a file with the specified name for tests */
72 static void createTestFile(const CHAR *name)
73 {
74     HANDLE file;
75     DWORD written;
76
77     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
78     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
79     WriteFile(file, name, strlen(name), &written, NULL);
80     WriteFile(file, "\n", strlen("\n"), &written, NULL);
81     CloseHandle(file);
82 }
83
84 static void createTestFileW(const WCHAR *name)
85 {
86     HANDLE file;
87
88     file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
89     ok(file != INVALID_HANDLE_VALUE, "Failure to open file\n");
90     CloseHandle(file);
91 }
92
93 static BOOL file_exists(const CHAR *name)
94 {
95     return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
96 }
97
98 static BOOL dir_exists(const CHAR *name)
99 {
100     DWORD attr;
101     BOOL dir;
102
103     attr = GetFileAttributesA(name);
104     dir = ((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
105
106     return ((attr != INVALID_FILE_ATTRIBUTES) && dir);
107 }
108
109 static BOOL file_existsW(LPCWSTR name)
110 {
111   return GetFileAttributesW(name) != INVALID_FILE_ATTRIBUTES;
112 }
113
114 static BOOL file_has_content(const CHAR *name, const CHAR *content)
115 {
116     CHAR buf[MAX_PATH];
117     HANDLE file;
118     DWORD read;
119
120     file = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
121     if (file == INVALID_HANDLE_VALUE)
122         return FALSE;
123     ReadFile(file, buf, MAX_PATH - 1, &read, NULL);
124     buf[read] = 0;
125     CloseHandle(file);
126     return strcmp(buf, content)==0;
127 }
128
129 /* initializes the tests */
130 static void init_shfo_tests(void)
131 {
132     int len;
133
134     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
135     len = lstrlenA(CURR_DIR);
136
137     if(len && (CURR_DIR[len-1] == '\\'))
138         CURR_DIR[len-1] = 0;
139
140     createTestFile("test1.txt");
141     createTestFile("test2.txt");
142     createTestFile("test3.txt");
143     createTestFile("test_5.txt");
144     CreateDirectoryA("test4.txt", NULL);
145     CreateDirectoryA("testdir2", NULL);
146     CreateDirectoryA("testdir2\\nested", NULL);
147     createTestFile("testdir2\\one.txt");
148     createTestFile("testdir2\\nested\\two.txt");
149 }
150
151 /* cleans after tests */
152 static void clean_after_shfo_tests(void)
153 {
154     DeleteFileA("test1.txt");
155     DeleteFileA("test2.txt");
156     DeleteFileA("test3.txt");
157     DeleteFileA("test_5.txt");
158     DeleteFileA("one.txt");
159     DeleteFileA("test4.txt\\test1.txt");
160     DeleteFileA("test4.txt\\test2.txt");
161     DeleteFileA("test4.txt\\test3.txt");
162     RemoveDirectoryA("test4.txt");
163     DeleteFileA("testdir2\\one.txt");
164     DeleteFileA("testdir2\\test1.txt");
165     DeleteFileA("testdir2\\test2.txt");
166     DeleteFileA("testdir2\\test3.txt");
167     DeleteFileA("testdir2\\test4.txt\\test1.txt");
168     DeleteFileA("testdir2\\nested\\two.txt");
169     RemoveDirectoryA("testdir2\\test4.txt");
170     RemoveDirectoryA("testdir2\\nested");
171     RemoveDirectoryA("testdir2");
172     RemoveDirectoryA("c:\\testdir3");
173     DeleteFileA("nonexistent\\notreal\\test2.txt");
174     RemoveDirectoryA("nonexistent\\notreal");
175     RemoveDirectoryA("nonexistent");
176 }
177
178
179 static void test_get_file_info(void)
180 {
181     DWORD rc, rc2;
182     SHFILEINFOA shfi, shfi2;
183     SHFILEINFOW shfiw;
184     char notepad[MAX_PATH];
185
186     /* Test whether fields of SHFILEINFOA are always cleared */
187     memset(&shfi, 0xcf, sizeof(shfi));
188     rc=SHGetFileInfoA("", 0, &shfi, sizeof(shfi), 0);
189     ok(rc, "SHGetFileInfoA('' | 0) should not fail\n");
190     todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA('' | 0) did not clear hIcon\n");
191     todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szDisplayName[0]\n");
192     todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szTypeName[0]\n");
193     ok(shfi.iIcon == 0xcfcfcfcf, "SHGetFileInfoA('' | 0) should not clear iIcon\n");
194     ok(shfi.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoA('' | 0) should not clear dwAttributes\n");
195
196     if (pSHGetFileInfoW)
197     {
198         /* Test whether fields of SHFILEINFOW are always cleared */
199         memset(&shfiw, 0xcf, sizeof(shfiw));
200         rc=pSHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0);
201         todo_wine ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n");
202         ok(shfiw.hIcon == (HANDLE) 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear hIcon\n");
203         todo_wine ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n");
204         todo_wine ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n");
205         todo_wine ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n");
206         ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear dwAttributes\n");
207     }
208     else
209         win_skip("SHGetFileInfoW is not available\n");
210
211
212     /* Test some flag combinations that MSDN claims are not allowed,
213      * but which work anyway
214      */
215     memset(&shfi, 0xcf, sizeof(shfi));
216     rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
217                       &shfi, sizeof(shfi),
218                       SHGFI_ATTRIBUTES | SHGFI_USEFILEATTRIBUTES);
219     ok(rc, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) failed\n");
220     if (rc)
221         ok(shfi.dwAttributes != 0xcfcfcfcf, "dwFileAttributes is not set\n");
222     todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear hIcon\n");
223     todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szDisplayName[0]\n");
224     todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szTypeName[0]\n");
225     ok(shfi.iIcon == 0xcfcfcfcf, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) should not clear iIcon\n");
226
227     rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
228                       &shfi, sizeof(shfi),
229                       SHGFI_EXETYPE | SHGFI_USEFILEATTRIBUTES);
230     todo_wine ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_EXETYPE) returned %d\n", rc);
231
232     /* Test SHGFI_USEFILEATTRIBUTES support */
233     strcpy(shfi.szDisplayName, "dummy");
234     shfi.iIcon=0xdeadbeef;
235     rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
236                       &shfi, sizeof(shfi),
237                       SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
238     ok(rc, "SHGetFileInfoA(c:\\nonexistent) failed\n");
239     if (rc)
240     {
241         ok(strcpy(shfi.szDisplayName, "dummy") != 0, "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n");
242         ok(shfi.iIcon != 0xdeadbeef, "SHGetFileInfoA(c:\\nonexistent) iIcon is not set\n");
243     }
244
245     /* Wine does not have a default icon for text files, and Windows 98 fails
246      * if we give it an empty executable. So use notepad.exe as the test
247      */
248     if (SearchPath(NULL, "notepad.exe", NULL, sizeof(notepad), notepad, NULL))
249     {
250         strcpy(shfi.szDisplayName, "dummy");
251         shfi.iIcon=0xdeadbeef;
252         rc=SHGetFileInfoA(notepad, GetFileAttributes(notepad),
253                           &shfi, sizeof(shfi),
254                           SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
255         ok(rc, "SHGetFileInfoA(%s, SHGFI_USEFILEATTRIBUTES) failed\n", notepad);
256         strcpy(shfi2.szDisplayName, "dummy");
257         shfi2.iIcon=0xdeadbeef;
258         rc2=SHGetFileInfoA(notepad, 0,
259                            &shfi2, sizeof(shfi2),
260                            SHGFI_ICONLOCATION);
261         ok(rc2, "SHGetFileInfoA(%s) failed\n", notepad);
262         if (rc && rc2)
263         {
264             ok(lstrcmpi(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
265             ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
266         }
267     }
268
269     /* with a directory now */
270     strcpy(shfi.szDisplayName, "dummy");
271     shfi.iIcon=0xdeadbeef;
272     rc=SHGetFileInfoA("test4.txt", GetFileAttributes("test4.txt"),
273                       &shfi, sizeof(shfi),
274                       SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
275     ok(rc, "SHGetFileInfoA(test4.txt/, SHGFI_USEFILEATTRIBUTES) failed\n");
276     strcpy(shfi2.szDisplayName, "dummy");
277     shfi2.iIcon=0xdeadbeef;
278     rc2=SHGetFileInfoA("test4.txt", 0,
279                       &shfi2, sizeof(shfi2),
280                       SHGFI_ICONLOCATION);
281     ok(rc2, "SHGetFileInfoA(test4.txt/) failed\n");
282     if (rc && rc2)
283     {
284         ok(lstrcmpi(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
285         ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
286     }
287 }
288
289 static void test_get_file_info_iconlist(void)
290 {
291     /* Test retrieving a handle to the system image list, and
292      * what that returns for hIcon
293      */
294     HRESULT hr;
295     HIMAGELIST hSysImageList;
296     LPITEMIDLIST pidList;
297     SHFILEINFOA shInfoa;
298     SHFILEINFOW shInfow;
299
300     hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidList);
301     if (FAILED(hr)) {
302          skip("can't get desktop pidl\n");
303          return;
304     }
305
306     memset(&shInfoa, 0xcf, sizeof(shInfoa));
307     hSysImageList = (HIMAGELIST) SHGetFileInfoA((const char *)pidList, 0,
308             &shInfoa, sizeof(shInfoa),
309             SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
310     ok(hSysImageList != INVALID_HANDLE_VALUE, "Can't get handle for CSIDL_DESKTOP imagelist\n");
311     todo_wine ok(shInfoa.hIcon == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
312     todo_wine ok(shInfoa.szTypeName[0] == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
313     ok(shInfoa.iIcon != 0xcfcfcfcf, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
314     ok(shInfoa.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should not change dwAttributes\n");
315     CloseHandle(hSysImageList);
316
317     if (!pSHGetFileInfoW)
318     {
319         win_skip("SHGetFileInfoW is not available\n");
320         ILFree(pidList);
321         return;
322     }
323
324     memset(&shInfow, 0xcf, sizeof(shInfow));
325     hSysImageList = (HIMAGELIST) pSHGetFileInfoW((const WCHAR *)pidList, 0,
326             &shInfow, sizeof(shInfow),
327             SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
328     if (!hSysImageList)
329     {
330         win_skip("SHGetFileInfoW is not implemented\n");
331         return;
332     }
333     ok(hSysImageList != INVALID_HANDLE_VALUE, "Can't get handle for CSIDL_DESKTOP imagelist\n");
334     todo_wine ok(shInfow.hIcon == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
335     ok(shInfow.szTypeName[0] == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
336     ok(shInfow.iIcon != 0xcfcfcfcf, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
337     ok(shInfow.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should not change dwAttributes\n");
338     CloseHandle(hSysImageList);
339
340     /* Various suposidly invalid flag testing */
341     memset(&shInfow, 0xcf, sizeof(shInfow));
342     hr =  pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
343             SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
344     ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
345     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
346     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
347
348     memset(&shInfow, 0xcf, sizeof(shInfow));
349     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
350             SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
351     ok(hr != 0, " SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
352     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
353     ok(shInfow.hIcon!=(HICON)0xcfcfcfcf && shInfow.hIcon!=0,"hIcon invalid\n");
354     if (shInfow.hIcon!=(HICON)0xcfcfcfcf) DestroyIcon(shInfow.hIcon);
355     todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
356
357     memset(&shInfow, 0xcf, sizeof(shInfow));
358     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
359             SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
360     ok(hr != 0, "SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON Failed\n");
361     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
362     ok(shInfow.hIcon!=(HICON)0xcfcfcfcf && shInfow.hIcon!=0,"hIcon invalid\n");
363     if (shInfow.hIcon != (HICON)0xcfcfcfcf) DestroyIcon(shInfow.hIcon);
364     todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
365
366     memset(&shInfow, 0xcf, sizeof(shInfow));
367     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
368             SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
369     ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON Failed\n");
370     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
371     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
372
373     memset(&shInfow, 0xcf, sizeof(shInfow));
374     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
375             SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
376     ok(hr != 0, "SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
377     todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
378     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
379
380     memset(&shInfow, 0xcf, sizeof(shInfow));
381     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
382             SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
383     ok(hr != 0, "SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
384     todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
385     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
386
387     memset(&shInfow, 0xcf, sizeof(shInfow));
388     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
389             SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
390     ok(hr != 0, "SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
391     todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
392     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
393
394     memset(&shInfow, 0xcf, sizeof(shInfow));
395     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
396             SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
397         SHGFI_ATTRIBUTES);
398     ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES Failed\n");
399     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
400     ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
401
402     memset(&shInfow, 0xcf, sizeof(shInfow));
403     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
404             SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
405         SHGFI_EXETYPE);
406     todo_wine ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE Failed\n");
407     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
408     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
409
410     memset(&shInfow, 0xcf, sizeof(shInfow));
411     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
412         SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE);
413     todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE Failed\n");
414     todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
415     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
416
417     memset(&shInfow, 0xcf, sizeof(shInfow));
418     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
419         SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES);
420     ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES Failed\n");
421     todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
422     ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
423
424     memset(&shInfow, 0xcf, sizeof(shInfow));
425     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
426             SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|
427         SHGFI_ATTRIBUTES);
428     ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
429     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
430     ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
431
432     memset(&shInfow, 0xcf, sizeof(shInfow));
433     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
434         SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
435     todo_wine ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE Failed\n");
436     ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
437     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
438
439     memset(&shInfow, 0xcf, sizeof(shInfow));
440     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
441         SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
442     todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE Failed\n");
443     todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
444     ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
445
446     memset(&shInfow, 0xcf, sizeof(shInfow));
447     hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
448         SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES);
449     ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
450     todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
451     ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
452
453     ILFree(pidList);
454 }
455
456
457 /*
458  puts into the specified buffer file names with current directory.
459  files - string with file names, separated by null characters. Ends on a double
460  null characters
461 */
462 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
463 {
464     buf[0] = 0;
465     while (files[0])
466     {
467         strcpy(buf, CURR_DIR);
468         buf += strlen(buf);
469         buf[0] = '\\';
470         buf++;
471         strcpy(buf, files);
472         buf += strlen(buf) + 1;
473         files += strlen(files) + 1;
474     }
475     buf[0] = 0;
476 }
477
478
479 /* tests the FO_DELETE action */
480 static void test_delete(void)
481 {
482     SHFILEOPSTRUCTA shfo;
483     DWORD ret;
484     CHAR buf[sizeof(CURR_DIR)+sizeof("/test?.txt")+1];
485
486     sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
487     buf[strlen(buf) + 1] = '\0';
488
489     shfo.hwnd = NULL;
490     shfo.wFunc = FO_DELETE;
491     shfo.pFrom = buf;
492     shfo.pTo = "\0";
493     shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
494     shfo.hNameMappings = NULL;
495     shfo.lpszProgressTitle = NULL;
496
497     ok(!SHFileOperationA(&shfo), "Deletion was not successful\n");
498     ok(file_exists("test4.txt"), "Directory should not have been removed\n");
499     ok(!file_exists("test1.txt"), "File should have been removed\n");
500
501     ret = SHFileOperationA(&shfo);
502     ok(!ret, "Directory exists, but is not removed, ret=%d\n", ret);
503     ok(file_exists("test4.txt"), "Directory should not have been removed\n");
504
505     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
506
507     ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
508     ok(!file_exists("test4.txt"), "Directory should have been removed\n");
509
510     ret = SHFileOperationA(&shfo);
511     ok(!ret, "The requested file does not exist, ret=%d\n", ret);
512
513     init_shfo_tests();
514     sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
515     buf[strlen(buf) + 1] = '\0';
516     ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Filling the subdirectory failed\n");
517     ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
518     ok(!file_exists("test4.txt"), "Directory is not removed\n");
519
520     init_shfo_tests();
521     shfo.pFrom = "test1.txt\0test4.txt\0";
522     ok(!SHFileOperationA(&shfo), "Directory and a file are not removed\n");
523     ok(!file_exists("test1.txt"), "The file should have been removed\n");
524     ok(!file_exists("test4.txt"), "Directory should have been removed\n");
525     ok(file_exists("test2.txt"), "This file should not have been removed\n");
526
527     /* FOF_FILESONLY does not delete a dir matching a wildcard */
528     init_shfo_tests();
529     shfo.fFlags |= FOF_FILESONLY;
530     shfo.pFrom = "*.txt\0";
531     ok(!SHFileOperation(&shfo), "Failed to delete files\n");
532     ok(!file_exists("test1.txt"), "test1.txt should have been removed\n");
533     ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
534     ok(file_exists("test4.txt"), "test4.txt should not have been removed\n");
535
536     /* FOF_FILESONLY only deletes a dir if explicitly specified */
537     init_shfo_tests();
538     shfo.pFrom = "test_?.txt\0test4.txt\0";
539     ok(!SHFileOperation(&shfo), "Failed to delete files and directory\n");
540     ok(!file_exists("test4.txt"), "test4.txt should have been removed\n");
541     ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
542     ok(file_exists("test1.txt"), "test1.txt should not have been removed\n");
543
544     /* try to delete an invalid filename */
545     if (0) {
546         /* this crashes on win9x */
547         init_shfo_tests();
548         shfo.pFrom = "\0";
549         shfo.fFlags &= ~FOF_FILESONLY;
550         shfo.fAnyOperationsAborted = FALSE;
551         ret = SHFileOperation(&shfo);
552         ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", ret);
553         ok(!shfo.fAnyOperationsAborted, "Expected no aborted operations\n");
554         ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
555     }
556
557     /* try an invalid function */
558     init_shfo_tests();
559     shfo.pFrom = "test1.txt\0";
560     shfo.wFunc = 0;
561     ret = SHFileOperation(&shfo);
562     ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret);
563     ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
564
565     /* try an invalid list, only one null terminator */
566     if (0) {
567         /* this crashes on win9x */
568         init_shfo_tests();
569         shfo.pFrom = "";
570         shfo.wFunc = FO_DELETE;
571         ret = SHFileOperation(&shfo);
572         ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", ret);
573         ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
574     }
575
576     /* delete a dir, and then a file inside the dir, same as
577     * deleting a nonexistent file
578     *
579     * FIXME: Vista throws up a dialog window to ask if one.txt should be created
580     */
581     init_shfo_tests();
582     shfo.pFrom = "testdir2\0testdir2\\one.txt\0";
583     shfo.wFunc = FO_DELETE;
584     ret = SHFileOperation(&shfo);
585     ok(ret == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", ret);
586     ok(!file_exists("testdir2"), "Expected testdir2 to not exist\n");
587     ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
588
589     /* try the FOF_NORECURSION flag, continues deleting subdirs */
590     init_shfo_tests();
591     shfo.pFrom = "testdir2\0";
592     shfo.fFlags |= FOF_NORECURSION;
593     ret = SHFileOperation(&shfo);
594     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
595     ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
596     ok(!file_exists("testdir2\\nested"), "Expected testdir2\\nested to exist\n");
597 }
598
599 /* tests the FO_RENAME action */
600 static void test_rename(void)
601 {
602     SHFILEOPSTRUCTA shfo, shfo2;
603     CHAR from[5*MAX_PATH];
604     CHAR to[5*MAX_PATH];
605     DWORD retval;
606
607     shfo.hwnd = NULL;
608     shfo.wFunc = FO_RENAME;
609     shfo.pFrom = from;
610     shfo.pTo = to;
611     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
612     shfo.hNameMappings = NULL;
613     shfo.lpszProgressTitle = NULL;
614
615     set_curr_dir_path(from, "test1.txt\0");
616     set_curr_dir_path(to, "test4.txt\0");
617     ok(SHFileOperationA(&shfo), "File is not renamed moving to other directory "
618        "when specifying directory name only\n");
619     ok(file_exists("test1.txt"), "The file is removed\n");
620
621     set_curr_dir_path(from, "test3.txt\0");
622     set_curr_dir_path(to, "test4.txt\\test1.txt\0");
623     ok(!SHFileOperationA(&shfo), "File is renamed moving to other directory\n");
624     ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
625
626     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
627     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
628     retval = SHFileOperationA(&shfo); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
629     ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
630        "Can't rename many files, retval = %d\n", retval);
631     ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
632
633     memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
634     shfo2.fFlags |= FOF_MULTIDESTFILES;
635
636     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
637     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
638     retval = SHFileOperationA(&shfo2); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
639     ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
640        "Can't rename many files, retval = %d\n", retval);
641     ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
642
643     set_curr_dir_path(from, "test1.txt\0");
644     set_curr_dir_path(to, "test6.txt\0");
645     retval = SHFileOperationA(&shfo);
646     ok(!retval, "Rename file failed, retval = %d\n", retval);
647     ok(!file_exists("test1.txt"), "The file is not renamed\n");
648     ok(file_exists("test6.txt"), "The file is not renamed\n");
649
650     set_curr_dir_path(from, "test6.txt\0");
651     set_curr_dir_path(to, "test1.txt\0");
652     retval = SHFileOperationA(&shfo);
653     ok(!retval, "Rename file back failed, retval = %d\n", retval);
654
655     set_curr_dir_path(from, "test4.txt\0");
656     set_curr_dir_path(to, "test6.txt\0");
657     retval = SHFileOperationA(&shfo);
658     ok(!retval, "Rename dir failed, retval = %d\n", retval);
659     ok(!file_exists("test4.txt"), "The dir is not renamed\n");
660     ok(file_exists("test6.txt"), "The dir is not renamed\n");
661
662     set_curr_dir_path(from, "test6.txt\0");
663     set_curr_dir_path(to, "test4.txt\0");
664     retval = SHFileOperationA(&shfo);
665     ok(!retval, "Rename dir back failed, retval = %d\n", retval);
666
667     /* try to rename more than one file to a single file */
668     shfo.pFrom = "test1.txt\0test2.txt\0";
669     shfo.pTo = "a.txt\0";
670     retval = SHFileOperationA(&shfo);
671     ok(retval == ERROR_GEN_FAILURE ||
672        retval == DE_MANYSRC1DEST || /* Vista */
673        broken(!retval), /* Win9x */
674        "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST, got %d\n", retval);
675     ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
676     ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
677     ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
678
679     /* pFrom doesn't exist */
680     shfo.pFrom = "idontexist\0";
681     shfo.pTo = "newfile\0";
682     retval = SHFileOperationA(&shfo);
683     ok(retval == 1026 ||
684        retval == ERROR_FILE_NOT_FOUND, /* Vista */
685        "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", retval);
686     ok(!file_exists("newfile"), "Expected newfile to not exist\n");
687
688     /* pTo already exist */
689     shfo.pFrom = "test1.txt\0";
690     shfo.pTo = "test2.txt\0";
691     retval = SHFileOperationA(&shfo);
692         ok(retval == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %d\n", retval);
693
694     /* pFrom is valid, but pTo is empty */
695     shfo.pFrom = "test1.txt\0";
696     shfo.pTo = "\0";
697     retval = SHFileOperationA(&shfo);
698     expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x */);
699     ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
700
701     /* pFrom is empty */
702     shfo.pFrom = "\0";
703     retval = SHFileOperationA(&shfo);
704     ok(retval == ERROR_ACCESS_DENIED ||
705        retval == ERROR_INVALID_TARGET_HANDLE, /* Vista */
706        "Expected ERROR_ACCESS_DENIED or ERROR_INVALID_TARGET_HANDLE, got %d\n", retval);
707
708     /* pFrom is NULL, commented out because it crashes on nt 4.0 */
709 #if 0
710     shfo.pFrom = NULL;
711     retval = SHFileOperationA(&shfo);
712     ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", retval);
713 #endif
714 }
715
716 /* tests the FO_COPY action */
717 static void test_copy(void)
718 {
719     SHFILEOPSTRUCTA shfo, shfo2;
720     CHAR from[5*MAX_PATH];
721     CHAR to[5*MAX_PATH];
722     FILEOP_FLAGS tmp_flags;
723     DWORD retval;
724     LPSTR ptr;
725     BOOL on_nt4 = FALSE;
726
727     shfo.hwnd = NULL;
728     shfo.wFunc = FO_COPY;
729     shfo.pFrom = from;
730     shfo.pTo = to;
731     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
732     shfo.hNameMappings = NULL;
733     shfo.lpszProgressTitle = NULL;
734
735     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
736     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
737     retval = SHFileOperationA(&shfo);
738     if (dir_exists("test6.txt"))
739     {
740         /* Vista and W2K8 (broken or new behavior ?) */
741         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
742         ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files "
743            "are specified as a target\n");
744         DeleteFileA("test6.txt\\test2.txt");
745         RemoveDirectoryA("test6.txt\\test4.txt");
746         RemoveDirectoryA("test6.txt");
747     }
748     else
749     {
750         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
751         ok(!file_exists("test6.txt"), "The file is copied - many files are "
752            "specified as a target\n");
753     }
754
755     memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
756     shfo2.fFlags |= FOF_MULTIDESTFILES;
757
758     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
759     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
760     ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
761     ok(file_exists("test6.txt"), "The file is not copied - many files are "
762        "specified as a target\n");
763     DeleteFileA("test6.txt");
764     DeleteFileA("test7.txt");
765     RemoveDirectoryA("test8.txt");
766
767     /* number of sources do not correspond to number of targets */
768     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
769     set_curr_dir_path(to, "test6.txt\0test7.txt\0");
770     retval = SHFileOperationA(&shfo2);
771     if (dir_exists("test6.txt"))
772     {
773         /* Vista and W2K8 (broken or new behavior ?) */
774         ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %d\n", retval);
775         ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files "
776            "are specified as a target\n");
777         RemoveDirectoryA("test6.txt");
778         ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not copied - many files "
779            "are specified as a target\n");
780         RemoveDirectoryA("test7.txt");
781     }
782     else
783     {
784         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
785         ok(!file_exists("test6.txt"), "The file is copied - many files are "
786            "specified as a target\n");
787     }
788
789     set_curr_dir_path(from, "test1.txt\0");
790     set_curr_dir_path(to, "test4.txt\0");
791     ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
792     ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
793
794     set_curr_dir_path(from, "test?.txt\0");
795     set_curr_dir_path(to, "testdir2\0");
796     ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
797     ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
798     ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
799     ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
800     ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
801     ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
802     clean_after_shfo_tests();
803
804     init_shfo_tests();
805     shfo.fFlags |= FOF_FILESONLY;
806     ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
807     ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
808     ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
809     ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
810     ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
811     clean_after_shfo_tests();
812
813     init_shfo_tests();
814     set_curr_dir_path(from, "test1.txt\0test2.txt\0");
815     ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
816     ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
817     ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
818     ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
819     ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
820     clean_after_shfo_tests();
821
822     /* Copying multiple files with one not existing as source, fails the
823        entire operation in Win98/ME/2K/XP, but not in 95/NT */
824     init_shfo_tests();
825     tmp_flags = shfo.fFlags;
826     set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
827     ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
828     ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
829     retval = SHFileOperationA(&shfo);
830     if (retval == ERROR_SUCCESS)
831         /* Win 95/NT returns success but copies only the files up to the nonexistent source */
832         ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
833     else
834     {
835         /* Failure if one source file does not exist */
836         ok(retval == 1026 || /* Win 98/ME/2K/XP */
837            retval == ERROR_FILE_NOT_FOUND, /* Vista and W2K8 */
838            "Files are copied to other directory\n");
839         ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
840     }
841     ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
842     shfo.fFlags = tmp_flags;
843
844     /* copy into a nonexistent directory */
845     init_shfo_tests();
846     shfo.fFlags = FOF_NOCONFIRMMKDIR;
847     set_curr_dir_path(from, "test1.txt\0");
848     set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
849     retval= SHFileOperation(&shfo);
850     ok(!retval, "Error copying into nonexistent directory\n");
851     ok(file_exists("nonexistent"), "nonexistent not created\n");
852     ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
853     ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
854     ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
855
856     /* a relative dest directory is OK */
857     clean_after_shfo_tests();
858     init_shfo_tests();
859     shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
860     shfo.pTo = "testdir2\0";
861     retval = SHFileOperation(&shfo);
862     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
863     ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
864
865     /* try to copy files to a file */
866     clean_after_shfo_tests();
867     init_shfo_tests();
868     shfo.pFrom = from;
869     shfo.pTo = to;
870     /* suppress the error-dialog in win9x here */
871     shfo.fFlags |= FOF_NOERRORUI;
872     set_curr_dir_path(from, "test1.txt\0test2.txt\0");
873     set_curr_dir_path(to, "test3.txt\0");
874     retval = SHFileOperation(&shfo);
875     expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
876     ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
877     ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
878
879     /* try to copy many files to nonexistent directory */
880     DeleteFile(to);
881     shfo.fFlags &= ~FOF_NOERRORUI;
882     shfo.fAnyOperationsAborted = FALSE;
883     retval = SHFileOperation(&shfo);
884     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
885     ok(DeleteFile("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
886     ok(DeleteFile("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
887     ok(RemoveDirectory(to), "Expected test3.txt to exist\n");
888
889     /* send in FOF_MULTIDESTFILES with too many destination files */
890     init_shfo_tests();
891     shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
892     shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
893     shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
894     retval = SHFileOperation(&shfo);
895     if (dir_exists("testdir2\\a.txt"))
896     {
897         /* Vista and W2K8 (broken or new behavior ?) */
898         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
899         ok(DeleteFile("testdir2\\a.txt\\test1.txt"), "Expected testdir2\\a.txt\\test1.txt to exist\n");
900         RemoveDirectory("testdir2\\a.txt");
901         ok(DeleteFile("testdir2\\b.txt\\test2.txt"), "Expected testdir2\\b.txt\\test2.txt to exist\n");
902         RemoveDirectory("testdir2\\b.txt");
903         ok(DeleteFile("testdir2\\c.txt\\test3.txt"), "Expected testdir2\\c.txt\\test3.txt to exist\n");
904         RemoveDirectory("testdir2\\c.txt");
905         ok(!file_exists("testdir2\\d.txt"), "Expected testdir2\\d.txt to not exist\n");
906     }
907     else
908     {
909         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
910         ok(shfo.fAnyOperationsAborted ||
911            broken(!shfo.fAnyOperationsAborted), /* NT4 */
912            "Expected aborted operations\n");
913         ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
914     }
915
916     /* send in FOF_MULTIDESTFILES with too many destination files */
917     shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
918     shfo.pTo = "e.txt\0f.txt\0";
919     shfo.fAnyOperationsAborted = FALSE;
920     retval = SHFileOperation(&shfo);
921     if (dir_exists("e.txt"))
922     {
923         /* Vista and W2K8 (broken or new behavior ?) */
924         ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
925         ok(DeleteFile("e.txt\\test1.txt"), "Expected e.txt\\test1.txt to exist\n");
926         RemoveDirectory("e.txt");
927         ok(DeleteFile("f.txt\\test2.txt"), "Expected f.txt\\test2.txt to exist\n");
928         RemoveDirectory("f.txt");
929     }
930     else
931     {
932         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
933         ok(shfo.fAnyOperationsAborted ||
934            broken(!shfo.fAnyOperationsAborted), /* NT4 */
935            "Expected aborted operations\n");
936         ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
937     }
938
939     /* use FOF_MULTIDESTFILES with files and a source directory */
940     shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
941     shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
942     shfo.fAnyOperationsAborted = FALSE;
943     retval = SHFileOperation(&shfo);
944     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
945     ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
946     ok(DeleteFile("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
947     ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
948
949     /* try many dest files without FOF_MULTIDESTFILES flag */
950     shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
951     shfo.pTo = "a.txt\0b.txt\0c.txt\0";
952     shfo.fAnyOperationsAborted = FALSE;
953     shfo.fFlags &= ~FOF_MULTIDESTFILES;
954     retval = SHFileOperation(&shfo);
955     if (dir_exists("a.txt"))
956     {
957         /* Vista and W2K8 (broken or new behavior ?) */
958         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
959         ok(DeleteFile("a.txt\\test1.txt"), "Expected a.txt\\test1.txt to exist\n");
960         ok(DeleteFile("a.txt\\test2.txt"), "Expected a.txt\\test2.txt to exist\n");
961         ok(DeleteFile("a.txt\\test3.txt"), "Expected a.txt\\test3.txt to exist\n");
962         RemoveDirectory("a.txt");
963     }
964     else
965     {
966         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
967         ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
968     }
969
970     /* try a glob */
971     shfo.pFrom = "test?.txt\0";
972     shfo.pTo = "testdir2\0";
973     shfo.fFlags &= ~FOF_MULTIDESTFILES;
974     retval = SHFileOperation(&shfo);
975     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
976     ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
977
978     /* try a glob with FOF_FILESONLY */
979     clean_after_shfo_tests();
980     init_shfo_tests();
981     shfo.pFrom = "test?.txt\0";
982     shfo.fFlags |= FOF_FILESONLY;
983     retval = SHFileOperation(&shfo);
984     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
985     ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
986     ok(!dir_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
987
988     /* try a glob with FOF_MULTIDESTFILES and the same number
989     * of dest files that we would expect
990     */
991     clean_after_shfo_tests();
992     init_shfo_tests();
993     shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
994     shfo.fFlags &= ~FOF_FILESONLY;
995     shfo.fFlags |= FOF_MULTIDESTFILES;
996     retval = SHFileOperation(&shfo);
997     if (dir_exists("testdir2\\a.txt"))
998     {
999         /* Vista and W2K8 (broken or new behavior ?) */
1000         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1001         ok(DeleteFile("testdir2\\a.txt\\test1.txt"), "Expected testdir2\\a.txt\\test1.txt to exist\n");
1002         ok(DeleteFile("testdir2\\a.txt\\test2.txt"), "Expected testdir2\\a.txt\\test2.txt to exist\n");
1003         ok(DeleteFile("testdir2\\a.txt\\test3.txt"), "Expected testdir2\\a.txt\\test3.txt to exist\n");
1004         ok(RemoveDirectory("testdir2\\a.txt\\test4.txt"), "Expected testdir2\\a.txt\\test4.txt to exist\n");
1005         RemoveDirectory("testdir2\\a.txt");
1006     }
1007     else
1008     {
1009         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1010         ok(shfo.fAnyOperationsAborted ||
1011            broken(!shfo.fAnyOperationsAborted), /* NT4 */
1012            "Expected aborted operations\n");
1013         ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
1014     }
1015     ok(!RemoveDirectory("b.txt"), "b.txt should not exist\n");
1016
1017     /* copy one file to two others, second is ignored */
1018     clean_after_shfo_tests();
1019     init_shfo_tests();
1020     shfo.pFrom = "test1.txt\0";
1021     shfo.pTo = "b.txt\0c.txt\0";
1022     shfo.fAnyOperationsAborted = FALSE;
1023     retval = SHFileOperation(&shfo);
1024     if (retval == DE_OPCANCELLED)
1025     {
1026         /* NT4 fails and doesn't copy any files */
1027         ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1028         /* Needed to skip some tests */
1029         win_skip("Skipping some tests on NT4\n");
1030         on_nt4 = TRUE;
1031     }
1032     else
1033     {
1034         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1035         ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
1036     }
1037     ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
1038
1039     /* copy two file to three others, all fail */
1040     shfo.pFrom = "test1.txt\0test2.txt\0";
1041     shfo.pTo = "b.txt\0c.txt\0d.txt\0";
1042     retval = SHFileOperation(&shfo);
1043     if (dir_exists("b.txt"))
1044     {
1045         /* Vista and W2K8 (broken or new behavior ?) */
1046         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1047         ok(DeleteFile("b.txt\\test1.txt"), "Expected b.txt\\test1.txt to exist\n");
1048         RemoveDirectory("b.txt");
1049         ok(DeleteFile("c.txt\\test2.txt"), "Expected c.txt\\test2.txt to exist\n");
1050         RemoveDirectory("c.txt");
1051     }
1052     else
1053     {
1054         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1055         ok(shfo.fAnyOperationsAborted ||
1056            broken(!shfo.fAnyOperationsAborted), /* NT4 */
1057            "Expected aborted operations\n");
1058         ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
1059     }
1060
1061     /* copy one file and one directory to three others */
1062     shfo.pFrom = "test1.txt\0test4.txt\0";
1063     shfo.pTo = "b.txt\0c.txt\0d.txt\0";
1064     shfo.fAnyOperationsAborted = FALSE;
1065     retval = SHFileOperation(&shfo);
1066     if (dir_exists("b.txt"))
1067     {
1068         /* Vista and W2K8 (broken or new behavior ?) */
1069         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1070         ok(DeleteFile("b.txt\\test1.txt"), "Expected b.txt\\test1.txt to exist\n");
1071         RemoveDirectory("b.txt");
1072         ok(RemoveDirectory("c.txt\\test4.txt"), "Expected c.txt\\test4.txt to exist\n");
1073         RemoveDirectory("c.txt");
1074     }
1075     else
1076     {
1077         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1078         ok(shfo.fAnyOperationsAborted ||
1079            broken(!shfo.fAnyOperationsAborted), /* NT4 */
1080            "Expected aborted operations\n");
1081         ok(!DeleteFile("b.txt"), "Expected b.txt to not exist\n");
1082         ok(!DeleteFile("c.txt"), "Expected c.txt to not exist\n");
1083     }
1084
1085     /* copy a directory with a file beneath it, plus some files */
1086     createTestFile("test4.txt\\a.txt");
1087     shfo.pFrom = "test4.txt\0test1.txt\0";
1088     shfo.pTo = "testdir2\0";
1089     shfo.fFlags &= ~FOF_MULTIDESTFILES;
1090     shfo.fAnyOperationsAborted = FALSE;
1091     retval = SHFileOperation(&shfo);
1092     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1093     ok(DeleteFile("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1094     ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
1095     ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
1096
1097     /* copy one directory and a file in that dir to another dir */
1098     shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
1099     shfo.pTo = "testdir2\0";
1100     retval = SHFileOperation(&shfo);
1101     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1102     ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
1103     ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
1104
1105     /* copy a file in a directory first, and then the directory to a nonexistent dir */
1106     shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
1107     shfo.pTo = "nonexistent\0";
1108     retval = SHFileOperation(&shfo);
1109     if (dir_exists("nonexistent"))
1110     {
1111         /* Vista and W2K8 (broken or new behavior ?) */
1112         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1113         ok(DeleteFile("nonexistent\\test4.txt\\a.txt"), "Expected nonexistent\\test4.txt\\a.txt to exist\n");
1114         RemoveDirectory("nonexistent\\test4.txt");
1115         ok(DeleteFile("nonexistent\\a.txt"), "Expected nonexistent\\a.txt to exist\n");
1116         RemoveDirectory("nonexistent");
1117     }
1118     else
1119     {
1120         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1121         ok(shfo.fAnyOperationsAborted ||
1122            broken(!shfo.fAnyOperationsAborted), /* NT4 */
1123            "Expected aborted operations\n");
1124         ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
1125     }
1126     DeleteFile("test4.txt\\a.txt");
1127
1128     /* destination is same as source file */
1129     shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1130     shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
1131     shfo.fAnyOperationsAborted = FALSE;
1132     shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
1133     retval = SHFileOperation(&shfo);
1134     if (retval == DE_OPCANCELLED)
1135     {
1136         /* NT4 fails and doesn't copy any files */
1137         ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1138     }
1139     else
1140     {
1141         ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
1142         ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
1143     }
1144     ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
1145     ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
1146
1147     /* destination is same as source directory */
1148     shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
1149     shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
1150     shfo.fAnyOperationsAborted = FALSE;
1151     retval = SHFileOperation(&shfo);
1152     if (retval == DE_OPCANCELLED)
1153     {
1154         /* NT4 fails and doesn't copy any files */
1155         ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1156     }
1157     else
1158     {
1159         ok(retval == ERROR_SUCCESS ||
1160            retval == DE_DESTSAMETREE, /* Vista */
1161            "Expected ERROR_SUCCESS or DE_DESTSAMETREE, got %d\n", retval);
1162         ok(DeleteFile("b.txt"), "Expected b.txt to exist\n");
1163     }
1164     ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
1165
1166     /* copy a directory into itself, error displayed in UI */
1167     shfo.pFrom = "test4.txt\0";
1168     shfo.pTo = "test4.txt\\newdir\0";
1169     shfo.fFlags &= ~FOF_MULTIDESTFILES;
1170     shfo.fAnyOperationsAborted = FALSE;
1171     retval = SHFileOperation(&shfo);
1172     ok(retval == ERROR_SUCCESS ||
1173        retval == DE_DESTSUBTREE, /* Vista */
1174        "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1175     ok(!RemoveDirectory("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
1176
1177     /* copy a directory to itself, error displayed in UI */
1178     shfo.pFrom = "test4.txt\0";
1179     shfo.pTo = "test4.txt\0";
1180     shfo.fAnyOperationsAborted = FALSE;
1181     retval = SHFileOperation(&shfo);
1182     ok(retval == ERROR_SUCCESS ||
1183        retval == DE_DESTSUBTREE, /* Vista */
1184        "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1185
1186     /* copy a file into a directory, and the directory into itself */
1187     shfo.pFrom = "test1.txt\0test4.txt\0";
1188     shfo.pTo = "test4.txt\0";
1189     shfo.fAnyOperationsAborted = FALSE;
1190     shfo.fFlags |= FOF_NOCONFIRMATION;
1191     retval = SHFileOperation(&shfo);
1192     ok(retval == ERROR_SUCCESS ||
1193        retval == DE_DESTSUBTREE, /* Vista */
1194        "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1195     ok(DeleteFile("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
1196
1197     /* copy a file to a file, and the directory into itself */
1198     shfo.pFrom = "test1.txt\0test4.txt\0";
1199     shfo.pTo = "test4.txt\\a.txt\0";
1200     shfo.fAnyOperationsAborted = FALSE;
1201     retval = SHFileOperation(&shfo);
1202     if (dir_exists("test4.txt\\a.txt"))
1203     {
1204         /* Vista and W2K8 (broken or new behavior ?) */
1205         ok(retval == DE_DESTSUBTREE, "Expected DE_DESTSUBTREE, got %d\n", retval);
1206         ok(DeleteFile("test4.txt\\a.txt\\test1.txt"), "Expected test4.txt\\a.txt\\test1.txt to exist\n");
1207         RemoveDirectory("test4.txt\\a.txt");
1208     }
1209     else
1210     {
1211         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1212         ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
1213     }
1214
1215     /* copy a nonexistent file to a nonexistent directory */
1216     shfo.pFrom = "e.txt\0";
1217     shfo.pTo = "nonexistent\0";
1218     shfo.fAnyOperationsAborted = FALSE;
1219     retval = SHFileOperation(&shfo);
1220     ok(retval == 1026 ||
1221        retval == ERROR_FILE_NOT_FOUND || /* Vista */
1222        broken(retval == ERROR_SUCCESS), /* NT4 */
1223        "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", retval);
1224     ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
1225     ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
1226
1227     /* Overwrite tests */
1228     clean_after_shfo_tests();
1229     init_shfo_tests();
1230     if (!on_nt4)
1231     {
1232         /* NT4 would throw up some dialog boxes and doesn't copy files that are needed
1233          * in subsequent tests.
1234          */
1235         shfo.fFlags = FOF_NOCONFIRMATION;
1236         shfo.pFrom = "test1.txt\0";
1237         shfo.pTo = "test2.txt\0";
1238         shfo.fAnyOperationsAborted = FALSE;
1239         /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
1240         retval = SHFileOperation(&shfo);
1241         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1242         ok(file_has_content("test2.txt", "test1.txt\n"), "The file was not copied\n");
1243
1244         shfo.pFrom = "test3.txt\0test1.txt\0";
1245         shfo.pTo = "test2.txt\0one.txt\0";
1246         shfo.fFlags = FOF_NOCONFIRMATION | FOF_MULTIDESTFILES;
1247         /* without FOF_NOCONFIRMATION the confirmation is Yes/Yes to All/No/Cancel */
1248         retval = SHFileOperation(&shfo);
1249         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1250         ok(file_has_content("test2.txt", "test3.txt\n"), "The file was not copied\n");
1251
1252         shfo.pFrom = "one.txt\0";
1253         shfo.pTo = "testdir2\0";
1254         shfo.fFlags = FOF_NOCONFIRMATION;
1255         /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
1256         retval = SHFileOperation(&shfo);
1257         ok(retval == 0, "Expected 0, got %d\n", retval);
1258         ok(file_has_content("testdir2\\one.txt", "test1.txt\n"), "The file was not copied\n");
1259     }
1260
1261     createTestFile("test4.txt\\test1.txt");
1262     shfo.pFrom = "test4.txt\0";
1263     shfo.pTo = "testdir2\0";
1264     shfo.fFlags = FOF_NOCONFIRMATION;
1265     ok(!SHFileOperation(&shfo), "First SHFileOperation failed\n");
1266     createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */
1267     /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */
1268     retval = SHFileOperation(&shfo);
1269     ok(retval == 0, "Expected 0, got %d\n", retval);
1270     ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
1271
1272     createTestFile("one.txt");
1273
1274     /* pFrom contains bogus 2nd name longer than MAX_PATH */
1275     memset(from, 'a', MAX_PATH*2);
1276     memset(from+MAX_PATH*2, 0, 2);
1277     lstrcpyA(from, "one.txt");
1278     shfo.pFrom = from;
1279     shfo.pTo = "two.txt\0";
1280     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1281     retval = SHFileOperation(&shfo);
1282     ok(retval == 1148 || retval == 1026 ||
1283        retval == ERROR_ACCESS_DENIED || /* win2k */
1284        retval == DE_INVALIDFILES, /* Vista */
1285        "Unexpected return value, got %d\n", retval);
1286     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1287     if (dir_exists("two.txt"))
1288         /* Vista and W2K8 (broken or new behavior ?) */
1289         ok(RemoveDirectory("two.txt"), "Expected two.txt to exist\n");
1290     else
1291         ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
1292
1293     createTestFile("one.txt");
1294
1295     /* pTo contains bogus 2nd name longer than MAX_PATH */
1296     memset(to, 'a', MAX_PATH*2);
1297     memset(to+MAX_PATH*2, 0, 2);
1298     lstrcpyA(to, "two.txt");
1299     shfo.pFrom = "one.txt\0";
1300     shfo.pTo = to;
1301     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1302     retval = SHFileOperation(&shfo);
1303     if (retval == DE_OPCANCELLED)
1304     {
1305         /* NT4 fails and doesn't copy any files */
1306         ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1307     }
1308     else
1309     {
1310         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1311         ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1312     }
1313     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1314
1315     createTestFile("one.txt");
1316
1317     /* no FOF_MULTIDESTFILES, two files in pTo */
1318     shfo.pFrom = "one.txt\0";
1319     shfo.pTo = "two.txt\0three.txt\0";
1320     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1321     retval = SHFileOperation(&shfo);
1322     if (retval == DE_OPCANCELLED)
1323     {
1324         /* NT4 fails and doesn't copy any files */
1325         ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1326     }
1327     else
1328     {
1329         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1330         ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1331     }
1332     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1333
1334     createTestFile("one.txt");
1335
1336     /* both pFrom and pTo contain bogus 2nd names longer than MAX_PATH */
1337     memset(from, 'a', MAX_PATH*2);
1338     memset(from+MAX_PATH*2, 0, 2);
1339     memset(to, 'a', MAX_PATH*2);
1340     memset(to+MAX_PATH*2, 0, 2);
1341     lstrcpyA(from, "one.txt");
1342     lstrcpyA(to, "two.txt");
1343     shfo.pFrom = from;
1344     shfo.pTo = to;
1345     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1346     retval = SHFileOperation(&shfo);
1347     ok(retval == 1148 || retval == 1026 ||
1348        retval == ERROR_ACCESS_DENIED ||  /* win2k */
1349        retval == DE_INVALIDFILES, /* Vista */
1350        "Unexpected return value, got %d\n", retval);
1351     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1352     if (dir_exists("two.txt"))
1353         /* Vista and W2K8 (broken or new behavior ?) */
1354         ok(RemoveDirectory("two.txt"), "Expected two.txt to exist\n");
1355     else
1356         ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
1357
1358     createTestFile("one.txt");
1359
1360     /* pTo contains bogus 2nd name longer than MAX_PATH, FOF_MULTIDESTFILES */
1361     memset(to, 'a', MAX_PATH*2);
1362     memset(to+MAX_PATH*2, 0, 2);
1363     lstrcpyA(to, "two.txt");
1364     shfo.pFrom = "one.txt\0";
1365     shfo.pTo = to;
1366     shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1367                   FOF_SILENT | FOF_NOERRORUI;
1368     retval = SHFileOperation(&shfo);
1369     if (retval == DE_OPCANCELLED)
1370     {
1371         /* NT4 fails and doesn't copy any files */
1372         ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1373     }
1374     else
1375     {
1376         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1377         ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1378     }
1379     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1380
1381     createTestFile("one.txt");
1382     createTestFile("two.txt");
1383
1384     /* pTo contains bogus 2nd name longer than MAX_PATH,
1385      * multiple source files,
1386      * dest directory does not exist
1387      */
1388     memset(to, 'a', 2 * MAX_PATH);
1389     memset(to+MAX_PATH*2, 0, 2);
1390     lstrcpyA(to, "threedir");
1391     shfo.pFrom = "one.txt\0two.txt\0";
1392     shfo.pTo = to;
1393     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1394     retval = SHFileOperation(&shfo);
1395     if (dir_exists("threedir"))
1396     {
1397         /* Vista and W2K8 (broken or new behavior ?) */
1398         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1399         ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1400         ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1401         ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1402     }
1403     else
1404     {
1405         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1406         ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1407         ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1408         ok(!DeleteFileA("threedir"), "Expected file to not exist\n");
1409         ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1410     }
1411     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1412     ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1413
1414     createTestFile("one.txt");
1415     createTestFile("two.txt");
1416     CreateDirectoryA("threedir", NULL);
1417
1418     /* pTo contains bogus 2nd name longer than MAX_PATH,
1419      * multiple source files,
1420      * dest directory does exist
1421      */
1422     memset(to, 'a', 2 * MAX_PATH);
1423     memset(to+MAX_PATH*2, 0, 2);
1424     lstrcpyA(to, "threedir");
1425     shfo.pFrom = "one.txt\0two.txt\0";
1426     shfo.pTo = to;
1427     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1428     retval = SHFileOperation(&shfo);
1429     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1430     ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1431     ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1432     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1433     ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1434     ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1435
1436     if (0) {
1437         /* this crashes on win9x */
1438         createTestFile("one.txt");
1439         createTestFile("two.txt");
1440
1441         /* pTo contains bogus 2nd name longer than MAX_PATH,
1442          * multiple source files, FOF_MULTIDESTFILES
1443          * dest dir does not exist
1444          */
1445
1446         memset(to, 'a', 2 * MAX_PATH);
1447         memset(to+MAX_PATH*2, 0, 2);
1448         lstrcpyA(to, "threedir");
1449         shfo.pFrom = "one.txt\0two.txt\0";
1450         shfo.pTo = to;
1451         shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1452                       FOF_SILENT | FOF_NOERRORUI;
1453         retval = SHFileOperation(&shfo);
1454         ok(retval == ERROR_CANCELLED ||
1455            retval == ERROR_SUCCESS, /* win2k3 */
1456            "Expected ERROR_CANCELLED or ERROR_SUCCESS, got %d\n", retval);
1457         ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1458         ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1459         ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1460         ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1461         ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1462
1463         /* file exists in win2k */
1464         DeleteFileA("threedir");
1465     }
1466
1467
1468     createTestFile("one.txt");
1469     createTestFile("two.txt");
1470     CreateDirectoryA("threedir", NULL);
1471
1472     /* pTo contains bogus 2nd name longer than MAX_PATH,
1473      * multiple source files, FOF_MULTIDESTFILES
1474      * dest dir does exist
1475      */
1476     memset(to, 'a', 2 * MAX_PATH);
1477     memset(to+MAX_PATH*2, 0, 2);
1478     lstrcpyA(to, "threedir");
1479     ptr = to + lstrlenA(to) + 1;
1480     lstrcpyA(ptr, "fourdir");
1481     shfo.pFrom = "one.txt\0two.txt\0";
1482     shfo.pTo = to;
1483     shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1484                   FOF_SILENT | FOF_NOERRORUI;
1485     retval = SHFileOperation(&shfo);
1486     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1487     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1488     ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1489     ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1490     if (dir_exists("fourdir"))
1491     {
1492         /* Vista and W2K8 (broken or new behavior ?) */
1493         ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1494         ok(DeleteFileA("fourdir\\two.txt"), "Expected file to exist\n");
1495         RemoveDirectoryA("fourdir");
1496     }
1497     else
1498     {
1499         ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1500         ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1501         ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1502     }
1503     ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1504
1505     createTestFile("one.txt");
1506     createTestFile("two.txt");
1507     CreateDirectoryA("threedir", NULL);
1508
1509     /* multiple source files, FOF_MULTIDESTFILES
1510      * multiple dest files, but first dest dir exists
1511      * num files in lists is equal
1512      */
1513     shfo.pFrom = "one.txt\0two.txt\0";
1514     shfo.pTo = "threedir\0fourdir\0";
1515     shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1516                   FOF_SILENT | FOF_NOERRORUI;
1517     retval = SHFileOperation(&shfo);
1518     expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1519     if (file_exists("threedir\\threedir"))
1520     {
1521         /* NT4 */
1522         ok(DeleteFileA("threedir\\threedir"), "Expected file to exist\n");
1523     }
1524     ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1525     ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1526     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1527     ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1528     ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1529     ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1530     ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1531
1532     createTestFile("one.txt");
1533     createTestFile("two.txt");
1534     CreateDirectoryA("threedir", NULL);
1535
1536     /* multiple source files, FOF_MULTIDESTFILES
1537      * multiple dest files, but first dest dir exists
1538      * num files in lists is not equal
1539      */
1540     shfo.pFrom = "one.txt\0two.txt\0";
1541     shfo.pTo = "threedir\0fourdir\0five\0";
1542     shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1543                   FOF_SILENT | FOF_NOERRORUI;
1544     retval = SHFileOperation(&shfo);
1545     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1546     ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1547     ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1548     ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1549     if (dir_exists("fourdir"))
1550     {
1551         /* Vista and W2K8 (broken or new behavior ?) */
1552         ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1553         ok(DeleteFileA("fourdir\\two.txt"), "Expected file to exist\n");
1554         RemoveDirectoryA("fourdir");
1555     }
1556     else
1557     {
1558         ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1559         ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1560         ok(!RemoveDirectoryA("fourdir"), "Expected dit to not exist\n");
1561     }
1562     ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1563     ok(!DeleteFileA("five"), "Expected file to not exist\n");
1564     ok(!RemoveDirectoryA("five"), "Expected dit to not exist\n");
1565
1566     createTestFile("aa.txt");
1567     createTestFile("ab.txt");
1568     CreateDirectoryA("one", NULL);
1569     CreateDirectoryA("two", NULL);
1570
1571     /* pFrom has a glob, pTo has more than one dest */
1572     shfo.pFrom = "a*.txt\0";
1573     shfo.pTo = "one\0two\0";
1574     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1575     retval = SHFileOperation(&shfo);
1576     ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1577     ok(DeleteFileA("one\\aa.txt"), "Expected file to exist\n");
1578     ok(DeleteFileA("one\\ab.txt"), "Expected file to exist\n");
1579     ok(!DeleteFileA("two\\aa.txt"), "Expected file to not exist\n");
1580     ok(!DeleteFileA("two\\ab.txt"), "Expected file to not exist\n");
1581     ok(DeleteFileA("aa.txt"), "Expected file to exist\n");
1582     ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
1583     ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
1584     ok(RemoveDirectoryA("two"), "Expected dir to exist\n");
1585 }
1586
1587 /* tests the FO_MOVE action */
1588 static void test_move(void)
1589 {
1590     SHFILEOPSTRUCTA shfo, shfo2;
1591     CHAR from[5*MAX_PATH];
1592     CHAR to[5*MAX_PATH];
1593     DWORD retval;
1594
1595     shfo.hwnd = NULL;
1596     shfo.wFunc = FO_MOVE;
1597     shfo.pFrom = from;
1598     shfo.pTo = to;
1599     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1600     shfo.hNameMappings = NULL;
1601     shfo.lpszProgressTitle = NULL;
1602
1603     set_curr_dir_path(from, "test1.txt\0");
1604     set_curr_dir_path(to, "test4.txt\0");
1605     ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
1606     ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
1607     ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
1608
1609     set_curr_dir_path(from, "test?.txt\0");
1610     set_curr_dir_path(to, "testdir2\0");
1611     ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
1612     ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
1613     ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
1614     ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
1615     ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
1616     ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
1617
1618     clean_after_shfo_tests();
1619     init_shfo_tests();
1620
1621     memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
1622     shfo2.fFlags |= FOF_MULTIDESTFILES;
1623
1624     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
1625     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
1626     ok(!SHFileOperationA(&shfo2), "Move many files\n");
1627     ok(DeleteFileA("test6.txt"), "The file is not moved - many files are "
1628        "specified as a target\n");
1629     ok(DeleteFileA("test7.txt"), "The file is not moved\n");
1630     ok(RemoveDirectoryA("test8.txt"), "The directory is not moved\n");
1631
1632     init_shfo_tests();
1633
1634     /* number of sources do not correspond to number of targets */
1635     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
1636     set_curr_dir_path(to, "test6.txt\0test7.txt\0");
1637     retval = SHFileOperationA(&shfo2);
1638     if (dir_exists("test6.txt"))
1639     {
1640         /* Vista and W2K8 (broken or new behavior ?) */
1641         ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %d\n", retval);
1642         ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved\n");
1643         RemoveDirectoryA("test6.txt");
1644         ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not moved\n");
1645         RemoveDirectoryA("test7.txt");
1646     }
1647     else
1648     {
1649         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1650         ok(!file_exists("test6.txt"), "The file is not moved - many files are "
1651            "specified as a target\n");
1652     }
1653
1654     init_shfo_tests();
1655
1656     set_curr_dir_path(from, "test3.txt\0");
1657     set_curr_dir_path(to, "test4.txt\\test1.txt\0");
1658     ok(!SHFileOperationA(&shfo), "Can't move file to other directory\n");
1659     ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
1660
1661     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
1662     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
1663     retval = SHFileOperationA(&shfo);
1664     if (dir_exists("test6.txt"))
1665     {
1666         /* Vista and W2K8 (broken or new behavior ?) */
1667         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1668         ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved. Many files are specified\n");
1669         ok(DeleteFileA("test6.txt\\test2.txt"), "The file is not moved. Many files are specified\n");
1670         ok(DeleteFileA("test6.txt\\test4.txt\\test1.txt"), "The file is not moved. Many files are specified\n");
1671         ok(RemoveDirectoryA("test6.txt\\test4.txt"), "The directory is not moved. Many files are specified\n");
1672         RemoveDirectoryA("test6.txt");
1673         init_shfo_tests();
1674     }
1675     else
1676     {
1677         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1678         ok(file_exists("test1.txt"), "The file is moved. Many files are specified\n");
1679         ok(dir_exists("test4.txt"), "The directory is moved. Many files are specified\n");
1680     }
1681
1682     set_curr_dir_path(from, "test1.txt\0");
1683     set_curr_dir_path(to, "test6.txt\0");
1684     ok(!SHFileOperationA(&shfo), "Move file failed\n");
1685     ok(!file_exists("test1.txt"), "The file is not moved\n");
1686     ok(file_exists("test6.txt"), "The file is not moved\n");
1687     set_curr_dir_path(from, "test6.txt\0");
1688     set_curr_dir_path(to, "test1.txt\0");
1689     ok(!SHFileOperationA(&shfo), "Move file back failed\n");
1690
1691     set_curr_dir_path(from, "test4.txt\0");
1692     set_curr_dir_path(to, "test6.txt\0");
1693     ok(!SHFileOperationA(&shfo), "Move dir failed\n");
1694     ok(!dir_exists("test4.txt"), "The dir is not moved\n");
1695     ok(dir_exists("test6.txt"), "The dir is moved\n");
1696     set_curr_dir_path(from, "test6.txt\0");
1697     set_curr_dir_path(to, "test4.txt\0");
1698     ok(!SHFileOperationA(&shfo), "Move dir back failed\n");
1699
1700     /* move one file to two others */
1701     init_shfo_tests();
1702     shfo.pFrom = "test1.txt\0";
1703     shfo.pTo = "a.txt\0b.txt\0";
1704     retval = SHFileOperationA(&shfo);
1705     if (retval == DE_OPCANCELLED)
1706     {
1707         /* NT4 fails and doesn't move any files */
1708         ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
1709         DeleteFileA("test1.txt");
1710     }
1711     else
1712     {
1713         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1714         ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
1715         ok(DeleteFile("a.txt"), "Expected a.txt to exist\n");
1716     }
1717     ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1718
1719     /* move two files to one other */
1720     shfo.pFrom = "test2.txt\0test3.txt\0";
1721     shfo.pTo = "test1.txt\0";
1722     retval = SHFileOperationA(&shfo);
1723     if (dir_exists("test1.txt"))
1724     {
1725         /* Vista and W2K8 (broken or new behavior ?) */
1726         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1727         ok(DeleteFileA("test1.txt\\test2.txt"), "Expected test1.txt\\test2.txt to exist\n");
1728         ok(DeleteFileA("test1.txt\\test3.txt"), "Expected test1.txt\\test3.txt to exist\n");
1729         RemoveDirectoryA("test1.txt");
1730         createTestFile("test2.txt");
1731         createTestFile("test3.txt");
1732     }
1733     else
1734     {
1735         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1736         ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
1737         ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
1738         ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
1739     }
1740
1741     /* move a directory into itself */
1742     shfo.pFrom = "test4.txt\0";
1743     shfo.pTo = "test4.txt\\b.txt\0";
1744     retval = SHFileOperationA(&shfo);
1745     ok(retval == ERROR_SUCCESS ||
1746        retval == DE_DESTSUBTREE, /* Vista */
1747        "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1748     ok(!RemoveDirectory("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
1749     ok(dir_exists("test4.txt"), "Expected test4.txt to exist\n");
1750
1751     /* move many files without FOF_MULTIDESTFILES */
1752     shfo.pFrom = "test2.txt\0test3.txt\0";
1753     shfo.pTo = "d.txt\0e.txt\0";
1754     retval = SHFileOperationA(&shfo);
1755     if (dir_exists("d.txt"))
1756     {
1757         /* Vista and W2K8 (broken or new behavior ?) */
1758         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1759         ok(DeleteFileA("d.txt\\test2.txt"), "Expected d.txt\\test2.txt to exist\n");
1760         ok(DeleteFileA("d.txt\\test3.txt"), "Expected d.txt\\test3.txt to exist\n");
1761         RemoveDirectoryA("d.txt");
1762         createTestFile("test2.txt");
1763         createTestFile("test3.txt");
1764     }
1765     else
1766     {
1767         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1768         ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
1769         ok(!DeleteFile("e.txt"), "Expected e.txt to not exist\n");
1770     }
1771
1772     /* number of sources != number of targets */
1773     shfo.pTo = "d.txt\0";
1774     shfo.fFlags |= FOF_MULTIDESTFILES;
1775     retval = SHFileOperationA(&shfo);
1776     if (dir_exists("d.txt"))
1777     {
1778         /* Vista and W2K8 (broken or new behavior ?) */
1779         ok(retval == DE_SAMEFILE,
1780            "Expected DE_SAMEFILE, got %d\n", retval);
1781         ok(DeleteFileA("d.txt\\test2.txt"), "Expected d.txt\\test2.txt to exist\n");
1782         ok(!file_exists("d.txt\\test3.txt"), "Expected d.txt\\test3.txt to not exist\n");
1783         RemoveDirectoryA("d.txt");
1784         createTestFile("test2.txt");
1785     }
1786     else
1787     {
1788         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1789         ok(!DeleteFile("d.txt"), "Expected d.txt to not exist\n");
1790     }
1791
1792     /* FO_MOVE does not create dest directories */
1793     shfo.pFrom = "test2.txt\0";
1794     shfo.pTo = "dir1\\dir2\\test2.txt\0";
1795     retval = SHFileOperationA(&shfo);
1796     if (dir_exists("dir1"))
1797     {
1798         /* Vista and W2K8 (broken or new behavior ?) */
1799         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1800         ok(DeleteFileA("dir1\\dir2\\test2.txt"), "Expected dir1\\dir2\\test2.txt to exist\n");
1801         RemoveDirectoryA("dir1\\dir2");
1802         RemoveDirectoryA("dir1");
1803         createTestFile("test2.txt");
1804     }
1805     else
1806     {
1807         expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1808     }
1809
1810     /* try to overwrite an existing file */
1811     shfo.pTo = "test3.txt\0";
1812     retval = SHFileOperationA(&shfo);
1813     if (retval == DE_OPCANCELLED)
1814     {
1815         /* NT4 fails and doesn't move any files */
1816         ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
1817     }
1818     else
1819     {
1820         ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1821         ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
1822         ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
1823     }
1824 }
1825
1826 static void test_sh_create_dir(void)
1827 {
1828     CHAR path[MAX_PATH];
1829     int ret;
1830
1831     if(!pSHCreateDirectoryExA)
1832     {
1833         win_skip("skipping SHCreateDirectoryExA tests\n");
1834         return;
1835     }
1836
1837     set_curr_dir_path(path, "testdir2\\test4.txt\0");
1838     ret = pSHCreateDirectoryExA(NULL, path, NULL);
1839     ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
1840     ok(file_exists("testdir2"), "The first directory is not created\n");
1841     ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
1842
1843     ret = pSHCreateDirectoryExA(NULL, path, NULL);
1844     ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
1845
1846     ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
1847     ok(file_exists("c:\\testdir3"), "The directory is not created\n");
1848 }
1849
1850 static void test_sh_path_prepare(void)
1851 {
1852     HRESULT res;
1853     CHAR path[MAX_PATH];
1854
1855     if(!pSHPathPrepareForWriteA)
1856     {
1857         win_skip("skipping SHPathPrepareForWriteA tests\n");
1858         return;
1859     }
1860
1861     /* directory exists, SHPPFW_NONE */
1862     set_curr_dir_path(path, "testdir2\0");
1863     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
1864     ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1865
1866     /* directory exists, SHPPFW_IGNOREFILENAME */
1867     set_curr_dir_path(path, "testdir2\\test4.txt\0");
1868     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
1869     ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1870
1871     /* directory exists, SHPPFW_DIRCREATE */
1872     set_curr_dir_path(path, "testdir2\0");
1873     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
1874     ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1875
1876     /* directory exists, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
1877     set_curr_dir_path(path, "testdir2\\test4.txt\0");
1878     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
1879     ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1880     ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
1881
1882     /* file exists, SHPPFW_NONE */
1883     set_curr_dir_path(path, "test1.txt\0");
1884     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
1885     ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
1886        res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
1887        "Unexpected result : 0x%08x\n", res);
1888
1889     /* file exists, SHPPFW_DIRCREATE */
1890     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
1891     ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
1892        res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
1893        "Unexpected result : 0x%08x\n", res);
1894
1895     /* file exists, SHPPFW_NONE, trailing \ */
1896     set_curr_dir_path(path, "test1.txt\\\0");
1897     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
1898     ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
1899        res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
1900        "Unexpected result : 0x%08x\n", res);
1901
1902     /* relative path exists, SHPPFW_DIRCREATE */
1903     res = pSHPathPrepareForWriteA(0, 0, ".\\testdir2", SHPPFW_DIRCREATE);
1904     ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1905
1906     /* relative path doesn't exist, SHPPFW_DIRCREATE -- Windows does not create the directory in this case */
1907     res = pSHPathPrepareForWriteA(0, 0, ".\\testdir2\\test4.txt", SHPPFW_DIRCREATE);
1908     ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
1909     ok(!file_exists(".\\testdir2\\test4.txt\\"), ".\\testdir2\\test4.txt\\ exists but shouldn't\n");
1910
1911     /* directory doesn't exist, SHPPFW_NONE */
1912     set_curr_dir_path(path, "nonexistent\0");
1913     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
1914     ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
1915
1916     /* directory doesn't exist, SHPPFW_IGNOREFILENAME */
1917     set_curr_dir_path(path, "nonexistent\\notreal\0");
1918     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
1919     ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
1920     ok(!file_exists("nonexistent\\notreal"), "nonexistent\\notreal exists but shouldn't\n");
1921     ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
1922
1923     /* directory doesn't exist, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
1924     set_curr_dir_path(path, "testdir2\\test4.txt\\\0");
1925     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
1926     ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1927     ok(file_exists("testdir2\\test4.txt\\"), "testdir2\\test4.txt doesn't exist but should\n");
1928
1929     /* nested directory doesn't exist, SHPPFW_DIRCREATE */
1930     set_curr_dir_path(path, "nonexistent\\notreal\0");
1931     res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
1932     ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
1933     ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal doesn't exist but should\n");
1934
1935     /* SHPPFW_ASKDIRCREATE, SHPPFW_NOWRITECHECK, and SHPPFW_MEDIACHECKONLY are untested */
1936
1937     if(!pSHPathPrepareForWriteW)
1938     {
1939         skip("Skipping SHPathPrepareForWriteW tests\n");
1940         return;
1941     }
1942     /* unicode directory doesn't exist, SHPPFW_NONE */
1943     res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
1944     ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == %08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
1945     ok(!file_existsW(UNICODE_PATH), "unicode path was created but shouldn't be\n");
1946     RemoveDirectoryW(UNICODE_PATH);
1947
1948     /* unicode directory doesn't exist, SHPPFW_DIRCREATE */
1949     res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
1950     ok(res == S_OK, "res == %08x, expected S_OK\n", res);
1951     ok(file_existsW(UNICODE_PATH), "unicode path should've been created\n");
1952
1953     /* unicode directory exists, SHPPFW_NONE */
1954     res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
1955     ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
1956
1957     /* unicode directory exists, SHPPFW_DIRCREATE */
1958     res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
1959     ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
1960     RemoveDirectoryW(UNICODE_PATH);
1961 }
1962
1963 static void test_unicode(void)
1964 {
1965     SHFILEOPSTRUCTW shfoW;
1966     int ret;
1967     HANDLE file;
1968
1969     if (!pSHFileOperationW)
1970     {
1971         skip("SHFileOperationW() is missing\n");
1972         return;
1973     }
1974
1975     shfoW.hwnd = NULL;
1976     shfoW.wFunc = FO_DELETE;
1977     shfoW.pFrom = UNICODE_PATH;
1978     shfoW.pTo = '\0';
1979     shfoW.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1980     shfoW.hNameMappings = NULL;
1981     shfoW.lpszProgressTitle = NULL;
1982
1983     /* Clean up before start test */
1984     DeleteFileW(UNICODE_PATH);
1985     RemoveDirectoryW(UNICODE_PATH);
1986
1987     /* Make sure we are on a system that supports unicode */
1988     SetLastError(0xdeadbeef);
1989     file = CreateFileW(UNICODE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1990     if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
1991     {
1992         skip("Unicode tests skipped on non-unicode system\n");
1993         return;
1994     }
1995     CloseHandle(file);
1996
1997     /* Try to delete a file with unicode filename */
1998     ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
1999     ret = pSHFileOperationW(&shfoW);
2000     ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
2001     ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
2002
2003     /* Try to trash a file with unicode filename */
2004     createTestFileW(UNICODE_PATH);
2005     shfoW.fFlags |= FOF_ALLOWUNDO;
2006     ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
2007     ret = pSHFileOperationW(&shfoW);
2008     ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
2009     ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
2010
2011     if(!pSHCreateDirectoryExW)
2012     {
2013         skip("Skipping SHCreateDirectoryExW tests\n");
2014         return;
2015     }
2016
2017     /* Try to delete a directory with unicode filename */
2018     ret = pSHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
2019     ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
2020     ok(file_existsW(UNICODE_PATH), "The directory is not created\n");
2021     shfoW.fFlags &= ~FOF_ALLOWUNDO;
2022     ret = pSHFileOperationW(&shfoW);
2023     ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
2024     ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
2025
2026     /* Try to trash a directory with unicode filename */
2027     ret = pSHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
2028     ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
2029     ok(file_existsW(UNICODE_PATH), "The directory was not created\n");
2030     shfoW.fFlags |= FOF_ALLOWUNDO;
2031     ret = pSHFileOperationW(&shfoW);
2032     ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
2033     ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
2034 }
2035
2036 START_TEST(shlfileop)
2037 {
2038     InitFunctionPointers();
2039
2040     clean_after_shfo_tests();
2041
2042     init_shfo_tests();
2043     test_get_file_info();
2044     test_get_file_info_iconlist();
2045     clean_after_shfo_tests();
2046
2047     init_shfo_tests();
2048     test_delete();
2049     clean_after_shfo_tests();
2050
2051     init_shfo_tests();
2052     test_rename();
2053     clean_after_shfo_tests();
2054
2055     init_shfo_tests();
2056     test_copy();
2057     clean_after_shfo_tests();
2058
2059     init_shfo_tests();
2060     test_move();
2061     clean_after_shfo_tests();
2062
2063     test_sh_create_dir();
2064     clean_after_shfo_tests();
2065
2066     init_shfo_tests();
2067     test_sh_path_prepare();
2068     clean_after_shfo_tests();
2069
2070     test_unicode();
2071 }