[SHELL32_WINETEST] Sync with Wine Staging 4.18. CORE-16441
[reactos.git] / modules / rostests / winetests / shell32 / 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 COBJMACROS
25 #define WINE_NOWINSOCK
26 #include <windows.h>
27 #include "shellapi.h"
28 #include "shlobj.h"
29 #include "commoncontrols.h"
30
31 #include "wine/test.h"
32
33 #ifdef __REACTOS__
34 #include <reactos/undocshell.h>
35 #endif
36
37 #ifndef FOF_NORECURSION
38 #define FOF_NORECURSION 0x1000
39 #endif
40
41 /* Error codes could be pre-Win32 */
42 #define DE_SAMEFILE 0x71
43 #define DE_MANYSRC1DEST 0x72
44 #define DE_DIFFDIR 0x73
45 #define DE_OPCANCELLED 0x75
46 #define DE_DESTSUBTREE 0x76
47 #define DE_INVALIDFILES 0x7C
48 #define DE_DESTSAMETREE 0x7D
49 #define DE_FLDDESTISFILE 0x7E
50 #define DE_FILEDESTISFLD 0x80
51 #define expect_retval(ret, ret_prewin32)\
52 ok(retval == ret ||\
53 broken(retval == ret_prewin32),\
54 "Expected %d, got %d\n", ret, retval)
55
56 static BOOL old_shell32 = FALSE;
57
58 static CHAR CURR_DIR[MAX_PATH];
59 static const WCHAR UNICODE_PATH[] = {'c',':','\\',0x00ae,'\0','\0'};
60 /* "c:\®" can be used in all codepages */
61 /* Double-null termination needed for pFrom field of SHFILEOPSTRUCT */
62
63 /* creates a file with the specified name for tests */
64 static void createTestFile(const CHAR *name)
65 {
66 HANDLE file;
67 DWORD written;
68
69 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
70 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
71 WriteFile(file, name, strlen(name), &written, NULL);
72 WriteFile(file, "\n", strlen("\n"), &written, NULL);
73 CloseHandle(file);
74 }
75
76 static void createTestFileW(const WCHAR *name)
77 {
78 HANDLE file;
79
80 file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
81 ok(file != INVALID_HANDLE_VALUE, "Failure to open file\n");
82 CloseHandle(file);
83 }
84
85 static BOOL file_exists(const CHAR *name)
86 {
87 return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
88 }
89
90 static BOOL dir_exists(const CHAR *name)
91 {
92 DWORD attr;
93 BOOL dir;
94
95 attr = GetFileAttributesA(name);
96 dir = ((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
97
98 return ((attr != INVALID_FILE_ATTRIBUTES) && dir);
99 }
100
101 static BOOL file_existsW(LPCWSTR name)
102 {
103 return GetFileAttributesW(name) != INVALID_FILE_ATTRIBUTES;
104 }
105
106 static BOOL file_has_content(const CHAR *name, const CHAR *content)
107 {
108 CHAR buf[MAX_PATH];
109 HANDLE file;
110 DWORD read;
111
112 file = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
113 if (file == INVALID_HANDLE_VALUE)
114 return FALSE;
115 ReadFile(file, buf, MAX_PATH - 1, &read, NULL);
116 buf[read] = 0;
117 CloseHandle(file);
118 return strcmp(buf, content)==0;
119 }
120
121 /* initializes the tests */
122 static void init_shfo_tests(void)
123 {
124 int len;
125
126 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
127 len = lstrlenA(CURR_DIR);
128
129 if(len && (CURR_DIR[len-1] == '\\'))
130 CURR_DIR[len-1] = 0;
131
132 createTestFile("test1.txt");
133 createTestFile("test2.txt");
134 createTestFile("test3.txt");
135 createTestFile("test_5.txt");
136 CreateDirectoryA("test4.txt", NULL);
137 CreateDirectoryA("testdir2", NULL);
138 CreateDirectoryA("testdir2\\nested", NULL);
139 createTestFile("testdir2\\one.txt");
140 createTestFile("testdir2\\nested\\two.txt");
141 }
142
143 /* cleans after tests */
144 static void clean_after_shfo_tests(void)
145 {
146 DeleteFileA("test1.txt");
147 DeleteFileA("test2.txt");
148 DeleteFileA("test3.txt");
149 DeleteFileA("test_5.txt");
150 DeleteFileA("one.txt");
151 DeleteFileA("test4.txt\\test1.txt");
152 DeleteFileA("test4.txt\\test2.txt");
153 DeleteFileA("test4.txt\\test3.txt");
154 DeleteFileA("test4.txt\\one.txt");
155 DeleteFileA("test4.txt\\nested\\two.txt");
156 RemoveDirectoryA("test4.txt\\nested");
157 RemoveDirectoryA("test4.txt");
158 DeleteFileA("testdir2\\one.txt");
159 DeleteFileA("testdir2\\test1.txt");
160 DeleteFileA("testdir2\\test2.txt");
161 DeleteFileA("testdir2\\test3.txt");
162 DeleteFileA("testdir2\\test4.txt\\test1.txt");
163 DeleteFileA("testdir2\\nested\\two.txt");
164 RemoveDirectoryA("testdir2\\test4.txt");
165 RemoveDirectoryA("testdir2\\nested");
166 RemoveDirectoryA("testdir2");
167 RemoveDirectoryA("c:\\testdir3");
168 DeleteFileA("nonexistent\\notreal\\test2.txt");
169 RemoveDirectoryA("nonexistent\\notreal");
170 RemoveDirectoryA("nonexistent");
171 }
172
173
174 static void test_get_file_info(void)
175 {
176 DWORD rc, rc2;
177 SHFILEINFOA shfi, shfi2;
178 SHFILEINFOW shfiw;
179 char notepad[MAX_PATH];
180 HANDLE unset_icon;
181
182 /* Test whether fields of SHFILEINFOA are always cleared */
183 memset(&shfi, 0xcf, sizeof(shfi));
184 rc=SHGetFileInfoA("", 0, &shfi, sizeof(shfi), 0);
185 ok(rc == 1, "SHGetFileInfoA('' | 0) should return 1, got 0x%x\n", rc);
186 todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA('' | 0) did not clear hIcon\n");
187 todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szDisplayName[0]\n");
188 todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szTypeName[0]\n");
189 ok(shfi.iIcon == 0xcfcfcfcf ||
190 broken(shfi.iIcon != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
191 "SHGetFileInfoA('' | 0) should not clear iIcon\n");
192 ok(shfi.dwAttributes == 0xcfcfcfcf ||
193 broken(shfi.dwAttributes != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
194 "SHGetFileInfoA('' | 0) should not clear dwAttributes\n");
195
196 memset(&shfiw, 0xcf, sizeof(shfiw));
197 memset(&unset_icon, 0xcf, sizeof(unset_icon));
198 rc = SHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0);
199 ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n");
200 ok(shfiw.hIcon == unset_icon, "SHGetFileInfoW(NULL | 0) should not clear hIcon\n");
201 ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n");
202 ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n");
203 ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n");
204 ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear dwAttributes\n");
205
206 /* Test some flag combinations that MSDN claims are not allowed,
207 * but which work anyway
208 */
209 memset(&shfi, 0xcf, sizeof(shfi));
210 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
211 &shfi, sizeof(shfi),
212 SHGFI_ATTRIBUTES | SHGFI_USEFILEATTRIBUTES);
213 ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) should return 1, got 0x%x\n", rc);
214 if (rc)
215 ok(shfi.dwAttributes != 0xcfcfcfcf, "dwFileAttributes is not set\n");
216 todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear hIcon\n");
217 todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szDisplayName[0]\n");
218 todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szTypeName[0]\n");
219 ok(shfi.iIcon == 0xcfcfcfcf ||
220 broken(shfi.iIcon != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
221 "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) should not clear iIcon\n");
222
223 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
224 &shfi, sizeof(shfi),
225 SHGFI_EXETYPE | SHGFI_USEFILEATTRIBUTES);
226 todo_wine ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_EXETYPE) should return 1, got 0x%x\n", rc);
227
228 /* Test SHGFI_USEFILEATTRIBUTES support */
229 strcpy(shfi.szDisplayName, "dummy");
230 shfi.iIcon=0xdeadbeef;
231 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
232 &shfi, sizeof(shfi),
233 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
234 ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent) should return 1, got 0x%x\n", rc);
235 if (rc)
236 {
237 ok(strcmp(shfi.szDisplayName, "dummy"), "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n");
238 ok(shfi.iIcon != 0xdeadbeef, "SHGetFileInfoA(c:\\nonexistent) iIcon is not set\n");
239 }
240
241 /* Wine does not have a default icon for text files, and Windows 98 fails
242 * if we give it an empty executable. So use notepad.exe as the test
243 */
244 if (SearchPathA(NULL, "notepad.exe", NULL, sizeof(notepad), notepad, NULL))
245 {
246 strcpy(shfi.szDisplayName, "dummy");
247 shfi.iIcon=0xdeadbeef;
248 rc=SHGetFileInfoA(notepad, GetFileAttributesA(notepad),
249 &shfi, sizeof(shfi),
250 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
251 ok(rc == 1, "SHGetFileInfoA(%s, SHGFI_USEFILEATTRIBUTES) should return 1, got 0x%x\n", notepad, rc);
252 strcpy(shfi2.szDisplayName, "dummy");
253 shfi2.iIcon=0xdeadbeef;
254 rc2=SHGetFileInfoA(notepad, 0,
255 &shfi2, sizeof(shfi2),
256 SHGFI_ICONLOCATION);
257 ok(rc2 == 1, "SHGetFileInfoA(%s) failed %x\n", notepad, rc2);
258 if (rc && rc2)
259 {
260 ok(lstrcmpiA(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
261 ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
262 }
263 }
264
265 /* with a directory now */
266 strcpy(shfi.szDisplayName, "dummy");
267 shfi.iIcon=0xdeadbeef;
268 rc=SHGetFileInfoA("test4.txt", GetFileAttributesA("test4.txt"),
269 &shfi, sizeof(shfi),
270 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
271 ok(rc == 1, "SHGetFileInfoA(test4.txt/, SHGFI_USEFILEATTRIBUTES) should return 1, got 0x%x\n", rc);
272 strcpy(shfi2.szDisplayName, "dummy");
273 shfi2.iIcon=0xdeadbeef;
274 rc2=SHGetFileInfoA("test4.txt", 0,
275 &shfi2, sizeof(shfi2),
276 SHGFI_ICONLOCATION);
277 ok(rc2 == 1, "SHGetFileInfoA(test4.txt/) should return 1, got 0x%x\n", rc2);
278 if (rc && rc2)
279 {
280 ok(lstrcmpiA(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
281 ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
282 }
283 /* with drive root directory */
284 strcpy(shfi.szDisplayName, "dummy");
285 strcpy(shfi.szTypeName, "dummy");
286 shfi.hIcon=(HICON) 0xdeadbeef;
287 shfi.iIcon=0xdeadbeef;
288 shfi.dwAttributes=0xdeadbeef;
289 rc=SHGetFileInfoA("c:\\", 0, &shfi, sizeof(shfi),
290 SHGFI_TYPENAME | SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_SMALLICON);
291 ok(rc == 1, "SHGetFileInfoA(c:\\) should return 1, got 0x%x\n", rc);
292 ok(strcmp(shfi.szDisplayName, "dummy") != 0, "display name was expected to change\n");
293 ok(strcmp(shfi.szTypeName, "dummy") != 0, "type name was expected to change\n");
294 ok(shfi.hIcon != (HICON) 0xdeadbeef, "hIcon was expected to change\n");
295 ok(shfi.iIcon != 0xdeadbeef, "iIcon was expected to change\n");
296 }
297
298 static void check_icon_size( HICON icon, DWORD flags )
299 {
300 ICONINFO info;
301 BITMAP bm;
302 SIZE list_size, metrics_size;
303 IImageList *list;
304
305 GetIconInfo( icon, &info );
306 GetObjectW( info.hbmColor, sizeof(bm), &bm );
307
308 SHGetImageList( (flags & SHGFI_SMALLICON) ? SHIL_SMALL : SHIL_LARGE,
309 &IID_IImageList, (void **)&list );
310 IImageList_GetIconSize( list, &list_size.cx, &list_size.cy );
311 IImageList_Release( list );
312
313 metrics_size.cx = GetSystemMetrics( (flags & SHGFI_SMALLICON) ? SM_CXSMICON : SM_CXICON );
314 metrics_size.cy = GetSystemMetrics( (flags & SHGFI_SMALLICON) ? SM_CYSMICON : SM_CYICON );
315
316
317 if (flags & SHGFI_SHELLICONSIZE)
318 {
319 ok( bm.bmWidth == list_size.cx, "got %d expected %d\n", bm.bmWidth, list_size.cx );
320 ok( bm.bmHeight == list_size.cy, "got %d expected %d\n", bm.bmHeight, list_size.cy );
321 }
322 else
323 {
324 ok( bm.bmWidth == metrics_size.cx, "got %d expected %d\n", bm.bmWidth, metrics_size.cx );
325 ok( bm.bmHeight == metrics_size.cy, "got %d expected %d\n", bm.bmHeight, metrics_size.cy );
326 }
327 }
328
329 static void test_get_file_info_iconlist(void)
330 {
331 /* Test retrieving a handle to the system image list, and
332 * what that returns for hIcon
333 */
334 HRESULT hr;
335 HIMAGELIST hSysImageList;
336 LPITEMIDLIST pidList;
337 SHFILEINFOA shInfoa;
338 SHFILEINFOW shInfow;
339 IImageList *small_list, *large_list;
340 ULONG start_refs, refs;
341
342 hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidList);
343 if (FAILED(hr)) {
344 skip("can't get desktop pidl\n");
345 return;
346 }
347
348 SHGetImageList( SHIL_LARGE, &IID_IImageList, (void **)&large_list );
349 SHGetImageList( SHIL_SMALL, &IID_IImageList, (void **)&small_list );
350
351 start_refs = IImageList_AddRef( small_list );
352 IImageList_Release( small_list );
353
354 memset(&shInfoa, 0xcf, sizeof(shInfoa));
355 hSysImageList = (HIMAGELIST) SHGetFileInfoA((const char *)pidList, 0,
356 &shInfoa, sizeof(shInfoa),
357 SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
358 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
359 refs = IImageList_AddRef( small_list );
360 IImageList_Release( small_list );
361 ok( refs == start_refs + 1 ||
362 broken( refs == start_refs ), /* XP and 2003 */
363 "got %d, start_refs %d\n", refs, start_refs );
364 todo_wine ok(shInfoa.hIcon == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
365 todo_wine ok(shInfoa.szTypeName[0] == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
366 ok(shInfoa.iIcon != 0xcfcfcfcf, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
367 ok(shInfoa.dwAttributes == 0xcfcfcfcf ||
368 shInfoa.dwAttributes == 0 || /* Vista */
369 broken(shInfoa.dwAttributes != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
370 "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL), unexpected dwAttributes\n");
371 /* Don't release hSysImageList here (and in similar places below) because of the broken reference behaviour of XP and 2003. */
372
373 memset(&shInfow, 0xcf, sizeof(shInfow));
374 hSysImageList = (HIMAGELIST) SHGetFileInfoW((const WCHAR *)pidList, 0,
375 &shInfow, sizeof(shInfow), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
376 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
377 todo_wine ok(shInfow.hIcon == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
378 ok(shInfow.szTypeName[0] == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
379 ok(shInfow.iIcon != 0xcfcfcfcf, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
380 ok(shInfow.dwAttributes == 0xcfcfcfcf ||
381 shInfoa.dwAttributes == 0, /* Vista */
382 "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) unexpected dwAttributes\n");
383
384 /* Various suposidly invalid flag testing */
385 memset(&shInfow, 0xcf, sizeof(shInfow));
386 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
387 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
388 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
389 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
390 ok(shInfow.dwAttributes==0xcfcfcfcf ||
391 shInfoa.dwAttributes==0, /* Vista */
392 "unexpected dwAttributes\n");
393
394 memset(&shInfow, 0xcf, sizeof(shInfow));
395 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
396 SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
397 ok(hr != 0, " SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
398 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
399 check_icon_size( shInfow.hIcon, SHGFI_SMALLICON );
400 DestroyIcon(shInfow.hIcon);
401 todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
402
403 memset(&shInfow, 0xcf, sizeof(shInfow));
404 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
405 SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
406 ok(hr != 0, "SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON Failed\n");
407 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
408 check_icon_size( shInfow.hIcon, SHGFI_LARGEICON );
409 DestroyIcon( shInfow.hIcon );
410 todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
411
412 memset(&shInfow, 0xcf, sizeof(shInfow));
413 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
414 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
415 ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, small_list);
416 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
417 ok(shInfow.dwAttributes==0xcfcfcfcf ||
418 shInfoa.dwAttributes==0, /* Vista */
419 "unexpected dwAttributes\n");
420
421 memset(&shInfow, 0xcf, sizeof(shInfow));
422 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
423 SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
424 ok(hr != 0, "SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
425 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
426 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
427
428 memset(&shInfow, 0xcf, sizeof(shInfow));
429 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
430 SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
431 ok(hr != 0, "SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
432 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
433 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
434
435 memset(&shInfow, 0xcf, sizeof(shInfow));
436 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
437 SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
438 ok(hr != 0, "SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
439 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
440 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
441
442 memset(&shInfow, 0xcf, sizeof(shInfow));
443 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
444 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
445 SHGFI_ATTRIBUTES);
446 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
447 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
448 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
449
450 memset(&shInfow, 0xcf, sizeof(shInfow));
451 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
452 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
453 SHGFI_EXETYPE);
454 todo_wine ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
455 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
456 ok(shInfow.dwAttributes==0xcfcfcfcf ||
457 shInfoa.dwAttributes==0, /* Vista */
458 "unexpected dwAttributes\n");
459
460 memset(&shInfow, 0xcf, sizeof(shInfow));
461 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
462 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE);
463 todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE Failed\n");
464 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
465 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
466
467 memset(&shInfow, 0xcf, sizeof(shInfow));
468 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
469 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES);
470 ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES Failed\n");
471 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
472 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
473
474 memset(&shInfow, 0xcf, sizeof(shInfow));
475 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
476 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|
477 SHGFI_ATTRIBUTES);
478 ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, large_list);
479 ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
480 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
481 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
482
483 memset(&shInfow, 0xcf, sizeof(shInfow));
484 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
485 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
486 todo_wine ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, large_list);
487 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
488 ok(shInfow.dwAttributes==0xcfcfcfcf ||
489 shInfoa.dwAttributes==0, /* Vista */
490 "unexpected dwAttributes\n");
491
492 memset(&shInfow, 0xcf, sizeof(shInfow));
493 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
494 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
495 todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE Failed\n");
496 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
497 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
498
499 memset(&shInfow, 0xcf, sizeof(shInfow));
500 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
501 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES);
502 ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
503 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
504 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
505
506 memset(&shInfow, 0xcf, sizeof(shInfow));
507 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
508 SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_SHELLICONSIZE|SHGFI_ICON);
509 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
510 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
511 check_icon_size( shInfow.hIcon, SHGFI_SMALLICON | SHGFI_SHELLICONSIZE );
512 DestroyIcon( shInfow.hIcon );
513
514 memset(&shInfow, 0xcf, sizeof(shInfow));
515 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
516 SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SHELLICONSIZE|SHGFI_ICON);
517 ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, small_list);
518 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
519 check_icon_size( shInfow.hIcon, SHGFI_LARGEICON | SHGFI_SHELLICONSIZE );
520 DestroyIcon( shInfow.hIcon );
521
522 ILFree(pidList);
523 IImageList_Release( small_list );
524 IImageList_Release( large_list );
525 }
526
527
528 /*
529 puts into the specified buffer file names with current directory.
530 files - string with file names, separated by null characters. Ends on a double
531 null characters
532 */
533 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
534 {
535 buf[0] = 0;
536 while (files[0])
537 {
538 strcpy(buf, CURR_DIR);
539 buf += strlen(buf);
540 buf[0] = '\\';
541 buf++;
542 strcpy(buf, files);
543 buf += strlen(buf) + 1;
544 files += strlen(files) + 1;
545 }
546 buf[0] = 0;
547 }
548
549
550 /* tests the FO_DELETE action */
551 static void test_delete(void)
552 {
553 SHFILEOPSTRUCTA shfo;
554 DWORD ret;
555 CHAR buf[sizeof(CURR_DIR)+sizeof("/test?.txt")+1];
556
557 sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
558 buf[strlen(buf) + 1] = '\0';
559
560 shfo.hwnd = NULL;
561 shfo.wFunc = FO_DELETE;
562 shfo.pFrom = buf;
563 shfo.pTo = NULL;
564 shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
565 shfo.hNameMappings = NULL;
566 shfo.lpszProgressTitle = NULL;
567
568 ok(!SHFileOperationA(&shfo), "Deletion was not successful\n");
569 ok(dir_exists("test4.txt"), "Directory should not have been removed\n");
570 ok(!file_exists("test1.txt"), "File should have been removed\n");
571 ok(!file_exists("test2.txt"), "File should have been removed\n");
572 ok(!file_exists("test3.txt"), "File should have been removed\n");
573
574 ret = SHFileOperationA(&shfo);
575 ok(ret == ERROR_SUCCESS, "Directory exists, but is not removed, ret=%d\n", ret);
576 ok(dir_exists("test4.txt"), "Directory should not have been removed\n");
577
578 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
579
580 ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
581 ok(!dir_exists("test4.txt"), "Directory should have been removed\n");
582
583 ret = SHFileOperationA(&shfo);
584 ok(!ret, "The requested file does not exist, ret=%d\n", ret);
585
586 init_shfo_tests();
587 sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
588 buf[strlen(buf) + 1] = '\0';
589 ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Filling the subdirectory failed\n");
590 ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
591 ok(!dir_exists("test4.txt"), "Directory is not removed\n");
592
593 init_shfo_tests();
594 shfo.pFrom = "test1.txt\0test4.txt\0";
595 ok(!SHFileOperationA(&shfo), "Directory and a file are not removed\n");
596 ok(!file_exists("test1.txt"), "The file should have been removed\n");
597 ok(!dir_exists("test4.txt"), "Directory should have been removed\n");
598 ok(file_exists("test2.txt"), "This file should not have been removed\n");
599
600 /* FOF_FILESONLY does not delete a dir matching a wildcard */
601 init_shfo_tests();
602 shfo.fFlags |= FOF_FILESONLY;
603 shfo.pFrom = "*.txt\0";
604 ok(!SHFileOperationA(&shfo), "Failed to delete files\n");
605 ok(!file_exists("test1.txt"), "test1.txt should have been removed\n");
606 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
607 ok(dir_exists("test4.txt"), "test4.txt should not have been removed\n");
608
609 /* FOF_FILESONLY only deletes a dir if explicitly specified */
610 init_shfo_tests();
611 shfo.pFrom = "test_?.txt\0test4.txt\0";
612 ok(!SHFileOperationA(&shfo), "Failed to delete files and directory\n");
613 ok(!dir_exists("test4.txt") ||
614 broken(dir_exists("test4.txt")), /* NT4 */
615 "test4.txt should have been removed\n");
616 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
617 ok(file_exists("test1.txt"), "test1.txt should not have been removed\n");
618
619 /* try to delete an invalid filename */
620 if (0) {
621 /* this crashes on win9x */
622 init_shfo_tests();
623 shfo.pFrom = "\0";
624 shfo.fFlags &= ~FOF_FILESONLY;
625 shfo.fAnyOperationsAborted = FALSE;
626 ret = SHFileOperationA(&shfo);
627 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", ret);
628 ok(!shfo.fAnyOperationsAborted, "Expected no aborted operations\n");
629 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
630 }
631
632 /* try an invalid function */
633 init_shfo_tests();
634 shfo.pFrom = "test1.txt\0";
635 shfo.wFunc = 0;
636 ret = SHFileOperationA(&shfo);
637 ok(ret == ERROR_INVALID_PARAMETER ||
638 broken(ret == ERROR_SUCCESS), /* Win9x, NT4 */
639 "Expected ERROR_INVALID_PARAMETER, got %d\n", ret);
640 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
641
642 /* try an invalid list, only one null terminator */
643 if (0) {
644 /* this crashes on win9x */
645 init_shfo_tests();
646 shfo.pFrom = "";
647 shfo.wFunc = FO_DELETE;
648 ret = SHFileOperationA(&shfo);
649 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", ret);
650 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
651 }
652
653 /* delete a nonexistent file */
654 shfo.pFrom = "nonexistent.txt\0";
655 shfo.wFunc = FO_DELETE;
656 ret = SHFileOperationA(&shfo);
657 ok(ret == 1026 ||
658 ret == ERROR_FILE_NOT_FOUND || /* Vista */
659 broken(ret == ERROR_SUCCESS), /* NT4 */
660 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", ret);
661
662 /* delete a dir, and then a file inside the dir, same as
663 * deleting a nonexistent file
664 */
665 if (ret != ERROR_FILE_NOT_FOUND)
666 {
667 /* Vista would throw up a dialog box that we can't suppress */
668 init_shfo_tests();
669 shfo.pFrom = "testdir2\0testdir2\\one.txt\0";
670 ret = SHFileOperationA(&shfo);
671 ok(ret == ERROR_PATH_NOT_FOUND ||
672 broken(ret == ERROR_SUCCESS), /* NT4 */
673 "Expected ERROR_PATH_NOT_FOUND, got %d\n", ret);
674 ok(!dir_exists("testdir2"), "Expected testdir2 to not exist\n");
675 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
676 }
677 else
678 skip("Test would show a dialog box\n");
679
680 /* delete an existent file and a nonexistent file */
681 init_shfo_tests();
682 shfo.pFrom = "test1.txt\0nonexistent.txt\0test2.txt\0";
683 shfo.wFunc = FO_DELETE;
684 ret = SHFileOperationA(&shfo);
685 ok(ret == 1026 ||
686 ret == ERROR_FILE_NOT_FOUND || /* Vista */
687 broken(ret == ERROR_SUCCESS), /* NT4 */
688 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", ret);
689 todo_wine
690 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
691 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
692
693 /* delete a nonexistent file in an existent dir or a nonexistent dir */
694 init_shfo_tests();
695 shfo.pFrom = "testdir2\\nonexistent.txt\0";
696 ret = SHFileOperationA(&shfo);
697 ok(ret == ERROR_FILE_NOT_FOUND || /* Vista */
698 broken(ret == 0x402) || /* XP */
699 broken(ret == ERROR_SUCCESS), /* NT4 */
700 "Expected 0x402 or ERROR_FILE_NOT_FOUND, got %x\n", ret);
701 shfo.pFrom = "nonexistent\\one.txt\0";
702 ret = SHFileOperationA(&shfo);
703 ok(ret == DE_INVALIDFILES || /* Vista or later */
704 broken(ret == 0x402), /* XP */
705 "Expected 0x402 or DE_INVALIDFILES, got %x\n", ret);
706
707 /* try the FOF_NORECURSION flag, continues deleting subdirs */
708 init_shfo_tests();
709 shfo.pFrom = "testdir2\0";
710 shfo.fFlags |= FOF_NORECURSION;
711 ret = SHFileOperationA(&shfo);
712 ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
713 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
714 ok(!dir_exists("testdir2\\nested"), "Expected testdir2\\nested to not exist\n");
715 }
716
717 /* tests the FO_RENAME action */
718 static void test_rename(void)
719 {
720 SHFILEOPSTRUCTA shfo, shfo2;
721 CHAR from[5*MAX_PATH];
722 CHAR to[5*MAX_PATH];
723 DWORD retval;
724
725 shfo.hwnd = NULL;
726 shfo.wFunc = FO_RENAME;
727 shfo.pFrom = from;
728 shfo.pTo = to;
729 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
730 shfo.hNameMappings = NULL;
731 shfo.lpszProgressTitle = NULL;
732
733 set_curr_dir_path(from, "test1.txt\0");
734 set_curr_dir_path(to, "test4.txt\0");
735 retval = SHFileOperationA(&shfo);
736 ok(retval == ERROR_ALREADY_EXISTS ||
737 retval == DE_FILEDESTISFLD || /* Vista */
738 broken(retval == ERROR_INVALID_NAME), /* Win9x, NT4 */
739 "Expected ERROR_ALREADY_EXISTS or DE_FILEDESTISFLD, got %d\n", retval);
740 ok(file_exists("test1.txt"), "The file is renamed\n");
741
742 set_curr_dir_path(from, "test3.txt\0");
743 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
744 retval = SHFileOperationA(&shfo);
745 if (retval == DE_DIFFDIR)
746 {
747 /* Vista and W2K8 (broken or new behavior ?) */
748 ok(!file_exists("test4.txt\\test1.txt"), "The file is renamed\n");
749 }
750 else
751 {
752 ok(retval == ERROR_SUCCESS, "File is renamed moving to other directory\n");
753 ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
754 }
755
756 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
757 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
758 retval = SHFileOperationA(&shfo);
759 ok(retval == ERROR_GEN_FAILURE ||
760 retval == DE_MANYSRC1DEST || /* Vista */
761 broken(retval == ERROR_SUCCESS), /* Win9x */
762 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST , got %d\n", retval);
763 ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
764
765 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
766 shfo2.fFlags |= FOF_MULTIDESTFILES;
767
768 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
769 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
770 retval = SHFileOperationA(&shfo2);
771 ok(retval == ERROR_GEN_FAILURE ||
772 retval == DE_MANYSRC1DEST || /* Vista */
773 broken(retval == ERROR_SUCCESS), /* Win9x */
774 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST files, got %d\n", retval);
775 ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
776
777 set_curr_dir_path(from, "test1.txt\0");
778 set_curr_dir_path(to, "test6.txt\0");
779 retval = SHFileOperationA(&shfo);
780 ok(retval == ERROR_SUCCESS, "Rename file failed, retval = %d\n", retval);
781 ok(!file_exists("test1.txt"), "The file is not renamed\n");
782 ok(file_exists("test6.txt"), "The file is not renamed\n");
783
784 set_curr_dir_path(from, "test6.txt\0");
785 set_curr_dir_path(to, "test1.txt\0");
786 retval = SHFileOperationA(&shfo);
787 ok(retval == ERROR_SUCCESS, "Rename file back failed, retval = %d\n", retval);
788
789 set_curr_dir_path(from, "test4.txt\0");
790 set_curr_dir_path(to, "test6.txt\0");
791 retval = SHFileOperationA(&shfo);
792 ok(retval == ERROR_SUCCESS, "Rename dir failed, retval = %d\n", retval);
793 ok(!dir_exists("test4.txt"), "The dir is not renamed\n");
794 ok(dir_exists("test6.txt"), "The dir is not renamed\n");
795
796 set_curr_dir_path(from, "test6.txt\0");
797 set_curr_dir_path(to, "test4.txt\0");
798 retval = SHFileOperationA(&shfo);
799 ok(retval == ERROR_SUCCESS, "Rename dir back failed, retval = %d\n", retval);
800 ok(dir_exists("test4.txt"), "The dir is not renamed\n");
801
802 /* try to rename more than one file to a single file */
803 shfo.pFrom = "test1.txt\0test2.txt\0";
804 shfo.pTo = "a.txt\0";
805 retval = SHFileOperationA(&shfo);
806 ok(retval == ERROR_GEN_FAILURE ||
807 retval == DE_MANYSRC1DEST || /* Vista */
808 broken(retval == ERROR_SUCCESS), /* Win9x */
809 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST, got %d\n", retval);
810 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
811 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
812 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
813
814 /* pFrom doesn't exist */
815 shfo.pFrom = "idontexist\0";
816 shfo.pTo = "newfile\0";
817 retval = SHFileOperationA(&shfo);
818 ok(retval == 1026 ||
819 retval == ERROR_FILE_NOT_FOUND || /* Vista */
820 broken(retval == ERROR_SUCCESS), /* NT4 */
821 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", retval);
822 ok(!file_exists("newfile"), "Expected newfile to not exist\n");
823
824 /* pTo already exist */
825 shfo.pFrom = "test1.txt\0";
826 shfo.pTo = "test2.txt\0";
827 if (old_shell32)
828 shfo.fFlags |= FOF_NOCONFIRMMKDIR;
829 retval = SHFileOperationA(&shfo);
830 if (retval == ERROR_SUCCESS)
831 {
832 /* Vista and W2K8 (broken or new behavior ?) */
833 createTestFile("test1.txt");
834 }
835 else
836 {
837 ok(retval == ERROR_ALREADY_EXISTS ||
838 broken(retval == DE_OPCANCELLED) || /* NT4 */
839 broken(retval == ERROR_INVALID_NAME), /* Win9x */
840 "Expected ERROR_ALREADY_EXISTS, got %d\n", retval);
841 }
842
843 /* pFrom is valid, but pTo is empty */
844 shfo.pFrom = "test1.txt\0";
845 shfo.pTo = "\0";
846 retval = SHFileOperationA(&shfo);
847 ok(retval == ERROR_CANCELLED ||
848 retval == DE_DIFFDIR || /* Vista */
849 retval == DE_FILEDESTISFLD || /* Vista, running from c: */
850 broken(retval == DE_OPCANCELLED) || /* Win9x */
851 broken(retval == 65652), /* NT4 */
852 "Expected ERROR_CANCELLED or DE_DIFFDIR, got %u\n", retval);
853 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
854
855 /* pFrom is empty */
856 shfo.pFrom = "\0";
857 retval = SHFileOperationA(&shfo);
858 ok(retval == ERROR_ACCESS_DENIED ||
859 retval == DE_MANYSRC1DEST || /* Vista */
860 broken(retval == ERROR_SUCCESS), /* Win9x */
861 "Expected ERROR_ACCESS_DENIED or DE_MANYSRC1DEST, got %d\n", retval);
862
863 /* pFrom is NULL, commented out because it crashes on nt 4.0 */
864 if (0)
865 {
866 shfo.pFrom = NULL;
867 retval = SHFileOperationA(&shfo);
868 ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", retval);
869 }
870 }
871
872 /* tests the FO_COPY action */
873 static void test_copy(void)
874 {
875 SHFILEOPSTRUCTA shfo, shfo2;
876 CHAR from[5*MAX_PATH];
877 CHAR to[5*MAX_PATH];
878 FILEOP_FLAGS tmp_flags;
879 DWORD retval;
880 LPSTR ptr;
881 BOOL on_nt4 = FALSE;
882 BOOL ret;
883
884 if (old_shell32)
885 {
886 win_skip("Too many differences for old shell32\n");
887 return;
888 }
889
890 shfo.hwnd = NULL;
891 shfo.wFunc = FO_COPY;
892 shfo.pFrom = from;
893 shfo.pTo = to;
894 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
895 shfo.hNameMappings = NULL;
896 shfo.lpszProgressTitle = NULL;
897
898 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
899 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
900 retval = SHFileOperationA(&shfo);
901 if (dir_exists("test6.txt"))
902 {
903 /* Vista and W2K8 (broken or new behavior ?) */
904 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
905 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files "
906 "are specified as a target\n");
907 DeleteFileA("test6.txt\\test2.txt");
908 RemoveDirectoryA("test6.txt\\test4.txt");
909 RemoveDirectoryA("test6.txt");
910 }
911 else
912 {
913 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
914 ok(!file_exists("test6.txt"), "The file is copied - many files are "
915 "specified as a target\n");
916 }
917
918 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
919 shfo2.fFlags |= FOF_MULTIDESTFILES;
920
921 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
922 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
923 ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
924 ok(file_exists("test6.txt"), "The file is not copied - many files are "
925 "specified as a target\n");
926 DeleteFileA("test6.txt");
927 DeleteFileA("test7.txt");
928 RemoveDirectoryA("test8.txt");
929
930 /* number of sources does not correspond to number of targets */
931 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
932 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
933 retval = SHFileOperationA(&shfo2);
934 if (dir_exists("test6.txt"))
935 {
936 /* Vista and W2K8 (broken or new behavior?) */
937 ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %d\n", retval);
938 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files "
939 "are specified as a target\n");
940 RemoveDirectoryA("test6.txt");
941 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not copied - many files "
942 "are specified as a target\n");
943 RemoveDirectoryA("test7.txt");
944 }
945 else
946 {
947 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
948 ok(!file_exists("test6.txt"), "The file is copied - many files are "
949 "specified as a target\n");
950 }
951
952 set_curr_dir_path(from, "test1.txt\0");
953 set_curr_dir_path(to, "test4.txt\0");
954 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
955 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
956
957 set_curr_dir_path(from, "test?.txt\0");
958 set_curr_dir_path(to, "testdir2\0");
959 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
960 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
961 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
962 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
963 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
964 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
965 clean_after_shfo_tests();
966
967 init_shfo_tests();
968 shfo.fFlags |= FOF_FILESONLY;
969 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
970 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
971 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
972 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
973 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
974 clean_after_shfo_tests();
975
976 init_shfo_tests();
977 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
978 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
979 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
980 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
981 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
982 ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
983 clean_after_shfo_tests();
984
985 /* Copying multiple files with one not existing as source, fails the
986 entire operation in Win98/ME/2K/XP, but not in 95/NT */
987 init_shfo_tests();
988 tmp_flags = shfo.fFlags;
989 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
990 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
991 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
992 retval = SHFileOperationA(&shfo);
993 if (retval == ERROR_SUCCESS)
994 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
995 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
996 else
997 {
998 /* Failure if one source file does not exist */
999 ok(retval == 1026 || /* Win 98/ME/2K/XP */
1000 retval == ERROR_FILE_NOT_FOUND, /* Vista and W2K8 */
1001 "Files are copied to other directory\n");
1002 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
1003 }
1004 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
1005 shfo.fFlags = tmp_flags;
1006
1007 /* copy into a nonexistent directory */
1008 init_shfo_tests();
1009 shfo.fFlags = FOF_NOCONFIRMMKDIR;
1010 set_curr_dir_path(from, "test1.txt\0");
1011 set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
1012 retval= SHFileOperationA(&shfo);
1013 ok(!retval, "Error copying into nonexistent directory\n");
1014 ok(file_exists("nonexistent"), "nonexistent not created\n");
1015 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
1016 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
1017 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
1018
1019 /* a relative dest directory is OK */
1020 clean_after_shfo_tests();
1021 init_shfo_tests();
1022 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1023 shfo.pTo = "testdir2\0";
1024 retval = SHFileOperationA(&shfo);
1025 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1026 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
1027
1028 /* try to overwrite an existing write protected file */
1029 clean_after_shfo_tests();
1030 init_shfo_tests();
1031 tmp_flags = shfo.fFlags;
1032 shfo.pFrom = "test1.txt\0";
1033 shfo.pTo = "test2.txt\0";
1034 /* suppress the error-dialog in win9x here */
1035 shfo.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT;
1036 ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_READONLY);
1037 ok(ret, "Failure to set file attributes (error %x)\n", GetLastError());
1038 retval = CopyFileA(shfo.pFrom, shfo.pTo, FALSE);
1039 ok(!retval && GetLastError() == ERROR_ACCESS_DENIED, "CopyFileA should have fail with ERROR_ACCESS_DENIED\n");
1040 retval = SHFileOperationA(&shfo);
1041 /* Does not work on Win95, Win95B, NT4WS and NT4SRV */
1042 ok(!retval || broken(retval == DE_OPCANCELLED), "SHFileOperationA failed to copy (error %x)\n", retval);
1043 /* Set back normal attributes to make the file deletion succeed */
1044 ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_NORMAL);
1045 ok(ret, "Failure to set file attributes (error %x)\n", GetLastError());
1046 shfo.fFlags = tmp_flags;
1047
1048 /* try to copy files to a file */
1049 clean_after_shfo_tests();
1050 init_shfo_tests();
1051 shfo.pFrom = from;
1052 shfo.pTo = to;
1053 /* suppress the error-dialog in win9x here */
1054 shfo.fFlags |= FOF_NOERRORUI;
1055 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
1056 set_curr_dir_path(to, "test3.txt\0");
1057 shfo.fAnyOperationsAborted = 0xdeadbeef;
1058 retval = SHFileOperationA(&shfo);
1059 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1060 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1061 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1062 if (retval == DE_FLDDESTISFILE || /* Vista and W2K8 */
1063 retval == DE_INVALIDFILES) /* Win7 */
1064 {
1065 /* Most likely new behavior */
1066 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1067 }
1068 else
1069 {
1070 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1071 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
1072 }
1073 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
1074
1075 /* try to copy many files to nonexistent directory */
1076 DeleteFileA(to);
1077 shfo.fFlags &= ~FOF_NOERRORUI;
1078 shfo.fAnyOperationsAborted = 0xdeadbeef;
1079 retval = SHFileOperationA(&shfo);
1080 ok(!shfo.fAnyOperationsAborted ||
1081 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1082 "Didn't expect aborted operations\n");
1083 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1084 ok(DeleteFileA("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
1085 ok(DeleteFileA("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
1086 ok(RemoveDirectoryA(to), "Expected test3.txt to exist\n");
1087
1088 /* send in FOF_MULTIDESTFILES with too many destination files */
1089 init_shfo_tests();
1090 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1091 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
1092 shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
1093 shfo.fAnyOperationsAborted = 0xdeadbeef;
1094 retval = SHFileOperationA(&shfo);
1095 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1096 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1097 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1098 if (dir_exists("testdir2\\a.txt"))
1099 {
1100 /* Vista and W2K8 (broken or new behavior ?) */
1101 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1102 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1103 ok(DeleteFileA("testdir2\\a.txt\\test1.txt"), "Expected testdir2\\a.txt\\test1.txt to exist\n");
1104 RemoveDirectoryA("testdir2\\a.txt");
1105 ok(DeleteFileA("testdir2\\b.txt\\test2.txt"), "Expected testdir2\\b.txt\\test2.txt to exist\n");
1106 RemoveDirectoryA("testdir2\\b.txt");
1107 ok(DeleteFileA("testdir2\\c.txt\\test3.txt"), "Expected testdir2\\c.txt\\test3.txt to exist\n");
1108 RemoveDirectoryA("testdir2\\c.txt");
1109 ok(!file_exists("testdir2\\d.txt"), "Expected testdir2\\d.txt to not exist\n");
1110 }
1111 else
1112 {
1113 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1114 ok(shfo.fAnyOperationsAborted ||
1115 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1116 "Expected aborted operations\n");
1117 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
1118 }
1119
1120 /* send in FOF_MULTIDESTFILES with too many destination files */
1121 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1122 shfo.pTo = "e.txt\0f.txt\0";
1123 shfo.fAnyOperationsAborted = 0xdeadbeef;
1124 retval = SHFileOperationA(&shfo);
1125 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1126 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1127 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1128 if (dir_exists("e.txt"))
1129 {
1130 /* Vista and W2K8 (broken or new behavior ?) */
1131 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1132 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
1133 ok(DeleteFileA("e.txt\\test1.txt"), "Expected e.txt\\test1.txt to exist\n");
1134 RemoveDirectoryA("e.txt");
1135 ok(DeleteFileA("f.txt\\test2.txt"), "Expected f.txt\\test2.txt to exist\n");
1136 RemoveDirectoryA("f.txt");
1137 }
1138 else
1139 {
1140 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1141 ok(shfo.fAnyOperationsAborted ||
1142 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1143 "Expected aborted operations\n");
1144 ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
1145 }
1146
1147 /* use FOF_MULTIDESTFILES with files and a source directory */
1148 shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
1149 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
1150 shfo.fAnyOperationsAborted = 0xdeadbeef;
1151 retval = SHFileOperationA(&shfo);
1152 ok(!shfo.fAnyOperationsAborted ||
1153 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1154 "Didn't expect aborted operations\n");
1155 ok(retval == ERROR_SUCCESS ||
1156 broken(retval == 0x100a1), /* WinMe */
1157 "Expected ERROR_SUCCESS, got %d\n", retval);
1158 ok(DeleteFileA("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
1159 ok(DeleteFileA("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
1160 if (retval == ERROR_SUCCESS)
1161 ok(RemoveDirectoryA("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
1162
1163 /* try many dest files without FOF_MULTIDESTFILES flag */
1164 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1165 shfo.pTo = "a.txt\0b.txt\0c.txt\0";
1166 shfo.fAnyOperationsAborted = 0xdeadbeef;
1167 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1168 retval = SHFileOperationA(&shfo);
1169 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1170 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1171 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1172 if (dir_exists("a.txt"))
1173 {
1174 /* Vista and W2K8 (broken or new behavior ?) */
1175 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1176 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1177 ok(DeleteFileA("a.txt\\test1.txt"), "Expected a.txt\\test1.txt to exist\n");
1178 ok(DeleteFileA("a.txt\\test2.txt"), "Expected a.txt\\test2.txt to exist\n");
1179 ok(DeleteFileA("a.txt\\test3.txt"), "Expected a.txt\\test3.txt to exist\n");
1180 RemoveDirectoryA("a.txt");
1181 }
1182 else
1183 {
1184
1185 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1186 ok(shfo.fAnyOperationsAborted ||
1187 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1188 "Expected aborted operations\n");
1189 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
1190 }
1191
1192 /* try a glob */
1193 shfo.pFrom = "test?.txt\0";
1194 shfo.pTo = "testdir2\0";
1195 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1196 retval = SHFileOperationA(&shfo);
1197 ok(retval == ERROR_SUCCESS ||
1198 broken(retval == 0x100a1), /* WinMe */
1199 "Expected ERROR_SUCCESS, got %d\n", retval);
1200 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1201
1202 /* try a glob with FOF_FILESONLY */
1203 clean_after_shfo_tests();
1204 init_shfo_tests();
1205 shfo.pFrom = "test?.txt\0";
1206 shfo.fFlags |= FOF_FILESONLY;
1207 retval = SHFileOperationA(&shfo);
1208 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1209 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1210 ok(!dir_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
1211
1212 /* try a glob with FOF_MULTIDESTFILES and the same number
1213 * of dest files that we would expect
1214 */
1215 clean_after_shfo_tests();
1216 init_shfo_tests();
1217 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
1218 shfo.fFlags &= ~FOF_FILESONLY;
1219 shfo.fFlags |= FOF_MULTIDESTFILES;
1220 retval = SHFileOperationA(&shfo);
1221 if (dir_exists("testdir2\\a.txt"))
1222 {
1223 /* Vista and W2K8 (broken or new behavior ?) */
1224 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1225 ok(DeleteFileA("testdir2\\a.txt\\test1.txt"), "Expected testdir2\\a.txt\\test1.txt to exist\n");
1226 ok(DeleteFileA("testdir2\\a.txt\\test2.txt"), "Expected testdir2\\a.txt\\test2.txt to exist\n");
1227 ok(DeleteFileA("testdir2\\a.txt\\test3.txt"), "Expected testdir2\\a.txt\\test3.txt to exist\n");
1228 ok(RemoveDirectoryA("testdir2\\a.txt\\test4.txt"), "Expected testdir2\\a.txt\\test4.txt to exist\n");
1229 RemoveDirectoryA("testdir2\\a.txt");
1230 }
1231 else
1232 {
1233 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1234 ok(shfo.fAnyOperationsAborted ||
1235 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1236 "Expected aborted operations\n");
1237 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
1238 }
1239 ok(!RemoveDirectoryA("b.txt"), "b.txt should not exist\n");
1240
1241 /* copy one file to two others, second is ignored */
1242 clean_after_shfo_tests();
1243 init_shfo_tests();
1244 shfo.pFrom = "test1.txt\0";
1245 shfo.pTo = "b.txt\0c.txt\0";
1246 shfo.fAnyOperationsAborted = 0xdeadbeef;
1247 retval = SHFileOperationA(&shfo);
1248 ok(!shfo.fAnyOperationsAborted ||
1249 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1250 "Didn't expect aborted operations\n");
1251 if (retval == DE_OPCANCELLED)
1252 {
1253 /* NT4 fails and doesn't copy any files */
1254 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1255 /* Needed to skip some tests */
1256 win_skip("Skipping some tests on NT4\n");
1257 on_nt4 = TRUE;
1258 }
1259 else
1260 {
1261 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1262 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1263 }
1264 ok(!DeleteFileA("c.txt"), "Expected c.txt to not exist\n");
1265
1266 /* copy two file to three others, all fail */
1267 shfo.pFrom = "test1.txt\0test2.txt\0";
1268 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
1269 shfo.fAnyOperationsAborted = 0xdeadbeef;
1270 retval = SHFileOperationA(&shfo);
1271 if (dir_exists("b.txt"))
1272 {
1273 /* Vista and W2K8 (broken or new behavior ?) */
1274 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1275 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1276 ok(DeleteFileA("b.txt\\test1.txt"), "Expected b.txt\\test1.txt to exist\n");
1277 RemoveDirectoryA("b.txt");
1278 ok(DeleteFileA("c.txt\\test2.txt"), "Expected c.txt\\test2.txt to exist\n");
1279 RemoveDirectoryA("c.txt");
1280 }
1281 else
1282 {
1283 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1284 ok(shfo.fAnyOperationsAborted ||
1285 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1286 "Expected aborted operations\n");
1287 ok(!DeleteFileA("b.txt"), "Expected b.txt to not exist\n");
1288 }
1289
1290 /* copy one file and one directory to three others */
1291 shfo.pFrom = "test1.txt\0test4.txt\0";
1292 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
1293 shfo.fAnyOperationsAborted = 0xdeadbeef;
1294 retval = SHFileOperationA(&shfo);
1295 if (dir_exists("b.txt"))
1296 {
1297 /* Vista and W2K8 (broken or new behavior ?) */
1298 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1299 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1300 ok(DeleteFileA("b.txt\\test1.txt"), "Expected b.txt\\test1.txt to exist\n");
1301 RemoveDirectoryA("b.txt");
1302 ok(RemoveDirectoryA("c.txt\\test4.txt"), "Expected c.txt\\test4.txt to exist\n");
1303 RemoveDirectoryA("c.txt");
1304 }
1305 else
1306 {
1307 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1308 ok(shfo.fAnyOperationsAborted ||
1309 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1310 "Expected aborted operations\n");
1311 ok(!DeleteFileA("b.txt"), "Expected b.txt to not exist\n");
1312 ok(!DeleteFileA("c.txt"), "Expected c.txt to not exist\n");
1313 }
1314
1315 /* copy a directory with a file beneath it, plus some files */
1316 createTestFile("test4.txt\\a.txt");
1317 shfo.pFrom = "test4.txt\0test1.txt\0";
1318 shfo.pTo = "testdir2\0";
1319 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1320 shfo.fAnyOperationsAborted = FALSE;
1321 retval = SHFileOperationA(&shfo);
1322 ok(retval == ERROR_SUCCESS ||
1323 broken(retval == 0x100a1), /* WinMe */
1324 "Expected ERROR_SUCCESS, got %d\n", retval);
1325 if (retval == ERROR_SUCCESS)
1326 {
1327 ok(DeleteFileA("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1328 ok(DeleteFileA("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
1329 ok(RemoveDirectoryA("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
1330 }
1331
1332 /* copy one directory and a file in that dir to another dir */
1333 shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
1334 shfo.pTo = "testdir2\0";
1335 retval = SHFileOperationA(&shfo);
1336 ok(retval == ERROR_SUCCESS ||
1337 broken(retval == 0x100a1), /* WinMe */
1338 "Expected ERROR_SUCCESS, got %d\n", retval);
1339 if (retval == ERROR_SUCCESS)
1340 {
1341 ok(DeleteFileA("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
1342 ok(DeleteFileA("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
1343 }
1344
1345 /* copy a file in a directory first, and then the directory to a nonexistent dir */
1346 shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
1347 shfo.pTo = "nonexistent\0";
1348 retval = SHFileOperationA(&shfo);
1349 if (dir_exists("nonexistent"))
1350 {
1351 /* Vista and W2K8 (broken or new behavior ?) */
1352 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1353 ok(DeleteFileA("nonexistent\\test4.txt\\a.txt"), "Expected nonexistent\\test4.txt\\a.txt to exist\n");
1354 RemoveDirectoryA("nonexistent\\test4.txt");
1355 ok(DeleteFileA("nonexistent\\a.txt"), "Expected nonexistent\\a.txt to exist\n");
1356 RemoveDirectoryA("nonexistent");
1357 }
1358 else
1359 {
1360 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1361 ok(shfo.fAnyOperationsAborted ||
1362 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1363 "Expected aborted operations\n");
1364 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
1365 }
1366 DeleteFileA("test4.txt\\a.txt");
1367
1368 /* destination is same as source file */
1369 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1370 shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
1371 shfo.fAnyOperationsAborted = FALSE;
1372 shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
1373 retval = SHFileOperationA(&shfo);
1374 if (retval == DE_OPCANCELLED)
1375 {
1376 /* NT4 fails and doesn't copy any files */
1377 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1378 }
1379 else
1380 {
1381 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
1382 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1383 }
1384 ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
1385 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
1386
1387 /* destination is same as source directory */
1388 shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
1389 shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
1390 shfo.fAnyOperationsAborted = FALSE;
1391 retval = SHFileOperationA(&shfo);
1392 if (retval == DE_OPCANCELLED)
1393 {
1394 /* NT4 fails and doesn't copy any files */
1395 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1396 }
1397 else
1398 {
1399 ok(retval == ERROR_SUCCESS ||
1400 retval == DE_DESTSAMETREE, /* Vista */
1401 "Expected ERROR_SUCCESS or DE_DESTSAMETREE, got %d\n", retval);
1402 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1403 }
1404 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
1405
1406 /* copy a directory into itself, error displayed in UI */
1407 shfo.pFrom = "test4.txt\0";
1408 shfo.pTo = "test4.txt\\newdir\0";
1409 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1410 shfo.fAnyOperationsAborted = FALSE;
1411 retval = SHFileOperationA(&shfo);
1412 ok(retval == ERROR_SUCCESS ||
1413 retval == DE_DESTSUBTREE, /* Vista */
1414 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1415 ok(!RemoveDirectoryA("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
1416
1417 /* copy a directory to itself, error displayed in UI */
1418 shfo.pFrom = "test4.txt\0";
1419 shfo.pTo = "test4.txt\0";
1420 shfo.fAnyOperationsAborted = FALSE;
1421 retval = SHFileOperationA(&shfo);
1422 ok(retval == ERROR_SUCCESS ||
1423 retval == DE_DESTSUBTREE, /* Vista */
1424 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1425
1426 /* copy a file into a directory, and the directory into itself */
1427 shfo.pFrom = "test1.txt\0test4.txt\0";
1428 shfo.pTo = "test4.txt\0";
1429 shfo.fAnyOperationsAborted = FALSE;
1430 shfo.fFlags |= FOF_NOCONFIRMATION;
1431 retval = SHFileOperationA(&shfo);
1432 ok(retval == ERROR_SUCCESS ||
1433 retval == DE_DESTSUBTREE, /* Vista */
1434 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1435 ok(DeleteFileA("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
1436
1437 /* copy a file to a file, and the directory into itself */
1438 shfo.pFrom = "test1.txt\0test4.txt\0";
1439 shfo.pTo = "test4.txt\\a.txt\0";
1440 shfo.fAnyOperationsAborted = FALSE;
1441 retval = SHFileOperationA(&shfo);
1442 if (dir_exists("test4.txt\\a.txt"))
1443 {
1444 /* Vista and W2K8 (broken or new behavior ?) */
1445 ok(retval == DE_DESTSUBTREE, "Expected DE_DESTSUBTREE, got %d\n", retval);
1446 ok(DeleteFileA("test4.txt\\a.txt\\test1.txt"), "Expected test4.txt\\a.txt\\test1.txt to exist\n");
1447 RemoveDirectoryA("test4.txt\\a.txt");
1448 }
1449 else
1450 {
1451 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1452 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
1453 }
1454
1455 /* copy a nonexistent file to a nonexistent directory */
1456 shfo.pFrom = "e.txt\0";
1457 shfo.pTo = "nonexistent\0";
1458 shfo.fAnyOperationsAborted = FALSE;
1459 retval = SHFileOperationA(&shfo);
1460 ok(retval == 1026 ||
1461 retval == ERROR_FILE_NOT_FOUND || /* Vista */
1462 broken(retval == ERROR_SUCCESS), /* NT4 */
1463 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", retval);
1464 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
1465 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
1466
1467 /* Overwrite tests */
1468 clean_after_shfo_tests();
1469 init_shfo_tests();
1470 if (!on_nt4)
1471 {
1472 /* NT4 would throw up some dialog boxes and doesn't copy files that are needed
1473 * in subsequent tests.
1474 */
1475 shfo.fFlags = FOF_NOCONFIRMATION;
1476 shfo.pFrom = "test1.txt\0";
1477 shfo.pTo = "test2.txt\0";
1478 shfo.fAnyOperationsAborted = 0xdeadbeef;
1479 /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
1480 retval = SHFileOperationA(&shfo);
1481 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1482 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1483 ok(file_has_content("test2.txt", "test1.txt\n"), "The file was not copied\n");
1484
1485 shfo.pFrom = "test3.txt\0test1.txt\0";
1486 shfo.pTo = "test2.txt\0one.txt\0";
1487 shfo.fFlags = FOF_NOCONFIRMATION | FOF_MULTIDESTFILES;
1488 /* without FOF_NOCONFIRMATION the confirmation is Yes/Yes to All/No/Cancel */
1489 retval = SHFileOperationA(&shfo);
1490 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1491 ok(file_has_content("test2.txt", "test3.txt\n"), "The file was not copied\n");
1492
1493 shfo.pFrom = "one.txt\0";
1494 shfo.pTo = "testdir2\0";
1495 shfo.fFlags = FOF_NOCONFIRMATION;
1496 /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
1497 retval = SHFileOperationA(&shfo);
1498 ok(retval == 0, "Expected 0, got %d\n", retval);
1499 ok(file_has_content("testdir2\\one.txt", "test1.txt\n"), "The file was not copied\n");
1500 }
1501
1502 createTestFile("test4.txt\\test1.txt");
1503 shfo.pFrom = "test4.txt\0";
1504 shfo.pTo = "testdir2\0";
1505 /* WinMe needs FOF_NOERRORUI */
1506 shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI;
1507 retval = SHFileOperationA(&shfo);
1508 ok(retval == ERROR_SUCCESS ||
1509 broken(retval == 0x100a1), /* WinMe */
1510 "Expected ERROR_SUCCESS, got %d\n", retval);
1511 shfo.fFlags = FOF_NOCONFIRMATION;
1512 if (ERROR_SUCCESS)
1513 {
1514 createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */
1515 /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */
1516 retval = SHFileOperationA(&shfo);
1517 ok(retval == 0, "Expected 0, got %d\n", retval);
1518 ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
1519 }
1520
1521 createTestFile("one.txt");
1522
1523 /* pFrom contains bogus 2nd name longer than MAX_PATH */
1524 memset(from, 'a', MAX_PATH*2);
1525 memset(from+MAX_PATH*2, 0, 2);
1526 lstrcpyA(from, "one.txt");
1527 shfo.pFrom = from;
1528 shfo.pTo = "two.txt\0";
1529 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1530 retval = SHFileOperationA(&shfo);
1531 ok(retval == 1148 || retval == 1026 ||
1532 retval == ERROR_ACCESS_DENIED || /* win2k */
1533 retval == DE_INVALIDFILES, /* Vista */
1534 "Unexpected return value, got %d\n", retval);
1535 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1536 if (dir_exists("two.txt"))
1537 /* Vista and W2K8 (broken or new behavior ?) */
1538 ok(RemoveDirectoryA("two.txt"), "Expected two.txt to exist\n");
1539 else
1540 ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
1541
1542 createTestFile("one.txt");
1543
1544 /* pTo contains bogus 2nd name longer than MAX_PATH */
1545 memset(to, 'a', MAX_PATH*2);
1546 memset(to+MAX_PATH*2, 0, 2);
1547 lstrcpyA(to, "two.txt");
1548 shfo.pFrom = "one.txt\0";
1549 shfo.pTo = to;
1550 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1551 retval = SHFileOperationA(&shfo);
1552 if (retval == DE_OPCANCELLED)
1553 {
1554 /* NT4 fails and doesn't copy any files */
1555 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1556 }
1557 else
1558 {
1559 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1560 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1561 }
1562 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1563
1564 createTestFile("one.txt");
1565
1566 /* no FOF_MULTIDESTFILES, two files in pTo */
1567 shfo.pFrom = "one.txt\0";
1568 shfo.pTo = "two.txt\0three.txt\0";
1569 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1570 retval = SHFileOperationA(&shfo);
1571 if (retval == DE_OPCANCELLED)
1572 {
1573 /* NT4 fails and doesn't copy any files */
1574 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1575 }
1576 else
1577 {
1578 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1579 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1580 }
1581 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1582
1583 createTestFile("one.txt");
1584
1585 /* both pFrom and pTo contain bogus 2nd names longer than MAX_PATH */
1586 memset(from, 'a', MAX_PATH*2);
1587 memset(from+MAX_PATH*2, 0, 2);
1588 memset(to, 'a', MAX_PATH*2);
1589 memset(to+MAX_PATH*2, 0, 2);
1590 lstrcpyA(from, "one.txt");
1591 lstrcpyA(to, "two.txt");
1592 shfo.pFrom = from;
1593 shfo.pTo = to;
1594 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1595 retval = SHFileOperationA(&shfo);
1596 ok(retval == 1148 || retval == 1026 ||
1597 retval == ERROR_ACCESS_DENIED || /* win2k */
1598 retval == DE_INVALIDFILES, /* Vista */
1599 "Unexpected return value, got %d\n", retval);
1600 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1601 if (dir_exists("two.txt"))
1602 /* Vista and W2K8 (broken or new behavior ?) */
1603 ok(RemoveDirectoryA("two.txt"), "Expected two.txt to exist\n");
1604 else
1605 ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
1606
1607 createTestFile("one.txt");
1608
1609 /* pTo contains bogus 2nd name longer than MAX_PATH, FOF_MULTIDESTFILES */
1610 memset(to, 'a', MAX_PATH*2);
1611 memset(to+MAX_PATH*2, 0, 2);
1612 lstrcpyA(to, "two.txt");
1613 shfo.pFrom = "one.txt\0";
1614 shfo.pTo = to;
1615 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1616 FOF_SILENT | FOF_NOERRORUI;
1617 retval = SHFileOperationA(&shfo);
1618 if (retval == DE_OPCANCELLED)
1619 {
1620 /* NT4 fails and doesn't copy any files */
1621 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1622 }
1623 else
1624 {
1625 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1626 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1627 }
1628 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1629
1630 createTestFile("one.txt");
1631 createTestFile("two.txt");
1632
1633 /* pTo contains bogus 2nd name longer than MAX_PATH,
1634 * multiple source files,
1635 * dest directory does not exist
1636 */
1637 memset(to, 'a', 2 * MAX_PATH);
1638 memset(to+MAX_PATH*2, 0, 2);
1639 lstrcpyA(to, "threedir");
1640 shfo.pFrom = "one.txt\0two.txt\0";
1641 shfo.pTo = to;
1642 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1643 retval = SHFileOperationA(&shfo);
1644 if (dir_exists("threedir"))
1645 {
1646 /* Vista and W2K8 (broken or new behavior ?) */
1647 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1648 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1649 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1650 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1651 }
1652 else
1653 {
1654 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1655 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1656 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1657 ok(!DeleteFileA("threedir"), "Expected file to not exist\n");
1658 ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1659 }
1660 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1661 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1662
1663 createTestFile("one.txt");
1664 createTestFile("two.txt");
1665 CreateDirectoryA("threedir", NULL);
1666
1667 /* pTo contains bogus 2nd name longer than MAX_PATH,
1668 * multiple source files,
1669 * dest directory does exist
1670 */
1671 memset(to, 'a', 2 * MAX_PATH);
1672 memset(to+MAX_PATH*2, 0, 2);
1673 lstrcpyA(to, "threedir");
1674 shfo.pFrom = "one.txt\0two.txt\0";
1675 shfo.pTo = to;
1676 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1677 retval = SHFileOperationA(&shfo);
1678 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1679 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1680 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1681 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1682 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1683 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1684
1685 if (0) {
1686 /* this crashes on win9x */
1687 createTestFile("one.txt");
1688 createTestFile("two.txt");
1689
1690 /* pTo contains bogus 2nd name longer than MAX_PATH,
1691 * multiple source files, FOF_MULTIDESTFILES
1692 * dest dir does not exist
1693 */
1694
1695 memset(to, 'a', 2 * MAX_PATH);
1696 memset(to+MAX_PATH*2, 0, 2);
1697 lstrcpyA(to, "threedir");
1698 shfo.pFrom = "one.txt\0two.txt\0";
1699 shfo.pTo = to;
1700 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1701 FOF_SILENT | FOF_NOERRORUI;
1702 retval = SHFileOperationA(&shfo);
1703 ok(retval == ERROR_CANCELLED ||
1704 retval == ERROR_SUCCESS, /* win2k3 */
1705 "Expected ERROR_CANCELLED or ERROR_SUCCESS, got %d\n", retval);
1706 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1707 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1708 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1709 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1710 ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1711
1712 /* file exists in win2k */
1713 DeleteFileA("threedir");
1714 }
1715
1716
1717 createTestFile("one.txt");
1718 createTestFile("two.txt");
1719 CreateDirectoryA("threedir", NULL);
1720
1721 /* pTo contains bogus 2nd name longer than MAX_PATH,
1722 * multiple source files, FOF_MULTIDESTFILES
1723 * dest dir does exist
1724 */
1725 memset(to, 'a', 2 * MAX_PATH);
1726 memset(to+MAX_PATH*2, 0, 2);
1727 lstrcpyA(to, "threedir");
1728 ptr = to + lstrlenA(to) + 1;
1729 lstrcpyA(ptr, "fourdir");
1730 shfo.pFrom = "one.txt\0two.txt\0";
1731 shfo.pTo = to;
1732 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1733 FOF_SILENT | FOF_NOERRORUI;
1734 retval = SHFileOperationA(&shfo);
1735 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1736 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1737 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1738 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1739 if (dir_exists("fourdir"))
1740 {
1741 /* Vista and W2K8 (broken or new behavior ?) */
1742 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1743 ok(DeleteFileA("fourdir\\two.txt"), "Expected file to exist\n");
1744 RemoveDirectoryA("fourdir");
1745 }
1746 else
1747 {
1748 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1749 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1750 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1751 }
1752 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1753
1754 createTestFile("one.txt");
1755 createTestFile("two.txt");
1756 CreateDirectoryA("threedir", NULL);
1757
1758 /* multiple source files, FOF_MULTIDESTFILES
1759 * multiple dest files, but first dest dir exists
1760 * num files in lists is equal
1761 */
1762 shfo.pFrom = "one.txt\0two.txt\0";
1763 shfo.pTo = "threedir\0fourdir\0";
1764 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1765 FOF_SILENT | FOF_NOERRORUI;
1766 retval = SHFileOperationA(&shfo);
1767 ok(retval == ERROR_CANCELLED ||
1768 retval == DE_FILEDESTISFLD || /* Vista */
1769 broken(retval == DE_OPCANCELLED), /* Win9x, NT4 */
1770 "Expected ERROR_CANCELLED or DE_FILEDESTISFLD. got %d\n", retval);
1771 if (file_exists("threedir\\threedir"))
1772 {
1773 /* NT4 */
1774 ok(DeleteFileA("threedir\\threedir"), "Expected file to exist\n");
1775 }
1776 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1777 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1778 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1779 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1780 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1781 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1782 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1783
1784 createTestFile("one.txt");
1785 createTestFile("two.txt");
1786 CreateDirectoryA("threedir", NULL);
1787
1788 /* multiple source files, FOF_MULTIDESTFILES
1789 * multiple dest files, but first dest dir exists
1790 * num files in lists is not equal
1791 */
1792 shfo.pFrom = "one.txt\0two.txt\0";
1793 shfo.pTo = "threedir\0fourdir\0five\0";
1794 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1795 FOF_SILENT | FOF_NOERRORUI;
1796 retval = SHFileOperationA(&shfo);
1797 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1798 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1799 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1800 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1801 if (dir_exists("fourdir"))
1802 {
1803 /* Vista and W2K8 (broken or new behavior ?) */
1804 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1805 ok(DeleteFileA("fourdir\\two.txt"), "Expected file to exist\n");
1806 RemoveDirectoryA("fourdir");
1807 }
1808 else
1809 {
1810 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1811 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1812 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1813 }
1814 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1815 ok(!DeleteFileA("five"), "Expected file to not exist\n");
1816 ok(!RemoveDirectoryA("five"), "Expected dir to not exist\n");
1817
1818 createTestFile("aa.txt");
1819 createTestFile("ab.txt");
1820 CreateDirectoryA("one", NULL);
1821 CreateDirectoryA("two", NULL);
1822
1823 /* pFrom has a glob, pTo has more than one dest */
1824 shfo.pFrom = "a*.txt\0";
1825 shfo.pTo = "one\0two\0";
1826 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1827 retval = SHFileOperationA(&shfo);
1828 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1829 ok(DeleteFileA("one\\aa.txt"), "Expected file to exist\n");
1830 ok(DeleteFileA("one\\ab.txt"), "Expected file to exist\n");
1831 ok(!DeleteFileA("two\\aa.txt"), "Expected file to not exist\n");
1832 ok(!DeleteFileA("two\\ab.txt"), "Expected file to not exist\n");
1833 ok(DeleteFileA("aa.txt"), "Expected file to exist\n");
1834 ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
1835 ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
1836 ok(RemoveDirectoryA("two"), "Expected dir to exist\n");
1837
1838 /* pTo is an empty string */
1839 CreateDirectoryA("dir", NULL);
1840 createTestFile("dir\\abcdefgh.abc");
1841 shfo.pFrom = "dir\\abcdefgh.abc\0";
1842 shfo.pTo = "\0";
1843 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1844 retval = SHFileOperationA(&shfo);
1845 ok(retval == ERROR_SUCCESS ||
1846 broken(retval == DE_OPCANCELLED), /* NT4 */
1847 "Expected ERROR_SUCCESS, got %d\n", retval);
1848 if (retval == ERROR_SUCCESS)
1849 ok(DeleteFileA("abcdefgh.abc"), "Expected file to exist\n");
1850 ok(DeleteFileA("dir\\abcdefgh.abc"), "Expected file to exist\n");
1851 ok(RemoveDirectoryA("dir"), "Expected dir to exist\n");
1852
1853 /* Check last error after a successful file operation. */
1854 clean_after_shfo_tests();
1855 init_shfo_tests();
1856 shfo.pFrom = "test1.txt\0";
1857 shfo.pTo = "testdir2\0";
1858 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1859 SetLastError(0xdeadbeef);
1860 retval = SHFileOperationA(&shfo);
1861 ok(retval == ERROR_SUCCESS, "File copy failed with %d\n", retval);
1862 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1863 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
1864
1865 /* Check last error after a failed file operation. */
1866 clean_after_shfo_tests();
1867 init_shfo_tests();
1868 shfo.pFrom = "nonexistent\0";
1869 shfo.pTo = "testdir2\0";
1870 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1871 SetLastError(0xdeadbeef);
1872 retval = SHFileOperationA(&shfo);
1873 ok(retval != ERROR_SUCCESS, "Unexpected ERROR_SUCCESS\n");
1874 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1875 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
1876
1877 /* test with / */
1878 CreateDirectoryA("dir", NULL);
1879 CreateDirectoryA("dir\\subdir", NULL);
1880 createTestFile("dir\\subdir\\aa.txt");
1881 shfo.pFrom = "dir/subdir/aa.txt\0";
1882 shfo.pTo = "dir\\destdir/aa.txt\0";
1883 shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT | FOF_NOERRORUI;
1884 retval = SHFileOperationA(&shfo);
1885 if (dir_exists("dir\\destdir"))
1886 {
1887 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1888 ok(DeleteFileA("dir\\destdir\\aa.txt"), "Expected file to exist\n");
1889 ok(RemoveDirectoryA("dir\\destdir"), "Expected dir to exist\n");
1890 }
1891 else
1892 {
1893 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* WinXp, Win2k */);
1894 }
1895 ok(DeleteFileA("dir\\subdir\\aa.txt"), "Expected file to exist\n");
1896 ok(RemoveDirectoryA("dir\\subdir"), "Expected dir to exist\n");
1897 ok(RemoveDirectoryA("dir"), "Expected dir to exist\n");
1898 }
1899
1900 /* tests the FO_MOVE action */
1901 static void test_move(void)
1902 {
1903 SHFILEOPSTRUCTA shfo, shfo2;
1904 CHAR from[5*MAX_PATH];
1905 CHAR to[5*MAX_PATH];
1906 DWORD retval;
1907
1908 clean_after_shfo_tests();
1909 init_shfo_tests();
1910
1911 shfo.hwnd = NULL;
1912 shfo.wFunc = FO_MOVE;
1913 shfo.pFrom = from;
1914 shfo.pTo = to;
1915 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR;
1916 shfo.hNameMappings = NULL;
1917 shfo.lpszProgressTitle = NULL;
1918 shfo.fAnyOperationsAborted = FALSE;
1919
1920 set_curr_dir_path(from, "testdir2\\*.*\0");
1921 set_curr_dir_path(to, "test4.txt\\*.*\0");
1922 retval = SHFileOperationA(&shfo);
1923 ok(retval != 0, "SHFileOperation should fail\n");
1924 ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
1925
1926 ok(file_exists("testdir2"), "dir should not be moved\n");
1927 ok(file_exists("testdir2\\one.txt"), "file should not be moved\n");
1928 ok(file_exists("testdir2\\nested"), "dir should not be moved\n");
1929 ok(file_exists("testdir2\\nested\\two.txt"), "file should not be moved\n");
1930
1931 set_curr_dir_path(from, "testdir2\\*.*\0");
1932 set_curr_dir_path(to, "test4.txt\0");
1933 retval = SHFileOperationA(&shfo);
1934 ok(!retval, "SHFileOperation error %#x\n", retval);
1935 ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
1936
1937 ok(file_exists("testdir2"), "dir should not be moved\n");
1938 ok(!file_exists("testdir2\\one.txt"), "file should be moved\n");
1939 ok(!file_exists("testdir2\\nested"), "dir should be moved\n");
1940 ok(!file_exists("testdir2\\nested\\two.txt"), "file should be moved\n");
1941
1942 ok(file_exists("test4.txt"), "dir should exist\n");
1943 ok(file_exists("test4.txt\\one.txt"), "file should exist\n");
1944 ok(file_exists("test4.txt\\nested"), "dir should exist\n");
1945 ok(file_exists("test4.txt\\nested\\two.txt"), "file should exist\n");
1946
1947 clean_after_shfo_tests();
1948 init_shfo_tests();
1949
1950 /* same tests above, but with / */
1951 set_curr_dir_path(from, "testdir2/*.*\0");
1952 set_curr_dir_path(to, "test4.txt\0");
1953 retval = SHFileOperationA(&shfo);
1954 ok(retval == ERROR_SUCCESS ||
1955 broken(retval == ERROR_FILE_NOT_FOUND), /* WinXp, Win2k3 */
1956 "Expected ERROR_SUCCESS, got %d\n", retval);
1957 if (retval == ERROR_SUCCESS)
1958 {
1959 ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
1960
1961 ok(dir_exists("testdir2"), "dir should not be moved\n");
1962 ok(!file_exists("testdir2\\one.txt"), "file should be moved\n");
1963 ok(!dir_exists("testdir2\\nested"), "dir should be moved\n");
1964 ok(!file_exists("testdir2\\nested\\two.txt"), "file should be moved\n");
1965
1966 ok(file_exists("test4.txt\\one.txt"), "file should exist\n");
1967 ok(dir_exists("test4.txt\\nested"), "dir should exist\n");
1968 ok(file_exists("test4.txt\\nested\\two.txt"), "file should exist\n");
1969 }
1970
1971 clean_after_shfo_tests();
1972 init_shfo_tests();
1973
1974 shfo.hwnd = NULL;
1975 shfo.wFunc = FO_MOVE;
1976 shfo.pFrom = from;
1977 shfo.pTo = to;
1978 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1979 shfo.hNameMappings = NULL;
1980 shfo.lpszProgressTitle = NULL;
1981
1982 set_curr_dir_path(from, "test1.txt\0");
1983 set_curr_dir_path(to, "test4.txt\0");
1984 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
1985 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
1986 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
1987
1988 set_curr_dir_path(from, "test?.txt\0");
1989 set_curr_dir_path(to, "testdir2\0");
1990 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
1991 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
1992 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
1993 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
1994 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
1995 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
1996
1997 clean_after_shfo_tests();
1998 init_shfo_tests();
1999
2000 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
2001 shfo2.fFlags |= FOF_MULTIDESTFILES;
2002
2003 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
2004 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
2005 if (old_shell32)
2006 shfo2.fFlags |= FOF_NOCONFIRMMKDIR;
2007 ok(!SHFileOperationA(&shfo2), "Move many files\n");
2008 ok(DeleteFileA("test6.txt"), "The file is not moved - many files are "
2009 "specified as a target\n");
2010 ok(DeleteFileA("test7.txt"), "The file is not moved\n");
2011 ok(RemoveDirectoryA("test8.txt"), "The directory is not moved\n");
2012
2013 init_shfo_tests();
2014
2015 /* number of sources does not correspond to number of targets,
2016 include directories */
2017 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
2018 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
2019 retval = SHFileOperationA(&shfo2);
2020 if (dir_exists("test6.txt"))
2021 {
2022 if (retval == ERROR_SUCCESS)
2023 {
2024 /* Old shell32 */
2025 DeleteFileA("test6.txt\\test1.txt");
2026 DeleteFileA("test6.txt\\test2.txt");
2027 RemoveDirectoryA("test6.txt\\test4.txt");
2028 RemoveDirectoryA("test6.txt");
2029 }
2030 else
2031 {
2032 /* Vista and W2K8 (broken or new behavior ?) */
2033 ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %d\n", retval);
2034 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved\n");
2035 RemoveDirectoryA("test6.txt");
2036 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not moved\n");
2037 RemoveDirectoryA("test7.txt");
2038 }
2039 }
2040 else
2041 {
2042 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2043 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2044 "specified as a target\n");
2045 }
2046
2047 init_shfo_tests();
2048 /* number of sources does not correspond to number of targets,
2049 files only,
2050 from exceeds to */
2051 set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0");
2052 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
2053 retval = SHFileOperationA(&shfo2);
2054 if (dir_exists("test6.txt"))
2055 {
2056 if (retval == ERROR_SUCCESS)
2057 {
2058 /* Old shell32 */
2059 DeleteFileA("test6.txt\\test1.txt");
2060 DeleteFileA("test6.txt\\test2.txt");
2061 RemoveDirectoryA("test6.txt\\test4.txt");
2062 RemoveDirectoryA("test6.txt");
2063 }
2064 else
2065 {
2066 /* Vista and W2K8 (broken or new behavior ?) */
2067 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
2068 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved\n");
2069 RemoveDirectoryA("test6.txt");
2070 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not moved\n");
2071 RemoveDirectoryA("test7.txt");
2072 ok(file_exists("test3.txt"), "File should not be moved\n");
2073 }
2074 }
2075 else
2076 {
2077 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2078 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2079 "specified as a target\n");
2080 }
2081
2082 init_shfo_tests();
2083 /* number of sources does not correspond to number of targets,
2084 files only,
2085 too exceeds from */
2086 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
2087 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
2088 retval = SHFileOperationA(&shfo2);
2089 if (dir_exists("test6.txt"))
2090 {
2091 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2092 ok(DeleteFileA("test6.txt\\test1.txt"),"The file is not moved\n");
2093 ok(DeleteFileA("test7.txt\\test2.txt"),"The file is not moved\n");
2094 ok(!dir_exists("test8.txt") && !file_exists("test8.txt"),
2095 "Directory should not be created\n");
2096 RemoveDirectoryA("test6.txt");
2097 RemoveDirectoryA("test7.txt");
2098 }
2099 else
2100 {
2101 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* WinXp, Win2k */);
2102 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2103 "specified as a target\n");
2104 }
2105
2106 init_shfo_tests();
2107 /* number of sources does not correspond to number of targets,
2108 target directories */
2109 set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0");
2110 set_curr_dir_path(to, "test4.txt\0test5.txt\0");
2111 retval = SHFileOperationA(&shfo2);
2112 if (dir_exists("test5.txt"))
2113 {
2114 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
2115 ok(DeleteFileA("test4.txt\\test1.txt"),"The file is not moved\n");
2116 ok(DeleteFileA("test5.txt\\test2.txt"),"The file is not moved\n");
2117 ok(file_exists("test3.txt"), "The file is not moved\n");
2118 RemoveDirectoryA("test4.txt");
2119 RemoveDirectoryA("test5.txt");
2120 }
2121 else
2122 {
2123 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2124 ok(DeleteFileA("test4.txt\\test1.txt"),"The file is not moved\n");
2125 ok(DeleteFileA("test4.txt\\test2.txt"),"The file is not moved\n");
2126 ok(DeleteFileA("test4.txt\\test3.txt"),"The file is not moved\n");
2127 }
2128
2129
2130 init_shfo_tests();
2131 /* 0 incoming files */
2132 set_curr_dir_path(from, "\0\0");
2133 set_curr_dir_path(to, "test6.txt\0\0");
2134 retval = SHFileOperationA(&shfo2);
2135 ok(retval == ERROR_SUCCESS || retval == ERROR_ACCESS_DENIED
2136 , "Expected ERROR_SUCCESS || ERROR_ACCESS_DENIED, got %d\n", retval);
2137 ok(!file_exists("test6.txt"), "The file should not exist\n");
2138
2139 init_shfo_tests();
2140 /* 0 outgoing files */
2141 set_curr_dir_path(from, "test1\0\0");
2142 set_curr_dir_path(to, "\0\0");
2143 retval = SHFileOperationA(&shfo2);
2144 ok(retval == ERROR_FILE_NOT_FOUND ||
2145 broken(retval == 1026)
2146 , "Expected ERROR_FILE_NOT_FOUND, got %d\n", retval);
2147 ok(!file_exists("test6.txt"), "The file should not exist\n");
2148
2149 init_shfo_tests();
2150
2151 set_curr_dir_path(from, "test3.txt\0");
2152 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
2153 ok(!SHFileOperationA(&shfo), "Can't move file to other directory\n");
2154 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
2155
2156 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
2157 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
2158 if (old_shell32)
2159 shfo.fFlags |= FOF_NOCONFIRMMKDIR;
2160 retval = SHFileOperationA(&shfo);
2161 if (dir_exists("test6.txt"))
2162 {
2163 /* Old shell32 */
2164 /* Vista and W2K8 (broken or new behavior ?) */
2165 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2166 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved. Many files are specified\n");
2167 ok(DeleteFileA("test6.txt\\test2.txt"), "The file is not moved. Many files are specified\n");
2168 ok(DeleteFileA("test6.txt\\test4.txt\\test1.txt"), "The file is not moved. Many files are specified\n");
2169 ok(RemoveDirectoryA("test6.txt\\test4.txt"), "The directory is not moved. Many files are specified\n");
2170 RemoveDirectoryA("test6.txt");
2171 init_shfo_tests();
2172 }
2173 else
2174 {
2175 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2176 ok(file_exists("test1.txt"), "The file is moved. Many files are specified\n");
2177 ok(dir_exists("test4.txt"), "The directory is moved. Many files are specified\n");
2178 }
2179
2180 set_curr_dir_path(from, "test1.txt\0");
2181 set_curr_dir_path(to, "test6.txt\0");
2182 ok(!SHFileOperationA(&shfo), "Move file failed\n");
2183 ok(!file_exists("test1.txt"), "The file is not moved\n");
2184 ok(file_exists("test6.txt"), "The file is not moved\n");
2185 set_curr_dir_path(from, "test6.txt\0");
2186 set_curr_dir_path(to, "test1.txt\0");
2187 ok(!SHFileOperationA(&shfo), "Move file back failed\n");
2188
2189 set_curr_dir_path(from, "test4.txt\0");
2190 set_curr_dir_path(to, "test6.txt\0");
2191 ok(!SHFileOperationA(&shfo), "Move dir failed\n");
2192 ok(!dir_exists("test4.txt"), "The dir is not moved\n");
2193 ok(dir_exists("test6.txt"), "The dir is moved\n");
2194 set_curr_dir_path(from, "test6.txt\0");
2195 set_curr_dir_path(to, "test4.txt\0");
2196 ok(!SHFileOperationA(&shfo), "Move dir back failed\n");
2197
2198 /* move one file to two others */
2199 init_shfo_tests();
2200 shfo.pFrom = "test1.txt\0";
2201 shfo.pTo = "a.txt\0b.txt\0";
2202 retval = SHFileOperationA(&shfo);
2203 if (retval == DE_OPCANCELLED)
2204 {
2205 /* NT4 fails and doesn't move any files */
2206 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
2207 DeleteFileA("test1.txt");
2208 }
2209 else
2210 {
2211 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2212 if (old_shell32)
2213 {
2214 DeleteFileA("a.txt\\a.txt");
2215 RemoveDirectoryA("a.txt");
2216 }
2217 else
2218 ok(DeleteFileA("a.txt"), "Expected a.txt to exist\n");
2219 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
2220 }
2221 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
2222
2223 /* move two files to one other */
2224 shfo.pFrom = "test2.txt\0test3.txt\0";
2225 shfo.pTo = "test1.txt\0";
2226 retval = SHFileOperationA(&shfo);
2227 if (dir_exists("test1.txt"))
2228 {
2229 /* Old shell32 */
2230 /* Vista and W2K8 (broken or new behavior ?) */
2231 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2232 ok(DeleteFileA("test1.txt\\test2.txt"), "Expected test1.txt\\test2.txt to exist\n");
2233 ok(DeleteFileA("test1.txt\\test3.txt"), "Expected test1.txt\\test3.txt to exist\n");
2234 RemoveDirectoryA("test1.txt");
2235 createTestFile("test2.txt");
2236 createTestFile("test3.txt");
2237 }
2238 else
2239 {
2240 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2241 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
2242 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
2243 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
2244 }
2245
2246 /* move a directory into itself */
2247 shfo.pFrom = "test4.txt\0";
2248 shfo.pTo = "test4.txt\\b.txt\0";
2249 retval = SHFileOperationA(&shfo);
2250 ok(retval == ERROR_SUCCESS ||
2251 retval == DE_DESTSUBTREE, /* Vista */
2252 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
2253 ok(!RemoveDirectoryA("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
2254 ok(dir_exists("test4.txt"), "Expected test4.txt to exist\n");
2255
2256 /* move many files without FOF_MULTIDESTFILES */
2257 shfo.pFrom = "test2.txt\0test3.txt\0";
2258 shfo.pTo = "d.txt\0e.txt\0";
2259 retval = SHFileOperationA(&shfo);
2260 if (dir_exists("d.txt"))
2261 {
2262 /* Old shell32 */
2263 /* Vista and W2K8 (broken or new behavior ?) */
2264 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2265 ok(DeleteFileA("d.txt\\test2.txt"), "Expected d.txt\\test2.txt to exist\n");
2266 ok(DeleteFileA("d.txt\\test3.txt"), "Expected d.txt\\test3.txt to exist\n");
2267 RemoveDirectoryA("d.txt");
2268 createTestFile("test2.txt");
2269 createTestFile("test3.txt");
2270 }
2271 else
2272 {
2273 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2274 ok(!DeleteFileA("d.txt"), "Expected d.txt to not exist\n");
2275 ok(!DeleteFileA("e.txt"), "Expected e.txt to not exist\n");
2276 }
2277
2278 /* number of sources != number of targets */
2279 shfo.pTo = "d.txt\0";
2280 shfo.fFlags |= FOF_MULTIDESTFILES;
2281 retval = SHFileOperationA(&shfo);
2282 if (dir_exists("d.txt"))
2283 {
2284 if (old_shell32)
2285 {
2286 DeleteFileA("d.txt\\test2.txt");
2287 DeleteFileA("d.txt\\test3.txt");
2288 RemoveDirectoryA("d.txt");
2289 createTestFile("test2.txt");
2290 }
2291 else
2292 {
2293 /* Vista and W2K8 (broken or new behavior ?) */
2294 ok(retval == DE_SAMEFILE,
2295 "Expected DE_SAMEFILE, got %d\n", retval);
2296 ok(DeleteFileA("d.txt\\test2.txt"), "Expected d.txt\\test2.txt to exist\n");
2297 ok(!file_exists("d.txt\\test3.txt"), "Expected d.txt\\test3.txt to not exist\n");
2298 RemoveDirectoryA("d.txt");
2299 createTestFile("test2.txt");
2300 }
2301 }
2302 else
2303 {
2304 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2305 ok(!DeleteFileA("d.txt"), "Expected d.txt to not exist\n");
2306 }
2307
2308 /* FO_MOVE should create dest directories */
2309 shfo.pFrom = "test2.txt\0";
2310 shfo.pTo = "dir1\\dir2\\test2.txt\0";
2311 retval = SHFileOperationA(&shfo);
2312 if (dir_exists("dir1"))
2313 {
2314 /* New behavior on Vista or later */
2315 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2316 ok(DeleteFileA("dir1\\dir2\\test2.txt"), "Expected dir1\\dir2\\test2.txt to exist\n");
2317 RemoveDirectoryA("dir1\\dir2");
2318 RemoveDirectoryA("dir1");
2319 createTestFile("test2.txt");
2320 }
2321 else
2322 {
2323 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2324 }
2325
2326 /* try to overwrite an existing file */
2327 shfo.pTo = "test3.txt\0";
2328 retval = SHFileOperationA(&shfo);
2329 if (retval == DE_OPCANCELLED)
2330 {
2331 /* NT4 fails and doesn't move any files */
2332 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
2333 }
2334 else
2335 {
2336 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2337 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
2338 if (old_shell32)
2339 {
2340 DeleteFileA("test3.txt\\test3.txt");
2341 RemoveDirectoryA("test3.txt");
2342 }
2343 else
2344 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
2345 }
2346 }
2347
2348 static void test_sh_create_dir(void)
2349 {
2350 CHAR path[MAX_PATH];
2351 int ret;
2352
2353 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2354 ret = SHCreateDirectoryExA(NULL, path, NULL);
2355 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
2356 ok(file_exists("testdir2"), "The first directory is not created\n");
2357 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
2358
2359 ret = SHCreateDirectoryExA(NULL, path, NULL);
2360 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
2361
2362 ret = SHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
2363 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory, ret = %d\n", ret);
2364 ok(file_exists("c:\\testdir3"), "The directory is not created\n");
2365 }
2366
2367 static void test_sh_path_prepare(void)
2368 {
2369 HRESULT res;
2370 CHAR path[MAX_PATH];
2371 CHAR UNICODE_PATH_A[MAX_PATH];
2372 BOOL UsedDefaultChar;
2373
2374 /* directory exists, SHPPFW_NONE */
2375 set_curr_dir_path(path, "testdir2\0");
2376 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2377 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2378
2379 /* directory exists, SHPPFW_IGNOREFILENAME */
2380 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2381 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
2382 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2383
2384 /* directory exists, SHPPFW_DIRCREATE */
2385 set_curr_dir_path(path, "testdir2\0");
2386 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
2387 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2388
2389 /* directory exists, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
2390 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2391 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
2392 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2393 ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
2394
2395 /* file exists, SHPPFW_NONE */
2396 set_curr_dir_path(path, "test1.txt\0");
2397 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2398 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
2399 res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
2400 res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
2401 "Unexpected result : 0x%08x\n", res);
2402
2403 /* file exists, SHPPFW_DIRCREATE */
2404 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
2405 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
2406 res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
2407 res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
2408 "Unexpected result : 0x%08x\n", res);
2409
2410 /* file exists, SHPPFW_NONE, trailing \ */
2411 set_curr_dir_path(path, "test1.txt\\\0");
2412 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2413 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
2414 res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
2415 res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
2416 "Unexpected result : 0x%08x\n", res);
2417
2418 /* relative path exists, SHPPFW_DIRCREATE */
2419 res = SHPathPrepareForWriteA(0, 0, ".\\testdir2", SHPPFW_DIRCREATE);
2420 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2421
2422 /* relative path doesn't exist, SHPPFW_DIRCREATE -- Windows does not create the directory in this case */
2423 res = SHPathPrepareForWriteA(0, 0, ".\\testdir2\\test4.txt", SHPPFW_DIRCREATE);
2424 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2425 ok(!file_exists(".\\testdir2\\test4.txt\\"), ".\\testdir2\\test4.txt\\ exists but shouldn't\n");
2426
2427 /* directory doesn't exist, SHPPFW_NONE */
2428 set_curr_dir_path(path, "nonexistent\0");
2429 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2430 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2431
2432 /* directory doesn't exist, SHPPFW_IGNOREFILENAME */
2433 set_curr_dir_path(path, "nonexistent\\notreal\0");
2434 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
2435 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2436 ok(!file_exists("nonexistent\\notreal"), "nonexistent\\notreal exists but shouldn't\n");
2437 ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
2438
2439 /* directory doesn't exist, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
2440 set_curr_dir_path(path, "testdir2\\test4.txt\\\0");
2441 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
2442 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2443 ok(file_exists("testdir2\\test4.txt\\"), "testdir2\\test4.txt doesn't exist but should\n");
2444
2445 /* nested directory doesn't exist, SHPPFW_DIRCREATE */
2446 set_curr_dir_path(path, "nonexistent\\notreal\0");
2447 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
2448 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2449 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal doesn't exist but should\n");
2450
2451 /* SHPPFW_ASKDIRCREATE, SHPPFW_NOWRITECHECK, and SHPPFW_MEDIACHECKONLY are untested */
2452
2453 SetLastError(0xdeadbeef);
2454 UsedDefaultChar = FALSE;
2455 if (WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, UNICODE_PATH, -1, UNICODE_PATH_A, sizeof(UNICODE_PATH_A), NULL, &UsedDefaultChar) == 0)
2456 {
2457 win_skip("Could not convert Unicode path name to multibyte (%d)\n", GetLastError());
2458 return;
2459 }
2460 if (UsedDefaultChar)
2461 {
2462 win_skip("Could not find unique multibyte representation for directory name using default codepage\n");
2463 return;
2464 }
2465
2466 /* unicode directory doesn't exist, SHPPFW_NONE */
2467 RemoveDirectoryA(UNICODE_PATH_A);
2468 res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
2469 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == %08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2470 ok(!file_exists(UNICODE_PATH_A), "unicode path was created but shouldn't be\n");
2471 RemoveDirectoryA(UNICODE_PATH_A);
2472
2473 /* unicode directory doesn't exist, SHPPFW_DIRCREATE */
2474 res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
2475 ok(res == S_OK, "res == %08x, expected S_OK\n", res);
2476 ok(file_exists(UNICODE_PATH_A), "unicode path should've been created\n");
2477
2478 /* unicode directory exists, SHPPFW_NONE */
2479 res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
2480 ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
2481
2482 /* unicode directory exists, SHPPFW_DIRCREATE */
2483 res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
2484 ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
2485 RemoveDirectoryA(UNICODE_PATH_A);
2486 }
2487
2488 static void test_sh_new_link_info(void)
2489 {
2490 BOOL ret, mustcopy=TRUE;
2491 CHAR linkto[MAX_PATH];
2492 CHAR destdir[MAX_PATH];
2493 CHAR result[MAX_PATH];
2494 CHAR result2[MAX_PATH];
2495
2496 /* source file does not exist */
2497 set_curr_dir_path(linkto, "nosuchfile.txt\0");
2498 set_curr_dir_path(destdir, "testdir2\0");
2499 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2500 ok(ret == FALSE ||
2501 broken(ret == lstrlenA(result) + 1), /* NT4 */
2502 "SHGetNewLinkInfoA succeeded\n");
2503 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2504
2505 /* dest dir does not exist */
2506 set_curr_dir_path(linkto, "test1.txt\0");
2507 set_curr_dir_path(destdir, "nosuchdir\0");
2508 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2509 ok(ret == TRUE ||
2510 broken(ret == lstrlenA(result) + 1), /* NT4 */
2511 "SHGetNewLinkInfoA failed, err=%i\n", GetLastError());
2512 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2513
2514 /* source file exists */
2515 set_curr_dir_path(linkto, "test1.txt\0");
2516 set_curr_dir_path(destdir, "testdir2\0");
2517 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2518 ok(ret == TRUE ||
2519 broken(ret == lstrlenA(result) + 1), /* NT4 */
2520 "SHGetNewLinkInfoA failed, err=%i\n", GetLastError());
2521 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2522 ok(CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, destdir,
2523 lstrlenA(destdir), result, lstrlenA(destdir)) == CSTR_EQUAL,