l3codeca.acm: Avoid mpg123 functions with suffix.
[wine.git] / dlls / scrrun / tests / filesystem.c
blob79af87591ff9158a7ba05c9dbf60557d26ea46df
1 /*
3 * Copyright 2012 Alistair Leslie-Hughes
4 * Copyright 2014 Dmitry Timoshkov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #include <stdio.h>
23 #include <limits.h>
25 #include "windows.h"
26 #include "ole2.h"
27 #include "olectl.h"
28 #include "oleauto.h"
29 #include "dispex.h"
31 #include "wine/test.h"
33 #include "initguid.h"
34 #include "scrrun.h"
36 static IFileSystem3 *fs3;
38 static HRESULT (WINAPI *pDoOpenPipeStream)(HANDLE pipe, DWORD mode, ITextStream **stream);
40 /* w2k and 2k3 error code. */
41 #define E_VAR_NOT_SET 0x800a005b
43 static inline ULONG get_refcount(IUnknown *iface)
45 IUnknown_AddRef(iface);
46 return IUnknown_Release(iface);
49 static const char utf16bom[] = {0xff,0xfe,0};
50 static const WCHAR testfileW[] = L"test.txt";
52 #define GET_REFCOUNT(iface) \
53 get_refcount((IUnknown*)iface)
55 static inline void get_temp_path(const WCHAR *prefix, WCHAR *path)
57 WCHAR buffW[MAX_PATH];
59 GetTempPathW(MAX_PATH, buffW);
60 GetTempFileNameW(buffW, prefix, 0, path);
61 DeleteFileW(path);
64 static IDrive *get_fixed_drive(void)
66 IDriveCollection *drives;
67 IEnumVARIANT *iter;
68 IDrive *drive;
69 HRESULT hr;
71 hr = IFileSystem3_get_Drives(fs3, &drives);
72 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
74 hr = IDriveCollection_get__NewEnum(drives, (IUnknown**)&iter);
75 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
76 IDriveCollection_Release(drives);
78 while (1) {
79 DriveTypeConst type;
80 VARIANT var;
82 hr = IEnumVARIANT_Next(iter, 1, &var, NULL);
83 if (hr == S_FALSE) {
84 drive = NULL;
85 break;
87 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
89 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDrive, (void**)&drive);
90 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
91 VariantClear(&var);
93 hr = IDrive_get_DriveType(drive, &type);
94 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
95 if (type == Fixed)
96 break;
98 IDrive_Release(drive);
101 IEnumVARIANT_Release(iter);
102 return drive;
105 #define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__)
106 static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line)
108 IProvideClassInfo *classinfo;
109 TYPEATTR *attr;
110 ITypeInfo *ti;
111 IUnknown *unk;
112 HRESULT hr;
114 hr = IDispatch_QueryInterface(disp, &IID_IProvideClassInfo, (void **)&classinfo);
115 ok_(__FILE__,line) (hr == S_OK, "Failed to get IProvideClassInfo, %#lx.\n", hr);
117 hr = IProvideClassInfo_GetClassInfo(classinfo, &ti);
118 ok_(__FILE__,line) (hr == S_OK, "GetClassInfo() failed, %#lx.\n", hr);
120 hr = ITypeInfo_GetTypeAttr(ti, &attr);
121 ok_(__FILE__,line) (hr == S_OK, "GetTypeAttr() failed, %#lx.\n", hr);
123 ok_(__FILE__,line) (IsEqualGUID(&attr->guid, guid), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr->guid),
124 wine_dbgstr_guid(guid));
126 hr = IProvideClassInfo_QueryInterface(classinfo, &IID_IUnknown, (void **)&unk);
127 ok(hr == S_OK, "Failed to QI for IUnknown.\n");
128 ok(unk == (IUnknown *)disp, "Got unk %p, original %p.\n", unk, disp);
129 IUnknown_Release(unk);
131 IProvideClassInfo_Release(classinfo);
132 ITypeInfo_ReleaseTypeAttr(ti, attr);
133 ITypeInfo_Release(ti);
136 static void test_interfaces(void)
138 HRESULT hr;
139 IDispatch *disp;
140 IDispatchEx *dispex;
141 IObjectWithSite *site;
142 VARIANT_BOOL b;
143 BSTR path;
144 WCHAR windows_path[MAX_PATH];
145 WCHAR file_path[MAX_PATH];
147 IFileSystem3_QueryInterface(fs3, &IID_IDispatch, (void**)&disp);
149 GetSystemDirectoryW(windows_path, MAX_PATH);
150 lstrcpyW(file_path, windows_path);
151 lstrcatW(file_path, L"\\kernel32.dll");
153 test_provideclassinfo(disp, &CLSID_FileSystemObject);
155 hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
156 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
158 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
159 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
161 b = VARIANT_TRUE;
162 hr = IFileSystem3_FileExists(fs3, NULL, &b);
163 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
164 ok(b == VARIANT_FALSE, "got %x\n", b);
166 hr = IFileSystem3_FileExists(fs3, NULL, NULL);
167 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
169 path = SysAllocString(L"path");
170 b = VARIANT_TRUE;
171 hr = IFileSystem3_FileExists(fs3, path, &b);
172 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
173 ok(b == VARIANT_FALSE, "got %x\n", b);
174 SysFreeString(path);
176 path = SysAllocString(file_path);
177 b = VARIANT_FALSE;
178 hr = IFileSystem3_FileExists(fs3, path, &b);
179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
180 ok(b == VARIANT_TRUE, "got %x\n", b);
181 SysFreeString(path);
183 path = SysAllocString(windows_path);
184 b = VARIANT_TRUE;
185 hr = IFileSystem3_FileExists(fs3, path, &b);
186 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
187 ok(b == VARIANT_FALSE, "got %x\n", b);
188 SysFreeString(path);
190 /* Folder Exists */
191 hr = IFileSystem3_FolderExists(fs3, NULL, NULL);
192 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
194 path = SysAllocString(windows_path);
195 hr = IFileSystem3_FolderExists(fs3, path, &b);
196 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
197 ok(b == VARIANT_TRUE, "Folder doesn't exists\n");
198 SysFreeString(path);
200 path = SysAllocString(L"c:\\Nonexistent");
201 hr = IFileSystem3_FolderExists(fs3, path, &b);
202 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
203 ok(b == VARIANT_FALSE, "Folder exists\n");
204 SysFreeString(path);
206 path = SysAllocString(file_path);
207 hr = IFileSystem3_FolderExists(fs3, path, &b);
208 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
209 ok(b == VARIANT_FALSE, "Folder exists\n");
210 SysFreeString(path);
212 IDispatch_Release(disp);
215 static void test_createfolder(void)
217 WCHAR buffW[MAX_PATH];
218 HRESULT hr;
219 BSTR path;
220 IFolder *folder;
221 BOOL ret;
223 get_temp_path(NULL, buffW);
224 ret = CreateDirectoryW(buffW, NULL);
225 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
227 /* create existing directory */
228 path = SysAllocString(buffW);
229 folder = (void*)0xdeabeef;
230 hr = IFileSystem3_CreateFolder(fs3, path, &folder);
231 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
232 ok(folder == NULL, "got %p\n", folder);
233 SysFreeString(path);
234 RemoveDirectoryW(buffW);
237 static void test_textstream(void)
239 ITextStream *stream;
240 VARIANT_BOOL b;
241 DWORD written;
242 HANDLE file;
243 HRESULT hr;
244 BSTR name, data;
245 BOOL ret;
247 file = CreateFileW(testfileW, GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
248 CloseHandle(file);
250 name = SysAllocString(testfileW);
251 b = VARIANT_FALSE;
252 hr = IFileSystem3_FileExists(fs3, name, &b);
253 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
254 ok(b == VARIANT_TRUE, "got %x\n", b);
256 /* different mode combinations */
257 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting | ForAppending, VARIANT_FALSE, TristateFalse, &stream);
258 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
260 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading | ForAppending, VARIANT_FALSE, TristateFalse, &stream);
261 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
263 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting | ForReading, VARIANT_FALSE, TristateFalse, &stream);
264 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
266 hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateFalse, &stream);
267 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
268 hr = ITextStream_Read(stream, 1, &data);
269 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
270 ITextStream_Release(stream);
272 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream);
273 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
274 hr = ITextStream_Read(stream, 1, &data);
275 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
276 ITextStream_Release(stream);
278 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream);
279 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
281 /* try to write when open for reading */
282 hr = ITextStream_WriteLine(stream, name);
283 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
285 hr = ITextStream_Write(stream, name);
286 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
288 hr = ITextStream_get_AtEndOfStream(stream, NULL);
289 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
291 b = 10;
292 hr = ITextStream_get_AtEndOfStream(stream, &b);
293 ok(hr == S_OK || broken(hr == S_FALSE), "Unexpected hr %#lx.\n", hr);
294 ok(b == VARIANT_TRUE, "got 0x%x\n", b);
296 ITextStream_Release(stream);
298 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream);
299 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
301 b = 10;
302 hr = ITextStream_get_AtEndOfStream(stream, &b);
303 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
304 ok(b == VARIANT_TRUE || broken(b == 10), "got 0x%x\n", b);
306 b = 10;
307 hr = ITextStream_get_AtEndOfLine(stream, &b);
308 todo_wine {
309 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
310 ok(b == VARIANT_FALSE || broken(b == 10), "got 0x%x\n", b);
312 hr = ITextStream_Read(stream, 1, &data);
313 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
315 hr = ITextStream_ReadLine(stream, &data);
316 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
318 hr = ITextStream_ReadAll(stream, &data);
319 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
321 ITextStream_Release(stream);
323 hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateFalse, &stream);
324 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
326 b = 10;
327 hr = ITextStream_get_AtEndOfStream(stream, &b);
328 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
329 ok(b == VARIANT_TRUE || broken(b == 10), "got 0x%x\n", b);
331 b = 10;
332 hr = ITextStream_get_AtEndOfLine(stream, &b);
333 todo_wine {
334 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
335 ok(b == VARIANT_FALSE || broken(b == 10), "got 0x%x\n", b);
337 hr = ITextStream_Read(stream, 1, &data);
338 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
340 hr = ITextStream_ReadLine(stream, &data);
341 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
343 hr = ITextStream_ReadAll(stream, &data);
344 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
346 ITextStream_Release(stream);
348 /* now with non-empty file */
349 file = CreateFileW(testfileW, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
350 ret = WriteFile(file, testfileW, sizeof(testfileW), &written, NULL);
351 ok(ret && written == sizeof(testfileW), "got %d\n", ret);
352 CloseHandle(file);
354 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream);
355 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
356 b = 10;
357 hr = ITextStream_get_AtEndOfStream(stream, &b);
358 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
359 ok(b == VARIANT_FALSE, "got 0x%x\n", b);
360 ITextStream_Release(stream);
362 SysFreeString(name);
363 DeleteFileW(testfileW);
366 static void test_GetFileVersion(void)
368 WCHAR pathW[MAX_PATH], filenameW[MAX_PATH];
369 BSTR path, version;
370 HRESULT hr;
372 GetSystemDirectoryW(pathW, ARRAY_SIZE(pathW));
374 lstrcpyW(filenameW, pathW);
375 lstrcatW(filenameW, L"\\kernel32.dll");
377 path = SysAllocString(filenameW);
378 hr = IFileSystem3_GetFileVersion(fs3, path, &version);
379 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
380 ok(*version != 0, "got %s\n", wine_dbgstr_w(version));
381 SysFreeString(version);
382 SysFreeString(path);
384 lstrcpyW(filenameW, pathW);
385 lstrcatW(filenameW, L"\\kernel33.dll");
387 path = SysAllocString(filenameW);
388 version = (void*)0xdeadbeef;
389 hr = IFileSystem3_GetFileVersion(fs3, path, &version);
390 ok(broken(hr == S_OK) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
391 if (hr == S_OK)
393 ok(*version == 0, "got %s\n", wine_dbgstr_w(version));
394 SysFreeString(version);
396 else
397 ok(version == (void*)0xdeadbeef, "got %p\n", version);
398 SysFreeString(path);
401 static void test_GetParentFolderName(void)
403 static const struct
405 const WCHAR *path;
406 const WCHAR *result;
408 tests[] =
410 { NULL, NULL },
411 { L"a", NULL },
412 { L"a/a/a", L"a/a" },
413 { L"a\\a\\a", L"a\\a" },
414 { L"a/a//\\\\", L"a" },
415 { L"c:\\\\a", L"c:\\" },
416 { L"ac:\\a", L"ac:" }
419 BSTR path, result;
420 HRESULT hr;
421 int i;
423 hr = IFileSystem3_GetParentFolderName(fs3, NULL, NULL);
424 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
426 for(i=0; i < ARRAY_SIZE(tests); i++) {
427 result = (BSTR)0xdeadbeef;
428 path = tests[i].path ? SysAllocString(tests[i].path) : NULL;
429 hr = IFileSystem3_GetParentFolderName(fs3, path, &result);
430 ok(hr == S_OK, "%d: unexpected hr %#lx.\n", i, hr);
431 if(!tests[i].result)
432 ok(!result, "%d) result = %s\n", i, wine_dbgstr_w(result));
433 else
434 ok(!lstrcmpW(result, tests[i].result), "%d) result = %s\n", i, wine_dbgstr_w(result));
435 SysFreeString(path);
436 SysFreeString(result);
440 static void test_GetFileName(void)
442 static const struct
444 const WCHAR *path;
445 const WCHAR *result;
446 } tests[] =
448 { NULL, NULL },
449 { L"a", L"a" },
450 { L"a/a.b", L"a.b" },
451 { L"a\\", L"a" },
452 { L"c:", NULL },
453 { L"/\\", NULL }
456 BSTR path, result;
457 HRESULT hr;
458 int i;
460 hr = IFileSystem3_GetFileName(fs3, NULL, NULL);
461 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
463 for(i=0; i < ARRAY_SIZE(tests); i++) {
464 result = (BSTR)0xdeadbeef;
465 path = tests[i].path ? SysAllocString(tests[i].path) : NULL;
466 hr = IFileSystem3_GetFileName(fs3, path, &result);
467 ok(hr == S_OK, "%d: unexpected hr %#lx.\n", i, hr);
468 if(!tests[i].result)
469 ok(!result, "%d) result = %s\n", i, wine_dbgstr_w(result));
470 else
471 ok(!lstrcmpW(result, tests[i].result), "%d) result = %s\n", i, wine_dbgstr_w(result));
472 SysFreeString(path);
473 SysFreeString(result);
477 static void test_GetTempName(void)
479 BSTR result;
480 HRESULT hr;
482 hr = IFileSystem3_GetTempName(fs3, NULL);
483 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
484 result = (BSTR)0xdeadbeef;
485 hr = IFileSystem3_GetTempName(fs3, &result);
486 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
487 ok(!!wcsstr( result,L".tmp"), "GetTempName returned %s, expected .tmp suffix\n", debugstr_w(result));
488 SysFreeString(result);
491 static void test_GetBaseName(void)
493 static const struct
495 const WCHAR *path;
496 const WCHAR *result;
498 tests[] =
500 { NULL, NULL},
501 { L"a", L"a" },
502 { L"a/a.b.c", L"a.b" },
503 { L"a.b\\", L"a" },
504 { L"c:", NULL },
505 { L"/\\", NULL },
506 { L".a", L"" }
509 BSTR path, result;
510 HRESULT hr;
511 int i;
513 hr = IFileSystem3_GetBaseName(fs3, NULL, NULL);
514 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
516 for(i=0; i < ARRAY_SIZE(tests); i++) {
517 result = (BSTR)0xdeadbeef;
518 path = tests[i].path ? SysAllocString(tests[i].path) : NULL;
519 hr = IFileSystem3_GetBaseName(fs3, path, &result);
520 ok(hr == S_OK, "%d, unexpected hr %#lx.\n", i, hr);
521 if(!tests[i].result)
522 ok(!result, "%d) result = %s\n", i, wine_dbgstr_w(result));
523 else
524 ok(!lstrcmpW(result, tests[i].result), "%d) result = %s\n", i, wine_dbgstr_w(result));
525 SysFreeString(path);
526 SysFreeString(result);
530 static void test_GetAbsolutePathName(void)
532 static const WCHAR dir1[] = L"test_dir1";
533 static const WCHAR dir2[] = L"test_dir2";
534 static const WCHAR dir_match1[] = L"test_dir*";
535 static const WCHAR dir_match2[] = L"test_di*";
537 WIN32_FIND_DATAW fdata;
538 HANDLE find;
539 WCHAR buf[MAX_PATH], buf2[MAX_PATH];
540 BSTR path, result;
541 HRESULT hr;
543 hr = IFileSystem3_GetAbsolutePathName(fs3, NULL, NULL);
544 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
546 hr = IFileSystem3_GetAbsolutePathName(fs3, NULL, &result);
547 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
548 GetFullPathNameW(L".", MAX_PATH, buf, NULL);
549 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf));
550 SysFreeString(result);
552 find = FindFirstFileW(dir_match2, &fdata);
553 if(find != INVALID_HANDLE_VALUE) {
554 skip("GetAbsolutePathName tests\n");
555 FindClose(find);
556 return;
559 path = SysAllocString(dir_match1);
560 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
561 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
562 GetFullPathNameW(dir_match1, MAX_PATH, buf2, NULL);
563 ok(!lstrcmpiW(buf2, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf2));
564 SysFreeString(result);
566 ok(CreateDirectoryW(dir1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir1));
567 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
568 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
569 GetFullPathNameW(dir1, MAX_PATH, buf, NULL);
570 ok(!lstrcmpiW(buf, result) || broken(!lstrcmpiW(buf2, result)), "result = %s, expected %s\n",
571 wine_dbgstr_w(result), wine_dbgstr_w(buf));
572 SysFreeString(result);
574 ok(CreateDirectoryW(dir2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir2));
575 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
576 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
577 if(!lstrcmpiW(buf, result) || !lstrcmpiW(buf2, result)) {
578 ok(!lstrcmpiW(buf, result) || broken(!lstrcmpiW(buf2, result)), "result = %s, expected %s\n",
579 wine_dbgstr_w(result), wine_dbgstr_w(buf));
580 }else {
581 GetFullPathNameW(dir2, MAX_PATH, buf, NULL);
582 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n",
583 wine_dbgstr_w(result), wine_dbgstr_w(buf));
585 SysFreeString(result);
587 SysFreeString(path);
588 path = SysAllocString(dir_match2);
589 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
591 GetFullPathNameW(dir_match2, MAX_PATH, buf, NULL);
592 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf));
593 SysFreeString(result);
594 SysFreeString(path);
596 RemoveDirectoryW(dir1);
597 RemoveDirectoryW(dir2);
600 static void test_GetFile(void)
602 BSTR path, str;
603 WCHAR pathW[MAX_PATH];
604 FileAttribute fa;
605 VARIANT size;
606 DWORD gfa, new_gfa;
607 IFile *file;
608 HRESULT hr;
609 HANDLE hf;
610 BOOL ret;
611 DATE date;
613 get_temp_path(NULL, pathW);
615 path = SysAllocString(pathW);
616 hr = IFileSystem3_GetFile(fs3, path, NULL);
617 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
618 hr = IFileSystem3_GetFile(fs3, NULL, &file);
619 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
621 file = (IFile*)0xdeadbeef;
622 hr = IFileSystem3_GetFile(fs3, path, &file);
623 ok(!file, "file != NULL\n");
624 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
626 hf = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
627 if(hf == INVALID_HANDLE_VALUE) {
628 skip("Can't create temporary file\n");
629 SysFreeString(path);
630 return;
632 CloseHandle(hf);
634 hr = IFileSystem3_GetFile(fs3, path, &file);
635 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
637 hr = IFile_get_DateLastModified(file, NULL);
638 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
640 date = 0.0;
641 hr = IFile_get_DateLastModified(file, &date);
642 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
643 ok(date > 0.0, "got %f\n", date);
645 hr = IFile_get_Path(file, NULL);
646 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
648 hr = IFile_get_Path(file, &str);
649 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
650 ok(!lstrcmpiW(str, pathW), "got %s\n", wine_dbgstr_w(str));
651 SysFreeString(str);
653 #define FILE_ATTR_MASK (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
654 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE | \
655 FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED)
657 hr = IFile_get_Attributes(file, &fa);
658 gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK;
659 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
660 ok(fa == gfa, "Unexpected flags %#x, expected %lx.\n", fa, gfa);
662 hr = IFile_put_Attributes(file, gfa | FILE_ATTRIBUTE_READONLY);
663 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
664 new_gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK;
665 ok(new_gfa == (gfa|FILE_ATTRIBUTE_READONLY), "Unexpected flags %#lx, expected %lx\n", new_gfa, gfa|FILE_ATTRIBUTE_READONLY);
667 hr = IFile_get_Attributes(file, &fa);
668 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
669 ok(fa == new_gfa, "Unexpected flags %#x, expected %lx.\n", fa, new_gfa);
671 hr = IFile_put_Attributes(file, gfa);
672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
673 new_gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK;
674 ok(new_gfa == gfa, "Unexpected flags %#lx, expected %lx.\n", new_gfa, gfa);
676 hr = IFile_get_Attributes(file, &fa);
677 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
678 ok(fa == gfa, "Unexpected flags %#x, expected %lx.\n", fa, gfa);
680 hr = IFile_get_Size(file, &size);
681 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
682 ok(V_VT(&size) == VT_I4, "V_VT(&size) = %d, expected VT_I4\n", V_VT(&size));
683 ok(V_I4(&size) == 0, "V_I4(&size) = %ld, expected 0\n", V_I4(&size));
684 IFile_Release(file);
686 hr = IFileSystem3_DeleteFile(fs3, path, FALSE);
687 ok(hr == CTL_E_PERMISSIONDENIED || broken(hr == S_OK), "Unexpected hr %#lx.\n", hr);
688 if(hr != S_OK) {
689 hr = IFileSystem3_DeleteFile(fs3, path, TRUE);
690 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
692 hr = IFileSystem3_DeleteFile(fs3, path, TRUE);
693 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
695 SysFreeString(path);
697 /* try with directory */
698 lstrcatW(pathW, L"\\");
699 ret = CreateDirectoryW(pathW, NULL);
700 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
702 path = SysAllocString(pathW);
703 hr = IFileSystem3_GetFile(fs3, path, &file);
704 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
705 SysFreeString(path);
707 RemoveDirectoryW(pathW);
710 static inline BOOL create_file(const WCHAR *name)
712 HANDLE f = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
713 CloseHandle(f);
714 return f != INVALID_HANDLE_VALUE;
717 static inline void create_path(const WCHAR *folder, const WCHAR *name, WCHAR *ret)
719 DWORD len = lstrlenW(folder);
720 memmove(ret, folder, len*sizeof(WCHAR));
721 ret[len] = '\\';
722 memmove(ret+len+1, name, (lstrlenW(name)+1)*sizeof(WCHAR));
725 static void test_CopyFolder(void)
727 static const WCHAR filesystem3_dir[] = L"filesystem3_test";
728 static const WCHAR src1W[] = L"src1";
729 static const WCHAR dstW[] = L"dst";
731 WCHAR tmp[MAX_PATH];
732 BSTR bsrc, bdst;
733 HRESULT hr;
735 if(!CreateDirectoryW(filesystem3_dir, NULL)) {
736 skip("can't create temporary directory\n");
737 return;
740 create_path(filesystem3_dir, src1W, tmp);
741 bsrc = SysAllocString(tmp);
742 create_path(filesystem3_dir, dstW, tmp);
743 bdst = SysAllocString(tmp);
744 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
745 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
747 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
748 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
750 ok(create_file(bsrc), "can't create %s file\n", wine_dbgstr_w(bsrc));
751 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
752 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
754 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
755 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
757 hr = IFileSystem3_DeleteFile(fs3, bsrc, VARIANT_FALSE);
758 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
760 ok(CreateDirectoryW(bsrc, NULL), "can't create %s\n", wine_dbgstr_w(bsrc));
761 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
762 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
764 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
765 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
767 hr = IFileSystem3_DeleteFile(fs3, bdst, VARIANT_TRUE);
768 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
770 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
773 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
774 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
775 create_path(tmp, src1W, tmp);
776 ok(GetFileAttributesW(tmp) == INVALID_FILE_ATTRIBUTES,
777 "%s file exists\n", wine_dbgstr_w(tmp));
779 create_path(filesystem3_dir, dstW, tmp);
780 create_path(tmp, L"", tmp);
781 SysFreeString(bdst);
782 bdst = SysAllocString(tmp);
783 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
784 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
785 create_path(tmp, src1W, tmp);
786 ok(GetFileAttributesW(tmp) != INVALID_FILE_ATTRIBUTES,
787 "%s directory doesn't exist\n", wine_dbgstr_w(tmp));
788 ok(RemoveDirectoryW(tmp), "can't remove %s directory\n", wine_dbgstr_w(tmp));
789 create_path(filesystem3_dir, dstW, tmp);
790 SysFreeString(bdst);
791 bdst = SysAllocString(tmp);
793 create_path(filesystem3_dir, L"src*", tmp);
794 SysFreeString(bsrc);
795 bsrc = SysAllocString(tmp);
796 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
797 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
798 create_path(filesystem3_dir, dstW, tmp);
799 create_path(tmp, src1W, tmp);
800 ok(GetFileAttributesW(tmp) != INVALID_FILE_ATTRIBUTES,
801 "%s directory doesn't exist\n", wine_dbgstr_w(tmp));
803 hr = IFileSystem3_DeleteFolder(fs3, bdst, VARIANT_FALSE);
804 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
806 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
807 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
809 create_path(filesystem3_dir, src1W, tmp);
810 SysFreeString(bsrc);
811 bsrc = SysAllocString(tmp);
812 create_path(tmp, src1W, tmp);
813 ok(create_file(tmp), "can't create %s file\n", wine_dbgstr_w(tmp));
814 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_FALSE);
815 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
817 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_FALSE);
818 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
820 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
821 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
822 SysFreeString(bsrc);
823 SysFreeString(bdst);
825 bsrc = SysAllocString(filesystem3_dir);
826 hr = IFileSystem3_DeleteFolder(fs3, bsrc, VARIANT_FALSE);
827 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
828 SysFreeString(bsrc);
831 static BSTR bstr_from_str(const char *str)
833 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
834 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
835 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
836 return ret;
839 struct buildpath_test
841 const char *path;
842 const char *name;
843 const char *result;
846 static struct buildpath_test buildpath_data[] =
848 { "C:\\path", "..\\name.tmp", "C:\\path\\..\\name.tmp" },
849 { "C:\\path", "\\name.tmp", "C:\\path\\name.tmp" },
850 { "C:\\path", "name.tmp", "C:\\path\\name.tmp" },
851 { "C:\\path\\", "name.tmp", "C:\\path\\name.tmp" },
852 { "C:\\path", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
853 { "C:\\path\\", "\\name.tmp", "C:\\path\\name.tmp" },
854 { "C:\\path\\", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
855 { "C:\\path\\\\", "\\\\name.tmp", "C:\\path\\\\\\name.tmp" },
856 { "C:\\\\", "\\name.tmp", "C:\\\\name.tmp" },
857 { "C:", "name.tmp", "C:name.tmp" },
858 { "C:", "\\\\name.tmp", "C:\\\\name.tmp" },
859 { NULL }
862 static void test_BuildPath(void)
864 struct buildpath_test *ptr = buildpath_data;
865 BSTR ret, path;
866 HRESULT hr;
867 int i = 0;
869 hr = IFileSystem3_BuildPath(fs3, NULL, NULL, NULL);
870 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
872 ret = (BSTR)0xdeadbeef;
873 hr = IFileSystem3_BuildPath(fs3, NULL, NULL, &ret);
874 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
875 ok(*ret == 0, "got %p\n", ret);
876 SysFreeString(ret);
878 ret = (BSTR)0xdeadbeef;
879 path = bstr_from_str("path");
880 hr = IFileSystem3_BuildPath(fs3, path, NULL, &ret);
881 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
882 ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret));
883 SysFreeString(ret);
884 SysFreeString(path);
886 ret = (BSTR)0xdeadbeef;
887 path = bstr_from_str("path");
888 hr = IFileSystem3_BuildPath(fs3, NULL, path, &ret);
889 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
890 ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret));
891 SysFreeString(ret);
892 SysFreeString(path);
894 while (ptr->path)
896 BSTR name, result;
898 ret = NULL;
899 path = bstr_from_str(ptr->path);
900 name = bstr_from_str(ptr->name);
901 result = bstr_from_str(ptr->result);
902 hr = IFileSystem3_BuildPath(fs3, path, name, &ret);
903 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", i, hr);
904 if (hr == S_OK)
906 ok(!lstrcmpW(ret, result), "%d: got wrong path %s, expected %s\n", i, wine_dbgstr_w(ret),
907 wine_dbgstr_w(result));
908 SysFreeString(ret);
910 SysFreeString(path);
911 SysFreeString(name);
912 SysFreeString(result);
914 i++;
915 ptr++;
919 static void test_GetFolder(void)
921 WCHAR buffW[MAX_PATH];
922 IFolder *folder;
923 HRESULT hr;
924 BSTR str;
926 folder = (void*)0xdeadbeef;
927 hr = IFileSystem3_GetFolder(fs3, NULL, &folder);
928 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
929 ok(folder == NULL, "got %p\n", folder);
931 hr = IFileSystem3_GetFolder(fs3, NULL, NULL);
932 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
934 /* something that doesn't exist */
935 str = SysAllocString(L"dummy");
937 hr = IFileSystem3_GetFolder(fs3, str, NULL);
938 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
940 folder = (void*)0xdeadbeef;
941 hr = IFileSystem3_GetFolder(fs3, str, &folder);
942 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
943 ok(folder == NULL, "got %p\n", folder);
944 SysFreeString(str);
946 GetWindowsDirectoryW(buffW, MAX_PATH);
947 str = SysAllocString(buffW);
948 hr = IFileSystem3_GetFolder(fs3, str, &folder);
949 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
950 SysFreeString(str);
951 test_provideclassinfo(folder, &CLSID_Folder);
952 IFolder_Release(folder);
955 static void _test_clone(IEnumVARIANT *enumvar, BOOL position_inherited, LONG count, int line)
957 HRESULT hr;
958 IEnumVARIANT *clone;
959 ULONG fetched;
960 VARIANT var, var2;
962 hr = IEnumVARIANT_Reset(enumvar);
963 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
965 VariantInit(&var);
966 fetched = -1;
967 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
968 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
969 ok(fetched == 1, "%d: unexpected value %lu.\n", line, fetched);
971 /* clone enumerator */
972 hr = IEnumVARIANT_Clone(enumvar, &clone);
973 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
974 ok(clone != enumvar, "%d: got %p, %p\n", line, enumvar, clone);
976 /* check if clone inherits position */
977 VariantInit(&var2);
978 fetched = -1;
979 hr = IEnumVARIANT_Next(clone, 1, &var2, &fetched);
980 if (position_inherited && count == 1)
982 ok(hr == S_FALSE, "%d: Unexpected hr %#lx.\n", line, hr);
983 ok(!fetched, "%d: unexpected value %lu.\n", line, fetched);
985 else
987 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
988 ok(fetched == 1, "%d: unexpected value %lu.\n", line, fetched);
989 if (!position_inherited)
990 todo_wine ok(V_DISPATCH(&var) == V_DISPATCH(&var2), "%d: values don't match\n", line);
991 else
993 fetched = -1;
994 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
995 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
996 ok(fetched == 1, "%d: unexpected value %lu.\n", line, fetched);
997 todo_wine ok(V_DISPATCH(&var) == V_DISPATCH(&var2), "%d: values don't match\n", line);
1001 VariantClear(&var2);
1002 VariantClear(&var);
1003 IEnumVARIANT_Release(clone);
1005 hr = IEnumVARIANT_Reset(enumvar);
1006 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
1008 #define test_clone(a, b, c) _test_clone(a, b, c, __LINE__)
1010 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1011 static void test_FolderCollection(void)
1013 static const WCHAR aW[] = L"\\a";
1014 static const WCHAR bW[] = L"\\b";
1015 static const WCHAR cW[] = L"\\c";
1016 IFolderCollection *folders;
1017 WCHAR buffW[MAX_PATH], pathW[MAX_PATH];
1018 IEnumVARIANT *enumvar;
1019 LONG count, ref, ref2;
1020 IUnknown *unk, *unk2;
1021 IFolder *folder;
1022 ULONG fetched;
1023 VARIANT var, var2[2];
1024 HRESULT hr;
1025 BSTR str;
1026 int found_a = 0, found_b = 0, found_c = 0;
1027 unsigned int i;
1029 get_temp_path(L"foo", buffW);
1030 CreateDirectoryW(buffW, NULL);
1032 str = SysAllocString(buffW);
1033 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1035 SysFreeString(str);
1037 hr = IFolder_get_SubFolders(folder, NULL);
1038 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1040 hr = IFolder_get_Path(folder, NULL);
1041 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1043 hr = IFolder_get_Path(folder, &str);
1044 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1045 ok(!lstrcmpiW(buffW, str), "got %s, expected %s\n", wine_dbgstr_w(str), wine_dbgstr_w(buffW));
1046 SysFreeString(str);
1048 lstrcpyW(pathW, buffW);
1049 lstrcatW(pathW, aW);
1050 CreateDirectoryW(pathW, NULL);
1052 lstrcpyW(pathW, buffW);
1053 lstrcatW(pathW, bW);
1054 CreateDirectoryW(pathW, NULL);
1056 hr = IFolder_get_SubFolders(folder, &folders);
1057 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1058 test_provideclassinfo(folders, &CLSID_Folders);
1059 IFolder_Release(folder);
1061 count = 0;
1062 hr = IFolderCollection_get_Count(folders, &count);
1063 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1064 ok(count == 2, "Unexpected value %lu.\n", count);
1066 lstrcpyW(pathW, buffW);
1067 lstrcatW(pathW, cW);
1068 CreateDirectoryW(pathW, NULL);
1070 /* every time property is requested it scans directory */
1071 count = 0;
1072 hr = IFolderCollection_get_Count(folders, &count);
1073 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1074 ok(count == 3, "Unexpected value %lu.\n", count);
1076 hr = IFolderCollection_get__NewEnum(folders, NULL);
1077 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1079 hr = IFolderCollection_QueryInterface(folders, &IID_IEnumVARIANT, (void**)&unk);
1080 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1082 /* NewEnum creates new instance each time it's called */
1083 ref = GET_REFCOUNT(folders);
1085 unk = NULL;
1086 hr = IFolderCollection_get__NewEnum(folders, &unk);
1087 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1089 ref2 = GET_REFCOUNT(folders);
1090 ok(ref2 == ref + 1, "Unexpected value %ld, %ld.\n", ref2, ref);
1092 unk2 = NULL;
1093 hr = IFolderCollection_get__NewEnum(folders, &unk2);
1094 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1095 ok(unk != unk2, "got %p, %p\n", unk2, unk);
1096 IUnknown_Release(unk2);
1098 /* now get IEnumVARIANT */
1099 ref = GET_REFCOUNT(folders);
1100 hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&enumvar);
1101 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1102 ref2 = GET_REFCOUNT(folders);
1103 ok(ref2 == ref, "Unexpected value %ld, %ld.\n", ref2, ref);
1105 test_clone(enumvar, FALSE, count);
1107 for (i = 0; i < 3; i++)
1109 VariantInit(&var);
1110 fetched = 0;
1111 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1112 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", i, hr);
1113 ok(fetched == 1, "%d: unexpected value %lu.\n", i, fetched);
1114 ok(V_VT(&var) == VT_DISPATCH, "%d: got type %d\n", i, V_VT(&var));
1116 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IFolder, (void**)&folder);
1117 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1119 str = NULL;
1120 hr = IFolder_get_Name(folder, &str);
1121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1122 if (!lstrcmpW(str, aW + 1))
1123 found_a++;
1124 else if (!lstrcmpW(str, bW + 1))
1125 found_b++;
1126 else if (!lstrcmpW(str, cW + 1))
1127 found_c++;
1128 else
1129 ok(0, "unexpected folder %s was found\n", wine_dbgstr_w(str));
1130 SysFreeString(str);
1132 IFolder_Release(folder);
1133 VariantClear(&var);
1136 ok(found_a == 1 && found_b == 1 && found_c == 1,
1137 "each folder should be found 1 time instead of %d/%d/%d\n",
1138 found_a, found_b, found_c);
1140 VariantInit(&var);
1141 fetched = -1;
1142 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1143 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1144 ok(!fetched, "Unexpected value %lu.\n", fetched);
1146 hr = IEnumVARIANT_Reset(enumvar);
1147 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1148 hr = IEnumVARIANT_Skip(enumvar, 2);
1149 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1150 hr = IEnumVARIANT_Skip(enumvar, 0);
1151 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1153 VariantInit(&var2[0]);
1154 VariantInit(&var2[1]);
1155 fetched = -1;
1156 hr = IEnumVARIANT_Next(enumvar, 0, var2, &fetched);
1157 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1158 ok(!fetched, "Unexpected value %lu.\n", fetched);
1159 fetched = -1;
1160 hr = IEnumVARIANT_Next(enumvar, 2, var2, &fetched);
1161 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1162 ok(fetched == 1, "Unexpected value %lu.\n", fetched);
1163 ok(V_VT(&var2[0]) == VT_DISPATCH, "got type %d\n", V_VT(&var2[0]));
1164 VariantClear(&var2[0]);
1165 VariantClear(&var2[1]);
1167 IEnumVARIANT_Release(enumvar);
1168 IUnknown_Release(unk);
1170 lstrcpyW(pathW, buffW);
1171 lstrcatW(pathW, aW);
1172 RemoveDirectoryW(pathW);
1173 lstrcpyW(pathW, buffW);
1174 lstrcatW(pathW, bW);
1175 RemoveDirectoryW(pathW);
1176 lstrcpyW(pathW, buffW);
1177 lstrcatW(pathW, cW);
1178 RemoveDirectoryW(pathW);
1179 RemoveDirectoryW(buffW);
1181 IFolderCollection_Release(folders);
1184 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1185 static void test_FileCollection(void)
1187 static const WCHAR aW[] = L"\\a";
1188 static const WCHAR bW[] = L"\\b";
1189 static const WCHAR cW[] = L"\\c";
1190 WCHAR buffW[MAX_PATH], pathW[MAX_PATH];
1191 IFolder *folder;
1192 IFileCollection *files;
1193 IFile *file;
1194 IEnumVARIANT *enumvar;
1195 LONG count, ref, ref2;
1196 IUnknown *unk, *unk2;
1197 ULONG fetched;
1198 VARIANT var, var2[2];
1199 HRESULT hr;
1200 BSTR str;
1201 HANDLE file_a, file_b, file_c;
1202 int found_a = 0, found_b = 0, found_c = 0;
1203 unsigned int i;
1205 get_temp_path(L"\\foo", buffW);
1206 CreateDirectoryW(buffW, NULL);
1208 str = SysAllocString(buffW);
1209 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1210 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1211 SysFreeString(str);
1213 hr = IFolder_get_Files(folder, NULL);
1214 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1216 lstrcpyW(pathW, buffW);
1217 lstrcatW(pathW, aW);
1218 file_a = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1219 FILE_FLAG_DELETE_ON_CLOSE, 0);
1220 lstrcpyW(pathW, buffW);
1221 lstrcatW(pathW, bW);
1222 file_b = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1223 FILE_FLAG_DELETE_ON_CLOSE, 0);
1225 hr = IFolder_get_Files(folder, &files);
1226 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1227 test_provideclassinfo(files, &CLSID_Files);
1228 IFolder_Release(folder);
1230 count = 0;
1231 hr = IFileCollection_get_Count(files, &count);
1232 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1233 ok(count == 2, "Unexpected value %lu.\n", count);
1235 lstrcpyW(pathW, buffW);
1236 lstrcatW(pathW, cW);
1237 file_c = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1238 FILE_FLAG_DELETE_ON_CLOSE, 0);
1240 /* every time property is requested it scans directory */
1241 count = 0;
1242 hr = IFileCollection_get_Count(files, &count);
1243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1244 ok(count == 3, "Unexpected value %lu.\n", count);
1246 hr = IFileCollection_get__NewEnum(files, NULL);
1247 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1249 hr = IFileCollection_QueryInterface(files, &IID_IEnumVARIANT, (void**)&unk);
1250 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1252 /* NewEnum creates new instance each time it's called */
1253 ref = GET_REFCOUNT(files);
1255 unk = NULL;
1256 hr = IFileCollection_get__NewEnum(files, &unk);
1257 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1259 ref2 = GET_REFCOUNT(files);
1260 ok(ref2 == ref + 1, "Unexpected value %ld, %ld.\n", ref2, ref);
1262 unk2 = NULL;
1263 hr = IFileCollection_get__NewEnum(files, &unk2);
1264 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1265 ok(unk != unk2, "got %p, %p\n", unk2, unk);
1266 IUnknown_Release(unk2);
1268 /* now get IEnumVARIANT */
1269 ref = GET_REFCOUNT(files);
1270 hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&enumvar);
1271 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1272 ref2 = GET_REFCOUNT(files);
1273 ok(ref2 == ref, "Unexpected value %ld, %ld.\n", ref2, ref);
1275 test_clone(enumvar, FALSE, count);
1277 for (i = 0; i < 3; i++)
1279 VariantInit(&var);
1280 fetched = 0;
1281 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1282 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", i, hr);
1283 ok(fetched == 1, "%d: unexpected value %lu.\n", i, fetched);
1284 ok(V_VT(&var) == VT_DISPATCH, "%d: got type %d\n", i, V_VT(&var));
1286 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IFile, (void **)&file);
1287 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1288 test_provideclassinfo(file, &CLSID_File);
1290 str = NULL;
1291 hr = IFile_get_Name(file, &str);
1292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1293 if (!lstrcmpW(str, aW + 1))
1294 found_a++;
1295 else if (!lstrcmpW(str, bW + 1))
1296 found_b++;
1297 else if (!lstrcmpW(str, cW + 1))
1298 found_c++;
1299 else
1300 ok(0, "unexpected file %s was found\n", wine_dbgstr_w(str));
1301 SysFreeString(str);
1303 IFile_Release(file);
1304 VariantClear(&var);
1307 ok(found_a == 1 && found_b == 1 && found_c == 1,
1308 "each file should be found 1 time instead of %d/%d/%d\n",
1309 found_a, found_b, found_c);
1311 VariantInit(&var);
1312 fetched = -1;
1313 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1314 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1315 ok(!fetched, "Unexpected value %lu.\n", fetched);
1317 hr = IEnumVARIANT_Reset(enumvar);
1318 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1319 hr = IEnumVARIANT_Skip(enumvar, 2);
1320 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1321 hr = IEnumVARIANT_Skip(enumvar, 0);
1322 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1324 VariantInit(&var2[0]);
1325 VariantInit(&var2[1]);
1326 fetched = 1;
1327 hr = IEnumVARIANT_Next(enumvar, 0, var2, &fetched);
1328 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1329 ok(!fetched, "Unexpected value %lu.\n", fetched);
1330 fetched = 0;
1331 hr = IEnumVARIANT_Next(enumvar, 2, var2, &fetched);
1332 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1333 ok(fetched == 1, "Unexpected value %lu.\n", fetched);
1334 ok(V_VT(&var2[0]) == VT_DISPATCH, "got type %d\n", V_VT(&var2[0]));
1335 VariantClear(&var2[0]);
1336 VariantClear(&var2[1]);
1338 IEnumVARIANT_Release(enumvar);
1339 IUnknown_Release(unk);
1341 CloseHandle(file_a);
1342 CloseHandle(file_b);
1343 CloseHandle(file_c);
1344 RemoveDirectoryW(buffW);
1346 IFileCollection_Release(files);
1349 static void test_DriveCollection(void)
1351 IDriveCollection *drives;
1352 IEnumVARIANT *enumvar;
1353 ULONG fetched;
1354 VARIANT var;
1355 HRESULT hr;
1356 LONG count;
1358 hr = IFileSystem3_get_Drives(fs3, &drives);
1359 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1361 test_provideclassinfo(drives, &CLSID_Drives);
1363 hr = IDriveCollection_get__NewEnum(drives, (IUnknown**)&enumvar);
1364 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1366 hr = IDriveCollection_get_Count(drives, NULL);
1367 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1369 count = 0;
1370 hr = IDriveCollection_get_Count(drives, &count);
1371 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1372 ok(count > 0, "Unexpected value %ld.\n", count);
1374 V_VT(&var) = VT_EMPTY;
1375 fetched = 1;
1376 hr = IEnumVARIANT_Next(enumvar, 0, &var, &fetched);
1377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1378 ok(!fetched, "Unexpected value %lu.\n", fetched);
1380 hr = IEnumVARIANT_Skip(enumvar, 0);
1381 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1383 hr = IEnumVARIANT_Skip(enumvar, count);
1384 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1386 hr = IEnumVARIANT_Skip(enumvar, 1);
1387 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1389 test_clone(enumvar, TRUE, count);
1391 while (IEnumVARIANT_Next(enumvar, 1, &var, &fetched) == S_OK) {
1392 IDrive *drive = (IDrive*)V_DISPATCH(&var);
1393 DriveTypeConst type;
1394 BSTR str;
1396 hr = IDrive_get_DriveType(drive, &type);
1397 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1399 hr = IDrive_get_DriveLetter(drive, NULL);
1400 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1402 hr = IDrive_get_DriveLetter(drive, &str);
1403 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1404 ok(SysStringLen(str) == 1, "got string %s\n", wine_dbgstr_w(str));
1405 SysFreeString(str);
1407 hr = IDrive_get_IsReady(drive, NULL);
1408 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1410 hr = IDrive_get_TotalSize(drive, NULL);
1411 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1413 hr = IDrive_get_AvailableSpace(drive, NULL);
1414 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1416 hr = IDrive_get_FreeSpace(drive, NULL);
1417 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1419 if (type == Fixed) {
1420 VARIANT_BOOL ready = VARIANT_FALSE;
1421 VARIANT size;
1423 hr = IDrive_get_IsReady(drive, &ready);
1424 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1425 ok(ready == VARIANT_TRUE, "got %x\n", ready);
1427 if (ready != VARIANT_TRUE) {
1428 hr = IDrive_get_DriveLetter(drive, &str);
1429 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1431 skip("Drive %s is not ready, skipping some tests\n", wine_dbgstr_w(str));
1433 VariantClear(&var);
1434 SysFreeString(str);
1435 continue;
1438 V_VT(&size) = VT_EMPTY;
1439 hr = IDrive_get_TotalSize(drive, &size);
1440 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1441 ok(V_VT(&size) == VT_R8 || V_VT(&size) == VT_I4, "got %d\n", V_VT(&size));
1442 if (V_VT(&size) == VT_R8)
1443 ok(V_R8(&size) > 0, "got %f\n", V_R8(&size));
1444 else
1445 ok(V_I4(&size) > 0, "got %ld\n", V_I4(&size));
1447 V_VT(&size) = VT_EMPTY;
1448 hr = IDrive_get_AvailableSpace(drive, &size);
1449 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1450 ok(V_VT(&size) == VT_R8 || V_VT(&size) == VT_I4, "got %d\n", V_VT(&size));
1451 if (V_VT(&size) == VT_R8)
1452 ok(V_R8(&size) > (double)INT_MAX, "got %f\n", V_R8(&size));
1453 else
1454 ok(V_I4(&size) > 0, "got %ld\n", V_I4(&size));
1456 V_VT(&size) = VT_EMPTY;
1457 hr = IDrive_get_FreeSpace(drive, &size);
1458 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1459 ok(V_VT(&size) == VT_R8 || V_VT(&size) == VT_I4, "got %d\n", V_VT(&size));
1460 if (V_VT(&size) == VT_R8)
1461 ok(V_R8(&size) > 0, "got %f\n", V_R8(&size));
1462 else
1463 ok(V_I4(&size) > 0, "got %ld\n", V_I4(&size));
1465 VariantClear(&var);
1468 IEnumVARIANT_Release(enumvar);
1469 IDriveCollection_Release(drives);
1472 static void get_temp_filepath(const WCHAR *filename, WCHAR *path, WCHAR *dir)
1474 GetTempPathW(MAX_PATH, path);
1475 lstrcatW(path, L"scrrun\\");
1476 lstrcpyW(dir, path);
1477 lstrcatW(path, filename);
1480 static void test_CreateTextFile(void)
1482 WCHAR pathW[MAX_PATH], dirW[MAX_PATH], buffW[10];
1483 ITextStream *stream;
1484 BSTR nameW, str;
1485 HANDLE file;
1486 HRESULT hr;
1487 BOOL ret;
1488 DWORD r;
1490 get_temp_filepath(testfileW, pathW, dirW);
1492 /* dir doesn't exist */
1493 nameW = SysAllocString(pathW);
1494 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1495 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
1497 ret = CreateDirectoryW(dirW, NULL);
1498 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1500 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1501 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1503 test_provideclassinfo(stream, &CLSID_TextStream);
1505 hr = ITextStream_Read(stream, 1, &str);
1506 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
1508 hr = ITextStream_Close(stream);
1509 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1511 hr = ITextStream_Read(stream, 1, &str);
1512 ok(hr == CTL_E_BADFILEMODE || hr == E_VAR_NOT_SET, "Unexpected hr %#lx.\n", hr);
1514 hr = ITextStream_Close(stream);
1515 ok(hr == S_FALSE || hr == E_VAR_NOT_SET, "Unexpected hr %#lx.\n", hr);
1517 ITextStream_Release(stream);
1519 /* check it's created */
1520 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1521 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1522 CloseHandle(file);
1524 /* try to create again with no-overwrite mode */
1525 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1526 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
1528 /* now overwrite */
1529 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
1530 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1531 ITextStream_Release(stream);
1533 /* overwrite in Unicode mode, check for BOM */
1534 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_TRUE, &stream);
1535 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1536 ITextStream_Release(stream);
1538 /* check contents */
1539 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1540 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1541 r = 0;
1542 ret = ReadFile(file, buffW, sizeof(buffW), &r, NULL);
1543 ok(ret && r == 2, "Read %ld, got %d, error %ld.\n", r, ret, GetLastError());
1545 ok( buffW[0] == 0xfeff, "got %04x\n", buffW[0] );
1546 CloseHandle(file);
1548 DeleteFileW(nameW);
1549 RemoveDirectoryW(dirW);
1550 SysFreeString(nameW);
1553 static void test_FolderCreateTextFile(void)
1555 WCHAR pathW[MAX_PATH], dirW[MAX_PATH], buffW[10], buff2W[10];
1556 ITextStream *stream;
1557 BSTR nameW, str;
1558 HANDLE file;
1559 IFolder *folder;
1560 HRESULT hr;
1561 BOOL ret;
1562 DWORD r;
1564 get_temp_filepath(testfileW, pathW, dirW);
1565 nameW = SysAllocString(L"foo.txt");
1566 lstrcpyW(pathW, dirW);
1567 lstrcatW(pathW, nameW);
1569 ret = CreateDirectoryW(dirW, NULL);
1570 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1572 str = SysAllocString(dirW);
1573 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1574 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1575 SysFreeString(str);
1577 hr = IFolder_CreateTextFile(folder, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1578 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1580 test_provideclassinfo(stream, &CLSID_TextStream);
1582 hr = ITextStream_Read(stream, 1, &str);
1583 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
1585 hr = ITextStream_Close(stream);
1586 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1588 hr = ITextStream_Read(stream, 1, &str);
1589 ok(hr == CTL_E_BADFILEMODE || hr == E_VAR_NOT_SET, "Unexpected hr %#lx.\n", hr);
1591 hr = ITextStream_Close(stream);
1592 ok(hr == S_FALSE || hr == E_VAR_NOT_SET, "Unexpected hr %#lx.\n", hr);
1594 ITextStream_Release(stream);
1596 /* check it's created */
1597 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1598 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1599 CloseHandle(file);
1601 /* try to create again with no-overwrite mode */
1602 hr = IFolder_CreateTextFile(folder, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1603 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
1605 /* now overwrite */
1606 hr = IFolder_CreateTextFile(folder, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
1607 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1608 ITextStream_Release(stream);
1610 /* overwrite in Unicode mode, check for BOM */
1611 hr = IFolder_CreateTextFile(folder, nameW, VARIANT_TRUE, VARIANT_TRUE, &stream);
1612 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1613 ITextStream_Release(stream);
1615 /* check contents */
1616 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1617 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1618 r = 0;
1619 ret = ReadFile(file, buffW, sizeof(buffW), &r, NULL);
1620 ok(ret && r == 2, "Read %ld, got %d, error %ld.\n", r, ret, GetLastError());
1621 buffW[r/sizeof(WCHAR)] = 0;
1623 buff2W[0] = 0xfeff;
1624 buff2W[1] = 0;
1625 ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
1626 CloseHandle(file);
1628 DeleteFileW(pathW);
1629 RemoveDirectoryW(dirW);
1630 SysFreeString(nameW);
1633 static void test_WriteLine(void)
1635 WCHAR pathW[MAX_PATH], dirW[MAX_PATH];
1636 WCHAR buffW[MAX_PATH], buff2W[MAX_PATH];
1637 char buffA[MAX_PATH];
1638 ITextStream *stream;
1639 DWORD r, len;
1640 HANDLE file;
1641 BSTR nameW;
1642 HRESULT hr;
1643 BOOL ret;
1645 get_temp_filepath(testfileW, pathW, dirW);
1647 ret = CreateDirectoryW(dirW, NULL);
1648 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1650 /* create as ASCII file first */
1651 nameW = SysAllocString(pathW);
1652 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1653 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1655 hr = ITextStream_WriteLine(stream, nameW);
1656 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1657 ITextStream_Release(stream);
1659 /* check contents */
1660 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1661 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1662 r = 0;
1663 ret = ReadFile(file, buffA, sizeof(buffA), &r, NULL);
1664 ok(ret && r, "Read %ld, got %d, error %ld.\n", r, ret, GetLastError());
1666 len = MultiByteToWideChar(CP_ACP, 0, buffA, r, buffW, ARRAY_SIZE(buffW));
1667 buffW[len] = 0;
1668 lstrcpyW(buff2W, nameW);
1669 lstrcatW(buff2W, L"\r\n");
1670 ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
1671 CloseHandle(file);
1672 DeleteFileW(nameW);
1674 /* same for unicode file */
1675 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_TRUE, &stream);
1676 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1678 hr = ITextStream_WriteLine(stream, nameW);
1679 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1680 ITextStream_Release(stream);
1682 /* check contents */
1683 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1684 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1685 r = 0;
1686 ret = ReadFile(file, buffW, sizeof(buffW), &r, NULL);
1687 ok(ret && r, "Read %ld, got %d, error %ld.\n", r, ret, GetLastError());
1688 buffW[r/sizeof(WCHAR)] = 0;
1690 buff2W[0] = 0xfeff;
1691 buff2W[1] = 0;
1692 lstrcatW(buff2W, nameW);
1693 lstrcatW(buff2W, L"\r\n");
1694 ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
1695 CloseHandle(file);
1696 DeleteFileW(nameW);
1698 RemoveDirectoryW(dirW);
1699 SysFreeString(nameW);
1702 static void test_ReadAll(void)
1704 static const WCHAR firstlineW[] = L"first";
1705 static const WCHAR secondlineW[] = L"second";
1706 static const WCHAR aW[] = L"A";
1707 WCHAR pathW[MAX_PATH], dirW[MAX_PATH], buffW[500];
1708 char buffA[MAX_PATH];
1709 ITextStream *stream;
1710 BSTR nameW;
1711 HRESULT hr;
1712 BOOL ret;
1713 BSTR str;
1715 get_temp_filepath(testfileW, pathW, dirW);
1717 ret = CreateDirectoryW(dirW, NULL);
1718 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1720 /* Unicode file -> read with ascii stream */
1721 nameW = SysAllocString(pathW);
1722 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_TRUE, &stream);
1723 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1725 str = SysAllocString(firstlineW);
1726 hr = ITextStream_WriteLine(stream, str);
1727 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1728 SysFreeString(str);
1730 str = SysAllocString(secondlineW);
1731 hr = ITextStream_WriteLine(stream, str);
1732 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1733 SysFreeString(str);
1735 hr = ITextStream_ReadAll(stream, NULL);
1736 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1738 str = (void*)0xdeadbeef;
1739 hr = ITextStream_ReadAll(stream, &str);
1740 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
1741 ok(str == NULL || broken(str == (void*)0xdeadbeef) /* win2k */, "got %p\n", str);
1743 ITextStream_Release(stream);
1745 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
1746 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1748 hr = ITextStream_ReadAll(stream, NULL);
1749 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1751 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1752 str = NULL;
1753 hr = ITextStream_ReadAll(stream, &str);
1754 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1755 buffW[0] = 0;
1756 lstrcpyA(buffA, utf16bom);
1757 lstrcatA(buffA, "first");
1758 MultiByteToWideChar(CP_ACP, 0, buffA, -1, buffW, ARRAY_SIZE(buffW));
1759 ok(str[0] == buffW[0] && str[1] == buffW[1], "got %s, %d\n", wine_dbgstr_w(str), SysStringLen(str));
1760 SysFreeString(str);
1761 ITextStream_Release(stream);
1763 /* Unicode file -> read with unicode stream */
1764 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1765 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1767 lstrcpyW(buffW, firstlineW);
1768 lstrcatW(buffW, L"\r\n");
1769 lstrcatW(buffW, secondlineW);
1770 lstrcatW(buffW, L"\r\n");
1771 str = NULL;
1772 hr = ITextStream_ReadAll(stream, &str);
1773 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1774 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1775 SysFreeString(str);
1777 /* ReadAll one more time */
1778 str = (void*)0xdeadbeef;
1779 hr = ITextStream_ReadAll(stream, &str);
1780 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1781 ok(str == NULL || broken(str == (void*)0xdeadbeef) /* win2k */, "got %p\n", str);
1783 /* ReadLine fails the same way */
1784 str = (void*)0xdeadbeef;
1785 hr = ITextStream_ReadLine(stream, &str);
1786 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1787 ok(str == NULL || broken(str == (void*)0xdeadbeef) /* win2k */, "got %p\n", str);
1788 ITextStream_Release(stream);
1790 /* Open again and skip first line before ReadAll */
1791 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1792 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1794 str = NULL;
1795 hr = ITextStream_ReadLine(stream, &str);
1796 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1797 ok(str != NULL, "got %p\n", str);
1798 ok(!wcscmp(str, firstlineW), "got %s\n", wine_dbgstr_w(str));
1799 SysFreeString(str);
1801 lstrcpyW(buffW, secondlineW);
1802 lstrcatW(buffW, L"\r\n");
1803 str = NULL;
1804 hr = ITextStream_ReadAll(stream, &str);
1805 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1806 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1807 SysFreeString(str);
1808 ITextStream_Release(stream);
1810 /* ASCII file, read with Unicode stream */
1811 /* 1. one byte content, not enough for Unicode read */
1812 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
1813 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1814 str = SysAllocString(aW);
1815 hr = ITextStream_Write(stream, str);
1816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1817 SysFreeString(str);
1818 ITextStream_Release(stream);
1820 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1821 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1823 str = (void*)0xdeadbeef;
1824 hr = ITextStream_ReadAll(stream, &str);
1825 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1826 ok(str == NULL || broken(str == (void*)0xdeadbeef) /* win2k */, "got %p\n", str);
1828 ITextStream_Release(stream);
1830 DeleteFileW(nameW);
1831 RemoveDirectoryW(dirW);
1832 SysFreeString(nameW);
1835 static void test_Read(void)
1837 static const WCHAR firstlineW[] = L"first";
1838 static const WCHAR secondlineW[] = L"second";
1839 WCHAR pathW[MAX_PATH], dirW[MAX_PATH], buffW[500];
1840 char buffA[MAX_PATH];
1841 ITextStream *stream;
1842 BSTR nameW;
1843 HRESULT hr;
1844 BOOL ret;
1845 BSTR str;
1847 get_temp_filepath(testfileW, pathW, dirW);
1849 ret = CreateDirectoryW(dirW, NULL);
1850 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1852 /* Unicode file -> read with ascii stream */
1853 nameW = SysAllocString(pathW);
1854 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_TRUE, &stream);
1855 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1857 str = SysAllocString(firstlineW);
1858 hr = ITextStream_WriteLine(stream, str);
1859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1860 SysFreeString(str);
1862 str = SysAllocString(secondlineW);
1863 hr = ITextStream_WriteLine(stream, str);
1864 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1865 SysFreeString(str);
1867 hr = ITextStream_Read(stream, 0, NULL);
1868 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1870 hr = ITextStream_Read(stream, 1, NULL);
1871 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1873 hr = ITextStream_Read(stream, -1, NULL);
1874 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1876 str = (void*)0xdeadbeef;
1877 hr = ITextStream_Read(stream, 1, &str);
1878 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
1879 ok(str == NULL, "got %p\n", str);
1881 ITextStream_Release(stream);
1883 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
1884 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1886 hr = ITextStream_Read(stream, 1, NULL);
1887 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1889 str = (void*)0xdeadbeef;
1890 hr = ITextStream_Read(stream, -1, &str);
1891 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1892 ok(str == NULL, "got %p\n", str);
1894 str = (void*)0xdeadbeef;
1895 hr = ITextStream_Read(stream, 0, &str);
1896 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1897 ok(str == NULL, "got %p\n", str);
1899 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1900 str = NULL;
1901 hr = ITextStream_Read(stream, 2, &str);
1902 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1904 buffW[0] = 0;
1905 lstrcpyA(buffA, utf16bom);
1906 lstrcatA(buffA, "first");
1907 MultiByteToWideChar(CP_ACP, 0, buffA, -1, buffW, ARRAY_SIZE(buffW));
1908 ok(str[0] == buffW[0] && str[1] == buffW[1], "got %s, expected %s, %d\n", wine_dbgstr_w(str), wine_dbgstr_w(buffW), SysStringLen(str));
1909 ok(SysStringLen(str) == 2, "got %d\n", SysStringLen(str));
1910 SysFreeString(str);
1911 ITextStream_Release(stream);
1913 /* Unicode file -> read with unicode stream */
1914 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1915 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1917 lstrcpyW(buffW, firstlineW);
1918 lstrcatW(buffW, L"\r\n");
1919 lstrcatW(buffW, secondlineW);
1920 lstrcatW(buffW, L"\r\n");
1921 str = NULL;
1922 hr = ITextStream_Read(stream, 500, &str);
1923 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1924 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1925 SysFreeString(str);
1927 /* ReadAll one more time */
1928 str = (void*)0xdeadbeef;
1929 hr = ITextStream_Read(stream, 10, &str);
1930 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1931 ok(str == NULL, "got %p\n", str);
1933 /* ReadLine fails the same way */
1934 str = (void*)0xdeadbeef;
1935 hr = ITextStream_ReadLine(stream, &str);
1936 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1937 ok(str == NULL || broken(str == (void*)0xdeadbeef), "got %p\n", str);
1938 ITextStream_Release(stream);
1940 /* Open again and skip first line before ReadAll */
1941 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1942 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1944 str = NULL;
1945 hr = ITextStream_ReadLine(stream, &str);
1946 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1947 ok(str != NULL, "got %p\n", str);
1948 SysFreeString(str);
1950 lstrcpyW(buffW, secondlineW);
1951 lstrcatW(buffW, L"\r\n");
1952 str = NULL;
1953 hr = ITextStream_Read(stream, 100, &str);
1954 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1955 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1956 SysFreeString(str);
1957 ITextStream_Release(stream);
1959 /* default read will use Unicode */
1960 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateUseDefault, &stream);
1961 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1963 lstrcpyW(buffW, firstlineW);
1964 lstrcatW(buffW, L"\r\n");
1965 lstrcatW(buffW, secondlineW);
1966 lstrcatW(buffW, L"\r\n");
1967 str = NULL;
1968 hr = ITextStream_Read(stream, 500, &str);
1969 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
1970 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1971 SysFreeString(str);
1973 ITextStream_Release(stream);
1975 /* default append will use Unicode */
1976 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForAppending, VARIANT_FALSE, TristateUseDefault, &stream);
1977 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1979 str = SysAllocString(L"123");
1980 hr = ITextStream_Write(stream, str);
1981 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1982 SysFreeString(str);
1984 ITextStream_Release(stream);
1986 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1987 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1989 lstrcatW(buffW, L"123");
1990 str = NULL;
1991 hr = ITextStream_Read(stream, 500, &str);
1992 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
1993 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1994 SysFreeString(str);
1996 ITextStream_Release(stream);
1998 /* default write will use ASCII */
1999 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForWriting, VARIANT_FALSE, TristateUseDefault, &stream);
2000 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2002 str = SysAllocString(L"123");
2003 hr = ITextStream_Write(stream, str);
2004 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2005 SysFreeString(str);
2007 ITextStream_Release(stream);
2009 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
2010 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2012 str = (void*)0xdeadbeef;
2013 hr = ITextStream_Read(stream, 500, &str);
2014 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2015 ok(!wcscmp(str, L"123"), "got %s\n", wine_dbgstr_w(str));
2017 ITextStream_Release(stream);
2018 /* ASCII file, read with default stream */
2019 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
2020 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2021 str = SysAllocString(L"test");
2022 hr = ITextStream_Write(stream, str);
2023 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2024 SysFreeString(str);
2025 ITextStream_Release(stream);
2027 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateUseDefault, &stream);
2028 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2030 str = (void*)0xdeadbeef;
2031 hr = ITextStream_Read(stream, 500, &str);
2032 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2033 ok(!wcscmp(str, L"test"), "got %s\n", wine_dbgstr_w(str));
2035 ITextStream_Release(stream);
2037 /* default append will use Unicode */
2038 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForAppending, VARIANT_FALSE, TristateUseDefault, &stream);
2039 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2041 str = SysAllocString(L"123");
2042 hr = ITextStream_Write(stream, str);
2043 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2044 SysFreeString(str);
2046 ITextStream_Release(stream);
2048 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
2049 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2051 str = NULL;
2052 hr = ITextStream_Read(stream, 500, &str);
2053 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2054 ok(!lstrcmpW(L"test123", str), "got %s\n", wine_dbgstr_w(str));
2055 SysFreeString(str);
2057 ITextStream_Release(stream);
2059 /* default write will use ASCII as well */
2060 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForWriting, VARIANT_FALSE, TristateUseDefault, &stream);
2061 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2063 str = SysAllocString(L"test string");
2064 hr = ITextStream_Write(stream, str);
2065 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2066 SysFreeString(str);
2068 ITextStream_Release(stream);
2070 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
2071 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2073 str = (void*)0xdeadbeef;
2074 hr = ITextStream_Read(stream, 500, &str);
2075 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2076 ok(!wcscmp(str, L"test string"), "got %s\n", wine_dbgstr_w(str));
2078 ITextStream_Release(stream);
2080 /* ASCII file, read with Unicode stream */
2081 /* 1. one byte content, not enough for Unicode read */
2082 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
2083 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2084 str = SysAllocString(L"A");
2085 hr = ITextStream_Write(stream, str);
2086 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2087 SysFreeString(str);
2088 ITextStream_Release(stream);
2090 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
2091 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2093 str = (void*)0xdeadbeef;
2094 hr = ITextStream_Read(stream, 500, &str);
2095 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
2096 ok(str == NULL, "got %p\n", str);
2098 ITextStream_Release(stream);
2100 /* ASCII file, read with Unicode stream */
2101 /* 3. one byte content, 2 are interpreted as a character, 3rd is lost */
2102 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
2103 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2104 str = SysAllocString(L"abc");
2105 hr = ITextStream_Write(stream, str);
2106 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2107 SysFreeString(str);
2108 ITextStream_Release(stream);
2110 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
2111 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2113 str = NULL;
2114 hr = ITextStream_Read(stream, 500, &str);
2115 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2116 ok(SysStringLen(str) == 1, "len = %u\n", SysStringLen(str));
2117 SysFreeString(str);
2119 str = (void*)0xdeadbeef;
2120 hr = ITextStream_Read(stream, 500, &str);
2121 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
2122 ok(str == NULL, "got %p\n", str);
2124 ITextStream_Release(stream);
2126 DeleteFileW(nameW);
2127 RemoveDirectoryW(dirW);
2128 SysFreeString(nameW);
2131 static void test_ReadLine(void)
2133 WCHAR path[MAX_PATH], dir[MAX_PATH];
2134 ITextStream *stream;
2135 unsigned int i;
2136 HANDLE file;
2137 DWORD size;
2138 HRESULT hr;
2139 BSTR str;
2140 BOOL ret;
2142 const char data[] = "first line\r\nsecond\n\n\rt\r\re \rst\n";
2144 get_temp_filepath(L"test.txt", path, dir);
2146 ret = CreateDirectoryW(dir, NULL);
2147 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
2149 file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2150 FILE_ATTRIBUTE_NORMAL, NULL);
2151 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2153 for (i = 0; i < 1000; i++)
2154 WriteFile(file, data, strlen(data), &size, NULL);
2155 CloseHandle(file);
2157 str = SysAllocString(path);
2158 hr = IFileSystem3_OpenTextFile(fs3, str, ForReading, VARIANT_FALSE, TristateFalse, &stream);
2159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2160 SysFreeString(str);
2162 for (i = 0; i < 1000; i++)
2164 hr = ITextStream_ReadLine(stream, &str);
2165 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2166 ok(!wcscmp(str, L"first line"), "ReadLine returned %s\n", wine_dbgstr_w(str));
2167 SysFreeString(str);
2169 hr = ITextStream_ReadLine(stream, &str);
2170 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2171 ok(!wcscmp(str, L"second"), "ReadLine returned %s\n", wine_dbgstr_w(str));
2172 SysFreeString(str);
2174 hr = ITextStream_ReadLine(stream, &str);
2175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2176 ok(!*str, "ReadLine returned %s\n", wine_dbgstr_w(str));
2177 SysFreeString(str);
2179 hr = ITextStream_ReadLine(stream, &str);
2180 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2181 ok(!wcscmp(str, L"\rt\r\re \rst"), "ReadLine returned %s\n", wine_dbgstr_w(str));
2182 SysFreeString(str);
2185 str = NULL;
2186 hr = ITextStream_ReadLine(stream, &str);
2187 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
2188 ok(!str, "ReadLine returned %s\n", wine_dbgstr_w(str));
2189 SysFreeString(str);
2191 ITextStream_Release(stream);
2193 ret = DeleteFileW(path);
2194 ok(ret, "Unexpected retval %ld.\n", GetLastError());
2196 ret = RemoveDirectoryW(dir);
2197 ok(ret, "Unexpected retval %ld.\n", GetLastError());
2200 struct driveexists_test {
2201 const WCHAR drivespec[10];
2202 const INT drivetype;
2203 const VARIANT_BOOL expected_ret;
2206 /* If 'drivetype' != -1, the first character of 'drivespec' will be replaced
2207 * with the drive letter of a drive of this type. If such a drive does not exist,
2208 * the test will be skipped. */
2209 static const struct driveexists_test driveexiststestdata[] = {
2210 { L"N:\\", DRIVE_NO_ROOT_DIR, VARIANT_FALSE },
2211 { L"R:\\", DRIVE_REMOVABLE, VARIANT_TRUE },
2212 { L"F:\\", DRIVE_FIXED, VARIANT_TRUE },
2213 { L"F:", DRIVE_FIXED, VARIANT_TRUE },
2214 { L"F?", DRIVE_FIXED, VARIANT_FALSE },
2215 { L"F", DRIVE_FIXED, VARIANT_TRUE },
2216 { L"?", -1, VARIANT_FALSE },
2217 { L"" }
2220 static void test_DriveExists(void)
2222 const struct driveexists_test *ptr = driveexiststestdata;
2223 HRESULT hr;
2224 VARIANT_BOOL ret;
2225 BSTR drivespec;
2226 WCHAR root[] = L"?:\\";
2228 hr = IFileSystem3_DriveExists(fs3, NULL, NULL);
2229 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2231 ret = VARIANT_TRUE;
2232 hr = IFileSystem3_DriveExists(fs3, NULL, &ret);
2233 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2234 ok(ret == VARIANT_FALSE, "got %x\n", ret);
2236 drivespec = SysAllocString(root);
2237 hr = IFileSystem3_DriveExists(fs3, drivespec, NULL);
2238 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2239 SysFreeString(drivespec);
2241 for (; *ptr->drivespec; ptr++) {
2242 drivespec = SysAllocString(ptr->drivespec);
2243 if (ptr->drivetype != -1) {
2244 for (root[0] = 'A'; root[0] <= 'Z'; root[0]++)
2245 if (GetDriveTypeW(root) == ptr->drivetype)
2246 break;
2247 if (root[0] > 'Z') {
2248 skip("No drive with type 0x%x found, skipping test %s.\n",
2249 ptr->drivetype, wine_dbgstr_w(ptr->drivespec));
2250 SysFreeString(drivespec);
2251 continue;
2254 /* Test both upper and lower case drive letters. */
2255 drivespec[0] = root[0];
2256 ret = ptr->expected_ret == VARIANT_TRUE ? VARIANT_FALSE : VARIANT_TRUE;
2257 hr = IFileSystem3_DriveExists(fs3, drivespec, &ret);
2258 ok(hr == S_OK, "Unexpected hr %#lx. for drive spec %s (%s)\n",
2259 hr, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec));
2260 ok(ret == ptr->expected_ret, "got %d, expected %d for drive spec %s (%s)\n",
2261 ret, ptr->expected_ret, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec));
2263 drivespec[0] = tolower(root[0]);
2266 ret = ptr->expected_ret == VARIANT_TRUE ? VARIANT_FALSE : VARIANT_TRUE;
2267 hr = IFileSystem3_DriveExists(fs3, drivespec, &ret);
2268 ok(hr == S_OK, "Unexpected hr %#lx. for drive spec %s (%s)\n",
2269 hr, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec));
2270 ok(ret == ptr->expected_ret, "got %d, expected %d for drive spec %s (%s)\n",
2271 ret, ptr->expected_ret, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec));
2273 SysFreeString(drivespec);
2277 struct getdrivename_test {
2278 const WCHAR path[10];
2279 const WCHAR drive[5];
2282 static const struct getdrivename_test getdrivenametestdata[] = {
2283 { L"C:\\1.tst", L"C:" },
2284 { L"O:\\1.tst", L"O:" },
2285 { L"O:", L"O:" },
2286 { L"o:", L"o:" },
2287 { L"OO:" },
2288 { L":" },
2289 { L"O" },
2290 { L"" }
2293 static void test_GetDriveName(void)
2295 const struct getdrivename_test *ptr = getdrivenametestdata;
2296 HRESULT hr;
2297 BSTR name;
2299 hr = IFileSystem3_GetDriveName(fs3, NULL, NULL);
2300 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2302 name = (void*)0xdeadbeef;
2303 hr = IFileSystem3_GetDriveName(fs3, NULL, &name);
2304 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2305 ok(name == NULL, "got %p\n", name);
2307 while (*ptr->path) {
2308 BSTR path = SysAllocString(ptr->path);
2309 name = (void*)0xdeadbeef;
2310 hr = IFileSystem3_GetDriveName(fs3, path, &name);
2311 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2312 if (name)
2313 ok(!lstrcmpW(ptr->drive, name), "got %s, expected %s\n", wine_dbgstr_w(name), wine_dbgstr_w(ptr->drive));
2314 else
2315 ok(!*ptr->drive, "got %s, expected %s\n", wine_dbgstr_w(name), wine_dbgstr_w(ptr->drive));
2316 SysFreeString(path);
2317 SysFreeString(name);
2318 ptr++;
2322 struct getdrive_test {
2323 const WCHAR drivespec[12];
2324 HRESULT res;
2325 const WCHAR driveletter[2];
2328 static void test_GetDrive(void)
2330 HRESULT hr;
2331 IDrive *drive_fixed, *drive;
2332 BSTR dl_fixed, drivespec;
2333 WCHAR root[] = L"?:\\";
2335 drive = (void*)0xdeadbeef;
2336 hr = IFileSystem3_GetDrive(fs3, NULL, NULL);
2337 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2338 ok(drive == (void*)0xdeadbeef, "got %p\n", drive);
2340 for (root[0] = 'A'; root[0] <= 'Z'; root[0]++)
2341 if (GetDriveTypeW(root) == DRIVE_NO_ROOT_DIR)
2342 break;
2344 if (root[0] > 'Z')
2345 skip("All drive letters are occupied, skipping test for nonexisting drive.\n");
2346 else {
2347 drivespec = SysAllocString(root);
2348 drive = (void*)0xdeadbeef;
2349 hr = IFileSystem3_GetDrive(fs3, drivespec, &drive);
2350 ok(hr == CTL_E_DEVICEUNAVAILABLE, "Unexpected hr %#lx.\n", hr);
2351 ok(drive == NULL, "got %p\n", drive);
2352 SysFreeString(drivespec);
2355 drive_fixed = get_fixed_drive();
2356 if (!drive_fixed) {
2357 skip("No fixed drive found, skipping test.\n");
2358 return;
2361 hr = IDrive_get_DriveLetter(drive_fixed, &dl_fixed);
2362 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2364 if (FAILED(hr))
2365 skip("Could not retrieve drive letter of fixed drive, skipping test.\n");
2366 else {
2367 WCHAR dl_upper = toupper(dl_fixed[0]);
2368 WCHAR dl_lower = tolower(dl_fixed[0]);
2369 struct getdrive_test testdata[] = {
2370 { {dl_upper,0}, S_OK, {dl_upper,0} },
2371 { {dl_upper,':',0}, S_OK, {dl_upper,0} },
2372 { {dl_upper,':','\\',0}, S_OK, {dl_upper,0} },
2373 { {dl_lower,':','\\',0}, S_OK, {dl_upper,0} },
2374 { {dl_upper,'\\',0 }, E_INVALIDARG, L""},
2375 { {dl_lower,'\\',0 }, E_INVALIDARG, L""},
2376 { L"$:\\", E_INVALIDARG, L"" },
2377 { L"\\host\\share", E_INVALIDARG, L"" },
2378 { L"host\\share", E_INVALIDARG, L"" },
2379 { L"" },
2381 struct getdrive_test *ptr = &testdata[0];
2383 for (; *ptr->drivespec; ptr++) {
2384 drivespec = SysAllocString(ptr->drivespec);
2385 drive = (void*)0xdeadbeef;
2386 hr = IFileSystem3_GetDrive(fs3, drivespec, &drive);
2387 ok(hr == ptr->res, "Unexpected hr %#lx, expected %#lx for drive spec %s.\n",
2388 hr, ptr->res, wine_dbgstr_w(ptr->drivespec));
2389 ok(!lstrcmpW(ptr->drivespec, drivespec), "GetDrive modified its DriveSpec argument\n");
2390 SysFreeString(drivespec);
2392 if (*ptr->driveletter) {
2393 BSTR driveletter;
2394 hr = IDrive_get_DriveLetter(drive, &driveletter);
2395 ok(hr == S_OK, "Unexpected hr %#lx. for drive spec %s\n", hr, wine_dbgstr_w(ptr->drivespec));
2396 if (SUCCEEDED(hr)) {
2397 ok(!lstrcmpW(ptr->driveletter, driveletter), "got %s, expected %s for drive spec %s\n",
2398 wine_dbgstr_w(driveletter), wine_dbgstr_w(ptr->driveletter),
2399 wine_dbgstr_w(ptr->drivespec));
2400 SysFreeString(driveletter);
2402 test_provideclassinfo(drive, &CLSID_Drive);
2403 IDrive_Release(drive);
2404 } else
2405 ok(drive == NULL, "got %p for drive spec %s\n", drive, wine_dbgstr_w(ptr->drivespec));
2407 SysFreeString(dl_fixed);
2411 static void test_SerialNumber(void)
2413 IDrive *drive;
2414 LONG serial;
2415 HRESULT hr;
2416 BSTR name;
2418 drive = get_fixed_drive();
2419 if (!drive) {
2420 skip("No fixed drive found, skipping test.\n");
2421 return;
2424 hr = IDrive_get_SerialNumber(drive, NULL);
2425 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2427 serial = 0xdeadbeef;
2428 hr = IDrive_get_SerialNumber(drive, &serial);
2429 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2430 ok(serial != 0xdeadbeef, "Unexpected value %#lx.\n", serial);
2432 hr = IDrive_get_FileSystem(drive, NULL);
2433 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2435 name = NULL;
2436 hr = IDrive_get_FileSystem(drive, &name);
2437 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2438 ok(name != NULL, "got %p\n", name);
2439 SysFreeString(name);
2441 hr = IDrive_get_VolumeName(drive, NULL);
2442 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2444 name = NULL;
2445 hr = IDrive_get_VolumeName(drive, &name);
2446 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2447 ok(name != NULL, "got %p\n", name);
2448 SysFreeString(name);
2450 IDrive_Release(drive);
2453 static const struct extension_test {
2454 WCHAR path[20];
2455 WCHAR ext[10];
2456 } extension_tests[] = {
2457 { L"noext", L"" },
2458 { L"n.o.ext", L"ext" },
2459 { L"n.o.eXt", L"eXt" },
2460 { L"" }
2463 static void test_GetExtensionName(void)
2465 BSTR path, ext;
2466 HRESULT hr;
2467 int i;
2469 for (i = 0; i < ARRAY_SIZE(extension_tests); i++) {
2471 path = SysAllocString(extension_tests[i].path);
2472 ext = NULL;
2473 hr = IFileSystem3_GetExtensionName(fs3, path, &ext);
2474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2475 if (*extension_tests[i].ext)
2476 ok(!lstrcmpW(ext, extension_tests[i].ext), "%d: path %s, got %s, expected %s\n", i,
2477 wine_dbgstr_w(path), wine_dbgstr_w(ext), wine_dbgstr_w(extension_tests[i].ext));
2478 else
2479 ok(ext == NULL, "%d: path %s, got %s, expected %s\n", i,
2480 wine_dbgstr_w(path), wine_dbgstr_w(ext), wine_dbgstr_w(extension_tests[i].ext));
2482 SysFreeString(path);
2483 SysFreeString(ext);
2487 static void test_GetSpecialFolder(void)
2489 WCHAR pathW[MAX_PATH];
2490 IFolder *folder;
2491 HRESULT hr;
2492 DWORD ret;
2493 BSTR path;
2495 hr = IFileSystem3_GetSpecialFolder(fs3, WindowsFolder, NULL);
2496 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2498 hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder+1, NULL);
2499 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2501 hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder+1, &folder);
2502 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2504 hr = IFileSystem3_GetSpecialFolder(fs3, WindowsFolder, &folder);
2505 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2506 hr = IFolder_get_Path(folder, &path);
2507 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2508 GetWindowsDirectoryW(pathW, ARRAY_SIZE(pathW));
2509 ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW));
2510 SysFreeString(path);
2511 IFolder_Release(folder);
2513 hr = IFileSystem3_GetSpecialFolder(fs3, SystemFolder, &folder);
2514 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2515 hr = IFolder_get_Path(folder, &path);
2516 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2517 GetSystemDirectoryW(pathW, ARRAY_SIZE(pathW));
2518 ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW));
2519 SysFreeString(path);
2520 IFolder_Release(folder);
2522 hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder, &folder);
2523 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2524 hr = IFolder_get_Path(folder, &path);
2525 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2526 ret = GetTempPathW(ARRAY_SIZE(pathW), pathW);
2527 if (ret && pathW[ret-1] == '\\')
2528 pathW[ret-1] = 0;
2530 ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW));
2531 SysFreeString(path);
2532 IFolder_Release(folder);
2535 static void test_MoveFile(void)
2537 ITextStream *stream;
2538 BSTR str, src, dst;
2539 HRESULT hr;
2541 str = SysAllocString(L"test.txt");
2542 hr = IFileSystem3_CreateTextFile(fs3, str, VARIANT_FALSE, VARIANT_FALSE, &stream);
2543 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2544 SysFreeString(str);
2546 str = SysAllocString(L"test");
2547 hr = ITextStream_Write(stream, str);
2548 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2549 SysFreeString(str);
2551 ITextStream_Release(stream);
2553 str = SysAllocString(L"test2.txt");
2554 hr = IFileSystem3_CreateTextFile(fs3, str, VARIANT_FALSE, VARIANT_FALSE, &stream);
2555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2556 SysFreeString(str);
2557 ITextStream_Release(stream);
2559 src = SysAllocString(L"test.txt");
2560 dst = SysAllocString(L"test3.txt");
2561 hr = IFileSystem3_MoveFile(fs3, src, dst);
2562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2563 SysFreeString(src);
2564 SysFreeString(dst);
2566 str = SysAllocString(L"test.txt");
2567 hr = IFileSystem3_DeleteFile(fs3, str, VARIANT_TRUE);
2568 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
2569 SysFreeString(str);
2571 src = SysAllocString(L"test3.txt");
2572 dst = SysAllocString(L"test2.txt"); /* already exists */
2573 hr = IFileSystem3_MoveFile(fs3, src, dst);
2574 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
2575 SysFreeString(src);
2576 SysFreeString(dst);
2578 src = SysAllocString(L"nonexistent.txt");
2579 dst = SysAllocString(L"test4.txt");
2580 hr = IFileSystem3_MoveFile(fs3, src, dst);
2581 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
2582 SysFreeString(src);
2583 SysFreeString(dst);
2585 str = SysAllocString(L"test3.txt");
2586 hr = IFileSystem3_DeleteFile(fs3, str, VARIANT_TRUE);
2587 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2588 SysFreeString(str);
2590 str = SysAllocString(L"test2.txt");
2591 hr = IFileSystem3_DeleteFile(fs3, str, VARIANT_TRUE);
2592 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2593 SysFreeString(str);
2596 static void test_DoOpenPipeStream(void)
2598 static const char testdata[] = "test";
2599 ITextStream *stream_read, *stream_write;
2600 SECURITY_ATTRIBUTES pipe_attr;
2601 HANDLE piperead, pipewrite;
2602 DWORD written;
2603 HRESULT hr;
2604 BSTR str;
2605 BOOL ret;
2607 pDoOpenPipeStream = (void *)GetProcAddress(GetModuleHandleA("scrrun.dll"), "DoOpenPipeStream");
2609 pipe_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
2610 pipe_attr.bInheritHandle = TRUE;
2611 pipe_attr.lpSecurityDescriptor = NULL;
2612 ret = CreatePipe(&piperead, &pipewrite, &pipe_attr, 0);
2613 ok(ret, "Failed to create pipes.\n");
2615 hr = pDoOpenPipeStream(piperead, ForReading, &stream_read);
2616 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2617 if (SUCCEEDED(hr))
2619 ok(!!stream_read, "Unexpected stream pointer.\n");
2621 ret = WriteFile(pipewrite, testdata, sizeof(testdata), &written, NULL);
2622 ok(ret, "Failed to write to the pipe.\n");
2623 ok(written == sizeof(testdata), "Write to anonymous pipe wrote %ld bytes.\n", written);
2625 hr = ITextStream_Read(stream_read, 4, &str);
2626 todo_wine
2627 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2628 if (SUCCEEDED(hr))
2630 ok(!wcscmp(str, L"test"), "Unexpected data read %s.\n", wine_dbgstr_w(str));
2631 SysFreeString(str);
2634 ITextStream_Release(stream_read);
2637 ret = CloseHandle(pipewrite);
2638 ok(ret, "Unexpected return value.\n");
2639 /* Stream takes ownership. */
2640 ret = CloseHandle(piperead);
2641 ok(!ret, "Unexpected return value.\n");
2643 /* Streams on both ends. */
2644 ret = CreatePipe(&piperead, &pipewrite, &pipe_attr, 0);
2645 ok(ret, "Failed to create pipes.\n");
2647 stream_read = NULL;
2648 hr = pDoOpenPipeStream(piperead, ForReading, &stream_read);
2649 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2651 stream_write = NULL;
2652 hr = pDoOpenPipeStream(pipewrite, ForWriting, &stream_write);
2653 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2655 if (SUCCEEDED(hr))
2657 str = SysAllocString(L"data");
2658 hr = ITextStream_Write(stream_write, str);
2659 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2661 hr = ITextStream_Write(stream_read, str);
2662 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
2664 SysFreeString(str);
2666 hr = ITextStream_Read(stream_write, 1, &str);
2667 todo_wine
2668 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
2670 hr = ITextStream_Read(stream_read, 4, &str);
2671 todo_wine
2672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2673 if (SUCCEEDED(hr))
2675 ok(!wcscmp(str, L"data"), "Unexpected data.\n");
2676 SysFreeString(str);
2680 if (stream_read)
2681 ITextStream_Release(stream_read);
2682 if (stream_write)
2683 ITextStream_Release(stream_write);
2686 START_TEST(filesystem)
2688 HRESULT hr;
2690 CoInitialize(NULL);
2692 hr = CoCreateInstance(&CLSID_FileSystemObject, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2693 &IID_IFileSystem3, (void**)&fs3);
2694 if(FAILED(hr))
2696 win_skip("Could not create FileSystem object, hr %#lx.\n", hr);
2697 return;
2700 test_interfaces();
2701 test_createfolder();
2702 test_textstream();
2703 test_GetFileVersion();
2704 test_GetParentFolderName();
2705 test_GetFileName();
2706 test_GetBaseName();
2707 test_GetAbsolutePathName();
2708 test_GetFile();
2709 test_GetTempName();
2710 test_CopyFolder();
2711 test_BuildPath();
2712 test_GetFolder();
2713 test_FolderCollection();
2714 test_FileCollection();
2715 test_DriveCollection();
2716 test_CreateTextFile();
2717 test_FolderCreateTextFile();
2718 test_WriteLine();
2719 test_ReadAll();
2720 test_Read();
2721 test_ReadLine();
2722 test_DriveExists();
2723 test_GetDriveName();
2724 test_GetDrive();
2725 test_SerialNumber();
2726 test_GetExtensionName();
2727 test_GetSpecialFolder();
2728 test_MoveFile();
2729 test_DoOpenPipeStream();
2731 IFileSystem3_Release(fs3);
2733 CoUninitialize();