Release 20050930.
[wine/gsoc-2012-control.git] / dlls / shell32 / tests / shlfileop.c
blob03b197d323368361c5e4547f59a50e4202cacf64
1 /*
2 * Unit test of the SHFileOperation function.
4 * Copyright 2002 Andriy Palamarchuk
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
22 #include <stdio.h>
24 #define WINE_NOWINSOCK
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wtypes.h"
28 #include "shellapi.h"
29 #include "shlobj.h"
31 #include "wine/test.h"
33 CHAR CURR_DIR[MAX_PATH];
35 static HMODULE hshell32;
36 static int (WINAPI *pSHCreateDirectoryExA)(HWND, LPCSTR, LPSECURITY_ATTRIBUTES);
38 static void InitFunctionPointers(void)
40 hshell32 = GetModuleHandleA("shell32.dll");
42 if(hshell32)
43 pSHCreateDirectoryExA = (void*)GetProcAddress(hshell32, "SHCreateDirectoryExA");
46 /* creates a file with the specified name for tests */
47 static void createTestFile(const CHAR *name)
49 HANDLE file;
50 DWORD written;
52 file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
53 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
54 WriteFile(file, name, strlen(name), &written, NULL);
55 WriteFile(file, "\n", strlen("\n"), &written, NULL);
56 CloseHandle(file);
59 static BOOL file_exists(const CHAR *name)
61 return GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES;
64 /* initializes the tests */
65 static void init_shfo_tests(void)
67 int len;
69 GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
70 len = lstrlenA(CURR_DIR);
72 if(len && (CURR_DIR[len-1] == '\\'))
73 CURR_DIR[len-1] = 0;
75 createTestFile(".\\test1.txt");
76 createTestFile(".\\test2.txt");
77 createTestFile(".\\test3.txt");
78 CreateDirectoryA(".\\test4.txt", NULL);
79 CreateDirectoryA(".\\testdir2", NULL);
82 /* cleans after tests */
83 static void clean_after_shfo_tests(void)
85 DeleteFileA(".\\test1.txt");
86 DeleteFileA(".\\test2.txt");
87 DeleteFileA(".\\test3.txt");
88 DeleteFileA(".\\test4.txt\\test1.txt");
89 DeleteFileA(".\\test4.txt\\test2.txt");
90 DeleteFileA(".\\test4.txt\\test3.txt");
91 RemoveDirectoryA(".\\test4.txt");
92 DeleteFileA(".\\testdir2\\test1.txt");
93 DeleteFileA(".\\testdir2\\test2.txt");
94 DeleteFileA(".\\testdir2\\test3.txt");
95 DeleteFileA(".\\testdir2\\test4.txt\\test1.txt");
96 RemoveDirectoryA(".\\testdir2\\test4.txt");
97 RemoveDirectoryA(".\\testdir2");
101 puts into the specified buffer file names with current directory.
102 files - string with file names, separated by null characters. Ends on a double
103 null characters
105 static void set_curr_dir_path(CHAR *buf, const CHAR* files)
107 buf[0] = 0;
108 while (files[0])
110 strcpy(buf, CURR_DIR);
111 buf += strlen(buf);
112 buf[0] = '\\';
113 buf++;
114 strcpy(buf, files);
115 buf += strlen(buf) + 1;
116 files += strlen(files) + 1;
118 buf[0] = 0;
122 /* tests the FO_DELETE action */
123 static void test_delete(void)
125 SHFILEOPSTRUCTA shfo;
126 DWORD ret;
127 CHAR buf[MAX_PATH];
129 sprintf(buf, "%s\\%s", CURR_DIR, "test?.txt");
130 buf[strlen(buf) + 1] = '\0';
132 shfo.hwnd = NULL;
133 shfo.wFunc = FO_DELETE;
134 shfo.pFrom = buf;
135 shfo.pTo = "\0";
136 shfo.fFlags = FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT;
137 shfo.hNameMappings = NULL;
138 shfo.lpszProgressTitle = NULL;
140 ok(!SHFileOperationA(&shfo), "Deletion was successful\n");
141 ok(file_exists(".\\test4.txt"), "Directory should not be removed\n");
142 ok(!file_exists(".\\test1.txt"), "File should be removed\n");
144 ret = SHFileOperationA(&shfo);
145 ok(!ret, "Directory exists, but is not removed, ret=%ld\n", ret);
146 ok(file_exists(".\\test4.txt"), "Directory should not be removed\n");
148 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
150 ok(!SHFileOperationA(&shfo), "Directory removed\n");
151 ok(!file_exists(".\\test4.txt"), "Directory should be removed\n");
153 ret = SHFileOperationA(&shfo);
154 ok(!ret, "The requested file does not exist, ret=%ld\n", ret);
156 init_shfo_tests();
157 sprintf(buf, "%s\\%s", CURR_DIR, "test4.txt");
158 buf[strlen(buf) + 1] = '\0';
159 ok(MoveFileA(".\\test1.txt", ".\\test4.txt\\test1.txt"), "Fill the subdirectory\n");
160 ok(!SHFileOperationA(&shfo), "Directory removed\n");
161 ok(!file_exists(".\\test4.txt"), "Directory is removed\n");
163 init_shfo_tests();
164 shfo.pFrom = ".\\test1.txt\0.\\test4.txt\0";
165 ok(!SHFileOperationA(&shfo), "Directory and a file removed\n");
166 ok(!file_exists(".\\test1.txt"), "The file should be removed\n");
167 ok(!file_exists(".\\test4.txt"), "Directory should be removed\n");
168 ok(file_exists(".\\test2.txt"), "This file should not be removed\n");
171 /* tests the FO_RENAME action */
172 static void test_rename(void)
174 SHFILEOPSTRUCTA shfo, shfo2;
175 CHAR from[MAX_PATH];
176 CHAR to[MAX_PATH];
177 DWORD retval;
179 shfo.hwnd = NULL;
180 shfo.wFunc = FO_RENAME;
181 shfo.pFrom = from;
182 shfo.pTo = to;
183 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
184 shfo.hNameMappings = NULL;
185 shfo.lpszProgressTitle = NULL;
187 set_curr_dir_path(from, "test1.txt\0");
188 set_curr_dir_path(to, "test4.txt\0");
189 ok(SHFileOperationA(&shfo), "File is not renamed moving to other directory "
190 "when specifying directory name only\n");
191 ok(file_exists(".\\test1.txt"), "The file is removed\n");
193 set_curr_dir_path(from, "test3.txt\0");
194 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
195 ok(!SHFileOperationA(&shfo), "File is renamed moving to other directory\n");
196 ok(file_exists(".\\test4.txt\\test1.txt"), "The file is not renamed\n");
198 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
199 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
200 retval = SHFileOperationA(&shfo); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
201 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
202 "Can't rename many files, retval = %ld\n", retval);
203 ok(file_exists(".\\test1.txt"), "The file is renamed - many files are specified\n");
205 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
206 shfo2.fFlags |= FOF_MULTIDESTFILES;
208 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
209 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
210 retval = SHFileOperationA(&shfo2); /* W98 returns 0, W2K and newer returns ERROR_GEN_FAILURE, both do nothing */
211 ok(!retval || retval == ERROR_GEN_FAILURE || retval == ERROR_INVALID_TARGET_HANDLE,
212 "Can't rename many files, retval = %ld\n", retval);
213 ok(file_exists(".\\test1.txt"), "The file is not renamed - many files are specified\n");
215 set_curr_dir_path(from, "test1.txt\0");
216 set_curr_dir_path(to, "test6.txt\0");
217 retval = SHFileOperationA(&shfo);
218 ok(!retval, "Rename file failed, retval = %ld\n", retval);
219 ok(!file_exists(".\\test1.txt"), "The file is not renamed\n");
220 ok(file_exists(".\\test6.txt"), "The file is not renamed\n");
222 set_curr_dir_path(from, "test6.txt\0");
223 set_curr_dir_path(to, "test1.txt\0");
224 retval = SHFileOperationA(&shfo);
225 ok(!retval, "Rename file back failed, retval = %ld\n", retval);
227 set_curr_dir_path(from, "test4.txt\0");
228 set_curr_dir_path(to, "test6.txt\0");
229 retval = SHFileOperationA(&shfo);
230 ok(!retval, "Rename dir failed, retval = %ld\n", retval);
231 ok(!file_exists(".\\test4.txt"), "The dir is not renamed\n");
232 ok(file_exists(".\\test6.txt"), "The dir is not renamed\n");
234 set_curr_dir_path(from, "test6.txt\0");
235 set_curr_dir_path(to, "test4.txt\0");
236 retval = SHFileOperationA(&shfo);
237 ok(!retval, "Rename dir back failed, retval = %ld\n", retval);
240 /* tests the FO_COPY action */
241 static void test_copy(void)
243 SHFILEOPSTRUCTA shfo, shfo2;
244 CHAR from[MAX_PATH];
245 CHAR to[MAX_PATH];
246 FILEOP_FLAGS tmp_flags;
247 DWORD retval;
249 shfo.hwnd = NULL;
250 shfo.wFunc = FO_COPY;
251 shfo.pFrom = from;
252 shfo.pTo = to;
253 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
254 shfo.hNameMappings = NULL;
255 shfo.lpszProgressTitle = NULL;
257 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
258 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
259 ok(SHFileOperationA(&shfo), "Can't copy many files\n");
260 ok(!file_exists(".\\test6.txt"), "The file is not copied - many files are "
261 "specified as a target\n");
263 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
264 shfo2.fFlags |= FOF_MULTIDESTFILES;
266 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
267 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
268 ok(!SHFileOperationA(&shfo2), "Can't copy many files\n");
269 ok(file_exists(".\\test6.txt"), "The file is copied - many files are "
270 "specified as a target\n");
271 DeleteFileA(".\\test6.txt");
272 DeleteFileA(".\\test7.txt");
273 RemoveDirectoryA(".\\test8.txt");
275 /* number of sources do not correspond to number of targets */
276 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
277 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
278 ok(SHFileOperationA(&shfo2), "Can't copy many files\n");
279 ok(!file_exists(".\\test6.txt"), "The file is not copied - many files are "
280 "specified as a target\n");
282 set_curr_dir_path(from, "test1.txt\0");
283 set_curr_dir_path(to, "test4.txt\0");
284 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are copied recursively\n");
285 ok(file_exists(".\\test4.txt\\test1.txt"), "The file is copied\n");
287 set_curr_dir_path(from, "test?.txt\0");
288 set_curr_dir_path(to, "testdir2\0");
289 ok(!file_exists(".\\testdir2\\test1.txt"), "The file is not copied yet\n");
290 ok(!file_exists(".\\testdir2\\test4.txt"), "The directory is not copied yet\n");
291 ok(!SHFileOperationA(&shfo), "Files and directories are copied to directory\n");
292 ok(file_exists(".\\testdir2\\test1.txt"), "The file is copied\n");
293 ok(file_exists(".\\testdir2\\test4.txt"), "The directory is copied\n");
294 ok(file_exists(".\\testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is copied\n");
295 clean_after_shfo_tests();
297 init_shfo_tests();
298 shfo.fFlags |= FOF_FILESONLY;
299 ok(!file_exists(".\\testdir2\\test1.txt"), "The file is not copied yet\n");
300 ok(!file_exists(".\\testdir2\\test4.txt"), "The directory is not copied yet\n");
301 ok(!SHFileOperationA(&shfo), "Files are copied to other directory\n");
302 ok(file_exists(".\\testdir2\\test1.txt"), "The file is copied\n");
303 ok(!file_exists(".\\testdir2\\test4.txt"), "The directory is copied\n");
304 clean_after_shfo_tests();
306 init_shfo_tests();
307 set_curr_dir_path(from, "test1.txt\0test2.txt\0");
308 ok(!file_exists(".\\testdir2\\test1.txt"), "The file is not copied yet\n");
309 ok(!file_exists(".\\testdir2\\test2.txt"), "The file is not copied yet\n");
310 ok(!SHFileOperationA(&shfo), "Files are copied to other directory \n");
311 ok(file_exists(".\\testdir2\\test1.txt"), "The file is copied\n");
312 ok(file_exists(".\\testdir2\\test2.txt"), "The file is copied\n");
313 clean_after_shfo_tests();
315 /* Copying multiple files with one not existing as source, fails the
316 entire operation in Win98/ME/2K/XP, but not in 95/NT */
317 init_shfo_tests();
318 tmp_flags = shfo.fFlags;
319 set_curr_dir_path(from, "test1.txt\0test10.txt\0test2.txt\0");
320 ok(!file_exists(".\\testdir2\\test1.txt"), "The file is not copied yet\n");
321 ok(!file_exists(".\\testdir2\\test2.txt"), "The file is not copied yet\n");
322 retval = SHFileOperationA(&shfo);
323 if (!retval)
324 /* Win 95/NT returns success but copies only the files up to the nonexistent source */
325 ok(file_exists(".\\testdir2\\test1.txt"), "The file is not copied\n");
326 else
328 /* Win 98/ME/2K/XP fail the entire operation with return code 1026 if one source file does not exist */
329 ok(retval == 1026, "Files are copied to other directory\n");
330 ok(!file_exists(".\\testdir2\\test1.txt"), "The file is copied\n");
332 ok(!file_exists(".\\testdir2\\test2.txt"), "The file is copied\n");
333 shfo.fFlags = tmp_flags;
336 /* tests the FO_MOVE action */
337 static void test_move(void)
339 SHFILEOPSTRUCTA shfo, shfo2;
340 CHAR from[MAX_PATH];
341 CHAR to[MAX_PATH];
343 shfo.hwnd = NULL;
344 shfo.wFunc = FO_MOVE;
345 shfo.pFrom = from;
346 shfo.pTo = to;
347 shfo.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
348 shfo.hNameMappings = NULL;
349 shfo.lpszProgressTitle = NULL;
351 set_curr_dir_path(from, "test1.txt\0");
352 set_curr_dir_path(to, "test4.txt\0");
353 ok(!SHFileOperationA(&shfo), "Prepare test to check how directories are moved recursively\n");
354 ok(file_exists(".\\test4.txt\\test1.txt"), "The file is moved\n");
356 set_curr_dir_path(from, "test?.txt\0");
357 set_curr_dir_path(to, "testdir2\0");
358 ok(!file_exists(".\\testdir2\\test2.txt"), "The file is not moved yet\n");
359 ok(!file_exists(".\\testdir2\\test4.txt"), "The directory is not moved yet\n");
360 ok(!SHFileOperationA(&shfo), "Files and directories are moved to directory\n");
361 ok(file_exists(".\\testdir2\\test2.txt"), "The file is moved\n");
362 ok(file_exists(".\\testdir2\\test4.txt"), "The directory is moved\n");
363 ok(file_exists(".\\testdir2\\test4.txt\\test1.txt"), "The file in subdirectory is moved\n");
365 clean_after_shfo_tests();
366 init_shfo_tests();
368 memcpy(&shfo2, &shfo, sizeof(SHFILEOPSTRUCTA));
369 shfo2.fFlags |= FOF_MULTIDESTFILES;
371 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
372 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
373 ok(!SHFileOperationA(&shfo2), "Move many files\n");
374 ok(file_exists(".\\test6.txt"), "The file is moved - many files are "
375 "specified as a target\n");
376 DeleteFileA(".\\test6.txt");
377 DeleteFileA(".\\test7.txt");
378 RemoveDirectoryA(".\\test8.txt");
380 init_shfo_tests();
382 /* number of sources do not correspond to number of targets */
383 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
384 set_curr_dir_path(to, "test6.txt\0test7.txt\0");
385 ok(SHFileOperationA(&shfo2), "Can't move many files\n");
386 ok(!file_exists(".\\test6.txt"), "The file is not moved - many files are "
387 "specified as a target\n");
389 init_shfo_tests();
391 set_curr_dir_path(from, "test3.txt\0");
392 set_curr_dir_path(to, "test4.txt\\test1.txt\0");
393 ok(!SHFileOperationA(&shfo), "File is moved moving to other directory\n");
394 ok(file_exists(".\\test4.txt\\test1.txt"), "The file is moved\n");
396 set_curr_dir_path(from, "test1.txt\0test2.txt\0test4.txt\0");
397 set_curr_dir_path(to, "test6.txt\0test7.txt\0test8.txt\0");
398 ok(SHFileOperationA(&shfo), "Cannot move many files\n");
399 ok(file_exists(".\\test1.txt"), "The file is not moved. Many files are specified\n");
400 ok(file_exists(".\\test4.txt"), "The directory is not moved. Many files are specified\n");
402 set_curr_dir_path(from, "test1.txt\0");
403 set_curr_dir_path(to, "test6.txt\0");
404 ok(!SHFileOperationA(&shfo), "Move file\n");
405 ok(!file_exists(".\\test1.txt"), "The file is moved\n");
406 ok(file_exists(".\\test6.txt"), "The file is moved\n");
407 set_curr_dir_path(from, "test6.txt\0");
408 set_curr_dir_path(to, "test1.txt\0");
409 ok(!SHFileOperationA(&shfo), "Move file back\n");
411 set_curr_dir_path(from, "test4.txt\0");
412 set_curr_dir_path(to, "test6.txt\0");
413 ok(!SHFileOperationA(&shfo), "Move dir\n");
414 ok(!file_exists(".\\test4.txt"), "The dir is moved\n");
415 ok(file_exists(".\\test6.txt"), "The dir is moved\n");
416 set_curr_dir_path(from, "test6.txt\0");
417 set_curr_dir_path(to, "test4.txt\0");
418 ok(!SHFileOperationA(&shfo), "Move dir back\n");
421 static void test_sh_create_dir(void)
423 CHAR path[MAX_PATH];
424 int ret;
426 if(!pSHCreateDirectoryExA)
428 trace("skipping SHCreateDirectoryExA tests\n");
429 return;
432 set_curr_dir_path(path, "testdir2\\test4.txt\0");
433 ret = pSHCreateDirectoryExA(NULL, path, NULL);
434 ok(ERROR_SUCCESS == ret, "SHCreateDirectoryEx failed to create directory recursively, ret = %d\n", ret);
435 ok(file_exists(".\\testdir2"), "The first directory is not created\n");
436 ok(file_exists(".\\testdir2\\test4.txt"), "The second directory is not created\n");
438 ret = pSHCreateDirectoryExA(NULL, path, NULL);
439 ok(ERROR_ALREADY_EXISTS == ret, "SHCreateDirectoryEx should fail to create existing directory, ret = %d\n", ret);
442 START_TEST(shlfileop)
444 InitFunctionPointers();
446 clean_after_shfo_tests();
448 init_shfo_tests();
449 test_delete();
450 clean_after_shfo_tests();
452 init_shfo_tests();
453 test_rename();
454 clean_after_shfo_tests();
456 init_shfo_tests();
457 test_copy();
458 clean_after_shfo_tests();
460 init_shfo_tests();
461 test_move();
462 clean_after_shfo_tests();
464 test_sh_create_dir();
465 clean_after_shfo_tests();