scrrun: Implement AvailableSpace property for a drive.
[wine/multimedia.git] / dlls / scrrun / tests / filesystem.c
blob3bf12094445709ab098960427c83a7f550770515
1 /*
3 * Copyright 2012 Alistair Leslie-Hughes
4 * Copyright 2014 Dmitry Timoshkov
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #include <stdio.h>
24 #include "windows.h"
25 #include "ole2.h"
26 #include "olectl.h"
27 #include "oleauto.h"
28 #include "dispex.h"
30 #include "wine/test.h"
32 #include "initguid.h"
33 #include "scrrun.h"
35 static IFileSystem3 *fs3;
37 static inline ULONG get_refcount(IUnknown *iface)
39 IUnknown_AddRef(iface);
40 return IUnknown_Release(iface);
43 #define GET_REFCOUNT(iface) \
44 get_refcount((IUnknown*)iface)
46 static void test_interfaces(void)
48 static const WCHAR nonexistent_dirW[] = {
49 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', 0};
50 static const WCHAR pathW[] = {'p','a','t','h',0};
51 static const WCHAR file_kernel32W[] = {
52 '\\', 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0};
53 HRESULT hr;
54 IDispatch *disp;
55 IDispatchEx *dispex;
56 IObjectWithSite *site;
57 VARIANT_BOOL b;
58 BSTR path;
59 WCHAR windows_path[MAX_PATH];
60 WCHAR file_path[MAX_PATH];
62 IFileSystem3_QueryInterface(fs3, &IID_IDispatch, (void**)&disp);
64 GetSystemDirectoryW(windows_path, MAX_PATH);
65 lstrcpyW(file_path, windows_path);
66 lstrcatW(file_path, file_kernel32W);
68 hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
69 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
71 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
72 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
74 b = VARIANT_TRUE;
75 hr = IFileSystem3_FileExists(fs3, NULL, &b);
76 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
77 ok(b == VARIANT_FALSE, "got %x\n", b);
79 hr = IFileSystem3_FileExists(fs3, NULL, NULL);
80 ok(hr == E_POINTER, "got 0x%08x, expected 0x%08x\n", hr, E_POINTER);
82 path = SysAllocString(pathW);
83 b = VARIANT_TRUE;
84 hr = IFileSystem3_FileExists(fs3, path, &b);
85 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
86 ok(b == VARIANT_FALSE, "got %x\n", b);
87 SysFreeString(path);
89 path = SysAllocString(file_path);
90 b = VARIANT_FALSE;
91 hr = IFileSystem3_FileExists(fs3, path, &b);
92 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
93 ok(b == VARIANT_TRUE, "got %x\n", b);
94 SysFreeString(path);
96 path = SysAllocString(windows_path);
97 b = VARIANT_TRUE;
98 hr = IFileSystem3_FileExists(fs3, path, &b);
99 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
100 ok(b == VARIANT_FALSE, "got %x\n", b);
101 SysFreeString(path);
103 /* Folder Exists */
104 hr = IFileSystem3_FolderExists(fs3, NULL, NULL);
105 ok(hr == E_POINTER, "got 0x%08x, expected 0x%08x\n", hr, E_POINTER);
107 path = SysAllocString(windows_path);
108 hr = IFileSystem3_FolderExists(fs3, path, &b);
109 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
110 ok(b == VARIANT_TRUE, "Folder doesn't exists\n");
111 SysFreeString(path);
113 path = SysAllocString(nonexistent_dirW);
114 hr = IFileSystem3_FolderExists(fs3, path, &b);
115 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
116 ok(b == VARIANT_FALSE, "Folder exists\n");
117 SysFreeString(path);
119 path = SysAllocString(file_path);
120 hr = IFileSystem3_FolderExists(fs3, path, &b);
121 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
122 ok(b == VARIANT_FALSE, "Folder exists\n");
123 SysFreeString(path);
125 IDispatch_Release(disp);
128 static void test_createfolder(void)
130 WCHAR pathW[MAX_PATH], buffW[MAX_PATH];
131 HRESULT hr;
132 BSTR path;
133 IFolder *folder;
134 BOOL ret;
136 GetTempPathW(MAX_PATH, pathW);
137 GetTempFileNameW(pathW, NULL, 0, buffW);
138 DeleteFileW(buffW);
139 ret = CreateDirectoryW(buffW, NULL);
140 ok(ret, "got %d, %d\n", ret, GetLastError());
142 /* create existing directory */
143 path = SysAllocString(buffW);
144 folder = (void*)0xdeabeef;
145 hr = IFileSystem3_CreateFolder(fs3, path, &folder);
146 ok(hr == CTL_E_FILEALREADYEXISTS, "got 0x%08x\n", hr);
147 ok(folder == NULL, "got %p\n", folder);
148 SysFreeString(path);
149 RemoveDirectoryW(buffW);
152 static void test_textstream(void)
154 static const WCHAR testfileW[] = {'t','e','s','t','f','i','l','e','.','t','x','t',0};
155 ITextStream *stream;
156 VARIANT_BOOL b;
157 DWORD written;
158 HANDLE file;
159 HRESULT hr;
160 BSTR name, data;
161 BOOL ret;
163 file = CreateFileW(testfileW, GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
164 CloseHandle(file);
166 name = SysAllocString(testfileW);
167 b = VARIANT_FALSE;
168 hr = IFileSystem3_FileExists(fs3, name, &b);
169 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
170 ok(b == VARIANT_TRUE, "got %x\n", b);
172 /* different mode combinations */
173 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting | ForAppending, VARIANT_FALSE, TristateFalse, &stream);
174 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
176 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading | ForAppending, VARIANT_FALSE, TristateFalse, &stream);
177 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
179 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting | ForReading, VARIANT_FALSE, TristateFalse, &stream);
180 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
182 hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateFalse, &stream);
183 ok(hr == S_OK, "got 0x%08x\n", hr);
184 hr = ITextStream_Read(stream, 1, &data);
185 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
186 ITextStream_Release(stream);
188 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream);
189 ok(hr == S_OK, "got 0x%08x\n", hr);
190 hr = ITextStream_Read(stream, 1, &data);
191 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
192 ITextStream_Release(stream);
194 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream);
195 ok(hr == S_OK, "got 0x%08x\n", hr);
197 /* try to write when open for reading */
198 hr = ITextStream_WriteLine(stream, name);
199 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
201 hr = ITextStream_Write(stream, name);
202 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
204 hr = ITextStream_get_AtEndOfStream(stream, NULL);
205 ok(hr == E_POINTER, "got 0x%08x\n", hr);
207 b = 10;
208 hr = ITextStream_get_AtEndOfStream(stream, &b);
209 ok(hr == S_OK || broken(hr == S_FALSE), "got 0x%08x\n", hr);
210 ok(b == VARIANT_TRUE, "got 0x%x\n", b);
212 ITextStream_Release(stream);
214 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream);
215 ok(hr == S_OK, "got 0x%08x\n", hr);
217 b = 10;
218 hr = ITextStream_get_AtEndOfStream(stream, &b);
219 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
220 ok(b == VARIANT_TRUE || broken(b == 10), "got 0x%x\n", b);
222 b = 10;
223 hr = ITextStream_get_AtEndOfLine(stream, &b);
224 todo_wine {
225 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
226 ok(b == VARIANT_FALSE || broken(b == 10), "got 0x%x\n", b);
228 hr = ITextStream_Read(stream, 1, &data);
229 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
231 hr = ITextStream_ReadLine(stream, &data);
232 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
234 hr = ITextStream_ReadAll(stream, &data);
235 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
237 ITextStream_Release(stream);
239 hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateFalse, &stream);
240 ok(hr == S_OK, "got 0x%08x\n", hr);
242 b = 10;
243 hr = ITextStream_get_AtEndOfStream(stream, &b);
244 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
245 ok(b == VARIANT_TRUE || broken(b == 10), "got 0x%x\n", b);
247 b = 10;
248 hr = ITextStream_get_AtEndOfLine(stream, &b);
249 todo_wine {
250 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
251 ok(b == VARIANT_FALSE || broken(b == 10), "got 0x%x\n", b);
253 hr = ITextStream_Read(stream, 1, &data);
254 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
256 hr = ITextStream_ReadLine(stream, &data);
257 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
259 hr = ITextStream_ReadAll(stream, &data);
260 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
262 ITextStream_Release(stream);
264 /* now with non-empty file */
265 file = CreateFileW(testfileW, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
266 ret = WriteFile(file, testfileW, sizeof(testfileW), &written, NULL);
267 ok(ret && written == sizeof(testfileW), "got %d\n", ret);
268 CloseHandle(file);
270 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream);
271 ok(hr == S_OK, "got 0x%08x\n", hr);
272 b = 10;
273 hr = ITextStream_get_AtEndOfStream(stream, &b);
274 ok(hr == S_OK, "got 0x%08x\n", hr);
275 ok(b == VARIANT_FALSE, "got 0x%x\n", b);
276 ITextStream_Release(stream);
278 SysFreeString(name);
279 DeleteFileW(testfileW);
282 static void test_GetFileVersion(void)
284 static const WCHAR k32W[] = {'\\','k','e','r','n','e','l','3','2','.','d','l','l',0};
285 static const WCHAR k33W[] = {'\\','k','e','r','n','e','l','3','3','.','d','l','l',0};
286 WCHAR pathW[MAX_PATH], filenameW[MAX_PATH];
287 BSTR path, version;
288 HRESULT hr;
290 GetSystemDirectoryW(pathW, sizeof(pathW)/sizeof(WCHAR));
292 lstrcpyW(filenameW, pathW);
293 lstrcatW(filenameW, k32W);
295 path = SysAllocString(filenameW);
296 hr = IFileSystem3_GetFileVersion(fs3, path, &version);
297 ok(hr == S_OK, "got 0x%08x\n", hr);
298 ok(*version != 0, "got %s\n", wine_dbgstr_w(version));
299 SysFreeString(version);
300 SysFreeString(path);
302 lstrcpyW(filenameW, pathW);
303 lstrcatW(filenameW, k33W);
305 path = SysAllocString(filenameW);
306 version = (void*)0xdeadbeef;
307 hr = IFileSystem3_GetFileVersion(fs3, path, &version);
308 ok(broken(hr == S_OK) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
309 if (hr == S_OK)
311 ok(*version == 0, "got %s\n", wine_dbgstr_w(version));
312 SysFreeString(version);
314 else
315 ok(version == (void*)0xdeadbeef, "got %p\n", version);
316 SysFreeString(path);
319 static void test_GetParentFolderName(void)
321 static const WCHAR path1[] = {'a',0};
322 static const WCHAR path2[] = {'a','/','a','/','a',0};
323 static const WCHAR path3[] = {'a','\\','a','\\','a',0};
324 static const WCHAR path4[] = {'a','/','a','/','/','\\','\\',0};
325 static const WCHAR path5[] = {'c',':','\\','\\','a',0};
326 static const WCHAR path6[] = {'a','c',':','\\','a',0};
327 static const WCHAR result2[] = {'a','/','a',0};
328 static const WCHAR result3[] = {'a','\\','a',0};
329 static const WCHAR result4[] = {'a',0};
330 static const WCHAR result5[] = {'c',':','\\',0};
331 static const WCHAR result6[] = {'a','c',':',0};
333 static const struct {
334 const WCHAR *path;
335 const WCHAR *result;
336 } tests[] = {
337 {NULL, NULL},
338 {path1, NULL},
339 {path2, result2},
340 {path3, result3},
341 {path4, result4},
342 {path5, result5},
343 {path6, result6}
346 BSTR path, result;
347 HRESULT hr;
348 int i;
350 hr = IFileSystem3_GetParentFolderName(fs3, NULL, NULL);
351 ok(hr == E_POINTER, "GetParentFolderName returned %x, expected E_POINTER\n", hr);
353 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
354 result = (BSTR)0xdeadbeef;
355 path = tests[i].path ? SysAllocString(tests[i].path) : NULL;
356 hr = IFileSystem3_GetParentFolderName(fs3, path, &result);
357 ok(hr == S_OK, "%d) GetParentFolderName returned %x, expected S_OK\n", i, hr);
358 if(!tests[i].result)
359 ok(!result, "%d) result = %s\n", i, wine_dbgstr_w(result));
360 else
361 ok(!lstrcmpW(result, tests[i].result), "%d) result = %s\n", i, wine_dbgstr_w(result));
362 SysFreeString(path);
363 SysFreeString(result);
367 static void test_GetFileName(void)
369 static const WCHAR path1[] = {'a',0};
370 static const WCHAR path2[] = {'a','/','a','.','b',0};
371 static const WCHAR path3[] = {'a','\\',0};
372 static const WCHAR path4[] = {'c',':',0};
373 static const WCHAR path5[] = {'/','\\',0};
374 static const WCHAR result2[] = {'a','.','b',0};
375 static const WCHAR result3[] = {'a',0};
377 static const struct {
378 const WCHAR *path;
379 const WCHAR *result;
380 } tests[] = {
381 {NULL, NULL},
382 {path1, path1},
383 {path2, result2},
384 {path3, result3},
385 {path4, NULL},
386 {path5, NULL}
389 BSTR path, result;
390 HRESULT hr;
391 int i;
393 hr = IFileSystem3_GetFileName(fs3, NULL, NULL);
394 ok(hr == E_POINTER, "GetFileName returned %x, expected E_POINTER\n", hr);
396 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
397 result = (BSTR)0xdeadbeef;
398 path = tests[i].path ? SysAllocString(tests[i].path) : NULL;
399 hr = IFileSystem3_GetFileName(fs3, path, &result);
400 ok(hr == S_OK, "%d) GetFileName returned %x, expected S_OK\n", i, hr);
401 if(!tests[i].result)
402 ok(!result, "%d) result = %s\n", i, wine_dbgstr_w(result));
403 else
404 ok(!lstrcmpW(result, tests[i].result), "%d) result = %s\n", i, wine_dbgstr_w(result));
405 SysFreeString(path);
406 SysFreeString(result);
410 static void test_GetBaseName(void)
412 static const WCHAR path1[] = {'a',0};
413 static const WCHAR path2[] = {'a','/','a','.','b','.','c',0};
414 static const WCHAR path3[] = {'a','.','b','\\',0};
415 static const WCHAR path4[] = {'c',':',0};
416 static const WCHAR path5[] = {'/','\\',0};
417 static const WCHAR path6[] = {'.','a',0};
418 static const WCHAR result1[] = {'a',0};
419 static const WCHAR result2[] = {'a','.','b',0};
420 static const WCHAR result6[] = {0};
422 static const struct {
423 const WCHAR *path;
424 const WCHAR *result;
425 } tests[] = {
426 {NULL, NULL},
427 {path1, result1},
428 {path2, result2},
429 {path3, result1},
430 {path4, NULL},
431 {path5, NULL},
432 {path6, result6}
435 BSTR path, result;
436 HRESULT hr;
437 int i;
439 hr = IFileSystem3_GetBaseName(fs3, NULL, NULL);
440 ok(hr == E_POINTER, "GetBaseName returned %x, expected E_POINTER\n", hr);
442 for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
443 result = (BSTR)0xdeadbeef;
444 path = tests[i].path ? SysAllocString(tests[i].path) : NULL;
445 hr = IFileSystem3_GetBaseName(fs3, path, &result);
446 ok(hr == S_OK, "%d) GetBaseName returned %x, expected S_OK\n", i, hr);
447 if(!tests[i].result)
448 ok(!result, "%d) result = %s\n", i, wine_dbgstr_w(result));
449 else
450 ok(!lstrcmpW(result, tests[i].result), "%d) result = %s\n", i, wine_dbgstr_w(result));
451 SysFreeString(path);
452 SysFreeString(result);
456 static void test_GetAbsolutePathName(void)
458 static const WCHAR dir1[] = {'t','e','s','t','_','d','i','r','1',0};
459 static const WCHAR dir2[] = {'t','e','s','t','_','d','i','r','2',0};
460 static const WCHAR dir_match1[] = {'t','e','s','t','_','d','i','r','*',0};
461 static const WCHAR dir_match2[] = {'t','e','s','t','_','d','i','*',0};
462 static const WCHAR cur_dir[] = {'.',0};
464 WIN32_FIND_DATAW fdata;
465 HANDLE find;
466 WCHAR buf[MAX_PATH], buf2[MAX_PATH];
467 BSTR path, result;
468 HRESULT hr;
470 hr = IFileSystem3_GetAbsolutePathName(fs3, NULL, NULL);
471 ok(hr == E_POINTER, "GetAbsolutePathName returned %x, expected E_POINTER\n", hr);
473 hr = IFileSystem3_GetAbsolutePathName(fs3, NULL, &result);
474 ok(hr == S_OK, "GetAbsolutePathName returned %x, expected S_OK\n", hr);
475 GetFullPathNameW(cur_dir, MAX_PATH, buf, NULL);
476 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf));
477 SysFreeString(result);
479 find = FindFirstFileW(dir_match2, &fdata);
480 if(find != INVALID_HANDLE_VALUE) {
481 skip("GetAbsolutePathName tests\n");
482 FindClose(find);
483 return;
486 path = SysAllocString(dir_match1);
487 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
488 ok(hr == S_OK, "GetAbsolutePathName returned %x, expected S_OK\n", hr);
489 GetFullPathNameW(dir_match1, MAX_PATH, buf2, NULL);
490 ok(!lstrcmpiW(buf2, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf2));
491 SysFreeString(result);
493 ok(CreateDirectoryW(dir1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir1));
494 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
495 ok(hr == S_OK, "GetAbsolutePathName returned %x, expected S_OK\n", hr);
496 GetFullPathNameW(dir1, MAX_PATH, buf, NULL);
497 ok(!lstrcmpiW(buf, result) || broken(!lstrcmpiW(buf2, result)), "result = %s, expected %s\n",
498 wine_dbgstr_w(result), wine_dbgstr_w(buf));
499 SysFreeString(result);
501 ok(CreateDirectoryW(dir2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir2));
502 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
503 ok(hr == S_OK, "GetAbsolutePathName returned %x, expected S_OK\n", hr);
504 if(!lstrcmpiW(buf, result) || !lstrcmpiW(buf2, result)) {
505 ok(!lstrcmpiW(buf, result) || broken(!lstrcmpiW(buf2, result)), "result = %s, expected %s\n",
506 wine_dbgstr_w(result), wine_dbgstr_w(buf));
507 }else {
508 GetFullPathNameW(dir2, MAX_PATH, buf, NULL);
509 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n",
510 wine_dbgstr_w(result), wine_dbgstr_w(buf));
512 SysFreeString(result);
514 SysFreeString(path);
515 path = SysAllocString(dir_match2);
516 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
517 ok(hr == S_OK, "GetAbsolutePathName returned %x, expected S_OK\n", hr);
518 GetFullPathNameW(dir_match2, MAX_PATH, buf, NULL);
519 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf));
520 SysFreeString(result);
521 SysFreeString(path);
523 RemoveDirectoryW(dir1);
524 RemoveDirectoryW(dir2);
527 static void test_GetFile(void)
529 static const WCHAR get_file[] = {'g','e','t','_','f','i','l','e','.','t','s','t',0};
531 BSTR path = SysAllocString(get_file);
532 FileAttribute fa;
533 VARIANT size;
534 DWORD gfa;
535 IFile *file;
536 HRESULT hr;
537 HANDLE hf;
539 hr = IFileSystem3_GetFile(fs3, path, NULL);
540 ok(hr == E_POINTER, "GetFile returned %x, expected E_POINTER\n", hr);
541 hr = IFileSystem3_GetFile(fs3, NULL, &file);
542 ok(hr == E_INVALIDARG, "GetFile returned %x, expected E_INVALIDARG\n", hr);
544 if(GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES) {
545 skip("File already exists, skipping GetFile tests\n");
546 SysFreeString(path);
547 return;
550 file = (IFile*)0xdeadbeef;
551 hr = IFileSystem3_GetFile(fs3, path, &file);
552 ok(!file, "file != NULL\n");
553 ok(hr == CTL_E_FILENOTFOUND, "GetFile returned %x, expected CTL_E_FILENOTFOUND\n", hr);
555 hf = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
556 if(hf == INVALID_HANDLE_VALUE) {
557 skip("Can't create temporary file\n");
558 SysFreeString(path);
559 return;
561 CloseHandle(hf);
563 hr = IFileSystem3_GetFile(fs3, path, &file);
564 ok(hr == S_OK, "GetFile returned %x, expected S_OK\n", hr);
566 hr = IFile_get_Attributes(file, &fa);
567 gfa = GetFileAttributesW(get_file) & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN |
568 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE |
569 FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED);
570 ok(hr == S_OK, "get_Attributes returned %x, expected S_OK\n", hr);
571 ok(fa == gfa, "fa = %x, expected %x\n", fa, gfa);
573 hr = IFile_get_Size(file, &size);
574 ok(hr == S_OK, "get_Size returned %x, expected S_OK\n", hr);
575 ok(V_VT(&size) == VT_I4, "V_VT(&size) = %d, expected VT_I4\n", V_VT(&size));
576 ok(V_I4(&size) == 0, "V_I4(&size) = %d, expected 0\n", V_I4(&size));
577 IFile_Release(file);
579 hr = IFileSystem3_DeleteFile(fs3, path, FALSE);
580 ok(hr==CTL_E_PERMISSIONDENIED || broken(hr==S_OK),
581 "DeleteFile returned %x, expected CTL_E_PERMISSIONDENIED\n", hr);
582 if(hr != S_OK) {
583 hr = IFileSystem3_DeleteFile(fs3, path, TRUE);
584 ok(hr == S_OK, "DeleteFile returned %x, expected S_OK\n", hr);
586 hr = IFileSystem3_DeleteFile(fs3, path, TRUE);
587 ok(hr == CTL_E_FILENOTFOUND, "DeleteFile returned %x, expected CTL_E_FILENOTFOUND\n", hr);
589 SysFreeString(path);
592 static inline BOOL create_file(const WCHAR *name)
594 HANDLE f = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
595 CloseHandle(f);
596 return f != INVALID_HANDLE_VALUE;
599 static inline void create_path(const WCHAR *folder, const WCHAR *name, WCHAR *ret)
601 DWORD len = lstrlenW(folder);
602 memmove(ret, folder, len*sizeof(WCHAR));
603 ret[len] = '\\';
604 memmove(ret+len+1, name, (lstrlenW(name)+1)*sizeof(WCHAR));
607 static void test_CopyFolder(void)
609 static const WCHAR filesystem3_dir[] = {'f','i','l','e','s','y','s','t','e','m','3','_','t','e','s','t',0};
610 static const WCHAR s1[] = {'s','r','c','1',0};
611 static const WCHAR s[] = {'s','r','c','*',0};
612 static const WCHAR d[] = {'d','s','t',0};
613 static const WCHAR empty[] = {0};
615 WCHAR tmp[MAX_PATH];
616 BSTR bsrc, bdst;
617 HRESULT hr;
619 if(!CreateDirectoryW(filesystem3_dir, NULL)) {
620 skip("can't create temporary directory\n");
621 return;
624 create_path(filesystem3_dir, s1, tmp);
625 bsrc = SysAllocString(tmp);
626 create_path(filesystem3_dir, d, tmp);
627 bdst = SysAllocString(tmp);
628 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
629 ok(hr == CTL_E_FILENOTFOUND, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr);
631 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
632 ok(hr == CTL_E_PATHNOTFOUND, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr);
634 ok(create_file(bsrc), "can't create %s file\n", wine_dbgstr_w(bsrc));
635 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
636 ok(hr == S_OK, "CopyFile returned %x, expected S_OK\n", hr);
638 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
639 ok(hr == CTL_E_PATHNOTFOUND, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr);
641 hr = IFileSystem3_DeleteFile(fs3, bsrc, VARIANT_FALSE);
642 ok(hr == S_OK, "DeleteFile returned %x, expected S_OK\n", hr);
644 ok(CreateDirectoryW(bsrc, NULL), "can't create %s\n", wine_dbgstr_w(bsrc));
645 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
646 ok(hr == CTL_E_FILENOTFOUND, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr);
648 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
649 ok(hr == CTL_E_FILEALREADYEXISTS, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr);
651 hr = IFileSystem3_DeleteFile(fs3, bdst, VARIANT_TRUE);
652 ok(hr == S_OK, "DeleteFile returned %x, expected S_OK\n", hr);
654 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
655 ok(hr == S_OK, "CopyFolder returned %x, expected S_OK\n", hr);
657 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
658 ok(hr == S_OK, "CopyFolder returned %x, expected S_OK\n", hr);
659 create_path(tmp, s1, tmp);
660 ok(GetFileAttributesW(tmp) == INVALID_FILE_ATTRIBUTES,
661 "%s file exists\n", wine_dbgstr_w(tmp));
663 create_path(filesystem3_dir, d, tmp);
664 create_path(tmp, empty, tmp);
665 SysFreeString(bdst);
666 bdst = SysAllocString(tmp);
667 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
668 ok(hr == S_OK, "CopyFolder returned %x, expected S_OK\n", hr);
669 create_path(tmp, s1, tmp);
670 ok(GetFileAttributesW(tmp) != INVALID_FILE_ATTRIBUTES,
671 "%s directory doesn't exist\n", wine_dbgstr_w(tmp));
672 ok(RemoveDirectoryW(tmp), "can't remove %s directory\n", wine_dbgstr_w(tmp));
673 create_path(filesystem3_dir, d, tmp);
674 SysFreeString(bdst);
675 bdst = SysAllocString(tmp);
678 create_path(filesystem3_dir, s, tmp);
679 SysFreeString(bsrc);
680 bsrc = SysAllocString(tmp);
681 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
682 ok(hr == S_OK, "CopyFolder returned %x, expected S_OK\n", hr);
683 create_path(filesystem3_dir, d, tmp);
684 create_path(tmp, s1, tmp);
685 ok(GetFileAttributesW(tmp) != INVALID_FILE_ATTRIBUTES,
686 "%s directory doesn't exist\n", wine_dbgstr_w(tmp));
688 hr = IFileSystem3_DeleteFolder(fs3, bdst, VARIANT_FALSE);
689 ok(hr == S_OK, "DeleteFolder returned %x, expected S_OK\n", hr);
691 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
692 ok(hr == CTL_E_PATHNOTFOUND, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr);
694 create_path(filesystem3_dir, s1, tmp);
695 SysFreeString(bsrc);
696 bsrc = SysAllocString(tmp);
697 create_path(tmp, s1, tmp);
698 ok(create_file(tmp), "can't create %s file\n", wine_dbgstr_w(tmp));
699 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_FALSE);
700 ok(hr == S_OK, "CopyFolder returned %x, expected S_OK\n", hr);
702 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_FALSE);
703 ok(hr == CTL_E_FILEALREADYEXISTS, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr);
705 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
706 ok(hr == S_OK, "CopyFolder returned %x, expected S_OK\n", hr);
707 SysFreeString(bsrc);
708 SysFreeString(bdst);
710 bsrc = SysAllocString(filesystem3_dir);
711 hr = IFileSystem3_DeleteFolder(fs3, bsrc, VARIANT_FALSE);
712 ok(hr == S_OK, "DeleteFolder returned %x, expected S_OK\n", hr);
713 SysFreeString(bsrc);
716 static BSTR bstr_from_str(const char *str)
718 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
719 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
720 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
721 return ret;
724 struct buildpath_test
726 const char *path;
727 const char *name;
728 const char *result;
731 static struct buildpath_test buildpath_data[] =
733 { "C:\\path", "..\\name.tmp", "C:\\path\\..\\name.tmp" },
734 { "C:\\path", "\\name.tmp", "C:\\path\\name.tmp" },
735 { "C:\\path", "name.tmp", "C:\\path\\name.tmp" },
736 { "C:\\path\\", "name.tmp", "C:\\path\\name.tmp" },
737 { "C:\\path", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
738 { "C:\\path\\", "\\name.tmp", "C:\\path\\name.tmp" },
739 { "C:\\path\\", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
740 { "C:\\path\\\\", "\\\\name.tmp", "C:\\path\\\\\\name.tmp" },
741 { "C:\\\\", "\\name.tmp", "C:\\\\name.tmp" },
742 { "C:", "name.tmp", "C:name.tmp" },
743 { "C:", "\\\\name.tmp", "C:\\\\name.tmp" },
744 { NULL }
747 static void test_BuildPath(void)
749 struct buildpath_test *ptr = buildpath_data;
750 BSTR ret, path;
751 HRESULT hr;
752 int i = 0;
754 hr = IFileSystem3_BuildPath(fs3, NULL, NULL, NULL);
755 ok(hr == E_POINTER, "got 0x%08x\n", hr);
757 ret = (BSTR)0xdeadbeef;
758 hr = IFileSystem3_BuildPath(fs3, NULL, NULL, &ret);
759 ok(hr == S_OK, "got 0x%08x\n", hr);
760 ok(*ret == 0, "got %p\n", ret);
761 SysFreeString(ret);
763 ret = (BSTR)0xdeadbeef;
764 path = bstr_from_str("path");
765 hr = IFileSystem3_BuildPath(fs3, path, NULL, &ret);
766 ok(hr == S_OK, "got 0x%08x\n", hr);
767 ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret));
768 SysFreeString(ret);
769 SysFreeString(path);
771 ret = (BSTR)0xdeadbeef;
772 path = bstr_from_str("path");
773 hr = IFileSystem3_BuildPath(fs3, NULL, path, &ret);
774 ok(hr == S_OK, "got 0x%08x\n", hr);
775 ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret));
776 SysFreeString(ret);
777 SysFreeString(path);
779 while (ptr->path)
781 BSTR name, result;
783 ret = NULL;
784 path = bstr_from_str(ptr->path);
785 name = bstr_from_str(ptr->name);
786 result = bstr_from_str(ptr->result);
787 hr = IFileSystem3_BuildPath(fs3, path, name, &ret);
788 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
789 if (hr == S_OK)
791 ok(!lstrcmpW(ret, result), "%d: got wrong path %s, expected %s\n", i, wine_dbgstr_w(ret),
792 wine_dbgstr_w(result));
793 SysFreeString(ret);
795 SysFreeString(path);
796 SysFreeString(name);
797 SysFreeString(result);
799 i++;
800 ptr++;
804 static void test_GetFolder(void)
806 static const WCHAR dummyW[] = {'d','u','m','m','y',0};
807 WCHAR buffW[MAX_PATH];
808 IFolder *folder;
809 HRESULT hr;
810 BSTR str;
812 folder = (void*)0xdeadbeef;
813 hr = IFileSystem3_GetFolder(fs3, NULL, &folder);
814 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
815 ok(folder == NULL, "got %p\n", folder);
817 hr = IFileSystem3_GetFolder(fs3, NULL, NULL);
818 ok(hr == E_POINTER, "got 0x%08x\n", hr);
820 /* something that doesn't exist */
821 str = SysAllocString(dummyW);
823 hr = IFileSystem3_GetFolder(fs3, str, NULL);
824 ok(hr == E_POINTER, "got 0x%08x\n", hr);
826 folder = (void*)0xdeadbeef;
827 hr = IFileSystem3_GetFolder(fs3, str, &folder);
828 ok(hr == CTL_E_PATHNOTFOUND, "got 0x%08x\n", hr);
829 ok(folder == NULL, "got %p\n", folder);
830 SysFreeString(str);
832 GetWindowsDirectoryW(buffW, MAX_PATH);
833 str = SysAllocString(buffW);
834 hr = IFileSystem3_GetFolder(fs3, str, &folder);
835 ok(hr == S_OK, "got 0x%08x\n", hr);
836 SysFreeString(str);
837 IFolder_Release(folder);
840 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
841 static void test_FolderCollection(void)
843 static const WCHAR fooW[] = {'f','o','o',0};
844 static const WCHAR aW[] = {'\\','a',0};
845 static const WCHAR bW[] = {'\\','b',0};
846 static const WCHAR cW[] = {'\\','c',0};
847 IFolderCollection *folders;
848 WCHAR buffW[MAX_PATH], pathW[MAX_PATH];
849 IEnumVARIANT *enumvar, *clone;
850 LONG count, ref, ref2, i;
851 IUnknown *unk, *unk2;
852 IFolder *folder;
853 ULONG fetched;
854 VARIANT var, var2[2];
855 HRESULT hr;
856 BSTR str;
857 int found_a = 0, found_b = 0, found_c = 0;
859 GetTempPathW(MAX_PATH, pathW);
860 GetTempFileNameW(pathW, fooW, 0, buffW);
861 DeleteFileW(buffW);
862 CreateDirectoryW(buffW, NULL);
864 str = SysAllocString(buffW);
865 hr = IFileSystem3_GetFolder(fs3, str, &folder);
866 ok(hr == S_OK, "got 0x%08x\n", hr);
867 SysFreeString(str);
869 hr = IFolder_get_SubFolders(folder, NULL);
870 ok(hr == E_POINTER, "got 0x%08x\n", hr);
872 hr = IFolder_get_Path(folder, NULL);
873 ok(hr == E_POINTER, "got 0x%08x\n", hr);
875 hr = IFolder_get_Path(folder, &str);
876 ok(hr == S_OK, "got 0x%08x\n", hr);
877 ok(!lstrcmpW(buffW, str), "got %s, expected %s\n", wine_dbgstr_w(str), wine_dbgstr_w(buffW));
878 SysFreeString(str);
880 lstrcpyW(pathW, buffW);
881 lstrcatW(pathW, aW);
882 CreateDirectoryW(pathW, NULL);
884 lstrcpyW(pathW, buffW);
885 lstrcatW(pathW, bW);
886 CreateDirectoryW(pathW, NULL);
888 hr = IFolder_get_SubFolders(folder, &folders);
889 ok(hr == S_OK, "got 0x%08x\n", hr);
890 IFolder_Release(folder);
892 count = 0;
893 hr = IFolderCollection_get_Count(folders, &count);
894 ok(hr == S_OK, "got 0x%08x\n", hr);
895 ok(count == 2, "got %d\n", count);
897 lstrcpyW(pathW, buffW);
898 lstrcatW(pathW, cW);
899 CreateDirectoryW(pathW, NULL);
901 /* every time property is requested it scans directory */
902 count = 0;
903 hr = IFolderCollection_get_Count(folders, &count);
904 ok(hr == S_OK, "got 0x%08x\n", hr);
905 ok(count == 3, "got %d\n", count);
907 hr = IFolderCollection_get__NewEnum(folders, NULL);
908 ok(hr == E_POINTER, "got 0x%08x\n", hr);
910 hr = IFolderCollection_QueryInterface(folders, &IID_IEnumVARIANT, (void**)&unk);
911 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
913 /* NewEnum creates new instance each time it's called */
914 ref = GET_REFCOUNT(folders);
916 unk = NULL;
917 hr = IFolderCollection_get__NewEnum(folders, &unk);
918 ok(hr == S_OK, "got 0x%08x\n", hr);
920 ref2 = GET_REFCOUNT(folders);
921 ok(ref2 == ref + 1, "got %d, %d\n", ref2, ref);
923 unk2 = NULL;
924 hr = IFolderCollection_get__NewEnum(folders, &unk2);
925 ok(hr == S_OK, "got 0x%08x\n", hr);
926 ok(unk != unk2, "got %p, %p\n", unk2, unk);
927 IUnknown_Release(unk2);
929 /* now get IEnumVARIANT */
930 ref = GET_REFCOUNT(folders);
931 hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&enumvar);
932 ok(hr == S_OK, "got 0x%08x\n", hr);
933 ref2 = GET_REFCOUNT(folders);
934 ok(ref2 == ref, "got %d, %d\n", ref2, ref);
936 /* clone enumerator */
937 hr = IEnumVARIANT_Clone(enumvar, &clone);
938 ok(hr == S_OK, "got 0x%08x\n", hr);
939 ok(clone != enumvar, "got %p, %p\n", enumvar, clone);
940 IEnumVARIANT_Release(clone);
942 hr = IEnumVARIANT_Reset(enumvar);
943 ok(hr == S_OK, "got 0x%08x\n", hr);
945 for (i = 0; i < 3; i++)
947 VariantInit(&var);
948 fetched = 0;
949 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
950 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
951 ok(fetched == 1, "%d: got %d\n", i, fetched);
952 ok(V_VT(&var) == VT_DISPATCH, "%d: got type %d\n", i, V_VT(&var));
954 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IFolder, (void**)&folder);
955 ok(hr == S_OK, "got 0x%08x\n", hr);
957 str = NULL;
958 hr = IFolder_get_Name(folder, &str);
959 ok(hr == S_OK, "got 0x%08x\n", hr);
960 if (!lstrcmpW(str, aW + 1))
961 found_a++;
962 else if (!lstrcmpW(str, bW + 1))
963 found_b++;
964 else if (!lstrcmpW(str, cW + 1))
965 found_c++;
966 else
967 ok(0, "unexpected folder %s was found\n", wine_dbgstr_w(str));
968 SysFreeString(str);
970 IFolder_Release(folder);
971 VariantClear(&var);
974 ok(found_a == 1 && found_b == 1 && found_c == 1,
975 "each folder should be found 1 time instead of %d/%d/%d\n",
976 found_a, found_b, found_c);
978 VariantInit(&var);
979 fetched = -1;
980 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
981 ok(hr == S_FALSE, "got 0x%08x\n", hr);
982 ok(fetched == 0, "got %d\n", fetched);
984 hr = IEnumVARIANT_Reset(enumvar);
985 ok(hr == S_OK, "got 0x%08x\n", hr);
986 hr = IEnumVARIANT_Skip(enumvar, 2);
987 ok(hr == S_OK, "got 0x%08x\n", hr);
988 hr = IEnumVARIANT_Skip(enumvar, 0);
989 ok(hr == S_OK, "got 0x%08x\n", hr);
991 VariantInit(&var2[0]);
992 VariantInit(&var2[1]);
993 fetched = -1;
994 hr = IEnumVARIANT_Next(enumvar, 0, var2, &fetched);
995 ok(hr == S_OK, "got 0x%08x\n", hr);
996 ok(fetched == 0, "got %d\n", fetched);
997 fetched = -1;
998 hr = IEnumVARIANT_Next(enumvar, 2, var2, &fetched);
999 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1000 ok(fetched == 1, "got %d\n", fetched);
1001 ok(V_VT(&var2[0]) == VT_DISPATCH, "got type %d\n", V_VT(&var2[0]));
1002 VariantClear(&var2[0]);
1003 VariantClear(&var2[1]);
1005 IEnumVARIANT_Release(enumvar);
1006 IUnknown_Release(unk);
1008 lstrcpyW(pathW, buffW);
1009 lstrcatW(pathW, aW);
1010 RemoveDirectoryW(pathW);
1011 lstrcpyW(pathW, buffW);
1012 lstrcatW(pathW, bW);
1013 RemoveDirectoryW(pathW);
1014 lstrcpyW(pathW, buffW);
1015 lstrcatW(pathW, cW);
1016 RemoveDirectoryW(pathW);
1017 RemoveDirectoryW(buffW);
1019 IFolderCollection_Release(folders);
1022 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1023 static void test_FileCollection(void)
1025 static const WCHAR fooW[] = {'\\','f','o','o',0};
1026 static const WCHAR aW[] = {'\\','a',0};
1027 static const WCHAR bW[] = {'\\','b',0};
1028 static const WCHAR cW[] = {'\\','c',0};
1029 WCHAR buffW[MAX_PATH], pathW[MAX_PATH];
1030 IFolder *folder;
1031 IFileCollection *files;
1032 IFile *file;
1033 IEnumVARIANT *enumvar, *clone;
1034 LONG count, ref, ref2, i;
1035 IUnknown *unk, *unk2;
1036 ULONG fetched;
1037 VARIANT var, var2[2];
1038 HRESULT hr;
1039 BSTR str;
1040 HANDLE file_a, file_b, file_c;
1041 int found_a = 0, found_b = 0, found_c = 0;
1043 GetTempPathW(MAX_PATH, pathW);
1044 GetTempFileNameW(pathW, fooW, 0, buffW);
1045 DeleteFileW(buffW);
1046 CreateDirectoryW(buffW, NULL);
1048 str = SysAllocString(buffW);
1049 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1050 ok(hr == S_OK, "got 0x%08x\n", hr);
1051 SysFreeString(str);
1053 hr = IFolder_get_Files(folder, NULL);
1054 ok(hr == E_POINTER, "got 0x%08x\n", hr);
1056 lstrcpyW(pathW, buffW);
1057 lstrcatW(pathW, aW);
1058 file_a = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1059 FILE_FLAG_DELETE_ON_CLOSE, 0);
1060 lstrcpyW(pathW, buffW);
1061 lstrcatW(pathW, bW);
1062 file_b = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1063 FILE_FLAG_DELETE_ON_CLOSE, 0);
1065 hr = IFolder_get_Files(folder, &files);
1066 ok(hr == S_OK, "got 0x%08x\n", hr);
1067 IFolder_Release(folder);
1069 count = 0;
1070 hr = IFileCollection_get_Count(files, &count);
1071 todo_wine
1072 ok(hr == S_OK, "got 0x%08x\n", hr);
1073 todo_wine
1074 ok(count == 2, "got %d\n", count);
1076 lstrcpyW(pathW, buffW);
1077 lstrcatW(pathW, cW);
1078 file_c = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1079 FILE_FLAG_DELETE_ON_CLOSE, 0);
1081 /* every time property is requested it scans directory */
1082 count = 0;
1083 hr = IFileCollection_get_Count(files, &count);
1084 todo_wine
1085 ok(hr == S_OK, "got 0x%08x\n", hr);
1086 todo_wine
1087 ok(count == 3, "got %d\n", count);
1089 hr = IFileCollection_get__NewEnum(files, NULL);
1090 ok(hr == E_POINTER, "got 0x%08x\n", hr);
1092 hr = IFileCollection_QueryInterface(files, &IID_IEnumVARIANT, (void**)&unk);
1093 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
1095 /* NewEnum creates new instance each time it's called */
1096 ref = GET_REFCOUNT(files);
1098 unk = NULL;
1099 hr = IFileCollection_get__NewEnum(files, &unk);
1100 ok(hr == S_OK, "got 0x%08x\n", hr);
1102 ref2 = GET_REFCOUNT(files);
1103 ok(ref2 == ref + 1, "got %d, %d\n", ref2, ref);
1105 unk2 = NULL;
1106 hr = IFileCollection_get__NewEnum(files, &unk2);
1107 ok(hr == S_OK, "got 0x%08x\n", hr);
1108 ok(unk != unk2, "got %p, %p\n", unk2, unk);
1109 IUnknown_Release(unk2);
1111 /* now get IEnumVARIANT */
1112 ref = GET_REFCOUNT(files);
1113 hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&enumvar);
1114 ok(hr == S_OK, "got 0x%08x\n", hr);
1115 ref2 = GET_REFCOUNT(files);
1116 ok(ref2 == ref, "got %d, %d\n", ref2, ref);
1118 /* clone enumerator */
1119 hr = IEnumVARIANT_Clone(enumvar, &clone);
1120 ok(hr == S_OK, "got 0x%08x\n", hr);
1121 ok(clone != enumvar, "got %p, %p\n", enumvar, clone);
1122 IEnumVARIANT_Release(clone);
1124 hr = IEnumVARIANT_Reset(enumvar);
1125 ok(hr == S_OK, "got 0x%08x\n", hr);
1127 for (i = 0; i < 3; i++)
1129 VariantInit(&var);
1130 fetched = 0;
1131 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1132 ok(hr == S_OK, "%d: got 0x%08x\n", i, hr);
1133 ok(fetched == 1, "%d: got %d\n", i, fetched);
1134 ok(V_VT(&var) == VT_DISPATCH, "%d: got type %d\n", i, V_VT(&var));
1136 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IFile, (void **)&file);
1137 ok(hr == S_OK, "got 0x%08x\n", hr);
1139 str = NULL;
1140 hr = IFile_get_Name(file, &str);
1141 ok(hr == S_OK, "got 0x%08x\n", hr);
1142 if (!lstrcmpW(str, aW + 1))
1143 found_a++;
1144 else if (!lstrcmpW(str, bW + 1))
1145 found_b++;
1146 else if (!lstrcmpW(str, cW + 1))
1147 found_c++;
1148 else
1149 ok(0, "unexpected file %s was found\n", wine_dbgstr_w(str));
1150 SysFreeString(str);
1152 IFile_Release(file);
1153 VariantClear(&var);
1156 ok(found_a == 1 && found_b == 1 && found_c == 1,
1157 "each file should be found 1 time instead of %d/%d/%d\n",
1158 found_a, found_b, found_c);
1160 VariantInit(&var);
1161 fetched = -1;
1162 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1163 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1164 ok(fetched == 0, "got %d\n", fetched);
1166 hr = IEnumVARIANT_Reset(enumvar);
1167 ok(hr == S_OK, "got 0x%08x\n", hr);
1168 hr = IEnumVARIANT_Skip(enumvar, 2);
1169 ok(hr == S_OK, "got 0x%08x\n", hr);
1170 hr = IEnumVARIANT_Skip(enumvar, 0);
1171 ok(hr == S_OK, "got 0x%08x\n", hr);
1173 VariantInit(&var2[0]);
1174 VariantInit(&var2[1]);
1175 fetched = -1;
1176 hr = IEnumVARIANT_Next(enumvar, 0, var2, &fetched);
1177 ok(hr == S_OK, "got 0x%08x\n", hr);
1178 ok(fetched == 0, "got %d\n", fetched);
1179 fetched = -1;
1180 hr = IEnumVARIANT_Next(enumvar, 2, var2, &fetched);
1181 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1182 ok(fetched == 1, "got %d\n", fetched);
1183 ok(V_VT(&var2[0]) == VT_DISPATCH, "got type %d\n", V_VT(&var2[0]));
1184 VariantClear(&var2[0]);
1185 VariantClear(&var2[1]);
1187 IEnumVARIANT_Release(enumvar);
1188 IUnknown_Release(unk);
1190 CloseHandle(file_a);
1191 CloseHandle(file_b);
1192 CloseHandle(file_c);
1193 RemoveDirectoryW(buffW);
1195 IFileCollection_Release(files);
1198 static void test_DriveCollection(void)
1200 IDriveCollection *drives;
1201 IEnumVARIANT *enumvar;
1202 ULONG fetched;
1203 VARIANT var;
1204 HRESULT hr;
1205 LONG count;
1207 hr = IFileSystem3_get_Drives(fs3, &drives);
1208 ok(hr == S_OK, "got 0x%08x\n", hr);
1210 hr = IDriveCollection_get__NewEnum(drives, (IUnknown**)&enumvar);
1211 ok(hr == S_OK, "got 0x%08x\n", hr);
1213 hr = IDriveCollection_get_Count(drives, NULL);
1214 ok(hr == E_POINTER, "got 0x%08x\n", hr);
1216 count = 0;
1217 hr = IDriveCollection_get_Count(drives, &count);
1218 ok(hr == S_OK, "got 0x%08x\n", hr);
1219 ok(count > 0, "got %d\n", count);
1221 V_VT(&var) = VT_EMPTY;
1222 fetched = -1;
1223 hr = IEnumVARIANT_Next(enumvar, 0, &var, &fetched);
1224 ok(hr == S_OK, "got 0x%08x\n", hr);
1225 ok(fetched == 0, "got %d\n", fetched);
1227 hr = IEnumVARIANT_Skip(enumvar, 0);
1228 ok(hr == S_OK, "got 0x%08x\n", hr);
1230 hr = IEnumVARIANT_Skip(enumvar, count);
1231 ok(hr == S_OK, "got 0x%08x\n", hr);
1233 hr = IEnumVARIANT_Skip(enumvar, 1);
1234 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1236 /* reset and iterate again */
1237 hr = IEnumVARIANT_Reset(enumvar);
1238 ok(hr == S_OK, "got 0x%08x\n", hr);
1240 while (IEnumVARIANT_Next(enumvar, 1, &var, &fetched) == S_OK) {
1241 IDrive *drive = (IDrive*)V_DISPATCH(&var);
1242 DriveTypeConst type;
1244 hr = IDrive_get_DriveType(drive, &type);
1245 ok(hr == S_OK, "got 0x%08x\n", hr);
1247 hr = IDrive_get_IsReady(drive, NULL);
1248 ok(hr == E_POINTER, "got 0x%08x\n", hr);
1250 hr = IDrive_get_TotalSize(drive, NULL);
1251 ok(hr == E_POINTER, "got 0x%08x\n", hr);
1253 hr = IDrive_get_AvailableSpace(drive, NULL);
1254 ok(hr == E_POINTER, "got 0x%08x\n", hr);
1256 if (type == Fixed) {
1257 VARIANT_BOOL ready = VARIANT_FALSE;
1258 VARIANT size;
1260 hr = IDrive_get_IsReady(drive, &ready);
1261 ok(hr == S_OK, "got 0x%08x\n", hr);
1262 ok(ready == VARIANT_TRUE, "got %x\n", ready);
1264 V_VT(&size) = VT_EMPTY;
1265 hr = IDrive_get_TotalSize(drive, &size);
1266 ok(hr == S_OK, "got 0x%08x\n", hr);
1267 ok(V_VT(&size) == VT_R8, "got %d\n", V_VT(&size));
1268 ok(V_R8(&size) > 0, "got %f\n", V_R8(&size));
1270 V_VT(&size) = VT_EMPTY;
1271 hr = IDrive_get_AvailableSpace(drive, &size);
1272 ok(hr == S_OK, "got 0x%08x\n", hr);
1273 ok(V_VT(&size) == VT_R8, "got %d\n", V_VT(&size));
1274 ok(V_R8(&size) > 0, "got %f\n", V_R8(&size));
1276 VariantClear(&var);
1279 IEnumVARIANT_Release(enumvar);
1280 IDriveCollection_Release(drives);
1283 static void test_CreateTextFile(void)
1285 static const WCHAR scrrunW[] = {'s','c','r','r','u','n','\\',0};
1286 static const WCHAR testfileW[] = {'t','e','s','t','.','t','x','t',0};
1287 WCHAR pathW[MAX_PATH], dirW[MAX_PATH];
1288 ITextStream *stream;
1289 BSTR nameW, str;
1290 HANDLE file;
1291 HRESULT hr;
1292 BOOL ret;
1294 GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW);
1295 lstrcatW(pathW, scrrunW);
1296 lstrcpyW(dirW, pathW);
1297 lstrcatW(pathW, testfileW);
1299 /* dir doesn't exist */
1300 nameW = SysAllocString(pathW);
1301 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1302 ok(hr == CTL_E_PATHNOTFOUND, "got 0x%08x\n", hr);
1304 ret = CreateDirectoryW(dirW, NULL);
1305 ok(ret, "got %d, %d\n", ret, GetLastError());
1307 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1308 ok(hr == S_OK, "got 0x%08x\n", hr);
1310 hr = ITextStream_Read(stream, 1, &str);
1311 ok(hr == CTL_E_BADFILEMODE, "got 0x%08x\n", hr);
1313 ITextStream_Release(stream);
1315 /* check it's created */
1316 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1317 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1318 CloseHandle(file);
1320 /* try to create again with no-overwrite mode */
1321 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1322 ok(hr == CTL_E_FILEALREADYEXISTS, "got 0x%08x\n", hr);
1324 /* now overwrite */
1325 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
1326 ok(hr == S_OK, "got 0x%08x\n", hr);
1327 ITextStream_Release(stream);
1329 DeleteFileW(nameW);
1330 RemoveDirectoryW(dirW);
1331 SysFreeString(nameW);
1334 static void test_WriteLine(void)
1336 static const WCHAR scrrunW[] = {'s','c','r','r','u','n','\\',0};
1337 static const WCHAR testfileW[] = {'t','e','s','t','.','t','x','t',0};
1338 static const WCHAR crlfW[] = {'\r','\n',0};
1339 WCHAR pathW[MAX_PATH], dirW[MAX_PATH];
1340 WCHAR buffW[MAX_PATH], buff2W[MAX_PATH];
1341 char buffA[MAX_PATH];
1342 ITextStream *stream;
1343 DWORD r, len;
1344 HANDLE file;
1345 BSTR nameW;
1346 HRESULT hr;
1347 BOOL ret;
1349 GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW);
1350 lstrcatW(pathW, scrrunW);
1351 lstrcpyW(dirW, pathW);
1352 lstrcatW(pathW, testfileW);
1354 ret = CreateDirectoryW(dirW, NULL);
1355 ok(ret, "got %d, %d\n", ret, GetLastError());
1357 /* create as ASCII file first */
1358 nameW = SysAllocString(pathW);
1359 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1360 ok(hr == S_OK, "got 0x%08x\n", hr);
1362 hr = ITextStream_WriteLine(stream, nameW);
1363 ok(hr == S_OK, "got 0x%08x\n", hr);
1364 ITextStream_Release(stream);
1366 /* check contents */
1367 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1368 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1369 r = 0;
1370 ret = ReadFile(file, buffA, sizeof(buffA), &r, NULL);
1371 ok(ret && r, "read %d, got %d, %d\n", r, ret, GetLastError());
1373 len = MultiByteToWideChar(CP_ACP, 0, buffA, r, buffW, sizeof(buffW)/sizeof(WCHAR));
1374 buffW[len] = 0;
1375 lstrcpyW(buff2W, nameW);
1376 lstrcatW(buff2W, crlfW);
1377 ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
1378 CloseHandle(file);
1379 DeleteFileW(nameW);
1381 /* same for unicode file */
1382 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_TRUE, &stream);
1383 ok(hr == S_OK, "got 0x%08x\n", hr);
1385 hr = ITextStream_WriteLine(stream, nameW);
1386 ok(hr == S_OK, "got 0x%08x\n", hr);
1387 ITextStream_Release(stream);
1389 /* check contents */
1390 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1391 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1392 r = 0;
1393 ret = ReadFile(file, buffW, sizeof(buffW), &r, NULL);
1394 ok(ret && r, "read %d, got %d, %d\n", r, ret, GetLastError());
1395 buffW[r/sizeof(WCHAR)] = 0;
1397 buff2W[0] = 0xfeff;
1398 buff2W[1] = 0;
1399 lstrcatW(buff2W, nameW);
1400 lstrcatW(buff2W, crlfW);
1401 ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
1402 CloseHandle(file);
1403 DeleteFileW(nameW);
1405 RemoveDirectoryW(dirW);
1406 SysFreeString(nameW);
1409 START_TEST(filesystem)
1411 HRESULT hr;
1413 CoInitialize(NULL);
1415 hr = CoCreateInstance(&CLSID_FileSystemObject, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1416 &IID_IFileSystem3, (void**)&fs3);
1417 if(FAILED(hr)) {
1418 win_skip("Could not create FileSystem object: %08x\n", hr);
1419 return;
1422 test_interfaces();
1423 test_createfolder();
1424 test_textstream();
1425 test_GetFileVersion();
1426 test_GetParentFolderName();
1427 test_GetFileName();
1428 test_GetBaseName();
1429 test_GetAbsolutePathName();
1430 test_GetFile();
1431 test_CopyFolder();
1432 test_BuildPath();
1433 test_GetFolder();
1434 test_FolderCollection();
1435 test_FileCollection();
1436 test_DriveCollection();
1437 test_CreateTextFile();
1438 test_WriteLine();
1440 IFileSystem3_Release(fs3);
1442 CoUninitialize();