shell32/tests: Enable compilation with long types.
[wine.git] / dlls / shell32 / tests / shlfileop.c
blob273b09d5005279dc3e951ded0c7f4927fd07c860
1 /*
2 * Unit test of the SHFileOperation function.
4 * Copyright 2002 Andriy Palamarchuk
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <stdio.h>
24 #define COBJMACROS
25 #include <windows.h>
26 #include "shellapi.h"
27 #include "shlobj.h"
28 #include "commoncontrols.h"
30 #include "wine/test.h"
32 /* Error codes could be pre-Win32 */
33 #define DE_SAMEFILE 0x71
34 #define DE_MANYSRC1DEST 0x72
35 #define DE_DIFFDIR 0x73
36 #define DE_OPCANCELLED 0x75
37 #define DE_DESTSUBTREE 0x76
38 #define DE_INVALIDFILES 0x7C
39 #define DE_DESTSAMETREE 0x7D
40 #define DE_FLDDESTISFILE 0x7E
41 #define DE_FILEDESTISFLD 0x80
42 #define expect_retval(ret, ret_prewin32)\
43 ok(retval == ret ||\
44 broken(retval == ret_prewin32),\
45 "Expected %d, got %ld\n", ret, retval)
47 static BOOL old_shell32 = FALSE;
49 static CHAR CURR_DIR[MAX_PATH];
50 static const WCHAR UNICODE_PATH[] = {'c',':','\\',0x00ae,'\0','\0'};
51 /* "c:\®" can be used in all codepages */
52 /* Double-null termination needed for pFrom field of SHFILEOPSTRUCT */
54 /* creates a file with the specified name for tests */
55 static void createTestFile(const CHAR *name)
57 HANDLE file;
58 DWORD written;
60 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
61 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
62 WriteFile(file, name, strlen(name), &written, NULL);
63 WriteFile(file, "\n", strlen("\n"), &written, NULL);
64 CloseHandle(file);
67 static void createTestFileW(const WCHAR *name)
69 HANDLE file;
71 file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
72 ok(file != INVALID_HANDLE_VALUE, "Failure to open file\n");
73 CloseHandle(file);
76 static BOOL file_exists(const CHAR *name)
78 return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
81 static BOOL dir_exists(const CHAR *name)
83 DWORD attr;
84 BOOL dir;
86 attr = GetFileAttributesA(name);
87 dir = ((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
89 return ((attr != INVALID_FILE_ATTRIBUTES) && dir);
92 static BOOL file_existsW(LPCWSTR name)
94 return GetFileAttributesW(name) != INVALID_FILE_ATTRIBUTES;
97 static BOOL file_has_content(const CHAR *name, const CHAR *content)
99 CHAR buf[MAX_PATH];
100 HANDLE file;
101 DWORD read;
103 file = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
104 if (file == INVALID_HANDLE_VALUE)
105 return FALSE;
106 ReadFile(file, buf, MAX_PATH - 1, &read, NULL);
107 buf[read] = 0;
108 CloseHandle(file);
109 return strcmp(buf, content)==0;
112 /* initializes the tests */
113 static void init_shfo_tests(void)
115 int len;
117 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
118 len = lstrlenA(CURR_DIR);
120 if(len && (CURR_DIR[len-1] == '\\'))
121 CURR_DIR[len-1] = 0;
123 createTestFile("test1.txt");
124 createTestFile("test2.txt");
125 createTestFile("test3.txt");
126 createTestFile("test_5.txt");
127 CreateDirectoryA("test4.txt", NULL);
128 CreateDirectoryA("testdir2", NULL);
129 CreateDirectoryA("testdir2\\nested", NULL);
130 createTestFile("testdir2\\one.txt");
131 createTestFile("testdir2\\nested\\two.txt");
134 /* cleans after tests */
135 static void clean_after_shfo_tests(void)
137 DeleteFileA("test1.txt");
138 DeleteFileA("test2.txt");
139 DeleteFileA("test3.txt");
140 DeleteFileA("test_5.txt");
141 DeleteFileA("one.txt");
142 DeleteFileA("test4.txt\\test1.txt");
143 DeleteFileA("test4.txt\\test2.txt");
144 DeleteFileA("test4.txt\\test3.txt");
145 DeleteFileA("test4.txt\\one.txt");
146 DeleteFileA("test4.txt\\nested\\two.txt");
147 RemoveDirectoryA("test4.txt\\nested");
148 RemoveDirectoryA("test4.txt");
149 DeleteFileA("testdir2\\one.txt");
150 DeleteFileA("testdir2\\test1.txt");
151 DeleteFileA("testdir2\\test2.txt");
152 DeleteFileA("testdir2\\test3.txt");
153 DeleteFileA("testdir2\\test4.txt\\test1.txt");
154 DeleteFileA("testdir2\\nested\\two.txt");
155 RemoveDirectoryA("testdir2\\test4.txt");
156 RemoveDirectoryA("testdir2\\nested");
157 RemoveDirectoryA("testdir2");
158 RemoveDirectoryA("c:\\testdir3");
159 DeleteFileA("nonexistent\\notreal\\test2.txt");
160 RemoveDirectoryA("nonexistent\\notreal");
161 RemoveDirectoryA("nonexistent");
165 static void test_get_file_info(void)
167 DWORD rc, rc2;
168 SHFILEINFOA shfi, shfi2;
169 SHFILEINFOW shfiw;
170 char notepad[MAX_PATH];
171 HANDLE unset_icon;
173 /* Test whether fields of SHFILEINFOA are always cleared */
174 memset(&shfi, 0xcf, sizeof(shfi));
175 rc=SHGetFileInfoA("", 0, &shfi, sizeof(shfi), 0);
176 ok(rc == 1, "SHGetFileInfoA('' | 0) should return 1, got 0x%lx\n", rc);
177 todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA('' | 0) did not clear hIcon\n");
178 todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szDisplayName[0]\n");
179 todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szTypeName[0]\n");
180 ok(shfi.iIcon == 0xcfcfcfcf ||
181 broken(shfi.iIcon != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
182 "SHGetFileInfoA('' | 0) should not clear iIcon\n");
183 ok(shfi.dwAttributes == 0xcfcfcfcf ||
184 broken(shfi.dwAttributes != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
185 "SHGetFileInfoA('' | 0) should not clear dwAttributes\n");
187 memset(&shfiw, 0xcf, sizeof(shfiw));
188 memset(&unset_icon, 0xcf, sizeof(unset_icon));
189 rc = SHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0);
190 ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n");
191 ok(shfiw.hIcon == unset_icon, "SHGetFileInfoW(NULL | 0) should not clear hIcon\n");
192 ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n");
193 ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n");
194 ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n");
195 ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear dwAttributes\n");
197 /* Test some flag combinations that MSDN claims are not allowed,
198 * but which work anyway
200 memset(&shfi, 0xcf, sizeof(shfi));
201 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
202 &shfi, sizeof(shfi),
203 SHGFI_ATTRIBUTES | SHGFI_USEFILEATTRIBUTES);
204 ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) should return 1, got 0x%lx\n", rc);
205 if (rc)
206 ok(shfi.dwAttributes != 0xcfcfcfcf, "dwFileAttributes is not set\n");
207 todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear hIcon\n");
208 todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szDisplayName[0]\n");
209 todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szTypeName[0]\n");
210 ok(shfi.iIcon == 0xcfcfcfcf ||
211 broken(shfi.iIcon != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
212 "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) should not clear iIcon\n");
214 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
215 &shfi, sizeof(shfi),
216 SHGFI_EXETYPE | SHGFI_USEFILEATTRIBUTES);
217 todo_wine ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_EXETYPE) should return 1, got 0x%lx\n", rc);
219 /* Test SHGFI_USEFILEATTRIBUTES support */
220 strcpy(shfi.szDisplayName, "dummy");
221 shfi.iIcon=0xdeadbeef;
222 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
223 &shfi, sizeof(shfi),
224 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
225 ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent) should return 1, got 0x%lx\n", rc);
226 if (rc)
228 ok(strcmp(shfi.szDisplayName, "dummy"), "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n");
229 ok(shfi.iIcon != 0xdeadbeef, "SHGetFileInfoA(c:\\nonexistent) iIcon is not set\n");
232 /* Wine does not have a default icon for text files, and Windows 98 fails
233 * if we give it an empty executable. So use notepad.exe as the test
235 if (SearchPathA(NULL, "notepad.exe", NULL, sizeof(notepad), notepad, NULL))
237 strcpy(shfi.szDisplayName, "dummy");
238 shfi.iIcon=0xdeadbeef;
239 rc=SHGetFileInfoA(notepad, GetFileAttributesA(notepad),
240 &shfi, sizeof(shfi),
241 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
242 ok(rc == 1, "SHGetFileInfoA(%s, SHGFI_USEFILEATTRIBUTES) should return 1, got 0x%lx\n", notepad, rc);
243 strcpy(shfi2.szDisplayName, "dummy");
244 shfi2.iIcon=0xdeadbeef;
245 rc2=SHGetFileInfoA(notepad, 0,
246 &shfi2, sizeof(shfi2),
247 SHGFI_ICONLOCATION);
248 ok(rc2 == 1, "SHGetFileInfoA(%s) failed %lx\n", notepad, rc2);
249 if (rc && rc2)
251 ok(lstrcmpiA(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
252 ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
256 /* with a directory now */
257 strcpy(shfi.szDisplayName, "dummy");
258 shfi.iIcon=0xdeadbeef;
259 rc=SHGetFileInfoA("test4.txt", GetFileAttributesA("test4.txt"),
260 &shfi, sizeof(shfi),
261 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
262 ok(rc == 1, "SHGetFileInfoA(test4.txt/, SHGFI_USEFILEATTRIBUTES) should return 1, got 0x%lx\n", rc);
263 strcpy(shfi2.szDisplayName, "dummy");
264 shfi2.iIcon=0xdeadbeef;
265 rc2=SHGetFileInfoA("test4.txt", 0,
266 &shfi2, sizeof(shfi2),
267 SHGFI_ICONLOCATION);
268 ok(rc2 == 1, "SHGetFileInfoA(test4.txt/) should return 1, got 0x%lx\n", rc2);
269 if (rc && rc2)
271 ok(lstrcmpiA(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
272 ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
274 /* with drive root directory */
275 strcpy(shfi.szDisplayName, "dummy");
276 strcpy(shfi.szTypeName, "dummy");
277 shfi.hIcon=(HICON) 0xdeadbeef;
278 shfi.iIcon=0xdeadbeef;
279 shfi.dwAttributes=0xdeadbeef;
280 rc=SHGetFileInfoA("c:\\", 0, &shfi, sizeof(shfi),
281 SHGFI_TYPENAME | SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_SMALLICON);
282 ok(rc == 1, "SHGetFileInfoA(c:\\) should return 1, got 0x%lx\n", rc);
283 ok(strcmp(shfi.szDisplayName, "dummy") != 0, "display name was expected to change\n");
284 ok(strcmp(shfi.szTypeName, "dummy") != 0, "type name was expected to change\n");
285 ok(shfi.hIcon != (HICON) 0xdeadbeef, "hIcon was expected to change\n");
286 ok(shfi.iIcon != 0xdeadbeef, "iIcon was expected to change\n");
289 static void check_icon_size( HICON icon, DWORD flags )
291 ICONINFO info;
292 BITMAP bm;
293 SIZE metrics_size;
294 int list_cx, list_cy;
295 IImageList *list;
297 GetIconInfo( icon, &info );
298 GetObjectW( info.hbmColor, sizeof(bm), &bm );
300 SHGetImageList( (flags & SHGFI_SMALLICON) ? SHIL_SMALL : SHIL_LARGE,
301 &IID_IImageList, (void **)&list );
302 IImageList_GetIconSize( list, &list_cx, &list_cy );
303 IImageList_Release( list );
305 metrics_size.cx = GetSystemMetrics( (flags & SHGFI_SMALLICON) ? SM_CXSMICON : SM_CXICON );
306 metrics_size.cy = GetSystemMetrics( (flags & SHGFI_SMALLICON) ? SM_CYSMICON : SM_CYICON );
309 if (flags & SHGFI_SHELLICONSIZE)
311 ok( bm.bmWidth == list_cx, "got %d expected %d\n", bm.bmWidth, list_cx );
312 ok( bm.bmHeight == list_cy, "got %d expected %d\n", bm.bmHeight, list_cy );
314 else
316 ok( bm.bmWidth == metrics_size.cx, "got %d expected %ld\n", bm.bmWidth, metrics_size.cx );
317 ok( bm.bmHeight == metrics_size.cy, "got %d expected %ld\n", bm.bmHeight, metrics_size.cy );
321 static void test_get_file_info_iconlist(void)
323 /* Test retrieving a handle to the system image list, and
324 * what that returns for hIcon
326 HRESULT hr;
327 HIMAGELIST hSysImageList;
328 LPITEMIDLIST pidList;
329 SHFILEINFOA shInfoa;
330 SHFILEINFOW shInfow;
331 IImageList *small_list, *large_list;
332 ULONG start_refs, refs;
334 hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidList);
335 if (FAILED(hr)) {
336 skip("can't get desktop pidl\n");
337 return;
340 SHGetImageList( SHIL_LARGE, &IID_IImageList, (void **)&large_list );
341 SHGetImageList( SHIL_SMALL, &IID_IImageList, (void **)&small_list );
343 start_refs = IImageList_AddRef( small_list );
344 IImageList_Release( small_list );
346 memset(&shInfoa, 0xcf, sizeof(shInfoa));
347 hSysImageList = (HIMAGELIST) SHGetFileInfoA((const char *)pidList, 0,
348 &shInfoa, sizeof(shInfoa),
349 SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
350 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
351 refs = IImageList_AddRef( small_list );
352 IImageList_Release( small_list );
353 ok( refs == start_refs + 1 ||
354 broken( refs == start_refs ), /* XP and 2003 */
355 "got %ld, start_refs %ld\n", refs, start_refs );
356 todo_wine ok(shInfoa.hIcon == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
357 todo_wine ok(shInfoa.szTypeName[0] == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
358 ok(shInfoa.iIcon != 0xcfcfcfcf, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
359 ok(shInfoa.dwAttributes == 0xcfcfcfcf ||
360 shInfoa.dwAttributes == 0 || /* Vista */
361 broken(shInfoa.dwAttributes != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
362 "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL), unexpected dwAttributes\n");
363 /* Don't release hSysImageList here (and in similar places below) because of the broken reference behaviour of XP and 2003. */
365 memset(&shInfow, 0xcf, sizeof(shInfow));
366 hSysImageList = (HIMAGELIST) SHGetFileInfoW((const WCHAR *)pidList, 0,
367 &shInfow, sizeof(shInfow), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
368 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
369 todo_wine ok(shInfow.hIcon == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
370 ok(shInfow.szTypeName[0] == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
371 ok(shInfow.iIcon != 0xcfcfcfcf, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
372 ok(shInfow.dwAttributes == 0xcfcfcfcf ||
373 shInfoa.dwAttributes == 0, /* Vista */
374 "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) unexpected dwAttributes\n");
376 /* Various suposidly invalid flag testing */
377 memset(&shInfow, 0xcf, sizeof(shInfow));
378 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
379 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
380 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
381 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
382 ok(shInfow.dwAttributes==0xcfcfcfcf ||
383 shInfoa.dwAttributes==0, /* Vista */
384 "unexpected dwAttributes\n");
386 memset(&shInfow, 0xcf, sizeof(shInfow));
387 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
388 SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
389 ok(hr != 0, " SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
390 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
391 check_icon_size( shInfow.hIcon, SHGFI_SMALLICON );
392 DestroyIcon(shInfow.hIcon);
393 todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
395 memset(&shInfow, 0xcf, sizeof(shInfow));
396 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
397 SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
398 ok(hr != 0, "SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON Failed\n");
399 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
400 check_icon_size( shInfow.hIcon, SHGFI_LARGEICON );
401 DestroyIcon( shInfow.hIcon );
402 todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
404 memset(&shInfow, 0xcf, sizeof(shInfow));
405 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
406 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
407 ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, small_list);
408 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
409 ok(shInfow.dwAttributes==0xcfcfcfcf ||
410 shInfoa.dwAttributes==0, /* Vista */
411 "unexpected dwAttributes\n");
413 memset(&shInfow, 0xcf, sizeof(shInfow));
414 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
415 SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
416 ok(hr != 0, "SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
417 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
418 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
420 memset(&shInfow, 0xcf, sizeof(shInfow));
421 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
422 SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
423 ok(hr != 0, "SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
424 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
425 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
427 memset(&shInfow, 0xcf, sizeof(shInfow));
428 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
429 SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
430 ok(hr != 0, "SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
431 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
432 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
434 memset(&shInfow, 0xcf, sizeof(shInfow));
435 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
436 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
437 SHGFI_ATTRIBUTES);
438 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
439 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
440 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
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_EXETYPE);
446 todo_wine 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 ||
449 shInfoa.dwAttributes==0, /* Vista */
450 "unexpected dwAttributes\n");
452 memset(&shInfow, 0xcf, sizeof(shInfow));
453 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
454 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE);
455 todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE Failed\n");
456 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
457 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
459 memset(&shInfow, 0xcf, sizeof(shInfow));
460 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
461 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES);
462 ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES Failed\n");
463 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
464 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
466 memset(&shInfow, 0xcf, sizeof(shInfow));
467 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
468 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|
469 SHGFI_ATTRIBUTES);
470 ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, large_list);
471 ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
472 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
473 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
475 memset(&shInfow, 0xcf, sizeof(shInfow));
476 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
477 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
478 todo_wine ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, large_list);
479 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
480 ok(shInfow.dwAttributes==0xcfcfcfcf ||
481 shInfoa.dwAttributes==0, /* Vista */
482 "unexpected dwAttributes\n");
484 memset(&shInfow, 0xcf, sizeof(shInfow));
485 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
486 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
487 todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE Failed\n");
488 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
489 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
491 memset(&shInfow, 0xcf, sizeof(shInfow));
492 hr = SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
493 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES);
494 ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
495 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
496 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
498 memset(&shInfow, 0xcf, sizeof(shInfow));
499 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
500 SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_SHELLICONSIZE|SHGFI_ICON);
501 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
502 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
503 check_icon_size( shInfow.hIcon, SHGFI_SMALLICON | SHGFI_SHELLICONSIZE );
504 DestroyIcon( shInfow.hIcon );
506 memset(&shInfow, 0xcf, sizeof(shInfow));
507 hSysImageList = (HIMAGELIST)SHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
508 SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SHELLICONSIZE|SHGFI_ICON);
509 ok(hSysImageList == (HIMAGELIST)large_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_LARGEICON | SHGFI_SHELLICONSIZE );
512 DestroyIcon( shInfow.hIcon );
514 ILFree(pidList);
515 IImageList_Release( small_list );
516 IImageList_Release( large_list );
521 puts into the specified buffer file names with current directory.
522 files - string with file names, separated by null characters. Ends on a double
523 null characters
525 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
527 buf[0] = 0;
528 while (files[0])
530 strcpy(buf, CURR_DIR);
531 buf += strlen(buf);
532 buf[0] = '\\';
533 buf++;
534 strcpy(buf, files);
535 buf += strlen(buf) + 1;
536 files += strlen(files) + 1;
538 buf[0] = 0;
542 /* tests the FO_DELETE action */
543 static void test_delete(void)
545 SHFILEOPSTRUCTA shfo;
546 DWORD ret;
547 CHAR buf[sizeof(CURR_DIR)+sizeof("/test?.txt")+1];
549 sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
550 buf[strlen(buf) + 1] = '\0';
552 shfo.hwnd = NULL;
553 shfo.wFunc = FO_DELETE;
554 shfo.pFrom = buf;
555 shfo.pTo = NULL;
556 shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
557 shfo.hNameMappings = NULL;
558 shfo.lpszProgressTitle = NULL;
560 ok(!SHFileOperationA(&shfo), "Deletion was not successful\n");
561 ok(dir_exists("test4.txt"), "Directory should not have been removed\n");
562 ok(!file_exists("test1.txt"), "File should have been removed\n");
563 ok(!file_exists("test2.txt"), "File should have been removed\n");
564 ok(!file_exists("test3.txt"), "File should have been removed\n");
566 ret = SHFileOperationA(&shfo);
567 ok(ret == ERROR_SUCCESS, "Directory exists, but is not removed, ret=%ld\n", ret);
568 ok(dir_exists("test4.txt"), "Directory should not have been removed\n");
570 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
572 ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
573 ok(!dir_exists("test4.txt"), "Directory should have been removed\n");
575 ret = SHFileOperationA(&shfo);
576 ok(!ret, "The requested file does not exist, ret=%ld\n", ret);
578 init_shfo_tests();
579 sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
580 buf[strlen(buf) + 1] = '\0';
581 ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Filling the subdirectory failed\n");
582 ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
583 ok(!dir_exists("test4.txt"), "Directory is not removed\n");
585 init_shfo_tests();
586 shfo.pFrom = "test1.txt\0test4.txt\0";
587 ok(!SHFileOperationA(&shfo), "Directory and a file are not removed\n");
588 ok(!file_exists("test1.txt"), "The file should have been removed\n");
589 ok(!dir_exists("test4.txt"), "Directory should have been removed\n");
590 ok(file_exists("test2.txt"), "This file should not have been removed\n");
592 /* FOF_FILESONLY does not delete a dir matching a wildcard */
593 init_shfo_tests();
594 shfo.fFlags |= FOF_FILESONLY;
595 shfo.pFrom = "*.txt\0";
596 ok(!SHFileOperationA(&shfo), "Failed to delete files\n");
597 ok(!file_exists("test1.txt"), "test1.txt should have been removed\n");
598 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
599 ok(dir_exists("test4.txt"), "test4.txt should not have been removed\n");
601 /* FOF_FILESONLY only deletes a dir if explicitly specified */
602 init_shfo_tests();
603 shfo.pFrom = "test_?.txt\0test4.txt\0";
604 ok(!SHFileOperationA(&shfo), "Failed to delete files and directory\n");
605 ok(!dir_exists("test4.txt") ||
606 broken(dir_exists("test4.txt")), /* NT4 */
607 "test4.txt should have been removed\n");
608 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
609 ok(file_exists("test1.txt"), "test1.txt should not have been removed\n");
611 /* try to delete an invalid filename */
612 if (0) {
613 /* this crashes on win9x */
614 init_shfo_tests();
615 shfo.pFrom = "\0";
616 shfo.fFlags &= ~FOF_FILESONLY;
617 shfo.fAnyOperationsAborted = FALSE;
618 ret = SHFileOperationA(&shfo);
619 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", ret);
620 ok(!shfo.fAnyOperationsAborted, "Expected no aborted operations\n");
621 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
624 /* try an invalid function */
625 init_shfo_tests();
626 shfo.pFrom = "test1.txt\0";
627 shfo.wFunc = 0;
628 ret = SHFileOperationA(&shfo);
629 ok(ret == ERROR_INVALID_PARAMETER ||
630 broken(ret == ERROR_SUCCESS), /* Win9x, NT4 */
631 "Expected ERROR_INVALID_PARAMETER, got %ld\n", ret);
632 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
634 /* try an invalid list, only one null terminator */
635 if (0) {
636 /* this crashes on win9x */
637 init_shfo_tests();
638 shfo.pFrom = "";
639 shfo.wFunc = FO_DELETE;
640 ret = SHFileOperationA(&shfo);
641 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %ld\n", ret);
642 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
645 /* delete a nonexistent file */
646 shfo.pFrom = "nonexistent.txt\0";
647 shfo.wFunc = FO_DELETE;
648 ret = SHFileOperationA(&shfo);
649 ok(ret == 1026 ||
650 ret == ERROR_FILE_NOT_FOUND || /* Vista */
651 broken(ret == ERROR_SUCCESS), /* NT4 */
652 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %ld\n", ret);
654 /* delete a dir, and then a file inside the dir, same as
655 * deleting a nonexistent file
657 if (ret != ERROR_FILE_NOT_FOUND)
659 /* Vista would throw up a dialog box that we can't suppress */
660 init_shfo_tests();
661 shfo.pFrom = "testdir2\0testdir2\\one.txt\0";
662 ret = SHFileOperationA(&shfo);
663 ok(ret == ERROR_PATH_NOT_FOUND ||
664 broken(ret == ERROR_SUCCESS), /* NT4 */
665 "Expected ERROR_PATH_NOT_FOUND, got %ld\n", ret);
666 ok(!dir_exists("testdir2"), "Expected testdir2 to not exist\n");
667 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
669 else
670 skip("Test would show a dialog box\n");
672 /* delete an existent file and a nonexistent file */
673 init_shfo_tests();
674 shfo.pFrom = "test1.txt\0nonexistent.txt\0test2.txt\0";
675 shfo.wFunc = FO_DELETE;
676 ret = SHFileOperationA(&shfo);
677 ok(ret == 1026 ||
678 ret == ERROR_FILE_NOT_FOUND || /* Vista */
679 broken(ret == ERROR_SUCCESS), /* NT4 */
680 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %ld\n", ret);
681 todo_wine
682 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
683 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
685 /* delete a nonexistent file in an existent dir or a nonexistent dir */
686 init_shfo_tests();
687 shfo.pFrom = "testdir2\\nonexistent.txt\0";
688 ret = SHFileOperationA(&shfo);
689 ok(ret == ERROR_FILE_NOT_FOUND || /* Vista */
690 broken(ret == 0x402) || /* XP */
691 broken(ret == ERROR_SUCCESS), /* NT4 */
692 "Expected 0x402 or ERROR_FILE_NOT_FOUND, got %lx\n", ret);
693 shfo.pFrom = "nonexistent\\one.txt\0";
694 ret = SHFileOperationA(&shfo);
695 ok(ret == DE_INVALIDFILES || /* Vista or later */
696 broken(ret == 0x402), /* XP */
697 "Expected 0x402 or DE_INVALIDFILES, got %lx\n", ret);
699 /* try the FOF_NORECURSION flag, continues deleting subdirs */
700 init_shfo_tests();
701 shfo.pFrom = "testdir2\0";
702 shfo.fFlags |= FOF_NORECURSION;
703 ret = SHFileOperationA(&shfo);
704 ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", ret);
705 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
706 ok(!dir_exists("testdir2\\nested"), "Expected testdir2\\nested to not exist\n");
709 /* tests the FO_RENAME action */
710 static void test_rename(void)
712 SHFILEOPSTRUCTA shfo, shfo2;
713 CHAR from[5*MAX_PATH];
714 CHAR to[5*MAX_PATH];
715 DWORD retval;
717 shfo.hwnd = NULL;
718 shfo.wFunc = FO_RENAME;
719 shfo.pFrom = from;
720 shfo.pTo = to;
721 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
722 shfo.hNameMappings = NULL;
723 shfo.lpszProgressTitle = NULL;
725 set_curr_dir_path(from, "test1.txt\0");
726 set_curr_dir_path(to, "test4.txt\0");
727 retval = SHFileOperationA(&shfo);
728 ok(retval == ERROR_ALREADY_EXISTS ||
729 retval == DE_FILEDESTISFLD || /* Vista */
730 broken(retval == ERROR_INVALID_NAME), /* Win9x, NT4 */
731 "Expected ERROR_ALREADY_EXISTS or DE_FILEDESTISFLD, got %ld\n", retval);
732 ok(file_exists("test1.txt"), "The file is renamed\n");
734 set_curr_dir_path(from, "test3.txt\0");
735 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
736 retval = SHFileOperationA(&shfo);
737 if (retval == DE_DIFFDIR)
739 /* Vista and W2K8 (broken or new behavior ?) */
740 ok(!file_exists("test4.txt\\test1.txt"), "The file is renamed\n");
742 else
744 ok(retval == ERROR_SUCCESS, "File is renamed moving to other directory\n");
745 ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
748 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
749 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
750 retval = SHFileOperationA(&shfo);
751 ok(retval == ERROR_GEN_FAILURE ||
752 retval == DE_MANYSRC1DEST || /* Vista */
753 broken(retval == ERROR_SUCCESS), /* Win9x */
754 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST , got %ld\n", retval);
755 ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
757 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
758 shfo2.fFlags |= FOF_MULTIDESTFILES;
760 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
761 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
762 retval = SHFileOperationA(&shfo2);
763 ok(retval == ERROR_GEN_FAILURE ||
764 retval == DE_MANYSRC1DEST || /* Vista */
765 broken(retval == ERROR_SUCCESS), /* Win9x */
766 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST files, got %ld\n", retval);
767 ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
769 set_curr_dir_path(from, "test1.txt\0");
770 set_curr_dir_path(to, "test6.txt\0");
771 retval = SHFileOperationA(&shfo);
772 ok(retval == ERROR_SUCCESS, "Rename file failed, retval = %ld\n", retval);
773 ok(!file_exists("test1.txt"), "The file is not renamed\n");
774 ok(file_exists("test6.txt"), "The file is not renamed\n");
776 set_curr_dir_path(from, "test6.txt\0");
777 set_curr_dir_path(to, "test1.txt\0");
778 retval = SHFileOperationA(&shfo);
779 ok(retval == ERROR_SUCCESS, "Rename file back failed, retval = %ld\n", retval);
781 set_curr_dir_path(from, "test4.txt\0");
782 set_curr_dir_path(to, "test6.txt\0");
783 retval = SHFileOperationA(&shfo);
784 ok(retval == ERROR_SUCCESS, "Rename dir failed, retval = %ld\n", retval);
785 ok(!dir_exists("test4.txt"), "The dir is not renamed\n");
786 ok(dir_exists("test6.txt"), "The dir is not renamed\n");
788 set_curr_dir_path(from, "test6.txt\0");
789 set_curr_dir_path(to, "test4.txt\0");
790 retval = SHFileOperationA(&shfo);
791 ok(retval == ERROR_SUCCESS, "Rename dir back failed, retval = %ld\n", retval);
792 ok(dir_exists("test4.txt"), "The dir is not renamed\n");
794 /* try to rename more than one file to a single file */
795 shfo.pFrom = "test1.txt\0test2.txt\0";
796 shfo.pTo = "a.txt\0";
797 retval = SHFileOperationA(&shfo);
798 ok(retval == ERROR_GEN_FAILURE ||
799 retval == DE_MANYSRC1DEST || /* Vista */
800 broken(retval == ERROR_SUCCESS), /* Win9x */
801 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST, got %ld\n", retval);
802 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
803 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
804 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
806 /* pFrom doesn't exist */
807 shfo.pFrom = "idontexist\0";
808 shfo.pTo = "newfile\0";
809 retval = SHFileOperationA(&shfo);
810 ok(retval == 1026 ||
811 retval == ERROR_FILE_NOT_FOUND || /* Vista */
812 broken(retval == ERROR_SUCCESS), /* NT4 */
813 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %ld\n", retval);
814 ok(!file_exists("newfile"), "Expected newfile to not exist\n");
816 /* pTo already exist */
817 shfo.pFrom = "test1.txt\0";
818 shfo.pTo = "test2.txt\0";
819 if (old_shell32)
820 shfo.fFlags |= FOF_NOCONFIRMMKDIR;
821 retval = SHFileOperationA(&shfo);
822 if (retval == ERROR_SUCCESS)
824 /* Vista and W2K8 (broken or new behavior ?) */
825 createTestFile("test1.txt");
827 else
829 ok(retval == ERROR_ALREADY_EXISTS ||
830 broken(retval == DE_OPCANCELLED) || /* NT4 */
831 broken(retval == ERROR_INVALID_NAME), /* Win9x */
832 "Expected ERROR_ALREADY_EXISTS, got %ld\n", retval);
835 /* pFrom is valid, but pTo is empty */
836 shfo.pFrom = "test1.txt\0";
837 shfo.pTo = "\0";
838 retval = SHFileOperationA(&shfo);
839 ok(retval == ERROR_CANCELLED ||
840 retval == DE_DIFFDIR || /* Vista */
841 retval == DE_FILEDESTISFLD || /* Vista, running from c: */
842 broken(retval == DE_OPCANCELLED) || /* Win9x */
843 broken(retval == 65652), /* NT4 */
844 "Expected ERROR_CANCELLED or DE_DIFFDIR, got %lu\n", retval);
845 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
847 /* pFrom is empty */
848 shfo.pFrom = "\0";
849 retval = SHFileOperationA(&shfo);
850 ok(retval == ERROR_ACCESS_DENIED ||
851 retval == DE_MANYSRC1DEST || /* Vista */
852 broken(retval == ERROR_SUCCESS), /* Win9x */
853 "Expected ERROR_ACCESS_DENIED or DE_MANYSRC1DEST, got %ld\n", retval);
855 /* pFrom is NULL, commented out because it crashes on nt 4.0 */
856 if (0)
858 shfo.pFrom = NULL;
859 retval = SHFileOperationA(&shfo);
860 ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", retval);
864 /* tests the FO_COPY action */
865 static void test_copy(void)
867 SHFILEOPSTRUCTA shfo, shfo2;
868 CHAR from[5*MAX_PATH];
869 CHAR to[5*MAX_PATH];
870 FILEOP_FLAGS tmp_flags;
871 DWORD retval;
872 LPSTR ptr;
873 BOOL on_nt4 = FALSE;
874 BOOL ret;
876 if (old_shell32)
878 win_skip("Too many differences for old shell32\n");
879 return;
882 shfo.hwnd = NULL;
883 shfo.wFunc = FO_COPY;
884 shfo.pFrom = from;
885 shfo.pTo = to;
886 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
887 shfo.hNameMappings = NULL;
888 shfo.lpszProgressTitle = NULL;
890 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
891 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
892 retval = SHFileOperationA(&shfo);
893 if (dir_exists("test6.txt"))
895 /* Vista and W2K8 (broken or new behavior ?) */
896 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
897 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files "
898 "are specified as a target\n");
899 DeleteFileA("test6.txt\\test2.txt");
900 RemoveDirectoryA("test6.txt\\test4.txt");
901 RemoveDirectoryA("test6.txt");
903 else
905 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
906 ok(!file_exists("test6.txt"), "The file is copied - many files are "
907 "specified as a target\n");
910 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
911 shfo2.fFlags |= FOF_MULTIDESTFILES;
913 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
914 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
915 ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
916 ok(file_exists("test6.txt"), "The file is not copied - many files are "
917 "specified as a target\n");
918 DeleteFileA("test6.txt");
919 DeleteFileA("test7.txt");
920 RemoveDirectoryA("test8.txt");
922 /* number of sources does not correspond to number of targets */
923 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
924 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
925 retval = SHFileOperationA(&shfo2);
926 if (dir_exists("test6.txt"))
928 /* Vista and W2K8 (broken or new behavior?) */
929 ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %ld\n", retval);
930 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files "
931 "are specified as a target\n");
932 RemoveDirectoryA("test6.txt");
933 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not copied - many files "
934 "are specified as a target\n");
935 RemoveDirectoryA("test7.txt");
937 else
939 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
940 ok(!file_exists("test6.txt"), "The file is copied - many files are "
941 "specified as a target\n");
944 set_curr_dir_path(from, "test1.txt\0");
945 set_curr_dir_path(to, "test4.txt\0");
946 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
947 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
949 set_curr_dir_path(from, "test?.txt\0");
950 set_curr_dir_path(to, "testdir2\0");
951 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
952 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
953 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
954 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
955 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
956 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
957 clean_after_shfo_tests();
959 init_shfo_tests();
960 shfo.fFlags |= FOF_FILESONLY;
961 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
962 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
963 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
964 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
965 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
966 clean_after_shfo_tests();
968 init_shfo_tests();
969 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
970 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
971 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
972 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
973 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
974 ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
975 clean_after_shfo_tests();
977 /* Copying multiple files with one not existing as source, fails the
978 entire operation in Win98/ME/2K/XP, but not in 95/NT */
979 init_shfo_tests();
980 tmp_flags = shfo.fFlags;
981 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
982 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
983 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
984 retval = SHFileOperationA(&shfo);
985 if (retval == ERROR_SUCCESS)
986 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
987 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
988 else
990 /* Failure if one source file does not exist */
991 ok(retval == 1026 || /* Win 98/ME/2K/XP */
992 retval == ERROR_FILE_NOT_FOUND, /* Vista and W2K8 */
993 "Files are copied to other directory\n");
994 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
996 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
997 shfo.fFlags = tmp_flags;
999 /* copy into a nonexistent directory */
1000 init_shfo_tests();
1001 shfo.fFlags = FOF_NOCONFIRMMKDIR;
1002 set_curr_dir_path(from, "test1.txt\0");
1003 set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
1004 retval= SHFileOperationA(&shfo);
1005 ok(!retval, "Error copying into nonexistent directory\n");
1006 ok(file_exists("nonexistent"), "nonexistent not created\n");
1007 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
1008 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
1009 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
1011 /* a relative dest directory is OK */
1012 clean_after_shfo_tests();
1013 init_shfo_tests();
1014 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1015 shfo.pTo = "testdir2\0";
1016 retval = SHFileOperationA(&shfo);
1017 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1018 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
1020 /* try to overwrite an existing write protected file */
1021 clean_after_shfo_tests();
1022 init_shfo_tests();
1023 tmp_flags = shfo.fFlags;
1024 shfo.pFrom = "test1.txt\0";
1025 shfo.pTo = "test2.txt\0";
1026 /* suppress the error-dialog in win9x here */
1027 shfo.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT;
1028 ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_READONLY);
1029 ok(ret, "Failure to set file attributes (error %lx)\n", GetLastError());
1030 retval = CopyFileA(shfo.pFrom, shfo.pTo, FALSE);
1031 ok(!retval && GetLastError() == ERROR_ACCESS_DENIED, "CopyFileA should have fail with ERROR_ACCESS_DENIED\n");
1032 retval = SHFileOperationA(&shfo);
1033 /* Does not work on Win95, Win95B, NT4WS and NT4SRV */
1034 ok(!retval || broken(retval == DE_OPCANCELLED), "SHFileOperationA failed to copy (error %lx)\n", retval);
1035 /* Set back normal attributes to make the file deletion succeed */
1036 ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_NORMAL);
1037 ok(ret, "Failure to set file attributes (error %lx)\n", GetLastError());
1038 shfo.fFlags = tmp_flags;
1040 /* try to copy files to a file */
1041 clean_after_shfo_tests();
1042 init_shfo_tests();
1043 shfo.pFrom = from;
1044 shfo.pTo = to;
1045 /* suppress the error-dialog in win9x here */
1046 shfo.fFlags |= FOF_NOERRORUI;
1047 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
1048 set_curr_dir_path(to, "test3.txt\0");
1049 shfo.fAnyOperationsAborted = 0xdeadbeef;
1050 retval = SHFileOperationA(&shfo);
1051 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1052 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1053 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1054 if (retval == DE_FLDDESTISFILE || /* Vista and W2K8 */
1055 retval == DE_INVALIDFILES) /* Win7 */
1057 /* Most likely new behavior */
1058 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1060 else
1062 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1063 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
1065 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
1067 /* try to copy many files to nonexistent directory */
1068 DeleteFileA(to);
1069 shfo.fFlags &= ~FOF_NOERRORUI;
1070 shfo.fAnyOperationsAborted = 0xdeadbeef;
1071 retval = SHFileOperationA(&shfo);
1072 ok(!shfo.fAnyOperationsAborted ||
1073 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1074 "Didn't expect aborted operations\n");
1075 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1076 ok(DeleteFileA("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
1077 ok(DeleteFileA("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
1078 ok(RemoveDirectoryA(to), "Expected test3.txt to exist\n");
1080 /* send in FOF_MULTIDESTFILES with too many destination files */
1081 init_shfo_tests();
1082 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1083 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
1084 shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
1085 shfo.fAnyOperationsAborted = 0xdeadbeef;
1086 retval = SHFileOperationA(&shfo);
1087 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1088 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1089 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1090 if (dir_exists("testdir2\\a.txt"))
1092 /* Vista and W2K8 (broken or new behavior ?) */
1093 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1094 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1095 ok(DeleteFileA("testdir2\\a.txt\\test1.txt"), "Expected testdir2\\a.txt\\test1.txt to exist\n");
1096 RemoveDirectoryA("testdir2\\a.txt");
1097 ok(DeleteFileA("testdir2\\b.txt\\test2.txt"), "Expected testdir2\\b.txt\\test2.txt to exist\n");
1098 RemoveDirectoryA("testdir2\\b.txt");
1099 ok(DeleteFileA("testdir2\\c.txt\\test3.txt"), "Expected testdir2\\c.txt\\test3.txt to exist\n");
1100 RemoveDirectoryA("testdir2\\c.txt");
1101 ok(!file_exists("testdir2\\d.txt"), "Expected testdir2\\d.txt to not exist\n");
1103 else
1105 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1106 ok(shfo.fAnyOperationsAborted ||
1107 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1108 "Expected aborted operations\n");
1109 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
1112 /* send in FOF_MULTIDESTFILES with too many destination files */
1113 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1114 shfo.pTo = "e.txt\0f.txt\0";
1115 shfo.fAnyOperationsAborted = 0xdeadbeef;
1116 retval = SHFileOperationA(&shfo);
1117 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1118 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1119 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1120 if (dir_exists("e.txt"))
1122 /* Vista and W2K8 (broken or new behavior ?) */
1123 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1124 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %ld\n", retval);
1125 ok(DeleteFileA("e.txt\\test1.txt"), "Expected e.txt\\test1.txt to exist\n");
1126 RemoveDirectoryA("e.txt");
1127 ok(DeleteFileA("f.txt\\test2.txt"), "Expected f.txt\\test2.txt to exist\n");
1128 RemoveDirectoryA("f.txt");
1130 else
1132 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1133 ok(shfo.fAnyOperationsAborted ||
1134 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1135 "Expected aborted operations\n");
1136 ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
1139 /* use FOF_MULTIDESTFILES with files and a source directory */
1140 shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
1141 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
1142 shfo.fAnyOperationsAborted = 0xdeadbeef;
1143 retval = SHFileOperationA(&shfo);
1144 ok(!shfo.fAnyOperationsAborted ||
1145 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1146 "Didn't expect aborted operations\n");
1147 ok(retval == ERROR_SUCCESS ||
1148 broken(retval == 0x100a1), /* WinMe */
1149 "Expected ERROR_SUCCESS, got %ld\n", retval);
1150 ok(DeleteFileA("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
1151 ok(DeleteFileA("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
1152 if (retval == ERROR_SUCCESS)
1153 ok(RemoveDirectoryA("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
1155 /* try many dest files without FOF_MULTIDESTFILES flag */
1156 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1157 shfo.pTo = "a.txt\0b.txt\0c.txt\0";
1158 shfo.fAnyOperationsAborted = 0xdeadbeef;
1159 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1160 retval = SHFileOperationA(&shfo);
1161 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1162 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1163 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1164 if (dir_exists("a.txt"))
1166 /* Vista and W2K8 (broken or new behavior ?) */
1167 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1168 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1169 ok(DeleteFileA("a.txt\\test1.txt"), "Expected a.txt\\test1.txt to exist\n");
1170 ok(DeleteFileA("a.txt\\test2.txt"), "Expected a.txt\\test2.txt to exist\n");
1171 ok(DeleteFileA("a.txt\\test3.txt"), "Expected a.txt\\test3.txt to exist\n");
1172 RemoveDirectoryA("a.txt");
1174 else
1177 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1178 ok(shfo.fAnyOperationsAborted ||
1179 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1180 "Expected aborted operations\n");
1181 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
1184 /* try a glob */
1185 shfo.pFrom = "test?.txt\0";
1186 shfo.pTo = "testdir2\0";
1187 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1188 retval = SHFileOperationA(&shfo);
1189 ok(retval == ERROR_SUCCESS ||
1190 broken(retval == 0x100a1), /* WinMe */
1191 "Expected ERROR_SUCCESS, got %ld\n", retval);
1192 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1194 /* try a glob with FOF_FILESONLY */
1195 clean_after_shfo_tests();
1196 init_shfo_tests();
1197 shfo.pFrom = "test?.txt\0";
1198 shfo.fFlags |= FOF_FILESONLY;
1199 retval = SHFileOperationA(&shfo);
1200 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1201 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1202 ok(!dir_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
1204 /* try a glob with FOF_MULTIDESTFILES and the same number
1205 * of dest files that we would expect
1207 clean_after_shfo_tests();
1208 init_shfo_tests();
1209 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
1210 shfo.fFlags &= ~FOF_FILESONLY;
1211 shfo.fFlags |= FOF_MULTIDESTFILES;
1212 retval = SHFileOperationA(&shfo);
1213 if (dir_exists("testdir2\\a.txt"))
1215 /* Vista and W2K8 (broken or new behavior ?) */
1216 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1217 ok(DeleteFileA("testdir2\\a.txt\\test1.txt"), "Expected testdir2\\a.txt\\test1.txt to exist\n");
1218 ok(DeleteFileA("testdir2\\a.txt\\test2.txt"), "Expected testdir2\\a.txt\\test2.txt to exist\n");
1219 ok(DeleteFileA("testdir2\\a.txt\\test3.txt"), "Expected testdir2\\a.txt\\test3.txt to exist\n");
1220 ok(RemoveDirectoryA("testdir2\\a.txt\\test4.txt"), "Expected testdir2\\a.txt\\test4.txt to exist\n");
1221 RemoveDirectoryA("testdir2\\a.txt");
1223 else
1225 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1226 ok(shfo.fAnyOperationsAborted ||
1227 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1228 "Expected aborted operations\n");
1229 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
1231 ok(!RemoveDirectoryA("b.txt"), "b.txt should not exist\n");
1233 /* copy one file to two others, second is ignored */
1234 clean_after_shfo_tests();
1235 init_shfo_tests();
1236 shfo.pFrom = "test1.txt\0";
1237 shfo.pTo = "b.txt\0c.txt\0";
1238 shfo.fAnyOperationsAborted = 0xdeadbeef;
1239 retval = SHFileOperationA(&shfo);
1240 ok(!shfo.fAnyOperationsAborted ||
1241 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1242 "Didn't expect aborted operations\n");
1243 if (retval == DE_OPCANCELLED)
1245 /* NT4 fails and doesn't copy any files */
1246 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1247 /* Needed to skip some tests */
1248 win_skip("Skipping some tests on NT4\n");
1249 on_nt4 = TRUE;
1251 else
1253 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1254 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1256 ok(!DeleteFileA("c.txt"), "Expected c.txt to not exist\n");
1258 /* copy two file to three others, all fail */
1259 shfo.pFrom = "test1.txt\0test2.txt\0";
1260 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
1261 shfo.fAnyOperationsAborted = 0xdeadbeef;
1262 retval = SHFileOperationA(&shfo);
1263 if (dir_exists("b.txt"))
1265 /* Vista and W2K8 (broken or new behavior ?) */
1266 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1267 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1268 ok(DeleteFileA("b.txt\\test1.txt"), "Expected b.txt\\test1.txt to exist\n");
1269 RemoveDirectoryA("b.txt");
1270 ok(DeleteFileA("c.txt\\test2.txt"), "Expected c.txt\\test2.txt to exist\n");
1271 RemoveDirectoryA("c.txt");
1273 else
1275 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1276 ok(shfo.fAnyOperationsAborted ||
1277 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1278 "Expected aborted operations\n");
1279 ok(!DeleteFileA("b.txt"), "Expected b.txt to not exist\n");
1282 /* copy one file and one directory to three others */
1283 shfo.pFrom = "test1.txt\0test4.txt\0";
1284 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
1285 shfo.fAnyOperationsAborted = 0xdeadbeef;
1286 retval = SHFileOperationA(&shfo);
1287 if (dir_exists("b.txt"))
1289 /* Vista and W2K8 (broken or new behavior ?) */
1290 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1291 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1292 ok(DeleteFileA("b.txt\\test1.txt"), "Expected b.txt\\test1.txt to exist\n");
1293 RemoveDirectoryA("b.txt");
1294 ok(RemoveDirectoryA("c.txt\\test4.txt"), "Expected c.txt\\test4.txt to exist\n");
1295 RemoveDirectoryA("c.txt");
1297 else
1299 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1300 ok(shfo.fAnyOperationsAborted ||
1301 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1302 "Expected aborted operations\n");
1303 ok(!DeleteFileA("b.txt"), "Expected b.txt to not exist\n");
1304 ok(!DeleteFileA("c.txt"), "Expected c.txt to not exist\n");
1307 /* copy a directory with a file beneath it, plus some files */
1308 createTestFile("test4.txt\\a.txt");
1309 shfo.pFrom = "test4.txt\0test1.txt\0";
1310 shfo.pTo = "testdir2\0";
1311 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1312 shfo.fAnyOperationsAborted = FALSE;
1313 retval = SHFileOperationA(&shfo);
1314 ok(retval == ERROR_SUCCESS ||
1315 broken(retval == 0x100a1), /* WinMe */
1316 "Expected ERROR_SUCCESS, got %ld\n", retval);
1317 if (retval == ERROR_SUCCESS)
1319 ok(DeleteFileA("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1320 ok(DeleteFileA("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
1321 ok(RemoveDirectoryA("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
1324 /* copy one directory and a file in that dir to another dir */
1325 shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
1326 shfo.pTo = "testdir2\0";
1327 retval = SHFileOperationA(&shfo);
1328 ok(retval == ERROR_SUCCESS ||
1329 broken(retval == 0x100a1), /* WinMe */
1330 "Expected ERROR_SUCCESS, got %ld\n", retval);
1331 if (retval == ERROR_SUCCESS)
1333 ok(DeleteFileA("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
1334 ok(DeleteFileA("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
1337 /* copy a file in a directory first, and then the directory to a nonexistent dir */
1338 shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
1339 shfo.pTo = "nonexistent\0";
1340 retval = SHFileOperationA(&shfo);
1341 if (dir_exists("nonexistent"))
1343 /* Vista and W2K8 (broken or new behavior ?) */
1344 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1345 ok(DeleteFileA("nonexistent\\test4.txt\\a.txt"), "Expected nonexistent\\test4.txt\\a.txt to exist\n");
1346 RemoveDirectoryA("nonexistent\\test4.txt");
1347 ok(DeleteFileA("nonexistent\\a.txt"), "Expected nonexistent\\a.txt to exist\n");
1348 RemoveDirectoryA("nonexistent");
1350 else
1352 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1353 ok(shfo.fAnyOperationsAborted ||
1354 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1355 "Expected aborted operations\n");
1356 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
1358 DeleteFileA("test4.txt\\a.txt");
1360 /* destination is same as source file */
1361 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1362 shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
1363 shfo.fAnyOperationsAborted = FALSE;
1364 shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
1365 retval = SHFileOperationA(&shfo);
1366 if (retval == DE_OPCANCELLED)
1368 /* NT4 fails and doesn't copy any files */
1369 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1371 else
1373 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %ld\n", retval);
1374 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1376 ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
1377 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
1379 /* destination is same as source directory */
1380 shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
1381 shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
1382 shfo.fAnyOperationsAborted = FALSE;
1383 retval = SHFileOperationA(&shfo);
1384 if (retval == DE_OPCANCELLED)
1386 /* NT4 fails and doesn't copy any files */
1387 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1389 else
1391 ok(retval == ERROR_SUCCESS ||
1392 retval == DE_DESTSAMETREE, /* Vista */
1393 "Expected ERROR_SUCCESS or DE_DESTSAMETREE, got %ld\n", retval);
1394 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1396 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
1398 /* copy a directory into itself, error displayed in UI */
1399 shfo.pFrom = "test4.txt\0";
1400 shfo.pTo = "test4.txt\\newdir\0";
1401 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1402 shfo.fAnyOperationsAborted = FALSE;
1403 retval = SHFileOperationA(&shfo);
1404 ok(retval == ERROR_SUCCESS ||
1405 retval == DE_DESTSUBTREE, /* Vista */
1406 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %ld\n", retval);
1407 ok(!RemoveDirectoryA("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
1409 /* copy a directory to itself, error displayed in UI */
1410 shfo.pFrom = "test4.txt\0";
1411 shfo.pTo = "test4.txt\0";
1412 shfo.fAnyOperationsAborted = FALSE;
1413 retval = SHFileOperationA(&shfo);
1414 ok(retval == ERROR_SUCCESS ||
1415 retval == DE_DESTSUBTREE, /* Vista */
1416 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %ld\n", retval);
1418 /* copy a file into a directory, and the directory into itself */
1419 shfo.pFrom = "test1.txt\0test4.txt\0";
1420 shfo.pTo = "test4.txt\0";
1421 shfo.fAnyOperationsAborted = FALSE;
1422 shfo.fFlags |= FOF_NOCONFIRMATION;
1423 retval = SHFileOperationA(&shfo);
1424 ok(retval == ERROR_SUCCESS ||
1425 retval == DE_DESTSUBTREE, /* Vista */
1426 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %ld\n", retval);
1427 ok(DeleteFileA("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
1429 /* copy a file to a file, and the directory into itself */
1430 shfo.pFrom = "test1.txt\0test4.txt\0";
1431 shfo.pTo = "test4.txt\\a.txt\0";
1432 shfo.fAnyOperationsAborted = FALSE;
1433 retval = SHFileOperationA(&shfo);
1434 if (dir_exists("test4.txt\\a.txt"))
1436 /* Vista and W2K8 (broken or new behavior ?) */
1437 ok(retval == DE_DESTSUBTREE, "Expected DE_DESTSUBTREE, got %ld\n", retval);
1438 ok(DeleteFileA("test4.txt\\a.txt\\test1.txt"), "Expected test4.txt\\a.txt\\test1.txt to exist\n");
1439 RemoveDirectoryA("test4.txt\\a.txt");
1441 else
1443 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1444 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
1447 /* copy a nonexistent file to a nonexistent directory */
1448 shfo.pFrom = "e.txt\0";
1449 shfo.pTo = "nonexistent\0";
1450 shfo.fAnyOperationsAborted = FALSE;
1451 retval = SHFileOperationA(&shfo);
1452 ok(retval == 1026 ||
1453 retval == ERROR_FILE_NOT_FOUND || /* Vista */
1454 broken(retval == ERROR_SUCCESS), /* NT4 */
1455 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %ld\n", retval);
1456 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
1457 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
1459 /* Overwrite tests */
1460 clean_after_shfo_tests();
1461 init_shfo_tests();
1462 if (!on_nt4)
1464 /* NT4 would throw up some dialog boxes and doesn't copy files that are needed
1465 * in subsequent tests.
1467 shfo.fFlags = FOF_NOCONFIRMATION;
1468 shfo.pFrom = "test1.txt\0";
1469 shfo.pTo = "test2.txt\0";
1470 shfo.fAnyOperationsAborted = 0xdeadbeef;
1471 /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
1472 retval = SHFileOperationA(&shfo);
1473 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1474 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1475 ok(file_has_content("test2.txt", "test1.txt\n"), "The file was not copied\n");
1477 shfo.pFrom = "test3.txt\0test1.txt\0";
1478 shfo.pTo = "test2.txt\0one.txt\0";
1479 shfo.fFlags = FOF_NOCONFIRMATION | FOF_MULTIDESTFILES;
1480 /* without FOF_NOCONFIRMATION the confirmation is Yes/Yes to All/No/Cancel */
1481 retval = SHFileOperationA(&shfo);
1482 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1483 ok(file_has_content("test2.txt", "test3.txt\n"), "The file was not copied\n");
1485 shfo.pFrom = "one.txt\0";
1486 shfo.pTo = "testdir2\0";
1487 shfo.fFlags = FOF_NOCONFIRMATION;
1488 /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
1489 retval = SHFileOperationA(&shfo);
1490 ok(retval == 0, "Expected 0, got %ld\n", retval);
1491 ok(file_has_content("testdir2\\one.txt", "test1.txt\n"), "The file was not copied\n");
1494 createTestFile("test4.txt\\test1.txt");
1495 shfo.pFrom = "test4.txt\0";
1496 shfo.pTo = "testdir2\0";
1497 /* WinMe needs FOF_NOERRORUI */
1498 shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI;
1499 retval = SHFileOperationA(&shfo);
1500 ok(retval == ERROR_SUCCESS ||
1501 broken(retval == 0x100a1), /* WinMe */
1502 "Expected ERROR_SUCCESS, got %ld\n", retval);
1503 shfo.fFlags = FOF_NOCONFIRMATION;
1504 if (ERROR_SUCCESS)
1506 createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */
1507 /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */
1508 retval = SHFileOperationA(&shfo);
1509 ok(retval == 0, "Expected 0, got %ld\n", retval);
1510 ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
1513 createTestFile("one.txt");
1515 /* pFrom contains bogus 2nd name longer than MAX_PATH */
1516 memset(from, 'a', MAX_PATH*2);
1517 memset(from+MAX_PATH*2, 0, 2);
1518 lstrcpyA(from, "one.txt");
1519 shfo.pFrom = from;
1520 shfo.pTo = "two.txt\0";
1521 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1522 retval = SHFileOperationA(&shfo);
1523 ok(retval == 1148 || retval == 1026 ||
1524 retval == ERROR_ACCESS_DENIED || /* win2k */
1525 retval == DE_INVALIDFILES, /* Vista */
1526 "Unexpected return value, got %ld\n", retval);
1527 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1528 if (dir_exists("two.txt"))
1529 /* Vista and W2K8 (broken or new behavior ?) */
1530 ok(RemoveDirectoryA("two.txt"), "Expected two.txt to exist\n");
1531 else
1532 ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
1534 createTestFile("one.txt");
1536 /* pTo contains bogus 2nd name longer than MAX_PATH */
1537 memset(to, 'a', MAX_PATH*2);
1538 memset(to+MAX_PATH*2, 0, 2);
1539 lstrcpyA(to, "two.txt");
1540 shfo.pFrom = "one.txt\0";
1541 shfo.pTo = to;
1542 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1543 retval = SHFileOperationA(&shfo);
1544 if (retval == DE_OPCANCELLED)
1546 /* NT4 fails and doesn't copy any files */
1547 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1549 else
1551 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1552 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1554 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1556 createTestFile("one.txt");
1558 /* no FOF_MULTIDESTFILES, two files in pTo */
1559 shfo.pFrom = "one.txt\0";
1560 shfo.pTo = "two.txt\0three.txt\0";
1561 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1562 retval = SHFileOperationA(&shfo);
1563 if (retval == DE_OPCANCELLED)
1565 /* NT4 fails and doesn't copy any files */
1566 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1568 else
1570 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1571 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1573 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1575 createTestFile("one.txt");
1577 /* both pFrom and pTo contain bogus 2nd names longer than MAX_PATH */
1578 memset(from, 'a', MAX_PATH*2);
1579 memset(from+MAX_PATH*2, 0, 2);
1580 memset(to, 'a', MAX_PATH*2);
1581 memset(to+MAX_PATH*2, 0, 2);
1582 lstrcpyA(from, "one.txt");
1583 lstrcpyA(to, "two.txt");
1584 shfo.pFrom = from;
1585 shfo.pTo = to;
1586 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1587 retval = SHFileOperationA(&shfo);
1588 ok(retval == 1148 || retval == 1026 ||
1589 retval == ERROR_ACCESS_DENIED || /* win2k */
1590 retval == DE_INVALIDFILES, /* Vista */
1591 "Unexpected return value, got %ld\n", retval);
1592 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1593 if (dir_exists("two.txt"))
1594 /* Vista and W2K8 (broken or new behavior ?) */
1595 ok(RemoveDirectoryA("two.txt"), "Expected two.txt to exist\n");
1596 else
1597 ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
1599 createTestFile("one.txt");
1601 /* pTo contains bogus 2nd name longer than MAX_PATH, FOF_MULTIDESTFILES */
1602 memset(to, 'a', MAX_PATH*2);
1603 memset(to+MAX_PATH*2, 0, 2);
1604 lstrcpyA(to, "two.txt");
1605 shfo.pFrom = "one.txt\0";
1606 shfo.pTo = to;
1607 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1608 FOF_SILENT | FOF_NOERRORUI;
1609 retval = SHFileOperationA(&shfo);
1610 if (retval == DE_OPCANCELLED)
1612 /* NT4 fails and doesn't copy any files */
1613 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1615 else
1617 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1618 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1620 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1622 createTestFile("one.txt");
1623 createTestFile("two.txt");
1625 /* pTo contains bogus 2nd name longer than MAX_PATH,
1626 * multiple source files,
1627 * dest directory does not exist
1629 memset(to, 'a', 2 * MAX_PATH);
1630 memset(to+MAX_PATH*2, 0, 2);
1631 lstrcpyA(to, "threedir");
1632 shfo.pFrom = "one.txt\0two.txt\0";
1633 shfo.pTo = to;
1634 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1635 retval = SHFileOperationA(&shfo);
1636 if (dir_exists("threedir"))
1638 /* Vista and W2K8 (broken or new behavior ?) */
1639 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1640 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1641 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1642 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1644 else
1646 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1647 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1648 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1649 ok(!DeleteFileA("threedir"), "Expected file to not exist\n");
1650 ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1652 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1653 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1655 createTestFile("one.txt");
1656 createTestFile("two.txt");
1657 CreateDirectoryA("threedir", NULL);
1659 /* pTo contains bogus 2nd name longer than MAX_PATH,
1660 * multiple source files,
1661 * dest directory does exist
1663 memset(to, 'a', 2 * MAX_PATH);
1664 memset(to+MAX_PATH*2, 0, 2);
1665 lstrcpyA(to, "threedir");
1666 shfo.pFrom = "one.txt\0two.txt\0";
1667 shfo.pTo = to;
1668 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1669 retval = SHFileOperationA(&shfo);
1670 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1671 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1672 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1673 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1674 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1675 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1677 if (0) {
1678 /* this crashes on win9x */
1679 createTestFile("one.txt");
1680 createTestFile("two.txt");
1682 /* pTo contains bogus 2nd name longer than MAX_PATH,
1683 * multiple source files, FOF_MULTIDESTFILES
1684 * dest dir does not exist
1687 memset(to, 'a', 2 * MAX_PATH);
1688 memset(to+MAX_PATH*2, 0, 2);
1689 lstrcpyA(to, "threedir");
1690 shfo.pFrom = "one.txt\0two.txt\0";
1691 shfo.pTo = to;
1692 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1693 FOF_SILENT | FOF_NOERRORUI;
1694 retval = SHFileOperationA(&shfo);
1695 ok(retval == ERROR_CANCELLED ||
1696 retval == ERROR_SUCCESS, /* win2k3 */
1697 "Expected ERROR_CANCELLED or ERROR_SUCCESS, got %ld\n", retval);
1698 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1699 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1700 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1701 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1702 ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1704 /* file exists in win2k */
1705 DeleteFileA("threedir");
1709 createTestFile("one.txt");
1710 createTestFile("two.txt");
1711 CreateDirectoryA("threedir", NULL);
1713 /* pTo contains bogus 2nd name longer than MAX_PATH,
1714 * multiple source files, FOF_MULTIDESTFILES
1715 * dest dir does exist
1717 memset(to, 'a', 2 * MAX_PATH);
1718 memset(to+MAX_PATH*2, 0, 2);
1719 lstrcpyA(to, "threedir");
1720 ptr = to + lstrlenA(to) + 1;
1721 lstrcpyA(ptr, "fourdir");
1722 shfo.pFrom = "one.txt\0two.txt\0";
1723 shfo.pTo = to;
1724 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1725 FOF_SILENT | FOF_NOERRORUI;
1726 retval = SHFileOperationA(&shfo);
1727 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1728 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1729 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1730 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1731 if (dir_exists("fourdir"))
1733 /* Vista and W2K8 (broken or new behavior ?) */
1734 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1735 ok(DeleteFileA("fourdir\\two.txt"), "Expected file to exist\n");
1736 RemoveDirectoryA("fourdir");
1738 else
1740 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1741 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1742 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1744 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1746 createTestFile("one.txt");
1747 createTestFile("two.txt");
1748 CreateDirectoryA("threedir", NULL);
1750 /* multiple source files, FOF_MULTIDESTFILES
1751 * multiple dest files, but first dest dir exists
1752 * num files in lists is equal
1754 shfo.pFrom = "one.txt\0two.txt\0";
1755 shfo.pTo = "threedir\0fourdir\0";
1756 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1757 FOF_SILENT | FOF_NOERRORUI;
1758 retval = SHFileOperationA(&shfo);
1759 ok(retval == ERROR_CANCELLED ||
1760 retval == DE_FILEDESTISFLD || /* Vista */
1761 broken(retval == DE_OPCANCELLED), /* Win9x, NT4 */
1762 "Expected ERROR_CANCELLED or DE_FILEDESTISFLD. got %ld\n", retval);
1763 if (file_exists("threedir\\threedir"))
1765 /* NT4 */
1766 ok(DeleteFileA("threedir\\threedir"), "Expected file to exist\n");
1768 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1769 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1770 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1771 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1772 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1773 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1774 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1776 createTestFile("one.txt");
1777 createTestFile("two.txt");
1778 CreateDirectoryA("threedir", NULL);
1780 /* multiple source files, FOF_MULTIDESTFILES
1781 * multiple dest files, but first dest dir exists
1782 * num files in lists is not equal
1784 shfo.pFrom = "one.txt\0two.txt\0";
1785 shfo.pTo = "threedir\0fourdir\0five\0";
1786 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1787 FOF_SILENT | FOF_NOERRORUI;
1788 retval = SHFileOperationA(&shfo);
1789 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1790 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1791 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1792 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1793 if (dir_exists("fourdir"))
1795 /* Vista and W2K8 (broken or new behavior ?) */
1796 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1797 ok(DeleteFileA("fourdir\\two.txt"), "Expected file to exist\n");
1798 RemoveDirectoryA("fourdir");
1800 else
1802 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1803 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1804 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1806 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1807 ok(!DeleteFileA("five"), "Expected file to not exist\n");
1808 ok(!RemoveDirectoryA("five"), "Expected dir to not exist\n");
1810 createTestFile("aa.txt");
1811 createTestFile("ab.txt");
1812 CreateDirectoryA("one", NULL);
1813 CreateDirectoryA("two", NULL);
1815 /* Test with FOF_MULTIDESTFILES with a wildcard in pFrom and single output directory. */
1816 shfo.pFrom = "a*.txt\0";
1817 shfo.pTo = "one\0";
1818 shfo.fFlags |= FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_MULTIDESTFILES;
1819 retval = SHFileOperationA(&shfo);
1820 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1821 ok(DeleteFileA("one\\aa.txt"), "Expected file to exist\n");
1822 ok(DeleteFileA("one\\ab.txt"), "Expected file to exist\n");
1824 /* pFrom has a glob, pTo has more than one dest */
1825 shfo.pFrom = "a*.txt\0";
1826 shfo.pTo = "one\0two\0";
1827 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1828 retval = SHFileOperationA(&shfo);
1829 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1830 ok(DeleteFileA("one\\aa.txt"), "Expected file to exist\n");
1831 ok(DeleteFileA("one\\ab.txt"), "Expected file to exist\n");
1832 ok(!DeleteFileA("two\\aa.txt"), "Expected file to not exist\n");
1833 ok(!DeleteFileA("two\\ab.txt"), "Expected file to not exist\n");
1834 ok(DeleteFileA("aa.txt"), "Expected file to exist\n");
1835 ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
1836 ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
1837 ok(RemoveDirectoryA("two"), "Expected dir to exist\n");
1839 /* pTo is an empty string */
1840 CreateDirectoryA("dir", NULL);
1841 createTestFile("dir\\abcdefgh.abc");
1842 shfo.pFrom = "dir\\abcdefgh.abc\0";
1843 shfo.pTo = "\0";
1844 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1845 retval = SHFileOperationA(&shfo);
1846 ok(retval == ERROR_SUCCESS ||
1847 broken(retval == DE_OPCANCELLED), /* NT4 */
1848 "Expected ERROR_SUCCESS, got %ld\n", retval);
1849 if (retval == ERROR_SUCCESS)
1850 ok(DeleteFileA("abcdefgh.abc"), "Expected file to exist\n");
1851 ok(DeleteFileA("dir\\abcdefgh.abc"), "Expected file to exist\n");
1852 ok(RemoveDirectoryA("dir"), "Expected dir to exist\n");
1854 /* Check last error after a successful file operation. */
1855 clean_after_shfo_tests();
1856 init_shfo_tests();
1857 shfo.pFrom = "test1.txt\0";
1858 shfo.pTo = "testdir2\0";
1859 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1860 SetLastError(0xdeadbeef);
1861 retval = SHFileOperationA(&shfo);
1862 ok(retval == ERROR_SUCCESS, "File copy failed with %ld\n", retval);
1863 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1864 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError());
1866 /* Check last error after a failed file operation. */
1867 clean_after_shfo_tests();
1868 init_shfo_tests();
1869 shfo.pFrom = "nonexistent\0";
1870 shfo.pTo = "testdir2\0";
1871 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1872 SetLastError(0xdeadbeef);
1873 retval = SHFileOperationA(&shfo);
1874 ok(retval != ERROR_SUCCESS, "Unexpected ERROR_SUCCESS\n");
1875 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1876 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError());
1878 /* test with / */
1879 CreateDirectoryA("dir", NULL);
1880 CreateDirectoryA("dir\\subdir", NULL);
1881 createTestFile("dir\\subdir\\aa.txt");
1882 shfo.pFrom = "dir/subdir/aa.txt\0";
1883 shfo.pTo = "dir\\destdir/aa.txt\0";
1884 shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT | FOF_NOERRORUI;
1885 retval = SHFileOperationA(&shfo);
1886 if (dir_exists("dir\\destdir"))
1888 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
1889 ok(DeleteFileA("dir\\destdir\\aa.txt"), "Expected file to exist\n");
1890 ok(RemoveDirectoryA("dir\\destdir"), "Expected dir to exist\n");
1892 else
1894 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* WinXp, Win2k */);
1896 ok(DeleteFileA("dir\\subdir\\aa.txt"), "Expected file to exist\n");
1897 ok(RemoveDirectoryA("dir\\subdir"), "Expected dir to exist\n");
1898 ok(RemoveDirectoryA("dir"), "Expected dir to exist\n");
1901 /* tests the FO_MOVE action */
1902 static void test_move(void)
1904 SHFILEOPSTRUCTA shfo, shfo2;
1905 CHAR from[5*MAX_PATH];
1906 CHAR to[5*MAX_PATH];
1907 DWORD retval;
1909 clean_after_shfo_tests();
1910 init_shfo_tests();
1912 shfo.hwnd = NULL;
1913 shfo.wFunc = FO_MOVE;
1914 shfo.pFrom = from;
1915 shfo.pTo = to;
1916 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR;
1917 shfo.hNameMappings = NULL;
1918 shfo.lpszProgressTitle = NULL;
1919 shfo.fAnyOperationsAborted = FALSE;
1921 set_curr_dir_path(from, "testdir2\\*.*\0");
1922 set_curr_dir_path(to, "test4.txt\\*.*\0");
1923 retval = SHFileOperationA(&shfo);
1924 ok(retval != 0, "SHFileOperation should fail\n");
1925 ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
1927 ok(file_exists("testdir2"), "dir should not be moved\n");
1928 ok(file_exists("testdir2\\one.txt"), "file should not be moved\n");
1929 ok(file_exists("testdir2\\nested"), "dir should not be moved\n");
1930 ok(file_exists("testdir2\\nested\\two.txt"), "file should not be moved\n");
1932 set_curr_dir_path(from, "testdir2\\*.*\0");
1933 set_curr_dir_path(to, "test4.txt\0");
1934 retval = SHFileOperationA(&shfo);
1935 ok(!retval, "SHFileOperation error %#lx\n", retval);
1936 ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
1938 ok(file_exists("testdir2"), "dir should not be moved\n");
1939 ok(!file_exists("testdir2\\one.txt"), "file should be moved\n");
1940 ok(!file_exists("testdir2\\nested"), "dir should be moved\n");
1941 ok(!file_exists("testdir2\\nested\\two.txt"), "file should be moved\n");
1943 ok(file_exists("test4.txt"), "dir should exist\n");
1944 ok(file_exists("test4.txt\\one.txt"), "file should exist\n");
1945 ok(file_exists("test4.txt\\nested"), "dir should exist\n");
1946 ok(file_exists("test4.txt\\nested\\two.txt"), "file should exist\n");
1948 clean_after_shfo_tests();
1949 init_shfo_tests();
1951 /* same tests above, but with / */
1952 set_curr_dir_path(from, "testdir2/*.*\0");
1953 set_curr_dir_path(to, "test4.txt\0");
1954 retval = SHFileOperationA(&shfo);
1955 ok(retval == ERROR_SUCCESS ||
1956 broken(retval == ERROR_FILE_NOT_FOUND), /* WinXp, Win2k3 */
1957 "Expected ERROR_SUCCESS, got %ld\n", retval);
1958 if (retval == ERROR_SUCCESS)
1960 ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
1962 ok(dir_exists("testdir2"), "dir should not be moved\n");
1963 ok(!file_exists("testdir2\\one.txt"), "file should be moved\n");
1964 ok(!dir_exists("testdir2\\nested"), "dir should be moved\n");
1965 ok(!file_exists("testdir2\\nested\\two.txt"), "file should be moved\n");
1967 ok(file_exists("test4.txt\\one.txt"), "file should exist\n");
1968 ok(dir_exists("test4.txt\\nested"), "dir should exist\n");
1969 ok(file_exists("test4.txt\\nested\\two.txt"), "file should exist\n");
1972 clean_after_shfo_tests();
1973 init_shfo_tests();
1975 shfo.hwnd = NULL;
1976 shfo.wFunc = FO_MOVE;
1977 shfo.pFrom = from;
1978 shfo.pTo = to;
1979 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1980 shfo.hNameMappings = NULL;
1981 shfo.lpszProgressTitle = NULL;
1983 set_curr_dir_path(from, "test1.txt\0");
1984 set_curr_dir_path(to, "test4.txt\0");
1985 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
1986 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
1987 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
1989 set_curr_dir_path(from, "test?.txt\0");
1990 set_curr_dir_path(to, "testdir2\0");
1991 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
1992 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
1993 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
1994 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
1995 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
1996 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
1998 clean_after_shfo_tests();
1999 init_shfo_tests();
2001 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
2002 shfo2.fFlags |= FOF_MULTIDESTFILES;
2004 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
2005 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
2006 if (old_shell32)
2007 shfo2.fFlags |= FOF_NOCONFIRMMKDIR;
2008 ok(!SHFileOperationA(&shfo2), "Move many files\n");
2009 ok(DeleteFileA("test6.txt"), "The file is not moved - many files are "
2010 "specified as a target\n");
2011 ok(DeleteFileA("test7.txt"), "The file is not moved\n");
2012 ok(RemoveDirectoryA("test8.txt"), "The directory is not moved\n");
2014 init_shfo_tests();
2016 /* number of sources does not correspond to number of targets,
2017 include directories */
2018 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
2019 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
2020 retval = SHFileOperationA(&shfo2);
2021 if (dir_exists("test6.txt"))
2023 if (retval == ERROR_SUCCESS)
2025 /* Old shell32 */
2026 DeleteFileA("test6.txt\\test1.txt");
2027 DeleteFileA("test6.txt\\test2.txt");
2028 RemoveDirectoryA("test6.txt\\test4.txt");
2029 RemoveDirectoryA("test6.txt");
2031 else
2033 /* Vista and W2K8 (broken or new behavior ?) */
2034 ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %ld\n", retval);
2035 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved\n");
2036 RemoveDirectoryA("test6.txt");
2037 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not moved\n");
2038 RemoveDirectoryA("test7.txt");
2041 else
2043 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2044 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2045 "specified as a target\n");
2048 init_shfo_tests();
2049 /* number of sources does not correspond to number of targets,
2050 files only,
2051 from exceeds to */
2052 set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0");
2053 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
2054 retval = SHFileOperationA(&shfo2);
2055 if (dir_exists("test6.txt"))
2057 if (retval == ERROR_SUCCESS)
2059 /* Old shell32 */
2060 DeleteFileA("test6.txt\\test1.txt");
2061 DeleteFileA("test6.txt\\test2.txt");
2062 RemoveDirectoryA("test6.txt\\test4.txt");
2063 RemoveDirectoryA("test6.txt");
2065 else
2067 /* Vista and W2K8 (broken or new behavior ?) */
2068 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %ld\n", retval);
2069 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved\n");
2070 RemoveDirectoryA("test6.txt");
2071 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not moved\n");
2072 RemoveDirectoryA("test7.txt");
2073 ok(file_exists("test3.txt"), "File should not be moved\n");
2076 else
2078 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2079 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2080 "specified as a target\n");
2083 init_shfo_tests();
2084 /* number of sources does not correspond to number of targets,
2085 files only,
2086 too exceeds from */
2087 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
2088 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
2089 retval = SHFileOperationA(&shfo2);
2090 if (dir_exists("test6.txt"))
2092 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
2093 ok(DeleteFileA("test6.txt\\test1.txt"),"The file is not moved\n");
2094 ok(DeleteFileA("test7.txt\\test2.txt"),"The file is not moved\n");
2095 ok(!dir_exists("test8.txt") && !file_exists("test8.txt"),
2096 "Directory should not be created\n");
2097 RemoveDirectoryA("test6.txt");
2098 RemoveDirectoryA("test7.txt");
2100 else
2102 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* WinXp, Win2k */);
2103 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2104 "specified as a target\n");
2107 init_shfo_tests();
2108 /* number of sources does not correspond to number of targets,
2109 target directories */
2110 set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0");
2111 set_curr_dir_path(to, "test4.txt\0test5.txt\0");
2112 retval = SHFileOperationA(&shfo2);
2113 if (dir_exists("test5.txt"))
2115 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %ld\n", retval);
2116 ok(DeleteFileA("test4.txt\\test1.txt"),"The file is not moved\n");
2117 ok(DeleteFileA("test5.txt\\test2.txt"),"The file is not moved\n");
2118 ok(file_exists("test3.txt"), "The file is not moved\n");
2119 RemoveDirectoryA("test4.txt");
2120 RemoveDirectoryA("test5.txt");
2122 else
2124 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
2125 ok(DeleteFileA("test4.txt\\test1.txt"),"The file is not moved\n");
2126 ok(DeleteFileA("test4.txt\\test2.txt"),"The file is not moved\n");
2127 ok(DeleteFileA("test4.txt\\test3.txt"),"The file is not moved\n");
2131 init_shfo_tests();
2132 /* 0 incoming files */
2133 set_curr_dir_path(from, "\0\0");
2134 set_curr_dir_path(to, "test6.txt\0\0");
2135 retval = SHFileOperationA(&shfo2);
2136 ok(retval == ERROR_SUCCESS || retval == ERROR_ACCESS_DENIED
2137 , "Expected ERROR_SUCCESS || ERROR_ACCESS_DENIED, got %ld\n", retval);
2138 ok(!file_exists("test6.txt"), "The file should not exist\n");
2140 init_shfo_tests();
2141 /* 0 outgoing files */
2142 set_curr_dir_path(from, "test1\0\0");
2143 set_curr_dir_path(to, "\0\0");
2144 retval = SHFileOperationA(&shfo2);
2145 ok(retval == ERROR_FILE_NOT_FOUND ||
2146 broken(retval == 1026)
2147 , "Expected ERROR_FILE_NOT_FOUND, got %ld\n", retval);
2148 ok(!file_exists("test6.txt"), "The file should not exist\n");
2150 init_shfo_tests();
2152 set_curr_dir_path(from, "test3.txt\0");
2153 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
2154 ok(!SHFileOperationA(&shfo), "Can't move file to other directory\n");
2155 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
2157 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
2158 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
2159 if (old_shell32)
2160 shfo.fFlags |= FOF_NOCONFIRMMKDIR;
2161 retval = SHFileOperationA(&shfo);
2162 if (dir_exists("test6.txt"))
2164 /* Old shell32 */
2165 /* Vista and W2K8 (broken or new behavior ?) */
2166 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
2167 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved. Many files are specified\n");
2168 ok(DeleteFileA("test6.txt\\test2.txt"), "The file is not moved. Many files are specified\n");
2169 ok(DeleteFileA("test6.txt\\test4.txt\\test1.txt"), "The file is not moved. Many files are specified\n");
2170 ok(RemoveDirectoryA("test6.txt\\test4.txt"), "The directory is not moved. Many files are specified\n");
2171 RemoveDirectoryA("test6.txt");
2172 init_shfo_tests();
2174 else
2176 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2177 ok(file_exists("test1.txt"), "The file is moved. Many files are specified\n");
2178 ok(dir_exists("test4.txt"), "The directory is moved. Many files are specified\n");
2181 set_curr_dir_path(from, "test1.txt\0");
2182 set_curr_dir_path(to, "test6.txt\0");
2183 ok(!SHFileOperationA(&shfo), "Move file failed\n");
2184 ok(!file_exists("test1.txt"), "The file is not moved\n");
2185 ok(file_exists("test6.txt"), "The file is not moved\n");
2186 set_curr_dir_path(from, "test6.txt\0");
2187 set_curr_dir_path(to, "test1.txt\0");
2188 ok(!SHFileOperationA(&shfo), "Move file back failed\n");
2190 set_curr_dir_path(from, "test4.txt\0");
2191 set_curr_dir_path(to, "test6.txt\0");
2192 ok(!SHFileOperationA(&shfo), "Move dir failed\n");
2193 ok(!dir_exists("test4.txt"), "The dir is not moved\n");
2194 ok(dir_exists("test6.txt"), "The dir is moved\n");
2195 set_curr_dir_path(from, "test6.txt\0");
2196 set_curr_dir_path(to, "test4.txt\0");
2197 ok(!SHFileOperationA(&shfo), "Move dir back failed\n");
2199 /* move one file to two others */
2200 init_shfo_tests();
2201 shfo.pFrom = "test1.txt\0";
2202 shfo.pTo = "a.txt\0b.txt\0";
2203 retval = SHFileOperationA(&shfo);
2204 if (retval == DE_OPCANCELLED)
2206 /* NT4 fails and doesn't move any files */
2207 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
2208 DeleteFileA("test1.txt");
2210 else
2212 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
2213 if (old_shell32)
2215 DeleteFileA("a.txt\\a.txt");
2216 RemoveDirectoryA("a.txt");
2218 else
2219 ok(DeleteFileA("a.txt"), "Expected a.txt to exist\n");
2220 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
2222 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
2224 /* move two files to one other */
2225 shfo.pFrom = "test2.txt\0test3.txt\0";
2226 shfo.pTo = "test1.txt\0";
2227 retval = SHFileOperationA(&shfo);
2228 if (dir_exists("test1.txt"))
2230 /* Old shell32 */
2231 /* Vista and W2K8 (broken or new behavior ?) */
2232 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
2233 ok(DeleteFileA("test1.txt\\test2.txt"), "Expected test1.txt\\test2.txt to exist\n");
2234 ok(DeleteFileA("test1.txt\\test3.txt"), "Expected test1.txt\\test3.txt to exist\n");
2235 RemoveDirectoryA("test1.txt");
2236 createTestFile("test2.txt");
2237 createTestFile("test3.txt");
2239 else
2241 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2242 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
2243 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
2244 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
2247 /* move a directory into itself */
2248 shfo.pFrom = "test4.txt\0";
2249 shfo.pTo = "test4.txt\\b.txt\0";
2250 retval = SHFileOperationA(&shfo);
2251 ok(retval == ERROR_SUCCESS ||
2252 retval == DE_DESTSUBTREE, /* Vista */
2253 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %ld\n", retval);
2254 ok(!RemoveDirectoryA("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
2255 ok(dir_exists("test4.txt"), "Expected test4.txt to exist\n");
2257 /* move many files without FOF_MULTIDESTFILES */
2258 shfo.pFrom = "test2.txt\0test3.txt\0";
2259 shfo.pTo = "d.txt\0e.txt\0";
2260 retval = SHFileOperationA(&shfo);
2261 if (dir_exists("d.txt"))
2263 /* Old shell32 */
2264 /* Vista and W2K8 (broken or new behavior ?) */
2265 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
2266 ok(DeleteFileA("d.txt\\test2.txt"), "Expected d.txt\\test2.txt to exist\n");
2267 ok(DeleteFileA("d.txt\\test3.txt"), "Expected d.txt\\test3.txt to exist\n");
2268 RemoveDirectoryA("d.txt");
2269 createTestFile("test2.txt");
2270 createTestFile("test3.txt");
2272 else
2274 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2275 ok(!DeleteFileA("d.txt"), "Expected d.txt to not exist\n");
2276 ok(!DeleteFileA("e.txt"), "Expected e.txt to not exist\n");
2279 /* number of sources != number of targets */
2280 shfo.pTo = "d.txt\0";
2281 shfo.fFlags |= FOF_MULTIDESTFILES;
2282 retval = SHFileOperationA(&shfo);
2283 if (dir_exists("d.txt"))
2285 if (old_shell32)
2287 DeleteFileA("d.txt\\test2.txt");
2288 DeleteFileA("d.txt\\test3.txt");
2289 RemoveDirectoryA("d.txt");
2290 createTestFile("test2.txt");
2292 else
2294 /* Vista and W2K8 (broken or new behavior ?) */
2295 ok(retval == DE_SAMEFILE,
2296 "Expected DE_SAMEFILE, got %ld\n", retval);
2297 ok(DeleteFileA("d.txt\\test2.txt"), "Expected d.txt\\test2.txt to exist\n");
2298 ok(!file_exists("d.txt\\test3.txt"), "Expected d.txt\\test3.txt to not exist\n");
2299 RemoveDirectoryA("d.txt");
2300 createTestFile("test2.txt");
2303 else
2305 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2306 ok(!DeleteFileA("d.txt"), "Expected d.txt to not exist\n");
2309 /* FO_MOVE does not create dest directories */
2310 shfo.pFrom = "test2.txt\0";
2311 shfo.pTo = "dir1\\dir2\\test2.txt\0";
2312 retval = SHFileOperationA(&shfo);
2313 if (dir_exists("dir1"))
2315 /* Vista and W2K8 (broken or new behavior ?) */
2316 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
2317 ok(DeleteFileA("dir1\\dir2\\test2.txt"), "Expected dir1\\dir2\\test2.txt to exist\n");
2318 RemoveDirectoryA("dir1\\dir2");
2319 RemoveDirectoryA("dir1");
2320 createTestFile("test2.txt");
2322 else
2324 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2327 /* try to overwrite an existing file */
2328 shfo.pTo = "test3.txt\0";
2329 retval = SHFileOperationA(&shfo);
2330 if (retval == DE_OPCANCELLED)
2332 /* NT4 fails and doesn't move any files */
2333 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
2335 else
2337 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", retval);
2338 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
2339 if (old_shell32)
2341 DeleteFileA("test3.txt\\test3.txt");
2342 RemoveDirectoryA("test3.txt");
2344 else
2345 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
2349 static void test_sh_create_dir(void)
2351 CHAR path[MAX_PATH];
2352 int ret;
2354 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2355 ret = SHCreateDirectoryExA(NULL, path, NULL);
2356 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
2357 ok(file_exists("testdir2"), "The first directory is not created\n");
2358 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
2360 ret = SHCreateDirectoryExA(NULL, path, NULL);
2361 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
2363 ret = SHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
2364 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory, ret = %d\n", ret);
2365 ok(file_exists("c:\\testdir3"), "The directory is not created\n");
2368 static void test_sh_path_prepare(void)
2370 HRESULT res;
2371 CHAR path[MAX_PATH];
2372 CHAR UNICODE_PATH_A[MAX_PATH];
2373 BOOL UsedDefaultChar;
2375 /* directory exists, SHPPFW_NONE */
2376 set_curr_dir_path(path, "testdir2\0");
2377 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2378 ok(res == S_OK, "res == 0x%08lx, expected S_OK\n", res);
2380 /* directory exists, SHPPFW_IGNOREFILENAME */
2381 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2382 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
2383 ok(res == S_OK, "res == 0x%08lx, expected S_OK\n", res);
2385 /* directory exists, SHPPFW_DIRCREATE */
2386 set_curr_dir_path(path, "testdir2\0");
2387 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
2388 ok(res == S_OK, "res == 0x%08lx, expected S_OK\n", res);
2390 /* directory exists, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
2391 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2392 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
2393 ok(res == S_OK, "res == 0x%08lx, expected S_OK\n", res);
2394 ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
2396 /* file exists, SHPPFW_NONE */
2397 set_curr_dir_path(path, "test1.txt\0");
2398 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2399 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
2400 res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
2401 res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
2402 "Unexpected result : 0x%08lx\n", res);
2404 /* file exists, SHPPFW_DIRCREATE */
2405 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
2406 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
2407 res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
2408 res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
2409 "Unexpected result : 0x%08lx\n", res);
2411 /* file exists, SHPPFW_NONE, trailing \ */
2412 set_curr_dir_path(path, "test1.txt\\\0");
2413 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2414 ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) ||
2415 res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */
2416 res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */
2417 "Unexpected result : 0x%08lx\n", res);
2419 /* relative path exists, SHPPFW_DIRCREATE */
2420 res = SHPathPrepareForWriteA(0, 0, ".\\testdir2", SHPPFW_DIRCREATE);
2421 ok(res == S_OK, "res == 0x%08lx, expected S_OK\n", res);
2423 /* relative path doesn't exist, SHPPFW_DIRCREATE -- Windows does not create the directory in this case */
2424 res = SHPathPrepareForWriteA(0, 0, ".\\testdir2\\test4.txt", SHPPFW_DIRCREATE);
2425 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08lx, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2426 ok(!file_exists(".\\testdir2\\test4.txt\\"), ".\\testdir2\\test4.txt\\ exists but shouldn't\n");
2428 /* directory doesn't exist, SHPPFW_NONE */
2429 set_curr_dir_path(path, "nonexistent\0");
2430 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2431 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08lx, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2433 /* directory doesn't exist, SHPPFW_IGNOREFILENAME */
2434 set_curr_dir_path(path, "nonexistent\\notreal\0");
2435 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
2436 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08lx, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2437 ok(!file_exists("nonexistent\\notreal"), "nonexistent\\notreal exists but shouldn't\n");
2438 ok(!file_exists("nonexistent\\"), "nonexistent\\ exists but shouldn't\n");
2440 /* directory doesn't exist, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
2441 set_curr_dir_path(path, "testdir2\\test4.txt\\\0");
2442 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
2443 ok(res == S_OK, "res == 0x%08lx, expected S_OK\n", res);
2444 ok(file_exists("testdir2\\test4.txt\\"), "testdir2\\test4.txt doesn't exist but should\n");
2446 /* nested directory doesn't exist, SHPPFW_DIRCREATE */
2447 set_curr_dir_path(path, "nonexistent\\notreal\0");
2448 res = SHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
2449 ok(res == S_OK, "res == 0x%08lx, expected S_OK\n", res);
2450 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal doesn't exist but should\n");
2452 /* SHPPFW_ASKDIRCREATE, SHPPFW_NOWRITECHECK, and SHPPFW_MEDIACHECKONLY are untested */
2454 SetLastError(0xdeadbeef);
2455 UsedDefaultChar = FALSE;
2456 if (WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, UNICODE_PATH, -1, UNICODE_PATH_A, sizeof(UNICODE_PATH_A), NULL, &UsedDefaultChar) == 0)
2458 win_skip("Could not convert Unicode path name to multibyte (%ld)\n", GetLastError());
2459 return;
2461 if (UsedDefaultChar)
2463 win_skip("Could not find unique multibyte representation for directory name using default codepage\n");
2464 return;
2467 /* unicode directory doesn't exist, SHPPFW_NONE */
2468 RemoveDirectoryA(UNICODE_PATH_A);
2469 res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
2470 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == %08lx, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2471 ok(!file_exists(UNICODE_PATH_A), "unicode path was created but shouldn't be\n");
2472 RemoveDirectoryA(UNICODE_PATH_A);
2474 /* unicode directory doesn't exist, SHPPFW_DIRCREATE */
2475 res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
2476 ok(res == S_OK, "res == %08lx, expected S_OK\n", res);
2477 ok(file_exists(UNICODE_PATH_A), "unicode path should've been created\n");
2479 /* unicode directory exists, SHPPFW_NONE */
2480 res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
2481 ok(res == S_OK, "ret == %08lx, expected S_OK\n", res);
2483 /* unicode directory exists, SHPPFW_DIRCREATE */
2484 res = SHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
2485 ok(res == S_OK, "ret == %08lx, expected S_OK\n", res);
2486 RemoveDirectoryA(UNICODE_PATH_A);
2489 static void test_sh_new_link_info(void)
2491 BOOL ret, mustcopy=TRUE;
2492 CHAR linkto[MAX_PATH];
2493 CHAR destdir[MAX_PATH];
2494 CHAR result[MAX_PATH];
2495 CHAR result2[MAX_PATH];
2497 /* source file does not exist */
2498 set_curr_dir_path(linkto, "nosuchfile.txt\0");
2499 set_curr_dir_path(destdir, "testdir2\0");
2500 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2501 ok(ret == FALSE ||
2502 broken(ret == lstrlenA(result) + 1), /* NT4 */
2503 "SHGetNewLinkInfoA succeeded\n");
2504 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2506 /* dest dir does not exist */
2507 set_curr_dir_path(linkto, "test1.txt\0");
2508 set_curr_dir_path(destdir, "nosuchdir\0");
2509 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2510 ok(ret == TRUE ||
2511 broken(ret == lstrlenA(result) + 1), /* NT4 */
2512 "SHGetNewLinkInfoA failed, err=%li\n", GetLastError());
2513 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2515 /* source file exists */
2516 set_curr_dir_path(linkto, "test1.txt\0");
2517 set_curr_dir_path(destdir, "testdir2\0");
2518 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2519 ok(ret == TRUE ||
2520 broken(ret == lstrlenA(result) + 1), /* NT4 */
2521 "SHGetNewLinkInfoA failed, err=%li\n", GetLastError());
2522 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2523 ok(CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, destdir,
2524 lstrlenA(destdir), result, lstrlenA(destdir)) == CSTR_EQUAL,
2525 "%s does not start with %s\n", result, destdir);
2526 ok(lstrlenA(result) > 4 && lstrcmpiA(result+lstrlenA(result)-4, ".lnk") == 0,
2527 "%s does not end with .lnk\n", result);
2529 /* preferred target name already exists */
2530 createTestFile(result);
2531 ret = SHGetNewLinkInfoA(linkto, destdir, result2, &mustcopy, 0);
2532 ok(ret == TRUE ||
2533 broken(ret == lstrlenA(result2) + 1), /* NT4 */
2534 "SHGetNewLinkInfoA failed, err=%li\n", GetLastError());
2535 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2536 ok(CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, destdir,
2537 lstrlenA(destdir), result2, lstrlenA(destdir)) == CSTR_EQUAL,
2538 "%s does not start with %s\n", result2, destdir);
2539 ok(lstrlenA(result2) > 4 && lstrcmpiA(result2+lstrlenA(result2)-4, ".lnk") == 0,
2540 "%s does not end with .lnk\n", result2);
2541 ok(lstrcmpiA(result, result2) != 0, "%s and %s are the same\n", result, result2);
2542 DeleteFileA(result);
2545 static void test_unicode(void)
2547 SHFILEOPSTRUCTW shfoW;
2548 int ret;
2549 HANDLE file;
2550 static const WCHAR UNICODE_PATH_TO[] = {'c',':','\\',0x00ae,0x00ae,'\0'};
2551 HWND hwnd;
2553 shfoW.hwnd = NULL;
2554 shfoW.wFunc = FO_DELETE;
2555 shfoW.pFrom = UNICODE_PATH;
2556 shfoW.pTo = NULL;
2557 shfoW.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
2558 shfoW.hNameMappings = NULL;
2559 shfoW.lpszProgressTitle = NULL;
2561 /* Clean up before start test */
2562 DeleteFileW(UNICODE_PATH);
2563 RemoveDirectoryW(UNICODE_PATH);
2565 /* Make sure we are on a system that supports unicode */
2566 SetLastError(0xdeadbeef);
2567 file = CreateFileW(UNICODE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2568 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
2570 skip("Unicode tests skipped on non-unicode system\n");
2571 return;
2573 if (GetLastError()==ERROR_ACCESS_DENIED)
2575 skip("test needs admin rights\n");
2576 return;
2578 CloseHandle(file);
2580 /* Try to delete a file with unicode filename */
2581 ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
2582 ret = SHFileOperationW(&shfoW);
2583 ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
2584 ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
2586 /* Try to trash a file with unicode filename */
2587 createTestFileW(UNICODE_PATH);
2588 shfoW.fFlags |= FOF_ALLOWUNDO;
2589 ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
2590 ret = SHFileOperationW(&shfoW);
2591 ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
2592 ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
2594 /* Try to delete a directory with unicode filename */
2595 ret = SHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
2596 ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
2597 ok(file_existsW(UNICODE_PATH), "The directory is not created\n");
2598 shfoW.fFlags &= ~FOF_ALLOWUNDO;
2599 ret = SHFileOperationW(&shfoW);
2600 ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
2601 ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
2603 /* Try to trash a directory with unicode filename */
2604 ret = SHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
2605 ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
2606 ok(file_existsW(UNICODE_PATH), "The directory was not created\n");
2607 shfoW.fFlags |= FOF_ALLOWUNDO;
2608 ret = SHFileOperationW(&shfoW);
2609 ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
2610 ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
2612 shfoW.hwnd = NULL;
2613 shfoW.wFunc = FO_COPY;
2614 shfoW.pFrom = UNICODE_PATH;
2615 shfoW.pTo = UNICODE_PATH_TO;
2616 shfoW.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
2617 shfoW.hNameMappings = NULL;
2618 shfoW.lpszProgressTitle = NULL;
2620 /* Check last error after a successful file operation. */
2621 createTestFileW(UNICODE_PATH);
2622 ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
2623 SetLastError(0xdeadbeef);
2624 ret = SHFileOperationW(&shfoW);
2625 ok(ret == ERROR_SUCCESS, "File copy failed with %d\n", ret);
2626 ok(!shfoW.fAnyOperationsAborted, "Didn't expect aborted operations\n");
2627 ok(GetLastError() == ERROR_SUCCESS ||
2628 broken(GetLastError() == ERROR_INVALID_HANDLE), /* WinXp, win2k3 */
2629 "Expected ERROR_SUCCESS, got %ld\n", GetLastError());
2630 DeleteFileW(UNICODE_PATH_TO);
2632 /* Check last error after a failed file operation. */
2633 DeleteFileW(UNICODE_PATH);
2634 ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
2635 SetLastError(0xdeadbeef);
2636 ret = SHFileOperationW(&shfoW);
2637 ok(ret != ERROR_SUCCESS, "Unexpected ERROR_SUCCESS\n");
2638 ok(!shfoW.fAnyOperationsAborted, "Didn't expect aborted operations\n");
2639 ok(GetLastError() == ERROR_SUCCESS ||
2640 broken(GetLastError() == ERROR_INVALID_HANDLE), /* WinXp, win2k3 */
2641 "Expected ERROR_SUCCESS, got %ld\n", GetLastError());
2643 /* Check SHCreateDirectoryExW with a Hwnd
2644 * returns ERROR_ALREADY_EXISTS where a directory already exists */
2645 /* Get any window handle */
2646 hwnd = FindWindowA(NULL, NULL);
2647 ok(hwnd != 0, "FindWindowA failed to produce a hwnd\n");
2648 ret = SHCreateDirectoryExW(hwnd, UNICODE_PATH, NULL);
2649 ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
2650 /* Create already-existing directory */
2651 ok(file_existsW(UNICODE_PATH), "The directory was not created\n");
2652 ret = SHCreateDirectoryExW(hwnd, UNICODE_PATH, NULL);
2653 ok(ret == ERROR_ALREADY_EXISTS,
2654 "Expected ERROR_ALREADY_EXISTS, got %d\n", ret);
2655 RemoveDirectoryW(UNICODE_PATH);
2658 static void
2659 test_shlmenu(void) {
2660 HRESULT hres;
2661 HMENU src_menu, dst_menu;
2662 int count;
2663 MENUITEMINFOA item_info;
2664 BOOL bres;
2666 hres = Shell_MergeMenus (0, 0, 0x42, 0x4242, 0x424242, 0);
2667 ok (hres == 0x4242, "expected 0x4242 but got %lx\n", hres);
2668 hres = Shell_MergeMenus ((HMENU)42, 0, 0x42, 0x4242, 0x424242, 0);
2669 ok (hres == 0x4242, "expected 0x4242 but got %lx\n", hres);
2671 src_menu = CreatePopupMenu ();
2672 ok (src_menu != NULL, "CreatePopupMenu() failed, error %ld\n", GetLastError ());
2674 dst_menu = CreatePopupMenu ();
2675 ok (dst_menu != NULL, "CreatePopupMenu() failed, error %ld\n", GetLastError ());
2676 bres = InsertMenuA (src_menu, -1, MF_BYPOSITION | MF_STRING, 10, "item1");
2677 ok (bres, "InsertMenuA failed, error %ld\n", GetLastError());
2678 bres = InsertMenuA (src_menu, -1, MF_BYPOSITION | MF_STRING, 11, "item2");
2679 ok (bres, "InsertMenuA failed, error %ld\n", GetLastError());
2680 hres = Shell_MergeMenus (dst_menu, src_menu, 0, 123, 133, MM_SUBMENUSHAVEIDS);
2681 ok (hres == 134, "got %ld\n", hres);
2682 count = GetMenuItemCount (dst_menu);
2683 ok (count == 1, "got %d\n", count);
2684 memset (&item_info, 0, sizeof(item_info));
2685 item_info.cbSize = sizeof(item_info);
2686 item_info.fMask = MIIM_ID;
2687 bres = GetMenuItemInfoA (dst_menu, 0, TRUE, &item_info);
2688 ok (bres, "GetMenuItemInfoA failed, error %ld\n", GetLastError ());
2689 ok (item_info.wID == 133, "got %d\n", item_info.wID);
2690 DestroyMenu (dst_menu);
2692 /* integer overflow: Shell_MergeMenus() return value is wrong, but items are still added */
2693 dst_menu = CreatePopupMenu ();
2694 ok (dst_menu != NULL, "CreatePopupMenu() failed, error %ld\n", GetLastError ());
2695 hres = Shell_MergeMenus (dst_menu, src_menu, 0, -1, 133, MM_SUBMENUSHAVEIDS);
2696 ok (hres == -1, "got %ld\n", hres);
2697 count = GetMenuItemCount (dst_menu);
2698 ok (count == 2, "got %d\n", count);
2699 DestroyMenu (dst_menu);
2701 DestroyMenu (src_menu);
2704 /* Check for old shell32 (4.0.x) */
2705 static BOOL is_old_shell32(void)
2707 SHFILEOPSTRUCTA shfo;
2708 CHAR from[5*MAX_PATH];
2709 CHAR to[5*MAX_PATH];
2710 DWORD retval;
2712 shfo.hwnd = NULL;
2713 shfo.wFunc = FO_COPY;
2714 shfo.pFrom = from;
2715 shfo.pTo = to;
2716 /* FOF_NOCONFIRMMKDIR is needed for old shell32 */
2717 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_MULTIDESTFILES | FOF_NOCONFIRMMKDIR;
2718 shfo.hNameMappings = NULL;
2719 shfo.lpszProgressTitle = NULL;
2721 set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0");
2722 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
2723 retval = SHFileOperationA(&shfo);
2725 /* Delete extra files on old shell32 and Vista+*/
2726 DeleteFileA("test6.txt\\test1.txt");
2727 /* Delete extra files on old shell32 */
2728 DeleteFileA("test6.txt\\test2.txt");
2729 DeleteFileA("test6.txt\\test3.txt");
2730 /* Delete extra directory on old shell32 and Vista+ */
2731 RemoveDirectoryA("test6.txt");
2732 /* Delete extra files/directories on Vista+*/
2733 DeleteFileA("test7.txt\\test2.txt");
2734 RemoveDirectoryA("test7.txt");
2736 if (retval == ERROR_SUCCESS)
2737 return TRUE;
2739 return FALSE;
2742 static void test_file_operation(void)
2744 IFileOperation *operation;
2745 IUnknown *unk;
2746 HRESULT hr;
2748 hr = CoCreateInstance(&CLSID_FileOperation, NULL, CLSCTX_INPROC_SERVER,
2749 &IID_IFileOperation, (void **)&operation);
2750 ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /* before vista */,
2751 "Got hr %#lx.\n", hr);
2752 if (hr == REGDB_E_CLASSNOTREG)
2754 win_skip("IFileOperation isn't supported.\n");
2755 return;
2758 hr = IFileOperation_QueryInterface(operation, &IID_IUnknown, (void **)&unk);
2759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2760 IUnknown_Release(unk);
2762 IFileOperation_Release(operation);
2765 START_TEST(shlfileop)
2767 clean_after_shfo_tests();
2769 init_shfo_tests();
2770 old_shell32 = is_old_shell32();
2771 if (old_shell32)
2772 win_skip("Need to cater for old shell32 (4.0.x) on Win95\n");
2773 clean_after_shfo_tests();
2775 init_shfo_tests();
2776 test_get_file_info();
2777 test_get_file_info_iconlist();
2778 clean_after_shfo_tests();
2780 init_shfo_tests();
2781 test_delete();
2782 clean_after_shfo_tests();
2784 init_shfo_tests();
2785 test_rename();
2786 clean_after_shfo_tests();
2788 init_shfo_tests();
2789 test_copy();
2790 clean_after_shfo_tests();
2792 init_shfo_tests();
2793 test_move();
2794 clean_after_shfo_tests();
2796 test_sh_create_dir();
2797 clean_after_shfo_tests();
2799 init_shfo_tests();
2800 test_sh_path_prepare();
2801 clean_after_shfo_tests();
2803 init_shfo_tests();
2804 test_sh_new_link_info();
2805 clean_after_shfo_tests();
2807 test_unicode();
2809 test_shlmenu();
2811 CoInitialize(NULL);
2813 test_file_operation();
2815 CoUninitialize();