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
31 #include "wine/test.h"
36 static IFileSystem3
*fs3
;
38 static inline ULONG
get_refcount(IUnknown
*iface
)
40 IUnknown_AddRef(iface
);
41 return IUnknown_Release(iface
);
44 static const WCHAR crlfW
[] = {'\r','\n',0};
45 static const char utf16bom
[] = {0xff,0xfe,0};
47 #define GET_REFCOUNT(iface) \
48 get_refcount((IUnknown*)iface)
50 static inline void get_temp_path(const WCHAR
*prefix
, WCHAR
*path
)
52 WCHAR buffW
[MAX_PATH
];
54 GetTempPathW(MAX_PATH
, buffW
);
55 GetTempFileNameW(buffW
, prefix
, 0, path
);
59 static void test_interfaces(void)
61 static const WCHAR nonexistent_dirW
[] = {
62 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', 0};
63 static const WCHAR pathW
[] = {'p','a','t','h',0};
64 static const WCHAR file_kernel32W
[] = {
65 '\\', 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0};
69 IObjectWithSite
*site
;
72 WCHAR windows_path
[MAX_PATH
];
73 WCHAR file_path
[MAX_PATH
];
75 IFileSystem3_QueryInterface(fs3
, &IID_IDispatch
, (void**)&disp
);
77 GetSystemDirectoryW(windows_path
, MAX_PATH
);
78 lstrcpyW(file_path
, windows_path
);
79 lstrcatW(file_path
, file_kernel32W
);
81 hr
= IDispatch_QueryInterface(disp
, &IID_IObjectWithSite
, (void**)&site
);
82 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
84 hr
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
85 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
88 hr
= IFileSystem3_FileExists(fs3
, NULL
, &b
);
89 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
90 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
92 hr
= IFileSystem3_FileExists(fs3
, NULL
, NULL
);
93 ok(hr
== E_POINTER
, "got 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
95 path
= SysAllocString(pathW
);
97 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
98 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
99 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
102 path
= SysAllocString(file_path
);
104 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
105 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
106 ok(b
== VARIANT_TRUE
, "got %x\n", b
);
109 path
= SysAllocString(windows_path
);
111 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
112 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
113 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
117 hr
= IFileSystem3_FolderExists(fs3
, NULL
, NULL
);
118 ok(hr
== E_POINTER
, "got 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
120 path
= SysAllocString(windows_path
);
121 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
122 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
123 ok(b
== VARIANT_TRUE
, "Folder doesn't exists\n");
126 path
= SysAllocString(nonexistent_dirW
);
127 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
128 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
129 ok(b
== VARIANT_FALSE
, "Folder exists\n");
132 path
= SysAllocString(file_path
);
133 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
134 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
135 ok(b
== VARIANT_FALSE
, "Folder exists\n");
138 IDispatch_Release(disp
);
141 static void test_createfolder(void)
143 WCHAR buffW
[MAX_PATH
];
149 get_temp_path(NULL
, buffW
);
150 ret
= CreateDirectoryW(buffW
, NULL
);
151 ok(ret
, "got %d, %d\n", ret
, GetLastError());
153 /* create existing directory */
154 path
= SysAllocString(buffW
);
155 folder
= (void*)0xdeabeef;
156 hr
= IFileSystem3_CreateFolder(fs3
, path
, &folder
);
157 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x\n", hr
);
158 ok(folder
== NULL
, "got %p\n", folder
);
160 RemoveDirectoryW(buffW
);
163 static void test_textstream(void)
165 static const WCHAR testfileW
[] = {'t','e','s','t','f','i','l','e','.','t','x','t',0};
174 file
= CreateFileW(testfileW
, GENERIC_READ
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
177 name
= SysAllocString(testfileW
);
179 hr
= IFileSystem3_FileExists(fs3
, name
, &b
);
180 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
181 ok(b
== VARIANT_TRUE
, "got %x\n", b
);
183 /* different mode combinations */
184 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
| ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
185 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
187 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
| ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
188 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
190 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
| ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
191 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
193 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
194 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
195 hr
= ITextStream_Read(stream
, 1, &data
);
196 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
197 ITextStream_Release(stream
);
199 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
, VARIANT_FALSE
, TristateFalse
, &stream
);
200 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
201 hr
= ITextStream_Read(stream
, 1, &data
);
202 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
203 ITextStream_Release(stream
);
205 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
206 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
208 /* try to write when open for reading */
209 hr
= ITextStream_WriteLine(stream
, name
);
210 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
212 hr
= ITextStream_Write(stream
, name
);
213 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
215 hr
= ITextStream_get_AtEndOfStream(stream
, NULL
);
216 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
219 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
220 ok(hr
== S_OK
|| broken(hr
== S_FALSE
), "got 0x%08x\n", hr
);
221 ok(b
== VARIANT_TRUE
, "got 0x%x\n", b
);
223 ITextStream_Release(stream
);
225 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
, VARIANT_FALSE
, TristateFalse
, &stream
);
226 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
229 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
230 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
231 ok(b
== VARIANT_TRUE
|| broken(b
== 10), "got 0x%x\n", b
);
234 hr
= ITextStream_get_AtEndOfLine(stream
, &b
);
236 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
237 ok(b
== VARIANT_FALSE
|| broken(b
== 10), "got 0x%x\n", b
);
239 hr
= ITextStream_Read(stream
, 1, &data
);
240 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
242 hr
= ITextStream_ReadLine(stream
, &data
);
243 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
245 hr
= ITextStream_ReadAll(stream
, &data
);
246 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
248 ITextStream_Release(stream
);
250 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
251 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
254 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
255 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
256 ok(b
== VARIANT_TRUE
|| broken(b
== 10), "got 0x%x\n", b
);
259 hr
= ITextStream_get_AtEndOfLine(stream
, &b
);
261 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
262 ok(b
== VARIANT_FALSE
|| broken(b
== 10), "got 0x%x\n", b
);
264 hr
= ITextStream_Read(stream
, 1, &data
);
265 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
267 hr
= ITextStream_ReadLine(stream
, &data
);
268 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
270 hr
= ITextStream_ReadAll(stream
, &data
);
271 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
273 ITextStream_Release(stream
);
275 /* now with non-empty file */
276 file
= CreateFileW(testfileW
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
277 ret
= WriteFile(file
, testfileW
, sizeof(testfileW
), &written
, NULL
);
278 ok(ret
&& written
== sizeof(testfileW
), "got %d\n", ret
);
281 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
282 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
284 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
285 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
286 ok(b
== VARIANT_FALSE
, "got 0x%x\n", b
);
287 ITextStream_Release(stream
);
290 DeleteFileW(testfileW
);
293 static void test_GetFileVersion(void)
295 static const WCHAR k32W
[] = {'\\','k','e','r','n','e','l','3','2','.','d','l','l',0};
296 static const WCHAR k33W
[] = {'\\','k','e','r','n','e','l','3','3','.','d','l','l',0};
297 WCHAR pathW
[MAX_PATH
], filenameW
[MAX_PATH
];
301 GetSystemDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
303 lstrcpyW(filenameW
, pathW
);
304 lstrcatW(filenameW
, k32W
);
306 path
= SysAllocString(filenameW
);
307 hr
= IFileSystem3_GetFileVersion(fs3
, path
, &version
);
308 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
309 ok(*version
!= 0, "got %s\n", wine_dbgstr_w(version
));
310 SysFreeString(version
);
313 lstrcpyW(filenameW
, pathW
);
314 lstrcatW(filenameW
, k33W
);
316 path
= SysAllocString(filenameW
);
317 version
= (void*)0xdeadbeef;
318 hr
= IFileSystem3_GetFileVersion(fs3
, path
, &version
);
319 ok(broken(hr
== S_OK
) || hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "got 0x%08x\n", hr
);
322 ok(*version
== 0, "got %s\n", wine_dbgstr_w(version
));
323 SysFreeString(version
);
326 ok(version
== (void*)0xdeadbeef, "got %p\n", version
);
330 static void test_GetParentFolderName(void)
332 static const WCHAR path1
[] = {'a',0};
333 static const WCHAR path2
[] = {'a','/','a','/','a',0};
334 static const WCHAR path3
[] = {'a','\\','a','\\','a',0};
335 static const WCHAR path4
[] = {'a','/','a','/','/','\\','\\',0};
336 static const WCHAR path5
[] = {'c',':','\\','\\','a',0};
337 static const WCHAR path6
[] = {'a','c',':','\\','a',0};
338 static const WCHAR result2
[] = {'a','/','a',0};
339 static const WCHAR result3
[] = {'a','\\','a',0};
340 static const WCHAR result4
[] = {'a',0};
341 static const WCHAR result5
[] = {'c',':','\\',0};
342 static const WCHAR result6
[] = {'a','c',':',0};
344 static const struct {
361 hr
= IFileSystem3_GetParentFolderName(fs3
, NULL
, NULL
);
362 ok(hr
== E_POINTER
, "GetParentFolderName returned %x, expected E_POINTER\n", hr
);
364 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
365 result
= (BSTR
)0xdeadbeef;
366 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
367 hr
= IFileSystem3_GetParentFolderName(fs3
, path
, &result
);
368 ok(hr
== S_OK
, "%d) GetParentFolderName returned %x, expected S_OK\n", i
, hr
);
370 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
372 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
374 SysFreeString(result
);
378 static void test_GetFileName(void)
380 static const WCHAR path1
[] = {'a',0};
381 static const WCHAR path2
[] = {'a','/','a','.','b',0};
382 static const WCHAR path3
[] = {'a','\\',0};
383 static const WCHAR path4
[] = {'c',':',0};
384 static const WCHAR path5
[] = {'/','\\',0};
385 static const WCHAR result2
[] = {'a','.','b',0};
386 static const WCHAR result3
[] = {'a',0};
388 static const struct {
404 hr
= IFileSystem3_GetFileName(fs3
, NULL
, NULL
);
405 ok(hr
== E_POINTER
, "GetFileName returned %x, expected E_POINTER\n", hr
);
407 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
408 result
= (BSTR
)0xdeadbeef;
409 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
410 hr
= IFileSystem3_GetFileName(fs3
, path
, &result
);
411 ok(hr
== S_OK
, "%d) GetFileName returned %x, expected S_OK\n", i
, hr
);
413 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
415 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
417 SysFreeString(result
);
421 static void test_GetBaseName(void)
423 static const WCHAR path1
[] = {'a',0};
424 static const WCHAR path2
[] = {'a','/','a','.','b','.','c',0};
425 static const WCHAR path3
[] = {'a','.','b','\\',0};
426 static const WCHAR path4
[] = {'c',':',0};
427 static const WCHAR path5
[] = {'/','\\',0};
428 static const WCHAR path6
[] = {'.','a',0};
429 static const WCHAR result1
[] = {'a',0};
430 static const WCHAR result2
[] = {'a','.','b',0};
431 static const WCHAR result6
[] = {0};
433 static const struct {
450 hr
= IFileSystem3_GetBaseName(fs3
, NULL
, NULL
);
451 ok(hr
== E_POINTER
, "GetBaseName returned %x, expected E_POINTER\n", hr
);
453 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
454 result
= (BSTR
)0xdeadbeef;
455 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
456 hr
= IFileSystem3_GetBaseName(fs3
, path
, &result
);
457 ok(hr
== S_OK
, "%d) GetBaseName returned %x, expected S_OK\n", i
, hr
);
459 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
461 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
463 SysFreeString(result
);
467 static void test_GetAbsolutePathName(void)
469 static const WCHAR dir1
[] = {'t','e','s','t','_','d','i','r','1',0};
470 static const WCHAR dir2
[] = {'t','e','s','t','_','d','i','r','2',0};
471 static const WCHAR dir_match1
[] = {'t','e','s','t','_','d','i','r','*',0};
472 static const WCHAR dir_match2
[] = {'t','e','s','t','_','d','i','*',0};
473 static const WCHAR cur_dir
[] = {'.',0};
475 WIN32_FIND_DATAW fdata
;
477 WCHAR buf
[MAX_PATH
], buf2
[MAX_PATH
];
481 hr
= IFileSystem3_GetAbsolutePathName(fs3
, NULL
, NULL
);
482 ok(hr
== E_POINTER
, "GetAbsolutePathName returned %x, expected E_POINTER\n", hr
);
484 hr
= IFileSystem3_GetAbsolutePathName(fs3
, NULL
, &result
);
485 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
486 GetFullPathNameW(cur_dir
, MAX_PATH
, buf
, NULL
);
487 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
488 SysFreeString(result
);
490 find
= FindFirstFileW(dir_match2
, &fdata
);
491 if(find
!= INVALID_HANDLE_VALUE
) {
492 skip("GetAbsolutePathName tests\n");
497 path
= SysAllocString(dir_match1
);
498 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
499 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
500 GetFullPathNameW(dir_match1
, MAX_PATH
, buf2
, NULL
);
501 ok(!lstrcmpiW(buf2
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf2
));
502 SysFreeString(result
);
504 ok(CreateDirectoryW(dir1
, NULL
), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir1
));
505 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
506 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
507 GetFullPathNameW(dir1
, MAX_PATH
, buf
, NULL
);
508 ok(!lstrcmpiW(buf
, result
) || broken(!lstrcmpiW(buf2
, result
)), "result = %s, expected %s\n",
509 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
510 SysFreeString(result
);
512 ok(CreateDirectoryW(dir2
, NULL
), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir2
));
513 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
514 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
515 if(!lstrcmpiW(buf
, result
) || !lstrcmpiW(buf2
, result
)) {
516 ok(!lstrcmpiW(buf
, result
) || broken(!lstrcmpiW(buf2
, result
)), "result = %s, expected %s\n",
517 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
519 GetFullPathNameW(dir2
, MAX_PATH
, buf
, NULL
);
520 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n",
521 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
523 SysFreeString(result
);
526 path
= SysAllocString(dir_match2
);
527 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
528 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
529 GetFullPathNameW(dir_match2
, MAX_PATH
, buf
, NULL
);
530 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
531 SysFreeString(result
);
534 RemoveDirectoryW(dir1
);
535 RemoveDirectoryW(dir2
);
538 static void test_GetFile(void)
540 static const WCHAR slW
[] = {'\\',0};
542 WCHAR pathW
[MAX_PATH
];
551 get_temp_path(NULL
, pathW
);
553 path
= SysAllocString(pathW
);
554 hr
= IFileSystem3_GetFile(fs3
, path
, NULL
);
555 ok(hr
== E_POINTER
, "GetFile returned %x, expected E_POINTER\n", hr
);
556 hr
= IFileSystem3_GetFile(fs3
, NULL
, &file
);
557 ok(hr
== E_INVALIDARG
, "GetFile returned %x, expected E_INVALIDARG\n", hr
);
559 file
= (IFile
*)0xdeadbeef;
560 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
561 ok(!file
, "file != NULL\n");
562 ok(hr
== CTL_E_FILENOTFOUND
, "GetFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
564 hf
= CreateFileW(pathW
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_READONLY
, NULL
);
565 if(hf
== INVALID_HANDLE_VALUE
) {
566 skip("Can't create temporary file\n");
572 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
573 ok(hr
== S_OK
, "GetFile returned %x, expected S_OK\n", hr
);
575 hr
= IFile_get_Attributes(file
, &fa
);
576 gfa
= GetFileAttributesW(pathW
) & (FILE_ATTRIBUTE_READONLY
| FILE_ATTRIBUTE_HIDDEN
|
577 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_ARCHIVE
|
578 FILE_ATTRIBUTE_REPARSE_POINT
| FILE_ATTRIBUTE_COMPRESSED
);
579 ok(hr
== S_OK
, "get_Attributes returned %x, expected S_OK\n", hr
);
580 ok(fa
== gfa
, "fa = %x, expected %x\n", fa
, gfa
);
582 hr
= IFile_get_Size(file
, &size
);
583 ok(hr
== S_OK
, "get_Size returned %x, expected S_OK\n", hr
);
584 ok(V_VT(&size
) == VT_I4
, "V_VT(&size) = %d, expected VT_I4\n", V_VT(&size
));
585 ok(V_I4(&size
) == 0, "V_I4(&size) = %d, expected 0\n", V_I4(&size
));
588 hr
= IFileSystem3_DeleteFile(fs3
, path
, FALSE
);
589 ok(hr
==CTL_E_PERMISSIONDENIED
|| broken(hr
==S_OK
),
590 "DeleteFile returned %x, expected CTL_E_PERMISSIONDENIED\n", hr
);
592 hr
= IFileSystem3_DeleteFile(fs3
, path
, TRUE
);
593 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
595 hr
= IFileSystem3_DeleteFile(fs3
, path
, TRUE
);
596 ok(hr
== CTL_E_FILENOTFOUND
, "DeleteFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
600 /* try with directory */
601 lstrcatW(pathW
, slW
);
602 ret
= CreateDirectoryW(pathW
, NULL
);
603 ok(ret
, "got %d, error %d\n", ret
, GetLastError());
605 path
= SysAllocString(pathW
);
606 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
607 ok(hr
== CTL_E_FILENOTFOUND
, "GetFile returned %x, expected S_OK\n", hr
);
610 RemoveDirectoryW(pathW
);
613 static inline BOOL
create_file(const WCHAR
*name
)
615 HANDLE f
= CreateFileW(name
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, 0, NULL
);
617 return f
!= INVALID_HANDLE_VALUE
;
620 static inline void create_path(const WCHAR
*folder
, const WCHAR
*name
, WCHAR
*ret
)
622 DWORD len
= lstrlenW(folder
);
623 memmove(ret
, folder
, len
*sizeof(WCHAR
));
625 memmove(ret
+len
+1, name
, (lstrlenW(name
)+1)*sizeof(WCHAR
));
628 static void test_CopyFolder(void)
630 static const WCHAR filesystem3_dir
[] = {'f','i','l','e','s','y','s','t','e','m','3','_','t','e','s','t',0};
631 static const WCHAR s1
[] = {'s','r','c','1',0};
632 static const WCHAR s
[] = {'s','r','c','*',0};
633 static const WCHAR d
[] = {'d','s','t',0};
634 static const WCHAR empty
[] = {0};
640 if(!CreateDirectoryW(filesystem3_dir
, NULL
)) {
641 skip("can't create temporary directory\n");
645 create_path(filesystem3_dir
, s1
, tmp
);
646 bsrc
= SysAllocString(tmp
);
647 create_path(filesystem3_dir
, d
, tmp
);
648 bdst
= SysAllocString(tmp
);
649 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
650 ok(hr
== CTL_E_FILENOTFOUND
, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
652 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
653 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
655 ok(create_file(bsrc
), "can't create %s file\n", wine_dbgstr_w(bsrc
));
656 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
657 ok(hr
== S_OK
, "CopyFile returned %x, expected S_OK\n", hr
);
659 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
660 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
662 hr
= IFileSystem3_DeleteFile(fs3
, bsrc
, VARIANT_FALSE
);
663 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
665 ok(CreateDirectoryW(bsrc
, NULL
), "can't create %s\n", wine_dbgstr_w(bsrc
));
666 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
667 ok(hr
== CTL_E_FILENOTFOUND
, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
669 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
670 ok(hr
== CTL_E_FILEALREADYEXISTS
, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
672 hr
= IFileSystem3_DeleteFile(fs3
, bdst
, VARIANT_TRUE
);
673 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
675 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
676 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
678 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
679 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
680 create_path(tmp
, s1
, tmp
);
681 ok(GetFileAttributesW(tmp
) == INVALID_FILE_ATTRIBUTES
,
682 "%s file exists\n", wine_dbgstr_w(tmp
));
684 create_path(filesystem3_dir
, d
, tmp
);
685 create_path(tmp
, empty
, tmp
);
687 bdst
= SysAllocString(tmp
);
688 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
689 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
690 create_path(tmp
, s1
, tmp
);
691 ok(GetFileAttributesW(tmp
) != INVALID_FILE_ATTRIBUTES
,
692 "%s directory doesn't exist\n", wine_dbgstr_w(tmp
));
693 ok(RemoveDirectoryW(tmp
), "can't remove %s directory\n", wine_dbgstr_w(tmp
));
694 create_path(filesystem3_dir
, d
, tmp
);
696 bdst
= SysAllocString(tmp
);
699 create_path(filesystem3_dir
, s
, tmp
);
701 bsrc
= SysAllocString(tmp
);
702 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
703 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
704 create_path(filesystem3_dir
, d
, tmp
);
705 create_path(tmp
, s1
, tmp
);
706 ok(GetFileAttributesW(tmp
) != INVALID_FILE_ATTRIBUTES
,
707 "%s directory doesn't exist\n", wine_dbgstr_w(tmp
));
709 hr
= IFileSystem3_DeleteFolder(fs3
, bdst
, VARIANT_FALSE
);
710 ok(hr
== S_OK
, "DeleteFolder returned %x, expected S_OK\n", hr
);
712 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
713 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
715 create_path(filesystem3_dir
, s1
, tmp
);
717 bsrc
= SysAllocString(tmp
);
718 create_path(tmp
, s1
, tmp
);
719 ok(create_file(tmp
), "can't create %s file\n", wine_dbgstr_w(tmp
));
720 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_FALSE
);
721 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
723 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_FALSE
);
724 ok(hr
== CTL_E_FILEALREADYEXISTS
, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
726 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
727 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
731 bsrc
= SysAllocString(filesystem3_dir
);
732 hr
= IFileSystem3_DeleteFolder(fs3
, bsrc
, VARIANT_FALSE
);
733 ok(hr
== S_OK
, "DeleteFolder returned %x, expected S_OK\n", hr
);
737 static BSTR
bstr_from_str(const char *str
)
739 int len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
740 BSTR ret
= SysAllocStringLen(NULL
, len
- 1); /* NUL character added automatically */
741 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
745 struct buildpath_test
752 static struct buildpath_test buildpath_data
[] =
754 { "C:\\path", "..\\name.tmp", "C:\\path\\..\\name.tmp" },
755 { "C:\\path", "\\name.tmp", "C:\\path\\name.tmp" },
756 { "C:\\path", "name.tmp", "C:\\path\\name.tmp" },
757 { "C:\\path\\", "name.tmp", "C:\\path\\name.tmp" },
758 { "C:\\path", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
759 { "C:\\path\\", "\\name.tmp", "C:\\path\\name.tmp" },
760 { "C:\\path\\", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
761 { "C:\\path\\\\", "\\\\name.tmp", "C:\\path\\\\\\name.tmp" },
762 { "C:\\\\", "\\name.tmp", "C:\\\\name.tmp" },
763 { "C:", "name.tmp", "C:name.tmp" },
764 { "C:", "\\\\name.tmp", "C:\\\\name.tmp" },
768 static void test_BuildPath(void)
770 struct buildpath_test
*ptr
= buildpath_data
;
775 hr
= IFileSystem3_BuildPath(fs3
, NULL
, NULL
, NULL
);
776 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
778 ret
= (BSTR
)0xdeadbeef;
779 hr
= IFileSystem3_BuildPath(fs3
, NULL
, NULL
, &ret
);
780 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
781 ok(*ret
== 0, "got %p\n", ret
);
784 ret
= (BSTR
)0xdeadbeef;
785 path
= bstr_from_str("path");
786 hr
= IFileSystem3_BuildPath(fs3
, path
, NULL
, &ret
);
787 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
788 ok(!lstrcmpW(ret
, path
), "got %s\n", wine_dbgstr_w(ret
));
792 ret
= (BSTR
)0xdeadbeef;
793 path
= bstr_from_str("path");
794 hr
= IFileSystem3_BuildPath(fs3
, NULL
, path
, &ret
);
795 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
796 ok(!lstrcmpW(ret
, path
), "got %s\n", wine_dbgstr_w(ret
));
805 path
= bstr_from_str(ptr
->path
);
806 name
= bstr_from_str(ptr
->name
);
807 result
= bstr_from_str(ptr
->result
);
808 hr
= IFileSystem3_BuildPath(fs3
, path
, name
, &ret
);
809 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
812 ok(!lstrcmpW(ret
, result
), "%d: got wrong path %s, expected %s\n", i
, wine_dbgstr_w(ret
),
813 wine_dbgstr_w(result
));
818 SysFreeString(result
);
825 static void test_GetFolder(void)
827 static const WCHAR dummyW
[] = {'d','u','m','m','y',0};
828 WCHAR buffW
[MAX_PATH
];
833 folder
= (void*)0xdeadbeef;
834 hr
= IFileSystem3_GetFolder(fs3
, NULL
, &folder
);
835 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
836 ok(folder
== NULL
, "got %p\n", folder
);
838 hr
= IFileSystem3_GetFolder(fs3
, NULL
, NULL
);
839 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
841 /* something that doesn't exist */
842 str
= SysAllocString(dummyW
);
844 hr
= IFileSystem3_GetFolder(fs3
, str
, NULL
);
845 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
847 folder
= (void*)0xdeadbeef;
848 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
849 ok(hr
== CTL_E_PATHNOTFOUND
, "got 0x%08x\n", hr
);
850 ok(folder
== NULL
, "got %p\n", folder
);
853 GetWindowsDirectoryW(buffW
, MAX_PATH
);
854 str
= SysAllocString(buffW
);
855 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
856 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
858 IFolder_Release(folder
);
861 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
862 static void test_FolderCollection(void)
864 static const WCHAR fooW
[] = {'f','o','o',0};
865 static const WCHAR aW
[] = {'\\','a',0};
866 static const WCHAR bW
[] = {'\\','b',0};
867 static const WCHAR cW
[] = {'\\','c',0};
868 IFolderCollection
*folders
;
869 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
870 IEnumVARIANT
*enumvar
, *clone
;
871 LONG count
, ref
, ref2
, i
;
872 IUnknown
*unk
, *unk2
;
875 VARIANT var
, var2
[2];
878 int found_a
= 0, found_b
= 0, found_c
= 0;
880 get_temp_path(fooW
, buffW
);
881 CreateDirectoryW(buffW
, NULL
);
883 str
= SysAllocString(buffW
);
884 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
885 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
888 hr
= IFolder_get_SubFolders(folder
, NULL
);
889 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
891 hr
= IFolder_get_Path(folder
, NULL
);
892 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
894 hr
= IFolder_get_Path(folder
, &str
);
895 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
896 ok(!lstrcmpiW(buffW
, str
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
899 lstrcpyW(pathW
, buffW
);
901 CreateDirectoryW(pathW
, NULL
);
903 lstrcpyW(pathW
, buffW
);
905 CreateDirectoryW(pathW
, NULL
);
907 hr
= IFolder_get_SubFolders(folder
, &folders
);
908 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
909 IFolder_Release(folder
);
912 hr
= IFolderCollection_get_Count(folders
, &count
);
913 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
914 ok(count
== 2, "got %d\n", count
);
916 lstrcpyW(pathW
, buffW
);
918 CreateDirectoryW(pathW
, NULL
);
920 /* every time property is requested it scans directory */
922 hr
= IFolderCollection_get_Count(folders
, &count
);
923 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
924 ok(count
== 3, "got %d\n", count
);
926 hr
= IFolderCollection_get__NewEnum(folders
, NULL
);
927 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
929 hr
= IFolderCollection_QueryInterface(folders
, &IID_IEnumVARIANT
, (void**)&unk
);
930 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
932 /* NewEnum creates new instance each time it's called */
933 ref
= GET_REFCOUNT(folders
);
936 hr
= IFolderCollection_get__NewEnum(folders
, &unk
);
937 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
939 ref2
= GET_REFCOUNT(folders
);
940 ok(ref2
== ref
+ 1, "got %d, %d\n", ref2
, ref
);
943 hr
= IFolderCollection_get__NewEnum(folders
, &unk2
);
944 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
945 ok(unk
!= unk2
, "got %p, %p\n", unk2
, unk
);
946 IUnknown_Release(unk2
);
948 /* now get IEnumVARIANT */
949 ref
= GET_REFCOUNT(folders
);
950 hr
= IUnknown_QueryInterface(unk
, &IID_IEnumVARIANT
, (void**)&enumvar
);
951 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
952 ref2
= GET_REFCOUNT(folders
);
953 ok(ref2
== ref
, "got %d, %d\n", ref2
, ref
);
955 /* clone enumerator */
956 hr
= IEnumVARIANT_Clone(enumvar
, &clone
);
957 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
958 ok(clone
!= enumvar
, "got %p, %p\n", enumvar
, clone
);
959 IEnumVARIANT_Release(clone
);
961 hr
= IEnumVARIANT_Reset(enumvar
);
962 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
964 for (i
= 0; i
< 3; i
++)
968 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
969 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
970 ok(fetched
== 1, "%d: got %d\n", i
, fetched
);
971 ok(V_VT(&var
) == VT_DISPATCH
, "%d: got type %d\n", i
, V_VT(&var
));
973 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IFolder
, (void**)&folder
);
974 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
977 hr
= IFolder_get_Name(folder
, &str
);
978 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
979 if (!lstrcmpW(str
, aW
+ 1))
981 else if (!lstrcmpW(str
, bW
+ 1))
983 else if (!lstrcmpW(str
, cW
+ 1))
986 ok(0, "unexpected folder %s was found\n", wine_dbgstr_w(str
));
989 IFolder_Release(folder
);
993 ok(found_a
== 1 && found_b
== 1 && found_c
== 1,
994 "each folder should be found 1 time instead of %d/%d/%d\n",
995 found_a
, found_b
, found_c
);
999 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1000 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1001 ok(fetched
== 0, "got %d\n", fetched
);
1003 hr
= IEnumVARIANT_Reset(enumvar
);
1004 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1005 hr
= IEnumVARIANT_Skip(enumvar
, 2);
1006 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1007 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1008 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1010 VariantInit(&var2
[0]);
1011 VariantInit(&var2
[1]);
1013 hr
= IEnumVARIANT_Next(enumvar
, 0, var2
, &fetched
);
1014 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1015 ok(fetched
== 0, "got %d\n", fetched
);
1017 hr
= IEnumVARIANT_Next(enumvar
, 2, var2
, &fetched
);
1018 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1019 ok(fetched
== 1, "got %d\n", fetched
);
1020 ok(V_VT(&var2
[0]) == VT_DISPATCH
, "got type %d\n", V_VT(&var2
[0]));
1021 VariantClear(&var2
[0]);
1022 VariantClear(&var2
[1]);
1024 IEnumVARIANT_Release(enumvar
);
1025 IUnknown_Release(unk
);
1027 lstrcpyW(pathW
, buffW
);
1028 lstrcatW(pathW
, aW
);
1029 RemoveDirectoryW(pathW
);
1030 lstrcpyW(pathW
, buffW
);
1031 lstrcatW(pathW
, bW
);
1032 RemoveDirectoryW(pathW
);
1033 lstrcpyW(pathW
, buffW
);
1034 lstrcatW(pathW
, cW
);
1035 RemoveDirectoryW(pathW
);
1036 RemoveDirectoryW(buffW
);
1038 IFolderCollection_Release(folders
);
1041 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1042 static void test_FileCollection(void)
1044 static const WCHAR fooW
[] = {'\\','f','o','o',0};
1045 static const WCHAR aW
[] = {'\\','a',0};
1046 static const WCHAR bW
[] = {'\\','b',0};
1047 static const WCHAR cW
[] = {'\\','c',0};
1048 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
1050 IFileCollection
*files
;
1052 IEnumVARIANT
*enumvar
, *clone
;
1053 LONG count
, ref
, ref2
, i
;
1054 IUnknown
*unk
, *unk2
;
1056 VARIANT var
, var2
[2];
1059 HANDLE file_a
, file_b
, file_c
;
1060 int found_a
= 0, found_b
= 0, found_c
= 0;
1062 get_temp_path(fooW
, buffW
);
1063 CreateDirectoryW(buffW
, NULL
);
1065 str
= SysAllocString(buffW
);
1066 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
1067 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1070 hr
= IFolder_get_Files(folder
, NULL
);
1071 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1073 lstrcpyW(pathW
, buffW
);
1074 lstrcatW(pathW
, aW
);
1075 file_a
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1076 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1077 lstrcpyW(pathW
, buffW
);
1078 lstrcatW(pathW
, bW
);
1079 file_b
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1080 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1082 hr
= IFolder_get_Files(folder
, &files
);
1083 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1084 IFolder_Release(folder
);
1087 hr
= IFileCollection_get_Count(files
, &count
);
1088 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1089 ok(count
== 2, "got %d\n", count
);
1091 lstrcpyW(pathW
, buffW
);
1092 lstrcatW(pathW
, cW
);
1093 file_c
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1094 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1096 /* every time property is requested it scans directory */
1098 hr
= IFileCollection_get_Count(files
, &count
);
1099 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1100 ok(count
== 3, "got %d\n", count
);
1102 hr
= IFileCollection_get__NewEnum(files
, NULL
);
1103 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1105 hr
= IFileCollection_QueryInterface(files
, &IID_IEnumVARIANT
, (void**)&unk
);
1106 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1108 /* NewEnum creates new instance each time it's called */
1109 ref
= GET_REFCOUNT(files
);
1112 hr
= IFileCollection_get__NewEnum(files
, &unk
);
1113 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1115 ref2
= GET_REFCOUNT(files
);
1116 ok(ref2
== ref
+ 1, "got %d, %d\n", ref2
, ref
);
1119 hr
= IFileCollection_get__NewEnum(files
, &unk2
);
1120 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1121 ok(unk
!= unk2
, "got %p, %p\n", unk2
, unk
);
1122 IUnknown_Release(unk2
);
1124 /* now get IEnumVARIANT */
1125 ref
= GET_REFCOUNT(files
);
1126 hr
= IUnknown_QueryInterface(unk
, &IID_IEnumVARIANT
, (void**)&enumvar
);
1127 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1128 ref2
= GET_REFCOUNT(files
);
1129 ok(ref2
== ref
, "got %d, %d\n", ref2
, ref
);
1131 /* clone enumerator */
1132 hr
= IEnumVARIANT_Clone(enumvar
, &clone
);
1133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1134 ok(clone
!= enumvar
, "got %p, %p\n", enumvar
, clone
);
1135 IEnumVARIANT_Release(clone
);
1137 hr
= IEnumVARIANT_Reset(enumvar
);
1138 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1140 for (i
= 0; i
< 3; i
++)
1144 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1145 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
1146 ok(fetched
== 1, "%d: got %d\n", i
, fetched
);
1147 ok(V_VT(&var
) == VT_DISPATCH
, "%d: got type %d\n", i
, V_VT(&var
));
1149 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IFile
, (void **)&file
);
1150 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1153 hr
= IFile_get_Name(file
, &str
);
1154 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1155 if (!lstrcmpW(str
, aW
+ 1))
1157 else if (!lstrcmpW(str
, bW
+ 1))
1159 else if (!lstrcmpW(str
, cW
+ 1))
1162 ok(0, "unexpected file %s was found\n", wine_dbgstr_w(str
));
1165 IFile_Release(file
);
1169 ok(found_a
== 1 && found_b
== 1 && found_c
== 1,
1170 "each file should be found 1 time instead of %d/%d/%d\n",
1171 found_a
, found_b
, found_c
);
1175 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1176 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1177 ok(fetched
== 0, "got %d\n", fetched
);
1179 hr
= IEnumVARIANT_Reset(enumvar
);
1180 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1181 hr
= IEnumVARIANT_Skip(enumvar
, 2);
1182 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1183 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1184 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1186 VariantInit(&var2
[0]);
1187 VariantInit(&var2
[1]);
1189 hr
= IEnumVARIANT_Next(enumvar
, 0, var2
, &fetched
);
1190 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1191 ok(fetched
== 0, "got %d\n", fetched
);
1193 hr
= IEnumVARIANT_Next(enumvar
, 2, var2
, &fetched
);
1194 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1195 ok(fetched
== 1, "got %d\n", fetched
);
1196 ok(V_VT(&var2
[0]) == VT_DISPATCH
, "got type %d\n", V_VT(&var2
[0]));
1197 VariantClear(&var2
[0]);
1198 VariantClear(&var2
[1]);
1200 IEnumVARIANT_Release(enumvar
);
1201 IUnknown_Release(unk
);
1203 CloseHandle(file_a
);
1204 CloseHandle(file_b
);
1205 CloseHandle(file_c
);
1206 RemoveDirectoryW(buffW
);
1208 IFileCollection_Release(files
);
1211 static void test_DriveCollection(void)
1213 IDriveCollection
*drives
;
1214 IEnumVARIANT
*enumvar
;
1220 hr
= IFileSystem3_get_Drives(fs3
, &drives
);
1221 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1223 hr
= IDriveCollection_get__NewEnum(drives
, (IUnknown
**)&enumvar
);
1224 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1226 hr
= IDriveCollection_get_Count(drives
, NULL
);
1227 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1230 hr
= IDriveCollection_get_Count(drives
, &count
);
1231 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1232 ok(count
> 0, "got %d\n", count
);
1234 V_VT(&var
) = VT_EMPTY
;
1236 hr
= IEnumVARIANT_Next(enumvar
, 0, &var
, &fetched
);
1237 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1238 ok(fetched
== 0, "got %d\n", fetched
);
1240 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1241 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1243 hr
= IEnumVARIANT_Skip(enumvar
, count
);
1244 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1246 hr
= IEnumVARIANT_Skip(enumvar
, 1);
1247 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1249 /* reset and iterate again */
1250 hr
= IEnumVARIANT_Reset(enumvar
);
1251 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1253 while (IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
) == S_OK
) {
1254 IDrive
*drive
= (IDrive
*)V_DISPATCH(&var
);
1255 DriveTypeConst type
;
1258 hr
= IDrive_get_DriveType(drive
, &type
);
1259 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1261 hr
= IDrive_get_DriveLetter(drive
, NULL
);
1262 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1264 hr
= IDrive_get_DriveLetter(drive
, &str
);
1265 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1266 ok(SysStringLen(str
) == 1, "got string %s\n", wine_dbgstr_w(str
));
1269 hr
= IDrive_get_IsReady(drive
, NULL
);
1270 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1272 hr
= IDrive_get_TotalSize(drive
, NULL
);
1273 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1275 hr
= IDrive_get_AvailableSpace(drive
, NULL
);
1276 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1278 hr
= IDrive_get_FreeSpace(drive
, NULL
);
1279 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1281 if (type
== Fixed
) {
1282 VARIANT_BOOL ready
= VARIANT_FALSE
;
1285 hr
= IDrive_get_IsReady(drive
, &ready
);
1286 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1287 ok(ready
== VARIANT_TRUE
, "got %x\n", ready
);
1289 V_VT(&size
) = VT_EMPTY
;
1290 hr
= IDrive_get_TotalSize(drive
, &size
);
1291 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1292 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1293 if (V_VT(&size
) == VT_R8
)
1294 ok(V_R8(&size
) > 0, "got %f\n", V_R8(&size
));
1296 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1298 V_VT(&size
) = VT_EMPTY
;
1299 hr
= IDrive_get_AvailableSpace(drive
, &size
);
1300 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1301 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1302 if (V_VT(&size
) == VT_R8
)
1303 ok(V_R8(&size
) > (double)INT_MAX
, "got %f\n", V_R8(&size
));
1305 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1307 V_VT(&size
) = VT_EMPTY
;
1308 hr
= IDrive_get_FreeSpace(drive
, &size
);
1309 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1310 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1311 if (V_VT(&size
) == VT_R8
)
1312 ok(V_R8(&size
) > 0, "got %f\n", V_R8(&size
));
1314 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1319 IEnumVARIANT_Release(enumvar
);
1320 IDriveCollection_Release(drives
);
1323 static void test_CreateTextFile(void)
1325 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1326 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1327 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[10];
1328 ITextStream
*stream
;
1334 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1335 lstrcatW(pathW
, scrrunW
);
1336 lstrcpyW(dirW
, pathW
);
1337 lstrcatW(pathW
, testfileW
);
1339 /* dir doesn't exist */
1340 nameW
= SysAllocString(pathW
);
1341 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1342 ok(hr
== CTL_E_PATHNOTFOUND
, "got 0x%08x\n", hr
);
1344 ret
= CreateDirectoryW(dirW
, NULL
);
1345 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1347 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1348 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1350 hr
= ITextStream_Read(stream
, 1, &str
);
1351 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1353 ITextStream_Release(stream
);
1355 /* check it's created */
1356 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1357 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1360 /* try to create again with no-overwrite mode */
1361 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1362 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x\n", hr
);
1365 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1366 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1367 ITextStream_Release(stream
);
1369 /* overwrite in Unicode mode, check for BOM */
1370 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_TRUE
, &stream
);
1371 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1372 ITextStream_Release(stream
);
1374 /* File was created in Unicode mode, it contains 0xfffe BOM. Opening it in non-Unicode mode
1375 treats BOM like a valuable data with appropriate CP_ACP -> WCHAR conversion. */
1377 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1379 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1380 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1381 hr
= ITextStream_ReadAll(stream
, &str
);
1382 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1383 ok(!lstrcmpW(str
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1385 ITextStream_Release(stream
);
1388 RemoveDirectoryW(dirW
);
1389 SysFreeString(nameW
);
1392 static void test_WriteLine(void)
1394 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1395 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1396 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
];
1397 WCHAR buffW
[MAX_PATH
], buff2W
[MAX_PATH
];
1398 char buffA
[MAX_PATH
];
1399 ITextStream
*stream
;
1406 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1407 lstrcatW(pathW
, scrrunW
);
1408 lstrcpyW(dirW
, pathW
);
1409 lstrcatW(pathW
, testfileW
);
1411 ret
= CreateDirectoryW(dirW
, NULL
);
1412 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1414 /* create as ASCII file first */
1415 nameW
= SysAllocString(pathW
);
1416 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1417 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1419 hr
= ITextStream_WriteLine(stream
, nameW
);
1420 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1421 ITextStream_Release(stream
);
1423 /* check contents */
1424 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1425 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1427 ret
= ReadFile(file
, buffA
, sizeof(buffA
), &r
, NULL
);
1428 ok(ret
&& r
, "read %d, got %d, %d\n", r
, ret
, GetLastError());
1430 len
= MultiByteToWideChar(CP_ACP
, 0, buffA
, r
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1432 lstrcpyW(buff2W
, nameW
);
1433 lstrcatW(buff2W
, crlfW
);
1434 ok(!lstrcmpW(buff2W
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(buff2W
));
1438 /* same for unicode file */
1439 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1440 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1442 hr
= ITextStream_WriteLine(stream
, nameW
);
1443 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1444 ITextStream_Release(stream
);
1446 /* check contents */
1447 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1448 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1450 ret
= ReadFile(file
, buffW
, sizeof(buffW
), &r
, NULL
);
1451 ok(ret
&& r
, "read %d, got %d, %d\n", r
, ret
, GetLastError());
1452 buffW
[r
/sizeof(WCHAR
)] = 0;
1456 lstrcatW(buff2W
, nameW
);
1457 lstrcatW(buff2W
, crlfW
);
1458 ok(!lstrcmpW(buff2W
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(buff2W
));
1462 RemoveDirectoryW(dirW
);
1463 SysFreeString(nameW
);
1466 static void test_ReadAll(void)
1468 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1469 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1470 static const WCHAR secondlineW
[] = {'s','e','c','o','n','d',0};
1471 static const WCHAR aW
[] = {'A',0};
1472 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[500];
1473 ITextStream
*stream
;
1479 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1480 lstrcatW(pathW
, scrrunW
);
1481 lstrcpyW(dirW
, pathW
);
1482 lstrcatW(pathW
, testfileW
);
1484 ret
= CreateDirectoryW(dirW
, NULL
);
1485 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1487 /* Unicode file -> read with ascii stream */
1488 nameW
= SysAllocString(pathW
);
1489 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1490 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1492 hr
= ITextStream_WriteLine(stream
, nameW
);
1493 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1495 str
= SysAllocString(secondlineW
);
1496 hr
= ITextStream_WriteLine(stream
, str
);
1497 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1500 hr
= ITextStream_ReadAll(stream
, NULL
);
1501 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1503 str
= (void*)0xdeadbeef;
1504 hr
= ITextStream_ReadAll(stream
, &str
);
1505 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1506 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1508 ITextStream_Release(stream
);
1510 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1511 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1513 hr
= ITextStream_ReadAll(stream
, NULL
);
1514 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1516 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1518 hr
= ITextStream_ReadAll(stream
, &str
);
1519 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1521 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1522 ok(str
[0] == buffW
[0] && str
[1] == buffW
[1], "got %s, %d\n", wine_dbgstr_w(str
), SysStringLen(str
));
1524 ITextStream_Release(stream
);
1526 /* Unicode file -> read with unicode stream */
1527 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1528 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1530 lstrcpyW(buffW
, nameW
);
1531 lstrcatW(buffW
, crlfW
);
1532 lstrcatW(buffW
, secondlineW
);
1533 lstrcatW(buffW
, crlfW
);
1535 hr
= ITextStream_ReadAll(stream
, &str
);
1536 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1537 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1540 /* ReadAll one more time */
1541 str
= (void*)0xdeadbeef;
1542 hr
= ITextStream_ReadAll(stream
, &str
);
1543 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1544 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1546 /* ReadLine fails the same way */
1547 str
= (void*)0xdeadbeef;
1548 hr
= ITextStream_ReadLine(stream
, &str
);
1549 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1550 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1551 ITextStream_Release(stream
);
1553 /* Open again and skip first line before ReadAll */
1554 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1555 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1558 hr
= ITextStream_ReadLine(stream
, &str
);
1560 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1561 ok(str
!= NULL
, "got %p\n", str
);
1565 lstrcpyW(buffW
, secondlineW
);
1566 lstrcatW(buffW
, crlfW
);
1568 hr
= ITextStream_ReadAll(stream
, &str
);
1569 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1571 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1573 ITextStream_Release(stream
);
1575 /* ASCII file, read with Unicode stream */
1576 /* 1. one byte content, not enough for Unicode read */
1577 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1578 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1579 str
= SysAllocString(aW
);
1580 hr
= ITextStream_Write(stream
, str
);
1581 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1583 ITextStream_Release(stream
);
1585 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1586 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1588 str
= (void*)0xdeadbeef;
1589 hr
= ITextStream_ReadAll(stream
, &str
);
1590 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1591 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1593 ITextStream_Release(stream
);
1596 RemoveDirectoryW(dirW
);
1597 SysFreeString(nameW
);
1600 static void test_Read(void)
1602 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1603 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1604 static const WCHAR secondlineW
[] = {'s','e','c','o','n','d',0};
1605 static const WCHAR aW
[] = {'A',0};
1606 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[500];
1607 ITextStream
*stream
;
1613 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1614 lstrcatW(pathW
, scrrunW
);
1615 lstrcpyW(dirW
, pathW
);
1616 lstrcatW(pathW
, testfileW
);
1618 ret
= CreateDirectoryW(dirW
, NULL
);
1619 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1621 /* Unicode file -> read with ascii stream */
1622 nameW
= SysAllocString(pathW
);
1623 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1624 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1626 hr
= ITextStream_WriteLine(stream
, nameW
);
1627 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1629 str
= SysAllocString(secondlineW
);
1630 hr
= ITextStream_WriteLine(stream
, str
);
1631 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1634 hr
= ITextStream_Read(stream
, 0, NULL
);
1635 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1637 hr
= ITextStream_Read(stream
, 1, NULL
);
1638 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1640 hr
= ITextStream_Read(stream
, -1, NULL
);
1641 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1643 str
= (void*)0xdeadbeef;
1644 hr
= ITextStream_Read(stream
, 1, &str
);
1645 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1646 ok(str
== NULL
, "got %p\n", str
);
1648 ITextStream_Release(stream
);
1650 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1651 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1653 hr
= ITextStream_Read(stream
, 1, NULL
);
1654 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1656 str
= (void*)0xdeadbeef;
1657 hr
= ITextStream_Read(stream
, -1, &str
);
1658 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1659 ok(str
== NULL
, "got %p\n", str
);
1661 str
= (void*)0xdeadbeef;
1662 hr
= ITextStream_Read(stream
, 0, &str
);
1663 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1664 ok(str
== NULL
, "got %p\n", str
);
1666 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1668 hr
= ITextStream_Read(stream
, 2, &str
);
1669 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1672 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1674 ok(!lstrcmpW(str
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1675 ok(SysStringLen(str
) == 2, "got %d\n", SysStringLen(str
));
1677 ITextStream_Release(stream
);
1679 /* Unicode file -> read with unicode stream */
1680 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1681 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1683 lstrcpyW(buffW
, nameW
);
1684 lstrcatW(buffW
, crlfW
);
1685 lstrcatW(buffW
, secondlineW
);
1686 lstrcatW(buffW
, crlfW
);
1688 hr
= ITextStream_Read(stream
, 500, &str
);
1689 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1690 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1693 /* ReadAll one more time */
1694 str
= (void*)0xdeadbeef;
1695 hr
= ITextStream_Read(stream
, 10, &str
);
1696 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1697 ok(str
== NULL
, "got %p\n", str
);
1699 /* ReadLine fails the same way */
1700 str
= (void*)0xdeadbeef;
1701 hr
= ITextStream_ReadLine(stream
, &str
);
1702 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1703 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef), "got %p\n", str
);
1704 ITextStream_Release(stream
);
1706 /* Open again and skip first line before ReadAll */
1707 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1708 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1711 hr
= ITextStream_ReadLine(stream
, &str
);
1713 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1714 ok(str
!= NULL
, "got %p\n", str
);
1718 lstrcpyW(buffW
, secondlineW
);
1719 lstrcatW(buffW
, crlfW
);
1721 hr
= ITextStream_Read(stream
, 100, &str
);
1722 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1724 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1726 ITextStream_Release(stream
);
1728 /* ASCII file, read with Unicode stream */
1729 /* 1. one byte content, not enough for Unicode read */
1730 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1731 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1732 str
= SysAllocString(aW
);
1733 hr
= ITextStream_Write(stream
, str
);
1734 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1736 ITextStream_Release(stream
);
1738 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1739 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1741 str
= (void*)0xdeadbeef;
1742 hr
= ITextStream_Read(stream
, 500, &str
);
1743 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1744 ok(str
== NULL
, "got %p\n", str
);
1746 ITextStream_Release(stream
);
1749 RemoveDirectoryW(dirW
);
1750 SysFreeString(nameW
);
1753 struct getdrivename_test
{
1754 const WCHAR path
[10];
1755 const WCHAR drive
[5];
1758 static const struct getdrivename_test getdrivenametestdata
[] = {
1759 { {'C',':','\\','1','.','t','s','t',0}, {'C',':',0} },
1760 { {'O',':','\\','1','.','t','s','t',0}, {'O',':',0} },
1761 { {'O',':',0}, {'O',':',0} },
1762 { {'o',':',0}, {'o',':',0} },
1763 { {'O','O',':',0} },
1769 static void test_GetDriveName(void)
1771 const struct getdrivename_test
*ptr
= getdrivenametestdata
;
1775 hr
= IFileSystem3_GetDriveName(fs3
, NULL
, NULL
);
1776 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1778 name
= (void*)0xdeadbeef;
1779 hr
= IFileSystem3_GetDriveName(fs3
, NULL
, &name
);
1780 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1781 ok(name
== NULL
, "got %p\n", name
);
1783 while (*ptr
->path
) {
1784 BSTR path
= SysAllocString(ptr
->path
);
1785 name
= (void*)0xdeadbeef;
1786 hr
= IFileSystem3_GetDriveName(fs3
, path
, &name
);
1787 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1789 ok(!lstrcmpW(ptr
->drive
, name
), "got %s, expected %s\n", wine_dbgstr_w(name
), wine_dbgstr_w(ptr
->drive
));
1791 ok(!*ptr
->drive
, "got %s, expected %s\n", wine_dbgstr_w(name
), wine_dbgstr_w(ptr
->drive
));
1792 SysFreeString(path
);
1793 SysFreeString(name
);
1798 static void test_SerialNumber(void)
1800 IDriveCollection
*drives
;
1807 hr
= IFileSystem3_get_Drives(fs3
, &drives
);
1808 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1810 hr
= IDriveCollection_get__NewEnum(drives
, (IUnknown
**)&iter
);
1811 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1812 IDriveCollection_Release(drives
);
1815 DriveTypeConst type
;
1818 hr
= IEnumVARIANT_Next(iter
, 1, &var
, NULL
);
1819 if (hr
== S_FALSE
) {
1820 skip("No fixed drive found, skipping test.\n");
1821 IEnumVARIANT_Release(iter
);
1824 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1826 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IDrive
, (void**)&drive
);
1827 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1830 hr
= IDrive_get_DriveType(drive
, &type
);
1831 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1835 IDrive_Release(drive
);
1838 hr
= IDrive_get_SerialNumber(drive
, NULL
);
1839 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1841 serial
= 0xdeadbeef;
1842 hr
= IDrive_get_SerialNumber(drive
, &serial
);
1843 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1844 ok(serial
!= 0xdeadbeef, "got %x\n", serial
);
1846 hr
= IDrive_get_FileSystem(drive
, NULL
);
1847 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1850 hr
= IDrive_get_FileSystem(drive
, &name
);
1851 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1852 ok(name
!= NULL
, "got %p\n", name
);
1853 SysFreeString(name
);
1855 hr
= IDrive_get_VolumeName(drive
, NULL
);
1856 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1859 hr
= IDrive_get_VolumeName(drive
, &name
);
1860 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1861 ok(name
!= NULL
, "got %p\n", name
);
1862 SysFreeString(name
);
1864 IDrive_Release(drive
);
1865 IEnumVARIANT_Release(iter
);
1868 START_TEST(filesystem
)
1874 hr
= CoCreateInstance(&CLSID_FileSystemObject
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
1875 &IID_IFileSystem3
, (void**)&fs3
);
1877 win_skip("Could not create FileSystem object: %08x\n", hr
);
1882 test_createfolder();
1884 test_GetFileVersion();
1885 test_GetParentFolderName();
1888 test_GetAbsolutePathName();
1893 test_FolderCollection();
1894 test_FileCollection();
1895 test_DriveCollection();
1896 test_CreateTextFile();
1900 test_GetDriveName();
1901 test_SerialNumber();
1903 IFileSystem3_Release(fs3
);