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