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 char utf16bom
[] = {0xff,0xfe,0};
48 static const WCHAR testfileW
[] = L
"test.txt";
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)
139 IObjectWithSite
*site
;
142 WCHAR windows_path
[MAX_PATH
];
143 WCHAR file_path
[MAX_PATH
];
145 IFileSystem3_QueryInterface(fs3
, &IID_IDispatch
, (void**)&disp
);
147 GetSystemDirectoryW(windows_path
, MAX_PATH
);
148 lstrcpyW(file_path
, windows_path
);
149 lstrcatW(file_path
, L
"\\kernel32.dll");
151 test_provideclassinfo(disp
, &CLSID_FileSystemObject
);
153 hr
= IDispatch_QueryInterface(disp
, &IID_IObjectWithSite
, (void**)&site
);
154 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
156 hr
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
157 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
160 hr
= IFileSystem3_FileExists(fs3
, NULL
, &b
);
161 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
162 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
164 hr
= IFileSystem3_FileExists(fs3
, NULL
, NULL
);
165 ok(hr
== E_POINTER
, "got 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
167 path
= SysAllocString(L
"path");
169 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
170 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
171 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
174 path
= SysAllocString(file_path
);
176 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
177 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
178 ok(b
== VARIANT_TRUE
, "got %x\n", b
);
181 path
= SysAllocString(windows_path
);
183 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
184 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
185 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
189 hr
= IFileSystem3_FolderExists(fs3
, NULL
, NULL
);
190 ok(hr
== E_POINTER
, "got 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
192 path
= SysAllocString(windows_path
);
193 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
194 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
195 ok(b
== VARIANT_TRUE
, "Folder doesn't exists\n");
198 path
= SysAllocString(L
"c:\\Nonexistent");
199 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
200 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
201 ok(b
== VARIANT_FALSE
, "Folder exists\n");
204 path
= SysAllocString(file_path
);
205 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
206 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
207 ok(b
== VARIANT_FALSE
, "Folder exists\n");
210 IDispatch_Release(disp
);
213 static void test_createfolder(void)
215 WCHAR buffW
[MAX_PATH
];
221 get_temp_path(NULL
, buffW
);
222 ret
= CreateDirectoryW(buffW
, NULL
);
223 ok(ret
, "got %d, %d\n", ret
, GetLastError());
225 /* create existing directory */
226 path
= SysAllocString(buffW
);
227 folder
= (void*)0xdeabeef;
228 hr
= IFileSystem3_CreateFolder(fs3
, path
, &folder
);
229 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x\n", hr
);
230 ok(folder
== NULL
, "got %p\n", folder
);
232 RemoveDirectoryW(buffW
);
235 static void test_textstream(void)
245 file
= CreateFileW(testfileW
, GENERIC_READ
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
248 name
= SysAllocString(testfileW
);
250 hr
= IFileSystem3_FileExists(fs3
, name
, &b
);
251 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
252 ok(b
== VARIANT_TRUE
, "got %x\n", b
);
254 /* different mode combinations */
255 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
| ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
256 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
258 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
| ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
259 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
261 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
| ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
262 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
264 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
265 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
266 hr
= ITextStream_Read(stream
, 1, &data
);
267 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
268 ITextStream_Release(stream
);
270 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
, 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
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
277 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
279 /* try to write when open for reading */
280 hr
= ITextStream_WriteLine(stream
, name
);
281 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
283 hr
= ITextStream_Write(stream
, name
);
284 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
286 hr
= ITextStream_get_AtEndOfStream(stream
, NULL
);
287 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
290 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
291 ok(hr
== S_OK
|| broken(hr
== S_FALSE
), "got 0x%08x\n", hr
);
292 ok(b
== VARIANT_TRUE
, "got 0x%x\n", b
);
294 ITextStream_Release(stream
);
296 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
, VARIANT_FALSE
, TristateFalse
, &stream
);
297 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
300 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
301 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
302 ok(b
== VARIANT_TRUE
|| broken(b
== 10), "got 0x%x\n", b
);
305 hr
= ITextStream_get_AtEndOfLine(stream
, &b
);
307 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
308 ok(b
== VARIANT_FALSE
|| broken(b
== 10), "got 0x%x\n", b
);
310 hr
= ITextStream_Read(stream
, 1, &data
);
311 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
313 hr
= ITextStream_ReadLine(stream
, &data
);
314 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
316 hr
= ITextStream_ReadAll(stream
, &data
);
317 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
319 ITextStream_Release(stream
);
321 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
322 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
325 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
326 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
327 ok(b
== VARIANT_TRUE
|| broken(b
== 10), "got 0x%x\n", b
);
330 hr
= ITextStream_get_AtEndOfLine(stream
, &b
);
332 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
333 ok(b
== VARIANT_FALSE
|| broken(b
== 10), "got 0x%x\n", b
);
335 hr
= ITextStream_Read(stream
, 1, &data
);
336 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
338 hr
= ITextStream_ReadLine(stream
, &data
);
339 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
341 hr
= ITextStream_ReadAll(stream
, &data
);
342 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
344 ITextStream_Release(stream
);
346 /* now with non-empty file */
347 file
= CreateFileW(testfileW
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
348 ret
= WriteFile(file
, testfileW
, sizeof(testfileW
), &written
, NULL
);
349 ok(ret
&& written
== sizeof(testfileW
), "got %d\n", ret
);
352 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
353 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
355 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
356 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
357 ok(b
== VARIANT_FALSE
, "got 0x%x\n", b
);
358 ITextStream_Release(stream
);
361 DeleteFileW(testfileW
);
364 static void test_GetFileVersion(void)
366 WCHAR pathW
[MAX_PATH
], filenameW
[MAX_PATH
];
370 GetSystemDirectoryW(pathW
, ARRAY_SIZE(pathW
));
372 lstrcpyW(filenameW
, pathW
);
373 lstrcatW(filenameW
, L
"\\kernel32.dll");
375 path
= SysAllocString(filenameW
);
376 hr
= IFileSystem3_GetFileVersion(fs3
, path
, &version
);
377 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
378 ok(*version
!= 0, "got %s\n", wine_dbgstr_w(version
));
379 SysFreeString(version
);
382 lstrcpyW(filenameW
, pathW
);
383 lstrcatW(filenameW
, L
"\\kernel33.dll");
385 path
= SysAllocString(filenameW
);
386 version
= (void*)0xdeadbeef;
387 hr
= IFileSystem3_GetFileVersion(fs3
, path
, &version
);
388 ok(broken(hr
== S_OK
) || hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "got 0x%08x\n", hr
);
391 ok(*version
== 0, "got %s\n", wine_dbgstr_w(version
));
392 SysFreeString(version
);
395 ok(version
== (void*)0xdeadbeef, "got %p\n", version
);
399 static void test_GetParentFolderName(void)
410 { L
"a/a/a", L
"a/a" },
411 { L
"a\\a\\a", L
"a\\a" },
412 { L
"a/a//\\\\", L
"a" },
413 { L
"c:\\\\a", L
"c:\\" },
414 { L
"ac:\\a", L
"ac:" }
421 hr
= IFileSystem3_GetParentFolderName(fs3
, NULL
, NULL
);
422 ok(hr
== E_POINTER
, "GetParentFolderName returned %x, expected E_POINTER\n", hr
);
424 for(i
=0; i
< ARRAY_SIZE(tests
); i
++) {
425 result
= (BSTR
)0xdeadbeef;
426 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
427 hr
= IFileSystem3_GetParentFolderName(fs3
, path
, &result
);
428 ok(hr
== S_OK
, "%d) GetParentFolderName returned %x, expected S_OK\n", i
, hr
);
430 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
432 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
434 SysFreeString(result
);
438 static void test_GetFileName(void)
448 { L
"a/a.b", L
"a.b" },
458 hr
= IFileSystem3_GetFileName(fs3
, NULL
, NULL
);
459 ok(hr
== E_POINTER
, "GetFileName returned %x, expected E_POINTER\n", hr
);
461 for(i
=0; i
< ARRAY_SIZE(tests
); i
++) {
462 result
= (BSTR
)0xdeadbeef;
463 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
464 hr
= IFileSystem3_GetFileName(fs3
, path
, &result
);
465 ok(hr
== S_OK
, "%d) GetFileName returned %x, expected S_OK\n", i
, hr
);
467 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
469 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
471 SysFreeString(result
);
475 static void test_GetBaseName(void)
486 { L
"a/a.b.c", L
"a.b" },
497 hr
= IFileSystem3_GetBaseName(fs3
, NULL
, NULL
);
498 ok(hr
== E_POINTER
, "GetBaseName returned %x, expected E_POINTER\n", hr
);
500 for(i
=0; i
< ARRAY_SIZE(tests
); i
++) {
501 result
= (BSTR
)0xdeadbeef;
502 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
503 hr
= IFileSystem3_GetBaseName(fs3
, path
, &result
);
504 ok(hr
== S_OK
, "%d) GetBaseName returned %x, expected S_OK\n", i
, hr
);
506 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
508 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
510 SysFreeString(result
);
514 static void test_GetAbsolutePathName(void)
516 static const WCHAR dir1
[] = L
"test_dir1";
517 static const WCHAR dir2
[] = L
"test_dir2";
518 static const WCHAR dir_match1
[] = L
"test_dir*";
519 static const WCHAR dir_match2
[] = L
"test_di*";
521 WIN32_FIND_DATAW fdata
;
523 WCHAR buf
[MAX_PATH
], buf2
[MAX_PATH
];
527 hr
= IFileSystem3_GetAbsolutePathName(fs3
, NULL
, NULL
);
528 ok(hr
== E_POINTER
, "GetAbsolutePathName returned %x, expected E_POINTER\n", hr
);
530 hr
= IFileSystem3_GetAbsolutePathName(fs3
, NULL
, &result
);
531 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
532 GetFullPathNameW(L
".", MAX_PATH
, buf
, NULL
);
533 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
534 SysFreeString(result
);
536 find
= FindFirstFileW(dir_match2
, &fdata
);
537 if(find
!= INVALID_HANDLE_VALUE
) {
538 skip("GetAbsolutePathName tests\n");
543 path
= SysAllocString(dir_match1
);
544 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
545 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
546 GetFullPathNameW(dir_match1
, MAX_PATH
, buf2
, NULL
);
547 ok(!lstrcmpiW(buf2
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf2
));
548 SysFreeString(result
);
550 ok(CreateDirectoryW(dir1
, NULL
), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir1
));
551 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
552 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
553 GetFullPathNameW(dir1
, MAX_PATH
, buf
, NULL
);
554 ok(!lstrcmpiW(buf
, result
) || broken(!lstrcmpiW(buf2
, result
)), "result = %s, expected %s\n",
555 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
556 SysFreeString(result
);
558 ok(CreateDirectoryW(dir2
, NULL
), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir2
));
559 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
560 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
561 if(!lstrcmpiW(buf
, result
) || !lstrcmpiW(buf2
, result
)) {
562 ok(!lstrcmpiW(buf
, result
) || broken(!lstrcmpiW(buf2
, result
)), "result = %s, expected %s\n",
563 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
565 GetFullPathNameW(dir2
, MAX_PATH
, buf
, NULL
);
566 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n",
567 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
569 SysFreeString(result
);
572 path
= SysAllocString(dir_match2
);
573 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
574 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
575 GetFullPathNameW(dir_match2
, MAX_PATH
, buf
, NULL
);
576 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
577 SysFreeString(result
);
580 RemoveDirectoryW(dir1
);
581 RemoveDirectoryW(dir2
);
584 static void test_GetFile(void)
587 WCHAR pathW
[MAX_PATH
];
597 get_temp_path(NULL
, pathW
);
599 path
= SysAllocString(pathW
);
600 hr
= IFileSystem3_GetFile(fs3
, path
, NULL
);
601 ok(hr
== E_POINTER
, "GetFile returned %x, expected E_POINTER\n", hr
);
602 hr
= IFileSystem3_GetFile(fs3
, NULL
, &file
);
603 ok(hr
== E_INVALIDARG
, "GetFile returned %x, expected E_INVALIDARG\n", hr
);
605 file
= (IFile
*)0xdeadbeef;
606 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
607 ok(!file
, "file != NULL\n");
608 ok(hr
== CTL_E_FILENOTFOUND
, "GetFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
610 hf
= CreateFileW(pathW
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_READONLY
, NULL
);
611 if(hf
== INVALID_HANDLE_VALUE
) {
612 skip("Can't create temporary file\n");
618 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
619 ok(hr
== S_OK
, "GetFile returned %x, expected S_OK\n", hr
);
621 hr
= IFile_get_DateLastModified(file
, NULL
);
622 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
625 hr
= IFile_get_DateLastModified(file
, &date
);
626 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
627 ok(date
> 0.0, "got %f\n", date
);
629 hr
= IFile_get_Path(file
, NULL
);
630 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
632 hr
= IFile_get_Path(file
, &str
);
633 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
634 ok(!lstrcmpiW(str
, pathW
), "got %s\n", wine_dbgstr_w(str
));
637 #define FILE_ATTR_MASK (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
638 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE | \
639 FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED)
641 hr
= IFile_get_Attributes(file
, &fa
);
642 gfa
= GetFileAttributesW(pathW
) & FILE_ATTR_MASK
;
643 ok(hr
== S_OK
, "get_Attributes returned %x, expected S_OK\n", hr
);
644 ok(fa
== gfa
, "fa = %x, expected %x\n", fa
, gfa
);
646 hr
= IFile_put_Attributes(file
, gfa
| FILE_ATTRIBUTE_READONLY
);
647 ok(hr
== S_OK
, "put_Attributes failed: %08x\n", hr
);
648 new_gfa
= GetFileAttributesW(pathW
) & FILE_ATTR_MASK
;
649 ok(new_gfa
== (gfa
|FILE_ATTRIBUTE_READONLY
), "new_gfa = %x, expected %x\n", new_gfa
, gfa
|FILE_ATTRIBUTE_READONLY
);
651 hr
= IFile_get_Attributes(file
, &fa
);
652 ok(hr
== S_OK
, "get_Attributes returned %x, expected S_OK\n", hr
);
653 ok(fa
== new_gfa
, "fa = %x, expected %x\n", fa
, new_gfa
);
655 hr
= IFile_put_Attributes(file
, gfa
);
656 ok(hr
== S_OK
, "put_Attributes failed: %08x\n", hr
);
657 new_gfa
= GetFileAttributesW(pathW
) & FILE_ATTR_MASK
;
658 ok(new_gfa
== gfa
, "new_gfa = %x, expected %x\n", new_gfa
, gfa
);
660 hr
= IFile_get_Attributes(file
, &fa
);
661 ok(hr
== S_OK
, "get_Attributes returned %x, expected S_OK\n", hr
);
662 ok(fa
== gfa
, "fa = %x, expected %x\n", fa
, gfa
);
664 hr
= IFile_get_Size(file
, &size
);
665 ok(hr
== S_OK
, "get_Size returned %x, expected S_OK\n", hr
);
666 ok(V_VT(&size
) == VT_I4
, "V_VT(&size) = %d, expected VT_I4\n", V_VT(&size
));
667 ok(V_I4(&size
) == 0, "V_I4(&size) = %d, expected 0\n", V_I4(&size
));
670 hr
= IFileSystem3_DeleteFile(fs3
, path
, FALSE
);
671 ok(hr
==CTL_E_PERMISSIONDENIED
|| broken(hr
==S_OK
),
672 "DeleteFile returned %x, expected CTL_E_PERMISSIONDENIED\n", hr
);
674 hr
= IFileSystem3_DeleteFile(fs3
, path
, TRUE
);
675 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
677 hr
= IFileSystem3_DeleteFile(fs3
, path
, TRUE
);
678 ok(hr
== CTL_E_FILENOTFOUND
, "DeleteFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
682 /* try with directory */
683 lstrcatW(pathW
, L
"\\");
684 ret
= CreateDirectoryW(pathW
, NULL
);
685 ok(ret
, "got %d, error %d\n", ret
, GetLastError());
687 path
= SysAllocString(pathW
);
688 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
689 ok(hr
== CTL_E_FILENOTFOUND
, "GetFile returned %x, expected S_OK\n", hr
);
692 RemoveDirectoryW(pathW
);
695 static inline BOOL
create_file(const WCHAR
*name
)
697 HANDLE f
= CreateFileW(name
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, 0, NULL
);
699 return f
!= INVALID_HANDLE_VALUE
;
702 static inline void create_path(const WCHAR
*folder
, const WCHAR
*name
, WCHAR
*ret
)
704 DWORD len
= lstrlenW(folder
);
705 memmove(ret
, folder
, len
*sizeof(WCHAR
));
707 memmove(ret
+len
+1, name
, (lstrlenW(name
)+1)*sizeof(WCHAR
));
710 static void test_CopyFolder(void)
712 static const WCHAR filesystem3_dir
[] = L
"filesystem3_test";
713 static const WCHAR src1W
[] = L
"src1";
714 static const WCHAR dstW
[] = L
"dst";
720 if(!CreateDirectoryW(filesystem3_dir
, NULL
)) {
721 skip("can't create temporary directory\n");
725 create_path(filesystem3_dir
, src1W
, tmp
);
726 bsrc
= SysAllocString(tmp
);
727 create_path(filesystem3_dir
, dstW
, tmp
);
728 bdst
= SysAllocString(tmp
);
729 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
730 ok(hr
== CTL_E_FILENOTFOUND
, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
732 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
733 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
735 ok(create_file(bsrc
), "can't create %s file\n", wine_dbgstr_w(bsrc
));
736 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
737 ok(hr
== S_OK
, "CopyFile returned %x, expected S_OK\n", hr
);
739 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
740 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
742 hr
= IFileSystem3_DeleteFile(fs3
, bsrc
, VARIANT_FALSE
);
743 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
745 ok(CreateDirectoryW(bsrc
, NULL
), "can't create %s\n", wine_dbgstr_w(bsrc
));
746 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
747 ok(hr
== CTL_E_FILENOTFOUND
, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
749 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
750 ok(hr
== CTL_E_FILEALREADYEXISTS
, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
752 hr
= IFileSystem3_DeleteFile(fs3
, bdst
, VARIANT_TRUE
);
753 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
755 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
756 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
758 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
759 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
760 create_path(tmp
, src1W
, tmp
);
761 ok(GetFileAttributesW(tmp
) == INVALID_FILE_ATTRIBUTES
,
762 "%s file exists\n", wine_dbgstr_w(tmp
));
764 create_path(filesystem3_dir
, dstW
, tmp
);
765 create_path(tmp
, L
"", tmp
);
767 bdst
= SysAllocString(tmp
);
768 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
769 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
770 create_path(tmp
, src1W
, tmp
);
771 ok(GetFileAttributesW(tmp
) != INVALID_FILE_ATTRIBUTES
,
772 "%s directory doesn't exist\n", wine_dbgstr_w(tmp
));
773 ok(RemoveDirectoryW(tmp
), "can't remove %s directory\n", wine_dbgstr_w(tmp
));
774 create_path(filesystem3_dir
, dstW
, tmp
);
776 bdst
= SysAllocString(tmp
);
778 create_path(filesystem3_dir
, L
"src*", tmp
);
780 bsrc
= SysAllocString(tmp
);
781 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
782 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
783 create_path(filesystem3_dir
, dstW
, tmp
);
784 create_path(tmp
, src1W
, tmp
);
785 ok(GetFileAttributesW(tmp
) != INVALID_FILE_ATTRIBUTES
,
786 "%s directory doesn't exist\n", wine_dbgstr_w(tmp
));
788 hr
= IFileSystem3_DeleteFolder(fs3
, bdst
, VARIANT_FALSE
);
789 ok(hr
== S_OK
, "DeleteFolder returned %x, expected S_OK\n", hr
);
791 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
792 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
794 create_path(filesystem3_dir
, src1W
, tmp
);
796 bsrc
= SysAllocString(tmp
);
797 create_path(tmp
, src1W
, tmp
);
798 ok(create_file(tmp
), "can't create %s file\n", wine_dbgstr_w(tmp
));
799 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_FALSE
);
800 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
802 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_FALSE
);
803 ok(hr
== CTL_E_FILEALREADYEXISTS
, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
805 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
806 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
810 bsrc
= SysAllocString(filesystem3_dir
);
811 hr
= IFileSystem3_DeleteFolder(fs3
, bsrc
, VARIANT_FALSE
);
812 ok(hr
== S_OK
, "DeleteFolder returned %x, expected S_OK\n", hr
);
816 static BSTR
bstr_from_str(const char *str
)
818 int len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
819 BSTR ret
= SysAllocStringLen(NULL
, len
- 1); /* NUL character added automatically */
820 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
824 struct buildpath_test
831 static struct buildpath_test buildpath_data
[] =
833 { "C:\\path", "..\\name.tmp", "C:\\path\\..\\name.tmp" },
834 { "C:\\path", "\\name.tmp", "C:\\path\\name.tmp" },
835 { "C:\\path", "name.tmp", "C:\\path\\name.tmp" },
836 { "C:\\path\\", "name.tmp", "C:\\path\\name.tmp" },
837 { "C:\\path", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
838 { "C:\\path\\", "\\name.tmp", "C:\\path\\name.tmp" },
839 { "C:\\path\\", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
840 { "C:\\path\\\\", "\\\\name.tmp", "C:\\path\\\\\\name.tmp" },
841 { "C:\\\\", "\\name.tmp", "C:\\\\name.tmp" },
842 { "C:", "name.tmp", "C:name.tmp" },
843 { "C:", "\\\\name.tmp", "C:\\\\name.tmp" },
847 static void test_BuildPath(void)
849 struct buildpath_test
*ptr
= buildpath_data
;
854 hr
= IFileSystem3_BuildPath(fs3
, NULL
, NULL
, NULL
);
855 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
857 ret
= (BSTR
)0xdeadbeef;
858 hr
= IFileSystem3_BuildPath(fs3
, NULL
, NULL
, &ret
);
859 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
860 ok(*ret
== 0, "got %p\n", ret
);
863 ret
= (BSTR
)0xdeadbeef;
864 path
= bstr_from_str("path");
865 hr
= IFileSystem3_BuildPath(fs3
, path
, NULL
, &ret
);
866 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
867 ok(!lstrcmpW(ret
, path
), "got %s\n", wine_dbgstr_w(ret
));
871 ret
= (BSTR
)0xdeadbeef;
872 path
= bstr_from_str("path");
873 hr
= IFileSystem3_BuildPath(fs3
, NULL
, path
, &ret
);
874 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
875 ok(!lstrcmpW(ret
, path
), "got %s\n", wine_dbgstr_w(ret
));
884 path
= bstr_from_str(ptr
->path
);
885 name
= bstr_from_str(ptr
->name
);
886 result
= bstr_from_str(ptr
->result
);
887 hr
= IFileSystem3_BuildPath(fs3
, path
, name
, &ret
);
888 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
891 ok(!lstrcmpW(ret
, result
), "%d: got wrong path %s, expected %s\n", i
, wine_dbgstr_w(ret
),
892 wine_dbgstr_w(result
));
897 SysFreeString(result
);
904 static void test_GetFolder(void)
906 WCHAR buffW
[MAX_PATH
];
911 folder
= (void*)0xdeadbeef;
912 hr
= IFileSystem3_GetFolder(fs3
, NULL
, &folder
);
913 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
914 ok(folder
== NULL
, "got %p\n", folder
);
916 hr
= IFileSystem3_GetFolder(fs3
, NULL
, NULL
);
917 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
919 /* something that doesn't exist */
920 str
= SysAllocString(L
"dummy");
922 hr
= IFileSystem3_GetFolder(fs3
, str
, NULL
);
923 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
925 folder
= (void*)0xdeadbeef;
926 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
927 ok(hr
== CTL_E_PATHNOTFOUND
, "got 0x%08x\n", hr
);
928 ok(folder
== NULL
, "got %p\n", folder
);
931 GetWindowsDirectoryW(buffW
, MAX_PATH
);
932 str
= SysAllocString(buffW
);
933 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
934 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
936 test_provideclassinfo(folder
, &CLSID_Folder
);
937 IFolder_Release(folder
);
940 static void _test_clone(IEnumVARIANT
*enumvar
, BOOL position_inherited
, LONG count
, int line
)
947 hr
= IEnumVARIANT_Reset(enumvar
);
948 ok(hr
== S_OK
, "%d: got 0x%08x\n", line
, hr
);
952 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
953 ok(hr
== S_OK
, "%d: got 0x%08x\n", line
, hr
);
954 ok(fetched
== 1, "%d: got %d\n", line
, fetched
);
956 /* clone enumerator */
957 hr
= IEnumVARIANT_Clone(enumvar
, &clone
);
958 ok(hr
== S_OK
, "%d: got 0x%08x\n", line
, hr
);
959 ok(clone
!= enumvar
, "%d: got %p, %p\n", line
, enumvar
, clone
);
961 /* check if clone inherits position */
964 hr
= IEnumVARIANT_Next(clone
, 1, &var2
, &fetched
);
965 if (position_inherited
&& count
== 1)
967 ok(hr
== S_FALSE
, "%d: got 0x%08x\n", line
, hr
);
968 ok(fetched
== 0, "%d: got %d\n", line
, fetched
);
972 ok(hr
== S_OK
, "%d: got 0x%08x\n", line
, hr
);
973 ok(fetched
== 1, "%d: got %d\n", line
, fetched
);
974 if (!position_inherited
)
975 todo_wine
ok(V_DISPATCH(&var
) == V_DISPATCH(&var2
), "%d: values don't match\n", line
);
979 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
980 ok(hr
== S_OK
, "%d: got 0x%08x\n", line
, hr
);
981 ok(fetched
== 1, "%d: got %d\n", line
, fetched
);
982 todo_wine
ok(V_DISPATCH(&var
) == V_DISPATCH(&var2
), "%d: values don't match\n", line
);
988 IEnumVARIANT_Release(clone
);
990 hr
= IEnumVARIANT_Reset(enumvar
);
991 ok(hr
== S_OK
, "%d: got 0x%08x\n", line
, hr
);
993 #define test_clone(a, b, c) _test_clone(a, b, c, __LINE__)
995 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
996 static void test_FolderCollection(void)
998 static const WCHAR aW
[] = L
"\\a";
999 static const WCHAR bW
[] = L
"\\b";
1000 static const WCHAR cW
[] = L
"\\c";
1001 IFolderCollection
*folders
;
1002 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
1003 IEnumVARIANT
*enumvar
;
1004 LONG count
, ref
, ref2
, i
;
1005 IUnknown
*unk
, *unk2
;
1008 VARIANT var
, var2
[2];
1011 int found_a
= 0, found_b
= 0, found_c
= 0;
1013 get_temp_path(L
"foo", buffW
);
1014 CreateDirectoryW(buffW
, NULL
);
1016 str
= SysAllocString(buffW
);
1017 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
1018 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1021 hr
= IFolder_get_SubFolders(folder
, NULL
);
1022 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1024 hr
= IFolder_get_Path(folder
, NULL
);
1025 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1027 hr
= IFolder_get_Path(folder
, &str
);
1028 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1029 ok(!lstrcmpiW(buffW
, str
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1032 lstrcpyW(pathW
, buffW
);
1033 lstrcatW(pathW
, aW
);
1034 CreateDirectoryW(pathW
, NULL
);
1036 lstrcpyW(pathW
, buffW
);
1037 lstrcatW(pathW
, bW
);
1038 CreateDirectoryW(pathW
, NULL
);
1040 hr
= IFolder_get_SubFolders(folder
, &folders
);
1041 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1042 test_provideclassinfo(folders
, &CLSID_Folders
);
1043 IFolder_Release(folder
);
1046 hr
= IFolderCollection_get_Count(folders
, &count
);
1047 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1048 ok(count
== 2, "got %d\n", count
);
1050 lstrcpyW(pathW
, buffW
);
1051 lstrcatW(pathW
, cW
);
1052 CreateDirectoryW(pathW
, NULL
);
1054 /* every time property is requested it scans directory */
1056 hr
= IFolderCollection_get_Count(folders
, &count
);
1057 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1058 ok(count
== 3, "got %d\n", count
);
1060 hr
= IFolderCollection_get__NewEnum(folders
, NULL
);
1061 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1063 hr
= IFolderCollection_QueryInterface(folders
, &IID_IEnumVARIANT
, (void**)&unk
);
1064 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1066 /* NewEnum creates new instance each time it's called */
1067 ref
= GET_REFCOUNT(folders
);
1070 hr
= IFolderCollection_get__NewEnum(folders
, &unk
);
1071 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1073 ref2
= GET_REFCOUNT(folders
);
1074 ok(ref2
== ref
+ 1, "got %d, %d\n", ref2
, ref
);
1077 hr
= IFolderCollection_get__NewEnum(folders
, &unk2
);
1078 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1079 ok(unk
!= unk2
, "got %p, %p\n", unk2
, unk
);
1080 IUnknown_Release(unk2
);
1082 /* now get IEnumVARIANT */
1083 ref
= GET_REFCOUNT(folders
);
1084 hr
= IUnknown_QueryInterface(unk
, &IID_IEnumVARIANT
, (void**)&enumvar
);
1085 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1086 ref2
= GET_REFCOUNT(folders
);
1087 ok(ref2
== ref
, "got %d, %d\n", ref2
, ref
);
1089 test_clone(enumvar
, FALSE
, count
);
1091 for (i
= 0; i
< 3; i
++)
1095 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1096 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
1097 ok(fetched
== 1, "%d: got %d\n", i
, fetched
);
1098 ok(V_VT(&var
) == VT_DISPATCH
, "%d: got type %d\n", i
, V_VT(&var
));
1100 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IFolder
, (void**)&folder
);
1101 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1104 hr
= IFolder_get_Name(folder
, &str
);
1105 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1106 if (!lstrcmpW(str
, aW
+ 1))
1108 else if (!lstrcmpW(str
, bW
+ 1))
1110 else if (!lstrcmpW(str
, cW
+ 1))
1113 ok(0, "unexpected folder %s was found\n", wine_dbgstr_w(str
));
1116 IFolder_Release(folder
);
1120 ok(found_a
== 1 && found_b
== 1 && found_c
== 1,
1121 "each folder should be found 1 time instead of %d/%d/%d\n",
1122 found_a
, found_b
, found_c
);
1126 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1127 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1128 ok(fetched
== 0, "got %d\n", fetched
);
1130 hr
= IEnumVARIANT_Reset(enumvar
);
1131 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1132 hr
= IEnumVARIANT_Skip(enumvar
, 2);
1133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1134 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1135 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1137 VariantInit(&var2
[0]);
1138 VariantInit(&var2
[1]);
1140 hr
= IEnumVARIANT_Next(enumvar
, 0, var2
, &fetched
);
1141 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1142 ok(fetched
== 0, "got %d\n", fetched
);
1144 hr
= IEnumVARIANT_Next(enumvar
, 2, var2
, &fetched
);
1145 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1146 ok(fetched
== 1, "got %d\n", fetched
);
1147 ok(V_VT(&var2
[0]) == VT_DISPATCH
, "got type %d\n", V_VT(&var2
[0]));
1148 VariantClear(&var2
[0]);
1149 VariantClear(&var2
[1]);
1151 IEnumVARIANT_Release(enumvar
);
1152 IUnknown_Release(unk
);
1154 lstrcpyW(pathW
, buffW
);
1155 lstrcatW(pathW
, aW
);
1156 RemoveDirectoryW(pathW
);
1157 lstrcpyW(pathW
, buffW
);
1158 lstrcatW(pathW
, bW
);
1159 RemoveDirectoryW(pathW
);
1160 lstrcpyW(pathW
, buffW
);
1161 lstrcatW(pathW
, cW
);
1162 RemoveDirectoryW(pathW
);
1163 RemoveDirectoryW(buffW
);
1165 IFolderCollection_Release(folders
);
1168 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1169 static void test_FileCollection(void)
1171 static const WCHAR aW
[] = L
"\\a";
1172 static const WCHAR bW
[] = L
"\\b";
1173 static const WCHAR cW
[] = L
"\\c";
1174 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
1176 IFileCollection
*files
;
1178 IEnumVARIANT
*enumvar
;
1179 LONG count
, ref
, ref2
, i
;
1180 IUnknown
*unk
, *unk2
;
1182 VARIANT var
, var2
[2];
1185 HANDLE file_a
, file_b
, file_c
;
1186 int found_a
= 0, found_b
= 0, found_c
= 0;
1188 get_temp_path(L
"\\foo", buffW
);
1189 CreateDirectoryW(buffW
, NULL
);
1191 str
= SysAllocString(buffW
);
1192 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
1193 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1196 hr
= IFolder_get_Files(folder
, NULL
);
1197 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1199 lstrcpyW(pathW
, buffW
);
1200 lstrcatW(pathW
, aW
);
1201 file_a
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1202 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1203 lstrcpyW(pathW
, buffW
);
1204 lstrcatW(pathW
, bW
);
1205 file_b
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1206 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1208 hr
= IFolder_get_Files(folder
, &files
);
1209 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1210 test_provideclassinfo(files
, &CLSID_Files
);
1211 IFolder_Release(folder
);
1214 hr
= IFileCollection_get_Count(files
, &count
);
1215 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1216 ok(count
== 2, "got %d\n", count
);
1218 lstrcpyW(pathW
, buffW
);
1219 lstrcatW(pathW
, cW
);
1220 file_c
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1221 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1223 /* every time property is requested it scans directory */
1225 hr
= IFileCollection_get_Count(files
, &count
);
1226 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1227 ok(count
== 3, "got %d\n", count
);
1229 hr
= IFileCollection_get__NewEnum(files
, NULL
);
1230 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1232 hr
= IFileCollection_QueryInterface(files
, &IID_IEnumVARIANT
, (void**)&unk
);
1233 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1235 /* NewEnum creates new instance each time it's called */
1236 ref
= GET_REFCOUNT(files
);
1239 hr
= IFileCollection_get__NewEnum(files
, &unk
);
1240 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1242 ref2
= GET_REFCOUNT(files
);
1243 ok(ref2
== ref
+ 1, "got %d, %d\n", ref2
, ref
);
1246 hr
= IFileCollection_get__NewEnum(files
, &unk2
);
1247 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1248 ok(unk
!= unk2
, "got %p, %p\n", unk2
, unk
);
1249 IUnknown_Release(unk2
);
1251 /* now get IEnumVARIANT */
1252 ref
= GET_REFCOUNT(files
);
1253 hr
= IUnknown_QueryInterface(unk
, &IID_IEnumVARIANT
, (void**)&enumvar
);
1254 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1255 ref2
= GET_REFCOUNT(files
);
1256 ok(ref2
== ref
, "got %d, %d\n", ref2
, ref
);
1258 test_clone(enumvar
, FALSE
, count
);
1260 for (i
= 0; i
< 3; i
++)
1264 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1265 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
1266 ok(fetched
== 1, "%d: got %d\n", i
, fetched
);
1267 ok(V_VT(&var
) == VT_DISPATCH
, "%d: got type %d\n", i
, V_VT(&var
));
1269 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IFile
, (void **)&file
);
1270 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1271 test_provideclassinfo(file
, &CLSID_File
);
1274 hr
= IFile_get_Name(file
, &str
);
1275 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1276 if (!lstrcmpW(str
, aW
+ 1))
1278 else if (!lstrcmpW(str
, bW
+ 1))
1280 else if (!lstrcmpW(str
, cW
+ 1))
1283 ok(0, "unexpected file %s was found\n", wine_dbgstr_w(str
));
1286 IFile_Release(file
);
1290 ok(found_a
== 1 && found_b
== 1 && found_c
== 1,
1291 "each file should be found 1 time instead of %d/%d/%d\n",
1292 found_a
, found_b
, found_c
);
1296 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1297 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1298 ok(fetched
== 0, "got %d\n", fetched
);
1300 hr
= IEnumVARIANT_Reset(enumvar
);
1301 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1302 hr
= IEnumVARIANT_Skip(enumvar
, 2);
1303 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1304 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1305 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1307 VariantInit(&var2
[0]);
1308 VariantInit(&var2
[1]);
1310 hr
= IEnumVARIANT_Next(enumvar
, 0, var2
, &fetched
);
1311 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1312 ok(fetched
== 0, "got %d\n", fetched
);
1314 hr
= IEnumVARIANT_Next(enumvar
, 2, var2
, &fetched
);
1315 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1316 ok(fetched
== 1, "got %d\n", fetched
);
1317 ok(V_VT(&var2
[0]) == VT_DISPATCH
, "got type %d\n", V_VT(&var2
[0]));
1318 VariantClear(&var2
[0]);
1319 VariantClear(&var2
[1]);
1321 IEnumVARIANT_Release(enumvar
);
1322 IUnknown_Release(unk
);
1324 CloseHandle(file_a
);
1325 CloseHandle(file_b
);
1326 CloseHandle(file_c
);
1327 RemoveDirectoryW(buffW
);
1329 IFileCollection_Release(files
);
1332 static void test_DriveCollection(void)
1334 IDriveCollection
*drives
;
1335 IEnumVARIANT
*enumvar
;
1341 hr
= IFileSystem3_get_Drives(fs3
, &drives
);
1342 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1344 test_provideclassinfo(drives
, &CLSID_Drives
);
1346 hr
= IDriveCollection_get__NewEnum(drives
, (IUnknown
**)&enumvar
);
1347 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1349 hr
= IDriveCollection_get_Count(drives
, NULL
);
1350 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1353 hr
= IDriveCollection_get_Count(drives
, &count
);
1354 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1355 ok(count
> 0, "got %d\n", count
);
1357 V_VT(&var
) = VT_EMPTY
;
1359 hr
= IEnumVARIANT_Next(enumvar
, 0, &var
, &fetched
);
1360 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1361 ok(fetched
== 0, "got %d\n", fetched
);
1363 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1364 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1366 hr
= IEnumVARIANT_Skip(enumvar
, count
);
1367 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1369 hr
= IEnumVARIANT_Skip(enumvar
, 1);
1370 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1372 test_clone(enumvar
, TRUE
, count
);
1374 while (IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
) == S_OK
) {
1375 IDrive
*drive
= (IDrive
*)V_DISPATCH(&var
);
1376 DriveTypeConst type
;
1379 hr
= IDrive_get_DriveType(drive
, &type
);
1380 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1382 hr
= IDrive_get_DriveLetter(drive
, NULL
);
1383 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1385 hr
= IDrive_get_DriveLetter(drive
, &str
);
1386 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1387 ok(SysStringLen(str
) == 1, "got string %s\n", wine_dbgstr_w(str
));
1390 hr
= IDrive_get_IsReady(drive
, NULL
);
1391 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1393 hr
= IDrive_get_TotalSize(drive
, NULL
);
1394 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1396 hr
= IDrive_get_AvailableSpace(drive
, NULL
);
1397 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1399 hr
= IDrive_get_FreeSpace(drive
, NULL
);
1400 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1402 if (type
== Fixed
) {
1403 VARIANT_BOOL ready
= VARIANT_FALSE
;
1406 hr
= IDrive_get_IsReady(drive
, &ready
);
1407 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1408 ok(ready
== VARIANT_TRUE
, "got %x\n", ready
);
1410 if (ready
!= VARIANT_TRUE
) {
1411 hr
= IDrive_get_DriveLetter(drive
, &str
);
1412 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1414 skip("Drive %s is not ready, skipping some tests\n", wine_dbgstr_w(str
));
1421 V_VT(&size
) = VT_EMPTY
;
1422 hr
= IDrive_get_TotalSize(drive
, &size
);
1423 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1424 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1425 if (V_VT(&size
) == VT_R8
)
1426 ok(V_R8(&size
) > 0, "got %f\n", V_R8(&size
));
1428 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1430 V_VT(&size
) = VT_EMPTY
;
1431 hr
= IDrive_get_AvailableSpace(drive
, &size
);
1432 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1433 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1434 if (V_VT(&size
) == VT_R8
)
1435 ok(V_R8(&size
) > (double)INT_MAX
, "got %f\n", V_R8(&size
));
1437 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1439 V_VT(&size
) = VT_EMPTY
;
1440 hr
= IDrive_get_FreeSpace(drive
, &size
);
1441 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1442 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1443 if (V_VT(&size
) == VT_R8
)
1444 ok(V_R8(&size
) > 0, "got %f\n", V_R8(&size
));
1446 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1451 IEnumVARIANT_Release(enumvar
);
1452 IDriveCollection_Release(drives
);
1455 static void get_temp_filepath(const WCHAR
*filename
, WCHAR
*path
, WCHAR
*dir
)
1457 GetTempPathW(MAX_PATH
, path
);
1458 lstrcatW(path
, L
"scrrun\\");
1459 lstrcpyW(dir
, path
);
1460 lstrcatW(path
, filename
);
1463 static void test_CreateTextFile(void)
1465 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[10];
1466 ITextStream
*stream
;
1472 get_temp_filepath(testfileW
, pathW
, dirW
);
1474 /* dir doesn't exist */
1475 nameW
= SysAllocString(pathW
);
1476 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1477 ok(hr
== CTL_E_PATHNOTFOUND
, "got 0x%08x\n", hr
);
1479 ret
= CreateDirectoryW(dirW
, NULL
);
1480 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1482 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1483 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1485 test_provideclassinfo(stream
, &CLSID_TextStream
);
1487 hr
= ITextStream_Read(stream
, 1, &str
);
1488 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1490 hr
= ITextStream_Close(stream
);
1491 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1493 hr
= ITextStream_Read(stream
, 1, &str
);
1494 ok(hr
== CTL_E_BADFILEMODE
|| hr
== E_VAR_NOT_SET
, "got 0x%08x\n", hr
);
1496 hr
= ITextStream_Close(stream
);
1497 ok(hr
== S_FALSE
|| hr
== E_VAR_NOT_SET
, "got 0x%08x\n", hr
);
1499 ITextStream_Release(stream
);
1501 /* check it's created */
1502 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1503 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1506 /* try to create again with no-overwrite mode */
1507 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1508 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x\n", hr
);
1511 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1512 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1513 ITextStream_Release(stream
);
1515 /* overwrite in Unicode mode, check for BOM */
1516 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_TRUE
, &stream
);
1517 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1518 ITextStream_Release(stream
);
1520 /* File was created in Unicode mode, it contains 0xfffe BOM. Opening it in non-Unicode mode
1521 treats BOM like a valuable data with appropriate CP_ACP -> WCHAR conversion. */
1523 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, ARRAY_SIZE(buffW
));
1525 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1526 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1527 hr
= ITextStream_ReadAll(stream
, &str
);
1528 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1529 ok(!lstrcmpW(str
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1531 ITextStream_Release(stream
);
1534 RemoveDirectoryW(dirW
);
1535 SysFreeString(nameW
);
1538 static void test_WriteLine(void)
1540 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
];
1541 WCHAR buffW
[MAX_PATH
], buff2W
[MAX_PATH
];
1542 char buffA
[MAX_PATH
];
1543 ITextStream
*stream
;
1550 get_temp_filepath(testfileW
, pathW
, dirW
);
1552 ret
= CreateDirectoryW(dirW
, NULL
);
1553 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1555 /* create as ASCII file first */
1556 nameW
= SysAllocString(pathW
);
1557 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1558 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1560 hr
= ITextStream_WriteLine(stream
, nameW
);
1561 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1562 ITextStream_Release(stream
);
1564 /* check contents */
1565 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1566 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1568 ret
= ReadFile(file
, buffA
, sizeof(buffA
), &r
, NULL
);
1569 ok(ret
&& r
, "read %d, got %d, %d\n", r
, ret
, GetLastError());
1571 len
= MultiByteToWideChar(CP_ACP
, 0, buffA
, r
, buffW
, ARRAY_SIZE(buffW
));
1573 lstrcpyW(buff2W
, nameW
);
1574 lstrcatW(buff2W
, L
"\r\n");
1575 ok(!lstrcmpW(buff2W
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(buff2W
));
1579 /* same for unicode file */
1580 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1581 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1583 hr
= ITextStream_WriteLine(stream
, nameW
);
1584 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1585 ITextStream_Release(stream
);
1587 /* check contents */
1588 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1589 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1591 ret
= ReadFile(file
, buffW
, sizeof(buffW
), &r
, NULL
);
1592 ok(ret
&& r
, "read %d, got %d, %d\n", r
, ret
, GetLastError());
1593 buffW
[r
/sizeof(WCHAR
)] = 0;
1597 lstrcatW(buff2W
, nameW
);
1598 lstrcatW(buff2W
, L
"\r\n");
1599 ok(!lstrcmpW(buff2W
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(buff2W
));
1603 RemoveDirectoryW(dirW
);
1604 SysFreeString(nameW
);
1607 static void test_ReadAll(void)
1609 static const WCHAR secondlineW
[] = L
"second";
1610 static const WCHAR aW
[] = L
"A";
1611 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[500];
1612 ITextStream
*stream
;
1618 get_temp_filepath(testfileW
, pathW
, dirW
);
1620 ret
= CreateDirectoryW(dirW
, NULL
);
1621 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1623 /* Unicode file -> read with ascii stream */
1624 nameW
= SysAllocString(pathW
);
1625 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1626 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1628 hr
= ITextStream_WriteLine(stream
, nameW
);
1629 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1631 str
= SysAllocString(secondlineW
);
1632 hr
= ITextStream_WriteLine(stream
, str
);
1633 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1636 hr
= ITextStream_ReadAll(stream
, NULL
);
1637 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1639 str
= (void*)0xdeadbeef;
1640 hr
= ITextStream_ReadAll(stream
, &str
);
1641 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1642 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1644 ITextStream_Release(stream
);
1646 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1647 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1649 hr
= ITextStream_ReadAll(stream
, NULL
);
1650 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1652 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1654 hr
= ITextStream_ReadAll(stream
, &str
);
1655 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1657 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, ARRAY_SIZE(buffW
));
1658 ok(str
[0] == buffW
[0] && str
[1] == buffW
[1], "got %s, %d\n", wine_dbgstr_w(str
), SysStringLen(str
));
1660 ITextStream_Release(stream
);
1662 /* Unicode file -> read with unicode stream */
1663 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1664 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1666 lstrcpyW(buffW
, nameW
);
1667 lstrcatW(buffW
, L
"\r\n");
1668 lstrcatW(buffW
, secondlineW
);
1669 lstrcatW(buffW
, L
"\r\n");
1671 hr
= ITextStream_ReadAll(stream
, &str
);
1672 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1673 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1676 /* ReadAll one more time */
1677 str
= (void*)0xdeadbeef;
1678 hr
= ITextStream_ReadAll(stream
, &str
);
1679 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1680 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1682 /* ReadLine fails the same way */
1683 str
= (void*)0xdeadbeef;
1684 hr
= ITextStream_ReadLine(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
);
1687 ITextStream_Release(stream
);
1689 /* Open again and skip first line before ReadAll */
1690 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1691 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1694 hr
= ITextStream_ReadLine(stream
, &str
);
1695 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1696 ok(str
!= NULL
, "got %p\n", str
);
1697 ok(!wcscmp(str
, nameW
), "got %s\n", wine_dbgstr_w(str
));
1700 lstrcpyW(buffW
, secondlineW
);
1701 lstrcatW(buffW
, L
"\r\n");
1703 hr
= ITextStream_ReadAll(stream
, &str
);
1704 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1705 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1707 ITextStream_Release(stream
);
1709 /* ASCII file, read with Unicode stream */
1710 /* 1. one byte content, not enough for Unicode read */
1711 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1712 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1713 str
= SysAllocString(aW
);
1714 hr
= ITextStream_Write(stream
, str
);
1715 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1717 ITextStream_Release(stream
);
1719 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1720 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1722 str
= (void*)0xdeadbeef;
1723 hr
= ITextStream_ReadAll(stream
, &str
);
1724 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1725 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1727 ITextStream_Release(stream
);
1730 RemoveDirectoryW(dirW
);
1731 SysFreeString(nameW
);
1734 static void test_Read(void)
1736 static const WCHAR secondlineW
[] = L
"second";
1737 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[500];
1738 ITextStream
*stream
;
1744 get_temp_filepath(testfileW
, pathW
, dirW
);
1746 ret
= CreateDirectoryW(dirW
, NULL
);
1747 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1749 /* Unicode file -> read with ascii stream */
1750 nameW
= SysAllocString(pathW
);
1751 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1752 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1754 hr
= ITextStream_WriteLine(stream
, nameW
);
1755 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1757 str
= SysAllocString(secondlineW
);
1758 hr
= ITextStream_WriteLine(stream
, str
);
1759 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1762 hr
= ITextStream_Read(stream
, 0, NULL
);
1763 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1765 hr
= ITextStream_Read(stream
, 1, NULL
);
1766 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1768 hr
= ITextStream_Read(stream
, -1, NULL
);
1769 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1771 str
= (void*)0xdeadbeef;
1772 hr
= ITextStream_Read(stream
, 1, &str
);
1773 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1774 ok(str
== NULL
, "got %p\n", str
);
1776 ITextStream_Release(stream
);
1778 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1779 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1781 hr
= ITextStream_Read(stream
, 1, NULL
);
1782 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1784 str
= (void*)0xdeadbeef;
1785 hr
= ITextStream_Read(stream
, -1, &str
);
1786 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1787 ok(str
== NULL
, "got %p\n", str
);
1789 str
= (void*)0xdeadbeef;
1790 hr
= ITextStream_Read(stream
, 0, &str
);
1791 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1792 ok(str
== NULL
, "got %p\n", str
);
1794 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1796 hr
= ITextStream_Read(stream
, 2, &str
);
1797 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1800 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, ARRAY_SIZE(buffW
));
1802 ok(!lstrcmpW(str
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1803 ok(SysStringLen(str
) == 2, "got %d\n", SysStringLen(str
));
1805 ITextStream_Release(stream
);
1807 /* Unicode file -> read with unicode stream */
1808 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1809 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1811 lstrcpyW(buffW
, nameW
);
1812 lstrcatW(buffW
, L
"\r\n");
1813 lstrcatW(buffW
, secondlineW
);
1814 lstrcatW(buffW
, L
"\r\n");
1816 hr
= ITextStream_Read(stream
, 500, &str
);
1817 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1818 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1821 /* ReadAll one more time */
1822 str
= (void*)0xdeadbeef;
1823 hr
= ITextStream_Read(stream
, 10, &str
);
1824 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1825 ok(str
== NULL
, "got %p\n", str
);
1827 /* ReadLine fails the same way */
1828 str
= (void*)0xdeadbeef;
1829 hr
= ITextStream_ReadLine(stream
, &str
);
1830 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1831 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef), "got %p\n", str
);
1832 ITextStream_Release(stream
);
1834 /* Open again and skip first line before ReadAll */
1835 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1836 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1839 hr
= ITextStream_ReadLine(stream
, &str
);
1840 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1841 ok(str
!= NULL
, "got %p\n", str
);
1844 lstrcpyW(buffW
, secondlineW
);
1845 lstrcatW(buffW
, L
"\r\n");
1847 hr
= ITextStream_Read(stream
, 100, &str
);
1848 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1849 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1851 ITextStream_Release(stream
);
1853 /* default read will use Unicode */
1854 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateUseDefault
, &stream
);
1855 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1857 lstrcpyW(buffW
, nameW
);
1858 lstrcatW(buffW
, L
"\r\n");
1859 lstrcatW(buffW
, secondlineW
);
1860 lstrcatW(buffW
, L
"\r\n");
1862 hr
= ITextStream_Read(stream
, 500, &str
);
1863 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2003 */, "got 0x%08x\n", hr
);
1864 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1867 ITextStream_Release(stream
);
1869 /* default append will use Unicode */
1870 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForAppending
, VARIANT_FALSE
, TristateUseDefault
, &stream
);
1871 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1873 str
= SysAllocString(L
"123");
1874 hr
= ITextStream_Write(stream
, str
);
1875 ok(hr
== S_OK
, "got %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 lstrcatW(buffW
, L
"123");
1885 hr
= ITextStream_Read(stream
, 500, &str
);
1886 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2003 */, "got 0x%08x\n", hr
);
1887 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1890 ITextStream_Release(stream
);
1892 /* default write will use ASCII */
1893 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForWriting
, VARIANT_FALSE
, TristateUseDefault
, &stream
);
1894 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1896 str
= SysAllocString(L
"123");
1897 hr
= ITextStream_Write(stream
, str
);
1898 ok(hr
== S_OK
, "got %08x\n", hr
);
1901 ITextStream_Release(stream
);
1903 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1904 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1906 str
= (void*)0xdeadbeef;
1907 hr
= ITextStream_Read(stream
, 500, &str
);
1908 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2003 */, "got 0x%08x\n", hr
);
1909 ok(!wcscmp(str
, L
"123"), "got %s\n", wine_dbgstr_w(str
));
1911 ITextStream_Release(stream
);
1912 /* ASCII file, read with default stream */
1913 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1914 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1915 str
= SysAllocString(L
"test");
1916 hr
= ITextStream_Write(stream
, str
);
1917 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1919 ITextStream_Release(stream
);
1921 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateUseDefault
, &stream
);
1922 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1924 str
= (void*)0xdeadbeef;
1925 hr
= ITextStream_Read(stream
, 500, &str
);
1926 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2003 */, "got 0x%08x\n", hr
);
1927 ok(!wcscmp(str
, L
"test"), "got %s\n", wine_dbgstr_w(str
));
1929 ITextStream_Release(stream
);
1931 /* default append will use Unicode */
1932 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForAppending
, VARIANT_FALSE
, TristateUseDefault
, &stream
);
1933 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1935 str
= SysAllocString(L
"123");
1936 hr
= ITextStream_Write(stream
, str
);
1937 ok(hr
== S_OK
, "got %08x\n", hr
);
1940 ITextStream_Release(stream
);
1942 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1943 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1946 hr
= ITextStream_Read(stream
, 500, &str
);
1947 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2003 */, "got 0x%08x\n", hr
);
1948 ok(!lstrcmpW(L
"test123", str
), "got %s\n", wine_dbgstr_w(str
));
1951 ITextStream_Release(stream
);
1953 /* default write will use ASCII as well */
1954 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForWriting
, VARIANT_FALSE
, TristateUseDefault
, &stream
);
1955 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1957 str
= SysAllocString(L
"test string");
1958 hr
= ITextStream_Write(stream
, str
);
1959 ok(hr
== S_OK
, "got %08x\n", hr
);
1962 ITextStream_Release(stream
);
1964 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1965 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1967 str
= (void*)0xdeadbeef;
1968 hr
= ITextStream_Read(stream
, 500, &str
);
1969 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2003 */, "got 0x%08x\n", hr
);
1970 ok(!wcscmp(str
, L
"test string"), "got %s\n", wine_dbgstr_w(str
));
1972 ITextStream_Release(stream
);
1974 /* ASCII file, read with Unicode stream */
1975 /* 1. one byte content, not enough for Unicode read */
1976 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1977 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1978 str
= SysAllocString(L
"A");
1979 hr
= ITextStream_Write(stream
, str
);
1980 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1982 ITextStream_Release(stream
);
1984 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1985 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1987 str
= (void*)0xdeadbeef;
1988 hr
= ITextStream_Read(stream
, 500, &str
);
1989 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1990 ok(str
== NULL
, "got %p\n", str
);
1992 ITextStream_Release(stream
);
1994 /* ASCII file, read with Unicode stream */
1995 /* 3. one byte content, 2 are interpreted as a character, 3rd is lost */
1996 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1997 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1998 str
= SysAllocString(L
"abc");
1999 hr
= ITextStream_Write(stream
, str
);
2000 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2002 ITextStream_Release(stream
);
2004 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
2005 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2008 hr
= ITextStream_Read(stream
, 500, &str
);
2009 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2003 */, "got 0x%08x\n", hr
);
2010 ok(SysStringLen(str
) == 1, "len = %u\n", SysStringLen(str
));
2013 str
= (void*)0xdeadbeef;
2014 hr
= ITextStream_Read(stream
, 500, &str
);
2015 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
2016 ok(str
== NULL
, "got %p\n", str
);
2018 ITextStream_Release(stream
);
2021 RemoveDirectoryW(dirW
);
2022 SysFreeString(nameW
);
2025 static void test_ReadLine(void)
2027 WCHAR path
[MAX_PATH
], dir
[MAX_PATH
];
2028 ITextStream
*stream
;
2036 const char data
[] = "first line\r\nsecond\n\n\rt\r\re \rst\n";
2038 get_temp_filepath(L
"test.txt", path
, dir
);
2040 ret
= CreateDirectoryW(dir
, NULL
);
2041 ok(ret
, "got %d, %d\n", ret
, GetLastError());
2043 file
= CreateFileW(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
2044 FILE_ATTRIBUTE_NORMAL
, NULL
);
2045 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
2047 for (i
= 0; i
< 1000; i
++)
2048 WriteFile(file
, data
, strlen(data
), &size
, NULL
);
2051 str
= SysAllocString(path
);
2052 hr
= IFileSystem3_OpenTextFile(fs3
, str
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
2053 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2056 for (i
= 0; i
< 1000; i
++)
2058 hr
= ITextStream_ReadLine(stream
, &str
);
2059 ok(hr
== S_OK
, "ReadLine failed: %08x\n", hr
);
2060 ok(!wcscmp(str
, L
"first line"), "ReadLine returned %s\n", wine_dbgstr_w(str
));
2063 hr
= ITextStream_ReadLine(stream
, &str
);
2064 ok(hr
== S_OK
, "ReadLine failed: %08x\n", hr
);
2065 ok(!wcscmp(str
, L
"second"), "ReadLine returned %s\n", wine_dbgstr_w(str
));
2068 hr
= ITextStream_ReadLine(stream
, &str
);
2069 ok(hr
== S_OK
, "ReadLine failed: %08x\n", hr
);
2070 ok(!*str
, "ReadLine returned %s\n", wine_dbgstr_w(str
));
2073 hr
= ITextStream_ReadLine(stream
, &str
);
2074 ok(hr
== S_OK
, "ReadLine failed: %08x\n", hr
);
2075 ok(!wcscmp(str
, L
"\rt\r\re \rst"), "ReadLine returned %s\n", wine_dbgstr_w(str
));
2080 hr
= ITextStream_ReadLine(stream
, &str
);
2081 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
2082 ok(!str
, "ReadLine returned %s\n", wine_dbgstr_w(str
));
2085 ITextStream_Release(stream
);
2087 ret
= DeleteFileW(path
);
2088 ok(ret
, "DeleteFile failed: %u\n", GetLastError());
2090 ret
= RemoveDirectoryW(dir
);
2091 ok(ret
, "RemoveDirectory failed: %u\n", GetLastError());
2094 struct driveexists_test
{
2095 const WCHAR drivespec
[10];
2096 const INT drivetype
;
2097 const VARIANT_BOOL expected_ret
;
2100 /* If 'drivetype' != -1, the first character of 'drivespec' will be replaced
2101 * with the drive letter of a drive of this type. If such a drive does not exist,
2102 * the test will be skipped. */
2103 static const struct driveexists_test driveexiststestdata
[] = {
2104 { L
"N:\\", DRIVE_NO_ROOT_DIR
, VARIANT_FALSE
},
2105 { L
"R:\\", DRIVE_REMOVABLE
, VARIANT_TRUE
},
2106 { L
"F:\\", DRIVE_FIXED
, VARIANT_TRUE
},
2107 { L
"F:", DRIVE_FIXED
, VARIANT_TRUE
},
2108 { L
"F?", DRIVE_FIXED
, VARIANT_FALSE
},
2109 { L
"F", DRIVE_FIXED
, VARIANT_TRUE
},
2110 { L
"?", -1, VARIANT_FALSE
},
2114 static void test_DriveExists(void)
2116 const struct driveexists_test
*ptr
= driveexiststestdata
;
2120 WCHAR root
[] = L
"?:\\";
2122 hr
= IFileSystem3_DriveExists(fs3
, NULL
, NULL
);
2123 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2126 hr
= IFileSystem3_DriveExists(fs3
, NULL
, &ret
);
2127 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2128 ok(ret
== VARIANT_FALSE
, "got %x\n", ret
);
2130 drivespec
= SysAllocString(root
);
2131 hr
= IFileSystem3_DriveExists(fs3
, drivespec
, NULL
);
2132 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2133 SysFreeString(drivespec
);
2135 for (; *ptr
->drivespec
; ptr
++) {
2136 drivespec
= SysAllocString(ptr
->drivespec
);
2137 if (ptr
->drivetype
!= -1) {
2138 for (root
[0] = 'A'; root
[0] <= 'Z'; root
[0]++)
2139 if (GetDriveTypeW(root
) == ptr
->drivetype
)
2141 if (root
[0] > 'Z') {
2142 skip("No drive with type 0x%x found, skipping test %s.\n",
2143 ptr
->drivetype
, wine_dbgstr_w(ptr
->drivespec
));
2144 SysFreeString(drivespec
);
2148 /* Test both upper and lower case drive letters. */
2149 drivespec
[0] = root
[0];
2150 ret
= ptr
->expected_ret
== VARIANT_TRUE
? VARIANT_FALSE
: VARIANT_TRUE
;
2151 hr
= IFileSystem3_DriveExists(fs3
, drivespec
, &ret
);
2152 ok(hr
== S_OK
, "got 0x%08x for drive spec %s (%s)\n",
2153 hr
, wine_dbgstr_w(drivespec
), wine_dbgstr_w(ptr
->drivespec
));
2154 ok(ret
== ptr
->expected_ret
, "got %d, expected %d for drive spec %s (%s)\n",
2155 ret
, ptr
->expected_ret
, wine_dbgstr_w(drivespec
), wine_dbgstr_w(ptr
->drivespec
));
2157 drivespec
[0] = tolower(root
[0]);
2160 ret
= ptr
->expected_ret
== VARIANT_TRUE
? VARIANT_FALSE
: VARIANT_TRUE
;
2161 hr
= IFileSystem3_DriveExists(fs3
, drivespec
, &ret
);
2162 ok(hr
== S_OK
, "got 0x%08x for drive spec %s (%s)\n",
2163 hr
, wine_dbgstr_w(drivespec
), wine_dbgstr_w(ptr
->drivespec
));
2164 ok(ret
== ptr
->expected_ret
, "got %d, expected %d for drive spec %s (%s)\n",
2165 ret
, ptr
->expected_ret
, wine_dbgstr_w(drivespec
), wine_dbgstr_w(ptr
->drivespec
));
2167 SysFreeString(drivespec
);
2171 struct getdrivename_test
{
2172 const WCHAR path
[10];
2173 const WCHAR drive
[5];
2176 static const struct getdrivename_test getdrivenametestdata
[] = {
2177 { L
"C:\\1.tst", L
"C:" },
2178 { L
"O:\\1.tst", L
"O:" },
2187 static void test_GetDriveName(void)
2189 const struct getdrivename_test
*ptr
= getdrivenametestdata
;
2193 hr
= IFileSystem3_GetDriveName(fs3
, NULL
, NULL
);
2194 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2196 name
= (void*)0xdeadbeef;
2197 hr
= IFileSystem3_GetDriveName(fs3
, NULL
, &name
);
2198 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2199 ok(name
== NULL
, "got %p\n", name
);
2201 while (*ptr
->path
) {
2202 BSTR path
= SysAllocString(ptr
->path
);
2203 name
= (void*)0xdeadbeef;
2204 hr
= IFileSystem3_GetDriveName(fs3
, path
, &name
);
2205 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2207 ok(!lstrcmpW(ptr
->drive
, name
), "got %s, expected %s\n", wine_dbgstr_w(name
), wine_dbgstr_w(ptr
->drive
));
2209 ok(!*ptr
->drive
, "got %s, expected %s\n", wine_dbgstr_w(name
), wine_dbgstr_w(ptr
->drive
));
2210 SysFreeString(path
);
2211 SysFreeString(name
);
2216 struct getdrive_test
{
2217 const WCHAR drivespec
[12];
2219 const WCHAR driveletter
[2];
2222 static void test_GetDrive(void)
2225 IDrive
*drive_fixed
, *drive
;
2226 BSTR dl_fixed
, drivespec
;
2227 WCHAR root
[] = L
"?:\\";
2229 drive
= (void*)0xdeadbeef;
2230 hr
= IFileSystem3_GetDrive(fs3
, NULL
, NULL
);
2231 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2232 ok(drive
== (void*)0xdeadbeef, "got %p\n", drive
);
2234 for (root
[0] = 'A'; root
[0] <= 'Z'; root
[0]++)
2235 if (GetDriveTypeW(root
) == DRIVE_NO_ROOT_DIR
)
2239 skip("All drive letters are occupied, skipping test for nonexisting drive.\n");
2241 drivespec
= SysAllocString(root
);
2242 drive
= (void*)0xdeadbeef;
2243 hr
= IFileSystem3_GetDrive(fs3
, drivespec
, &drive
);
2244 ok(hr
== CTL_E_DEVICEUNAVAILABLE
, "got 0x%08x\n", hr
);
2245 ok(drive
== NULL
, "got %p\n", drive
);
2246 SysFreeString(drivespec
);
2249 drive_fixed
= get_fixed_drive();
2251 skip("No fixed drive found, skipping test.\n");
2255 hr
= IDrive_get_DriveLetter(drive_fixed
, &dl_fixed
);
2256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2259 skip("Could not retrieve drive letter of fixed drive, skipping test.\n");
2261 WCHAR dl_upper
= toupper(dl_fixed
[0]);
2262 WCHAR dl_lower
= tolower(dl_fixed
[0]);
2263 struct getdrive_test testdata
[] = {
2264 { {dl_upper
,0}, S_OK
, {dl_upper
,0} },
2265 { {dl_upper
,':',0}, S_OK
, {dl_upper
,0} },
2266 { {dl_upper
,':','\\',0}, S_OK
, {dl_upper
,0} },
2267 { {dl_lower
,':','\\',0}, S_OK
, {dl_upper
,0} },
2268 { {dl_upper
,'\\',0 }, E_INVALIDARG
, L
""},
2269 { {dl_lower
,'\\',0 }, E_INVALIDARG
, L
""},
2270 { L
"$:\\", E_INVALIDARG
, L
"" },
2271 { L
"\\host\\share", E_INVALIDARG
, L
"" },
2272 { L
"host\\share", E_INVALIDARG
, L
"" },
2275 struct getdrive_test
*ptr
= &testdata
[0];
2277 for (; *ptr
->drivespec
; ptr
++) {
2278 drivespec
= SysAllocString(ptr
->drivespec
);
2279 drive
= (void*)0xdeadbeef;
2280 hr
= IFileSystem3_GetDrive(fs3
, drivespec
, &drive
);
2281 ok(hr
== ptr
->res
, "got 0x%08x, expected 0x%08x for drive spec %s\n",
2282 hr
, ptr
->res
, wine_dbgstr_w(ptr
->drivespec
));
2283 ok(!lstrcmpW(ptr
->drivespec
, drivespec
), "GetDrive modified its DriveSpec argument\n");
2284 SysFreeString(drivespec
);
2286 if (*ptr
->driveletter
) {
2288 hr
= IDrive_get_DriveLetter(drive
, &driveletter
);
2289 ok(hr
== S_OK
, "got 0x%08x for drive spec %s\n", hr
, wine_dbgstr_w(ptr
->drivespec
));
2290 if (SUCCEEDED(hr
)) {
2291 ok(!lstrcmpW(ptr
->driveletter
, driveletter
), "got %s, expected %s for drive spec %s\n",
2292 wine_dbgstr_w(driveletter
), wine_dbgstr_w(ptr
->driveletter
),
2293 wine_dbgstr_w(ptr
->drivespec
));
2294 SysFreeString(driveletter
);
2296 test_provideclassinfo(drive
, &CLSID_Drive
);
2297 IDrive_Release(drive
);
2299 ok(drive
== NULL
, "got %p for drive spec %s\n", drive
, wine_dbgstr_w(ptr
->drivespec
));
2301 SysFreeString(dl_fixed
);
2305 static void test_SerialNumber(void)
2312 drive
= get_fixed_drive();
2314 skip("No fixed drive found, skipping test.\n");
2318 hr
= IDrive_get_SerialNumber(drive
, NULL
);
2319 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2321 serial
= 0xdeadbeef;
2322 hr
= IDrive_get_SerialNumber(drive
, &serial
);
2323 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2324 ok(serial
!= 0xdeadbeef, "got %x\n", serial
);
2326 hr
= IDrive_get_FileSystem(drive
, NULL
);
2327 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2330 hr
= IDrive_get_FileSystem(drive
, &name
);
2331 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2332 ok(name
!= NULL
, "got %p\n", name
);
2333 SysFreeString(name
);
2335 hr
= IDrive_get_VolumeName(drive
, NULL
);
2336 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2339 hr
= IDrive_get_VolumeName(drive
, &name
);
2340 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2341 ok(name
!= NULL
, "got %p\n", name
);
2342 SysFreeString(name
);
2344 IDrive_Release(drive
);
2347 static const struct extension_test
{
2350 } extension_tests
[] = {
2352 { L
"n.o.ext", L
"ext" },
2353 { L
"n.o.eXt", L
"eXt" },
2357 static void test_GetExtensionName(void)
2363 for (i
= 0; i
< ARRAY_SIZE(extension_tests
); i
++) {
2365 path
= SysAllocString(extension_tests
[i
].path
);
2367 hr
= IFileSystem3_GetExtensionName(fs3
, path
, &ext
);
2368 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2369 if (*extension_tests
[i
].ext
)
2370 ok(!lstrcmpW(ext
, extension_tests
[i
].ext
), "%d: path %s, got %s, expected %s\n", i
,
2371 wine_dbgstr_w(path
), wine_dbgstr_w(ext
), wine_dbgstr_w(extension_tests
[i
].ext
));
2373 ok(ext
== NULL
, "%d: path %s, got %s, expected %s\n", i
,
2374 wine_dbgstr_w(path
), wine_dbgstr_w(ext
), wine_dbgstr_w(extension_tests
[i
].ext
));
2376 SysFreeString(path
);
2381 static void test_GetSpecialFolder(void)
2383 WCHAR pathW
[MAX_PATH
];
2389 hr
= IFileSystem3_GetSpecialFolder(fs3
, WindowsFolder
, NULL
);
2390 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2392 hr
= IFileSystem3_GetSpecialFolder(fs3
, TemporaryFolder
+1, NULL
);
2393 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
2395 hr
= IFileSystem3_GetSpecialFolder(fs3
, TemporaryFolder
+1, &folder
);
2396 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2398 hr
= IFileSystem3_GetSpecialFolder(fs3
, WindowsFolder
, &folder
);
2399 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2400 hr
= IFolder_get_Path(folder
, &path
);
2401 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2402 GetWindowsDirectoryW(pathW
, ARRAY_SIZE(pathW
));
2403 ok(!lstrcmpiW(pathW
, path
), "got %s, expected %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(pathW
));
2404 SysFreeString(path
);
2405 IFolder_Release(folder
);
2407 hr
= IFileSystem3_GetSpecialFolder(fs3
, SystemFolder
, &folder
);
2408 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2409 hr
= IFolder_get_Path(folder
, &path
);
2410 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2411 GetSystemDirectoryW(pathW
, ARRAY_SIZE(pathW
));
2412 ok(!lstrcmpiW(pathW
, path
), "got %s, expected %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(pathW
));
2413 SysFreeString(path
);
2414 IFolder_Release(folder
);
2416 hr
= IFileSystem3_GetSpecialFolder(fs3
, TemporaryFolder
, &folder
);
2417 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2418 hr
= IFolder_get_Path(folder
, &path
);
2419 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2420 ret
= GetTempPathW(ARRAY_SIZE(pathW
), pathW
);
2421 if (ret
&& pathW
[ret
-1] == '\\')
2424 ok(!lstrcmpiW(pathW
, path
), "got %s, expected %s\n", wine_dbgstr_w(path
), wine_dbgstr_w(pathW
));
2425 SysFreeString(path
);
2426 IFolder_Release(folder
);
2429 static void test_MoveFile(void)
2431 ITextStream
*stream
;
2435 str
= SysAllocString(L
"test.txt");
2436 hr
= IFileSystem3_CreateTextFile(fs3
, str
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
2437 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2440 str
= SysAllocString(L
"test");
2441 hr
= ITextStream_Write(stream
, str
);
2442 ok(hr
== S_OK
, "Write failed: %08x\n", hr
);
2445 ITextStream_Release(stream
);
2447 str
= SysAllocString(L
"test2.txt");
2448 hr
= IFileSystem3_CreateTextFile(fs3
, str
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
2449 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2451 ITextStream_Release(stream
);
2453 src
= SysAllocString(L
"test.txt");
2454 dst
= SysAllocString(L
"test3.txt");
2455 hr
= IFileSystem3_MoveFile(fs3
, src
, dst
);
2456 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2460 str
= SysAllocString(L
"test.txt");
2461 hr
= IFileSystem3_DeleteFile(fs3
, str
, VARIANT_TRUE
);
2462 ok(hr
== CTL_E_FILENOTFOUND
, "DeleteFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
2465 src
= SysAllocString(L
"test3.txt");
2466 dst
= SysAllocString(L
"test2.txt"); /* already exists */
2467 hr
= IFileSystem3_MoveFile(fs3
, src
, dst
);
2468 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
2472 src
= SysAllocString(L
"nonexistent.txt");
2473 dst
= SysAllocString(L
"test4.txt");
2474 hr
= IFileSystem3_MoveFile(fs3
, src
, dst
);
2475 ok(hr
== CTL_E_FILENOTFOUND
, "got 0x%08x, expected CTL_E_FILENOTFOUND\n", hr
);
2479 str
= SysAllocString(L
"test3.txt");
2480 hr
= IFileSystem3_DeleteFile(fs3
, str
, VARIANT_TRUE
);
2481 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2484 str
= SysAllocString(L
"test2.txt");
2485 hr
= IFileSystem3_DeleteFile(fs3
, str
, VARIANT_TRUE
);
2486 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2490 START_TEST(filesystem
)
2496 hr
= CoCreateInstance(&CLSID_FileSystemObject
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
2497 &IID_IFileSystem3
, (void**)&fs3
);
2499 win_skip("Could not create FileSystem object: %08x\n", hr
);
2504 test_createfolder();
2506 test_GetFileVersion();
2507 test_GetParentFolderName();
2510 test_GetAbsolutePathName();
2515 test_FolderCollection();
2516 test_FileCollection();
2517 test_DriveCollection();
2518 test_CreateTextFile();
2524 test_GetDriveName();
2526 test_SerialNumber();
2527 test_GetExtensionName();
2528 test_GetSpecialFolder();
2531 IFileSystem3_Release(fs3
);