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