Removed W->A from DEFWND_ImmIsUIMessageW.
[wine] / dlls / shell32 / tests / shlfileop.c
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define WINE_NOWINSOCK
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wtypes.h"
28 #include "shellapi.h"
29 #include "shlobj.h"
30
31 #include "wine/test.h"
32
33 CHAR CURR_DIR[MAX_PATH];
34
35 /* creates a file with the specified name for tests */
36 void createTestFile(CHAR *name)
37 {
38     HANDLE file;
39     DWORD written;
40
41     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
42     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
43     WriteFile(file, name, strlen(name), &written, NULL);
44     WriteFile(file, "\n", strlen("\n"), &written, NULL);
45     CloseHandle(file);
46 }
47
48 BOOL file_exists(CHAR *name)
49 {
50     return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
51 }
52
53 /* initializes the tests */
54 void init_shfo_tests(void)
55 {
56     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
57     createTestFile(".\\test1.txt");
58     createTestFile(".\\test2.txt");
59     createTestFile(".\\test3.txt");
60     CreateDirectoryA(".\\test4.txt", NULL);
61     CreateDirectoryA(".\\testdir2", NULL);
62 }
63
64 /* cleans after tests */
65 void clean_after_shfo_tests(void)
66 {
67     DeleteFileA(".\\test1.txt");
68     DeleteFileA(".\\test2.txt");
69     DeleteFileA(".\\test3.txt");
70     DeleteFileA(".\\test4.txt\\test1.txt");
71     DeleteFileA(".\\test4.txt\\test2.txt");
72     DeleteFileA(".\\test4.txt\\test3.txt");
73     RemoveDirectoryA(".\\test4.txt");
74     DeleteFileA(".\\testdir2\\test1.txt");
75     DeleteFileA(".\\testdir2\\test2.txt");
76     DeleteFileA(".\\testdir2\\test3.txt");
77     DeleteFileA(".\\testdir2\\test4.txt\\test1.txt");
78     RemoveDirectoryA(".\\testdir2\\test4.txt");
79     RemoveDirectoryA(".\\testdir2");
80 }
81
82 /*
83  puts into the specified buffer file names with current directory.
84  files - string with file names, separated by null characters. Ends on a double
85  null characters
86 */
87 void set_curr_dir_path(CHAR *buf, CHAR* files)
88 {
89     buf[0] = 0;
90     while (files[0])
91     {
92         strcpy(buf, CURR_DIR);
93         buf += strlen(buf);
94         buf[0] = '\\';
95         buf++;
96         strcpy(buf, files);
97         buf += strlen(buf) + 1;
98         files += strlen(files) + 1;
99     }
100     buf[0] = 0;
101 }
102
103
104 /* tests the FO_DELETE action */
105 void test_delete(void)
106 {
107     SHFILEOPSTRUCTA shfo;
108     DWORD ret;
109     CHAR buf[MAX_PATH];
110
111     sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
112     buf[strlen(buf) + 1] = '\0';
113
114     shfo.hwnd = NULL;
115     shfo.wFunc = FO_DELETE;
116     shfo.pFrom = buf;
117     shfo.pTo = "\0";
118     shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
119     shfo.hNameMappings = NULL;
120     shfo.lpszProgressTitle = NULL;
121
122     ok(!SHFileOperationA(&shfo), "Deletion was successful\n");
123     ok(file_exists(".\\test4.txt"), "Directory should not be removed\n");
124     ok(!file_exists(".\\test1.txt"), "File should be removed\n");
125
126     ret = SHFileOperationA(&shfo);
127     ok(!ret, "Directory exists, but is not removed, ret=%ld\n", ret);
128     ok(file_exists(".\\test4.txt"), "Directory should not be removed\n");
129
130     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
131
132     ok(!SHFileOperationA(&shfo), "Directory removed\n");
133     ok(!file_exists(".\\test4.txt"), "Directory should be removed\n");
134
135     ret = SHFileOperationA(&shfo);
136     ok(!ret, "The requested file does not exist, ret=%ld\n", ret);
137
138     init_shfo_tests();
139     sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
140     buf[strlen(buf) + 1] = '\0';
141     ok(MoveFileA(".\\test1.txt", ".\\test4.txt\\test1.txt"), "Fill the subdirectory\n");
142     ok(!SHFileOperationA(&shfo), "Directory removed\n");
143     ok(!file_exists(".\\test4.txt"), "Directory is removed\n");
144
145     init_shfo_tests();
146     shfo.pFrom = ".\\test1.txt\0.\\test4.txt\0";
147     ok(!SHFileOperationA(&shfo), "Directory and a file removed\n");
148     ok(!file_exists(".\\test1.txt"), "The file should be removed\n");
149     ok(!file_exists(".\\test4.txt"), "Directory should be removed\n");
150     ok(file_exists(".\\test2.txt"), "This file should not be removed\n");
151 }
152
153 /* tests the FO_RENAME action */
154 void test_rename()
155 {
156     SHFILEOPSTRUCTA shfo, shfo2;
157     CHAR from[MAX_PATH];
158     CHAR to[MAX_PATH];
159     DWORD retval;
160
161     shfo.hwnd = NULL;
162     shfo.wFunc = FO_RENAME;
163     shfo.pFrom = from;
164     shfo.pTo = to;
165     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
166     shfo.hNameMappings = NULL;
167     shfo.lpszProgressTitle = NULL;
168
169     set_curr_dir_path(from, "test1.txt\0");
170     set_curr_dir_path(to, "test4.txt\0");
171     ok(SHFileOperationA(&shfo), "File is not renamed moving to other directory "
172        "when specifying directory name only\n");
173     ok(file_exists(".\\test1.txt"), "The file is not removed\n");
174
175     set_curr_dir_path(from, "test3.txt\0");
176     set_curr_dir_path(to, "test4.txt\\test1.txt\0");
177     ok(!SHFileOperationA(&shfo), "File is renamed moving to other directory\n");
178     ok(file_exists(".\\test4.txt\\test1.txt"), "The file is renamed\n");
179
180     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
181     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
182     retval = SHFileOperationA(&shfo); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
183     ok(!retval || retval == ERROR_GEN_FAILURE, "Can't rename many files, retval = %lx\n", retval);
184     ok(file_exists(".\\test1.txt"), "The file is not renamed - many files are specified\n");
185
186     memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
187     shfo2.fFlags |= FOF_MULTIDESTFILES;
188
189     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
190     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
191     retval = SHFileOperationA(&shfo2); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
192     ok(!retval || retval == ERROR_GEN_FAILURE, "Can't rename many files, retval = %lx\n", retval);
193     ok(file_exists(".\\test1.txt"), "The file is not renamed - many files are specified\n");
194
195     set_curr_dir_path(from, "test1.txt\0");
196     set_curr_dir_path(to, "test6.txt\0");
197     ok(!SHFileOperationA(&shfo), "Rename file\n");
198     ok(!file_exists(".\\test1.txt"), "The file is renamed\n");
199     ok(file_exists(".\\test6.txt"), "The file is renamed\n");
200     set_curr_dir_path(from, "test6.txt\0");
201     set_curr_dir_path(to, "test1.txt\0");
202     ok(!SHFileOperationA(&shfo), "Rename file back\n");
203
204     set_curr_dir_path(from, "test4.txt\0");
205     set_curr_dir_path(to, "test6.txt\0");
206     ok(!SHFileOperationA(&shfo), "Rename dir\n");
207     ok(!file_exists(".\\test4.txt"), "The dir is renamed\n");
208     ok(file_exists(".\\test6.txt"), "The dir is renamed\n");
209     set_curr_dir_path(from, "test6.txt\0");
210     set_curr_dir_path(to, "test4.txt\0");
211     ok(!SHFileOperationA(&shfo), "Rename dir back\n");
212 }
213
214 /* tests the FO_COPY action */
215 void test_copy(void)
216 {
217     SHFILEOPSTRUCTA shfo, shfo2;
218     CHAR from[MAX_PATH];
219     CHAR to[MAX_PATH];
220     FILEOP_FLAGS tmp_flags;
221     DWORD retval;
222
223     shfo.hwnd = NULL;
224     shfo.wFunc = FO_COPY;
225     shfo.pFrom = from;
226     shfo.pTo = to;
227     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
228     shfo.hNameMappings = NULL;
229     shfo.lpszProgressTitle = NULL;
230
231     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
232     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
233     ok(SHFileOperationA(&shfo), "Can't copy many files\n");
234     ok(!file_exists(".\\test6.txt"), "The file is not copied - many files are "
235        "specified as a target\n");
236
237     memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
238     shfo2.fFlags |= FOF_MULTIDESTFILES;
239
240     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
241     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
242     ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
243     ok(file_exists(".\\test6.txt"), "The file is copied - many files are "
244        "specified as a target\n");
245     DeleteFileA(".\\test6.txt");
246     DeleteFileA(".\\test7.txt");
247     RemoveDirectoryA(".\\test8.txt");
248
249     /* number of sources do not correspond to number of targets */
250     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
251     set_curr_dir_path(to, "test6.txt\0test7.txt\0");
252     ok(SHFileOperationA(&shfo2), "Can't copy many files\n");
253     ok(!file_exists(".\\test6.txt"), "The file is not copied - many files are "
254        "specified as a target\n");
255
256     set_curr_dir_path(from, "test1.txt\0");
257     set_curr_dir_path(to, "test4.txt\0");
258     ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
259     ok(file_exists(".\\test4.txt\\test1.txt"), "The file is copied\n");
260
261     set_curr_dir_path(from, "test?.txt\0");
262     set_curr_dir_path(to, "testdir2\0");
263     ok(!file_exists(".\\testdir2\\test1.txt"), "The file is not copied yet\n");
264     ok(!file_exists(".\\testdir2\\test4.txt"), "The directory is not copied yet\n");
265     ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
266     ok(file_exists(".\\testdir2\\test1.txt"), "The file is copied\n");
267     ok(file_exists(".\\testdir2\\test4.txt"), "The directory is copied\n");
268     ok(file_exists(".\\testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
269     clean_after_shfo_tests();
270
271     init_shfo_tests();
272     shfo.fFlags |= FOF_FILESONLY;
273     ok(!file_exists(".\\testdir2\\test1.txt"), "The file is not copied yet\n");
274     ok(!file_exists(".\\testdir2\\test4.txt"), "The directory is not copied yet\n");
275     ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
276     ok(file_exists(".\\testdir2\\test1.txt"), "The file is copied\n");
277     ok(!file_exists(".\\testdir2\\test4.txt"), "The directory is copied\n");
278     clean_after_shfo_tests();
279
280     init_shfo_tests();
281     set_curr_dir_path(from, "test1.txt\0test2.txt\0");
282     ok(!file_exists(".\\testdir2\\test1.txt"), "The file is not copied yet\n");
283     ok(!file_exists(".\\testdir2\\test2.txt"), "The file is not copied yet\n");
284     ok(!SHFileOperationA(&shfo), "Files are copied to other directory \n");
285     ok(file_exists(".\\testdir2\\test1.txt"), "The file is copied\n");
286     ok(file_exists(".\\testdir2\\test2.txt"), "The file is copied\n");
287     clean_after_shfo_tests();
288
289     /* Copying multiple files with one not existing as source, fails the
290        entire operation in Win98/ME/2K/XP, but not in 95/NT */
291     init_shfo_tests();
292     tmp_flags = shfo.fFlags;
293     set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
294     ok(!file_exists(".\\testdir2\\test1.txt"), "The file is not copied yet\n");
295     ok(!file_exists(".\\testdir2\\test2.txt"), "The file is not copied yet\n");
296     retval = SHFileOperationA(&shfo);
297     if (!retval)
298       /* Win 95/NT returns success but copies only the files up to the non-existent source */
299       ok(file_exists(".\\testdir2\\test1.txt"), "The file is not copied\n");
300     else
301     {
302       /* Win 98/ME/2K/XP fail the entire operation with return code 1026 if one source file does not exist */
303       ok(retval == 1026, "Files are copied to other directory\n");
304       ok(!file_exists(".\\testdir2\\test1.txt"), "The file is copied\n");
305     }
306     ok(!file_exists(".\\testdir2\\test2.txt"), "The file is copied\n");
307     shfo.fFlags = tmp_flags;
308 }
309
310 /* tests the FO_MOVE action */
311 void test_move(void)
312 {
313     SHFILEOPSTRUCTA shfo, shfo2;
314     CHAR from[MAX_PATH];
315     CHAR to[MAX_PATH];
316
317     shfo.hwnd = NULL;
318     shfo.wFunc = FO_MOVE;
319     shfo.pFrom = from;
320     shfo.pTo = to;
321     shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
322     shfo.hNameMappings = NULL;
323     shfo.lpszProgressTitle = NULL;
324
325     set_curr_dir_path(from, "test1.txt\0");
326     set_curr_dir_path(to, "test4.txt\0");
327     ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
328     ok(file_exists(".\\test4.txt\\test1.txt"), "The file is moved\n");
329
330     set_curr_dir_path(from, "test?.txt\0");
331     set_curr_dir_path(to, "testdir2\0");
332     ok(!file_exists(".\\testdir2\\test2.txt"), "The file is not moved yet\n");
333     ok(!file_exists(".\\testdir2\\test4.txt"), "The directory is not moved yet\n");
334     ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
335     ok(file_exists(".\\testdir2\\test2.txt"), "The file is moved\n");
336     ok(file_exists(".\\testdir2\\test4.txt"), "The directory is moved\n");
337     ok(file_exists(".\\testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
338
339     clean_after_shfo_tests();
340     init_shfo_tests();
341
342     memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
343     shfo2.fFlags |= FOF_MULTIDESTFILES;
344
345     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
346     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
347     ok(!SHFileOperationA(&shfo2), "Move many files\n");
348     ok(file_exists(".\\test6.txt"), "The file is moved - many files are "
349        "specified as a target\n");
350     DeleteFileA(".\\test6.txt");
351     DeleteFileA(".\\test7.txt");
352     RemoveDirectoryA(".\\test8.txt");
353
354     init_shfo_tests();
355
356     /* number of sources do not correspond to number of targets */
357     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
358     set_curr_dir_path(to, "test6.txt\0test7.txt\0");
359     ok(SHFileOperationA(&shfo2), "Can't move many files\n");
360     ok(!file_exists(".\\test6.txt"), "The file is not moved - many files are "
361        "specified as a target\n");
362
363     init_shfo_tests();
364
365     set_curr_dir_path(from, "test3.txt\0");
366     set_curr_dir_path(to, "test4.txt\\test1.txt\0");
367     ok(!SHFileOperationA(&shfo), "File is moved moving to other directory\n");
368     ok(file_exists(".\\test4.txt\\test1.txt"), "The file is moved\n");
369
370     set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
371     set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
372     ok(SHFileOperationA(&shfo), "Can not move many files\n");
373     ok(file_exists(".\\test1.txt"), "The file is not moved. Many files are specified\n");
374     ok(file_exists(".\\test4.txt"), "The directory is not moved. Many files are specified\n");
375
376     set_curr_dir_path(from, "test1.txt\0");
377     set_curr_dir_path(to, "test6.txt\0");
378     ok(!SHFileOperationA(&shfo), "Move file\n");
379     ok(!file_exists(".\\test1.txt"), "The file is moved\n");
380     ok(file_exists(".\\test6.txt"), "The file is moved\n");
381     set_curr_dir_path(from, "test6.txt\0");
382     set_curr_dir_path(to, "test1.txt\0");
383     ok(!SHFileOperationA(&shfo), "Move file back\n");
384
385     set_curr_dir_path(from, "test4.txt\0");
386     set_curr_dir_path(to, "test6.txt\0");
387     ok(!SHFileOperationA(&shfo), "Move dir\n");
388     ok(!file_exists(".\\test4.txt"), "The dir is moved\n");
389     ok(file_exists(".\\test6.txt"), "The dir is moved\n");
390     set_curr_dir_path(from, "test6.txt\0");
391     set_curr_dir_path(to, "test4.txt\0");
392     ok(!SHFileOperationA(&shfo), "Move dir back\n");
393 }
394
395 void test_sh_create_dir()
396 {
397     CHAR path[MAX_PATH];
398     int ret;
399
400     set_curr_dir_path(path, "testdir2\\test4.txt\0");
401     ret = SHCreateDirectoryExA(NULL, path, NULL);
402     ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
403     ok(file_exists(".\\testdir2"), "The first directory is not created\n");
404     ok(file_exists(".\\testdir2\\test4.txt"), "The second directory is not created\n");
405
406     ret = SHCreateDirectoryExA(NULL, path, NULL);
407     ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
408 }
409
410 START_TEST(shlfileop)
411 {
412     clean_after_shfo_tests();
413
414     init_shfo_tests();
415     test_delete();
416     clean_after_shfo_tests();
417
418     init_shfo_tests();
419     test_rename();
420     clean_after_shfo_tests();
421
422     init_shfo_tests();
423     test_copy();
424     clean_after_shfo_tests();
425
426     init_shfo_tests();
427     test_move();
428     clean_after_shfo_tests();
429
430     test_sh_create_dir();
431     clean_after_shfo_tests();
432 }