wined3d: Implement multisample resolve for typed resources.
[wine.git] / dlls / shell32 / tests / shlfileop.c
blobdd933f6d1f16262d2376ad305ca56af6a7b5c394
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 #define WINE_NOWINSOCK
26 #include <windows.h>
27 #include "shellapi.h"
28 #include "shlobj.h"
29 #include "commoncontrols.h"
31 #include "wine/test.h"
33 #ifndef FOF_NORECURSION
34 #define FOF_NORECURSION 0x1000
35 #endif
37 /* Error codes could be pre-Win32 */
38 #define DE_SAMEFILE 0x71
39 #define DE_MANYSRC1DEST 0x72
40 #define DE_DIFFDIR 0x73
41 #define DE_OPCANCELLED 0x75
42 #define DE_DESTSUBTREE 0x76
43 #define DE_INVALIDFILES 0x7C
44 #define DE_DESTSAMETREE 0x7D
45 #define DE_FLDDESTISFILE 0x7E
46 #define DE_FILEDESTISFLD 0x80
47 #define expect_retval(ret, ret_prewin32)\
48 ok(retval == ret ||\
49 broken(retval == ret_prewin32),\
50 "Expected %d, got %d\n", ret, retval)
52 static BOOL old_shell32 = FALSE;
54 static CHAR CURR_DIR[MAX_PATH];
55 static const WCHAR UNICODE_PATH[] = {'c',':','\\',0x00ae,'\0','\0'};
56 /* "c:\®" can be used in all codepages */
57 /* Double-null termination needed for pFrom field of SHFILEOPSTRUCT */
59 static HMODULE hshell32;
60 static int (WINAPI *pSHCreateDirectoryExA)(HWND, LPCSTR, LPSECURITY_ATTRIBUTES);
61 static int (WINAPI *pSHCreateDirectoryExW)(HWND, LPCWSTR, LPSECURITY_ATTRIBUTES);
62 static int (WINAPI *pSHFileOperationW)(LPSHFILEOPSTRUCTW);
63 static DWORD_PTR (WINAPI *pSHGetFileInfoW)(LPCWSTR, DWORD , SHFILEINFOW*, UINT, UINT);
64 static int (WINAPI *pSHPathPrepareForWriteA)(HWND, IUnknown*, LPCSTR, DWORD);
65 static int (WINAPI *pSHPathPrepareForWriteW)(HWND, IUnknown*, LPCWSTR, DWORD);
67 static void InitFunctionPointers(void)
69 hshell32 = GetModuleHandleA("shell32.dll");
70 pSHCreateDirectoryExA = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExA");
71 pSHCreateDirectoryExW = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExW");
72 pSHFileOperationW = (void*)GetProcAddress(hshell32, "SHFileOperationW");
73 pSHGetFileInfoW = (void*)GetProcAddress(hshell32, "SHGetFileInfoW");
74 pSHPathPrepareForWriteA = (void*)GetProcAddress(hshell32, "SHPathPrepareForWriteA");
75 pSHPathPrepareForWriteW = (void*)GetProcAddress(hshell32, "SHPathPrepareForWriteW");
78 /* creates a file with the specified name for tests */
79 static void createTestFile(const CHAR *name)
81 HANDLE file;
82 DWORD written;
84 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
85 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
86 WriteFile(file, name, strlen(name), &written, NULL);
87 WriteFile(file, "\n", strlen("\n"), &written, NULL);
88 CloseHandle(file);
91 static void createTestFileW(const WCHAR *name)
93 HANDLE file;
95 file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
96 ok(file != INVALID_HANDLE_VALUE, "Failure to open file\n");
97 CloseHandle(file);
100 static BOOL file_exists(const CHAR *name)
102 return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
105 static BOOL dir_exists(const CHAR *name)
107 DWORD attr;
108 BOOL dir;
110 attr = GetFileAttributesA(name);
111 dir = ((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
113 return ((attr != INVALID_FILE_ATTRIBUTES) && dir);
116 static BOOL file_existsW(LPCWSTR name)
118 return GetFileAttributesW(name) != INVALID_FILE_ATTRIBUTES;
121 static BOOL file_has_content(const CHAR *name, const CHAR *content)
123 CHAR buf[MAX_PATH];
124 HANDLE file;
125 DWORD read;
127 file = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
128 if (file == INVALID_HANDLE_VALUE)
129 return FALSE;
130 ReadFile(file, buf, MAX_PATH - 1, &read, NULL);
131 buf[read] = 0;
132 CloseHandle(file);
133 return strcmp(buf, content)==0;
136 /* initializes the tests */
137 static void init_shfo_tests(void)
139 int len;
141 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
142 len = lstrlenA(CURR_DIR);
144 if(len && (CURR_DIR[len-1] == '\\'))
145 CURR_DIR[len-1] = 0;
147 createTestFile("test1.txt");
148 createTestFile("test2.txt");
149 createTestFile("test3.txt");
150 createTestFile("test_5.txt");
151 CreateDirectoryA("test4.txt", NULL);
152 CreateDirectoryA("testdir2", NULL);
153 CreateDirectoryA("testdir2\\nested", NULL);
154 createTestFile("testdir2\\one.txt");
155 createTestFile("testdir2\\nested\\two.txt");
158 /* cleans after tests */
159 static void clean_after_shfo_tests(void)
161 DeleteFileA("test1.txt");
162 DeleteFileA("test2.txt");
163 DeleteFileA("test3.txt");
164 DeleteFileA("test_5.txt");
165 DeleteFileA("one.txt");
166 DeleteFileA("test4.txt\\test1.txt");
167 DeleteFileA("test4.txt\\test2.txt");
168 DeleteFileA("test4.txt\\test3.txt");
169 DeleteFileA("test4.txt\\one.txt");
170 DeleteFileA("test4.txt\\nested\\two.txt");
171 RemoveDirectoryA("test4.txt\\nested");
172 RemoveDirectoryA("test4.txt");
173 DeleteFileA("testdir2\\one.txt");
174 DeleteFileA("testdir2\\test1.txt");
175 DeleteFileA("testdir2\\test2.txt");
176 DeleteFileA("testdir2\\test3.txt");
177 DeleteFileA("testdir2\\test4.txt\\test1.txt");
178 DeleteFileA("testdir2\\nested\\two.txt");
179 RemoveDirectoryA("testdir2\\test4.txt");
180 RemoveDirectoryA("testdir2\\nested");
181 RemoveDirectoryA("testdir2");
182 RemoveDirectoryA("c:\\testdir3");
183 DeleteFileA("nonexistent\\notreal\\test2.txt");
184 RemoveDirectoryA("nonexistent\\notreal");
185 RemoveDirectoryA("nonexistent");
189 static void test_get_file_info(void)
191 DWORD rc, rc2;
192 SHFILEINFOA shfi, shfi2;
193 SHFILEINFOW shfiw;
194 char notepad[MAX_PATH];
196 /* Test whether fields of SHFILEINFOA are always cleared */
197 memset(&shfi, 0xcf, sizeof(shfi));
198 rc=SHGetFileInfoA("", 0, &shfi, sizeof(shfi), 0);
199 ok(rc == 1, "SHGetFileInfoA('' | 0) should return 1, got 0x%x\n", rc);
200 todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA('' | 0) did not clear hIcon\n");
201 todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szDisplayName[0]\n");
202 todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA('' | 0) did not clear szTypeName[0]\n");
203 ok(shfi.iIcon == 0xcfcfcfcf ||
204 broken(shfi.iIcon != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
205 "SHGetFileInfoA('' | 0) should not clear iIcon\n");
206 ok(shfi.dwAttributes == 0xcfcfcfcf ||
207 broken(shfi.dwAttributes != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
208 "SHGetFileInfoA('' | 0) should not clear dwAttributes\n");
210 if (pSHGetFileInfoW)
212 HANDLE unset_icon;
213 /* Test whether fields of SHFILEINFOW are always cleared */
214 memset(&shfiw, 0xcf, sizeof(shfiw));
215 memset(&unset_icon, 0xcf, sizeof(unset_icon));
216 rc=pSHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0);
217 ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n");
218 ok(shfiw.hIcon == unset_icon, "SHGetFileInfoW(NULL | 0) should not clear hIcon\n");
219 ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n");
220 ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n");
221 ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n");
222 ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear dwAttributes\n");
224 else
225 win_skip("SHGetFileInfoW is not available\n");
228 /* Test some flag combinations that MSDN claims are not allowed,
229 * but which work anyway
231 memset(&shfi, 0xcf, sizeof(shfi));
232 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
233 &shfi, sizeof(shfi),
234 SHGFI_ATTRIBUTES | SHGFI_USEFILEATTRIBUTES);
235 ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) should return 1, got 0x%x\n", rc);
236 if (rc)
237 ok(shfi.dwAttributes != 0xcfcfcfcf, "dwFileAttributes is not set\n");
238 todo_wine ok(shfi.hIcon == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear hIcon\n");
239 todo_wine ok(shfi.szDisplayName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szDisplayName[0]\n");
240 todo_wine ok(shfi.szTypeName[0] == 0, "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) did not clear szTypeName[0]\n");
241 ok(shfi.iIcon == 0xcfcfcfcf ||
242 broken(shfi.iIcon != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
243 "SHGetFileInfoA(c:\\nonexistent | SHGFI_ATTRIBUTES) should not clear iIcon\n");
245 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
246 &shfi, sizeof(shfi),
247 SHGFI_EXETYPE | SHGFI_USEFILEATTRIBUTES);
248 todo_wine ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent | SHGFI_EXETYPE) should return 1, got 0x%x\n", rc);
250 /* Test SHGFI_USEFILEATTRIBUTES support */
251 strcpy(shfi.szDisplayName, "dummy");
252 shfi.iIcon=0xdeadbeef;
253 rc=SHGetFileInfoA("c:\\nonexistent", FILE_ATTRIBUTE_DIRECTORY,
254 &shfi, sizeof(shfi),
255 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
256 ok(rc == 1, "SHGetFileInfoA(c:\\nonexistent) should return 1, got 0x%x\n", rc);
257 if (rc)
259 ok(strcmp(shfi.szDisplayName, "dummy"), "SHGetFileInfoA(c:\\nonexistent) displayname is not set\n");
260 ok(shfi.iIcon != 0xdeadbeef, "SHGetFileInfoA(c:\\nonexistent) iIcon is not set\n");
263 /* Wine does not have a default icon for text files, and Windows 98 fails
264 * if we give it an empty executable. So use notepad.exe as the test
266 if (SearchPathA(NULL, "notepad.exe", NULL, sizeof(notepad), notepad, NULL))
268 strcpy(shfi.szDisplayName, "dummy");
269 shfi.iIcon=0xdeadbeef;
270 rc=SHGetFileInfoA(notepad, GetFileAttributesA(notepad),
271 &shfi, sizeof(shfi),
272 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
273 ok(rc == 1, "SHGetFileInfoA(%s, SHGFI_USEFILEATTRIBUTES) should return 1, got 0x%x\n", notepad, rc);
274 strcpy(shfi2.szDisplayName, "dummy");
275 shfi2.iIcon=0xdeadbeef;
276 rc2=SHGetFileInfoA(notepad, 0,
277 &shfi2, sizeof(shfi2),
278 SHGFI_ICONLOCATION);
279 ok(rc2 == 1, "SHGetFileInfoA(%s) failed %x\n", notepad, rc2);
280 if (rc && rc2)
282 ok(lstrcmpiA(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
283 ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
287 /* with a directory now */
288 strcpy(shfi.szDisplayName, "dummy");
289 shfi.iIcon=0xdeadbeef;
290 rc=SHGetFileInfoA("test4.txt", GetFileAttributesA("test4.txt"),
291 &shfi, sizeof(shfi),
292 SHGFI_ICONLOCATION | SHGFI_USEFILEATTRIBUTES);
293 ok(rc == 1, "SHGetFileInfoA(test4.txt/, SHGFI_USEFILEATTRIBUTES) should return 1, got 0x%x\n", rc);
294 strcpy(shfi2.szDisplayName, "dummy");
295 shfi2.iIcon=0xdeadbeef;
296 rc2=SHGetFileInfoA("test4.txt", 0,
297 &shfi2, sizeof(shfi2),
298 SHGFI_ICONLOCATION);
299 ok(rc2 == 1, "SHGetFileInfoA(test4.txt/) should return 1, got 0x%x\n", rc2);
300 if (rc && rc2)
302 ok(lstrcmpiA(shfi2.szDisplayName, shfi.szDisplayName) == 0, "wrong display name %s != %s\n", shfi.szDisplayName, shfi2.szDisplayName);
303 ok(shfi2.iIcon == shfi.iIcon, "wrong icon index %d != %d\n", shfi.iIcon, shfi2.iIcon);
305 /* with drive root directory */
306 strcpy(shfi.szDisplayName, "dummy");
307 strcpy(shfi.szTypeName, "dummy");
308 shfi.hIcon=(HICON) 0xdeadbeef;
309 shfi.iIcon=0xdeadbeef;
310 shfi.dwAttributes=0xdeadbeef;
311 rc=SHGetFileInfoA("c:\\", 0, &shfi, sizeof(shfi),
312 SHGFI_TYPENAME | SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_SMALLICON);
313 ok(rc == 1, "SHGetFileInfoA(c:\\) should return 1, got 0x%x\n", rc);
314 ok(strcmp(shfi.szDisplayName, "dummy") != 0, "display name was expected to change\n");
315 ok(strcmp(shfi.szTypeName, "dummy") != 0, "type name was expected to change\n");
316 ok(shfi.hIcon != (HICON) 0xdeadbeef, "hIcon was expected to change\n");
317 ok(shfi.iIcon != 0xdeadbeef, "iIcon was expected to change\n");
320 static void check_icon_size( HICON icon, DWORD flags )
322 ICONINFO info;
323 BITMAP bm;
324 SIZE list_size, metrics_size;
325 IImageList *list;
327 GetIconInfo( icon, &info );
328 GetObjectW( info.hbmColor, sizeof(bm), &bm );
330 SHGetImageList( (flags & SHGFI_SMALLICON) ? SHIL_SMALL : SHIL_LARGE,
331 &IID_IImageList, (void **)&list );
332 IImageList_GetIconSize( list, &list_size.cx, &list_size.cy );
333 IImageList_Release( list );
335 metrics_size.cx = GetSystemMetrics( (flags & SHGFI_SMALLICON) ? SM_CXSMICON : SM_CXICON );
336 metrics_size.cy = GetSystemMetrics( (flags & SHGFI_SMALLICON) ? SM_CYSMICON : SM_CYICON );
339 if (flags & SHGFI_SHELLICONSIZE)
341 ok( bm.bmWidth == list_size.cx, "got %d expected %d\n", bm.bmWidth, list_size.cx );
342 ok( bm.bmHeight == list_size.cy, "got %d expected %d\n", bm.bmHeight, list_size.cy );
344 else
346 ok( bm.bmWidth == metrics_size.cx, "got %d expected %d\n", bm.bmWidth, metrics_size.cx );
347 ok( bm.bmHeight == metrics_size.cy, "got %d expected %d\n", bm.bmHeight, metrics_size.cy );
351 static void test_get_file_info_iconlist(void)
353 /* Test retrieving a handle to the system image list, and
354 * what that returns for hIcon
356 HRESULT hr;
357 HIMAGELIST hSysImageList;
358 LPITEMIDLIST pidList;
359 SHFILEINFOA shInfoa;
360 SHFILEINFOW shInfow;
361 IImageList *small_list, *large_list;
362 ULONG start_refs, refs;
364 hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidList);
365 if (FAILED(hr)) {
366 skip("can't get desktop pidl\n");
367 return;
370 SHGetImageList( SHIL_LARGE, &IID_IImageList, (void **)&large_list );
371 SHGetImageList( SHIL_SMALL, &IID_IImageList, (void **)&small_list );
373 start_refs = IImageList_AddRef( small_list );
374 IImageList_Release( small_list );
376 memset(&shInfoa, 0xcf, sizeof(shInfoa));
377 hSysImageList = (HIMAGELIST) SHGetFileInfoA((const char *)pidList, 0,
378 &shInfoa, sizeof(shInfoa),
379 SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
380 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
381 refs = IImageList_AddRef( small_list );
382 IImageList_Release( small_list );
383 ok( refs == start_refs + 1 ||
384 broken( refs == start_refs ), /* XP and 2003 */
385 "got %d, start_refs %d\n", refs, start_refs );
386 todo_wine ok(shInfoa.hIcon == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
387 todo_wine ok(shInfoa.szTypeName[0] == 0, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
388 ok(shInfoa.iIcon != 0xcfcfcfcf, "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
389 ok(shInfoa.dwAttributes == 0xcfcfcfcf ||
390 shInfoa.dwAttributes == 0 || /* Vista */
391 broken(shInfoa.dwAttributes != 0xcfcfcfcf), /* NT4 doesn't clear but sets this field */
392 "SHGetFileInfoA(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL), unexpected dwAttributes\n");
393 /* Don't release hSysImageList here (and in similar places below) because of the broken reference behaviour of XP and 2003. */
395 if (!pSHGetFileInfoW)
397 win_skip("SHGetFileInfoW is not available\n");
398 ILFree(pidList);
399 return;
402 memset(&shInfow, 0xcf, sizeof(shInfow));
403 hSysImageList = (HIMAGELIST) pSHGetFileInfoW((const WCHAR *)pidList, 0,
404 &shInfow, sizeof(shInfow),
405 SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_PIDL);
406 if (!hSysImageList)
408 win_skip("SHGetFileInfoW is not implemented\n");
409 return;
411 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
412 todo_wine ok(shInfow.hIcon == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear hIcon\n");
413 ok(shInfow.szTypeName[0] == 0, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) did not clear szTypeName[0]\n");
414 ok(shInfow.iIcon != 0xcfcfcfcf, "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) should set iIcon\n");
415 ok(shInfow.dwAttributes == 0xcfcfcfcf ||
416 shInfoa.dwAttributes == 0, /* Vista */
417 "SHGetFileInfoW(CSIDL_DESKTOP, SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_PIDL) unexpected dwAttributes\n");
419 /* Various suposidly invalid flag testing */
420 memset(&shInfow, 0xcf, sizeof(shInfow));
421 hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
422 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
423 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
424 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
425 ok(shInfow.dwAttributes==0xcfcfcfcf ||
426 shInfoa.dwAttributes==0, /* Vista */
427 "unexpected dwAttributes\n");
429 memset(&shInfow, 0xcf, sizeof(shInfow));
430 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
431 SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
432 ok(hr != 0, " SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
433 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
434 check_icon_size( shInfow.hIcon, SHGFI_SMALLICON );
435 DestroyIcon(shInfow.hIcon);
436 todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
438 memset(&shInfow, 0xcf, sizeof(shInfow));
439 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
440 SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
441 ok(hr != 0, "SHGFI_ICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON Failed\n");
442 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
443 check_icon_size( shInfow.hIcon, SHGFI_LARGEICON );
444 DestroyIcon( shInfow.hIcon );
445 todo_wine ok(shInfow.dwAttributes==0,"dwAttributes not set\n");
447 memset(&shInfow, 0xcf, sizeof(shInfow));
448 hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
449 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_LARGEICON);
450 ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, small_list);
451 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
452 ok(shInfow.dwAttributes==0xcfcfcfcf ||
453 shInfoa.dwAttributes==0, /* Vista */
454 "unexpected dwAttributes\n");
456 memset(&shInfow, 0xcf, sizeof(shInfow));
457 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
458 SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
459 ok(hr != 0, "SHGFI_OPENICON|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
460 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
461 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
463 memset(&shInfow, 0xcf, sizeof(shInfow));
464 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
465 SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
466 ok(hr != 0, "SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
467 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
468 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
470 memset(&shInfow, 0xcf, sizeof(shInfow));
471 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
472 SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON);
473 ok(hr != 0, "SHGFI_SHELLICONSIZE|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON Failed\n");
474 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
475 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
477 memset(&shInfow, 0xcf, sizeof(shInfow));
478 hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
479 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
480 SHGFI_ATTRIBUTES);
481 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
482 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
483 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
485 memset(&shInfow, 0xcf, sizeof(shInfow));
486 hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
487 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|
488 SHGFI_EXETYPE);
489 todo_wine ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
490 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
491 ok(shInfow.dwAttributes==0xcfcfcfcf ||
492 shInfoa.dwAttributes==0, /* Vista */
493 "unexpected dwAttributes\n");
495 memset(&shInfow, 0xcf, sizeof(shInfow));
496 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
497 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE);
498 todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_EXETYPE Failed\n");
499 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
500 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
502 memset(&shInfow, 0xcf, sizeof(shInfow));
503 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
504 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES);
505 ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_ATTRIBUTES Failed\n");
506 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
507 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
509 memset(&shInfow, 0xcf, sizeof(shInfow));
510 hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
511 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|
512 SHGFI_ATTRIBUTES);
513 ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, large_list);
514 ok(hr != 0, "SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
515 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
516 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
518 memset(&shInfow, 0xcf, sizeof(shInfow));
519 hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
520 SHGFI_SYSICONINDEX|SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
521 todo_wine ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, large_list);
522 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
523 ok(shInfow.dwAttributes==0xcfcfcfcf ||
524 shInfoa.dwAttributes==0, /* Vista */
525 "unexpected dwAttributes\n");
527 memset(&shInfow, 0xcf, sizeof(shInfow));
528 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
529 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE);
530 todo_wine ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_EXETYPE Failed\n");
531 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
532 ok(shInfow.dwAttributes==0xcfcfcfcf,"dwAttributes modified\n");
534 memset(&shInfow, 0xcf, sizeof(shInfow));
535 hr = pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
536 SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES);
537 ok(hr != 0, "SHGFI_USEFILEATTRIBUTES|SHGFI_PIDL|SHGFI_ATTRIBUTES Failed\n");
538 todo_wine ok(shInfow.iIcon==0xcfcfcfcf, "Icon Index Modified\n");
539 ok(shInfow.dwAttributes!=0xcfcfcfcf,"dwAttributes not set\n");
541 memset(&shInfow, 0xcf, sizeof(shInfow));
542 hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
543 SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_SHELLICONSIZE|SHGFI_ICON);
544 ok(hSysImageList == (HIMAGELIST)small_list, "got %p expect %p\n", hSysImageList, small_list);
545 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
546 check_icon_size( shInfow.hIcon, SHGFI_SMALLICON | SHGFI_SHELLICONSIZE );
547 DestroyIcon( shInfow.hIcon );
549 memset(&shInfow, 0xcf, sizeof(shInfow));
550 hSysImageList = (HIMAGELIST)pSHGetFileInfoW((const WCHAR *)pidList, 0, &shInfow, sizeof(shInfow),
551 SHGFI_SYSICONINDEX|SHGFI_PIDL|SHGFI_SHELLICONSIZE|SHGFI_ICON);
552 ok(hSysImageList == (HIMAGELIST)large_list, "got %p expect %p\n", hSysImageList, small_list);
553 ok(shInfow.iIcon!=0xcfcfcfcf, "Icon Index Missing\n");
554 check_icon_size( shInfow.hIcon, SHGFI_LARGEICON | SHGFI_SHELLICONSIZE );
555 DestroyIcon( shInfow.hIcon );
557 ILFree(pidList);
558 IImageList_Release( small_list );
559 IImageList_Release( large_list );
564 puts into the specified buffer file names with current directory.
565 files - string with file names, separated by null characters. Ends on a double
566 null characters
568 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
570 buf[0] = 0;
571 while (files[0])
573 strcpy(buf, CURR_DIR);
574 buf += strlen(buf);
575 buf[0] = '\\';
576 buf++;
577 strcpy(buf, files);
578 buf += strlen(buf) + 1;
579 files += strlen(files) + 1;
581 buf[0] = 0;
585 /* tests the FO_DELETE action */
586 static void test_delete(void)
588 SHFILEOPSTRUCTA shfo;
589 DWORD ret;
590 CHAR buf[sizeof(CURR_DIR)+sizeof("/test?.txt")+1];
592 sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
593 buf[strlen(buf) + 1] = '\0';
595 shfo.hwnd = NULL;
596 shfo.wFunc = FO_DELETE;
597 shfo.pFrom = buf;
598 shfo.pTo = NULL;
599 shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
600 shfo.hNameMappings = NULL;
601 shfo.lpszProgressTitle = NULL;
603 ok(!SHFileOperationA(&shfo), "Deletion was not successful\n");
604 ok(dir_exists("test4.txt"), "Directory should not have been removed\n");
605 ok(!file_exists("test1.txt"), "File should have been removed\n");
606 ok(!file_exists("test2.txt"), "File should have been removed\n");
607 ok(!file_exists("test3.txt"), "File should have been removed\n");
609 ret = SHFileOperationA(&shfo);
610 ok(ret == ERROR_SUCCESS, "Directory exists, but is not removed, ret=%d\n", ret);
611 ok(dir_exists("test4.txt"), "Directory should not have been removed\n");
613 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
615 ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
616 ok(!dir_exists("test4.txt"), "Directory should have been removed\n");
618 ret = SHFileOperationA(&shfo);
619 ok(!ret, "The requested file does not exist, ret=%d\n", ret);
621 init_shfo_tests();
622 sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
623 buf[strlen(buf) + 1] = '\0';
624 ok(MoveFileA("test1.txt", "test4.txt\\test1.txt"), "Filling the subdirectory failed\n");
625 ok(!SHFileOperationA(&shfo), "Directory is not removed\n");
626 ok(!dir_exists("test4.txt"), "Directory is not removed\n");
628 init_shfo_tests();
629 shfo.pFrom = "test1.txt\0test4.txt\0";
630 ok(!SHFileOperationA(&shfo), "Directory and a file are not removed\n");
631 ok(!file_exists("test1.txt"), "The file should have been removed\n");
632 ok(!dir_exists("test4.txt"), "Directory should have been removed\n");
633 ok(file_exists("test2.txt"), "This file should not have been removed\n");
635 /* FOF_FILESONLY does not delete a dir matching a wildcard */
636 init_shfo_tests();
637 shfo.fFlags |= FOF_FILESONLY;
638 shfo.pFrom = "*.txt\0";
639 ok(!SHFileOperationA(&shfo), "Failed to delete files\n");
640 ok(!file_exists("test1.txt"), "test1.txt should have been removed\n");
641 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
642 ok(dir_exists("test4.txt"), "test4.txt should not have been removed\n");
644 /* FOF_FILESONLY only deletes a dir if explicitly specified */
645 init_shfo_tests();
646 shfo.pFrom = "test_?.txt\0test4.txt\0";
647 ok(!SHFileOperationA(&shfo), "Failed to delete files and directory\n");
648 ok(!dir_exists("test4.txt") ||
649 broken(dir_exists("test4.txt")), /* NT4 */
650 "test4.txt should have been removed\n");
651 ok(!file_exists("test_5.txt"), "test_5.txt should have been removed\n");
652 ok(file_exists("test1.txt"), "test1.txt should not have been removed\n");
654 /* try to delete an invalid filename */
655 if (0) {
656 /* this crashes on win9x */
657 init_shfo_tests();
658 shfo.pFrom = "\0";
659 shfo.fFlags &= ~FOF_FILESONLY;
660 shfo.fAnyOperationsAborted = FALSE;
661 ret = SHFileOperationA(&shfo);
662 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", ret);
663 ok(!shfo.fAnyOperationsAborted, "Expected no aborted operations\n");
664 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
667 /* try an invalid function */
668 init_shfo_tests();
669 shfo.pFrom = "test1.txt\0";
670 shfo.wFunc = 0;
671 ret = SHFileOperationA(&shfo);
672 ok(ret == ERROR_INVALID_PARAMETER ||
673 broken(ret == ERROR_SUCCESS), /* Win9x, NT4 */
674 "Expected ERROR_INVALID_PARAMETER, got %d\n", ret);
675 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
677 /* try an invalid list, only one null terminator */
678 if (0) {
679 /* this crashes on win9x */
680 init_shfo_tests();
681 shfo.pFrom = "";
682 shfo.wFunc = FO_DELETE;
683 ret = SHFileOperationA(&shfo);
684 ok(ret == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", ret);
685 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
688 /* delete a nonexistent file */
689 shfo.pFrom = "nonexistent.txt\0";
690 shfo.wFunc = FO_DELETE;
691 ret = SHFileOperationA(&shfo);
692 ok(ret == 1026 ||
693 ret == ERROR_FILE_NOT_FOUND || /* Vista */
694 broken(ret == ERROR_SUCCESS), /* NT4 */
695 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", ret);
697 /* delete a dir, and then a file inside the dir, same as
698 * deleting a nonexistent file
700 if (ret != ERROR_FILE_NOT_FOUND)
702 /* Vista would throw up a dialog box that we can't suppress */
703 init_shfo_tests();
704 shfo.pFrom = "testdir2\0testdir2\\one.txt\0";
705 ret = SHFileOperationA(&shfo);
706 ok(ret == ERROR_PATH_NOT_FOUND ||
707 broken(ret == ERROR_SUCCESS), /* NT4 */
708 "Expected ERROR_PATH_NOT_FOUND, got %d\n", ret);
709 ok(!dir_exists("testdir2"), "Expected testdir2 to not exist\n");
710 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
712 else
713 skip("Test would show a dialog box\n");
715 /* delete an existent file and a nonexistent file */
716 init_shfo_tests();
717 shfo.pFrom = "test1.txt\0nonexistent.txt\0test2.txt\0";
718 shfo.wFunc = FO_DELETE;
719 ret = SHFileOperationA(&shfo);
720 ok(ret == 1026 ||
721 ret == ERROR_FILE_NOT_FOUND || /* Vista */
722 broken(ret == ERROR_SUCCESS), /* NT4 */
723 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", ret);
724 todo_wine
725 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
726 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
728 /* delete a nonexistent file in an existent dir or a nonexistent dir */
729 init_shfo_tests();
730 shfo.pFrom = "testdir2\\nonexistent.txt\0";
731 ret = SHFileOperationA(&shfo);
732 ok(ret == ERROR_FILE_NOT_FOUND || /* Vista */
733 broken(ret == 0x402) || /* XP */
734 broken(ret == ERROR_SUCCESS), /* NT4 */
735 "Expected 0x402 or ERROR_FILE_NOT_FOUND, got %x\n", ret);
736 shfo.pFrom = "nonexistent\\one.txt\0";
737 ret = SHFileOperationA(&shfo);
738 ok(ret == DE_INVALIDFILES || /* Vista or later */
739 broken(ret == 0x402), /* XP */
740 "Expected 0x402 or DE_INVALIDFILES, got %x\n", ret);
742 /* try the FOF_NORECURSION flag, continues deleting subdirs */
743 init_shfo_tests();
744 shfo.pFrom = "testdir2\0";
745 shfo.fFlags |= FOF_NORECURSION;
746 ret = SHFileOperationA(&shfo);
747 ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
748 ok(!file_exists("testdir2\\one.txt"), "Expected testdir2\\one.txt to not exist\n");
749 ok(!dir_exists("testdir2\\nested"), "Expected testdir2\\nested to not exist\n");
752 /* tests the FO_RENAME action */
753 static void test_rename(void)
755 SHFILEOPSTRUCTA shfo, shfo2;
756 CHAR from[5*MAX_PATH];
757 CHAR to[5*MAX_PATH];
758 DWORD retval;
760 shfo.hwnd = NULL;
761 shfo.wFunc = FO_RENAME;
762 shfo.pFrom = from;
763 shfo.pTo = to;
764 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
765 shfo.hNameMappings = NULL;
766 shfo.lpszProgressTitle = NULL;
768 set_curr_dir_path(from, "test1.txt\0");
769 set_curr_dir_path(to, "test4.txt\0");
770 retval = SHFileOperationA(&shfo);
771 ok(retval == ERROR_ALREADY_EXISTS ||
772 retval == DE_FILEDESTISFLD || /* Vista */
773 broken(retval == ERROR_INVALID_NAME), /* Win9x, NT4 */
774 "Expected ERROR_ALREADY_EXISTS or DE_FILEDESTISFLD, got %d\n", retval);
775 ok(file_exists("test1.txt"), "The file is renamed\n");
777 set_curr_dir_path(from, "test3.txt\0");
778 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
779 retval = SHFileOperationA(&shfo);
780 if (retval == DE_DIFFDIR)
782 /* Vista and W2K8 (broken or new behavior ?) */
783 ok(!file_exists("test4.txt\\test1.txt"), "The file is renamed\n");
785 else
787 ok(retval == ERROR_SUCCESS, "File is renamed moving to other directory\n");
788 ok(file_exists("test4.txt\\test1.txt"), "The file is not renamed\n");
791 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
792 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
793 retval = SHFileOperationA(&shfo);
794 ok(retval == ERROR_GEN_FAILURE ||
795 retval == DE_MANYSRC1DEST || /* Vista */
796 broken(retval == ERROR_SUCCESS), /* Win9x */
797 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST , got %d\n", retval);
798 ok(file_exists("test1.txt"), "The file is renamed - many files are specified\n");
800 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
801 shfo2.fFlags |= FOF_MULTIDESTFILES;
803 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
804 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
805 retval = SHFileOperationA(&shfo2);
806 ok(retval == ERROR_GEN_FAILURE ||
807 retval == DE_MANYSRC1DEST || /* Vista */
808 broken(retval == ERROR_SUCCESS), /* Win9x */
809 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST files, got %d\n", retval);
810 ok(file_exists("test1.txt"), "The file is not renamed - many files are specified\n");
812 set_curr_dir_path(from, "test1.txt\0");
813 set_curr_dir_path(to, "test6.txt\0");
814 retval = SHFileOperationA(&shfo);
815 ok(retval == ERROR_SUCCESS, "Rename file failed, retval = %d\n", retval);
816 ok(!file_exists("test1.txt"), "The file is not renamed\n");
817 ok(file_exists("test6.txt"), "The file is not renamed\n");
819 set_curr_dir_path(from, "test6.txt\0");
820 set_curr_dir_path(to, "test1.txt\0");
821 retval = SHFileOperationA(&shfo);
822 ok(retval == ERROR_SUCCESS, "Rename file back failed, retval = %d\n", retval);
824 set_curr_dir_path(from, "test4.txt\0");
825 set_curr_dir_path(to, "test6.txt\0");
826 retval = SHFileOperationA(&shfo);
827 ok(retval == ERROR_SUCCESS, "Rename dir failed, retval = %d\n", retval);
828 ok(!dir_exists("test4.txt"), "The dir is not renamed\n");
829 ok(dir_exists("test6.txt"), "The dir is not renamed\n");
831 set_curr_dir_path(from, "test6.txt\0");
832 set_curr_dir_path(to, "test4.txt\0");
833 retval = SHFileOperationA(&shfo);
834 ok(retval == ERROR_SUCCESS, "Rename dir back failed, retval = %d\n", retval);
835 ok(dir_exists("test4.txt"), "The dir is not renamed\n");
837 /* try to rename more than one file to a single file */
838 shfo.pFrom = "test1.txt\0test2.txt\0";
839 shfo.pTo = "a.txt\0";
840 retval = SHFileOperationA(&shfo);
841 ok(retval == ERROR_GEN_FAILURE ||
842 retval == DE_MANYSRC1DEST || /* Vista */
843 broken(retval == ERROR_SUCCESS), /* Win9x */
844 "Expected ERROR_GEN_FAILURE or DE_MANYSRC1DEST, got %d\n", retval);
845 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
846 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
847 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
849 /* pFrom doesn't exist */
850 shfo.pFrom = "idontexist\0";
851 shfo.pTo = "newfile\0";
852 retval = SHFileOperationA(&shfo);
853 ok(retval == 1026 ||
854 retval == ERROR_FILE_NOT_FOUND || /* Vista */
855 broken(retval == ERROR_SUCCESS), /* NT4 */
856 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", retval);
857 ok(!file_exists("newfile"), "Expected newfile to not exist\n");
859 /* pTo already exist */
860 shfo.pFrom = "test1.txt\0";
861 shfo.pTo = "test2.txt\0";
862 if (old_shell32)
863 shfo.fFlags |= FOF_NOCONFIRMMKDIR;
864 retval = SHFileOperationA(&shfo);
865 if (retval == ERROR_SUCCESS)
867 /* Vista and W2K8 (broken or new behavior ?) */
868 createTestFile("test1.txt");
870 else
872 ok(retval == ERROR_ALREADY_EXISTS ||
873 broken(retval == DE_OPCANCELLED) || /* NT4 */
874 broken(retval == ERROR_INVALID_NAME), /* Win9x */
875 "Expected ERROR_ALREADY_EXISTS, got %d\n", retval);
878 /* pFrom is valid, but pTo is empty */
879 shfo.pFrom = "test1.txt\0";
880 shfo.pTo = "\0";
881 retval = SHFileOperationA(&shfo);
882 ok(retval == ERROR_CANCELLED ||
883 retval == DE_DIFFDIR || /* Vista */
884 retval == DE_FILEDESTISFLD || /* Vista, running from c: */
885 broken(retval == DE_OPCANCELLED) || /* Win9x */
886 broken(retval == 65652), /* NT4 */
887 "Expected ERROR_CANCELLED or DE_DIFFDIR, got %u\n", retval);
888 ok(file_exists("test1.txt"), "Expected test1.txt to exist\n");
890 /* pFrom is empty */
891 shfo.pFrom = "\0";
892 retval = SHFileOperationA(&shfo);
893 ok(retval == ERROR_ACCESS_DENIED ||
894 retval == DE_MANYSRC1DEST || /* Vista */
895 broken(retval == ERROR_SUCCESS), /* Win9x */
896 "Expected ERROR_ACCESS_DENIED or DE_MANYSRC1DEST, got %d\n", retval);
898 /* pFrom is NULL, commented out because it crashes on nt 4.0 */
899 if (0)
901 shfo.pFrom = NULL;
902 retval = SHFileOperationA(&shfo);
903 ok(retval == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", retval);
907 /* tests the FO_COPY action */
908 static void test_copy(void)
910 SHFILEOPSTRUCTA shfo, shfo2;
911 CHAR from[5*MAX_PATH];
912 CHAR to[5*MAX_PATH];
913 FILEOP_FLAGS tmp_flags;
914 DWORD retval;
915 LPSTR ptr;
916 BOOL on_nt4 = FALSE;
917 BOOL ret;
919 if (old_shell32)
921 win_skip("Too many differences for old shell32\n");
922 return;
925 shfo.hwnd = NULL;
926 shfo.wFunc = FO_COPY;
927 shfo.pFrom = from;
928 shfo.pTo = to;
929 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
930 shfo.hNameMappings = NULL;
931 shfo.lpszProgressTitle = NULL;
933 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
934 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
935 retval = SHFileOperationA(&shfo);
936 if (dir_exists("test6.txt"))
938 /* Vista and W2K8 (broken or new behavior ?) */
939 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
940 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files "
941 "are specified as a target\n");
942 DeleteFileA("test6.txt\\test2.txt");
943 RemoveDirectoryA("test6.txt\\test4.txt");
944 RemoveDirectoryA("test6.txt");
946 else
948 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
949 ok(!file_exists("test6.txt"), "The file is copied - many files are "
950 "specified as a target\n");
953 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
954 shfo2.fFlags |= FOF_MULTIDESTFILES;
956 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
957 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
958 ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
959 ok(file_exists("test6.txt"), "The file is not copied - many files are "
960 "specified as a target\n");
961 DeleteFileA("test6.txt");
962 DeleteFileA("test7.txt");
963 RemoveDirectoryA("test8.txt");
965 /* number of sources does not correspond to number of targets */
966 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
967 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
968 retval = SHFileOperationA(&shfo2);
969 if (dir_exists("test6.txt"))
971 /* Vista and W2K8 (broken or new behavior?) */
972 ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %d\n", retval);
973 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not copied - many files "
974 "are specified as a target\n");
975 RemoveDirectoryA("test6.txt");
976 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not copied - many files "
977 "are specified as a target\n");
978 RemoveDirectoryA("test7.txt");
980 else
982 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
983 ok(!file_exists("test6.txt"), "The file is copied - many files are "
984 "specified as a target\n");
987 set_curr_dir_path(from, "test1.txt\0");
988 set_curr_dir_path(to, "test4.txt\0");
989 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
990 ok(file_exists("test4.txt\\test1.txt"), "The file is copied\n");
992 set_curr_dir_path(from, "test?.txt\0");
993 set_curr_dir_path(to, "testdir2\0");
994 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
995 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
996 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
997 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
998 ok(file_exists("testdir2\\test4.txt"), "The directory is copied\n");
999 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
1000 clean_after_shfo_tests();
1002 init_shfo_tests();
1003 shfo.fFlags |= FOF_FILESONLY;
1004 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
1005 ok(!file_exists("testdir2\\test4.txt"), "The directory is not copied yet\n");
1006 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
1007 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
1008 ok(!file_exists("testdir2\\test4.txt"), "The directory is copied\n");
1009 clean_after_shfo_tests();
1011 init_shfo_tests();
1012 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
1013 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
1014 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
1015 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
1016 ok(file_exists("testdir2\\test1.txt"), "The file is copied\n");
1017 ok(file_exists("testdir2\\test2.txt"), "The file is copied\n");
1018 clean_after_shfo_tests();
1020 /* Copying multiple files with one not existing as source, fails the
1021 entire operation in Win98/ME/2K/XP, but not in 95/NT */
1022 init_shfo_tests();
1023 tmp_flags = shfo.fFlags;
1024 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
1025 ok(!file_exists("testdir2\\test1.txt"), "The file is not copied yet\n");
1026 ok(!file_exists("testdir2\\test2.txt"), "The file is not copied yet\n");
1027 retval = SHFileOperationA(&shfo);
1028 if (retval == ERROR_SUCCESS)
1029 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
1030 ok(file_exists("testdir2\\test1.txt"), "The file is not copied\n");
1031 else
1033 /* Failure if one source file does not exist */
1034 ok(retval == 1026 || /* Win 98/ME/2K/XP */
1035 retval == ERROR_FILE_NOT_FOUND, /* Vista and W2K8 */
1036 "Files are copied to other directory\n");
1037 ok(!file_exists("testdir2\\test1.txt"), "The file is copied\n");
1039 ok(!file_exists("testdir2\\test2.txt"), "The file is copied\n");
1040 shfo.fFlags = tmp_flags;
1042 /* copy into a nonexistent directory */
1043 init_shfo_tests();
1044 shfo.fFlags = FOF_NOCONFIRMMKDIR;
1045 set_curr_dir_path(from, "test1.txt\0");
1046 set_curr_dir_path(to, "nonexistent\\notreal\\test2.txt\0");
1047 retval= SHFileOperationA(&shfo);
1048 ok(!retval, "Error copying into nonexistent directory\n");
1049 ok(file_exists("nonexistent"), "nonexistent not created\n");
1050 ok(file_exists("nonexistent\\notreal"), "nonexistent\\notreal not created\n");
1051 ok(file_exists("nonexistent\\notreal\\test2.txt"), "Directory not created\n");
1052 ok(!file_exists("nonexistent\\notreal\\test1.txt"), "test1.txt should not exist\n");
1054 /* a relative dest directory is OK */
1055 clean_after_shfo_tests();
1056 init_shfo_tests();
1057 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1058 shfo.pTo = "testdir2\0";
1059 retval = SHFileOperationA(&shfo);
1060 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1061 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1 to exist\n");
1063 /* try to overwrite an existing write protected file */
1064 clean_after_shfo_tests();
1065 init_shfo_tests();
1066 tmp_flags = shfo.fFlags;
1067 shfo.pFrom = "test1.txt\0";
1068 shfo.pTo = "test2.txt\0";
1069 /* suppress the error-dialog in win9x here */
1070 shfo.fFlags = FOF_NOERRORUI | FOF_NOCONFIRMATION | FOF_SILENT;
1071 ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_READONLY);
1072 ok(ret, "Failure to set file attributes (error %x)\n", GetLastError());
1073 retval = CopyFileA(shfo.pFrom, shfo.pTo, FALSE);
1074 ok(!retval && GetLastError() == ERROR_ACCESS_DENIED, "CopyFileA should have fail with ERROR_ACCESS_DENIED\n");
1075 retval = SHFileOperationA(&shfo);
1076 /* Does not work on Win95, Win95B, NT4WS and NT4SRV */
1077 ok(!retval || broken(retval == DE_OPCANCELLED), "SHFileOperationA failed to copy (error %x)\n", retval);
1078 /* Set back normal attributes to make the file deletion succeed */
1079 ret = SetFileAttributesA(shfo.pTo, FILE_ATTRIBUTE_NORMAL);
1080 ok(ret, "Failure to set file attributes (error %x)\n", GetLastError());
1081 shfo.fFlags = tmp_flags;
1083 /* try to copy files to a file */
1084 clean_after_shfo_tests();
1085 init_shfo_tests();
1086 shfo.pFrom = from;
1087 shfo.pTo = to;
1088 /* suppress the error-dialog in win9x here */
1089 shfo.fFlags |= FOF_NOERRORUI;
1090 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
1091 set_curr_dir_path(to, "test3.txt\0");
1092 shfo.fAnyOperationsAborted = 0xdeadbeef;
1093 retval = SHFileOperationA(&shfo);
1094 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1095 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1096 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1097 if (retval == DE_FLDDESTISFILE || /* Vista and W2K8 */
1098 retval == DE_INVALIDFILES) /* Win7 */
1100 /* Most likely new behavior */
1101 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1103 else
1105 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1106 ok(shfo.fAnyOperationsAborted, "Expected aborted operations\n");
1108 ok(!file_exists("test3.txt\\test2.txt"), "Expected test3.txt\\test2.txt to not exist\n");
1110 /* try to copy many files to nonexistent directory */
1111 DeleteFileA(to);
1112 shfo.fFlags &= ~FOF_NOERRORUI;
1113 shfo.fAnyOperationsAborted = 0xdeadbeef;
1114 retval = SHFileOperationA(&shfo);
1115 ok(!shfo.fAnyOperationsAborted ||
1116 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1117 "Didn't expect aborted operations\n");
1118 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1119 ok(DeleteFileA("test3.txt\\test1.txt"), "Expected test3.txt\\test1.txt to exist\n");
1120 ok(DeleteFileA("test3.txt\\test2.txt"), "Expected test3.txt\\test1.txt to exist\n");
1121 ok(RemoveDirectoryA(to), "Expected test3.txt to exist\n");
1123 /* send in FOF_MULTIDESTFILES with too many destination files */
1124 init_shfo_tests();
1125 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1126 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
1127 shfo.fFlags |= FOF_NOERRORUI | FOF_MULTIDESTFILES;
1128 shfo.fAnyOperationsAborted = 0xdeadbeef;
1129 retval = SHFileOperationA(&shfo);
1130 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1131 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1132 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1133 if (dir_exists("testdir2\\a.txt"))
1135 /* Vista and W2K8 (broken or new behavior ?) */
1136 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1137 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1138 ok(DeleteFileA("testdir2\\a.txt\\test1.txt"), "Expected testdir2\\a.txt\\test1.txt to exist\n");
1139 RemoveDirectoryA("testdir2\\a.txt");
1140 ok(DeleteFileA("testdir2\\b.txt\\test2.txt"), "Expected testdir2\\b.txt\\test2.txt to exist\n");
1141 RemoveDirectoryA("testdir2\\b.txt");
1142 ok(DeleteFileA("testdir2\\c.txt\\test3.txt"), "Expected testdir2\\c.txt\\test3.txt to exist\n");
1143 RemoveDirectoryA("testdir2\\c.txt");
1144 ok(!file_exists("testdir2\\d.txt"), "Expected testdir2\\d.txt to not exist\n");
1146 else
1148 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1149 ok(shfo.fAnyOperationsAborted ||
1150 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1151 "Expected aborted operations\n");
1152 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\a.txt to not exist\n");
1155 /* send in FOF_MULTIDESTFILES with too many destination files */
1156 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1157 shfo.pTo = "e.txt\0f.txt\0";
1158 shfo.fAnyOperationsAborted = 0xdeadbeef;
1159 retval = SHFileOperationA(&shfo);
1160 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1161 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1162 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1163 if (dir_exists("e.txt"))
1165 /* Vista and W2K8 (broken or new behavior ?) */
1166 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1167 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
1168 ok(DeleteFileA("e.txt\\test1.txt"), "Expected e.txt\\test1.txt to exist\n");
1169 RemoveDirectoryA("e.txt");
1170 ok(DeleteFileA("f.txt\\test2.txt"), "Expected f.txt\\test2.txt to exist\n");
1171 RemoveDirectoryA("f.txt");
1173 else
1175 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1176 ok(shfo.fAnyOperationsAborted ||
1177 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1178 "Expected aborted operations\n");
1179 ok(!file_exists("e.txt"), "Expected e.txt to not exist\n");
1182 /* use FOF_MULTIDESTFILES with files and a source directory */
1183 shfo.pFrom = "test1.txt\0test2.txt\0test4.txt\0";
1184 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0";
1185 shfo.fAnyOperationsAborted = 0xdeadbeef;
1186 retval = SHFileOperationA(&shfo);
1187 ok(!shfo.fAnyOperationsAborted ||
1188 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1189 "Didn't expect aborted operations\n");
1190 ok(retval == ERROR_SUCCESS ||
1191 broken(retval == 0x100a1), /* WinMe */
1192 "Expected ERROR_SUCCESS, got %d\n", retval);
1193 ok(DeleteFileA("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
1194 ok(DeleteFileA("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n");
1195 if (retval == ERROR_SUCCESS)
1196 ok(RemoveDirectoryA("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n");
1198 /* try many dest files without FOF_MULTIDESTFILES flag */
1199 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1200 shfo.pTo = "a.txt\0b.txt\0c.txt\0";
1201 shfo.fAnyOperationsAborted = 0xdeadbeef;
1202 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1203 retval = SHFileOperationA(&shfo);
1204 ok(shfo.fAnyOperationsAborted != 0xdeadbeef ||
1205 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1206 "Expected TRUE/FALSE fAnyOperationsAborted not 0xdeadbeef\n");
1207 if (dir_exists("a.txt"))
1209 /* Vista and W2K8 (broken or new behavior ?) */
1210 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1211 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1212 ok(DeleteFileA("a.txt\\test1.txt"), "Expected a.txt\\test1.txt to exist\n");
1213 ok(DeleteFileA("a.txt\\test2.txt"), "Expected a.txt\\test2.txt to exist\n");
1214 ok(DeleteFileA("a.txt\\test3.txt"), "Expected a.txt\\test3.txt to exist\n");
1215 RemoveDirectoryA("a.txt");
1217 else
1220 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1221 ok(shfo.fAnyOperationsAborted ||
1222 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1223 "Expected aborted operations\n");
1224 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
1227 /* try a glob */
1228 shfo.pFrom = "test?.txt\0";
1229 shfo.pTo = "testdir2\0";
1230 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1231 retval = SHFileOperationA(&shfo);
1232 ok(retval == ERROR_SUCCESS ||
1233 broken(retval == 0x100a1), /* WinMe */
1234 "Expected ERROR_SUCCESS, got %d\n", retval);
1235 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1237 /* try a glob with FOF_FILESONLY */
1238 clean_after_shfo_tests();
1239 init_shfo_tests();
1240 shfo.pFrom = "test?.txt\0";
1241 shfo.fFlags |= FOF_FILESONLY;
1242 retval = SHFileOperationA(&shfo);
1243 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1244 ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1245 ok(!dir_exists("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to not exist\n");
1247 /* try a glob with FOF_MULTIDESTFILES and the same number
1248 * of dest files that we would expect
1250 clean_after_shfo_tests();
1251 init_shfo_tests();
1252 shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0testdir2\\d.txt\0";
1253 shfo.fFlags &= ~FOF_FILESONLY;
1254 shfo.fFlags |= FOF_MULTIDESTFILES;
1255 retval = SHFileOperationA(&shfo);
1256 if (dir_exists("testdir2\\a.txt"))
1258 /* Vista and W2K8 (broken or new behavior ?) */
1259 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1260 ok(DeleteFileA("testdir2\\a.txt\\test1.txt"), "Expected testdir2\\a.txt\\test1.txt to exist\n");
1261 ok(DeleteFileA("testdir2\\a.txt\\test2.txt"), "Expected testdir2\\a.txt\\test2.txt to exist\n");
1262 ok(DeleteFileA("testdir2\\a.txt\\test3.txt"), "Expected testdir2\\a.txt\\test3.txt to exist\n");
1263 ok(RemoveDirectoryA("testdir2\\a.txt\\test4.txt"), "Expected testdir2\\a.txt\\test4.txt to exist\n");
1264 RemoveDirectoryA("testdir2\\a.txt");
1266 else
1268 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1269 ok(shfo.fAnyOperationsAborted ||
1270 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1271 "Expected aborted operations\n");
1272 ok(!file_exists("testdir2\\a.txt"), "Expected testdir2\\test1.txt to not exist\n");
1274 ok(!RemoveDirectoryA("b.txt"), "b.txt should not exist\n");
1276 /* copy one file to two others, second is ignored */
1277 clean_after_shfo_tests();
1278 init_shfo_tests();
1279 shfo.pFrom = "test1.txt\0";
1280 shfo.pTo = "b.txt\0c.txt\0";
1281 shfo.fAnyOperationsAborted = 0xdeadbeef;
1282 retval = SHFileOperationA(&shfo);
1283 ok(!shfo.fAnyOperationsAborted ||
1284 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1285 "Didn't expect aborted operations\n");
1286 if (retval == DE_OPCANCELLED)
1288 /* NT4 fails and doesn't copy any files */
1289 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1290 /* Needed to skip some tests */
1291 win_skip("Skipping some tests on NT4\n");
1292 on_nt4 = TRUE;
1294 else
1296 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1297 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1299 ok(!DeleteFileA("c.txt"), "Expected c.txt to not exist\n");
1301 /* copy two file to three others, all fail */
1302 shfo.pFrom = "test1.txt\0test2.txt\0";
1303 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
1304 shfo.fAnyOperationsAborted = 0xdeadbeef;
1305 retval = SHFileOperationA(&shfo);
1306 if (dir_exists("b.txt"))
1308 /* Vista and W2K8 (broken or new behavior ?) */
1309 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1310 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1311 ok(DeleteFileA("b.txt\\test1.txt"), "Expected b.txt\\test1.txt to exist\n");
1312 RemoveDirectoryA("b.txt");
1313 ok(DeleteFileA("c.txt\\test2.txt"), "Expected c.txt\\test2.txt to exist\n");
1314 RemoveDirectoryA("c.txt");
1316 else
1318 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1319 ok(shfo.fAnyOperationsAborted ||
1320 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1321 "Expected aborted operations\n");
1322 ok(!DeleteFileA("b.txt"), "Expected b.txt to not exist\n");
1325 /* copy one file and one directory to three others */
1326 shfo.pFrom = "test1.txt\0test4.txt\0";
1327 shfo.pTo = "b.txt\0c.txt\0d.txt\0";
1328 shfo.fAnyOperationsAborted = 0xdeadbeef;
1329 retval = SHFileOperationA(&shfo);
1330 if (dir_exists("b.txt"))
1332 /* Vista and W2K8 (broken or new behavior ?) */
1333 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1334 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1335 ok(DeleteFileA("b.txt\\test1.txt"), "Expected b.txt\\test1.txt to exist\n");
1336 RemoveDirectoryA("b.txt");
1337 ok(RemoveDirectoryA("c.txt\\test4.txt"), "Expected c.txt\\test4.txt to exist\n");
1338 RemoveDirectoryA("c.txt");
1340 else
1342 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1343 ok(shfo.fAnyOperationsAborted ||
1344 broken(shfo.fAnyOperationsAborted == 0xdeadbeef), /* NT4 */
1345 "Expected aborted operations\n");
1346 ok(!DeleteFileA("b.txt"), "Expected b.txt to not exist\n");
1347 ok(!DeleteFileA("c.txt"), "Expected c.txt to not exist\n");
1350 /* copy a directory with a file beneath it, plus some files */
1351 createTestFile("test4.txt\\a.txt");
1352 shfo.pFrom = "test4.txt\0test1.txt\0";
1353 shfo.pTo = "testdir2\0";
1354 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1355 shfo.fAnyOperationsAborted = FALSE;
1356 retval = SHFileOperationA(&shfo);
1357 ok(retval == ERROR_SUCCESS ||
1358 broken(retval == 0x100a1), /* WinMe */
1359 "Expected ERROR_SUCCESS, got %d\n", retval);
1360 if (retval == ERROR_SUCCESS)
1362 ok(DeleteFileA("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n");
1363 ok(DeleteFileA("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
1364 ok(RemoveDirectoryA("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n");
1367 /* copy one directory and a file in that dir to another dir */
1368 shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0";
1369 shfo.pTo = "testdir2\0";
1370 retval = SHFileOperationA(&shfo);
1371 ok(retval == ERROR_SUCCESS ||
1372 broken(retval == 0x100a1), /* WinMe */
1373 "Expected ERROR_SUCCESS, got %d\n", retval);
1374 if (retval == ERROR_SUCCESS)
1376 ok(DeleteFileA("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n");
1377 ok(DeleteFileA("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n");
1380 /* copy a file in a directory first, and then the directory to a nonexistent dir */
1381 shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0";
1382 shfo.pTo = "nonexistent\0";
1383 retval = SHFileOperationA(&shfo);
1384 if (dir_exists("nonexistent"))
1386 /* Vista and W2K8 (broken or new behavior ?) */
1387 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1388 ok(DeleteFileA("nonexistent\\test4.txt\\a.txt"), "Expected nonexistent\\test4.txt\\a.txt to exist\n");
1389 RemoveDirectoryA("nonexistent\\test4.txt");
1390 ok(DeleteFileA("nonexistent\\a.txt"), "Expected nonexistent\\a.txt to exist\n");
1391 RemoveDirectoryA("nonexistent");
1393 else
1395 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1396 ok(shfo.fAnyOperationsAborted ||
1397 broken(!shfo.fAnyOperationsAborted), /* NT4 */
1398 "Expected aborted operations\n");
1399 ok(!file_exists("nonexistent\\test4.txt"), "Expected nonexistent\\test4.txt to not exist\n");
1401 DeleteFileA("test4.txt\\a.txt");
1403 /* destination is same as source file */
1404 shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0";
1405 shfo.pTo = "b.txt\0test2.txt\0c.txt\0";
1406 shfo.fAnyOperationsAborted = FALSE;
1407 shfo.fFlags = FOF_NOERRORUI | FOF_MULTIDESTFILES;
1408 retval = SHFileOperationA(&shfo);
1409 if (retval == DE_OPCANCELLED)
1411 /* NT4 fails and doesn't copy any files */
1412 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1414 else
1416 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
1417 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1419 ok(!shfo.fAnyOperationsAborted, "Expected no operations to be aborted\n");
1420 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
1422 /* destination is same as source directory */
1423 shfo.pFrom = "test1.txt\0test4.txt\0test3.txt\0";
1424 shfo.pTo = "b.txt\0test4.txt\0c.txt\0";
1425 shfo.fAnyOperationsAborted = FALSE;
1426 retval = SHFileOperationA(&shfo);
1427 if (retval == DE_OPCANCELLED)
1429 /* NT4 fails and doesn't copy any files */
1430 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
1432 else
1434 ok(retval == ERROR_SUCCESS ||
1435 retval == DE_DESTSAMETREE, /* Vista */
1436 "Expected ERROR_SUCCESS or DE_DESTSAMETREE, got %d\n", retval);
1437 ok(DeleteFileA("b.txt"), "Expected b.txt to exist\n");
1439 ok(!file_exists("c.txt"), "Expected c.txt to not exist\n");
1441 /* copy a directory into itself, error displayed in UI */
1442 shfo.pFrom = "test4.txt\0";
1443 shfo.pTo = "test4.txt\\newdir\0";
1444 shfo.fFlags &= ~FOF_MULTIDESTFILES;
1445 shfo.fAnyOperationsAborted = FALSE;
1446 retval = SHFileOperationA(&shfo);
1447 ok(retval == ERROR_SUCCESS ||
1448 retval == DE_DESTSUBTREE, /* Vista */
1449 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1450 ok(!RemoveDirectoryA("test4.txt\\newdir"), "Expected test4.txt\\newdir to not exist\n");
1452 /* copy a directory to itself, error displayed in UI */
1453 shfo.pFrom = "test4.txt\0";
1454 shfo.pTo = "test4.txt\0";
1455 shfo.fAnyOperationsAborted = FALSE;
1456 retval = SHFileOperationA(&shfo);
1457 ok(retval == ERROR_SUCCESS ||
1458 retval == DE_DESTSUBTREE, /* Vista */
1459 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1461 /* copy a file into a directory, and the directory into itself */
1462 shfo.pFrom = "test1.txt\0test4.txt\0";
1463 shfo.pTo = "test4.txt\0";
1464 shfo.fAnyOperationsAborted = FALSE;
1465 shfo.fFlags |= FOF_NOCONFIRMATION;
1466 retval = SHFileOperationA(&shfo);
1467 ok(retval == ERROR_SUCCESS ||
1468 retval == DE_DESTSUBTREE, /* Vista */
1469 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
1470 ok(DeleteFileA("test4.txt\\test1.txt"), "Expected test4.txt\\test1.txt to exist\n");
1472 /* copy a file to a file, and the directory into itself */
1473 shfo.pFrom = "test1.txt\0test4.txt\0";
1474 shfo.pTo = "test4.txt\\a.txt\0";
1475 shfo.fAnyOperationsAborted = FALSE;
1476 retval = SHFileOperationA(&shfo);
1477 if (dir_exists("test4.txt\\a.txt"))
1479 /* Vista and W2K8 (broken or new behavior ?) */
1480 ok(retval == DE_DESTSUBTREE, "Expected DE_DESTSUBTREE, got %d\n", retval);
1481 ok(DeleteFileA("test4.txt\\a.txt\\test1.txt"), "Expected test4.txt\\a.txt\\test1.txt to exist\n");
1482 RemoveDirectoryA("test4.txt\\a.txt");
1484 else
1486 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1487 ok(!file_exists("test4.txt\\a.txt"), "Expected test4.txt\\a.txt to not exist\n");
1490 /* copy a nonexistent file to a nonexistent directory */
1491 shfo.pFrom = "e.txt\0";
1492 shfo.pTo = "nonexistent\0";
1493 shfo.fAnyOperationsAborted = FALSE;
1494 retval = SHFileOperationA(&shfo);
1495 ok(retval == 1026 ||
1496 retval == ERROR_FILE_NOT_FOUND || /* Vista */
1497 broken(retval == ERROR_SUCCESS), /* NT4 */
1498 "Expected 1026 or ERROR_FILE_NOT_FOUND, got %d\n", retval);
1499 ok(!file_exists("nonexistent\\e.txt"), "Expected nonexistent\\e.txt to not exist\n");
1500 ok(!file_exists("nonexistent"), "Expected nonexistent to not exist\n");
1502 /* Overwrite tests */
1503 clean_after_shfo_tests();
1504 init_shfo_tests();
1505 if (!on_nt4)
1507 /* NT4 would throw up some dialog boxes and doesn't copy files that are needed
1508 * in subsequent tests.
1510 shfo.fFlags = FOF_NOCONFIRMATION;
1511 shfo.pFrom = "test1.txt\0";
1512 shfo.pTo = "test2.txt\0";
1513 shfo.fAnyOperationsAborted = 0xdeadbeef;
1514 /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
1515 retval = SHFileOperationA(&shfo);
1516 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1517 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1518 ok(file_has_content("test2.txt", "test1.txt\n"), "The file was not copied\n");
1520 shfo.pFrom = "test3.txt\0test1.txt\0";
1521 shfo.pTo = "test2.txt\0one.txt\0";
1522 shfo.fFlags = FOF_NOCONFIRMATION | FOF_MULTIDESTFILES;
1523 /* without FOF_NOCONFIRMATION the confirmation is Yes/Yes to All/No/Cancel */
1524 retval = SHFileOperationA(&shfo);
1525 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1526 ok(file_has_content("test2.txt", "test3.txt\n"), "The file was not copied\n");
1528 shfo.pFrom = "one.txt\0";
1529 shfo.pTo = "testdir2\0";
1530 shfo.fFlags = FOF_NOCONFIRMATION;
1531 /* without FOF_NOCONFIRMATION the confirmation is Yes/No */
1532 retval = SHFileOperationA(&shfo);
1533 ok(retval == 0, "Expected 0, got %d\n", retval);
1534 ok(file_has_content("testdir2\\one.txt", "test1.txt\n"), "The file was not copied\n");
1537 createTestFile("test4.txt\\test1.txt");
1538 shfo.pFrom = "test4.txt\0";
1539 shfo.pTo = "testdir2\0";
1540 /* WinMe needs FOF_NOERRORUI */
1541 shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI;
1542 retval = SHFileOperationA(&shfo);
1543 ok(retval == ERROR_SUCCESS ||
1544 broken(retval == 0x100a1), /* WinMe */
1545 "Expected ERROR_SUCCESS, got %d\n", retval);
1546 shfo.fFlags = FOF_NOCONFIRMATION;
1547 if (ERROR_SUCCESS)
1549 createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */
1550 /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */
1551 retval = SHFileOperationA(&shfo);
1552 ok(retval == 0, "Expected 0, got %d\n", retval);
1553 ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n");
1556 createTestFile("one.txt");
1558 /* pFrom contains bogus 2nd name longer than MAX_PATH */
1559 memset(from, 'a', MAX_PATH*2);
1560 memset(from+MAX_PATH*2, 0, 2);
1561 lstrcpyA(from, "one.txt");
1562 shfo.pFrom = from;
1563 shfo.pTo = "two.txt\0";
1564 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1565 retval = SHFileOperationA(&shfo);
1566 ok(retval == 1148 || retval == 1026 ||
1567 retval == ERROR_ACCESS_DENIED || /* win2k */
1568 retval == DE_INVALIDFILES, /* Vista */
1569 "Unexpected return value, got %d\n", retval);
1570 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1571 if (dir_exists("two.txt"))
1572 /* Vista and W2K8 (broken or new behavior ?) */
1573 ok(RemoveDirectoryA("two.txt"), "Expected two.txt to exist\n");
1574 else
1575 ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
1577 createTestFile("one.txt");
1579 /* pTo contains bogus 2nd name longer than MAX_PATH */
1580 memset(to, 'a', MAX_PATH*2);
1581 memset(to+MAX_PATH*2, 0, 2);
1582 lstrcpyA(to, "two.txt");
1583 shfo.pFrom = "one.txt\0";
1584 shfo.pTo = to;
1585 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1586 retval = SHFileOperationA(&shfo);
1587 if (retval == DE_OPCANCELLED)
1589 /* NT4 fails and doesn't copy any files */
1590 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1592 else
1594 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1595 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1597 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1599 createTestFile("one.txt");
1601 /* no FOF_MULTIDESTFILES, two files in pTo */
1602 shfo.pFrom = "one.txt\0";
1603 shfo.pTo = "two.txt\0three.txt\0";
1604 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1605 retval = SHFileOperationA(&shfo);
1606 if (retval == DE_OPCANCELLED)
1608 /* NT4 fails and doesn't copy any files */
1609 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1611 else
1613 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1614 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1616 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1618 createTestFile("one.txt");
1620 /* both pFrom and pTo contain bogus 2nd names longer than MAX_PATH */
1621 memset(from, 'a', MAX_PATH*2);
1622 memset(from+MAX_PATH*2, 0, 2);
1623 memset(to, 'a', MAX_PATH*2);
1624 memset(to+MAX_PATH*2, 0, 2);
1625 lstrcpyA(from, "one.txt");
1626 lstrcpyA(to, "two.txt");
1627 shfo.pFrom = from;
1628 shfo.pTo = to;
1629 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1630 retval = SHFileOperationA(&shfo);
1631 ok(retval == 1148 || retval == 1026 ||
1632 retval == ERROR_ACCESS_DENIED || /* win2k */
1633 retval == DE_INVALIDFILES, /* Vista */
1634 "Unexpected return value, got %d\n", retval);
1635 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1636 if (dir_exists("two.txt"))
1637 /* Vista and W2K8 (broken or new behavior ?) */
1638 ok(RemoveDirectoryA("two.txt"), "Expected two.txt to exist\n");
1639 else
1640 ok(!DeleteFileA("two.txt"), "Expected file to not exist\n");
1642 createTestFile("one.txt");
1644 /* pTo contains bogus 2nd name longer than MAX_PATH, FOF_MULTIDESTFILES */
1645 memset(to, 'a', MAX_PATH*2);
1646 memset(to+MAX_PATH*2, 0, 2);
1647 lstrcpyA(to, "two.txt");
1648 shfo.pFrom = "one.txt\0";
1649 shfo.pTo = to;
1650 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1651 FOF_SILENT | FOF_NOERRORUI;
1652 retval = SHFileOperationA(&shfo);
1653 if (retval == DE_OPCANCELLED)
1655 /* NT4 fails and doesn't copy any files */
1656 ok(!file_exists("two.txt"), "Expected two.txt to not exist\n");
1658 else
1660 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1661 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1663 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1665 createTestFile("one.txt");
1666 createTestFile("two.txt");
1668 /* pTo contains bogus 2nd name longer than MAX_PATH,
1669 * multiple source files,
1670 * dest directory does not exist
1672 memset(to, 'a', 2 * MAX_PATH);
1673 memset(to+MAX_PATH*2, 0, 2);
1674 lstrcpyA(to, "threedir");
1675 shfo.pFrom = "one.txt\0two.txt\0";
1676 shfo.pTo = to;
1677 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1678 retval = SHFileOperationA(&shfo);
1679 if (dir_exists("threedir"))
1681 /* Vista and W2K8 (broken or new behavior ?) */
1682 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1683 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1684 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1685 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1687 else
1689 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
1690 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1691 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1692 ok(!DeleteFileA("threedir"), "Expected file to not exist\n");
1693 ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1695 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1696 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1698 createTestFile("one.txt");
1699 createTestFile("two.txt");
1700 CreateDirectoryA("threedir", NULL);
1702 /* pTo contains bogus 2nd name longer than MAX_PATH,
1703 * multiple source files,
1704 * dest directory does exist
1706 memset(to, 'a', 2 * MAX_PATH);
1707 memset(to+MAX_PATH*2, 0, 2);
1708 lstrcpyA(to, "threedir");
1709 shfo.pFrom = "one.txt\0two.txt\0";
1710 shfo.pTo = to;
1711 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1712 retval = SHFileOperationA(&shfo);
1713 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1714 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1715 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1716 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1717 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1718 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1720 if (0) {
1721 /* this crashes on win9x */
1722 createTestFile("one.txt");
1723 createTestFile("two.txt");
1725 /* pTo contains bogus 2nd name longer than MAX_PATH,
1726 * multiple source files, FOF_MULTIDESTFILES
1727 * dest dir does not exist
1730 memset(to, 'a', 2 * MAX_PATH);
1731 memset(to+MAX_PATH*2, 0, 2);
1732 lstrcpyA(to, "threedir");
1733 shfo.pFrom = "one.txt\0two.txt\0";
1734 shfo.pTo = to;
1735 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1736 FOF_SILENT | FOF_NOERRORUI;
1737 retval = SHFileOperationA(&shfo);
1738 ok(retval == ERROR_CANCELLED ||
1739 retval == ERROR_SUCCESS, /* win2k3 */
1740 "Expected ERROR_CANCELLED or ERROR_SUCCESS, got %d\n", retval);
1741 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1742 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1743 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1744 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1745 ok(!RemoveDirectoryA("threedir"), "Expected dir to not exist\n");
1747 /* file exists in win2k */
1748 DeleteFileA("threedir");
1752 createTestFile("one.txt");
1753 createTestFile("two.txt");
1754 CreateDirectoryA("threedir", NULL);
1756 /* pTo contains bogus 2nd name longer than MAX_PATH,
1757 * multiple source files, FOF_MULTIDESTFILES
1758 * dest dir does exist
1760 memset(to, 'a', 2 * MAX_PATH);
1761 memset(to+MAX_PATH*2, 0, 2);
1762 lstrcpyA(to, "threedir");
1763 ptr = to + lstrlenA(to) + 1;
1764 lstrcpyA(ptr, "fourdir");
1765 shfo.pFrom = "one.txt\0two.txt\0";
1766 shfo.pTo = to;
1767 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1768 FOF_SILENT | FOF_NOERRORUI;
1769 retval = SHFileOperationA(&shfo);
1770 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1771 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1772 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1773 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1774 if (dir_exists("fourdir"))
1776 /* Vista and W2K8 (broken or new behavior ?) */
1777 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1778 ok(DeleteFileA("fourdir\\two.txt"), "Expected file to exist\n");
1779 RemoveDirectoryA("fourdir");
1781 else
1783 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1784 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1785 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1787 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1789 createTestFile("one.txt");
1790 createTestFile("two.txt");
1791 CreateDirectoryA("threedir", NULL);
1793 /* multiple source files, FOF_MULTIDESTFILES
1794 * multiple dest files, but first dest dir exists
1795 * num files in lists is equal
1797 shfo.pFrom = "one.txt\0two.txt\0";
1798 shfo.pTo = "threedir\0fourdir\0";
1799 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1800 FOF_SILENT | FOF_NOERRORUI;
1801 retval = SHFileOperationA(&shfo);
1802 ok(retval == ERROR_CANCELLED ||
1803 retval == DE_FILEDESTISFLD || /* Vista */
1804 broken(retval == DE_OPCANCELLED), /* Win9x, NT4 */
1805 "Expected ERROR_CANCELLED or DE_FILEDESTISFLD. got %d\n", retval);
1806 if (file_exists("threedir\\threedir"))
1808 /* NT4 */
1809 ok(DeleteFileA("threedir\\threedir"), "Expected file to exist\n");
1811 ok(!DeleteFileA("threedir\\one.txt"), "Expected file to not exist\n");
1812 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1813 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1814 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1815 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1816 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1817 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1819 createTestFile("one.txt");
1820 createTestFile("two.txt");
1821 CreateDirectoryA("threedir", NULL);
1823 /* multiple source files, FOF_MULTIDESTFILES
1824 * multiple dest files, but first dest dir exists
1825 * num files in lists is not equal
1827 shfo.pFrom = "one.txt\0two.txt\0";
1828 shfo.pTo = "threedir\0fourdir\0five\0";
1829 shfo.fFlags = FOF_MULTIDESTFILES | FOF_NOCONFIRMATION |
1830 FOF_SILENT | FOF_NOERRORUI;
1831 retval = SHFileOperationA(&shfo);
1832 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1833 ok(DeleteFileA("one.txt"), "Expected file to exist\n");
1834 ok(DeleteFileA("two.txt"), "Expected file to exist\n");
1835 ok(DeleteFileA("threedir\\one.txt"), "Expected file to exist\n");
1836 if (dir_exists("fourdir"))
1838 /* Vista and W2K8 (broken or new behavior ?) */
1839 ok(!DeleteFileA("threedir\\two.txt"), "Expected file to not exist\n");
1840 ok(DeleteFileA("fourdir\\two.txt"), "Expected file to exist\n");
1841 RemoveDirectoryA("fourdir");
1843 else
1845 ok(DeleteFileA("threedir\\two.txt"), "Expected file to exist\n");
1846 ok(!DeleteFileA("fourdir"), "Expected file to not exist\n");
1847 ok(!RemoveDirectoryA("fourdir"), "Expected dir to not exist\n");
1849 ok(RemoveDirectoryA("threedir"), "Expected dir to exist\n");
1850 ok(!DeleteFileA("five"), "Expected file to not exist\n");
1851 ok(!RemoveDirectoryA("five"), "Expected dir to not exist\n");
1853 createTestFile("aa.txt");
1854 createTestFile("ab.txt");
1855 CreateDirectoryA("one", NULL);
1856 CreateDirectoryA("two", NULL);
1858 /* pFrom has a glob, pTo has more than one dest */
1859 shfo.pFrom = "a*.txt\0";
1860 shfo.pTo = "one\0two\0";
1861 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1862 retval = SHFileOperationA(&shfo);
1863 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
1864 ok(DeleteFileA("one\\aa.txt"), "Expected file to exist\n");
1865 ok(DeleteFileA("one\\ab.txt"), "Expected file to exist\n");
1866 ok(!DeleteFileA("two\\aa.txt"), "Expected file to not exist\n");
1867 ok(!DeleteFileA("two\\ab.txt"), "Expected file to not exist\n");
1868 ok(DeleteFileA("aa.txt"), "Expected file to exist\n");
1869 ok(DeleteFileA("ab.txt"), "Expected file to exist\n");
1870 ok(RemoveDirectoryA("one"), "Expected dir to exist\n");
1871 ok(RemoveDirectoryA("two"), "Expected dir to exist\n");
1873 /* pTo is an empty string */
1874 CreateDirectoryA("dir", NULL);
1875 createTestFile("dir\\abcdefgh.abc");
1876 shfo.pFrom = "dir\\abcdefgh.abc\0";
1877 shfo.pTo = "\0";
1878 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1879 retval = SHFileOperationA(&shfo);
1880 ok(retval == ERROR_SUCCESS ||
1881 broken(retval == DE_OPCANCELLED), /* NT4 */
1882 "Expected ERROR_SUCCESS, got %d\n", retval);
1883 if (retval == ERROR_SUCCESS)
1884 ok(DeleteFileA("abcdefgh.abc"), "Expected file to exist\n");
1885 ok(DeleteFileA("dir\\abcdefgh.abc"), "Expected file to exist\n");
1886 ok(RemoveDirectoryA("dir"), "Expected dir to exist\n");
1888 /* Check last error after a successful file operation. */
1889 clean_after_shfo_tests();
1890 init_shfo_tests();
1891 shfo.pFrom = "test1.txt\0";
1892 shfo.pTo = "testdir2\0";
1893 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1894 SetLastError(0xdeadbeef);
1895 retval = SHFileOperationA(&shfo);
1896 ok(retval == ERROR_SUCCESS, "File copy failed with %d\n", retval);
1897 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1898 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
1900 /* Check last error after a failed file operation. */
1901 clean_after_shfo_tests();
1902 init_shfo_tests();
1903 shfo.pFrom = "nonexistent\0";
1904 shfo.pTo = "testdir2\0";
1905 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1906 SetLastError(0xdeadbeef);
1907 retval = SHFileOperationA(&shfo);
1908 ok(retval != ERROR_SUCCESS, "Unexpected ERROR_SUCCESS\n");
1909 ok(!shfo.fAnyOperationsAborted, "Didn't expect aborted operations\n");
1910 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", GetLastError());
1913 /* tests the FO_MOVE action */
1914 static void test_move(void)
1916 SHFILEOPSTRUCTA shfo, shfo2;
1917 CHAR from[5*MAX_PATH];
1918 CHAR to[5*MAX_PATH];
1919 DWORD retval;
1921 clean_after_shfo_tests();
1922 init_shfo_tests();
1924 shfo.hwnd = NULL;
1925 shfo.wFunc = FO_MOVE;
1926 shfo.pFrom = from;
1927 shfo.pTo = to;
1928 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR;
1929 shfo.hNameMappings = NULL;
1930 shfo.lpszProgressTitle = NULL;
1931 shfo.fAnyOperationsAborted = FALSE;
1933 set_curr_dir_path(from, "testdir2\\*.*\0");
1934 set_curr_dir_path(to, "test4.txt\\*.*\0");
1935 retval = SHFileOperationA(&shfo);
1936 ok(retval != 0, "SHFileOperation should fail\n");
1937 ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
1939 ok(file_exists("testdir2"), "dir should not be moved\n");
1940 ok(file_exists("testdir2\\one.txt"), "file should not be moved\n");
1941 ok(file_exists("testdir2\\nested"), "dir should not be moved\n");
1942 ok(file_exists("testdir2\\nested\\two.txt"), "file should not be moved\n");
1944 set_curr_dir_path(from, "testdir2\\*.*\0");
1945 set_curr_dir_path(to, "test4.txt\0");
1946 retval = SHFileOperationA(&shfo);
1947 ok(!retval, "SHFileOperation error %#x\n", retval);
1948 ok(!shfo.fAnyOperationsAborted, "fAnyOperationsAborted %d\n", shfo.fAnyOperationsAborted);
1950 ok(file_exists("testdir2"), "dir should not be moved\n");
1951 ok(!file_exists("testdir2\\one.txt"), "file should be moved\n");
1952 ok(!file_exists("testdir2\\nested"), "dir should be moved\n");
1953 ok(!file_exists("testdir2\\nested\\two.txt"), "file should be moved\n");
1955 ok(file_exists("test4.txt"), "dir should exist\n");
1956 ok(file_exists("test4.txt\\one.txt"), "file should exist\n");
1957 ok(file_exists("test4.txt\\nested"), "dir should exist\n");
1958 ok(file_exists("test4.txt\\nested\\two.txt"), "file should exist\n");
1960 clean_after_shfo_tests();
1961 init_shfo_tests();
1963 shfo.hwnd = NULL;
1964 shfo.wFunc = FO_MOVE;
1965 shfo.pFrom = from;
1966 shfo.pTo = to;
1967 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
1968 shfo.hNameMappings = NULL;
1969 shfo.lpszProgressTitle = NULL;
1971 set_curr_dir_path(from, "test1.txt\0");
1972 set_curr_dir_path(to, "test4.txt\0");
1973 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
1974 ok(!file_exists("test1.txt"), "test1.txt should not exist\n");
1975 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
1977 set_curr_dir_path(from, "test?.txt\0");
1978 set_curr_dir_path(to, "testdir2\0");
1979 ok(!file_exists("testdir2\\test2.txt"), "The file is not moved yet\n");
1980 ok(!file_exists("testdir2\\test4.txt"), "The directory is not moved yet\n");
1981 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
1982 ok(file_exists("testdir2\\test2.txt"), "The file is moved\n");
1983 ok(file_exists("testdir2\\test4.txt"), "The directory is moved\n");
1984 ok(file_exists("testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
1986 clean_after_shfo_tests();
1987 init_shfo_tests();
1989 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
1990 shfo2.fFlags |= FOF_MULTIDESTFILES;
1992 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
1993 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
1994 if (old_shell32)
1995 shfo2.fFlags |= FOF_NOCONFIRMMKDIR;
1996 ok(!SHFileOperationA(&shfo2), "Move many files\n");
1997 ok(DeleteFileA("test6.txt"), "The file is not moved - many files are "
1998 "specified as a target\n");
1999 ok(DeleteFileA("test7.txt"), "The file is not moved\n");
2000 ok(RemoveDirectoryA("test8.txt"), "The directory is not moved\n");
2002 init_shfo_tests();
2004 /* number of sources does not correspond to number of targets,
2005 include directories */
2006 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
2007 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
2008 retval = SHFileOperationA(&shfo2);
2009 if (dir_exists("test6.txt"))
2011 if (retval == ERROR_SUCCESS)
2013 /* Old shell32 */
2014 DeleteFileA("test6.txt\\test1.txt");
2015 DeleteFileA("test6.txt\\test2.txt");
2016 RemoveDirectoryA("test6.txt\\test4.txt");
2017 RemoveDirectoryA("test6.txt");
2019 else
2021 /* Vista and W2K8 (broken or new behavior ?) */
2022 ok(retval == DE_DESTSAMETREE, "Expected DE_DESTSAMETREE, got %d\n", retval);
2023 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved\n");
2024 RemoveDirectoryA("test6.txt");
2025 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not moved\n");
2026 RemoveDirectoryA("test7.txt");
2029 else
2031 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2032 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2033 "specified as a target\n");
2036 init_shfo_tests();
2037 /* number of sources does not correspond to number of targets,
2038 files only,
2039 from exceeds to */
2040 set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0");
2041 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
2042 retval = SHFileOperationA(&shfo2);
2043 if (dir_exists("test6.txt"))
2045 if (retval == ERROR_SUCCESS)
2047 /* Old shell32 */
2048 DeleteFileA("test6.txt\\test1.txt");
2049 DeleteFileA("test6.txt\\test2.txt");
2050 RemoveDirectoryA("test6.txt\\test4.txt");
2051 RemoveDirectoryA("test6.txt");
2053 else
2055 /* Vista and W2K8 (broken or new behavior ?) */
2056 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
2057 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved\n");
2058 RemoveDirectoryA("test6.txt");
2059 ok(DeleteFileA("test7.txt\\test2.txt"), "The file is not moved\n");
2060 RemoveDirectoryA("test7.txt");
2061 ok(file_exists("test3.txt"), "File should not be moved\n");
2064 else
2066 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2067 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2068 "specified as a target\n");
2071 init_shfo_tests();
2072 /* number of sources does not correspond to number of targets,
2073 files only,
2074 too exceeds from */
2075 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
2076 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
2077 retval = SHFileOperationA(&shfo2);
2078 if (dir_exists("test6.txt"))
2080 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2081 ok(DeleteFileA("test6.txt\\test1.txt"),"The file is not moved\n");
2082 ok(DeleteFileA("test7.txt\\test2.txt"),"The file is not moved\n");
2083 ok(!dir_exists("test8.txt") && !file_exists("test8.txt"),
2084 "Directory should not be created\n");
2085 RemoveDirectoryA("test6.txt");
2086 RemoveDirectoryA("test7.txt");
2088 else
2090 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* WinXp, Win2k */);
2091 ok(!file_exists("test6.txt"), "The file is not moved - many files are "
2092 "specified as a target\n");
2095 init_shfo_tests();
2096 /* number of sources does not correspond to number of targets,
2097 target directories */
2098 set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0");
2099 set_curr_dir_path(to, "test4.txt\0test5.txt\0");
2100 retval = SHFileOperationA(&shfo2);
2101 if (dir_exists("test5.txt"))
2103 ok(retval == DE_SAMEFILE, "Expected DE_SAMEFILE, got %d\n", retval);
2104 ok(DeleteFileA("test4.txt\\test1.txt"),"The file is not moved\n");
2105 ok(DeleteFileA("test5.txt\\test2.txt"),"The file is not moved\n");
2106 ok(file_exists("test3.txt"), "The file is not moved\n");
2107 RemoveDirectoryA("test4.txt");
2108 RemoveDirectoryA("test5.txt");
2110 else
2112 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2113 ok(DeleteFileA("test4.txt\\test1.txt"),"The file is not moved\n");
2114 ok(DeleteFileA("test4.txt\\test2.txt"),"The file is not moved\n");
2115 ok(DeleteFileA("test4.txt\\test3.txt"),"The file is not moved\n");
2119 init_shfo_tests();
2120 /* 0 incoming files */
2121 set_curr_dir_path(from, "\0\0");
2122 set_curr_dir_path(to, "test6.txt\0\0");
2123 retval = SHFileOperationA(&shfo2);
2124 ok(retval == ERROR_SUCCESS || retval == ERROR_ACCESS_DENIED
2125 , "Expected ERROR_SUCCESS || ERROR_ACCESS_DENIED, got %d\n", retval);
2126 ok(!file_exists("test6.txt"), "The file should not exist\n");
2128 init_shfo_tests();
2129 /* 0 outgoing files */
2130 set_curr_dir_path(from, "test1\0\0");
2131 set_curr_dir_path(to, "\0\0");
2132 retval = SHFileOperationA(&shfo2);
2133 ok(retval == ERROR_FILE_NOT_FOUND ||
2134 broken(retval == 1026)
2135 , "Expected ERROR_FILE_NOT_FOUND, got %d\n", retval);
2136 ok(!file_exists("test6.txt"), "The file should not exist\n");
2138 init_shfo_tests();
2140 set_curr_dir_path(from, "test3.txt\0");
2141 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
2142 ok(!SHFileOperationA(&shfo), "Can't move file to other directory\n");
2143 ok(file_exists("test4.txt\\test1.txt"), "The file is not moved\n");
2145 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
2146 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
2147 if (old_shell32)
2148 shfo.fFlags |= FOF_NOCONFIRMMKDIR;
2149 retval = SHFileOperationA(&shfo);
2150 if (dir_exists("test6.txt"))
2152 /* Old shell32 */
2153 /* Vista and W2K8 (broken or new behavior ?) */
2154 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2155 ok(DeleteFileA("test6.txt\\test1.txt"), "The file is not moved. Many files are specified\n");
2156 ok(DeleteFileA("test6.txt\\test2.txt"), "The file is not moved. Many files are specified\n");
2157 ok(DeleteFileA("test6.txt\\test4.txt\\test1.txt"), "The file is not moved. Many files are specified\n");
2158 ok(RemoveDirectoryA("test6.txt\\test4.txt"), "The directory is not moved. Many files are specified\n");
2159 RemoveDirectoryA("test6.txt");
2160 init_shfo_tests();
2162 else
2164 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2165 ok(file_exists("test1.txt"), "The file is moved. Many files are specified\n");
2166 ok(dir_exists("test4.txt"), "The directory is moved. Many files are specified\n");
2169 set_curr_dir_path(from, "test1.txt\0");
2170 set_curr_dir_path(to, "test6.txt\0");
2171 ok(!SHFileOperationA(&shfo), "Move file failed\n");
2172 ok(!file_exists("test1.txt"), "The file is not moved\n");
2173 ok(file_exists("test6.txt"), "The file is not moved\n");
2174 set_curr_dir_path(from, "test6.txt\0");
2175 set_curr_dir_path(to, "test1.txt\0");
2176 ok(!SHFileOperationA(&shfo), "Move file back failed\n");
2178 set_curr_dir_path(from, "test4.txt\0");
2179 set_curr_dir_path(to, "test6.txt\0");
2180 ok(!SHFileOperationA(&shfo), "Move dir failed\n");
2181 ok(!dir_exists("test4.txt"), "The dir is not moved\n");
2182 ok(dir_exists("test6.txt"), "The dir is moved\n");
2183 set_curr_dir_path(from, "test6.txt\0");
2184 set_curr_dir_path(to, "test4.txt\0");
2185 ok(!SHFileOperationA(&shfo), "Move dir back failed\n");
2187 /* move one file to two others */
2188 init_shfo_tests();
2189 shfo.pFrom = "test1.txt\0";
2190 shfo.pTo = "a.txt\0b.txt\0";
2191 retval = SHFileOperationA(&shfo);
2192 if (retval == DE_OPCANCELLED)
2194 /* NT4 fails and doesn't move any files */
2195 ok(!file_exists("a.txt"), "Expected a.txt to not exist\n");
2196 DeleteFileA("test1.txt");
2198 else
2200 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2201 if (old_shell32)
2203 DeleteFileA("a.txt\\a.txt");
2204 RemoveDirectoryA("a.txt");
2206 else
2207 ok(DeleteFileA("a.txt"), "Expected a.txt to exist\n");
2208 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
2210 ok(!file_exists("b.txt"), "Expected b.txt to not exist\n");
2212 /* move two files to one other */
2213 shfo.pFrom = "test2.txt\0test3.txt\0";
2214 shfo.pTo = "test1.txt\0";
2215 retval = SHFileOperationA(&shfo);
2216 if (dir_exists("test1.txt"))
2218 /* Old shell32 */
2219 /* Vista and W2K8 (broken or new behavior ?) */
2220 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2221 ok(DeleteFileA("test1.txt\\test2.txt"), "Expected test1.txt\\test2.txt to exist\n");
2222 ok(DeleteFileA("test1.txt\\test3.txt"), "Expected test1.txt\\test3.txt to exist\n");
2223 RemoveDirectoryA("test1.txt");
2224 createTestFile("test2.txt");
2225 createTestFile("test3.txt");
2227 else
2229 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2230 ok(!file_exists("test1.txt"), "Expected test1.txt to not exist\n");
2231 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
2232 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
2235 /* move a directory into itself */
2236 shfo.pFrom = "test4.txt\0";
2237 shfo.pTo = "test4.txt\\b.txt\0";
2238 retval = SHFileOperationA(&shfo);
2239 ok(retval == ERROR_SUCCESS ||
2240 retval == DE_DESTSUBTREE, /* Vista */
2241 "Expected ERROR_SUCCESS or DE_DESTSUBTREE, got %d\n", retval);
2242 ok(!RemoveDirectoryA("test4.txt\\b.txt"), "Expected test4.txt\\b.txt to not exist\n");
2243 ok(dir_exists("test4.txt"), "Expected test4.txt to exist\n");
2245 /* move many files without FOF_MULTIDESTFILES */
2246 shfo.pFrom = "test2.txt\0test3.txt\0";
2247 shfo.pTo = "d.txt\0e.txt\0";
2248 retval = SHFileOperationA(&shfo);
2249 if (dir_exists("d.txt"))
2251 /* Old shell32 */
2252 /* Vista and W2K8 (broken or new behavior ?) */
2253 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2254 ok(DeleteFileA("d.txt\\test2.txt"), "Expected d.txt\\test2.txt to exist\n");
2255 ok(DeleteFileA("d.txt\\test3.txt"), "Expected d.txt\\test3.txt to exist\n");
2256 RemoveDirectoryA("d.txt");
2257 createTestFile("test2.txt");
2258 createTestFile("test3.txt");
2260 else
2262 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2263 ok(!DeleteFileA("d.txt"), "Expected d.txt to not exist\n");
2264 ok(!DeleteFileA("e.txt"), "Expected e.txt to not exist\n");
2267 /* number of sources != number of targets */
2268 shfo.pTo = "d.txt\0";
2269 shfo.fFlags |= FOF_MULTIDESTFILES;
2270 retval = SHFileOperationA(&shfo);
2271 if (dir_exists("d.txt"))
2273 if (old_shell32)
2275 DeleteFileA("d.txt\\test2.txt");
2276 DeleteFileA("d.txt\\test3.txt");
2277 RemoveDirectoryA("d.txt");
2278 createTestFile("test2.txt");
2280 else
2282 /* Vista and W2K8 (broken or new behavior ?) */
2283 ok(retval == DE_SAMEFILE,
2284 "Expected DE_SAMEFILE, got %d\n", retval);
2285 ok(DeleteFileA("d.txt\\test2.txt"), "Expected d.txt\\test2.txt to exist\n");
2286 ok(!file_exists("d.txt\\test3.txt"), "Expected d.txt\\test3.txt to not exist\n");
2287 RemoveDirectoryA("d.txt");
2288 createTestFile("test2.txt");
2291 else
2293 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2294 ok(!DeleteFileA("d.txt"), "Expected d.txt to not exist\n");
2297 /* FO_MOVE does not create dest directories */
2298 shfo.pFrom = "test2.txt\0";
2299 shfo.pTo = "dir1\\dir2\\test2.txt\0";
2300 retval = SHFileOperationA(&shfo);
2301 if (dir_exists("dir1"))
2303 /* Vista and W2K8 (broken or new behavior ?) */
2304 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2305 ok(DeleteFileA("dir1\\dir2\\test2.txt"), "Expected dir1\\dir2\\test2.txt to exist\n");
2306 RemoveDirectoryA("dir1\\dir2");
2307 RemoveDirectoryA("dir1");
2308 createTestFile("test2.txt");
2310 else
2312 expect_retval(ERROR_CANCELLED, DE_OPCANCELLED /* Win9x, NT4 */);
2315 /* try to overwrite an existing file */
2316 shfo.pTo = "test3.txt\0";
2317 retval = SHFileOperationA(&shfo);
2318 if (retval == DE_OPCANCELLED)
2320 /* NT4 fails and doesn't move any files */
2321 ok(file_exists("test2.txt"), "Expected test2.txt to exist\n");
2323 else
2325 ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval);
2326 ok(!file_exists("test2.txt"), "Expected test2.txt to not exist\n");
2327 if (old_shell32)
2329 DeleteFileA("test3.txt\\test3.txt");
2330 RemoveDirectoryA("test3.txt");
2332 else
2333 ok(file_exists("test3.txt"), "Expected test3.txt to exist\n");
2337 static void test_sh_create_dir(void)
2339 CHAR path[MAX_PATH];
2340 int ret;
2342 if(!pSHCreateDirectoryExA)
2344 win_skip("skipping SHCreateDirectoryExA tests\n");
2345 return;
2348 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2349 ret = pSHCreateDirectoryExA(NULL, path, NULL);
2350 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
2351 ok(file_exists("testdir2"), "The first directory is not created\n");
2352 ok(file_exists("testdir2\\test4.txt"), "The second directory is not created\n");
2354 ret = pSHCreateDirectoryExA(NULL, path, NULL);
2355 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
2357 ret = pSHCreateDirectoryExA(NULL, "c:\\testdir3", NULL);
2358 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory, ret = %d\n", ret);
2359 ok(file_exists("c:\\testdir3"), "The directory is not created\n");
2362 static void test_sh_path_prepare(void)
2364 HRESULT res;
2365 CHAR path[MAX_PATH];
2366 CHAR UNICODE_PATH_A[MAX_PATH];
2367 BOOL UsedDefaultChar;
2369 if(!pSHPathPrepareForWriteA)
2371 win_skip("skipping SHPathPrepareForWriteA tests\n");
2372 return;
2375 /* directory exists, SHPPFW_NONE */
2376 set_curr_dir_path(path, "testdir2\0");
2377 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2378 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2380 /* directory exists, SHPPFW_IGNOREFILENAME */
2381 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2382 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
2383 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2385 /* directory exists, SHPPFW_DIRCREATE */
2386 set_curr_dir_path(path, "testdir2\0");
2387 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
2388 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2390 /* directory exists, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE */
2391 set_curr_dir_path(path, "testdir2\\test4.txt\0");
2392 res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
2393 ok(res == S_OK, "res == 0x%08x, 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 = pSHPathPrepareForWriteA(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%08x\n", res);
2404 /* file exists, SHPPFW_DIRCREATE */
2405 res = pSHPathPrepareForWriteA(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%08x\n", res);
2411 /* file exists, SHPPFW_NONE, trailing \ */
2412 set_curr_dir_path(path, "test1.txt\\\0");
2413 res = pSHPathPrepareForWriteA(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%08x\n", res);
2419 /* relative path exists, SHPPFW_DIRCREATE */
2420 res = pSHPathPrepareForWriteA(0, 0, ".\\testdir2", SHPPFW_DIRCREATE);
2421 ok(res == S_OK, "res == 0x%08x, expected S_OK\n", res);
2423 /* relative path doesn't exist, SHPPFW_DIRCREATE -- Windows does not create the directory in this case */
2424 res = pSHPathPrepareForWriteA(0, 0, ".\\testdir2\\test4.txt", SHPPFW_DIRCREATE);
2425 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, 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 = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE);
2431 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, 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 = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME);
2436 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == 0x%08x, 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 = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_IGNOREFILENAME|SHPPFW_DIRCREATE);
2443 ok(res == S_OK, "res == 0x%08x, 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 = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE);
2449 ok(res == S_OK, "res == 0x%08x, 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 if(!pSHPathPrepareForWriteW)
2456 win_skip("Skipping SHPathPrepareForWriteW tests\n");
2457 return;
2460 SetLastError(0xdeadbeef);
2461 UsedDefaultChar = FALSE;
2462 if (WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, UNICODE_PATH, -1, UNICODE_PATH_A, sizeof(UNICODE_PATH_A), NULL, &UsedDefaultChar) == 0)
2464 win_skip("Could not convert Unicode path name to multibyte (%d)\n", GetLastError());
2465 return;
2467 if (UsedDefaultChar)
2469 win_skip("Could not find unique multibyte representation for directory name using default codepage\n");
2470 return;
2473 /* unicode directory doesn't exist, SHPPFW_NONE */
2474 RemoveDirectoryA(UNICODE_PATH_A);
2475 res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
2476 ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == %08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res);
2477 ok(!file_exists(UNICODE_PATH_A), "unicode path was created but shouldn't be\n");
2478 RemoveDirectoryA(UNICODE_PATH_A);
2480 /* unicode directory doesn't exist, SHPPFW_DIRCREATE */
2481 res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
2482 ok(res == S_OK, "res == %08x, expected S_OK\n", res);
2483 ok(file_exists(UNICODE_PATH_A), "unicode path should've been created\n");
2485 /* unicode directory exists, SHPPFW_NONE */
2486 res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE);
2487 ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
2489 /* unicode directory exists, SHPPFW_DIRCREATE */
2490 res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE);
2491 ok(res == S_OK, "ret == %08x, expected S_OK\n", res);
2492 RemoveDirectoryA(UNICODE_PATH_A);
2495 static void test_sh_new_link_info(void)
2497 BOOL ret, mustcopy=TRUE;
2498 CHAR linkto[MAX_PATH];
2499 CHAR destdir[MAX_PATH];
2500 CHAR result[MAX_PATH];
2501 CHAR result2[MAX_PATH];
2503 /* source file does not exist */
2504 set_curr_dir_path(linkto, "nosuchfile.txt\0");
2505 set_curr_dir_path(destdir, "testdir2\0");
2506 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2507 ok(ret == FALSE ||
2508 broken(ret == lstrlenA(result) + 1), /* NT4 */
2509 "SHGetNewLinkInfoA succeeded\n");
2510 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2512 /* dest dir does not exist */
2513 set_curr_dir_path(linkto, "test1.txt\0");
2514 set_curr_dir_path(destdir, "nosuchdir\0");
2515 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2516 ok(ret == TRUE ||
2517 broken(ret == lstrlenA(result) + 1), /* NT4 */
2518 "SHGetNewLinkInfoA failed, err=%i\n", GetLastError());
2519 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2521 /* source file exists */
2522 set_curr_dir_path(linkto, "test1.txt\0");
2523 set_curr_dir_path(destdir, "testdir2\0");
2524 ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0);
2525 ok(ret == TRUE ||
2526 broken(ret == lstrlenA(result) + 1), /* NT4 */
2527 "SHGetNewLinkInfoA failed, err=%i\n", GetLastError());
2528 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2529 ok(CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, destdir,
2530 lstrlenA(destdir), result, lstrlenA(destdir)) == CSTR_EQUAL,
2531 "%s does not start with %s\n", result, destdir);
2532 ok(lstrlenA(result) > 4 && lstrcmpiA(result+lstrlenA(result)-4, ".lnk") == 0,
2533 "%s does not end with .lnk\n", result);
2535 /* preferred target name already exists */
2536 createTestFile(result);
2537 ret = SHGetNewLinkInfoA(linkto, destdir, result2, &mustcopy, 0);
2538 ok(ret == TRUE ||
2539 broken(ret == lstrlenA(result2) + 1), /* NT4 */
2540 "SHGetNewLinkInfoA failed, err=%i\n", GetLastError());
2541 ok(mustcopy == FALSE, "mustcopy should be FALSE\n");
2542 ok(CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, destdir,
2543 lstrlenA(destdir), result2, lstrlenA(destdir)) == CSTR_EQUAL,
2544 "%s does not start with %s\n", result2, destdir);
2545 ok(lstrlenA(result2) > 4 && lstrcmpiA(result2+lstrlenA(result2)-4, ".lnk") == 0,
2546 "%s does not end with .lnk\n", result2);
2547 ok(lstrcmpiA(result, result2) != 0, "%s and %s are the same\n", result, result2);
2548 DeleteFileA(result);
2551 static void test_unicode(void)
2553 SHFILEOPSTRUCTW shfoW;
2554 int ret;
2555 HANDLE file;
2556 static const WCHAR UNICODE_PATH_TO[] = {'c',':','\\',0x00ae,0x00ae,'\0'};
2558 if (!pSHFileOperationW)
2560 skip("SHFileOperationW() is missing\n");
2561 return;
2564 shfoW.hwnd = NULL;
2565 shfoW.wFunc = FO_DELETE;
2566 shfoW.pFrom = UNICODE_PATH;
2567 shfoW.pTo = NULL;
2568 shfoW.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
2569 shfoW.hNameMappings = NULL;
2570 shfoW.lpszProgressTitle = NULL;
2572 /* Clean up before start test */
2573 DeleteFileW(UNICODE_PATH);
2574 RemoveDirectoryW(UNICODE_PATH);
2576 /* Make sure we are on a system that supports unicode */
2577 SetLastError(0xdeadbeef);
2578 file = CreateFileW(UNICODE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
2579 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
2581 skip("Unicode tests skipped on non-unicode system\n");
2582 return;
2584 if (GetLastError()==ERROR_ACCESS_DENIED)
2586 skip("test needs admin rights\n");
2587 return;
2589 CloseHandle(file);
2591 /* Try to delete a file with unicode filename */
2592 ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
2593 ret = pSHFileOperationW(&shfoW);
2594 ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
2595 ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
2597 /* Try to trash a file with unicode filename */
2598 createTestFileW(UNICODE_PATH);
2599 shfoW.fFlags |= FOF_ALLOWUNDO;
2600 ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
2601 ret = pSHFileOperationW(&shfoW);
2602 ok(!ret, "File is not removed, ErrorCode: %d\n", ret);
2603 ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
2605 if(!pSHCreateDirectoryExW)
2607 skip("Skipping SHCreateDirectoryExW tests\n");
2608 return;
2611 /* Try to delete a directory with unicode filename */
2612 ret = pSHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
2613 ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
2614 ok(file_existsW(UNICODE_PATH), "The directory is not created\n");
2615 shfoW.fFlags &= ~FOF_ALLOWUNDO;
2616 ret = pSHFileOperationW(&shfoW);
2617 ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
2618 ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
2620 /* Try to trash a directory with unicode filename */
2621 ret = pSHCreateDirectoryExW(NULL, UNICODE_PATH, NULL);
2622 ok(!ret, "SHCreateDirectoryExW returned %d\n", ret);
2623 ok(file_existsW(UNICODE_PATH), "The directory was not created\n");
2624 shfoW.fFlags |= FOF_ALLOWUNDO;
2625 ret = pSHFileOperationW(&shfoW);
2626 ok(!ret, "Directory is not removed, ErrorCode: %d\n", ret);
2627 ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
2629 shfoW.hwnd = NULL;
2630 shfoW.wFunc = FO_COPY;
2631 shfoW.pFrom = UNICODE_PATH;
2632 shfoW.pTo = UNICODE_PATH_TO;
2633 shfoW.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
2634 shfoW.hNameMappings = NULL;
2635 shfoW.lpszProgressTitle = NULL;
2637 /* Check last error after a successful file operation. */
2638 createTestFileW(UNICODE_PATH);
2639 ok(file_existsW(UNICODE_PATH), "The file does not exist\n");
2640 SetLastError(0xdeadbeef);
2641 ret = SHFileOperationW(&shfoW);
2642 ok(ret == ERROR_SUCCESS, "File copy failed with %d\n", ret);
2643 ok(!shfoW.fAnyOperationsAborted, "Didn't expect aborted operations\n");
2644 ok(GetLastError() == ERROR_SUCCESS ||
2645 broken(GetLastError() == ERROR_INVALID_HANDLE), /* WinXp, win2k3 */
2646 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
2647 DeleteFileW(UNICODE_PATH_TO);
2649 /* Check last error after a failed file operation. */
2650 DeleteFileW(UNICODE_PATH);
2651 ok(!file_existsW(UNICODE_PATH), "The file should have been removed\n");
2652 SetLastError(0xdeadbeef);
2653 ret = SHFileOperationW(&shfoW);
2654 ok(ret != ERROR_SUCCESS, "Unexpected ERROR_SUCCESS\n");
2655 ok(!shfoW.fAnyOperationsAborted, "Didn't expect aborted operations\n");
2656 ok(GetLastError() == ERROR_SUCCESS ||
2657 broken(GetLastError() == ERROR_INVALID_HANDLE), /* WinXp, win2k3 */
2658 "Expected ERROR_SUCCESS, got %d\n", GetLastError());
2661 static void
2662 test_shlmenu(void) {
2663 HRESULT hres;
2664 hres = Shell_MergeMenus (0, 0, 0x42, 0x4242, 0x424242, 0);
2665 ok (hres == 0x4242, "expected 0x4242 but got %x\n", hres);
2666 hres = Shell_MergeMenus ((HMENU)42, 0, 0x42, 0x4242, 0x424242, 0);
2667 ok (hres == 0x4242, "expected 0x4242 but got %x\n", hres);
2670 /* Check for old shell32 (4.0.x) */
2671 static BOOL is_old_shell32(void)
2673 SHFILEOPSTRUCTA shfo;
2674 CHAR from[5*MAX_PATH];
2675 CHAR to[5*MAX_PATH];
2676 DWORD retval;
2678 shfo.hwnd = NULL;
2679 shfo.wFunc = FO_COPY;
2680 shfo.pFrom = from;
2681 shfo.pTo = to;
2682 /* FOF_NOCONFIRMMKDIR is needed for old shell32 */
2683 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI | FOF_MULTIDESTFILES | FOF_NOCONFIRMMKDIR;
2684 shfo.hNameMappings = NULL;
2685 shfo.lpszProgressTitle = NULL;
2687 set_curr_dir_path(from, "test1.txt\0test2.txt\0test3.txt\0");
2688 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
2689 retval = SHFileOperationA(&shfo);
2691 /* Delete extra files on old shell32 and Vista+*/
2692 DeleteFileA("test6.txt\\test1.txt");
2693 /* Delete extra files on old shell32 */
2694 DeleteFileA("test6.txt\\test2.txt");
2695 DeleteFileA("test6.txt\\test3.txt");
2696 /* Delete extra directory on old shell32 and Vista+ */
2697 RemoveDirectoryA("test6.txt");
2698 /* Delete extra files/directories on Vista+*/
2699 DeleteFileA("test7.txt\\test2.txt");
2700 RemoveDirectoryA("test7.txt");
2702 if (retval == ERROR_SUCCESS)
2703 return TRUE;
2705 return FALSE;
2708 START_TEST(shlfileop)
2710 InitFunctionPointers();
2712 clean_after_shfo_tests();
2714 init_shfo_tests();
2715 old_shell32 = is_old_shell32();
2716 if (old_shell32)
2717 win_skip("Need to cater for old shell32 (4.0.x) on Win95\n");
2718 clean_after_shfo_tests();
2720 init_shfo_tests();
2721 test_get_file_info();
2722 test_get_file_info_iconlist();
2723 clean_after_shfo_tests();
2725 init_shfo_tests();
2726 test_delete();
2727 clean_after_shfo_tests();
2729 init_shfo_tests();
2730 test_rename();
2731 clean_after_shfo_tests();
2733 init_shfo_tests();
2734 test_copy();
2735 clean_after_shfo_tests();
2737 init_shfo_tests();
2738 test_move();
2739 clean_after_shfo_tests();
2741 test_sh_create_dir();
2742 clean_after_shfo_tests();
2744 init_shfo_tests();
2745 test_sh_path_prepare();
2746 clean_after_shfo_tests();
2748 init_shfo_tests();
2749 test_sh_new_link_info();
2750 clean_after_shfo_tests();
2752 test_unicode();
2754 test_shlmenu();