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