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 /* w2k and 2k3 error code. */
39 #define E_VAR_NOT_SET 0x800a005b
41 static inline ULONG
get_refcount(IUnknown
*iface
)
43 IUnknown_AddRef(iface
);
44 return IUnknown_Release(iface
);
47 static const WCHAR crlfW
[] = {'\r','\n',0};
48 static const char utf16bom
[] = {0xff,0xfe,0};
50 #define GET_REFCOUNT(iface) \
51 get_refcount((IUnknown*)iface)
53 static inline void get_temp_path(const WCHAR
*prefix
, WCHAR
*path
)
55 WCHAR buffW
[MAX_PATH
];
57 GetTempPathW(MAX_PATH
, buffW
);
58 GetTempFileNameW(buffW
, prefix
, 0, path
);
62 static IDrive
*get_fixed_drive(void)
64 IDriveCollection
*drives
;
69 hr
= IFileSystem3_get_Drives(fs3
, &drives
);
70 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
72 hr
= IDriveCollection_get__NewEnum(drives
, (IUnknown
**)&iter
);
73 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
74 IDriveCollection_Release(drives
);
80 hr
= IEnumVARIANT_Next(iter
, 1, &var
, NULL
);
85 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
87 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IDrive
, (void**)&drive
);
88 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
91 hr
= IDrive_get_DriveType(drive
, &type
);
92 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
96 IDrive_Release(drive
);
99 IEnumVARIANT_Release(iter
);
103 #define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__)
104 static void _test_provideclassinfo(IDispatch
*disp
, const GUID
*guid
, int line
)
106 IProvideClassInfo
*classinfo
;
112 hr
= IDispatch_QueryInterface(disp
, &IID_IProvideClassInfo
, (void **)&classinfo
);
113 ok_(__FILE__
,line
) (hr
== S_OK
, "Failed to get IProvideClassInfo, %#x.\n", hr
);
115 hr
= IProvideClassInfo_GetClassInfo(classinfo
, &ti
);
116 ok_(__FILE__
,line
) (hr
== S_OK
, "GetClassInfo() failed, %#x.\n", hr
);
118 hr
= ITypeInfo_GetTypeAttr(ti
, &attr
);
119 ok_(__FILE__
,line
) (hr
== S_OK
, "GetTypeAttr() failed, %#x.\n", hr
);
121 ok_(__FILE__
,line
) (IsEqualGUID(&attr
->guid
, guid
), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr
->guid
),
122 wine_dbgstr_guid(guid
));
124 hr
= IProvideClassInfo_QueryInterface(classinfo
, &IID_IUnknown
, (void **)&unk
);
125 ok(hr
== S_OK
, "Failed to QI for IUnknown.\n");
126 ok(unk
== (IUnknown
*)disp
, "Got unk %p, original %p.\n", unk
, disp
);
127 IUnknown_Release(unk
);
129 IProvideClassInfo_Release(classinfo
);
130 ITypeInfo_ReleaseTypeAttr(ti
, attr
);
131 ITypeInfo_Release(ti
);
134 static void test_interfaces(void)
136 static const WCHAR nonexistent_dirW
[] = {
137 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', 0};
138 static const WCHAR pathW
[] = {'p','a','t','h',0};
139 static const WCHAR file_kernel32W
[] = {
140 '\\', 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0};
144 IObjectWithSite
*site
;
147 WCHAR windows_path
[MAX_PATH
];
148 WCHAR file_path
[MAX_PATH
];
150 IFileSystem3_QueryInterface(fs3
, &IID_IDispatch
, (void**)&disp
);
152 GetSystemDirectoryW(windows_path
, MAX_PATH
);
153 lstrcpyW(file_path
, windows_path
);
154 lstrcatW(file_path
, file_kernel32W
);
156 test_provideclassinfo(disp
, &CLSID_FileSystemObject
);
158 hr
= IDispatch_QueryInterface(disp
, &IID_IObjectWithSite
, (void**)&site
);
159 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
161 hr
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
162 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
165 hr
= IFileSystem3_FileExists(fs3
, NULL
, &b
);
166 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
167 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
169 hr
= IFileSystem3_FileExists(fs3
, NULL
, NULL
);
170 ok(hr
== E_POINTER
, "got 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
172 path
= SysAllocString(pathW
);
174 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
175 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
176 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
179 path
= SysAllocString(file_path
);
181 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
182 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
183 ok(b
== VARIANT_TRUE
, "got %x\n", b
);
186 path
= SysAllocString(windows_path
);
188 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
189 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
190 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
194 hr
= IFileSystem3_FolderExists(fs3
, NULL
, NULL
);
195 ok(hr
== E_POINTER
, "got 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
197 path
= SysAllocString(windows_path
);
198 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
199 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
200 ok(b
== VARIANT_TRUE
, "Folder doesn't exists\n");
203 path
= SysAllocString(nonexistent_dirW
);
204 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
205 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
206 ok(b
== VARIANT_FALSE
, "Folder exists\n");
209 path
= SysAllocString(file_path
);
210 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
211 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
212 ok(b
== VARIANT_FALSE
, "Folder exists\n");
215 IDispatch_Release(disp
);
218 static void test_createfolder(void)
220 WCHAR buffW
[MAX_PATH
];
226 get_temp_path(NULL
, buffW
);
227 ret
= CreateDirectoryW(buffW
, NULL
);
228 ok(ret
, "got %d, %d\n", ret
, GetLastError());
230 /* create existing directory */
231 path
= SysAllocString(buffW
);
232 folder
= (void*)0xdeabeef;
233 hr
= IFileSystem3_CreateFolder(fs3
, path
, &folder
);
234 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x\n", hr
);
235 ok(folder
== NULL
, "got %p\n", folder
);
237 RemoveDirectoryW(buffW
);
240 static void test_textstream(void)
242 static const WCHAR testfileW
[] = {'t','e','s','t','f','i','l','e','.','t','x','t',0};
251 file
= CreateFileW(testfileW
, GENERIC_READ
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
254 name
= SysAllocString(testfileW
);
256 hr
= IFileSystem3_FileExists(fs3
, name
, &b
);
257 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
258 ok(b
== VARIANT_TRUE
, "got %x\n", b
);
260 /* different mode combinations */
261 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
| ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
262 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
264 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
| ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
265 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
267 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
| ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
268 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
270 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
271 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
272 hr
= ITextStream_Read(stream
, 1, &data
);
273 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
274 ITextStream_Release(stream
);
276 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
, VARIANT_FALSE
, TristateFalse
, &stream
);
277 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
278 hr
= ITextStream_Read(stream
, 1, &data
);
279 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
280 ITextStream_Release(stream
);
282 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
283 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
285 /* try to write when open for reading */
286 hr
= ITextStream_WriteLine(stream
, name
);
287 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
289 hr
= ITextStream_Write(stream
, name
);
290 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
292 hr
= ITextStream_get_AtEndOfStream(stream
, NULL
);
293 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
296 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
297 ok(hr
== S_OK
|| broken(hr
== S_FALSE
), "got 0x%08x\n", hr
);
298 ok(b
== VARIANT_TRUE
, "got 0x%x\n", b
);
300 ITextStream_Release(stream
);
302 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
, VARIANT_FALSE
, TristateFalse
, &stream
);
303 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
306 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
307 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
308 ok(b
== VARIANT_TRUE
|| broken(b
== 10), "got 0x%x\n", b
);
311 hr
= ITextStream_get_AtEndOfLine(stream
, &b
);
313 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
314 ok(b
== VARIANT_FALSE
|| broken(b
== 10), "got 0x%x\n", b
);
316 hr
= ITextStream_Read(stream
, 1, &data
);
317 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
319 hr
= ITextStream_ReadLine(stream
, &data
);
320 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
322 hr
= ITextStream_ReadAll(stream
, &data
);
323 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
325 ITextStream_Release(stream
);
327 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
328 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
331 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
332 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
333 ok(b
== VARIANT_TRUE
|| broken(b
== 10), "got 0x%x\n", b
);
336 hr
= ITextStream_get_AtEndOfLine(stream
, &b
);
338 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
339 ok(b
== VARIANT_FALSE
|| broken(b
== 10), "got 0x%x\n", b
);
341 hr
= ITextStream_Read(stream
, 1, &data
);
342 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
344 hr
= ITextStream_ReadLine(stream
, &data
);
345 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
347 hr
= ITextStream_ReadAll(stream
, &data
);
348 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
350 ITextStream_Release(stream
);
352 /* now with non-empty file */
353 file
= CreateFileW(testfileW
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
354 ret
= WriteFile(file
, testfileW
, sizeof(testfileW
), &written
, NULL
);
355 ok(ret
&& written
== sizeof(testfileW
), "got %d\n", ret
);
358 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
359 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
361 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
362 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
363 ok(b
== VARIANT_FALSE
, "got 0x%x\n", b
);
364 ITextStream_Release(stream
);
367 DeleteFileW(testfileW
);
370 static void test_GetFileVersion(void)
372 static const WCHAR k32W
[] = {'\\','k','e','r','n','e','l','3','2','.','d','l','l',0};
373 static const WCHAR k33W
[] = {'\\','k','e','r','n','e','l','3','3','.','d','l','l',0};
374 WCHAR pathW
[MAX_PATH
], filenameW
[MAX_PATH
];
378 GetSystemDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
380 lstrcpyW(filenameW
, pathW
);
381 lstrcatW(filenameW
, k32W
);
383 path
= SysAllocString(filenameW
);
384 hr
= IFileSystem3_GetFileVersion(fs3
, path
, &version
);
385 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
386 ok(*version
!= 0, "got %s\n", wine_dbgstr_w(version
));
387 SysFreeString(version
);
390 lstrcpyW(filenameW
, pathW
);
391 lstrcatW(filenameW
, k33W
);
393 path
= SysAllocString(filenameW
);
394 version
= (void*)0xdeadbeef;
395 hr
= IFileSystem3_GetFileVersion(fs3
, path
, &version
);
396 ok(broken(hr
== S_OK
) || hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "got 0x%08x\n", hr
);
399 ok(*version
== 0, "got %s\n", wine_dbgstr_w(version
));
400 SysFreeString(version
);
403 ok(version
== (void*)0xdeadbeef, "got %p\n", version
);
407 static void test_GetParentFolderName(void)
409 static const WCHAR path1
[] = {'a',0};
410 static const WCHAR path2
[] = {'a','/','a','/','a',0};
411 static const WCHAR path3
[] = {'a','\\','a','\\','a',0};
412 static const WCHAR path4
[] = {'a','/','a','/','/','\\','\\',0};
413 static const WCHAR path5
[] = {'c',':','\\','\\','a',0};
414 static const WCHAR path6
[] = {'a','c',':','\\','a',0};
415 static const WCHAR result2
[] = {'a','/','a',0};
416 static const WCHAR result3
[] = {'a','\\','a',0};
417 static const WCHAR result4
[] = {'a',0};
418 static const WCHAR result5
[] = {'c',':','\\',0};
419 static const WCHAR result6
[] = {'a','c',':',0};
421 static const struct {
438 hr
= IFileSystem3_GetParentFolderName(fs3
, NULL
, NULL
);
439 ok(hr
== E_POINTER
, "GetParentFolderName returned %x, expected E_POINTER\n", hr
);
441 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
442 result
= (BSTR
)0xdeadbeef;
443 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
444 hr
= IFileSystem3_GetParentFolderName(fs3
, path
, &result
);
445 ok(hr
== S_OK
, "%d) GetParentFolderName returned %x, expected S_OK\n", i
, hr
);
447 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
449 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
451 SysFreeString(result
);
455 static void test_GetFileName(void)
457 static const WCHAR path1
[] = {'a',0};
458 static const WCHAR path2
[] = {'a','/','a','.','b',0};
459 static const WCHAR path3
[] = {'a','\\',0};
460 static const WCHAR path4
[] = {'c',':',0};
461 static const WCHAR path5
[] = {'/','\\',0};
462 static const WCHAR result2
[] = {'a','.','b',0};
463 static const WCHAR result3
[] = {'a',0};
465 static const struct {
481 hr
= IFileSystem3_GetFileName(fs3
, NULL
, NULL
);
482 ok(hr
== E_POINTER
, "GetFileName returned %x, expected E_POINTER\n", hr
);
484 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
485 result
= (BSTR
)0xdeadbeef;
486 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
487 hr
= IFileSystem3_GetFileName(fs3
, path
, &result
);
488 ok(hr
== S_OK
, "%d) GetFileName returned %x, expected S_OK\n", i
, hr
);
490 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
492 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
494 SysFreeString(result
);
498 static void test_GetBaseName(void)
500 static const WCHAR path1
[] = {'a',0};
501 static const WCHAR path2
[] = {'a','/','a','.','b','.','c',0};
502 static const WCHAR path3
[] = {'a','.','b','\\',0};
503 static const WCHAR path4
[] = {'c',':',0};
504 static const WCHAR path5
[] = {'/','\\',0};
505 static const WCHAR path6
[] = {'.','a',0};
506 static const WCHAR result1
[] = {'a',0};
507 static const WCHAR result2
[] = {'a','.','b',0};
508 static const WCHAR result6
[] = {0};
510 static const struct {
527 hr
= IFileSystem3_GetBaseName(fs3
, NULL
, NULL
);
528 ok(hr
== E_POINTER
, "GetBaseName returned %x, expected E_POINTER\n", hr
);
530 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
531 result
= (BSTR
)0xdeadbeef;
532 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
533 hr
= IFileSystem3_GetBaseName(fs3
, path
, &result
);
534 ok(hr
== S_OK
, "%d) GetBaseName returned %x, expected S_OK\n", i
, hr
);
536 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
538 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
540 SysFreeString(result
);
544 static void test_GetAbsolutePathName(void)
546 static const WCHAR dir1
[] = {'t','e','s','t','_','d','i','r','1',0};
547 static const WCHAR dir2
[] = {'t','e','s','t','_','d','i','r','2',0};
548 static const WCHAR dir_match1
[] = {'t','e','s','t','_','d','i','r','*',0};
549 static const WCHAR dir_match2
[] = {'t','e','s','t','_','d','i','*',0};
550 static const WCHAR cur_dir
[] = {'.',0};
552 WIN32_FIND_DATAW fdata
;
554 WCHAR buf
[MAX_PATH
], buf2
[MAX_PATH
];
558 hr
= IFileSystem3_GetAbsolutePathName(fs3
, NULL
, NULL
);
559 ok(hr
== E_POINTER
, "GetAbsolutePathName returned %x, expected E_POINTER\n", hr
);
561 hr
= IFileSystem3_GetAbsolutePathName(fs3
, NULL
, &result
);
562 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
563 GetFullPathNameW(cur_dir
, MAX_PATH
, buf
, NULL
);
564 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
565 SysFreeString(result
);
567 find
= FindFirstFileW(dir_match2
, &fdata
);
568 if(find
!= INVALID_HANDLE_VALUE
) {
569 skip("GetAbsolutePathName tests\n");
574 path
= SysAllocString(dir_match1
);
575 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
576 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
577 GetFullPathNameW(dir_match1
, MAX_PATH
, buf2
, NULL
);
578 ok(!lstrcmpiW(buf2
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf2
));
579 SysFreeString(result
);
581 ok(CreateDirectoryW(dir1
, NULL
), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir1
));
582 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
583 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
584 GetFullPathNameW(dir1
, MAX_PATH
, buf
, NULL
);
585 ok(!lstrcmpiW(buf
, result
) || broken(!lstrcmpiW(buf2
, result
)), "result = %s, expected %s\n",
586 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
587 SysFreeString(result
);
589 ok(CreateDirectoryW(dir2
, NULL
), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir2
));
590 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
591 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
592 if(!lstrcmpiW(buf
, result
) || !lstrcmpiW(buf2
, result
)) {
593 ok(!lstrcmpiW(buf
, result
) || broken(!lstrcmpiW(buf2
, result
)), "result = %s, expected %s\n",
594 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
596 GetFullPathNameW(dir2
, MAX_PATH
, buf
, NULL
);
597 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n",
598 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
600 SysFreeString(result
);
603 path
= SysAllocString(dir_match2
);
604 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
605 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
606 GetFullPathNameW(dir_match2
, MAX_PATH
, buf
, NULL
);
607 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
608 SysFreeString(result
);
611 RemoveDirectoryW(dir1
);
612 RemoveDirectoryW(dir2
);
615 static void test_GetFile(void)
617 static const WCHAR slW
[] = {'\\',0};
619 WCHAR pathW
[MAX_PATH
];
629 get_temp_path(NULL
, pathW
);
631 path
= SysAllocString(pathW
);
632 hr
= IFileSystem3_GetFile(fs3
, path
, NULL
);
633 ok(hr
== E_POINTER
, "GetFile returned %x, expected E_POINTER\n", hr
);
634 hr
= IFileSystem3_GetFile(fs3
, NULL
, &file
);
635 ok(hr
== E_INVALIDARG
, "GetFile returned %x, expected E_INVALIDARG\n", hr
);
637 file
= (IFile
*)0xdeadbeef;
638 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
639 ok(!file
, "file != NULL\n");
640 ok(hr
== CTL_E_FILENOTFOUND
, "GetFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
642 hf
= CreateFileW(pathW
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_READONLY
, NULL
);
643 if(hf
== INVALID_HANDLE_VALUE
) {
644 skip("Can't create temporary file\n");
650 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
651 ok(hr
== S_OK
, "GetFile returned %x, expected S_OK\n", hr
);
653 hr
= IFile_get_DateLastModified(file
, NULL
);
654 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
657 hr
= IFile_get_DateLastModified(file
, &date
);
658 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
659 ok(date
> 0.0, "got %f\n", date
);
661 hr
= IFile_get_Path(file
, NULL
);
662 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
664 hr
= IFile_get_Path(file
, &str
);
665 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
666 ok(!lstrcmpiW(str
, pathW
), "got %s\n", wine_dbgstr_w(str
));
669 #define FILE_ATTR_MASK (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
670 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE | \
671 FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED)
673 hr
= IFile_get_Attributes(file
, &fa
);
674 gfa
= GetFileAttributesW(pathW
) & FILE_ATTR_MASK
;
675 ok(hr
== S_OK
, "get_Attributes returned %x, expected S_OK\n", hr
);
676 ok(fa
== gfa
, "fa = %x, expected %x\n", fa
, gfa
);
678 hr
= IFile_put_Attributes(file
, gfa
| FILE_ATTRIBUTE_READONLY
);
679 ok(hr
== S_OK
, "put_Attributes failed: %08x\n", hr
);
680 new_gfa
= GetFileAttributesW(pathW
) & FILE_ATTR_MASK
;
681 ok(new_gfa
== (gfa
|FILE_ATTRIBUTE_READONLY
), "new_gfa = %x, expected %x\n", new_gfa
, gfa
|FILE_ATTRIBUTE_READONLY
);
683 hr
= IFile_get_Attributes(file
, &fa
);
684 ok(hr
== S_OK
, "get_Attributes returned %x, expected S_OK\n", hr
);
685 ok(fa
== new_gfa
, "fa = %x, expected %x\n", fa
, new_gfa
);
687 hr
= IFile_put_Attributes(file
, gfa
);
688 ok(hr
== S_OK
, "put_Attributes failed: %08x\n", hr
);
689 new_gfa
= GetFileAttributesW(pathW
) & FILE_ATTR_MASK
;
690 ok(new_gfa
== gfa
, "new_gfa = %x, expected %x\n", new_gfa
, gfa
);
692 hr
= IFile_get_Attributes(file
, &fa
);
693 ok(hr
== S_OK
, "get_Attributes returned %x, expected S_OK\n", hr
);
694 ok(fa
== gfa
, "fa = %x, expected %x\n", fa
, gfa
);
696 hr
= IFile_get_Size(file
, &size
);
697 ok(hr
== S_OK
, "get_Size returned %x, expected S_OK\n", hr
);
698 ok(V_VT(&size
) == VT_I4
, "V_VT(&size) = %d, expected VT_I4\n", V_VT(&size
));
699 ok(V_I4(&size
) == 0, "V_I4(&size) = %d, expected 0\n", V_I4(&size
));
702 hr
= IFileSystem3_DeleteFile(fs3
, path
, FALSE
);
703 ok(hr
==CTL_E_PERMISSIONDENIED
|| broken(hr
==S_OK
),
704 "DeleteFile returned %x, expected CTL_E_PERMISSIONDENIED\n", hr
);
706 hr
= IFileSystem3_DeleteFile(fs3
, path
, TRUE
);
707 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
709 hr
= IFileSystem3_DeleteFile(fs3
, path
, TRUE
);
710 ok(hr
== CTL_E_FILENOTFOUND
, "DeleteFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
714 /* try with directory */
715 lstrcatW(pathW
, slW
);
716 ret
= CreateDirectoryW(pathW
, NULL
);
717 ok(ret
, "got %d, error %d\n", ret
, GetLastError());
719 path
= SysAllocString(pathW
);
720 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
721 ok(hr
== CTL_E_FILENOTFOUND
, "GetFile returned %x, expected S_OK\n", hr
);
724 RemoveDirectoryW(pathW
);
727 static inline BOOL
create_file(const WCHAR
*name
)
729 HANDLE f
= CreateFileW(name
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, 0, NULL
);
731 return f
!= INVALID_HANDLE_VALUE
;
734 static inline void create_path(const WCHAR
*folder
, const WCHAR
*name
, WCHAR
*ret
)
736 DWORD len
= lstrlenW(folder
);
737 memmove(ret
, folder
, len
*sizeof(WCHAR
));
739 memmove(ret
+len
+1, name
, (lstrlenW(name
)+1)*sizeof(WCHAR
));
742 static void test_CopyFolder(void)
744 static const WCHAR filesystem3_dir
[] = {'f','i','l','e','s','y','s','t','e','m','3','_','t','e','s','t',0};
745 static const WCHAR s1
[] = {'s','r','c','1',0};
746 static const WCHAR s
[] = {'s','r','c','*',0};
747 static const WCHAR d
[] = {'d','s','t',0};
748 static const WCHAR empty
[] = {0};
754 if(!CreateDirectoryW(filesystem3_dir
, NULL
)) {
755 skip("can't create temporary directory\n");
759 create_path(filesystem3_dir
, s1
, tmp
);
760 bsrc
= SysAllocString(tmp
);
761 create_path(filesystem3_dir
, d
, tmp
);
762 bdst
= SysAllocString(tmp
);
763 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
764 ok(hr
== CTL_E_FILENOTFOUND
, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
766 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
767 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
769 ok(create_file(bsrc
), "can't create %s file\n", wine_dbgstr_w(bsrc
));
770 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
771 ok(hr
== S_OK
, "CopyFile returned %x, expected S_OK\n", hr
);
773 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
774 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
776 hr
= IFileSystem3_DeleteFile(fs3
, bsrc
, VARIANT_FALSE
);
777 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
779 ok(CreateDirectoryW(bsrc
, NULL
), "can't create %s\n", wine_dbgstr_w(bsrc
));
780 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
781 ok(hr
== CTL_E_FILENOTFOUND
, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
783 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
784 ok(hr
== CTL_E_FILEALREADYEXISTS
, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
786 hr
= IFileSystem3_DeleteFile(fs3
, bdst
, VARIANT_TRUE
);
787 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
789 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
790 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
792 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
793 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
794 create_path(tmp
, s1
, tmp
);
795 ok(GetFileAttributesW(tmp
) == INVALID_FILE_ATTRIBUTES
,
796 "%s file exists\n", wine_dbgstr_w(tmp
));
798 create_path(filesystem3_dir
, d
, tmp
);
799 create_path(tmp
, empty
, tmp
);
801 bdst
= SysAllocString(tmp
);
802 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
803 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
804 create_path(tmp
, s1
, tmp
);
805 ok(GetFileAttributesW(tmp
) != INVALID_FILE_ATTRIBUTES
,
806 "%s directory doesn't exist\n", wine_dbgstr_w(tmp
));
807 ok(RemoveDirectoryW(tmp
), "can't remove %s directory\n", wine_dbgstr_w(tmp
));
808 create_path(filesystem3_dir
, d
, tmp
);
810 bdst
= SysAllocString(tmp
);
813 create_path(filesystem3_dir
, s
, tmp
);
815 bsrc
= SysAllocString(tmp
);
816 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
817 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
818 create_path(filesystem3_dir
, d
, tmp
);
819 create_path(tmp
, s1
, tmp
);
820 ok(GetFileAttributesW(tmp
) != INVALID_FILE_ATTRIBUTES
,
821 "%s directory doesn't exist\n", wine_dbgstr_w(tmp
));
823 hr
= IFileSystem3_DeleteFolder(fs3
, bdst
, VARIANT_FALSE
);
824 ok(hr
== S_OK
, "DeleteFolder returned %x, expected S_OK\n", hr
);
826 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
827 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
829 create_path(filesystem3_dir
, s1
, tmp
);
831 bsrc
= SysAllocString(tmp
);
832 create_path(tmp
, s1
, tmp
);
833 ok(create_file(tmp
), "can't create %s file\n", wine_dbgstr_w(tmp
));
834 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_FALSE
);
835 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
837 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_FALSE
);
838 ok(hr
== CTL_E_FILEALREADYEXISTS
, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
840 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
841 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
845 bsrc
= SysAllocString(filesystem3_dir
);
846 hr
= IFileSystem3_DeleteFolder(fs3
, bsrc
, VARIANT_FALSE
);
847 ok(hr
== S_OK
, "DeleteFolder returned %x, expected S_OK\n", hr
);
851 static BSTR
bstr_from_str(const char *str
)
853 int len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
854 BSTR ret
= SysAllocStringLen(NULL
, len
- 1); /* NUL character added automatically */
855 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
859 struct buildpath_test
866 static struct buildpath_test buildpath_data
[] =
868 { "C:\\path", "..\\name.tmp", "C:\\path\\..\\name.tmp" },
869 { "C:\\path", "\\name.tmp", "C:\\path\\name.tmp" },
870 { "C:\\path", "name.tmp", "C:\\path\\name.tmp" },
871 { "C:\\path\\", "name.tmp", "C:\\path\\name.tmp" },
872 { "C:\\path", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
873 { "C:\\path\\", "\\name.tmp", "C:\\path\\name.tmp" },
874 { "C:\\path\\", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
875 { "C:\\path\\\\", "\\\\name.tmp", "C:\\path\\\\\\name.tmp" },
876 { "C:\\\\", "\\name.tmp", "C:\\\\name.tmp" },
877 { "C:", "name.tmp", "C:name.tmp" },
878 { "C:", "\\\\name.tmp", "C:\\\\name.tmp" },
882 static void test_BuildPath(void)
884 struct buildpath_test
*ptr
= buildpath_data
;
889 hr
= IFileSystem3_BuildPath(fs3
, NULL
, NULL
, NULL
);
890 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
892 ret
= (BSTR
)0xdeadbeef;
893 hr
= IFileSystem3_BuildPath(fs3
, NULL
, NULL
, &ret
);
894 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
895 ok(*ret
== 0, "got %p\n", ret
);
898 ret
= (BSTR
)0xdeadbeef;
899 path
= bstr_from_str("path");
900 hr
= IFileSystem3_BuildPath(fs3
, path
, NULL
, &ret
);
901 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
902 ok(!lstrcmpW(ret
, path
), "got %s\n", wine_dbgstr_w(ret
));
906 ret
= (BSTR
)0xdeadbeef;
907 path
= bstr_from_str("path");
908 hr
= IFileSystem3_BuildPath(fs3
, NULL
, path
, &ret
);
909 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
910 ok(!lstrcmpW(ret
, path
), "got %s\n", wine_dbgstr_w(ret
));
919 path
= bstr_from_str(ptr
->path
);
920 name
= bstr_from_str(ptr
->name
);
921 result
= bstr_from_str(ptr
->result
);
922 hr
= IFileSystem3_BuildPath(fs3
, path
, name
, &ret
);
923 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
926 ok(!lstrcmpW(ret
, result
), "%d: got wrong path %s, expected %s\n", i
, wine_dbgstr_w(ret
),
927 wine_dbgstr_w(result
));
932 SysFreeString(result
);
939 static void test_GetFolder(void)
941 static const WCHAR dummyW
[] = {'d','u','m','m','y',0};
942 WCHAR buffW
[MAX_PATH
];
947 folder
= (void*)0xdeadbeef;
948 hr
= IFileSystem3_GetFolder(fs3
, NULL
, &folder
);
949 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
950 ok(folder
== NULL
, "got %p\n", folder
);
952 hr
= IFileSystem3_GetFolder(fs3
, NULL
, NULL
);
953 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
955 /* something that doesn't exist */
956 str
= SysAllocString(dummyW
);
958 hr
= IFileSystem3_GetFolder(fs3
, str
, NULL
);
959 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
961 folder
= (void*)0xdeadbeef;
962 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
963 ok(hr
== CTL_E_PATHNOTFOUND
, "got 0x%08x\n", hr
);
964 ok(folder
== NULL
, "got %p\n", folder
);
967 GetWindowsDirectoryW(buffW
, MAX_PATH
);
968 str
= SysAllocString(buffW
);
969 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
970 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
972 test_provideclassinfo(folder
, &CLSID_Folder
);
973 IFolder_Release(folder
);
976 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
977 static void test_FolderCollection(void)
979 static const WCHAR fooW
[] = {'f','o','o',0};
980 static const WCHAR aW
[] = {'\\','a',0};
981 static const WCHAR bW
[] = {'\\','b',0};
982 static const WCHAR cW
[] = {'\\','c',0};
983 IFolderCollection
*folders
;
984 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
985 IEnumVARIANT
*enumvar
, *clone
;
986 LONG count
, ref
, ref2
, i
;
987 IUnknown
*unk
, *unk2
;
990 VARIANT var
, var2
[2];
993 int found_a
= 0, found_b
= 0, found_c
= 0;
995 get_temp_path(fooW
, buffW
);
996 CreateDirectoryW(buffW
, NULL
);
998 str
= SysAllocString(buffW
);
999 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
1000 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1003 hr
= IFolder_get_SubFolders(folder
, NULL
);
1004 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1006 hr
= IFolder_get_Path(folder
, NULL
);
1007 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1009 hr
= IFolder_get_Path(folder
, &str
);
1010 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1011 ok(!lstrcmpiW(buffW
, str
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1014 lstrcpyW(pathW
, buffW
);
1015 lstrcatW(pathW
, aW
);
1016 CreateDirectoryW(pathW
, NULL
);
1018 lstrcpyW(pathW
, buffW
);
1019 lstrcatW(pathW
, bW
);
1020 CreateDirectoryW(pathW
, NULL
);
1022 hr
= IFolder_get_SubFolders(folder
, &folders
);
1023 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1024 test_provideclassinfo(folders
, &CLSID_Folders
);
1025 IFolder_Release(folder
);
1028 hr
= IFolderCollection_get_Count(folders
, &count
);
1029 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1030 ok(count
== 2, "got %d\n", count
);
1032 lstrcpyW(pathW
, buffW
);
1033 lstrcatW(pathW
, cW
);
1034 CreateDirectoryW(pathW
, NULL
);
1036 /* every time property is requested it scans directory */
1038 hr
= IFolderCollection_get_Count(folders
, &count
);
1039 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1040 ok(count
== 3, "got %d\n", count
);
1042 hr
= IFolderCollection_get__NewEnum(folders
, NULL
);
1043 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1045 hr
= IFolderCollection_QueryInterface(folders
, &IID_IEnumVARIANT
, (void**)&unk
);
1046 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1048 /* NewEnum creates new instance each time it's called */
1049 ref
= GET_REFCOUNT(folders
);
1052 hr
= IFolderCollection_get__NewEnum(folders
, &unk
);
1053 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1055 ref2
= GET_REFCOUNT(folders
);
1056 ok(ref2
== ref
+ 1, "got %d, %d\n", ref2
, ref
);
1059 hr
= IFolderCollection_get__NewEnum(folders
, &unk2
);
1060 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1061 ok(unk
!= unk2
, "got %p, %p\n", unk2
, unk
);
1062 IUnknown_Release(unk2
);
1064 /* now get IEnumVARIANT */
1065 ref
= GET_REFCOUNT(folders
);
1066 hr
= IUnknown_QueryInterface(unk
, &IID_IEnumVARIANT
, (void**)&enumvar
);
1067 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1068 ref2
= GET_REFCOUNT(folders
);
1069 ok(ref2
== ref
, "got %d, %d\n", ref2
, ref
);
1071 /* clone enumerator */
1072 hr
= IEnumVARIANT_Clone(enumvar
, &clone
);
1073 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1074 ok(clone
!= enumvar
, "got %p, %p\n", enumvar
, clone
);
1075 IEnumVARIANT_Release(clone
);
1077 hr
= IEnumVARIANT_Reset(enumvar
);
1078 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1080 for (i
= 0; i
< 3; i
++)
1084 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1085 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
1086 ok(fetched
== 1, "%d: got %d\n", i
, fetched
);
1087 ok(V_VT(&var
) == VT_DISPATCH
, "%d: got type %d\n", i
, V_VT(&var
));
1089 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IFolder
, (void**)&folder
);
1090 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1093 hr
= IFolder_get_Name(folder
, &str
);
1094 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1095 if (!lstrcmpW(str
, aW
+ 1))
1097 else if (!lstrcmpW(str
, bW
+ 1))
1099 else if (!lstrcmpW(str
, cW
+ 1))
1102 ok(0, "unexpected folder %s was found\n", wine_dbgstr_w(str
));
1105 IFolder_Release(folder
);
1109 ok(found_a
== 1 && found_b
== 1 && found_c
== 1,
1110 "each folder should be found 1 time instead of %d/%d/%d\n",
1111 found_a
, found_b
, found_c
);
1115 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1116 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1117 ok(fetched
== 0, "got %d\n", fetched
);
1119 hr
= IEnumVARIANT_Reset(enumvar
);
1120 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1121 hr
= IEnumVARIANT_Skip(enumvar
, 2);
1122 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1123 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1124 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1126 VariantInit(&var2
[0]);
1127 VariantInit(&var2
[1]);
1129 hr
= IEnumVARIANT_Next(enumvar
, 0, var2
, &fetched
);
1130 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1131 ok(fetched
== 0, "got %d\n", fetched
);
1133 hr
= IEnumVARIANT_Next(enumvar
, 2, var2
, &fetched
);
1134 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1135 ok(fetched
== 1, "got %d\n", fetched
);
1136 ok(V_VT(&var2
[0]) == VT_DISPATCH
, "got type %d\n", V_VT(&var2
[0]));
1137 VariantClear(&var2
[0]);
1138 VariantClear(&var2
[1]);
1140 IEnumVARIANT_Release(enumvar
);
1141 IUnknown_Release(unk
);
1143 lstrcpyW(pathW
, buffW
);
1144 lstrcatW(pathW
, aW
);
1145 RemoveDirectoryW(pathW
);
1146 lstrcpyW(pathW
, buffW
);
1147 lstrcatW(pathW
, bW
);
1148 RemoveDirectoryW(pathW
);
1149 lstrcpyW(pathW
, buffW
);
1150 lstrcatW(pathW
, cW
);
1151 RemoveDirectoryW(pathW
);
1152 RemoveDirectoryW(buffW
);
1154 IFolderCollection_Release(folders
);
1157 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1158 static void test_FileCollection(void)
1160 static const WCHAR fooW
[] = {'\\','f','o','o',0};
1161 static const WCHAR aW
[] = {'\\','a',0};
1162 static const WCHAR bW
[] = {'\\','b',0};
1163 static const WCHAR cW
[] = {'\\','c',0};
1164 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
1166 IFileCollection
*files
;
1168 IEnumVARIANT
*enumvar
, *clone
;
1169 LONG count
, ref
, ref2
, i
;
1170 IUnknown
*unk
, *unk2
;
1172 VARIANT var
, var2
[2];
1175 HANDLE file_a
, file_b
, file_c
;
1176 int found_a
= 0, found_b
= 0, found_c
= 0;
1178 get_temp_path(fooW
, buffW
);
1179 CreateDirectoryW(buffW
, NULL
);
1181 str
= SysAllocString(buffW
);
1182 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
1183 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1186 hr
= IFolder_get_Files(folder
, NULL
);
1187 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1189 lstrcpyW(pathW
, buffW
);
1190 lstrcatW(pathW
, aW
);
1191 file_a
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1192 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1193 lstrcpyW(pathW
, buffW
);
1194 lstrcatW(pathW
, bW
);
1195 file_b
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1196 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1198 hr
= IFolder_get_Files(folder
, &files
);
1199 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1200 test_provideclassinfo(files
, &CLSID_Files
);
1201 IFolder_Release(folder
);
1204 hr
= IFileCollection_get_Count(files
, &count
);
1205 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1206 ok(count
== 2, "got %d\n", count
);
1208 lstrcpyW(pathW
, buffW
);
1209 lstrcatW(pathW
, cW
);
1210 file_c
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1211 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1213 /* every time property is requested it scans directory */
1215 hr
= IFileCollection_get_Count(files
, &count
);
1216 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1217 ok(count
== 3, "got %d\n", count
);
1219 hr
= IFileCollection_get__NewEnum(files
, NULL
);
1220 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1222 hr
= IFileCollection_QueryInterface(files
, &IID_IEnumVARIANT
, (void**)&unk
);
1223 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1225 /* NewEnum creates new instance each time it's called */
1226 ref
= GET_REFCOUNT(files
);
1229 hr
= IFileCollection_get__NewEnum(files
, &unk
);
1230 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1232 ref2
= GET_REFCOUNT(files
);
1233 ok(ref2
== ref
+ 1, "got %d, %d\n", ref2
, ref
);
1236 hr
= IFileCollection_get__NewEnum(files
, &unk2
);
1237 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1238 ok(unk
!= unk2
, "got %p, %p\n", unk2
, unk
);
1239 IUnknown_Release(unk2
);
1241 /* now get IEnumVARIANT */
1242 ref
= GET_REFCOUNT(files
);
1243 hr
= IUnknown_QueryInterface(unk
, &IID_IEnumVARIANT
, (void**)&enumvar
);
1244 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1245 ref2
= GET_REFCOUNT(files
);
1246 ok(ref2
== ref
, "got %d, %d\n", ref2
, ref
);
1248 /* clone enumerator */
1249 hr
= IEnumVARIANT_Clone(enumvar
, &clone
);
1250 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1251 ok(clone
!= enumvar
, "got %p, %p\n", enumvar
, clone
);
1252 IEnumVARIANT_Release(clone
);
1254 hr
= IEnumVARIANT_Reset(enumvar
);
1255 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1257 for (i
= 0; i
< 3; i
++)
1261 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1262 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
1263 ok(fetched
== 1, "%d: got %d\n", i
, fetched
);
1264 ok(V_VT(&var
) == VT_DISPATCH
, "%d: got type %d\n", i
, V_VT(&var
));
1266 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IFile
, (void **)&file
);
1267 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1268 test_provideclassinfo(file
, &CLSID_File
);
1271 hr
= IFile_get_Name(file
, &str
);
1272 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1273 if (!lstrcmpW(str
, aW
+ 1))
1275 else if (!lstrcmpW(str
, bW
+ 1))
1277 else if (!lstrcmpW(str
, cW
+ 1))
1280 ok(0, "unexpected file %s was found\n", wine_dbgstr_w(str
));
1283 IFile_Release(file
);
1287 ok(found_a
== 1 && found_b
== 1 && found_c
== 1,
1288 "each file should be found 1 time instead of %d/%d/%d\n",
1289 found_a
, found_b
, found_c
);
1293 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1294 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1295 ok(fetched
== 0, "got %d\n", fetched
);
1297 hr
= IEnumVARIANT_Reset(enumvar
);
1298 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1299 hr
= IEnumVARIANT_Skip(enumvar
, 2);
1300 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1301 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1302 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1304 VariantInit(&var2
[0]);
1305 VariantInit(&var2
[1]);
1307 hr
= IEnumVARIANT_Next(enumvar
, 0, var2
, &fetched
);
1308 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1309 ok(fetched
== 0, "got %d\n", fetched
);
1311 hr
= IEnumVARIANT_Next(enumvar
, 2, var2
, &fetched
);
1312 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1313 ok(fetched
== 1, "got %d\n", fetched
);
1314 ok(V_VT(&var2
[0]) == VT_DISPATCH
, "got type %d\n", V_VT(&var2
[0]));
1315 VariantClear(&var2
[0]);
1316 VariantClear(&var2
[1]);
1318 IEnumVARIANT_Release(enumvar
);
1319 IUnknown_Release(unk
);
1321 CloseHandle(file_a
);
1322 CloseHandle(file_b
);
1323 CloseHandle(file_c
);
1324 RemoveDirectoryW(buffW
);
1326 IFileCollection_Release(files
);
1329 static void test_DriveCollection(void)
1331 IDriveCollection
*drives
;
1332 IEnumVARIANT
*enumvar
;
1338 hr
= IFileSystem3_get_Drives(fs3
, &drives
);
1339 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1341 test_provideclassinfo(drives
, &CLSID_Drives
);
1343 hr
= IDriveCollection_get__NewEnum(drives
, (IUnknown
**)&enumvar
);
1344 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1346 hr
= IDriveCollection_get_Count(drives
, NULL
);
1347 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1350 hr
= IDriveCollection_get_Count(drives
, &count
);
1351 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1352 ok(count
> 0, "got %d\n", count
);
1354 V_VT(&var
) = VT_EMPTY
;
1356 hr
= IEnumVARIANT_Next(enumvar
, 0, &var
, &fetched
);
1357 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1358 ok(fetched
== 0, "got %d\n", fetched
);
1360 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1361 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1363 hr
= IEnumVARIANT_Skip(enumvar
, count
);
1364 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1366 hr
= IEnumVARIANT_Skip(enumvar
, 1);
1367 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1369 /* reset and iterate again */
1370 hr
= IEnumVARIANT_Reset(enumvar
);
1371 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1373 while (IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
) == S_OK
) {
1374 IDrive
*drive
= (IDrive
*)V_DISPATCH(&var
);
1375 DriveTypeConst type
;
1378 hr
= IDrive_get_DriveType(drive
, &type
);
1379 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1381 hr
= IDrive_get_DriveLetter(drive
, NULL
);
1382 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1384 hr
= IDrive_get_DriveLetter(drive
, &str
);
1385 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1386 ok(SysStringLen(str
) == 1, "got string %s\n", wine_dbgstr_w(str
));
1389 hr
= IDrive_get_IsReady(drive
, NULL
);
1390 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1392 hr
= IDrive_get_TotalSize(drive
, NULL
);
1393 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1395 hr
= IDrive_get_AvailableSpace(drive
, NULL
);
1396 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1398 hr
= IDrive_get_FreeSpace(drive
, NULL
);
1399 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1401 if (type
== Fixed
) {
1402 VARIANT_BOOL ready
= VARIANT_FALSE
;
1405 hr
= IDrive_get_IsReady(drive
, &ready
);
1406 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1407 ok(ready
== VARIANT_TRUE
, "got %x\n", ready
);
1409 if (ready
!= VARIANT_TRUE
) {
1410 hr
= IDrive_get_DriveLetter(drive
, &str
);
1411 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1413 skip("Drive %s is not ready, skipping some tests\n", wine_dbgstr_w(str
));
1420 V_VT(&size
) = VT_EMPTY
;
1421 hr
= IDrive_get_TotalSize(drive
, &size
);
1422 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1423 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1424 if (V_VT(&size
) == VT_R8
)
1425 ok(V_R8(&size
) > 0, "got %f\n", V_R8(&size
));
1427 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1429 V_VT(&size
) = VT_EMPTY
;
1430 hr
= IDrive_get_AvailableSpace(drive
, &size
);
1431 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1432 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1433 if (V_VT(&size
) == VT_R8
)
1434 ok(V_R8(&size
) > (double)INT_MAX
, "got %f\n", V_R8(&size
));
1436 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1438 V_VT(&size
) = VT_EMPTY
;
1439 hr
= IDrive_get_FreeSpace(drive
, &size
);
1440 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1441 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1442 if (V_VT(&size
) == VT_R8
)
1443 ok(V_R8(&size
) > 0, "got %f\n", V_R8(&size
));
1445 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1450 IEnumVARIANT_Release(enumvar
);
1451 IDriveCollection_Release(drives
);
1454 static void test_CreateTextFile(void)
1456 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1457 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1458 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[10];
1459 ITextStream
*stream
;
1465 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1466 lstrcatW(pathW
, scrrunW
);
1467 lstrcpyW(dirW
, pathW
);
1468 lstrcatW(pathW
, testfileW
);
1470 /* dir doesn't exist */
1471 nameW
= SysAllocString(pathW
);
1472 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1473 ok(hr
== CTL_E_PATHNOTFOUND
, "got 0x%08x\n", hr
);
1475 ret
= CreateDirectoryW(dirW
, NULL
);
1476 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1478 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1479 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1481 test_provideclassinfo(stream
, &CLSID_TextStream
);
1483 hr
= ITextStream_Read(stream
, 1, &str
);
1484 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1486 hr
= ITextStream_Close(stream
);
1487 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1489 hr
= ITextStream_Read(stream
, 1, &str
);
1490 ok(hr
== CTL_E_BADFILEMODE
|| hr
== E_VAR_NOT_SET
, "got 0x%08x\n", hr
);
1492 hr
= ITextStream_Close(stream
);
1493 ok(hr
== S_FALSE
|| hr
== E_VAR_NOT_SET
, "got 0x%08x\n", hr
);
1495 ITextStream_Release(stream
);
1497 /* check it's created */
1498 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1499 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1502 /* try to create again with no-overwrite mode */
1503 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1504 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x\n", hr
);
1507 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1508 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1509 ITextStream_Release(stream
);
1511 /* overwrite in Unicode mode, check for BOM */
1512 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_TRUE
, &stream
);
1513 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1514 ITextStream_Release(stream
);
1516 /* File was created in Unicode mode, it contains 0xfffe BOM. Opening it in non-Unicode mode
1517 treats BOM like a valuable data with appropriate CP_ACP -> WCHAR conversion. */
1519 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1521 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1522 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1523 hr
= ITextStream_ReadAll(stream
, &str
);
1524 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1525 ok(!lstrcmpW(str
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1527 ITextStream_Release(stream
);
1530 RemoveDirectoryW(dirW
);
1531 SysFreeString(nameW
);
1534 static void test_WriteLine(void)
1536 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1537 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1538 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
];
1539 WCHAR buffW
[MAX_PATH
], buff2W
[MAX_PATH
];
1540 char buffA
[MAX_PATH
];
1541 ITextStream
*stream
;
1548 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1549 lstrcatW(pathW
, scrrunW
);
1550 lstrcpyW(dirW
, pathW
);
1551 lstrcatW(pathW
, testfileW
);
1553 ret
= CreateDirectoryW(dirW
, NULL
);
1554 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1556 /* create as ASCII file first */
1557 nameW
= SysAllocString(pathW
);
1558 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1561 hr
= ITextStream_WriteLine(stream
, nameW
);
1562 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1563 ITextStream_Release(stream
);
1565 /* check contents */
1566 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1567 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1569 ret
= ReadFile(file
, buffA
, sizeof(buffA
), &r
, NULL
);
1570 ok(ret
&& r
, "read %d, got %d, %d\n", r
, ret
, GetLastError());
1572 len
= MultiByteToWideChar(CP_ACP
, 0, buffA
, r
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1574 lstrcpyW(buff2W
, nameW
);
1575 lstrcatW(buff2W
, crlfW
);
1576 ok(!lstrcmpW(buff2W
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(buff2W
));
1580 /* same for unicode file */
1581 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1582 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1584 hr
= ITextStream_WriteLine(stream
, nameW
);
1585 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1586 ITextStream_Release(stream
);
1588 /* check contents */
1589 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1590 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1592 ret
= ReadFile(file
, buffW
, sizeof(buffW
), &r
, NULL
);
1593 ok(ret
&& r
, "read %d, got %d, %d\n", r
, ret
, GetLastError());
1594 buffW
[r
/sizeof(WCHAR
)] = 0;
1598 lstrcatW(buff2W
, nameW
);
1599 lstrcatW(buff2W
, crlfW
);
1600 ok(!lstrcmpW(buff2W
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(buff2W
));
1604 RemoveDirectoryW(dirW
);
1605 SysFreeString(nameW
);
1608 static void test_ReadAll(void)
1610 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1611 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1612 static const WCHAR secondlineW
[] = {'s','e','c','o','n','d',0};
1613 static const WCHAR aW
[] = {'A',0};
1614 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[500];
1615 ITextStream
*stream
;
1621 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1622 lstrcatW(pathW
, scrrunW
);
1623 lstrcpyW(dirW
, pathW
);
1624 lstrcatW(pathW
, testfileW
);
1626 ret
= CreateDirectoryW(dirW
, NULL
);
1627 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1629 /* Unicode file -> read with ascii stream */
1630 nameW
= SysAllocString(pathW
);
1631 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1632 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1634 hr
= ITextStream_WriteLine(stream
, nameW
);
1635 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1637 str
= SysAllocString(secondlineW
);
1638 hr
= ITextStream_WriteLine(stream
, str
);
1639 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1642 hr
= ITextStream_ReadAll(stream
, NULL
);
1643 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1645 str
= (void*)0xdeadbeef;
1646 hr
= ITextStream_ReadAll(stream
, &str
);
1647 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1648 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1650 ITextStream_Release(stream
);
1652 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1653 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1655 hr
= ITextStream_ReadAll(stream
, NULL
);
1656 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1658 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1660 hr
= ITextStream_ReadAll(stream
, &str
);
1661 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1663 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1664 ok(str
[0] == buffW
[0] && str
[1] == buffW
[1], "got %s, %d\n", wine_dbgstr_w(str
), SysStringLen(str
));
1666 ITextStream_Release(stream
);
1668 /* Unicode file -> read with unicode stream */
1669 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1670 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1672 lstrcpyW(buffW
, nameW
);
1673 lstrcatW(buffW
, crlfW
);
1674 lstrcatW(buffW
, secondlineW
);
1675 lstrcatW(buffW
, crlfW
);
1677 hr
= ITextStream_ReadAll(stream
, &str
);
1678 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1679 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1682 /* ReadAll one more time */
1683 str
= (void*)0xdeadbeef;
1684 hr
= ITextStream_ReadAll(stream
, &str
);
1685 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1686 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1688 /* ReadLine fails the same way */
1689 str
= (void*)0xdeadbeef;
1690 hr
= ITextStream_ReadLine(stream
, &str
);
1691 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1692 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1693 ITextStream_Release(stream
);
1695 /* Open again and skip first line before ReadAll */
1696 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1697 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1700 hr
= ITextStream_ReadLine(stream
, &str
);
1702 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1703 ok(str
!= NULL
, "got %p\n", str
);
1707 lstrcpyW(buffW
, secondlineW
);
1708 lstrcatW(buffW
, crlfW
);
1710 hr
= ITextStream_ReadAll(stream
, &str
);
1711 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1713 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1715 ITextStream_Release(stream
);
1717 /* ASCII file, read with Unicode stream */
1718 /* 1. one byte content, not enough for Unicode read */
1719 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1720 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1721 str
= SysAllocString(aW
);
1722 hr
= ITextStream_Write(stream
, str
);
1723 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1725 ITextStream_Release(stream
);
1727 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1728 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1730 str
= (void*)0xdeadbeef;
1731 hr
= ITextStream_ReadAll(stream
, &str
);
1732 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1733 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1735 ITextStream_Release(stream
);
1738 RemoveDirectoryW(dirW
);
1739 SysFreeString(nameW
);
1742 static void test_Read(void)
1744 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1745 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1746 static const WCHAR secondlineW
[] = {'s','e','c','o','n','d',0};
1747 static const WCHAR aW
[] = {'A',0};
1748 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[500];
1749 ITextStream
*stream
;
1755 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1756 lstrcatW(pathW
, scrrunW
);
1757 lstrcpyW(dirW
, pathW
);
1758 lstrcatW(pathW
, testfileW
);
1760 ret
= CreateDirectoryW(dirW
, NULL
);
1761 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1763 /* Unicode file -> read with ascii stream */
1764 nameW
= SysAllocString(pathW
);
1765 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1766 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1768 hr
= ITextStream_WriteLine(stream
, nameW
);
1769 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1771 str
= SysAllocString(secondlineW
);
1772 hr
= ITextStream_WriteLine(stream
, str
);
1773 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1776 hr
= ITextStream_Read(stream
, 0, NULL
);
1777 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1779 hr
= ITextStream_Read(stream
, 1, NULL
);
1780 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1782 hr
= ITextStream_Read(stream
, -1, NULL
);
1783 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1785 str
= (void*)0xdeadbeef;
1786 hr
= ITextStream_Read(stream
, 1, &str
);
1787 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1788 ok(str
== NULL
, "got %p\n", str
);
1790 ITextStream_Release(stream
);
1792 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1793 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1795 hr
= ITextStream_Read(stream
, 1, NULL
);
1796 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1798 str
= (void*)0xdeadbeef;
1799 hr
= ITextStream_Read(stream
, -1, &str
);
1800 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1801 ok(str
== NULL
, "got %p\n", str
);
1803 str
= (void*)0xdeadbeef;
1804 hr
= ITextStream_Read(stream
, 0, &str
);
1805 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1806 ok(str
== NULL
, "got %p\n", str
);
1808 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1810 hr
= ITextStream_Read(stream
, 2, &str
);
1811 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1814 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1816 ok(!lstrcmpW(str
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1817 ok(SysStringLen(str
) == 2, "got %d\n", SysStringLen(str
));
1819 ITextStream_Release(stream
);
1821 /* Unicode file -> read with unicode stream */
1822 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1823 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1825 lstrcpyW(buffW
, nameW
);
1826 lstrcatW(buffW
, crlfW
);
1827 lstrcatW(buffW
, secondlineW
);
1828 lstrcatW(buffW
, crlfW
);
1830 hr
= ITextStream_Read(stream
, 500, &str
);
1831 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1832 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1835 /* ReadAll one more time */
1836 str
= (void*)0xdeadbeef;
1837 hr
= ITextStream_Read(stream
, 10, &str
);
1838 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1839 ok(str
== NULL
, "got %p\n", str
);
1841 /* ReadLine fails the same way */
1842 str
= (void*)0xdeadbeef;
1843 hr
= ITextStream_ReadLine(stream
, &str
);
1844 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1845 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef), "got %p\n", str
);
1846 ITextStream_Release(stream
);
1848 /* Open again and skip first line before ReadAll */
1849 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1850 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1853 hr
= ITextStream_ReadLine(stream
, &str
);
1855 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1856 ok(str
!= NULL
, "got %p\n", str
);
1860 lstrcpyW(buffW
, secondlineW
);
1861 lstrcatW(buffW
, crlfW
);
1863 hr
= ITextStream_Read(stream
, 100, &str
);
1864 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1866 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1868 ITextStream_Release(stream
);
1870 /* ASCII file, read with Unicode stream */
1871 /* 1. one byte content, not enough for Unicode read */
1872 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1873 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1874 str
= SysAllocString(aW
);
1875 hr
= ITextStream_Write(stream
, str
);
1876 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1878 ITextStream_Release(stream
);
1880 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1881 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1883 str
= (void*)0xdeadbeef;
1884 hr
= ITextStream_Read(stream
, 500, &str
);
1885 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1886 ok(str
== NULL
, "got %p\n", str
);
1888 ITextStream_Release(stream
);
1891 RemoveDirectoryW(dirW
);
1892 SysFreeString(nameW
);
1895 struct driveexists_test
{
1896 const WCHAR drivespec
[10];
1897 const INT drivetype
;
1898 const VARIANT_BOOL expected_ret
;
1901 /* If 'drivetype' != -1, the first character of 'drivespec' will be replaced
1902 * with the drive letter of a drive of this type. If such a drive does not exist,
1903 * the test will be skipped. */
1904 static const struct driveexists_test driveexiststestdata
[] = {
1905 { {'N',':','\\',0}, DRIVE_NO_ROOT_DIR
, VARIANT_FALSE
},
1906 { {'R',':','\\',0}, DRIVE_REMOVABLE
, VARIANT_TRUE
},
1907 { {'F',':','\\',0}, DRIVE_FIXED
, VARIANT_TRUE
},
1908 { {'F',':',0}, DRIVE_FIXED
, VARIANT_TRUE
},
1909 { {'F','?',0}, DRIVE_FIXED
, VARIANT_FALSE
},
1910 { {'F',0}, DRIVE_FIXED
, VARIANT_TRUE
},
1911 { {'?',0}, -1, VARIANT_FALSE
},
1915 static void test_DriveExists(void)
1917 const struct driveexists_test
*ptr
= driveexiststestdata
;
1921 WCHAR root
[] = {'?',':','\\',0};
1923 hr
= IFileSystem3_DriveExists(fs3
, NULL
, NULL
);
1924 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1927 hr
= IFileSystem3_DriveExists(fs3
, NULL
, &ret
);
1928 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1929 ok(ret
== VARIANT_FALSE
, "got %x\n", ret
);
1931 drivespec
= SysAllocString(root
);
1932 hr
= IFileSystem3_DriveExists(fs3
, drivespec
, NULL
);
1933 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1934 SysFreeString(drivespec
);
1936 for (; *ptr
->drivespec
; ptr
++) {
1937 drivespec
= SysAllocString(ptr
->drivespec
);
1938 if (ptr
->drivetype
!= -1) {
1939 for (root
[0] = 'A'; root
[0] <= 'Z'; root
[0]++)
1940 if (GetDriveTypeW(root
) == ptr
->drivetype
)
1942 if (root
[0] > 'Z') {
1943 skip("No drive with type 0x%x found, skipping test %s.\n",
1944 ptr
->drivetype
, wine_dbgstr_w(ptr
->drivespec
));
1945 SysFreeString(drivespec
);
1949 /* Test both upper and lower case drive letters. */
1950 drivespec
[0] = root
[0];
1951 ret
= ptr
->expected_ret
== VARIANT_TRUE
? VARIANT_FALSE
: VARIANT_TRUE
;
1952 hr
= IFileSystem3_DriveExists(fs3
, drivespec
, &ret
);
1953 ok(hr
== S_OK
, "got 0x%08x for drive spec %s (%s)\n",
1954 hr
, wine_dbgstr_w(drivespec
), wine_dbgstr_w(ptr
->drivespec
));
1955 ok(ret
== ptr
->expected_ret
, "got %d, expected %d for drive spec %s (%s)\n",
1956 ret
, ptr
->expected_ret
, wine_dbgstr_w(drivespec
), wine_dbgstr_w(ptr
->drivespec
));
1958 drivespec
[0] = tolower(root
[0]);
1961 ret
= ptr
->expected_ret
== VARIANT_TRUE
? VARIANT_FALSE
: VARIANT_TRUE
;
1962 hr
= IFileSystem3_DriveExists(fs3
, drivespec
, &ret
);
1963 ok(hr
== S_OK
, "got 0x%08x for drive spec %s (%s)\n",
1964 hr
, wine_dbgstr_w(drivespec
), wine_dbgstr_w(ptr
->drivespec
));
1965 ok(ret
== ptr
->expected_ret
, "got %d, expected %d for drive spec %s (%s)\n",
1966 ret
, ptr
->expected_ret
, wine_dbgstr_w(drivespec
), wine_dbgstr_w(ptr
->drivespec
));
1968 SysFreeString(drivespec
);
1972 struct getdrivename_test
{
1973 const WCHAR path
[10];
1974 const WCHAR drive
[5];
1977 static const struct getdrivename_test getdrivenametestdata
[] = {
1978 { {'C',':','\\','1','.','t','s','t',0}, {'C',':',0} },
1979 { {'O',':','\\','1','.','t','s','t',0}, {'O',':',0} },
1980 { {'O',':',0}, {'O',':',0} },
1981 { {'o',':',0}, {'o',':',0} },
1982 { {'O','O',':',0} },
1988 static void test_GetDriveName(void)
1990 const struct getdrivename_test
*ptr
= getdrivenametestdata
;
1994 hr
= IFileSystem3_GetDriveName(fs3
, NULL
, NULL
);
1995 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1997 name
= (void*)0xdeadbeef;
1998 hr
= IFileSystem3_GetDriveName(fs3
, NULL
, &name
);
1999 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2000 ok(name
== NULL
, "got %p\n", name
);
2002 while (*ptr
->path
) {
2003 BSTR path
= SysAllocString(ptr
->path
);
2004 name
= (void*)0xdeadbeef;
2005 hr
= IFileSystem3_GetDriveName(fs3
, path
, &name
);
2006 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2008 ok(!lstrcmpW(ptr
->drive
, name
), "got %s, expected %s\n", wine_dbgstr_w(name
), wine_dbgstr_w(ptr
->drive
));
2010 ok(!*ptr
->drive
, "got %s, expected %s\n", wine_dbgstr_w(name
), wine_dbgstr_w(ptr
->drive
));
2011 SysFreeString(path
);
2012 SysFreeString(name
);
2017 struct getdrive_test
{
2018 const WCHAR drivespec
[12];
2020 const WCHAR driveletter
[2];
2023 static void test_GetDrive(void)
2026 IDrive
*drive_fixed
, *drive
;
2027 BSTR dl_fixed
, drivespec
;
2028 WCHAR root
[] = {'?',':','\\',0};
2030 drive
= (void*)0xdeadbeef;
2031 hr
= IFileSystem3_GetDrive(fs3
, NULL
, NULL
);
2032 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2033 ok(drive
== (void*)0xdeadbeef, "got %p\n", drive
);
2035 for (root
[0] = 'A'; root
[0] <= 'Z'; root
[0]++)
2036 if (GetDriveTypeW(root
) == DRIVE_NO_ROOT_DIR
)
2040 skip("All drive letters are occupied, skipping test for nonexisting drive.\n");
2042 drivespec
= SysAllocString(root
);
2043 drive
= (void*)0xdeadbeef;
2044 hr
= IFileSystem3_GetDrive(fs3
, drivespec
, &drive
);
2045 ok(hr
== CTL_E_DEVICEUNAVAILABLE
, "got 0x%08x\n", hr
);
2046 ok(drive
== NULL
, "got %p\n", drive
);
2047 SysFreeString(drivespec
);
2050 drive_fixed
= get_fixed_drive();
2052 skip("No fixed drive found, skipping test.\n");
2056 hr
= IDrive_get_DriveLetter(drive_fixed
, &dl_fixed
);
2057 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2060 skip("Could not retrieve drive letter of fixed drive, skipping test.\n");
2062 WCHAR dl_upper
= toupper(dl_fixed
[0]);
2063 WCHAR dl_lower
= tolower(dl_fixed
[0]);
2064 struct getdrive_test testdata
[] = {
2065 { {dl_upper
,0}, S_OK
, {dl_upper
,0} },
2066 { {dl_upper
,':',0}, S_OK
, {dl_upper
,0} },
2067 { {dl_upper
,':','\\',0}, S_OK
, {dl_upper
,0} },
2068 { {dl_lower
,':','\\',0}, S_OK
, {dl_upper
,0} },
2069 { {dl_upper
,'\\',0}, E_INVALIDARG
, { 0 } },
2070 { {dl_lower
,'\\',0}, E_INVALIDARG
, { 0 } },
2071 { {'$',':','\\',0}, E_INVALIDARG
, { 0 } },
2072 { {'\\','h','o','s','t','\\','s','h','a','r','e',0}, E_INVALIDARG
, { 0 } },
2073 { {'h','o','s','t','\\','s','h','a','r','e',0}, E_INVALIDARG
, { 0 } },
2076 struct getdrive_test
*ptr
= &testdata
[0];
2078 for (; *ptr
->drivespec
; ptr
++) {
2079 drivespec
= SysAllocString(ptr
->drivespec
);
2080 drive
= (void*)0xdeadbeef;
2081 hr
= IFileSystem3_GetDrive(fs3
, drivespec
, &drive
);
2082 ok(hr
== ptr
->res
, "got 0x%08x, expected 0x%08x for drive spec %s\n",
2083 hr
, ptr
->res
, wine_dbgstr_w(ptr
->drivespec
));
2084 ok(!lstrcmpW(ptr
->drivespec
, drivespec
), "GetDrive modified its DriveSpec argument\n");
2085 SysFreeString(drivespec
);
2087 if (*ptr
->driveletter
) {
2089 hr
= IDrive_get_DriveLetter(drive
, &driveletter
);
2090 ok(hr
== S_OK
, "got 0x%08x for drive spec %s\n", hr
, wine_dbgstr_w(ptr
->drivespec
));
2091 if (SUCCEEDED(hr
)) {
2092 ok(!lstrcmpW(ptr
->driveletter
, driveletter
), "got %s, expected %s for drive spec %s\n",
2093 wine_dbgstr_w(driveletter
), wine_dbgstr_w(ptr
->driveletter
),
2094 wine_dbgstr_w(ptr
->drivespec
));
2095 SysFreeString(driveletter
);
2097 test_provideclassinfo(drive
, &CLSID_Drive
);
2098 IDrive_Release(drive
);
2100 ok(drive
== NULL
, "got %p for drive spec %s\n", drive
, wine_dbgstr_w(ptr
->drivespec
));
2102 SysFreeString(dl_fixed
);
2106 static void test_SerialNumber(void)
2113 drive
= get_fixed_drive();
2115 skip("No fixed drive found, skipping test.\n");
2119 hr
= IDrive_get_SerialNumber(drive
, NULL
);
2120 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2122 serial
= 0xdeadbeef;
2123 hr
= IDrive_get_SerialNumber(drive
, &serial
);
2124 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2125 ok(serial
!= 0xdeadbeef, "got %x\n", serial
);
2127 hr
= IDrive_get_FileSystem(drive
, NULL
);
2128 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2131 hr
= IDrive_get_FileSystem(drive
, &name
);
2132 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2133 ok(name
!= NULL
, "got %p\n", name
);
2134 SysFreeString(name
);
2136 hr
= IDrive_get_VolumeName(drive
, NULL
);
2137 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2140 hr
= IDrive_get_VolumeName(drive
, &name
);
2141 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2142 ok(name
!= NULL
, "got %p\n", name
);
2143 SysFreeString(name
);
2145 IDrive_Release(drive
);
2148 static const struct extension_test
{
2151 } extension_tests
[] = {
2152 { {'n','o','e','x','t',0}, {0} },
2153 { {'n','.','o','.','e','x','t',0}, {'e','x','t',0} },
2154 { {'n','.','o','.','e','X','t',0}, {'e','X','t',0} },
2158 static void test_GetExtensionName(void)
2164 for (i
= 0; i
< sizeof(extension_tests
)/sizeof(extension_tests
[0]); i
++) {
2166 path
= SysAllocString(extension_tests
[i
].path
);
2168 hr
= IFileSystem3_GetExtensionName(fs3
, path
, &ext
);
2169 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2170 if (*extension_tests
[i
].ext
)
2171 ok(!lstrcmpW(ext
, extension_tests
[i
].ext
), "%d: path %s, got %s, expected %s\n", i
,
2172 wine_dbgstr_w(path
), wine_dbgstr_w(ext
), wine_dbgstr_w(extension_tests
[i
].ext
));
2174 ok(ext
== NULL
, "%d: path %s, got %s, expected %s\n", i
,
2175 wine_dbgstr_w(path
), wine_dbgstr_w(ext
), wine_dbgstr_w(extension_tests
[i
].ext
));
2177 SysFreeString(path
);
2182 static void test_GetSpecialFolder(void)
2184 WCHAR pathW
[MAX_PATH
];
2190 hr
= IFileSystem3_GetSpecialFolder(fs3
, WindowsFolder
, NULL
);
2191 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2193 hr
= IFileSystem3_GetSpecialFolder(fs3
, TemporaryFolder
+1, NULL
);
2194 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2196 hr
= IFileSystem3_GetSpecialFolder(fs3
, TemporaryFolder
+1, &folder
);
2197 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2199 hr
= IFileSystem3_GetSpecialFolder(fs3
, WindowsFolder
, &folder
);
2200 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2201 hr
= IFolder_get_Path(folder
, &path
);
2202 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2203 GetWindowsDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
2204 ok(!lstrcmpiW(pathW
, path
), "got %s, expected %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(pathW
));
2205 SysFreeString(path
);
2206 IFolder_Release(folder
);
2208 hr
= IFileSystem3_GetSpecialFolder(fs3
, SystemFolder
, &folder
);
2209 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2210 hr
= IFolder_get_Path(folder
, &path
);
2211 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2212 GetSystemDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
2213 ok(!lstrcmpiW(pathW
, path
), "got %s, expected %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(pathW
));
2214 SysFreeString(path
);
2215 IFolder_Release(folder
);
2217 hr
= IFileSystem3_GetSpecialFolder(fs3
, TemporaryFolder
, &folder
);
2218 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2219 hr
= IFolder_get_Path(folder
, &path
);
2220 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2221 ret
= GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
2222 if (ret
&& pathW
[ret
-1] == '\\')
2225 ok(!lstrcmpiW(pathW
, path
), "got %s, expected %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(pathW
));
2226 SysFreeString(path
);
2227 IFolder_Release(folder
);
2230 START_TEST(filesystem
)
2236 hr
= CoCreateInstance(&CLSID_FileSystemObject
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
2237 &IID_IFileSystem3
, (void**)&fs3
);
2239 win_skip("Could not create FileSystem object: %08x\n", hr
);
2244 test_createfolder();
2246 test_GetFileVersion();
2247 test_GetParentFolderName();
2250 test_GetAbsolutePathName();
2255 test_FolderCollection();
2256 test_FileCollection();
2257 test_DriveCollection();
2258 test_CreateTextFile();
2263 test_GetDriveName();
2265 test_SerialNumber();
2266 test_GetExtensionName();
2267 test_GetSpecialFolder();
2269 IFileSystem3_Release(fs3
);