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
30 #include "wine/test.h"
35 static IFileSystem3
*fs3
;
37 static inline ULONG
get_refcount(IUnknown
*iface
)
39 IUnknown_AddRef(iface
);
40 return IUnknown_Release(iface
);
43 static const WCHAR crlfW
[] = {'\r','\n',0};
44 static const char utf16bom
[] = {0xff,0xfe,0};
46 #define GET_REFCOUNT(iface) \
47 get_refcount((IUnknown*)iface)
49 static inline void get_temp_path(const WCHAR
*prefix
, WCHAR
*path
)
51 WCHAR buffW
[MAX_PATH
];
53 GetTempPathW(MAX_PATH
, buffW
);
54 GetTempFileNameW(buffW
, prefix
, 0, path
);
58 static void test_interfaces(void)
60 static const WCHAR nonexistent_dirW
[] = {
61 'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', 0};
62 static const WCHAR pathW
[] = {'p','a','t','h',0};
63 static const WCHAR file_kernel32W
[] = {
64 '\\', 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0};
68 IObjectWithSite
*site
;
71 WCHAR windows_path
[MAX_PATH
];
72 WCHAR file_path
[MAX_PATH
];
74 IFileSystem3_QueryInterface(fs3
, &IID_IDispatch
, (void**)&disp
);
76 GetSystemDirectoryW(windows_path
, MAX_PATH
);
77 lstrcpyW(file_path
, windows_path
);
78 lstrcatW(file_path
, file_kernel32W
);
80 hr
= IDispatch_QueryInterface(disp
, &IID_IObjectWithSite
, (void**)&site
);
81 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
83 hr
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
84 ok(hr
== E_NOINTERFACE
, "got 0x%08x, expected 0x%08x\n", hr
, E_NOINTERFACE
);
87 hr
= IFileSystem3_FileExists(fs3
, NULL
, &b
);
88 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
89 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
91 hr
= IFileSystem3_FileExists(fs3
, NULL
, NULL
);
92 ok(hr
== E_POINTER
, "got 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
94 path
= SysAllocString(pathW
);
96 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
97 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
98 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
101 path
= SysAllocString(file_path
);
103 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
104 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
105 ok(b
== VARIANT_TRUE
, "got %x\n", b
);
108 path
= SysAllocString(windows_path
);
110 hr
= IFileSystem3_FileExists(fs3
, path
, &b
);
111 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
112 ok(b
== VARIANT_FALSE
, "got %x\n", b
);
116 hr
= IFileSystem3_FolderExists(fs3
, NULL
, NULL
);
117 ok(hr
== E_POINTER
, "got 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
119 path
= SysAllocString(windows_path
);
120 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
121 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
122 ok(b
== VARIANT_TRUE
, "Folder doesn't exists\n");
125 path
= SysAllocString(nonexistent_dirW
);
126 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
127 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
128 ok(b
== VARIANT_FALSE
, "Folder exists\n");
131 path
= SysAllocString(file_path
);
132 hr
= IFileSystem3_FolderExists(fs3
, path
, &b
);
133 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
134 ok(b
== VARIANT_FALSE
, "Folder exists\n");
137 IDispatch_Release(disp
);
140 static void test_createfolder(void)
142 WCHAR buffW
[MAX_PATH
];
148 get_temp_path(NULL
, buffW
);
149 ret
= CreateDirectoryW(buffW
, NULL
);
150 ok(ret
, "got %d, %d\n", ret
, GetLastError());
152 /* create existing directory */
153 path
= SysAllocString(buffW
);
154 folder
= (void*)0xdeabeef;
155 hr
= IFileSystem3_CreateFolder(fs3
, path
, &folder
);
156 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x\n", hr
);
157 ok(folder
== NULL
, "got %p\n", folder
);
159 RemoveDirectoryW(buffW
);
162 static void test_textstream(void)
164 static const WCHAR testfileW
[] = {'t','e','s','t','f','i','l','e','.','t','x','t',0};
173 file
= CreateFileW(testfileW
, GENERIC_READ
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
176 name
= SysAllocString(testfileW
);
178 hr
= IFileSystem3_FileExists(fs3
, name
, &b
);
179 ok(hr
== S_OK
, "got 0x%08x, expected 0x%08x\n", hr
, S_OK
);
180 ok(b
== VARIANT_TRUE
, "got %x\n", b
);
182 /* different mode combinations */
183 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
| ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
184 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
186 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
| ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
187 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
189 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
| ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
190 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
192 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
193 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
194 hr
= ITextStream_Read(stream
, 1, &data
);
195 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
196 ITextStream_Release(stream
);
198 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
, VARIANT_FALSE
, TristateFalse
, &stream
);
199 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
200 hr
= ITextStream_Read(stream
, 1, &data
);
201 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
202 ITextStream_Release(stream
);
204 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
205 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
207 /* try to write when open for reading */
208 hr
= ITextStream_WriteLine(stream
, name
);
209 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
211 hr
= ITextStream_Write(stream
, name
);
212 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
214 hr
= ITextStream_get_AtEndOfStream(stream
, NULL
);
215 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
218 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
219 ok(hr
== S_OK
|| broken(hr
== S_FALSE
), "got 0x%08x\n", hr
);
220 ok(b
== VARIANT_TRUE
, "got 0x%x\n", b
);
222 ITextStream_Release(stream
);
224 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForWriting
, VARIANT_FALSE
, TristateFalse
, &stream
);
225 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
228 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
229 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
230 ok(b
== VARIANT_TRUE
|| broken(b
== 10), "got 0x%x\n", b
);
233 hr
= ITextStream_get_AtEndOfLine(stream
, &b
);
235 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
236 ok(b
== VARIANT_FALSE
|| broken(b
== 10), "got 0x%x\n", b
);
238 hr
= ITextStream_Read(stream
, 1, &data
);
239 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
241 hr
= ITextStream_ReadLine(stream
, &data
);
242 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
244 hr
= ITextStream_ReadAll(stream
, &data
);
245 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
247 ITextStream_Release(stream
);
249 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForAppending
, VARIANT_FALSE
, TristateFalse
, &stream
);
250 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
253 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
254 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
255 ok(b
== VARIANT_TRUE
|| broken(b
== 10), "got 0x%x\n", b
);
258 hr
= ITextStream_get_AtEndOfLine(stream
, &b
);
260 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
261 ok(b
== VARIANT_FALSE
|| broken(b
== 10), "got 0x%x\n", b
);
263 hr
= ITextStream_Read(stream
, 1, &data
);
264 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
266 hr
= ITextStream_ReadLine(stream
, &data
);
267 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
269 hr
= ITextStream_ReadAll(stream
, &data
);
270 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
272 ITextStream_Release(stream
);
274 /* now with non-empty file */
275 file
= CreateFileW(testfileW
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
276 ret
= WriteFile(file
, testfileW
, sizeof(testfileW
), &written
, NULL
);
277 ok(ret
&& written
== sizeof(testfileW
), "got %d\n", ret
);
280 hr
= IFileSystem3_OpenTextFile(fs3
, name
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
281 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
283 hr
= ITextStream_get_AtEndOfStream(stream
, &b
);
284 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
285 ok(b
== VARIANT_FALSE
, "got 0x%x\n", b
);
286 ITextStream_Release(stream
);
289 DeleteFileW(testfileW
);
292 static void test_GetFileVersion(void)
294 static const WCHAR k32W
[] = {'\\','k','e','r','n','e','l','3','2','.','d','l','l',0};
295 static const WCHAR k33W
[] = {'\\','k','e','r','n','e','l','3','3','.','d','l','l',0};
296 WCHAR pathW
[MAX_PATH
], filenameW
[MAX_PATH
];
300 GetSystemDirectoryW(pathW
, sizeof(pathW
)/sizeof(WCHAR
));
302 lstrcpyW(filenameW
, pathW
);
303 lstrcatW(filenameW
, k32W
);
305 path
= SysAllocString(filenameW
);
306 hr
= IFileSystem3_GetFileVersion(fs3
, path
, &version
);
307 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
308 ok(*version
!= 0, "got %s\n", wine_dbgstr_w(version
));
309 SysFreeString(version
);
312 lstrcpyW(filenameW
, pathW
);
313 lstrcatW(filenameW
, k33W
);
315 path
= SysAllocString(filenameW
);
316 version
= (void*)0xdeadbeef;
317 hr
= IFileSystem3_GetFileVersion(fs3
, path
, &version
);
318 ok(broken(hr
== S_OK
) || hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "got 0x%08x\n", hr
);
321 ok(*version
== 0, "got %s\n", wine_dbgstr_w(version
));
322 SysFreeString(version
);
325 ok(version
== (void*)0xdeadbeef, "got %p\n", version
);
329 static void test_GetParentFolderName(void)
331 static const WCHAR path1
[] = {'a',0};
332 static const WCHAR path2
[] = {'a','/','a','/','a',0};
333 static const WCHAR path3
[] = {'a','\\','a','\\','a',0};
334 static const WCHAR path4
[] = {'a','/','a','/','/','\\','\\',0};
335 static const WCHAR path5
[] = {'c',':','\\','\\','a',0};
336 static const WCHAR path6
[] = {'a','c',':','\\','a',0};
337 static const WCHAR result2
[] = {'a','/','a',0};
338 static const WCHAR result3
[] = {'a','\\','a',0};
339 static const WCHAR result4
[] = {'a',0};
340 static const WCHAR result5
[] = {'c',':','\\',0};
341 static const WCHAR result6
[] = {'a','c',':',0};
343 static const struct {
360 hr
= IFileSystem3_GetParentFolderName(fs3
, NULL
, NULL
);
361 ok(hr
== E_POINTER
, "GetParentFolderName returned %x, expected E_POINTER\n", hr
);
363 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
364 result
= (BSTR
)0xdeadbeef;
365 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
366 hr
= IFileSystem3_GetParentFolderName(fs3
, path
, &result
);
367 ok(hr
== S_OK
, "%d) GetParentFolderName returned %x, expected S_OK\n", i
, hr
);
369 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
371 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
373 SysFreeString(result
);
377 static void test_GetFileName(void)
379 static const WCHAR path1
[] = {'a',0};
380 static const WCHAR path2
[] = {'a','/','a','.','b',0};
381 static const WCHAR path3
[] = {'a','\\',0};
382 static const WCHAR path4
[] = {'c',':',0};
383 static const WCHAR path5
[] = {'/','\\',0};
384 static const WCHAR result2
[] = {'a','.','b',0};
385 static const WCHAR result3
[] = {'a',0};
387 static const struct {
403 hr
= IFileSystem3_GetFileName(fs3
, NULL
, NULL
);
404 ok(hr
== E_POINTER
, "GetFileName returned %x, expected E_POINTER\n", hr
);
406 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
407 result
= (BSTR
)0xdeadbeef;
408 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
409 hr
= IFileSystem3_GetFileName(fs3
, path
, &result
);
410 ok(hr
== S_OK
, "%d) GetFileName returned %x, expected S_OK\n", i
, hr
);
412 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
414 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
416 SysFreeString(result
);
420 static void test_GetBaseName(void)
422 static const WCHAR path1
[] = {'a',0};
423 static const WCHAR path2
[] = {'a','/','a','.','b','.','c',0};
424 static const WCHAR path3
[] = {'a','.','b','\\',0};
425 static const WCHAR path4
[] = {'c',':',0};
426 static const WCHAR path5
[] = {'/','\\',0};
427 static const WCHAR path6
[] = {'.','a',0};
428 static const WCHAR result1
[] = {'a',0};
429 static const WCHAR result2
[] = {'a','.','b',0};
430 static const WCHAR result6
[] = {0};
432 static const struct {
449 hr
= IFileSystem3_GetBaseName(fs3
, NULL
, NULL
);
450 ok(hr
== E_POINTER
, "GetBaseName returned %x, expected E_POINTER\n", hr
);
452 for(i
=0; i
<sizeof(tests
)/sizeof(tests
[0]); i
++) {
453 result
= (BSTR
)0xdeadbeef;
454 path
= tests
[i
].path
? SysAllocString(tests
[i
].path
) : NULL
;
455 hr
= IFileSystem3_GetBaseName(fs3
, path
, &result
);
456 ok(hr
== S_OK
, "%d) GetBaseName returned %x, expected S_OK\n", i
, hr
);
458 ok(!result
, "%d) result = %s\n", i
, wine_dbgstr_w(result
));
460 ok(!lstrcmpW(result
, tests
[i
].result
), "%d) result = %s\n", i
, wine_dbgstr_w(result
));
462 SysFreeString(result
);
466 static void test_GetAbsolutePathName(void)
468 static const WCHAR dir1
[] = {'t','e','s','t','_','d','i','r','1',0};
469 static const WCHAR dir2
[] = {'t','e','s','t','_','d','i','r','2',0};
470 static const WCHAR dir_match1
[] = {'t','e','s','t','_','d','i','r','*',0};
471 static const WCHAR dir_match2
[] = {'t','e','s','t','_','d','i','*',0};
472 static const WCHAR cur_dir
[] = {'.',0};
474 WIN32_FIND_DATAW fdata
;
476 WCHAR buf
[MAX_PATH
], buf2
[MAX_PATH
];
480 hr
= IFileSystem3_GetAbsolutePathName(fs3
, NULL
, NULL
);
481 ok(hr
== E_POINTER
, "GetAbsolutePathName returned %x, expected E_POINTER\n", hr
);
483 hr
= IFileSystem3_GetAbsolutePathName(fs3
, NULL
, &result
);
484 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
485 GetFullPathNameW(cur_dir
, MAX_PATH
, buf
, NULL
);
486 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
487 SysFreeString(result
);
489 find
= FindFirstFileW(dir_match2
, &fdata
);
490 if(find
!= INVALID_HANDLE_VALUE
) {
491 skip("GetAbsolutePathName tests\n");
496 path
= SysAllocString(dir_match1
);
497 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
498 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
499 GetFullPathNameW(dir_match1
, MAX_PATH
, buf2
, NULL
);
500 ok(!lstrcmpiW(buf2
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf2
));
501 SysFreeString(result
);
503 ok(CreateDirectoryW(dir1
, NULL
), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir1
));
504 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
505 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
506 GetFullPathNameW(dir1
, MAX_PATH
, buf
, NULL
);
507 ok(!lstrcmpiW(buf
, result
) || broken(!lstrcmpiW(buf2
, result
)), "result = %s, expected %s\n",
508 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
509 SysFreeString(result
);
511 ok(CreateDirectoryW(dir2
, NULL
), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir2
));
512 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
513 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
514 if(!lstrcmpiW(buf
, result
) || !lstrcmpiW(buf2
, result
)) {
515 ok(!lstrcmpiW(buf
, result
) || broken(!lstrcmpiW(buf2
, result
)), "result = %s, expected %s\n",
516 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
518 GetFullPathNameW(dir2
, MAX_PATH
, buf
, NULL
);
519 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n",
520 wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
522 SysFreeString(result
);
525 path
= SysAllocString(dir_match2
);
526 hr
= IFileSystem3_GetAbsolutePathName(fs3
, path
, &result
);
527 ok(hr
== S_OK
, "GetAbsolutePathName returned %x, expected S_OK\n", hr
);
528 GetFullPathNameW(dir_match2
, MAX_PATH
, buf
, NULL
);
529 ok(!lstrcmpiW(buf
, result
), "result = %s, expected %s\n", wine_dbgstr_w(result
), wine_dbgstr_w(buf
));
530 SysFreeString(result
);
533 RemoveDirectoryW(dir1
);
534 RemoveDirectoryW(dir2
);
537 static void test_GetFile(void)
539 static const WCHAR slW
[] = {'\\',0};
541 WCHAR pathW
[MAX_PATH
];
550 get_temp_path(NULL
, pathW
);
552 path
= SysAllocString(pathW
);
553 hr
= IFileSystem3_GetFile(fs3
, path
, NULL
);
554 ok(hr
== E_POINTER
, "GetFile returned %x, expected E_POINTER\n", hr
);
555 hr
= IFileSystem3_GetFile(fs3
, NULL
, &file
);
556 ok(hr
== E_INVALIDARG
, "GetFile returned %x, expected E_INVALIDARG\n", hr
);
558 file
= (IFile
*)0xdeadbeef;
559 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
560 ok(!file
, "file != NULL\n");
561 ok(hr
== CTL_E_FILENOTFOUND
, "GetFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
563 hf
= CreateFileW(pathW
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_ATTRIBUTE_READONLY
, NULL
);
564 if(hf
== INVALID_HANDLE_VALUE
) {
565 skip("Can't create temporary file\n");
571 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
572 ok(hr
== S_OK
, "GetFile returned %x, expected S_OK\n", hr
);
574 hr
= IFile_get_Attributes(file
, &fa
);
575 gfa
= GetFileAttributesW(pathW
) & (FILE_ATTRIBUTE_READONLY
| FILE_ATTRIBUTE_HIDDEN
|
576 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_ARCHIVE
|
577 FILE_ATTRIBUTE_REPARSE_POINT
| FILE_ATTRIBUTE_COMPRESSED
);
578 ok(hr
== S_OK
, "get_Attributes returned %x, expected S_OK\n", hr
);
579 ok(fa
== gfa
, "fa = %x, expected %x\n", fa
, gfa
);
581 hr
= IFile_get_Size(file
, &size
);
582 ok(hr
== S_OK
, "get_Size returned %x, expected S_OK\n", hr
);
583 ok(V_VT(&size
) == VT_I4
, "V_VT(&size) = %d, expected VT_I4\n", V_VT(&size
));
584 ok(V_I4(&size
) == 0, "V_I4(&size) = %d, expected 0\n", V_I4(&size
));
587 hr
= IFileSystem3_DeleteFile(fs3
, path
, FALSE
);
588 ok(hr
==CTL_E_PERMISSIONDENIED
|| broken(hr
==S_OK
),
589 "DeleteFile returned %x, expected CTL_E_PERMISSIONDENIED\n", hr
);
591 hr
= IFileSystem3_DeleteFile(fs3
, path
, TRUE
);
592 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
594 hr
= IFileSystem3_DeleteFile(fs3
, path
, TRUE
);
595 ok(hr
== CTL_E_FILENOTFOUND
, "DeleteFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
599 /* try with directory */
600 lstrcatW(pathW
, slW
);
601 ret
= CreateDirectoryW(pathW
, NULL
);
602 ok(ret
, "got %d, error %d\n", ret
, GetLastError());
604 path
= SysAllocString(pathW
);
605 hr
= IFileSystem3_GetFile(fs3
, path
, &file
);
606 ok(hr
== CTL_E_FILENOTFOUND
, "GetFile returned %x, expected S_OK\n", hr
);
609 RemoveDirectoryW(pathW
);
612 static inline BOOL
create_file(const WCHAR
*name
)
614 HANDLE f
= CreateFileW(name
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, 0, NULL
);
616 return f
!= INVALID_HANDLE_VALUE
;
619 static inline void create_path(const WCHAR
*folder
, const WCHAR
*name
, WCHAR
*ret
)
621 DWORD len
= lstrlenW(folder
);
622 memmove(ret
, folder
, len
*sizeof(WCHAR
));
624 memmove(ret
+len
+1, name
, (lstrlenW(name
)+1)*sizeof(WCHAR
));
627 static void test_CopyFolder(void)
629 static const WCHAR filesystem3_dir
[] = {'f','i','l','e','s','y','s','t','e','m','3','_','t','e','s','t',0};
630 static const WCHAR s1
[] = {'s','r','c','1',0};
631 static const WCHAR s
[] = {'s','r','c','*',0};
632 static const WCHAR d
[] = {'d','s','t',0};
633 static const WCHAR empty
[] = {0};
639 if(!CreateDirectoryW(filesystem3_dir
, NULL
)) {
640 skip("can't create temporary directory\n");
644 create_path(filesystem3_dir
, s1
, tmp
);
645 bsrc
= SysAllocString(tmp
);
646 create_path(filesystem3_dir
, d
, tmp
);
647 bdst
= SysAllocString(tmp
);
648 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
649 ok(hr
== CTL_E_FILENOTFOUND
, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
651 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
652 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
654 ok(create_file(bsrc
), "can't create %s file\n", wine_dbgstr_w(bsrc
));
655 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
656 ok(hr
== S_OK
, "CopyFile returned %x, expected S_OK\n", hr
);
658 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
659 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
661 hr
= IFileSystem3_DeleteFile(fs3
, bsrc
, VARIANT_FALSE
);
662 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
664 ok(CreateDirectoryW(bsrc
, NULL
), "can't create %s\n", wine_dbgstr_w(bsrc
));
665 hr
= IFileSystem3_CopyFile(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
666 ok(hr
== CTL_E_FILENOTFOUND
, "CopyFile returned %x, expected CTL_E_FILENOTFOUND\n", hr
);
668 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
669 ok(hr
== CTL_E_FILEALREADYEXISTS
, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
671 hr
= IFileSystem3_DeleteFile(fs3
, bdst
, VARIANT_TRUE
);
672 ok(hr
== S_OK
, "DeleteFile returned %x, expected S_OK\n", hr
);
674 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
675 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
677 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
678 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
679 create_path(tmp
, s1
, tmp
);
680 ok(GetFileAttributesW(tmp
) == INVALID_FILE_ATTRIBUTES
,
681 "%s file exists\n", wine_dbgstr_w(tmp
));
683 create_path(filesystem3_dir
, d
, tmp
);
684 create_path(tmp
, empty
, tmp
);
686 bdst
= SysAllocString(tmp
);
687 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
688 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
689 create_path(tmp
, s1
, tmp
);
690 ok(GetFileAttributesW(tmp
) != INVALID_FILE_ATTRIBUTES
,
691 "%s directory doesn't exist\n", wine_dbgstr_w(tmp
));
692 ok(RemoveDirectoryW(tmp
), "can't remove %s directory\n", wine_dbgstr_w(tmp
));
693 create_path(filesystem3_dir
, d
, tmp
);
695 bdst
= SysAllocString(tmp
);
698 create_path(filesystem3_dir
, s
, tmp
);
700 bsrc
= SysAllocString(tmp
);
701 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
702 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
703 create_path(filesystem3_dir
, d
, tmp
);
704 create_path(tmp
, s1
, tmp
);
705 ok(GetFileAttributesW(tmp
) != INVALID_FILE_ATTRIBUTES
,
706 "%s directory doesn't exist\n", wine_dbgstr_w(tmp
));
708 hr
= IFileSystem3_DeleteFolder(fs3
, bdst
, VARIANT_FALSE
);
709 ok(hr
== S_OK
, "DeleteFolder returned %x, expected S_OK\n", hr
);
711 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
712 ok(hr
== CTL_E_PATHNOTFOUND
, "CopyFolder returned %x, expected CTL_E_PATHNOTFOUND\n", hr
);
714 create_path(filesystem3_dir
, s1
, tmp
);
716 bsrc
= SysAllocString(tmp
);
717 create_path(tmp
, s1
, tmp
);
718 ok(create_file(tmp
), "can't create %s file\n", wine_dbgstr_w(tmp
));
719 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_FALSE
);
720 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
722 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_FALSE
);
723 ok(hr
== CTL_E_FILEALREADYEXISTS
, "CopyFolder returned %x, expected CTL_E_FILEALREADYEXISTS\n", hr
);
725 hr
= IFileSystem3_CopyFolder(fs3
, bsrc
, bdst
, VARIANT_TRUE
);
726 ok(hr
== S_OK
, "CopyFolder returned %x, expected S_OK\n", hr
);
730 bsrc
= SysAllocString(filesystem3_dir
);
731 hr
= IFileSystem3_DeleteFolder(fs3
, bsrc
, VARIANT_FALSE
);
732 ok(hr
== S_OK
, "DeleteFolder returned %x, expected S_OK\n", hr
);
736 static BSTR
bstr_from_str(const char *str
)
738 int len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
739 BSTR ret
= SysAllocStringLen(NULL
, len
- 1); /* NUL character added automatically */
740 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
744 struct buildpath_test
751 static struct buildpath_test buildpath_data
[] =
753 { "C:\\path", "..\\name.tmp", "C:\\path\\..\\name.tmp" },
754 { "C:\\path", "\\name.tmp", "C:\\path\\name.tmp" },
755 { "C:\\path", "name.tmp", "C:\\path\\name.tmp" },
756 { "C:\\path\\", "name.tmp", "C:\\path\\name.tmp" },
757 { "C:\\path", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
758 { "C:\\path\\", "\\name.tmp", "C:\\path\\name.tmp" },
759 { "C:\\path\\", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
760 { "C:\\path\\\\", "\\\\name.tmp", "C:\\path\\\\\\name.tmp" },
761 { "C:\\\\", "\\name.tmp", "C:\\\\name.tmp" },
762 { "C:", "name.tmp", "C:name.tmp" },
763 { "C:", "\\\\name.tmp", "C:\\\\name.tmp" },
767 static void test_BuildPath(void)
769 struct buildpath_test
*ptr
= buildpath_data
;
774 hr
= IFileSystem3_BuildPath(fs3
, NULL
, NULL
, NULL
);
775 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
777 ret
= (BSTR
)0xdeadbeef;
778 hr
= IFileSystem3_BuildPath(fs3
, NULL
, NULL
, &ret
);
779 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
780 ok(*ret
== 0, "got %p\n", ret
);
783 ret
= (BSTR
)0xdeadbeef;
784 path
= bstr_from_str("path");
785 hr
= IFileSystem3_BuildPath(fs3
, path
, NULL
, &ret
);
786 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
787 ok(!lstrcmpW(ret
, path
), "got %s\n", wine_dbgstr_w(ret
));
791 ret
= (BSTR
)0xdeadbeef;
792 path
= bstr_from_str("path");
793 hr
= IFileSystem3_BuildPath(fs3
, NULL
, path
, &ret
);
794 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
795 ok(!lstrcmpW(ret
, path
), "got %s\n", wine_dbgstr_w(ret
));
804 path
= bstr_from_str(ptr
->path
);
805 name
= bstr_from_str(ptr
->name
);
806 result
= bstr_from_str(ptr
->result
);
807 hr
= IFileSystem3_BuildPath(fs3
, path
, name
, &ret
);
808 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
811 ok(!lstrcmpW(ret
, result
), "%d: got wrong path %s, expected %s\n", i
, wine_dbgstr_w(ret
),
812 wine_dbgstr_w(result
));
817 SysFreeString(result
);
824 static void test_GetFolder(void)
826 static const WCHAR dummyW
[] = {'d','u','m','m','y',0};
827 WCHAR buffW
[MAX_PATH
];
832 folder
= (void*)0xdeadbeef;
833 hr
= IFileSystem3_GetFolder(fs3
, NULL
, &folder
);
834 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
835 ok(folder
== NULL
, "got %p\n", folder
);
837 hr
= IFileSystem3_GetFolder(fs3
, NULL
, NULL
);
838 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
840 /* something that doesn't exist */
841 str
= SysAllocString(dummyW
);
843 hr
= IFileSystem3_GetFolder(fs3
, str
, NULL
);
844 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
846 folder
= (void*)0xdeadbeef;
847 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
848 ok(hr
== CTL_E_PATHNOTFOUND
, "got 0x%08x\n", hr
);
849 ok(folder
== NULL
, "got %p\n", folder
);
852 GetWindowsDirectoryW(buffW
, MAX_PATH
);
853 str
= SysAllocString(buffW
);
854 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
855 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
857 IFolder_Release(folder
);
860 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
861 static void test_FolderCollection(void)
863 static const WCHAR fooW
[] = {'f','o','o',0};
864 static const WCHAR aW
[] = {'\\','a',0};
865 static const WCHAR bW
[] = {'\\','b',0};
866 static const WCHAR cW
[] = {'\\','c',0};
867 IFolderCollection
*folders
;
868 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
869 IEnumVARIANT
*enumvar
, *clone
;
870 LONG count
, ref
, ref2
, i
;
871 IUnknown
*unk
, *unk2
;
874 VARIANT var
, var2
[2];
877 int found_a
= 0, found_b
= 0, found_c
= 0;
879 get_temp_path(fooW
, buffW
);
880 CreateDirectoryW(buffW
, NULL
);
882 str
= SysAllocString(buffW
);
883 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
884 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
887 hr
= IFolder_get_SubFolders(folder
, NULL
);
888 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
890 hr
= IFolder_get_Path(folder
, NULL
);
891 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
893 hr
= IFolder_get_Path(folder
, &str
);
894 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
895 ok(!lstrcmpW(buffW
, str
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
898 lstrcpyW(pathW
, buffW
);
900 CreateDirectoryW(pathW
, NULL
);
902 lstrcpyW(pathW
, buffW
);
904 CreateDirectoryW(pathW
, NULL
);
906 hr
= IFolder_get_SubFolders(folder
, &folders
);
907 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
908 IFolder_Release(folder
);
911 hr
= IFolderCollection_get_Count(folders
, &count
);
912 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
913 ok(count
== 2, "got %d\n", count
);
915 lstrcpyW(pathW
, buffW
);
917 CreateDirectoryW(pathW
, NULL
);
919 /* every time property is requested it scans directory */
921 hr
= IFolderCollection_get_Count(folders
, &count
);
922 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
923 ok(count
== 3, "got %d\n", count
);
925 hr
= IFolderCollection_get__NewEnum(folders
, NULL
);
926 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
928 hr
= IFolderCollection_QueryInterface(folders
, &IID_IEnumVARIANT
, (void**)&unk
);
929 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
931 /* NewEnum creates new instance each time it's called */
932 ref
= GET_REFCOUNT(folders
);
935 hr
= IFolderCollection_get__NewEnum(folders
, &unk
);
936 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
938 ref2
= GET_REFCOUNT(folders
);
939 ok(ref2
== ref
+ 1, "got %d, %d\n", ref2
, ref
);
942 hr
= IFolderCollection_get__NewEnum(folders
, &unk2
);
943 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
944 ok(unk
!= unk2
, "got %p, %p\n", unk2
, unk
);
945 IUnknown_Release(unk2
);
947 /* now get IEnumVARIANT */
948 ref
= GET_REFCOUNT(folders
);
949 hr
= IUnknown_QueryInterface(unk
, &IID_IEnumVARIANT
, (void**)&enumvar
);
950 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
951 ref2
= GET_REFCOUNT(folders
);
952 ok(ref2
== ref
, "got %d, %d\n", ref2
, ref
);
954 /* clone enumerator */
955 hr
= IEnumVARIANT_Clone(enumvar
, &clone
);
956 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
957 ok(clone
!= enumvar
, "got %p, %p\n", enumvar
, clone
);
958 IEnumVARIANT_Release(clone
);
960 hr
= IEnumVARIANT_Reset(enumvar
);
961 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
963 for (i
= 0; i
< 3; i
++)
967 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
968 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
969 ok(fetched
== 1, "%d: got %d\n", i
, fetched
);
970 ok(V_VT(&var
) == VT_DISPATCH
, "%d: got type %d\n", i
, V_VT(&var
));
972 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IFolder
, (void**)&folder
);
973 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
976 hr
= IFolder_get_Name(folder
, &str
);
977 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
978 if (!lstrcmpW(str
, aW
+ 1))
980 else if (!lstrcmpW(str
, bW
+ 1))
982 else if (!lstrcmpW(str
, cW
+ 1))
985 ok(0, "unexpected folder %s was found\n", wine_dbgstr_w(str
));
988 IFolder_Release(folder
);
992 ok(found_a
== 1 && found_b
== 1 && found_c
== 1,
993 "each folder should be found 1 time instead of %d/%d/%d\n",
994 found_a
, found_b
, found_c
);
998 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
999 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1000 ok(fetched
== 0, "got %d\n", fetched
);
1002 hr
= IEnumVARIANT_Reset(enumvar
);
1003 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1004 hr
= IEnumVARIANT_Skip(enumvar
, 2);
1005 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1006 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1007 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1009 VariantInit(&var2
[0]);
1010 VariantInit(&var2
[1]);
1012 hr
= IEnumVARIANT_Next(enumvar
, 0, var2
, &fetched
);
1013 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1014 ok(fetched
== 0, "got %d\n", fetched
);
1016 hr
= IEnumVARIANT_Next(enumvar
, 2, var2
, &fetched
);
1017 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1018 ok(fetched
== 1, "got %d\n", fetched
);
1019 ok(V_VT(&var2
[0]) == VT_DISPATCH
, "got type %d\n", V_VT(&var2
[0]));
1020 VariantClear(&var2
[0]);
1021 VariantClear(&var2
[1]);
1023 IEnumVARIANT_Release(enumvar
);
1024 IUnknown_Release(unk
);
1026 lstrcpyW(pathW
, buffW
);
1027 lstrcatW(pathW
, aW
);
1028 RemoveDirectoryW(pathW
);
1029 lstrcpyW(pathW
, buffW
);
1030 lstrcatW(pathW
, bW
);
1031 RemoveDirectoryW(pathW
);
1032 lstrcpyW(pathW
, buffW
);
1033 lstrcatW(pathW
, cW
);
1034 RemoveDirectoryW(pathW
);
1035 RemoveDirectoryW(buffW
);
1037 IFolderCollection_Release(folders
);
1040 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1041 static void test_FileCollection(void)
1043 static const WCHAR fooW
[] = {'\\','f','o','o',0};
1044 static const WCHAR aW
[] = {'\\','a',0};
1045 static const WCHAR bW
[] = {'\\','b',0};
1046 static const WCHAR cW
[] = {'\\','c',0};
1047 WCHAR buffW
[MAX_PATH
], pathW
[MAX_PATH
];
1049 IFileCollection
*files
;
1051 IEnumVARIANT
*enumvar
, *clone
;
1052 LONG count
, ref
, ref2
, i
;
1053 IUnknown
*unk
, *unk2
;
1055 VARIANT var
, var2
[2];
1058 HANDLE file_a
, file_b
, file_c
;
1059 int found_a
= 0, found_b
= 0, found_c
= 0;
1061 get_temp_path(fooW
, buffW
);
1062 CreateDirectoryW(buffW
, NULL
);
1064 str
= SysAllocString(buffW
);
1065 hr
= IFileSystem3_GetFolder(fs3
, str
, &folder
);
1066 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1069 hr
= IFolder_get_Files(folder
, NULL
);
1070 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1072 lstrcpyW(pathW
, buffW
);
1073 lstrcatW(pathW
, aW
);
1074 file_a
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1075 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1076 lstrcpyW(pathW
, buffW
);
1077 lstrcatW(pathW
, bW
);
1078 file_b
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1079 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1081 hr
= IFolder_get_Files(folder
, &files
);
1082 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1083 IFolder_Release(folder
);
1086 hr
= IFileCollection_get_Count(files
, &count
);
1087 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1088 ok(count
== 2, "got %d\n", count
);
1090 lstrcpyW(pathW
, buffW
);
1091 lstrcatW(pathW
, cW
);
1092 file_c
= CreateFileW(pathW
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
1093 FILE_FLAG_DELETE_ON_CLOSE
, 0);
1095 /* every time property is requested it scans directory */
1097 hr
= IFileCollection_get_Count(files
, &count
);
1098 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1099 ok(count
== 3, "got %d\n", count
);
1101 hr
= IFileCollection_get__NewEnum(files
, NULL
);
1102 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1104 hr
= IFileCollection_QueryInterface(files
, &IID_IEnumVARIANT
, (void**)&unk
);
1105 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1107 /* NewEnum creates new instance each time it's called */
1108 ref
= GET_REFCOUNT(files
);
1111 hr
= IFileCollection_get__NewEnum(files
, &unk
);
1112 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1114 ref2
= GET_REFCOUNT(files
);
1115 ok(ref2
== ref
+ 1, "got %d, %d\n", ref2
, ref
);
1118 hr
= IFileCollection_get__NewEnum(files
, &unk2
);
1119 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1120 ok(unk
!= unk2
, "got %p, %p\n", unk2
, unk
);
1121 IUnknown_Release(unk2
);
1123 /* now get IEnumVARIANT */
1124 ref
= GET_REFCOUNT(files
);
1125 hr
= IUnknown_QueryInterface(unk
, &IID_IEnumVARIANT
, (void**)&enumvar
);
1126 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1127 ref2
= GET_REFCOUNT(files
);
1128 ok(ref2
== ref
, "got %d, %d\n", ref2
, ref
);
1130 /* clone enumerator */
1131 hr
= IEnumVARIANT_Clone(enumvar
, &clone
);
1132 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1133 ok(clone
!= enumvar
, "got %p, %p\n", enumvar
, clone
);
1134 IEnumVARIANT_Release(clone
);
1136 hr
= IEnumVARIANT_Reset(enumvar
);
1137 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1139 for (i
= 0; i
< 3; i
++)
1143 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1144 ok(hr
== S_OK
, "%d: got 0x%08x\n", i
, hr
);
1145 ok(fetched
== 1, "%d: got %d\n", i
, fetched
);
1146 ok(V_VT(&var
) == VT_DISPATCH
, "%d: got type %d\n", i
, V_VT(&var
));
1148 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IFile
, (void **)&file
);
1149 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1152 hr
= IFile_get_Name(file
, &str
);
1153 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1154 if (!lstrcmpW(str
, aW
+ 1))
1156 else if (!lstrcmpW(str
, bW
+ 1))
1158 else if (!lstrcmpW(str
, cW
+ 1))
1161 ok(0, "unexpected file %s was found\n", wine_dbgstr_w(str
));
1164 IFile_Release(file
);
1168 ok(found_a
== 1 && found_b
== 1 && found_c
== 1,
1169 "each file should be found 1 time instead of %d/%d/%d\n",
1170 found_a
, found_b
, found_c
);
1174 hr
= IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
);
1175 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1176 ok(fetched
== 0, "got %d\n", fetched
);
1178 hr
= IEnumVARIANT_Reset(enumvar
);
1179 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1180 hr
= IEnumVARIANT_Skip(enumvar
, 2);
1181 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1182 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1183 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1185 VariantInit(&var2
[0]);
1186 VariantInit(&var2
[1]);
1188 hr
= IEnumVARIANT_Next(enumvar
, 0, var2
, &fetched
);
1189 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1190 ok(fetched
== 0, "got %d\n", fetched
);
1192 hr
= IEnumVARIANT_Next(enumvar
, 2, var2
, &fetched
);
1193 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1194 ok(fetched
== 1, "got %d\n", fetched
);
1195 ok(V_VT(&var2
[0]) == VT_DISPATCH
, "got type %d\n", V_VT(&var2
[0]));
1196 VariantClear(&var2
[0]);
1197 VariantClear(&var2
[1]);
1199 IEnumVARIANT_Release(enumvar
);
1200 IUnknown_Release(unk
);
1202 CloseHandle(file_a
);
1203 CloseHandle(file_b
);
1204 CloseHandle(file_c
);
1205 RemoveDirectoryW(buffW
);
1207 IFileCollection_Release(files
);
1210 static void test_DriveCollection(void)
1212 IDriveCollection
*drives
;
1213 IEnumVARIANT
*enumvar
;
1219 hr
= IFileSystem3_get_Drives(fs3
, &drives
);
1220 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1222 hr
= IDriveCollection_get__NewEnum(drives
, (IUnknown
**)&enumvar
);
1223 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1225 hr
= IDriveCollection_get_Count(drives
, NULL
);
1226 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1229 hr
= IDriveCollection_get_Count(drives
, &count
);
1230 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1231 ok(count
> 0, "got %d\n", count
);
1233 V_VT(&var
) = VT_EMPTY
;
1235 hr
= IEnumVARIANT_Next(enumvar
, 0, &var
, &fetched
);
1236 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1237 ok(fetched
== 0, "got %d\n", fetched
);
1239 hr
= IEnumVARIANT_Skip(enumvar
, 0);
1240 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1242 hr
= IEnumVARIANT_Skip(enumvar
, count
);
1243 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1245 hr
= IEnumVARIANT_Skip(enumvar
, 1);
1246 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1248 /* reset and iterate again */
1249 hr
= IEnumVARIANT_Reset(enumvar
);
1250 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1252 while (IEnumVARIANT_Next(enumvar
, 1, &var
, &fetched
) == S_OK
) {
1253 IDrive
*drive
= (IDrive
*)V_DISPATCH(&var
);
1254 DriveTypeConst type
;
1257 hr
= IDrive_get_DriveType(drive
, &type
);
1258 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1260 hr
= IDrive_get_DriveLetter(drive
, NULL
);
1261 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1263 hr
= IDrive_get_DriveLetter(drive
, &str
);
1264 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1265 ok(SysStringLen(str
) == 1, "got string %s\n", wine_dbgstr_w(str
));
1268 hr
= IDrive_get_IsReady(drive
, NULL
);
1269 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1271 hr
= IDrive_get_TotalSize(drive
, NULL
);
1272 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1274 hr
= IDrive_get_AvailableSpace(drive
, NULL
);
1275 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1277 hr
= IDrive_get_FreeSpace(drive
, NULL
);
1278 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1280 if (type
== Fixed
) {
1281 VARIANT_BOOL ready
= VARIANT_FALSE
;
1284 hr
= IDrive_get_IsReady(drive
, &ready
);
1285 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1286 ok(ready
== VARIANT_TRUE
, "got %x\n", ready
);
1288 V_VT(&size
) = VT_EMPTY
;
1289 hr
= IDrive_get_TotalSize(drive
, &size
);
1290 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1291 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1292 if (V_VT(&size
) == VT_R8
)
1293 ok(V_R8(&size
) > 0, "got %f\n", V_R8(&size
));
1295 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1297 V_VT(&size
) = VT_EMPTY
;
1298 hr
= IDrive_get_AvailableSpace(drive
, &size
);
1299 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1300 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1301 if (V_VT(&size
) == VT_R8
)
1302 ok(V_R8(&size
) > (double)INT_MAX
, "got %f\n", V_R8(&size
));
1304 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1306 V_VT(&size
) = VT_EMPTY
;
1307 hr
= IDrive_get_FreeSpace(drive
, &size
);
1308 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1309 ok(V_VT(&size
) == VT_R8
|| V_VT(&size
) == VT_I4
, "got %d\n", V_VT(&size
));
1310 if (V_VT(&size
) == VT_R8
)
1311 ok(V_R8(&size
) > 0, "got %f\n", V_R8(&size
));
1313 ok(V_I4(&size
) > 0, "got %d\n", V_I4(&size
));
1318 IEnumVARIANT_Release(enumvar
);
1319 IDriveCollection_Release(drives
);
1322 static void test_CreateTextFile(void)
1324 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1325 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1326 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[10];
1327 ITextStream
*stream
;
1333 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1334 lstrcatW(pathW
, scrrunW
);
1335 lstrcpyW(dirW
, pathW
);
1336 lstrcatW(pathW
, testfileW
);
1338 /* dir doesn't exist */
1339 nameW
= SysAllocString(pathW
);
1340 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1341 ok(hr
== CTL_E_PATHNOTFOUND
, "got 0x%08x\n", hr
);
1343 ret
= CreateDirectoryW(dirW
, NULL
);
1344 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1346 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1347 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1349 hr
= ITextStream_Read(stream
, 1, &str
);
1350 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1352 ITextStream_Release(stream
);
1354 /* check it's created */
1355 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1356 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1359 /* try to create again with no-overwrite mode */
1360 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1361 ok(hr
== CTL_E_FILEALREADYEXISTS
, "got 0x%08x\n", hr
);
1364 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1365 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1366 ITextStream_Release(stream
);
1368 /* overwrite in Unicode mode, check for BOM */
1369 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_TRUE
, &stream
);
1370 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1371 ITextStream_Release(stream
);
1373 /* File was created in Unicode mode, it contains 0xfffe BOM. Opening it in non-Unicode mode
1374 treats BOM like a valuable data with appropriate CP_ACP -> WCHAR conversion. */
1376 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1378 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1379 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1380 hr
= ITextStream_ReadAll(stream
, &str
);
1381 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1382 ok(!lstrcmpW(str
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1384 ITextStream_Release(stream
);
1387 RemoveDirectoryW(dirW
);
1388 SysFreeString(nameW
);
1391 static void test_WriteLine(void)
1393 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1394 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1395 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
];
1396 WCHAR buffW
[MAX_PATH
], buff2W
[MAX_PATH
];
1397 char buffA
[MAX_PATH
];
1398 ITextStream
*stream
;
1405 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1406 lstrcatW(pathW
, scrrunW
);
1407 lstrcpyW(dirW
, pathW
);
1408 lstrcatW(pathW
, testfileW
);
1410 ret
= CreateDirectoryW(dirW
, NULL
);
1411 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1413 /* create as ASCII file first */
1414 nameW
= SysAllocString(pathW
);
1415 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_FALSE
, &stream
);
1416 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1418 hr
= ITextStream_WriteLine(stream
, nameW
);
1419 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1420 ITextStream_Release(stream
);
1422 /* check contents */
1423 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1424 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1426 ret
= ReadFile(file
, buffA
, sizeof(buffA
), &r
, NULL
);
1427 ok(ret
&& r
, "read %d, got %d, %d\n", r
, ret
, GetLastError());
1429 len
= MultiByteToWideChar(CP_ACP
, 0, buffA
, r
, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1431 lstrcpyW(buff2W
, nameW
);
1432 lstrcatW(buff2W
, crlfW
);
1433 ok(!lstrcmpW(buff2W
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(buff2W
));
1437 /* same for unicode file */
1438 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1439 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1441 hr
= ITextStream_WriteLine(stream
, nameW
);
1442 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1443 ITextStream_Release(stream
);
1445 /* check contents */
1446 file
= CreateFileW(pathW
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1447 ok(file
!= INVALID_HANDLE_VALUE
, "got %p\n", file
);
1449 ret
= ReadFile(file
, buffW
, sizeof(buffW
), &r
, NULL
);
1450 ok(ret
&& r
, "read %d, got %d, %d\n", r
, ret
, GetLastError());
1451 buffW
[r
/sizeof(WCHAR
)] = 0;
1455 lstrcatW(buff2W
, nameW
);
1456 lstrcatW(buff2W
, crlfW
);
1457 ok(!lstrcmpW(buff2W
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(buffW
), wine_dbgstr_w(buff2W
));
1461 RemoveDirectoryW(dirW
);
1462 SysFreeString(nameW
);
1465 static void test_ReadAll(void)
1467 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1468 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1469 static const WCHAR secondlineW
[] = {'s','e','c','o','n','d',0};
1470 static const WCHAR aW
[] = {'A',0};
1471 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[500];
1472 ITextStream
*stream
;
1478 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1479 lstrcatW(pathW
, scrrunW
);
1480 lstrcpyW(dirW
, pathW
);
1481 lstrcatW(pathW
, testfileW
);
1483 ret
= CreateDirectoryW(dirW
, NULL
);
1484 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1486 /* Unicode file -> read with ascii stream */
1487 nameW
= SysAllocString(pathW
);
1488 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1489 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1491 hr
= ITextStream_WriteLine(stream
, nameW
);
1492 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1494 str
= SysAllocString(secondlineW
);
1495 hr
= ITextStream_WriteLine(stream
, str
);
1496 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1499 hr
= ITextStream_ReadAll(stream
, NULL
);
1500 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1502 str
= (void*)0xdeadbeef;
1503 hr
= ITextStream_ReadAll(stream
, &str
);
1504 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1505 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1507 ITextStream_Release(stream
);
1509 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1510 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1512 hr
= ITextStream_ReadAll(stream
, NULL
);
1513 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1515 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1517 hr
= ITextStream_ReadAll(stream
, &str
);
1518 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1520 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1521 ok(str
[0] == buffW
[0] && str
[1] == buffW
[1], "got %s, %d\n", wine_dbgstr_w(str
), SysStringLen(str
));
1523 ITextStream_Release(stream
);
1525 /* Unicode file -> read with unicode stream */
1526 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1527 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1529 lstrcpyW(buffW
, nameW
);
1530 lstrcatW(buffW
, crlfW
);
1531 lstrcatW(buffW
, secondlineW
);
1532 lstrcatW(buffW
, crlfW
);
1534 hr
= ITextStream_ReadAll(stream
, &str
);
1535 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1536 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1539 /* ReadAll one more time */
1540 str
= (void*)0xdeadbeef;
1541 hr
= ITextStream_ReadAll(stream
, &str
);
1542 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1543 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1545 /* ReadLine fails the same way */
1546 str
= (void*)0xdeadbeef;
1547 hr
= ITextStream_ReadLine(stream
, &str
);
1548 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1549 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1550 ITextStream_Release(stream
);
1552 /* Open again and skip first line before ReadAll */
1553 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1554 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1557 hr
= ITextStream_ReadLine(stream
, &str
);
1559 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1560 ok(str
!= NULL
, "got %p\n", str
);
1564 lstrcpyW(buffW
, secondlineW
);
1565 lstrcatW(buffW
, crlfW
);
1567 hr
= ITextStream_ReadAll(stream
, &str
);
1568 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1570 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1572 ITextStream_Release(stream
);
1574 /* ASCII file, read with Unicode stream */
1575 /* 1. one byte content, not enough for Unicode read */
1576 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1577 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1578 str
= SysAllocString(aW
);
1579 hr
= ITextStream_Write(stream
, str
);
1581 ITextStream_Release(stream
);
1583 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1584 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1586 str
= (void*)0xdeadbeef;
1587 hr
= ITextStream_ReadAll(stream
, &str
);
1588 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1589 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef) /* win2k */, "got %p\n", str
);
1591 ITextStream_Release(stream
);
1594 RemoveDirectoryW(dirW
);
1595 SysFreeString(nameW
);
1598 static void test_Read(void)
1600 static const WCHAR scrrunW
[] = {'s','c','r','r','u','n','\\',0};
1601 static const WCHAR testfileW
[] = {'t','e','s','t','.','t','x','t',0};
1602 static const WCHAR secondlineW
[] = {'s','e','c','o','n','d',0};
1603 static const WCHAR aW
[] = {'A',0};
1604 WCHAR pathW
[MAX_PATH
], dirW
[MAX_PATH
], buffW
[500];
1605 ITextStream
*stream
;
1611 GetTempPathW(sizeof(pathW
)/sizeof(WCHAR
), pathW
);
1612 lstrcatW(pathW
, scrrunW
);
1613 lstrcpyW(dirW
, pathW
);
1614 lstrcatW(pathW
, testfileW
);
1616 ret
= CreateDirectoryW(dirW
, NULL
);
1617 ok(ret
, "got %d, %d\n", ret
, GetLastError());
1619 /* Unicode file -> read with ascii stream */
1620 nameW
= SysAllocString(pathW
);
1621 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_FALSE
, VARIANT_TRUE
, &stream
);
1622 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1624 hr
= ITextStream_WriteLine(stream
, nameW
);
1625 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1627 str
= SysAllocString(secondlineW
);
1628 hr
= ITextStream_WriteLine(stream
, str
);
1629 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1632 hr
= ITextStream_Read(stream
, 0, NULL
);
1633 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1635 hr
= ITextStream_Read(stream
, 1, NULL
);
1636 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1638 hr
= ITextStream_Read(stream
, -1, NULL
);
1639 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1641 str
= (void*)0xdeadbeef;
1642 hr
= ITextStream_Read(stream
, 1, &str
);
1643 ok(hr
== CTL_E_BADFILEMODE
, "got 0x%08x\n", hr
);
1644 ok(str
== NULL
, "got %p\n", str
);
1646 ITextStream_Release(stream
);
1648 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateFalse
, &stream
);
1649 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1651 hr
= ITextStream_Read(stream
, 1, NULL
);
1652 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1654 str
= (void*)0xdeadbeef;
1655 hr
= ITextStream_Read(stream
, -1, &str
);
1656 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1657 ok(str
== NULL
, "got %p\n", str
);
1659 str
= (void*)0xdeadbeef;
1660 hr
= ITextStream_Read(stream
, 0, &str
);
1661 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1662 ok(str
== NULL
, "got %p\n", str
);
1664 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1666 hr
= ITextStream_Read(stream
, 2, &str
);
1667 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1670 MultiByteToWideChar(CP_ACP
, 0, utf16bom
, -1, buffW
, sizeof(buffW
)/sizeof(WCHAR
));
1672 ok(!lstrcmpW(str
, buffW
), "got %s, expected %s\n", wine_dbgstr_w(str
), wine_dbgstr_w(buffW
));
1673 ok(SysStringLen(str
) == 2, "got %d\n", SysStringLen(str
));
1675 ITextStream_Release(stream
);
1677 /* Unicode file -> read with unicode stream */
1678 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1679 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1681 lstrcpyW(buffW
, nameW
);
1682 lstrcatW(buffW
, crlfW
);
1683 lstrcatW(buffW
, secondlineW
);
1684 lstrcatW(buffW
, crlfW
);
1686 hr
= ITextStream_Read(stream
, 500, &str
);
1687 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1688 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1691 /* ReadAll one more time */
1692 str
= (void*)0xdeadbeef;
1693 hr
= ITextStream_Read(stream
, 10, &str
);
1694 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1695 ok(str
== NULL
, "got %p\n", str
);
1697 /* ReadLine fails the same way */
1698 str
= (void*)0xdeadbeef;
1699 hr
= ITextStream_ReadLine(stream
, &str
);
1700 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1701 ok(str
== NULL
|| broken(str
== (void*)0xdeadbeef), "got %p\n", str
);
1702 ITextStream_Release(stream
);
1704 /* Open again and skip first line before ReadAll */
1705 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1706 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1709 hr
= ITextStream_ReadLine(stream
, &str
);
1711 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1712 ok(str
!= NULL
, "got %p\n", str
);
1716 lstrcpyW(buffW
, secondlineW
);
1717 lstrcatW(buffW
, crlfW
);
1719 hr
= ITextStream_Read(stream
, 100, &str
);
1720 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* win2k */, "got 0x%08x\n", hr
);
1722 ok(!lstrcmpW(buffW
, str
), "got %s\n", wine_dbgstr_w(str
));
1724 ITextStream_Release(stream
);
1726 /* ASCII file, read with Unicode stream */
1727 /* 1. one byte content, not enough for Unicode read */
1728 hr
= IFileSystem3_CreateTextFile(fs3
, nameW
, VARIANT_TRUE
, VARIANT_FALSE
, &stream
);
1729 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1730 str
= SysAllocString(aW
);
1731 hr
= ITextStream_Write(stream
, str
);
1733 ITextStream_Release(stream
);
1735 hr
= IFileSystem3_OpenTextFile(fs3
, nameW
, ForReading
, VARIANT_FALSE
, TristateTrue
, &stream
);
1736 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1738 str
= (void*)0xdeadbeef;
1739 hr
= ITextStream_Read(stream
, 500, &str
);
1740 ok(hr
== CTL_E_ENDOFFILE
, "got 0x%08x\n", hr
);
1741 ok(str
== NULL
, "got %p\n", str
);
1743 ITextStream_Release(stream
);
1746 RemoveDirectoryW(dirW
);
1747 SysFreeString(nameW
);
1750 struct getdrivename_test
{
1751 const WCHAR path
[10];
1752 const WCHAR drive
[5];
1755 static const struct getdrivename_test getdrivenametestdata
[] = {
1756 { {'C',':','\\','1','.','t','s','t',0}, {'C',':',0} },
1757 { {'O',':','\\','1','.','t','s','t',0}, {'O',':',0} },
1758 { {'O',':',0}, {'O',':',0} },
1759 { {'o',':',0}, {'o',':',0} },
1760 { {'O','O',':',0} },
1766 static void test_GetDriveName(void)
1768 const struct getdrivename_test
*ptr
= getdrivenametestdata
;
1772 hr
= IFileSystem3_GetDriveName(fs3
, NULL
, NULL
);
1773 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1775 name
= (void*)0xdeadbeef;
1776 hr
= IFileSystem3_GetDriveName(fs3
, NULL
, &name
);
1777 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1778 ok(name
== NULL
, "got %p\n", name
);
1780 while (*ptr
->path
) {
1781 BSTR path
= SysAllocString(ptr
->path
);
1782 name
= (void*)0xdeadbeef;
1783 hr
= IFileSystem3_GetDriveName(fs3
, path
, &name
);
1784 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1786 ok(!lstrcmpW(ptr
->drive
, name
), "got %s, expected %s\n", wine_dbgstr_w(name
), wine_dbgstr_w(ptr
->drive
));
1788 ok(!*ptr
->drive
, "got %s, expected %s\n", wine_dbgstr_w(name
), wine_dbgstr_w(ptr
->drive
));
1789 SysFreeString(path
);
1790 SysFreeString(name
);
1795 static void test_SerialNumber(void)
1797 IDriveCollection
*drives
;
1804 hr
= IFileSystem3_get_Drives(fs3
, &drives
);
1805 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1807 hr
= IDriveCollection_get__NewEnum(drives
, (IUnknown
**)&iter
);
1808 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1809 IDriveCollection_Release(drives
);
1812 DriveTypeConst type
;
1815 hr
= IEnumVARIANT_Next(iter
, 1, &var
, NULL
);
1816 if (hr
== S_FALSE
) {
1817 skip("No fixed drive found, skipping test.\n");
1818 IEnumVARIANT_Release(iter
);
1821 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1823 hr
= IDispatch_QueryInterface(V_DISPATCH(&var
), &IID_IDrive
, (void**)&drive
);
1824 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1827 hr
= IDrive_get_DriveType(drive
, &type
);
1828 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1832 IDrive_Release(drive
);
1835 hr
= IDrive_get_SerialNumber(drive
, NULL
);
1836 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1838 serial
= 0xdeadbeef;
1839 hr
= IDrive_get_SerialNumber(drive
, &serial
);
1840 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1841 ok(serial
!= 0xdeadbeef, "got %x\n", serial
);
1843 hr
= IDrive_get_FileSystem(drive
, NULL
);
1844 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1847 hr
= IDrive_get_FileSystem(drive
, &name
);
1848 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1849 ok(name
!= NULL
, "got %p\n", name
);
1850 SysFreeString(name
);
1852 hr
= IDrive_get_VolumeName(drive
, NULL
);
1853 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
1856 hr
= IDrive_get_VolumeName(drive
, &name
);
1857 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1858 ok(name
!= NULL
, "got %p\n", name
);
1859 SysFreeString(name
);
1861 IDrive_Release(drive
);
1862 IEnumVARIANT_Release(iter
);
1865 START_TEST(filesystem
)
1871 hr
= CoCreateInstance(&CLSID_FileSystemObject
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
1872 &IID_IFileSystem3
, (void**)&fs3
);
1874 win_skip("Could not create FileSystem object: %08x\n", hr
);
1879 test_createfolder();
1881 test_GetFileVersion();
1882 test_GetParentFolderName();
1885 test_GetAbsolutePathName();
1890 test_FolderCollection();
1891 test_FileCollection();
1892 test_DriveCollection();
1893 test_CreateTextFile();
1897 test_GetDriveName();
1898 test_SerialNumber();
1900 IFileSystem3_Release(fs3
);