uiautomationcore: Put general purpose helper functions into separate source file.
[wine.git] / dlls / scrrun / tests / filesystem.c
blobe53bd092ce9c26e5bfa84145166ea30efa82e0fe
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"
30 #include "shlwapi.h"
32 #include "wine/test.h"
34 #include "initguid.h"
35 #include "scrrun.h"
37 static IFileSystem3 *fs3;
39 static HRESULT (WINAPI *pDoOpenPipeStream)(HANDLE pipe, DWORD mode, ITextStream **stream);
41 /* w2k and 2k3 error code. */
42 #define E_VAR_NOT_SET 0x800a005b
44 static inline ULONG get_refcount(IUnknown *iface)
46 IUnknown_AddRef(iface);
47 return IUnknown_Release(iface);
50 static const char utf16bom[] = {0xff,0xfe,0};
51 static const WCHAR testfileW[] = L"test.txt";
53 #define GET_REFCOUNT(iface) \
54 get_refcount((IUnknown*)iface)
56 static inline void get_temp_path(const WCHAR *prefix, WCHAR *path)
58 WCHAR buffW[MAX_PATH];
60 GetTempPathW(MAX_PATH, buffW);
61 GetTempFileNameW(buffW, prefix, 0, path);
62 DeleteFileW(path);
65 #define test_file_contents(a, b, c) _test_file_contents(a, b, c, __LINE__)
66 static void _test_file_contents(LPCWSTR pathW, DWORD expected_size, const void * expected_contents, int line)
68 HANDLE file;
69 BOOL ret;
70 DWORD actual_size;
72 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
73 ok_(__FILE__,line) (file != INVALID_HANDLE_VALUE, "got %p\n", file);
75 actual_size = GetFileSize(file,NULL);
76 ok_(__FILE__,line) (actual_size == expected_size, "expected file %s size %ld, got %ld\n", wine_dbgstr_w(pathW), expected_size, actual_size);
78 if((expected_contents != NULL) && (actual_size > 0))
80 DWORD r;
81 void *actual_contents = malloc(actual_size);
82 ret = ReadFile(file, actual_contents, actual_size, &r, NULL);
83 ok_(__FILE__,line) (ret && r == actual_size, "Read %ld, got %d, error %ld.\n", r, ret, GetLastError());
84 ok_(__FILE__,line) (!memcmp(expected_contents, actual_contents, expected_size), "expected file %s contents %s, got %s\n", wine_dbgstr_w(pathW), wine_dbgstr_an(expected_contents,expected_size), wine_dbgstr_an(actual_contents,r));
85 free(actual_contents);
88 CloseHandle(file);
91 static IDrive *get_fixed_drive(void)
93 IDriveCollection *drives;
94 IEnumVARIANT *iter;
95 IDrive *drive;
96 HRESULT hr;
98 hr = IFileSystem3_get_Drives(fs3, &drives);
99 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
101 hr = IDriveCollection_get__NewEnum(drives, (IUnknown**)&iter);
102 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
103 IDriveCollection_Release(drives);
105 while (1) {
106 DriveTypeConst type;
107 VARIANT var;
109 hr = IEnumVARIANT_Next(iter, 1, &var, NULL);
110 if (hr == S_FALSE) {
111 drive = NULL;
112 break;
114 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
116 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDrive, (void**)&drive);
117 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
118 VariantClear(&var);
120 hr = IDrive_get_DriveType(drive, &type);
121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
122 if (type == Fixed)
123 break;
125 IDrive_Release(drive);
128 IEnumVARIANT_Release(iter);
129 return drive;
132 #define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__)
133 static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line)
135 IProvideClassInfo *classinfo;
136 TYPEATTR *attr;
137 ITypeInfo *ti;
138 IUnknown *unk;
139 HRESULT hr;
141 hr = IDispatch_QueryInterface(disp, &IID_IProvideClassInfo, (void **)&classinfo);
142 ok_(__FILE__,line) (hr == S_OK, "Failed to get IProvideClassInfo, %#lx.\n", hr);
144 hr = IProvideClassInfo_GetClassInfo(classinfo, &ti);
145 ok_(__FILE__,line) (hr == S_OK, "GetClassInfo() failed, %#lx.\n", hr);
147 hr = ITypeInfo_GetTypeAttr(ti, &attr);
148 ok_(__FILE__,line) (hr == S_OK, "GetTypeAttr() failed, %#lx.\n", hr);
150 ok_(__FILE__,line) (IsEqualGUID(&attr->guid, guid), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr->guid),
151 wine_dbgstr_guid(guid));
153 hr = IProvideClassInfo_QueryInterface(classinfo, &IID_IUnknown, (void **)&unk);
154 ok(hr == S_OK, "Failed to QI for IUnknown.\n");
155 ok(unk == (IUnknown *)disp, "Got unk %p, original %p.\n", unk, disp);
156 IUnknown_Release(unk);
158 IProvideClassInfo_Release(classinfo);
159 ITypeInfo_ReleaseTypeAttr(ti, attr);
160 ITypeInfo_Release(ti);
163 static void test_interfaces(void)
165 HRESULT hr;
166 IDispatch *disp;
167 IDispatchEx *dispex;
168 IObjectWithSite *site;
169 VARIANT_BOOL b;
170 BSTR path;
171 WCHAR windows_path[MAX_PATH];
172 WCHAR file_path[MAX_PATH];
174 IFileSystem3_QueryInterface(fs3, &IID_IDispatch, (void**)&disp);
176 GetSystemDirectoryW(windows_path, MAX_PATH);
177 lstrcpyW(file_path, windows_path);
178 lstrcatW(file_path, L"\\kernel32.dll");
180 test_provideclassinfo(disp, &CLSID_FileSystemObject);
182 hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
183 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
185 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
186 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
188 b = VARIANT_TRUE;
189 hr = IFileSystem3_FileExists(fs3, NULL, &b);
190 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
191 ok(b == VARIANT_FALSE, "got %x\n", b);
193 hr = IFileSystem3_FileExists(fs3, NULL, NULL);
194 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
196 path = SysAllocString(L"path");
197 b = VARIANT_TRUE;
198 hr = IFileSystem3_FileExists(fs3, path, &b);
199 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
200 ok(b == VARIANT_FALSE, "got %x\n", b);
201 SysFreeString(path);
203 path = SysAllocString(file_path);
204 b = VARIANT_FALSE;
205 hr = IFileSystem3_FileExists(fs3, path, &b);
206 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
207 ok(b == VARIANT_TRUE, "got %x\n", b);
208 SysFreeString(path);
210 path = SysAllocString(windows_path);
211 b = VARIANT_TRUE;
212 hr = IFileSystem3_FileExists(fs3, path, &b);
213 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
214 ok(b == VARIANT_FALSE, "got %x\n", b);
215 SysFreeString(path);
217 /* Folder Exists */
218 hr = IFileSystem3_FolderExists(fs3, NULL, NULL);
219 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
221 path = SysAllocString(windows_path);
222 hr = IFileSystem3_FolderExists(fs3, path, &b);
223 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
224 ok(b == VARIANT_TRUE, "Folder doesn't exists\n");
225 SysFreeString(path);
227 path = SysAllocString(L"c:\\Nonexistent");
228 hr = IFileSystem3_FolderExists(fs3, path, &b);
229 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
230 ok(b == VARIANT_FALSE, "Folder exists\n");
231 SysFreeString(path);
233 path = SysAllocString(file_path);
234 hr = IFileSystem3_FolderExists(fs3, path, &b);
235 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
236 ok(b == VARIANT_FALSE, "Folder exists\n");
237 SysFreeString(path);
239 IDispatch_Release(disp);
242 static void test_createfolder(void)
244 WCHAR buffW[MAX_PATH];
245 HRESULT hr;
246 BSTR path;
247 IFolder *folder;
248 BOOL ret;
250 get_temp_path(NULL, buffW);
251 ret = CreateDirectoryW(buffW, NULL);
252 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
254 /* create existing directory */
255 path = SysAllocString(buffW);
256 folder = (void*)0xdeabeef;
257 hr = IFileSystem3_CreateFolder(fs3, path, &folder);
258 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
259 ok(folder == NULL, "got %p\n", folder);
260 SysFreeString(path);
261 RemoveDirectoryW(buffW);
264 static void test_textstream(void)
266 WCHAR ExpectedW[10];
267 ITextStream *stream;
268 VARIANT_BOOL b;
269 DWORD written;
270 HANDLE file;
271 HRESULT hr;
272 BSTR name, data;
273 BOOL ret;
275 file = CreateFileW(testfileW, GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
276 CloseHandle(file);
278 name = SysAllocString(testfileW);
279 b = VARIANT_FALSE;
280 hr = IFileSystem3_FileExists(fs3, name, &b);
281 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
282 ok(b == VARIANT_TRUE, "got %x\n", b);
284 /* different mode combinations */
285 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting | ForAppending, VARIANT_FALSE, TristateFalse, &stream);
286 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
288 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading | ForAppending, VARIANT_FALSE, TristateFalse, &stream);
289 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
291 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting | ForReading, VARIANT_FALSE, TristateFalse, &stream);
292 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
294 hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateFalse, &stream);
295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
296 hr = ITextStream_Read(stream, 1, &data);
297 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
298 ITextStream_Release(stream);
300 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream);
301 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
302 hr = ITextStream_Read(stream, 1, &data);
303 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
304 ITextStream_Release(stream);
306 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream);
307 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
309 /* try to write when open for reading */
310 hr = ITextStream_WriteLine(stream, name);
311 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
313 hr = ITextStream_Write(stream, name);
314 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
316 hr = ITextStream_get_AtEndOfStream(stream, NULL);
317 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
319 b = 10;
320 hr = ITextStream_get_AtEndOfStream(stream, &b);
321 ok(hr == S_OK || broken(hr == S_FALSE), "Unexpected hr %#lx.\n", hr);
322 ok(b == VARIANT_TRUE, "got 0x%x\n", b);
324 ITextStream_Release(stream);
326 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream);
327 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
329 b = 10;
330 hr = ITextStream_get_AtEndOfStream(stream, &b);
331 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
332 ok(b == VARIANT_TRUE || broken(b == 10), "got 0x%x\n", b);
334 b = 10;
335 hr = ITextStream_get_AtEndOfLine(stream, &b);
336 todo_wine {
337 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
338 ok(b == VARIANT_FALSE || broken(b == 10), "got 0x%x\n", b);
340 hr = ITextStream_Read(stream, 1, &data);
341 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
343 hr = ITextStream_ReadLine(stream, &data);
344 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
346 hr = ITextStream_ReadAll(stream, &data);
347 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
349 ITextStream_Release(stream);
351 hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateFalse, &stream);
352 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
354 b = 10;
355 hr = ITextStream_get_AtEndOfStream(stream, &b);
356 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
357 ok(b == VARIANT_TRUE || broken(b == 10), "got 0x%x\n", b);
359 b = 10;
360 hr = ITextStream_get_AtEndOfLine(stream, &b);
361 todo_wine {
362 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
363 ok(b == VARIANT_FALSE || broken(b == 10), "got 0x%x\n", b);
365 hr = ITextStream_Read(stream, 1, &data);
366 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
368 hr = ITextStream_ReadLine(stream, &data);
369 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
371 hr = ITextStream_ReadAll(stream, &data);
372 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
374 ITextStream_Release(stream);
376 /* now with non-empty file */
377 file = CreateFileW(testfileW, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
378 ret = WriteFile(file, testfileW, sizeof(testfileW), &written, NULL);
379 ok(ret && written == sizeof(testfileW), "got %d\n", ret);
380 CloseHandle(file);
382 /* opening a non-empty file (from above) for writing should truncate it */
383 hr = IFileSystem3_OpenTextFile(fs3, name, ForWriting, VARIANT_FALSE, TristateFalse, &stream);
384 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
385 ITextStream_Release(stream);
387 test_file_contents(testfileW,0,"");
389 /* appending to an empty file file and specifying unicode should immediately write a BOM */
390 hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateTrue, &stream);
391 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
392 ITextStream_Release(stream);
394 test_file_contents(testfileW,2,L"\ufeff");
396 /* appending to a file that contains a BOM should detect unicode mode, but not write a second BOM */
397 hr = IFileSystem3_OpenTextFile(fs3, name, ForAppending, VARIANT_FALSE, TristateUseDefault, &stream);
398 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
399 hr = ITextStream_Write(stream, name);
400 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
401 ITextStream_Release(stream);
403 lstrcpyW(ExpectedW, L"\ufeff");
404 lstrcatW(ExpectedW, name);
405 test_file_contents(testfileW,lstrlenW(ExpectedW)*sizeof(WCHAR),ExpectedW);
407 hr = IFileSystem3_OpenTextFile(fs3, name, ForReading, VARIANT_FALSE, TristateFalse, &stream);
408 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
409 b = 10;
410 hr = ITextStream_get_AtEndOfStream(stream, &b);
411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
412 ok(b == VARIANT_FALSE, "got 0x%x\n", b);
413 ITextStream_Release(stream);
415 SysFreeString(name);
416 DeleteFileW(testfileW);
419 static void test_GetFileVersion(void)
421 WCHAR pathW[MAX_PATH], filenameW[MAX_PATH];
422 BSTR path, version;
423 HRESULT hr;
425 GetSystemDirectoryW(pathW, ARRAY_SIZE(pathW));
427 lstrcpyW(filenameW, pathW);
428 lstrcatW(filenameW, L"\\kernel32.dll");
430 path = SysAllocString(filenameW);
431 hr = IFileSystem3_GetFileVersion(fs3, path, &version);
432 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
433 ok(*version != 0, "got %s\n", wine_dbgstr_w(version));
434 SysFreeString(version);
435 SysFreeString(path);
437 lstrcpyW(filenameW, pathW);
438 lstrcatW(filenameW, L"\\kernel33.dll");
440 path = SysAllocString(filenameW);
441 version = (void*)0xdeadbeef;
442 hr = IFileSystem3_GetFileVersion(fs3, path, &version);
443 ok(broken(hr == S_OK) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
444 if (hr == S_OK)
446 ok(*version == 0, "got %s\n", wine_dbgstr_w(version));
447 SysFreeString(version);
449 else
450 ok(version == (void*)0xdeadbeef, "got %p\n", version);
451 SysFreeString(path);
454 static void test_GetParentFolderName(void)
456 static const struct
458 const WCHAR *path;
459 const WCHAR *result;
461 tests[] =
463 { NULL, NULL },
464 { L"a", NULL },
465 { L"a/a/a", L"a/a" },
466 { L"a\\a\\a", L"a\\a" },
467 { L"a/a//\\\\", L"a" },
468 { L"c:\\\\a", L"c:\\" },
469 { L"ac:\\a", L"ac:" }
472 BSTR path, result;
473 HRESULT hr;
474 int i;
476 hr = IFileSystem3_GetParentFolderName(fs3, NULL, NULL);
477 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
479 for(i=0; i < ARRAY_SIZE(tests); i++) {
480 result = (BSTR)0xdeadbeef;
481 path = tests[i].path ? SysAllocString(tests[i].path) : NULL;
482 hr = IFileSystem3_GetParentFolderName(fs3, path, &result);
483 ok(hr == S_OK, "%d: unexpected hr %#lx.\n", i, hr);
484 if(!tests[i].result)
485 ok(!result, "%d) result = %s\n", i, wine_dbgstr_w(result));
486 else
487 ok(!lstrcmpW(result, tests[i].result), "%d) result = %s\n", i, wine_dbgstr_w(result));
488 SysFreeString(path);
489 SysFreeString(result);
493 static void test_GetFileName(void)
495 static const struct
497 const WCHAR *path;
498 const WCHAR *result;
499 } tests[] =
501 { NULL, NULL },
502 { L"a", L"a" },
503 { L"a/a.b", L"a.b" },
504 { L"a\\", L"a" },
505 { L"c:", NULL },
506 { L"/\\", NULL }
509 BSTR path, result;
510 HRESULT hr;
511 int i;
513 hr = IFileSystem3_GetFileName(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_GetFileName(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_GetTempName(void)
532 BSTR result;
533 HRESULT hr;
535 hr = IFileSystem3_GetTempName(fs3, NULL);
536 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
537 result = (BSTR)0xdeadbeef;
538 hr = IFileSystem3_GetTempName(fs3, &result);
539 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
540 ok(!!wcsstr( result,L".tmp"), "GetTempName returned %s, expected .tmp suffix\n", debugstr_w(result));
541 ok(SysStringLen(result) == lstrlenW(result),"GetTempName returned %s, has incorrect string len.\n", debugstr_w(result));
542 SysFreeString(result);
545 static void test_GetBaseName(void)
547 static const struct
549 const WCHAR *path;
550 const WCHAR *result;
552 tests[] =
554 { NULL, NULL},
555 { L"a", L"a" },
556 { L"a/a.b.c", L"a.b" },
557 { L"a.b\\", L"a" },
558 { L"c:", NULL },
559 { L"/\\", NULL },
560 { L".a", L"" }
563 BSTR path, result;
564 HRESULT hr;
565 int i;
567 hr = IFileSystem3_GetBaseName(fs3, NULL, NULL);
568 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
570 for(i=0; i < ARRAY_SIZE(tests); i++) {
571 result = (BSTR)0xdeadbeef;
572 path = tests[i].path ? SysAllocString(tests[i].path) : NULL;
573 hr = IFileSystem3_GetBaseName(fs3, path, &result);
574 ok(hr == S_OK, "%d, unexpected hr %#lx.\n", i, hr);
575 if(!tests[i].result)
576 ok(!result, "%d) result = %s\n", i, wine_dbgstr_w(result));
577 else
578 ok(!lstrcmpW(result, tests[i].result), "%d) result = %s\n", i, wine_dbgstr_w(result));
579 SysFreeString(path);
580 SysFreeString(result);
584 static void test_GetAbsolutePathName(void)
586 static const WCHAR dir1[] = L"test_dir1";
587 static const WCHAR dir2[] = L"test_dir2";
588 static const WCHAR dir_match1[] = L"test_dir*";
589 static const WCHAR dir_match2[] = L"test_di*";
591 WIN32_FIND_DATAW fdata;
592 HANDLE find;
593 WCHAR buf[MAX_PATH], buf2[MAX_PATH];
594 BSTR path, result;
595 HRESULT hr;
597 hr = IFileSystem3_GetAbsolutePathName(fs3, NULL, NULL);
598 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
600 hr = IFileSystem3_GetAbsolutePathName(fs3, NULL, &result);
601 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
602 GetFullPathNameW(L".", MAX_PATH, buf, NULL);
603 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf));
604 SysFreeString(result);
606 find = FindFirstFileW(dir_match2, &fdata);
607 if(find != INVALID_HANDLE_VALUE) {
608 skip("GetAbsolutePathName tests\n");
609 FindClose(find);
610 return;
613 path = SysAllocString(dir_match1);
614 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
615 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
616 GetFullPathNameW(dir_match1, MAX_PATH, buf2, NULL);
617 ok(!lstrcmpiW(buf2, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf2));
618 SysFreeString(result);
620 ok(CreateDirectoryW(dir1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir1));
621 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
622 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
623 GetFullPathNameW(dir1, MAX_PATH, buf, NULL);
624 ok(!lstrcmpiW(buf, result) || broken(!lstrcmpiW(buf2, result)), "result = %s, expected %s\n",
625 wine_dbgstr_w(result), wine_dbgstr_w(buf));
626 SysFreeString(result);
628 ok(CreateDirectoryW(dir2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir2));
629 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
630 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
631 if(!lstrcmpiW(buf, result) || !lstrcmpiW(buf2, result)) {
632 ok(!lstrcmpiW(buf, result) || broken(!lstrcmpiW(buf2, result)), "result = %s, expected %s\n",
633 wine_dbgstr_w(result), wine_dbgstr_w(buf));
634 }else {
635 GetFullPathNameW(dir2, MAX_PATH, buf, NULL);
636 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n",
637 wine_dbgstr_w(result), wine_dbgstr_w(buf));
639 SysFreeString(result);
641 SysFreeString(path);
642 path = SysAllocString(dir_match2);
643 hr = IFileSystem3_GetAbsolutePathName(fs3, path, &result);
644 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
645 GetFullPathNameW(dir_match2, MAX_PATH, buf, NULL);
646 ok(!lstrcmpiW(buf, result), "result = %s, expected %s\n", wine_dbgstr_w(result), wine_dbgstr_w(buf));
647 SysFreeString(result);
648 SysFreeString(path);
650 RemoveDirectoryW(dir1);
651 RemoveDirectoryW(dir2);
654 static void test_GetFile(void)
656 BSTR path, str;
657 WCHAR pathW[MAX_PATH];
658 FileAttribute fa;
659 VARIANT size;
660 DWORD gfa, new_gfa;
661 IFile *file;
662 HRESULT hr;
663 HANDLE hf;
664 BOOL ret;
665 DATE date;
667 get_temp_path(NULL, pathW);
669 path = SysAllocString(pathW);
670 hr = IFileSystem3_GetFile(fs3, path, NULL);
671 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
672 hr = IFileSystem3_GetFile(fs3, NULL, &file);
673 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
675 file = (IFile*)0xdeadbeef;
676 hr = IFileSystem3_GetFile(fs3, path, &file);
677 ok(!file, "file != NULL\n");
678 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
680 hf = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_READONLY, NULL);
681 if(hf == INVALID_HANDLE_VALUE) {
682 skip("Can't create temporary file\n");
683 SysFreeString(path);
684 return;
686 CloseHandle(hf);
688 hr = IFileSystem3_GetFile(fs3, path, &file);
689 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
691 hr = IFile_get_DateCreated(file, NULL);
692 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
694 date = 0.0;
695 hr = IFile_get_DateCreated(file, &date);
696 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
697 ok(date > 0.0, "got %f\n", date);
699 hr = IFile_get_DateLastModified(file, NULL);
700 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
702 date = 0.0;
703 hr = IFile_get_DateLastModified(file, &date);
704 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
705 ok(date > 0.0, "got %f\n", date);
707 hr = IFile_get_Path(file, NULL);
708 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
710 hr = IFile_get_Path(file, &str);
711 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
712 ok(!lstrcmpiW(str, pathW), "got %s\n", wine_dbgstr_w(str));
713 SysFreeString(str);
715 #define FILE_ATTR_MASK (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
716 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE | \
717 FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED)
719 hr = IFile_get_Attributes(file, &fa);
720 gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK;
721 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
722 ok(fa == gfa, "Unexpected flags %#x, expected %lx.\n", fa, gfa);
724 hr = IFile_put_Attributes(file, gfa | FILE_ATTRIBUTE_READONLY);
725 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
726 new_gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK;
727 ok(new_gfa == (gfa|FILE_ATTRIBUTE_READONLY), "Unexpected flags %#lx, expected %lx\n", new_gfa, gfa|FILE_ATTRIBUTE_READONLY);
729 hr = IFile_get_Attributes(file, &fa);
730 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
731 ok(fa == new_gfa, "Unexpected flags %#x, expected %lx.\n", fa, new_gfa);
733 hr = IFile_put_Attributes(file, gfa);
734 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
735 new_gfa = GetFileAttributesW(pathW) & FILE_ATTR_MASK;
736 ok(new_gfa == gfa, "Unexpected flags %#lx, expected %lx.\n", new_gfa, gfa);
738 hr = IFile_get_Attributes(file, &fa);
739 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
740 ok(fa == gfa, "Unexpected flags %#x, expected %lx.\n", fa, gfa);
742 hr = IFile_get_Size(file, &size);
743 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
744 ok(V_VT(&size) == VT_I4, "V_VT(&size) = %d, expected VT_I4\n", V_VT(&size));
745 ok(V_I4(&size) == 0, "V_I4(&size) = %ld, expected 0\n", V_I4(&size));
746 IFile_Release(file);
748 hr = IFileSystem3_DeleteFile(fs3, path, FALSE);
749 ok(hr == CTL_E_PERMISSIONDENIED || broken(hr == S_OK), "Unexpected hr %#lx.\n", hr);
750 if(hr != S_OK) {
751 hr = IFileSystem3_DeleteFile(fs3, path, TRUE);
752 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
754 hr = IFileSystem3_DeleteFile(fs3, path, TRUE);
755 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
757 SysFreeString(path);
759 /* try with directory */
760 lstrcatW(pathW, L"\\");
761 ret = CreateDirectoryW(pathW, NULL);
762 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
764 path = SysAllocString(pathW);
765 hr = IFileSystem3_GetFile(fs3, path, &file);
766 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
767 SysFreeString(path);
769 RemoveDirectoryW(pathW);
772 static inline BOOL create_file(const WCHAR *name)
774 HANDLE f = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
775 CloseHandle(f);
776 return f != INVALID_HANDLE_VALUE;
779 static inline void create_path(const WCHAR *folder, const WCHAR *name, WCHAR *ret)
781 DWORD len = lstrlenW(folder);
782 memmove(ret, folder, len*sizeof(WCHAR));
783 ret[len] = '\\';
784 memmove(ret+len+1, name, (lstrlenW(name)+1)*sizeof(WCHAR));
787 static void test_CopyFolder(void)
789 static const WCHAR filesystem3_dir[] = L"filesystem3_test";
790 static const WCHAR src1W[] = L"src1";
791 static const WCHAR dstW[] = L"dst";
793 WCHAR tmp[MAX_PATH];
794 BSTR bsrc, bdst;
795 HRESULT hr;
797 if(!CreateDirectoryW(filesystem3_dir, NULL)) {
798 skip("can't create temporary directory\n");
799 return;
802 create_path(filesystem3_dir, src1W, tmp);
803 bsrc = SysAllocString(tmp);
804 create_path(filesystem3_dir, dstW, tmp);
805 bdst = SysAllocString(tmp);
806 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
807 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
809 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
810 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
812 ok(create_file(bsrc), "can't create %s file\n", wine_dbgstr_w(bsrc));
813 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
814 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
816 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
817 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
819 hr = IFileSystem3_DeleteFile(fs3, bsrc, VARIANT_FALSE);
820 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
822 ok(CreateDirectoryW(bsrc, NULL), "can't create %s\n", wine_dbgstr_w(bsrc));
823 hr = IFileSystem3_CopyFile(fs3, bsrc, bdst, VARIANT_TRUE);
824 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
826 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
827 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
829 hr = IFileSystem3_DeleteFile(fs3, bdst, VARIANT_TRUE);
830 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
832 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
833 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
835 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
836 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
837 create_path(tmp, src1W, tmp);
838 ok(GetFileAttributesW(tmp) == INVALID_FILE_ATTRIBUTES,
839 "%s file exists\n", wine_dbgstr_w(tmp));
841 create_path(filesystem3_dir, dstW, tmp);
842 create_path(tmp, L"", tmp);
843 SysFreeString(bdst);
844 bdst = SysAllocString(tmp);
845 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
846 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
847 create_path(tmp, src1W, tmp);
848 ok(GetFileAttributesW(tmp) != INVALID_FILE_ATTRIBUTES,
849 "%s directory doesn't exist\n", wine_dbgstr_w(tmp));
850 ok(RemoveDirectoryW(tmp), "can't remove %s directory\n", wine_dbgstr_w(tmp));
851 create_path(filesystem3_dir, dstW, tmp);
852 SysFreeString(bdst);
853 bdst = SysAllocString(tmp);
855 create_path(filesystem3_dir, L"src*", tmp);
856 SysFreeString(bsrc);
857 bsrc = SysAllocString(tmp);
858 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
859 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
860 create_path(filesystem3_dir, dstW, tmp);
861 create_path(tmp, src1W, tmp);
862 ok(GetFileAttributesW(tmp) != INVALID_FILE_ATTRIBUTES,
863 "%s directory doesn't exist\n", wine_dbgstr_w(tmp));
865 hr = IFileSystem3_DeleteFolder(fs3, bdst, VARIANT_FALSE);
866 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
868 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
869 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
871 create_path(filesystem3_dir, src1W, tmp);
872 SysFreeString(bsrc);
873 bsrc = SysAllocString(tmp);
874 create_path(tmp, src1W, tmp);
875 ok(create_file(tmp), "can't create %s file\n", wine_dbgstr_w(tmp));
876 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_FALSE);
877 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
879 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_FALSE);
880 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
882 hr = IFileSystem3_CopyFolder(fs3, bsrc, bdst, VARIANT_TRUE);
883 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
884 SysFreeString(bsrc);
885 SysFreeString(bdst);
887 bsrc = SysAllocString(filesystem3_dir);
888 hr = IFileSystem3_DeleteFolder(fs3, bsrc, VARIANT_FALSE);
889 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
890 SysFreeString(bsrc);
893 static BSTR bstr_from_str(const char *str)
895 int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
896 BSTR ret = SysAllocStringLen(NULL, len - 1); /* NUL character added automatically */
897 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
898 return ret;
901 struct buildpath_test
903 const char *path;
904 const char *name;
905 const char *result;
908 static struct buildpath_test buildpath_data[] =
910 { "C:\\path", "..\\name.tmp", "C:\\path\\..\\name.tmp" },
911 { "C:\\path", "\\name.tmp", "C:\\path\\name.tmp" },
912 { "C:\\path", "name.tmp", "C:\\path\\name.tmp" },
913 { "C:\\path\\", "name.tmp", "C:\\path\\name.tmp" },
914 { "C:\\path", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
915 { "C:\\path\\", "\\name.tmp", "C:\\path\\name.tmp" },
916 { "C:\\path\\", "\\\\name.tmp", "C:\\path\\\\name.tmp" },
917 { "C:\\path\\\\", "\\\\name.tmp", "C:\\path\\\\\\name.tmp" },
918 { "C:\\\\", "\\name.tmp", "C:\\\\name.tmp" },
919 { "C:", "name.tmp", "C:name.tmp" },
920 { "C:", "\\\\name.tmp", "C:\\\\name.tmp" },
921 { NULL }
924 static void test_BuildPath(void)
926 struct buildpath_test *ptr = buildpath_data;
927 BSTR ret, path;
928 HRESULT hr;
929 int i = 0;
931 hr = IFileSystem3_BuildPath(fs3, NULL, NULL, NULL);
932 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
934 ret = (BSTR)0xdeadbeef;
935 hr = IFileSystem3_BuildPath(fs3, NULL, NULL, &ret);
936 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
937 ok(*ret == 0, "got %p\n", ret);
938 SysFreeString(ret);
940 ret = (BSTR)0xdeadbeef;
941 path = bstr_from_str("path");
942 hr = IFileSystem3_BuildPath(fs3, path, NULL, &ret);
943 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
944 ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret));
945 SysFreeString(ret);
946 SysFreeString(path);
948 ret = (BSTR)0xdeadbeef;
949 path = bstr_from_str("path");
950 hr = IFileSystem3_BuildPath(fs3, NULL, path, &ret);
951 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
952 ok(!lstrcmpW(ret, path), "got %s\n", wine_dbgstr_w(ret));
953 SysFreeString(ret);
954 SysFreeString(path);
956 while (ptr->path)
958 BSTR name, result;
960 ret = NULL;
961 path = bstr_from_str(ptr->path);
962 name = bstr_from_str(ptr->name);
963 result = bstr_from_str(ptr->result);
964 hr = IFileSystem3_BuildPath(fs3, path, name, &ret);
965 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", i, hr);
966 if (hr == S_OK)
968 ok(!lstrcmpW(ret, result), "%d: got wrong path %s, expected %s\n", i, wine_dbgstr_w(ret),
969 wine_dbgstr_w(result));
970 SysFreeString(ret);
972 SysFreeString(path);
973 SysFreeString(name);
974 SysFreeString(result);
976 i++;
977 ptr++;
981 static void test_GetFolder(void)
983 static const WCHAR dir[] = L"test_dir";
985 WCHAR buffW[MAX_PATH], temp_path[MAX_PATH], prev_path[MAX_PATH];
986 IFolder *folder;
987 HRESULT hr;
988 BSTR str;
990 folder = (void*)0xdeadbeef;
991 hr = IFileSystem3_GetFolder(fs3, NULL, &folder);
992 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
993 ok(folder == NULL, "got %p\n", folder);
995 hr = IFileSystem3_GetFolder(fs3, NULL, NULL);
996 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
998 /* something that doesn't exist */
999 str = SysAllocString(L"dummy");
1001 hr = IFileSystem3_GetFolder(fs3, str, NULL);
1002 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1004 folder = (void*)0xdeadbeef;
1005 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1006 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
1007 ok(folder == NULL, "got %p\n", folder);
1008 SysFreeString(str);
1010 GetWindowsDirectoryW(buffW, MAX_PATH);
1011 str = SysAllocString(buffW);
1012 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1013 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1014 SysFreeString(str);
1015 test_provideclassinfo(folder, &CLSID_Folder);
1016 IFolder_Release(folder);
1018 GetCurrentDirectoryW(MAX_PATH, prev_path);
1019 GetTempPathW(MAX_PATH, temp_path);
1020 SetCurrentDirectoryW(temp_path);
1021 ok(CreateDirectoryW(dir, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(dir));
1022 str = SysAllocString(dir);
1023 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1024 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1025 SysFreeString(str);
1026 hr = IFolder_get_Path(folder, &str);
1027 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1028 ok(!PathIsRelativeW(str), "path %s is relative.\n", wine_dbgstr_w(str));
1029 SysFreeString(str);
1030 IFolder_Release(folder);
1031 RemoveDirectoryW(dir);
1032 SetCurrentDirectoryW(prev_path);
1035 static void _test_clone(IEnumVARIANT *enumvar, BOOL position_inherited, LONG count, int line)
1037 HRESULT hr;
1038 IEnumVARIANT *clone;
1039 ULONG fetched;
1040 VARIANT var, var2;
1042 hr = IEnumVARIANT_Reset(enumvar);
1043 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
1045 VariantInit(&var);
1046 fetched = -1;
1047 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1048 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
1049 ok(fetched == 1, "%d: unexpected value %lu.\n", line, fetched);
1051 /* clone enumerator */
1052 hr = IEnumVARIANT_Clone(enumvar, &clone);
1053 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
1054 ok(clone != enumvar, "%d: got %p, %p\n", line, enumvar, clone);
1056 /* check if clone inherits position */
1057 VariantInit(&var2);
1058 fetched = -1;
1059 hr = IEnumVARIANT_Next(clone, 1, &var2, &fetched);
1060 if (position_inherited && count == 1)
1062 ok(hr == S_FALSE, "%d: Unexpected hr %#lx.\n", line, hr);
1063 ok(!fetched, "%d: unexpected value %lu.\n", line, fetched);
1065 else
1067 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
1068 ok(fetched == 1, "%d: unexpected value %lu.\n", line, fetched);
1069 if (!position_inherited)
1070 todo_wine ok(V_DISPATCH(&var) == V_DISPATCH(&var2), "%d: values don't match\n", line);
1071 else
1073 fetched = -1;
1074 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1075 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
1076 ok(fetched == 1, "%d: unexpected value %lu.\n", line, fetched);
1077 todo_wine ok(V_DISPATCH(&var) == V_DISPATCH(&var2), "%d: values don't match\n", line);
1081 VariantClear(&var2);
1082 VariantClear(&var);
1083 IEnumVARIANT_Release(clone);
1085 hr = IEnumVARIANT_Reset(enumvar);
1086 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", line, hr);
1088 #define test_clone(a, b, c) _test_clone(a, b, c, __LINE__)
1090 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1091 static void test_FolderCollection(void)
1093 static const WCHAR aW[] = L"\\a";
1094 static const WCHAR bW[] = L"\\b";
1095 static const WCHAR cW[] = L"\\c";
1096 IFolderCollection *folders;
1097 WCHAR buffW[MAX_PATH], pathW[MAX_PATH];
1098 IEnumVARIANT *enumvar;
1099 LONG count, ref, ref2;
1100 IUnknown *unk, *unk2;
1101 IFolder *folder;
1102 ULONG fetched;
1103 VARIANT var, var2[2];
1104 HRESULT hr;
1105 BSTR str;
1106 int found_a = 0, found_b = 0, found_c = 0;
1107 unsigned int i;
1109 get_temp_path(L"foo", buffW);
1110 CreateDirectoryW(buffW, NULL);
1112 str = SysAllocString(buffW);
1113 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1114 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1115 SysFreeString(str);
1117 hr = IFolder_get_SubFolders(folder, NULL);
1118 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1120 hr = IFolder_get_Path(folder, NULL);
1121 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1123 hr = IFolder_get_Path(folder, &str);
1124 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1125 ok(!lstrcmpiW(buffW, str), "got %s, expected %s\n", wine_dbgstr_w(str), wine_dbgstr_w(buffW));
1126 SysFreeString(str);
1128 lstrcpyW(pathW, buffW);
1129 lstrcatW(pathW, aW);
1130 CreateDirectoryW(pathW, NULL);
1132 lstrcpyW(pathW, buffW);
1133 lstrcatW(pathW, bW);
1134 CreateDirectoryW(pathW, NULL);
1136 hr = IFolder_get_SubFolders(folder, &folders);
1137 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1138 test_provideclassinfo(folders, &CLSID_Folders);
1139 IFolder_Release(folder);
1141 count = 0;
1142 hr = IFolderCollection_get_Count(folders, &count);
1143 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1144 ok(count == 2, "Unexpected value %lu.\n", count);
1146 lstrcpyW(pathW, buffW);
1147 lstrcatW(pathW, cW);
1148 CreateDirectoryW(pathW, NULL);
1150 /* every time property is requested it scans directory */
1151 count = 0;
1152 hr = IFolderCollection_get_Count(folders, &count);
1153 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1154 ok(count == 3, "Unexpected value %lu.\n", count);
1156 hr = IFolderCollection_get__NewEnum(folders, NULL);
1157 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1159 hr = IFolderCollection_QueryInterface(folders, &IID_IEnumVARIANT, (void**)&unk);
1160 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1162 /* NewEnum creates new instance each time it's called */
1163 ref = GET_REFCOUNT(folders);
1165 unk = NULL;
1166 hr = IFolderCollection_get__NewEnum(folders, &unk);
1167 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1169 ref2 = GET_REFCOUNT(folders);
1170 ok(ref2 == ref + 1, "Unexpected value %ld, %ld.\n", ref2, ref);
1172 unk2 = NULL;
1173 hr = IFolderCollection_get__NewEnum(folders, &unk2);
1174 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1175 ok(unk != unk2, "got %p, %p\n", unk2, unk);
1176 IUnknown_Release(unk2);
1178 /* now get IEnumVARIANT */
1179 ref = GET_REFCOUNT(folders);
1180 hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&enumvar);
1181 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1182 ref2 = GET_REFCOUNT(folders);
1183 ok(ref2 == ref, "Unexpected value %ld, %ld.\n", ref2, ref);
1185 test_clone(enumvar, FALSE, count);
1187 for (i = 0; i < 3; i++)
1189 VariantInit(&var);
1190 fetched = 0;
1191 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1192 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", i, hr);
1193 ok(fetched == 1, "%d: unexpected value %lu.\n", i, fetched);
1194 ok(V_VT(&var) == VT_DISPATCH, "%d: got type %d\n", i, V_VT(&var));
1196 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IFolder, (void**)&folder);
1197 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1199 str = NULL;
1200 hr = IFolder_get_Name(folder, &str);
1201 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1202 if (!lstrcmpW(str, aW + 1))
1203 found_a++;
1204 else if (!lstrcmpW(str, bW + 1))
1205 found_b++;
1206 else if (!lstrcmpW(str, cW + 1))
1207 found_c++;
1208 else
1209 ok(0, "unexpected folder %s was found\n", wine_dbgstr_w(str));
1210 SysFreeString(str);
1212 IFolder_Release(folder);
1213 VariantClear(&var);
1216 ok(found_a == 1 && found_b == 1 && found_c == 1,
1217 "each folder should be found 1 time instead of %d/%d/%d\n",
1218 found_a, found_b, found_c);
1220 VariantInit(&var);
1221 fetched = -1;
1222 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1223 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1224 ok(!fetched, "Unexpected value %lu.\n", fetched);
1226 hr = IEnumVARIANT_Reset(enumvar);
1227 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1228 hr = IEnumVARIANT_Skip(enumvar, 2);
1229 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1230 hr = IEnumVARIANT_Skip(enumvar, 0);
1231 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1233 VariantInit(&var2[0]);
1234 VariantInit(&var2[1]);
1235 fetched = -1;
1236 hr = IEnumVARIANT_Next(enumvar, 0, var2, &fetched);
1237 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1238 ok(!fetched, "Unexpected value %lu.\n", fetched);
1239 fetched = -1;
1240 hr = IEnumVARIANT_Next(enumvar, 2, var2, &fetched);
1241 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1242 ok(fetched == 1, "Unexpected value %lu.\n", fetched);
1243 ok(V_VT(&var2[0]) == VT_DISPATCH, "got type %d\n", V_VT(&var2[0]));
1244 VariantClear(&var2[0]);
1245 VariantClear(&var2[1]);
1247 IEnumVARIANT_Release(enumvar);
1248 IUnknown_Release(unk);
1250 lstrcpyW(pathW, buffW);
1251 lstrcatW(pathW, aW);
1252 RemoveDirectoryW(pathW);
1253 lstrcpyW(pathW, buffW);
1254 lstrcatW(pathW, bW);
1255 RemoveDirectoryW(pathW);
1256 lstrcpyW(pathW, buffW);
1257 lstrcatW(pathW, cW);
1258 RemoveDirectoryW(pathW);
1259 RemoveDirectoryW(buffW);
1261 IFolderCollection_Release(folders);
1264 /* Please keep the tests for IFolderCollection and IFileCollection in sync */
1265 static void test_FileCollection(void)
1267 static const WCHAR aW[] = L"\\a";
1268 static const WCHAR bW[] = L"\\b";
1269 static const WCHAR cW[] = L"\\c";
1270 WCHAR buffW[MAX_PATH], pathW[MAX_PATH];
1271 IFolder *folder;
1272 IFileCollection *files;
1273 IFile *file;
1274 IEnumVARIANT *enumvar;
1275 LONG count, ref, ref2;
1276 IUnknown *unk, *unk2;
1277 ULONG fetched;
1278 VARIANT var, var2[2];
1279 HRESULT hr;
1280 BSTR str;
1281 HANDLE file_a, file_b, file_c;
1282 int found_a = 0, found_b = 0, found_c = 0;
1283 unsigned int i;
1285 get_temp_path(L"\\foo", buffW);
1286 CreateDirectoryW(buffW, NULL);
1288 str = SysAllocString(buffW);
1289 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1290 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1291 SysFreeString(str);
1293 hr = IFolder_get_Files(folder, NULL);
1294 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1296 lstrcpyW(pathW, buffW);
1297 lstrcatW(pathW, aW);
1298 file_a = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1299 FILE_FLAG_DELETE_ON_CLOSE, 0);
1300 lstrcpyW(pathW, buffW);
1301 lstrcatW(pathW, bW);
1302 file_b = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1303 FILE_FLAG_DELETE_ON_CLOSE, 0);
1305 hr = IFolder_get_Files(folder, &files);
1306 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1307 test_provideclassinfo(files, &CLSID_Files);
1308 IFolder_Release(folder);
1310 count = 0;
1311 hr = IFileCollection_get_Count(files, &count);
1312 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1313 ok(count == 2, "Unexpected value %lu.\n", count);
1315 lstrcpyW(pathW, buffW);
1316 lstrcatW(pathW, cW);
1317 file_c = CreateFileW(pathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1318 FILE_FLAG_DELETE_ON_CLOSE, 0);
1320 /* every time property is requested it scans directory */
1321 count = 0;
1322 hr = IFileCollection_get_Count(files, &count);
1323 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1324 ok(count == 3, "Unexpected value %lu.\n", count);
1326 hr = IFileCollection_get__NewEnum(files, NULL);
1327 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1329 hr = IFileCollection_QueryInterface(files, &IID_IEnumVARIANT, (void**)&unk);
1330 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1332 /* NewEnum creates new instance each time it's called */
1333 ref = GET_REFCOUNT(files);
1335 unk = NULL;
1336 hr = IFileCollection_get__NewEnum(files, &unk);
1337 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1339 ref2 = GET_REFCOUNT(files);
1340 ok(ref2 == ref + 1, "Unexpected value %ld, %ld.\n", ref2, ref);
1342 unk2 = NULL;
1343 hr = IFileCollection_get__NewEnum(files, &unk2);
1344 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1345 ok(unk != unk2, "got %p, %p\n", unk2, unk);
1346 IUnknown_Release(unk2);
1348 /* now get IEnumVARIANT */
1349 ref = GET_REFCOUNT(files);
1350 hr = IUnknown_QueryInterface(unk, &IID_IEnumVARIANT, (void**)&enumvar);
1351 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1352 ref2 = GET_REFCOUNT(files);
1353 ok(ref2 == ref, "Unexpected value %ld, %ld.\n", ref2, ref);
1355 test_clone(enumvar, FALSE, count);
1357 for (i = 0; i < 3; i++)
1359 VariantInit(&var);
1360 fetched = 0;
1361 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1362 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", i, hr);
1363 ok(fetched == 1, "%d: unexpected value %lu.\n", i, fetched);
1364 ok(V_VT(&var) == VT_DISPATCH, "%d: got type %d\n", i, V_VT(&var));
1366 hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IFile, (void **)&file);
1367 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1368 test_provideclassinfo(file, &CLSID_File);
1370 str = NULL;
1371 hr = IFile_get_Name(file, &str);
1372 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1373 if (!lstrcmpW(str, aW + 1))
1374 found_a++;
1375 else if (!lstrcmpW(str, bW + 1))
1376 found_b++;
1377 else if (!lstrcmpW(str, cW + 1))
1378 found_c++;
1379 else
1380 ok(0, "unexpected file %s was found\n", wine_dbgstr_w(str));
1381 SysFreeString(str);
1383 IFile_Release(file);
1384 VariantClear(&var);
1387 ok(found_a == 1 && found_b == 1 && found_c == 1,
1388 "each file should be found 1 time instead of %d/%d/%d\n",
1389 found_a, found_b, found_c);
1391 VariantInit(&var);
1392 fetched = -1;
1393 hr = IEnumVARIANT_Next(enumvar, 1, &var, &fetched);
1394 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1395 ok(!fetched, "Unexpected value %lu.\n", fetched);
1397 hr = IEnumVARIANT_Reset(enumvar);
1398 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1399 hr = IEnumVARIANT_Skip(enumvar, 2);
1400 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1401 hr = IEnumVARIANT_Skip(enumvar, 0);
1402 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1404 VariantInit(&var2[0]);
1405 VariantInit(&var2[1]);
1406 fetched = 1;
1407 hr = IEnumVARIANT_Next(enumvar, 0, var2, &fetched);
1408 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1409 ok(!fetched, "Unexpected value %lu.\n", fetched);
1410 fetched = 0;
1411 hr = IEnumVARIANT_Next(enumvar, 2, var2, &fetched);
1412 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1413 ok(fetched == 1, "Unexpected value %lu.\n", fetched);
1414 ok(V_VT(&var2[0]) == VT_DISPATCH, "got type %d\n", V_VT(&var2[0]));
1415 VariantClear(&var2[0]);
1416 VariantClear(&var2[1]);
1418 IEnumVARIANT_Release(enumvar);
1419 IUnknown_Release(unk);
1421 CloseHandle(file_a);
1422 CloseHandle(file_b);
1423 CloseHandle(file_c);
1424 RemoveDirectoryW(buffW);
1426 IFileCollection_Release(files);
1429 static void test_DriveCollection(void)
1431 IDriveCollection *drives;
1432 IEnumVARIANT *enumvar;
1433 ULONG fetched;
1434 VARIANT var;
1435 HRESULT hr;
1436 LONG count;
1438 hr = IFileSystem3_get_Drives(fs3, &drives);
1439 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1441 test_provideclassinfo(drives, &CLSID_Drives);
1443 hr = IDriveCollection_get__NewEnum(drives, (IUnknown**)&enumvar);
1444 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1446 hr = IDriveCollection_get_Count(drives, NULL);
1447 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1449 count = 0;
1450 hr = IDriveCollection_get_Count(drives, &count);
1451 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1452 ok(count > 0, "Unexpected value %ld.\n", count);
1454 V_VT(&var) = VT_EMPTY;
1455 fetched = 1;
1456 hr = IEnumVARIANT_Next(enumvar, 0, &var, &fetched);
1457 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1458 ok(!fetched, "Unexpected value %lu.\n", fetched);
1460 hr = IEnumVARIANT_Skip(enumvar, 0);
1461 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1463 hr = IEnumVARIANT_Skip(enumvar, count);
1464 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1466 hr = IEnumVARIANT_Skip(enumvar, 1);
1467 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1469 test_clone(enumvar, TRUE, count);
1471 while (IEnumVARIANT_Next(enumvar, 1, &var, &fetched) == S_OK) {
1472 IDrive *drive = (IDrive*)V_DISPATCH(&var);
1473 DriveTypeConst type;
1474 BSTR str;
1476 hr = IDrive_get_DriveType(drive, &type);
1477 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1479 hr = IDrive_get_DriveLetter(drive, NULL);
1480 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1482 hr = IDrive_get_DriveLetter(drive, &str);
1483 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1484 ok(SysStringLen(str) == 1, "got string %s\n", wine_dbgstr_w(str));
1485 SysFreeString(str);
1487 hr = IDrive_get_IsReady(drive, NULL);
1488 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1490 hr = IDrive_get_TotalSize(drive, NULL);
1491 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1493 hr = IDrive_get_AvailableSpace(drive, NULL);
1494 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1496 hr = IDrive_get_FreeSpace(drive, NULL);
1497 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1499 if (type == Fixed) {
1500 VARIANT_BOOL ready = VARIANT_FALSE;
1501 VARIANT size;
1503 hr = IDrive_get_IsReady(drive, &ready);
1504 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1505 ok(ready == VARIANT_TRUE, "got %x\n", ready);
1507 if (ready != VARIANT_TRUE) {
1508 hr = IDrive_get_DriveLetter(drive, &str);
1509 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1511 skip("Drive %s is not ready, skipping some tests\n", wine_dbgstr_w(str));
1513 VariantClear(&var);
1514 SysFreeString(str);
1515 continue;
1518 V_VT(&size) = VT_EMPTY;
1519 hr = IDrive_get_TotalSize(drive, &size);
1520 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1521 ok(V_VT(&size) == VT_R8 || V_VT(&size) == VT_I4, "got %d\n", V_VT(&size));
1522 if (V_VT(&size) == VT_R8)
1523 ok(V_R8(&size) > 0, "got %f\n", V_R8(&size));
1524 else
1525 ok(V_I4(&size) > 0, "got %ld\n", V_I4(&size));
1527 V_VT(&size) = VT_EMPTY;
1528 hr = IDrive_get_AvailableSpace(drive, &size);
1529 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1530 ok(V_VT(&size) == VT_R8 || V_VT(&size) == VT_I4, "got %d\n", V_VT(&size));
1531 if (V_VT(&size) == VT_R8)
1532 ok(V_R8(&size) > (double)INT_MAX, "got %f\n", V_R8(&size));
1533 else
1534 ok(V_I4(&size) > 0, "got %ld\n", V_I4(&size));
1536 V_VT(&size) = VT_EMPTY;
1537 hr = IDrive_get_FreeSpace(drive, &size);
1538 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1539 ok(V_VT(&size) == VT_R8 || V_VT(&size) == VT_I4, "got %d\n", V_VT(&size));
1540 if (V_VT(&size) == VT_R8)
1541 ok(V_R8(&size) > 0, "got %f\n", V_R8(&size));
1542 else
1543 ok(V_I4(&size) > 0, "got %ld\n", V_I4(&size));
1545 VariantClear(&var);
1548 IEnumVARIANT_Release(enumvar);
1549 IDriveCollection_Release(drives);
1552 static void get_temp_filepath(const WCHAR *filename, WCHAR *path, WCHAR *dir)
1554 GetTempPathW(MAX_PATH, path);
1555 lstrcatW(path, L"scrrun\\");
1556 lstrcpyW(dir, path);
1557 lstrcatW(path, filename);
1560 static void test_CreateTextFile(void)
1562 WCHAR pathW[MAX_PATH], dirW[MAX_PATH];
1563 ITextStream *stream;
1564 BSTR nameW, str;
1565 HANDLE file;
1566 HRESULT hr;
1567 BOOL ret;
1569 get_temp_filepath(testfileW, pathW, dirW);
1571 /* dir doesn't exist */
1572 nameW = SysAllocString(pathW);
1573 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1574 ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr);
1576 ret = CreateDirectoryW(dirW, NULL);
1577 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1579 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1580 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1582 test_provideclassinfo(stream, &CLSID_TextStream);
1584 hr = ITextStream_Read(stream, 1, &str);
1585 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
1587 hr = ITextStream_Close(stream);
1588 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1590 hr = ITextStream_Read(stream, 1, &str);
1591 ok(hr == CTL_E_BADFILEMODE || hr == E_VAR_NOT_SET, "Unexpected hr %#lx.\n", hr);
1593 hr = ITextStream_Close(stream);
1594 ok(hr == S_FALSE || hr == E_VAR_NOT_SET, "Unexpected hr %#lx.\n", hr);
1596 ITextStream_Release(stream);
1598 /* check it's created */
1599 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1600 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1601 CloseHandle(file);
1603 /* try to create again with no-overwrite mode */
1604 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1605 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
1607 /* now overwrite */
1608 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
1609 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1610 ITextStream_Release(stream);
1612 /* overwrite in Unicode mode, check for BOM */
1613 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_TRUE, &stream);
1614 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1615 ITextStream_Release(stream);
1617 test_file_contents(pathW,2,L"\ufeff");
1619 DeleteFileW(nameW);
1620 RemoveDirectoryW(dirW);
1621 SysFreeString(nameW);
1624 static void test_FolderCreateTextFile(void)
1626 WCHAR pathW[MAX_PATH], dirW[MAX_PATH];
1627 ITextStream *stream;
1628 BSTR nameW, str;
1629 HANDLE file;
1630 IFolder *folder;
1631 HRESULT hr;
1632 BOOL ret;
1634 get_temp_filepath(testfileW, pathW, dirW);
1635 nameW = SysAllocString(L"foo.txt");
1636 lstrcpyW(pathW, dirW);
1637 lstrcatW(pathW, nameW);
1639 ret = CreateDirectoryW(dirW, NULL);
1640 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1642 str = SysAllocString(dirW);
1643 hr = IFileSystem3_GetFolder(fs3, str, &folder);
1644 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1645 SysFreeString(str);
1647 hr = IFolder_CreateTextFile(folder, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1648 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1650 test_provideclassinfo(stream, &CLSID_TextStream);
1652 hr = ITextStream_Read(stream, 1, &str);
1653 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
1655 hr = ITextStream_Close(stream);
1656 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1658 hr = ITextStream_Read(stream, 1, &str);
1659 ok(hr == CTL_E_BADFILEMODE || hr == E_VAR_NOT_SET, "Unexpected hr %#lx.\n", hr);
1661 hr = ITextStream_Close(stream);
1662 ok(hr == S_FALSE || hr == E_VAR_NOT_SET, "Unexpected hr %#lx.\n", hr);
1664 ITextStream_Release(stream);
1666 /* check it's created */
1667 file = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1668 ok(file != INVALID_HANDLE_VALUE, "got %p\n", file);
1669 CloseHandle(file);
1671 /* try to create again with no-overwrite mode */
1672 hr = IFolder_CreateTextFile(folder, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1673 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
1675 /* now overwrite */
1676 hr = IFolder_CreateTextFile(folder, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
1677 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1678 ITextStream_Release(stream);
1680 /* overwrite in Unicode mode, check for BOM */
1681 hr = IFolder_CreateTextFile(folder, nameW, VARIANT_TRUE, VARIANT_TRUE, &stream);
1682 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1683 ITextStream_Release(stream);
1685 test_file_contents(pathW,2,L"\ufeff");
1687 DeleteFileW(pathW);
1688 RemoveDirectoryW(dirW);
1689 SysFreeString(nameW);
1692 static void test_WriteLine(void)
1694 WCHAR pathW[MAX_PATH], dirW[MAX_PATH];
1695 WCHAR ExpectedW[MAX_PATH];
1696 char ExpectedA[MAX_PATH];
1697 ITextStream *stream;
1698 DWORD len;
1699 BSTR nameW;
1700 HRESULT hr;
1701 BOOL ret;
1703 get_temp_filepath(testfileW, pathW, dirW);
1705 ret = CreateDirectoryW(dirW, NULL);
1706 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1708 /* create as ASCII file first */
1709 nameW = SysAllocString(pathW);
1710 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_FALSE, &stream);
1711 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1713 hr = ITextStream_WriteLine(stream, nameW);
1714 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1715 ITextStream_Release(stream);
1717 len = WideCharToMultiByte(CP_ACP, 0, nameW, -1, ExpectedA, ARRAY_SIZE(ExpectedA)-2, NULL, NULL);
1718 ok(len > 0, "got %ld", len);
1719 lstrcatA(ExpectedA, "\r\n");
1720 test_file_contents(pathW,lstrlenA(ExpectedA),ExpectedA);
1721 DeleteFileW(nameW);
1723 /* same for unicode file */
1724 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_TRUE, &stream);
1725 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1727 hr = ITextStream_WriteLine(stream, nameW);
1728 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1729 ITextStream_Release(stream);
1731 lstrcpyW(ExpectedW, L"\ufeff");
1732 lstrcatW(ExpectedW, nameW);
1733 lstrcatW(ExpectedW, L"\r\n");
1734 test_file_contents(pathW,lstrlenW(ExpectedW)*sizeof(WCHAR),ExpectedW);
1735 DeleteFileW(nameW);
1737 RemoveDirectoryW(dirW);
1738 SysFreeString(nameW);
1741 static void test_ReadAll(void)
1743 static const WCHAR firstlineW[] = L"first";
1744 static const WCHAR secondlineW[] = L"second";
1745 static const WCHAR aW[] = L"A";
1746 WCHAR pathW[MAX_PATH], dirW[MAX_PATH], buffW[500];
1747 char buffA[MAX_PATH];
1748 ITextStream *stream;
1749 BSTR nameW;
1750 HRESULT hr;
1751 BOOL ret;
1752 BSTR str;
1754 get_temp_filepath(testfileW, pathW, dirW);
1756 ret = CreateDirectoryW(dirW, NULL);
1757 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1759 /* Unicode file -> read with ascii stream */
1760 nameW = SysAllocString(pathW);
1761 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_TRUE, &stream);
1762 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1764 str = SysAllocString(firstlineW);
1765 hr = ITextStream_WriteLine(stream, str);
1766 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1767 SysFreeString(str);
1769 str = SysAllocString(secondlineW);
1770 hr = ITextStream_WriteLine(stream, str);
1771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1772 SysFreeString(str);
1774 hr = ITextStream_ReadAll(stream, NULL);
1775 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1777 str = (void*)0xdeadbeef;
1778 hr = ITextStream_ReadAll(stream, &str);
1779 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
1780 ok(str == NULL || broken(str == (void*)0xdeadbeef) /* win2k */, "got %p\n", str);
1782 ITextStream_Release(stream);
1784 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
1785 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1787 hr = ITextStream_ReadAll(stream, NULL);
1788 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1790 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1791 str = NULL;
1792 hr = ITextStream_ReadAll(stream, &str);
1793 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1794 buffW[0] = 0;
1795 lstrcpyA(buffA, utf16bom);
1796 lstrcatA(buffA, "first");
1797 MultiByteToWideChar(CP_ACP, 0, buffA, -1, buffW, ARRAY_SIZE(buffW));
1798 ok(str[0] == buffW[0] && str[1] == buffW[1], "got %s, %d\n", wine_dbgstr_w(str), SysStringLen(str));
1799 SysFreeString(str);
1800 ITextStream_Release(stream);
1802 /* Unicode file -> read with unicode stream */
1803 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1804 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1806 lstrcpyW(buffW, firstlineW);
1807 lstrcatW(buffW, L"\r\n");
1808 lstrcatW(buffW, secondlineW);
1809 lstrcatW(buffW, L"\r\n");
1810 str = NULL;
1811 hr = ITextStream_ReadAll(stream, &str);
1812 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1813 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1814 SysFreeString(str);
1816 /* ReadAll one more time */
1817 str = (void*)0xdeadbeef;
1818 hr = ITextStream_ReadAll(stream, &str);
1819 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1820 ok(str == NULL || broken(str == (void*)0xdeadbeef) /* win2k */, "got %p\n", str);
1822 /* ReadLine fails the same way */
1823 str = (void*)0xdeadbeef;
1824 hr = ITextStream_ReadLine(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);
1827 ITextStream_Release(stream);
1829 /* Open again and skip first line before ReadAll */
1830 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1831 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1833 str = NULL;
1834 hr = ITextStream_ReadLine(stream, &str);
1835 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1836 ok(str != NULL, "got %p\n", str);
1837 ok(!wcscmp(str, firstlineW), "got %s\n", wine_dbgstr_w(str));
1838 SysFreeString(str);
1840 lstrcpyW(buffW, secondlineW);
1841 lstrcatW(buffW, L"\r\n");
1842 str = NULL;
1843 hr = ITextStream_ReadAll(stream, &str);
1844 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1845 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1846 SysFreeString(str);
1847 ITextStream_Release(stream);
1849 /* ASCII file, read with Unicode stream */
1850 /* 1. one byte content, not enough for Unicode read */
1851 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
1852 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1853 str = SysAllocString(aW);
1854 hr = ITextStream_Write(stream, str);
1855 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1856 SysFreeString(str);
1857 ITextStream_Release(stream);
1859 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1860 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1862 str = (void*)0xdeadbeef;
1863 hr = ITextStream_ReadAll(stream, &str);
1864 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1865 ok(str == NULL || broken(str == (void*)0xdeadbeef) /* win2k */, "got %p\n", str);
1867 ITextStream_Release(stream);
1869 DeleteFileW(nameW);
1870 RemoveDirectoryW(dirW);
1871 SysFreeString(nameW);
1874 static void test_Read(void)
1876 static const WCHAR firstlineW[] = L"first";
1877 static const WCHAR secondlineW[] = L"second";
1878 WCHAR pathW[MAX_PATH], dirW[MAX_PATH], buffW[500];
1879 char buffA[MAX_PATH];
1880 ITextStream *stream;
1881 BSTR nameW;
1882 HRESULT hr;
1883 BOOL ret;
1884 BSTR str;
1886 get_temp_filepath(testfileW, pathW, dirW);
1888 ret = CreateDirectoryW(dirW, NULL);
1889 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
1891 /* Unicode file -> read with ascii stream */
1892 nameW = SysAllocString(pathW);
1893 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_FALSE, VARIANT_TRUE, &stream);
1894 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1896 str = SysAllocString(firstlineW);
1897 hr = ITextStream_WriteLine(stream, str);
1898 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1899 SysFreeString(str);
1901 str = SysAllocString(secondlineW);
1902 hr = ITextStream_WriteLine(stream, str);
1903 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1904 SysFreeString(str);
1906 hr = ITextStream_Read(stream, 0, NULL);
1907 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1909 hr = ITextStream_Read(stream, 1, NULL);
1910 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1912 hr = ITextStream_Read(stream, -1, NULL);
1913 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1915 str = (void*)0xdeadbeef;
1916 hr = ITextStream_Read(stream, 1, &str);
1917 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
1918 ok(str == NULL, "got %p\n", str);
1920 ITextStream_Release(stream);
1922 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
1923 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1925 hr = ITextStream_Read(stream, 1, NULL);
1926 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1928 str = (void*)0xdeadbeef;
1929 hr = ITextStream_Read(stream, -1, &str);
1930 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1931 ok(str == NULL, "got %p\n", str);
1933 str = (void*)0xdeadbeef;
1934 hr = ITextStream_Read(stream, 0, &str);
1935 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1936 ok(str == NULL, "got %p\n", str);
1938 /* Buffer content is not interpreted - BOM is kept, all data is converted to WCHARs */
1939 str = NULL;
1940 hr = ITextStream_Read(stream, 2, &str);
1941 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1943 buffW[0] = 0;
1944 lstrcpyA(buffA, utf16bom);
1945 lstrcatA(buffA, "first");
1946 MultiByteToWideChar(CP_ACP, 0, buffA, -1, buffW, ARRAY_SIZE(buffW));
1947 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));
1948 ok(SysStringLen(str) == 2, "got %d\n", SysStringLen(str));
1949 SysFreeString(str);
1950 ITextStream_Release(stream);
1952 /* Unicode file -> read with unicode stream */
1953 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1954 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1956 lstrcpyW(buffW, firstlineW);
1957 lstrcatW(buffW, L"\r\n");
1958 lstrcatW(buffW, secondlineW);
1959 lstrcatW(buffW, L"\r\n");
1960 str = NULL;
1961 hr = ITextStream_Read(stream, 500, &str);
1962 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1963 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1964 SysFreeString(str);
1966 /* ReadAll one more time */
1967 str = (void*)0xdeadbeef;
1968 hr = ITextStream_Read(stream, 10, &str);
1969 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1970 ok(str == NULL, "got %p\n", str);
1972 /* ReadLine fails the same way */
1973 str = (void*)0xdeadbeef;
1974 hr = ITextStream_ReadLine(stream, &str);
1975 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
1976 ok(str == NULL || broken(str == (void*)0xdeadbeef), "got %p\n", str);
1977 ITextStream_Release(stream);
1979 /* Open again and skip first line before ReadAll */
1980 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
1981 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1983 str = NULL;
1984 hr = ITextStream_ReadLine(stream, &str);
1985 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1986 ok(str != NULL, "got %p\n", str);
1987 SysFreeString(str);
1989 lstrcpyW(buffW, secondlineW);
1990 lstrcatW(buffW, L"\r\n");
1991 str = NULL;
1992 hr = ITextStream_Read(stream, 100, &str);
1993 ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
1994 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
1995 SysFreeString(str);
1996 ITextStream_Release(stream);
1998 /* default read will use Unicode */
1999 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateUseDefault, &stream);
2000 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2002 lstrcpyW(buffW, firstlineW);
2003 lstrcatW(buffW, L"\r\n");
2004 lstrcatW(buffW, secondlineW);
2005 lstrcatW(buffW, L"\r\n");
2006 str = NULL;
2007 hr = ITextStream_Read(stream, 500, &str);
2008 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2009 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
2010 SysFreeString(str);
2012 ITextStream_Release(stream);
2014 /* default append will use Unicode */
2015 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForAppending, VARIANT_FALSE, TristateUseDefault, &stream);
2016 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2018 str = SysAllocString(L"123");
2019 hr = ITextStream_Write(stream, str);
2020 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2021 SysFreeString(str);
2023 ITextStream_Release(stream);
2025 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
2026 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2028 lstrcatW(buffW, L"123");
2029 str = NULL;
2030 hr = ITextStream_Read(stream, 500, &str);
2031 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2032 ok(!lstrcmpW(buffW, str), "got %s\n", wine_dbgstr_w(str));
2033 SysFreeString(str);
2035 ITextStream_Release(stream);
2037 /* default write will use ASCII */
2038 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForWriting, 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 = (void*)0xdeadbeef;
2052 hr = ITextStream_Read(stream, 500, &str);
2053 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2054 ok(!wcscmp(str, L"123"), "got %s\n", wine_dbgstr_w(str));
2056 ITextStream_Release(stream);
2057 /* ASCII file, read with default stream */
2058 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
2059 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2060 str = SysAllocString(L"test");
2061 hr = ITextStream_Write(stream, str);
2062 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2063 SysFreeString(str);
2064 ITextStream_Release(stream);
2066 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateUseDefault, &stream);
2067 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2069 str = (void*)0xdeadbeef;
2070 hr = ITextStream_Read(stream, 500, &str);
2071 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2072 ok(!wcscmp(str, L"test"), "got %s\n", wine_dbgstr_w(str));
2074 ITextStream_Release(stream);
2076 /* default append will use Unicode */
2077 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForAppending, VARIANT_FALSE, TristateUseDefault, &stream);
2078 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2080 str = SysAllocString(L"123");
2081 hr = ITextStream_Write(stream, str);
2082 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2083 SysFreeString(str);
2085 ITextStream_Release(stream);
2087 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
2088 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2090 str = NULL;
2091 hr = ITextStream_Read(stream, 500, &str);
2092 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2093 ok(!lstrcmpW(L"test123", str), "got %s\n", wine_dbgstr_w(str));
2094 SysFreeString(str);
2096 ITextStream_Release(stream);
2098 /* default write will use ASCII as well */
2099 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForWriting, VARIANT_FALSE, TristateUseDefault, &stream);
2100 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2102 str = SysAllocString(L"test string");
2103 hr = ITextStream_Write(stream, str);
2104 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2105 SysFreeString(str);
2107 ITextStream_Release(stream);
2109 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateFalse, &stream);
2110 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2112 str = (void*)0xdeadbeef;
2113 hr = ITextStream_Read(stream, 500, &str);
2114 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2115 ok(!wcscmp(str, L"test string"), "got %s\n", wine_dbgstr_w(str));
2117 ITextStream_Release(stream);
2119 /* ASCII file, read with Unicode stream */
2120 /* 1. one byte content, not enough for Unicode read */
2121 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
2122 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2123 str = SysAllocString(L"A");
2124 hr = ITextStream_Write(stream, str);
2125 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2126 SysFreeString(str);
2127 ITextStream_Release(stream);
2129 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
2130 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2132 str = (void*)0xdeadbeef;
2133 hr = ITextStream_Read(stream, 500, &str);
2134 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
2135 ok(str == NULL, "got %p\n", str);
2137 ITextStream_Release(stream);
2139 /* ASCII file, read with Unicode stream */
2140 /* 3. one byte content, 2 are interpreted as a character, 3rd is lost */
2141 hr = IFileSystem3_CreateTextFile(fs3, nameW, VARIANT_TRUE, VARIANT_FALSE, &stream);
2142 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2143 str = SysAllocString(L"abc");
2144 hr = ITextStream_Write(stream, str);
2145 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2146 SysFreeString(str);
2147 ITextStream_Release(stream);
2149 hr = IFileSystem3_OpenTextFile(fs3, nameW, ForReading, VARIANT_FALSE, TristateTrue, &stream);
2150 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2152 str = NULL;
2153 hr = ITextStream_Read(stream, 500, &str);
2154 ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "Unexpected hr %#lx.\n", hr);
2155 ok(SysStringLen(str) == 1, "len = %u\n", SysStringLen(str));
2156 SysFreeString(str);
2158 str = (void*)0xdeadbeef;
2159 hr = ITextStream_Read(stream, 500, &str);
2160 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
2161 ok(str == NULL, "got %p\n", str);
2163 ITextStream_Release(stream);
2165 DeleteFileW(nameW);
2166 RemoveDirectoryW(dirW);
2167 SysFreeString(nameW);
2170 static void test_ReadLine(void)
2172 WCHAR path[MAX_PATH], dir[MAX_PATH];
2173 ITextStream *stream;
2174 unsigned int i;
2175 HANDLE file;
2176 DWORD size;
2177 HRESULT hr;
2178 BSTR str;
2179 BOOL ret;
2181 const char data[] = "first line\r\nsecond\n\n\rt\r\re \rst\n";
2183 get_temp_filepath(L"test.txt", path, dir);
2185 ret = CreateDirectoryW(dir, NULL);
2186 ok(ret, "Unexpected retval %d, error %ld.\n", ret, GetLastError());
2188 file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
2189 FILE_ATTRIBUTE_NORMAL, NULL);
2190 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
2192 for (i = 0; i < 1000; i++)
2193 WriteFile(file, data, strlen(data), &size, NULL);
2194 CloseHandle(file);
2196 str = SysAllocString(path);
2197 hr = IFileSystem3_OpenTextFile(fs3, str, ForReading, VARIANT_FALSE, TristateFalse, &stream);
2198 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2199 SysFreeString(str);
2201 for (i = 0; i < 1000; i++)
2203 hr = ITextStream_ReadLine(stream, &str);
2204 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2205 ok(!wcscmp(str, L"first line"), "ReadLine returned %s\n", wine_dbgstr_w(str));
2206 SysFreeString(str);
2208 hr = ITextStream_ReadLine(stream, &str);
2209 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2210 ok(!wcscmp(str, L"second"), "ReadLine returned %s\n", wine_dbgstr_w(str));
2211 SysFreeString(str);
2213 hr = ITextStream_ReadLine(stream, &str);
2214 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2215 ok(!*str, "ReadLine returned %s\n", wine_dbgstr_w(str));
2216 SysFreeString(str);
2218 hr = ITextStream_ReadLine(stream, &str);
2219 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2220 ok(!wcscmp(str, L"\rt\r\re \rst"), "ReadLine returned %s\n", wine_dbgstr_w(str));
2221 SysFreeString(str);
2224 str = NULL;
2225 hr = ITextStream_ReadLine(stream, &str);
2226 ok(hr == CTL_E_ENDOFFILE, "Unexpected hr %#lx.\n", hr);
2227 ok(!str, "ReadLine returned %s\n", wine_dbgstr_w(str));
2228 SysFreeString(str);
2230 ITextStream_Release(stream);
2232 ret = DeleteFileW(path);
2233 ok(ret, "Unexpected retval %ld.\n", GetLastError());
2235 ret = RemoveDirectoryW(dir);
2236 ok(ret, "Unexpected retval %ld.\n", GetLastError());
2239 struct driveexists_test {
2240 const WCHAR drivespec[10];
2241 const INT drivetype;
2242 const VARIANT_BOOL expected_ret;
2245 /* If 'drivetype' != -1, the first character of 'drivespec' will be replaced
2246 * with the drive letter of a drive of this type. If such a drive does not exist,
2247 * the test will be skipped. */
2248 static const struct driveexists_test driveexiststestdata[] = {
2249 { L"N:\\", DRIVE_NO_ROOT_DIR, VARIANT_FALSE },
2250 { L"R:\\", DRIVE_REMOVABLE, VARIANT_TRUE },
2251 { L"F:\\", DRIVE_FIXED, VARIANT_TRUE },
2252 { L"F:", DRIVE_FIXED, VARIANT_TRUE },
2253 { L"F?", DRIVE_FIXED, VARIANT_FALSE },
2254 { L"F", DRIVE_FIXED, VARIANT_TRUE },
2255 { L"?", -1, VARIANT_FALSE },
2256 { L"" }
2259 static void test_DriveExists(void)
2261 const struct driveexists_test *ptr = driveexiststestdata;
2262 HRESULT hr;
2263 VARIANT_BOOL ret;
2264 BSTR drivespec;
2265 WCHAR root[] = L"?:\\";
2267 hr = IFileSystem3_DriveExists(fs3, NULL, NULL);
2268 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2270 ret = VARIANT_TRUE;
2271 hr = IFileSystem3_DriveExists(fs3, NULL, &ret);
2272 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2273 ok(ret == VARIANT_FALSE, "got %x\n", ret);
2275 drivespec = SysAllocString(root);
2276 hr = IFileSystem3_DriveExists(fs3, drivespec, NULL);
2277 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2278 SysFreeString(drivespec);
2280 for (; *ptr->drivespec; ptr++) {
2281 drivespec = SysAllocString(ptr->drivespec);
2282 if (ptr->drivetype != -1) {
2283 for (root[0] = 'A'; root[0] <= 'Z'; root[0]++)
2284 if (GetDriveTypeW(root) == ptr->drivetype)
2285 break;
2286 if (root[0] > 'Z') {
2287 skip("No drive with type 0x%x found, skipping test %s.\n",
2288 ptr->drivetype, wine_dbgstr_w(ptr->drivespec));
2289 SysFreeString(drivespec);
2290 continue;
2293 /* Test both upper and lower case drive letters. */
2294 drivespec[0] = root[0];
2295 ret = ptr->expected_ret == VARIANT_TRUE ? VARIANT_FALSE : VARIANT_TRUE;
2296 hr = IFileSystem3_DriveExists(fs3, drivespec, &ret);
2297 ok(hr == S_OK, "Unexpected hr %#lx. for drive spec %s (%s)\n",
2298 hr, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec));
2299 ok(ret == ptr->expected_ret, "got %d, expected %d for drive spec %s (%s)\n",
2300 ret, ptr->expected_ret, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec));
2302 drivespec[0] = tolower(root[0]);
2305 ret = ptr->expected_ret == VARIANT_TRUE ? VARIANT_FALSE : VARIANT_TRUE;
2306 hr = IFileSystem3_DriveExists(fs3, drivespec, &ret);
2307 ok(hr == S_OK, "Unexpected hr %#lx. for drive spec %s (%s)\n",
2308 hr, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec));
2309 ok(ret == ptr->expected_ret, "got %d, expected %d for drive spec %s (%s)\n",
2310 ret, ptr->expected_ret, wine_dbgstr_w(drivespec), wine_dbgstr_w(ptr->drivespec));
2312 SysFreeString(drivespec);
2316 struct getdrivename_test {
2317 const WCHAR path[10];
2318 const WCHAR drive[5];
2321 static const struct getdrivename_test getdrivenametestdata[] = {
2322 { L"C:\\1.tst", L"C:" },
2323 { L"O:\\1.tst", L"O:" },
2324 { L"O:", L"O:" },
2325 { L"o:", L"o:" },
2326 { L"OO:" },
2327 { L":" },
2328 { L"O" },
2329 { L"" }
2332 static void test_GetDriveName(void)
2334 const struct getdrivename_test *ptr = getdrivenametestdata;
2335 HRESULT hr;
2336 BSTR name;
2338 hr = IFileSystem3_GetDriveName(fs3, NULL, NULL);
2339 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2341 name = (void*)0xdeadbeef;
2342 hr = IFileSystem3_GetDriveName(fs3, NULL, &name);
2343 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2344 ok(name == NULL, "got %p\n", name);
2346 while (*ptr->path) {
2347 BSTR path = SysAllocString(ptr->path);
2348 name = (void*)0xdeadbeef;
2349 hr = IFileSystem3_GetDriveName(fs3, path, &name);
2350 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2351 if (name)
2352 ok(!lstrcmpW(ptr->drive, name), "got %s, expected %s\n", wine_dbgstr_w(name), wine_dbgstr_w(ptr->drive));
2353 else
2354 ok(!*ptr->drive, "got %s, expected %s\n", wine_dbgstr_w(name), wine_dbgstr_w(ptr->drive));
2355 SysFreeString(path);
2356 SysFreeString(name);
2357 ptr++;
2361 struct getdrive_test {
2362 const WCHAR drivespec[12];
2363 HRESULT res;
2364 const WCHAR driveletter[2];
2367 static void test_GetDrive(void)
2369 HRESULT hr;
2370 IDrive *drive_fixed, *drive;
2371 BSTR dl_fixed, drivespec;
2372 WCHAR root[] = L"?:\\";
2374 drive = (void*)0xdeadbeef;
2375 hr = IFileSystem3_GetDrive(fs3, NULL, NULL);
2376 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2377 ok(drive == (void*)0xdeadbeef, "got %p\n", drive);
2379 for (root[0] = 'A'; root[0] <= 'Z'; root[0]++)
2380 if (GetDriveTypeW(root) == DRIVE_NO_ROOT_DIR)
2381 break;
2383 if (root[0] > 'Z')
2384 skip("All drive letters are occupied, skipping test for nonexisting drive.\n");
2385 else {
2386 drivespec = SysAllocString(root);
2387 drive = (void*)0xdeadbeef;
2388 hr = IFileSystem3_GetDrive(fs3, drivespec, &drive);
2389 ok(hr == CTL_E_DEVICEUNAVAILABLE, "Unexpected hr %#lx.\n", hr);
2390 ok(drive == NULL, "got %p\n", drive);
2391 SysFreeString(drivespec);
2394 drive_fixed = get_fixed_drive();
2395 if (!drive_fixed) {
2396 skip("No fixed drive found, skipping test.\n");
2397 return;
2400 hr = IDrive_get_DriveLetter(drive_fixed, &dl_fixed);
2401 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2403 if (FAILED(hr))
2404 skip("Could not retrieve drive letter of fixed drive, skipping test.\n");
2405 else {
2406 WCHAR dl_upper = toupper(dl_fixed[0]);
2407 WCHAR dl_lower = tolower(dl_fixed[0]);
2408 struct getdrive_test testdata[] = {
2409 { {dl_upper,0}, S_OK, {dl_upper,0} },
2410 { {dl_upper,':',0}, S_OK, {dl_upper,0} },
2411 { {dl_upper,':','\\',0}, S_OK, {dl_upper,0} },
2412 { {dl_lower,':','\\',0}, S_OK, {dl_upper,0} },
2413 { {dl_upper,'\\',0 }, E_INVALIDARG, L""},
2414 { {dl_lower,'\\',0 }, E_INVALIDARG, L""},
2415 { L"$:\\", E_INVALIDARG, L"" },
2416 { L"\\host\\share", E_INVALIDARG, L"" },
2417 { L"host\\share", E_INVALIDARG, L"" },
2418 { L"" },
2420 struct getdrive_test *ptr = &testdata[0];
2422 for (; *ptr->drivespec; ptr++) {
2423 drivespec = SysAllocString(ptr->drivespec);
2424 drive = (void*)0xdeadbeef;
2425 hr = IFileSystem3_GetDrive(fs3, drivespec, &drive);
2426 ok(hr == ptr->res, "Unexpected hr %#lx, expected %#lx for drive spec %s.\n",
2427 hr, ptr->res, wine_dbgstr_w(ptr->drivespec));
2428 ok(!lstrcmpW(ptr->drivespec, drivespec), "GetDrive modified its DriveSpec argument\n");
2429 SysFreeString(drivespec);
2431 if (*ptr->driveletter) {
2432 BSTR driveletter;
2433 hr = IDrive_get_DriveLetter(drive, &driveletter);
2434 ok(hr == S_OK, "Unexpected hr %#lx. for drive spec %s\n", hr, wine_dbgstr_w(ptr->drivespec));
2435 if (SUCCEEDED(hr)) {
2436 ok(!lstrcmpW(ptr->driveletter, driveletter), "got %s, expected %s for drive spec %s\n",
2437 wine_dbgstr_w(driveletter), wine_dbgstr_w(ptr->driveletter),
2438 wine_dbgstr_w(ptr->drivespec));
2439 SysFreeString(driveletter);
2441 test_provideclassinfo(drive, &CLSID_Drive);
2442 IDrive_Release(drive);
2443 } else
2444 ok(drive == NULL, "got %p for drive spec %s\n", drive, wine_dbgstr_w(ptr->drivespec));
2446 SysFreeString(dl_fixed);
2450 static void test_SerialNumber(void)
2452 IDrive *drive;
2453 LONG serial;
2454 HRESULT hr;
2455 BSTR name;
2457 drive = get_fixed_drive();
2458 if (!drive) {
2459 skip("No fixed drive found, skipping test.\n");
2460 return;
2463 hr = IDrive_get_SerialNumber(drive, NULL);
2464 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2466 serial = 0xdeadbeef;
2467 hr = IDrive_get_SerialNumber(drive, &serial);
2468 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2469 ok(serial != 0xdeadbeef, "Unexpected value %#lx.\n", serial);
2471 hr = IDrive_get_FileSystem(drive, NULL);
2472 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2474 name = NULL;
2475 hr = IDrive_get_FileSystem(drive, &name);
2476 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2477 ok(name != NULL, "got %p\n", name);
2478 SysFreeString(name);
2480 hr = IDrive_get_VolumeName(drive, NULL);
2481 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2483 name = NULL;
2484 hr = IDrive_get_VolumeName(drive, &name);
2485 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2486 ok(name != NULL, "got %p\n", name);
2487 SysFreeString(name);
2489 IDrive_Release(drive);
2492 static const struct extension_test {
2493 WCHAR path[20];
2494 WCHAR ext[10];
2495 } extension_tests[] = {
2496 { L"noext", L"" },
2497 { L"n.o.ext", L"ext" },
2498 { L"n.o.eXt", L"eXt" },
2499 { L"" }
2502 static void test_GetExtensionName(void)
2504 BSTR path, ext;
2505 HRESULT hr;
2506 int i;
2508 for (i = 0; i < ARRAY_SIZE(extension_tests); i++) {
2510 path = SysAllocString(extension_tests[i].path);
2511 ext = NULL;
2512 hr = IFileSystem3_GetExtensionName(fs3, path, &ext);
2513 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2514 if (*extension_tests[i].ext)
2515 ok(!lstrcmpW(ext, extension_tests[i].ext), "%d: path %s, got %s, expected %s\n", i,
2516 wine_dbgstr_w(path), wine_dbgstr_w(ext), wine_dbgstr_w(extension_tests[i].ext));
2517 else
2518 ok(ext == NULL, "%d: path %s, got %s, expected %s\n", i,
2519 wine_dbgstr_w(path), wine_dbgstr_w(ext), wine_dbgstr_w(extension_tests[i].ext));
2521 SysFreeString(path);
2522 SysFreeString(ext);
2526 static void test_GetSpecialFolder(void)
2528 WCHAR pathW[MAX_PATH];
2529 IFolder *folder;
2530 HRESULT hr;
2531 DWORD ret;
2532 BSTR path;
2534 hr = IFileSystem3_GetSpecialFolder(fs3, WindowsFolder, NULL);
2535 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2537 hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder+1, NULL);
2538 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2540 hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder+1, &folder);
2541 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2543 hr = IFileSystem3_GetSpecialFolder(fs3, WindowsFolder, &folder);
2544 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2545 hr = IFolder_get_Path(folder, &path);
2546 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2547 GetWindowsDirectoryW(pathW, ARRAY_SIZE(pathW));
2548 ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW));
2549 SysFreeString(path);
2550 IFolder_Release(folder);
2552 hr = IFileSystem3_GetSpecialFolder(fs3, SystemFolder, &folder);
2553 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2554 hr = IFolder_get_Path(folder, &path);
2555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2556 GetSystemDirectoryW(pathW, ARRAY_SIZE(pathW));
2557 ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW));
2558 SysFreeString(path);
2559 IFolder_Release(folder);
2561 hr = IFileSystem3_GetSpecialFolder(fs3, TemporaryFolder, &folder);
2562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2563 hr = IFolder_get_Path(folder, &path);
2564 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2565 ret = GetTempPathW(ARRAY_SIZE(pathW), pathW);
2566 if (ret && pathW[ret-1] == '\\')
2567 pathW[ret-1] = 0;
2569 ok(!lstrcmpiW(pathW, path), "got %s, expected %s\n", wine_dbgstr_w(path), wine_dbgstr_w(pathW));
2570 SysFreeString(path);
2571 IFolder_Release(folder);
2574 static void test_MoveFile(void)
2576 ITextStream *stream;
2577 BSTR str, src, dst;
2578 HRESULT hr;
2580 str = SysAllocString(L"test.txt");
2581 hr = IFileSystem3_CreateTextFile(fs3, str, VARIANT_FALSE, VARIANT_FALSE, &stream);
2582 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2583 SysFreeString(str);
2585 str = SysAllocString(L"test");
2586 hr = ITextStream_Write(stream, str);
2587 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2588 SysFreeString(str);
2590 ITextStream_Release(stream);
2592 str = SysAllocString(L"test2.txt");
2593 hr = IFileSystem3_CreateTextFile(fs3, str, VARIANT_FALSE, VARIANT_FALSE, &stream);
2594 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2595 SysFreeString(str);
2596 ITextStream_Release(stream);
2598 src = SysAllocString(L"test.txt");
2599 dst = SysAllocString(L"test3.txt");
2600 hr = IFileSystem3_MoveFile(fs3, src, dst);
2601 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2602 SysFreeString(src);
2603 SysFreeString(dst);
2605 str = SysAllocString(L"test.txt");
2606 hr = IFileSystem3_DeleteFile(fs3, str, VARIANT_TRUE);
2607 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
2608 SysFreeString(str);
2610 src = SysAllocString(L"test3.txt");
2611 dst = SysAllocString(L"test2.txt"); /* already exists */
2612 hr = IFileSystem3_MoveFile(fs3, src, dst);
2613 ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr);
2614 SysFreeString(src);
2615 SysFreeString(dst);
2617 src = SysAllocString(L"nonexistent.txt");
2618 dst = SysAllocString(L"test4.txt");
2619 hr = IFileSystem3_MoveFile(fs3, src, dst);
2620 ok(hr == CTL_E_FILENOTFOUND, "Unexpected hr %#lx.\n", hr);
2621 SysFreeString(src);
2622 SysFreeString(dst);
2624 str = SysAllocString(L"test3.txt");
2625 hr = IFileSystem3_DeleteFile(fs3, str, VARIANT_TRUE);
2626 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2627 SysFreeString(str);
2629 str = SysAllocString(L"test2.txt");
2630 hr = IFileSystem3_DeleteFile(fs3, str, VARIANT_TRUE);
2631 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2632 SysFreeString(str);
2634 str = SysAllocString(L"null.txt");
2635 hr = IFileSystem3_MoveFile(fs3, str, NULL);
2636 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2637 hr = IFileSystem3_MoveFile(fs3, NULL, str);
2638 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2639 SysFreeString(str);
2642 static void test_DoOpenPipeStream(void)
2644 static const char testdata[] = "test";
2645 ITextStream *stream_read, *stream_write;
2646 SECURITY_ATTRIBUTES pipe_attr;
2647 HANDLE piperead, pipewrite;
2648 DWORD written;
2649 HRESULT hr;
2650 BSTR str;
2651 BOOL ret;
2653 pDoOpenPipeStream = (void *)GetProcAddress(GetModuleHandleA("scrrun.dll"), "DoOpenPipeStream");
2655 pipe_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
2656 pipe_attr.bInheritHandle = TRUE;
2657 pipe_attr.lpSecurityDescriptor = NULL;
2658 ret = CreatePipe(&piperead, &pipewrite, &pipe_attr, 0);
2659 ok(ret, "Failed to create pipes.\n");
2661 hr = pDoOpenPipeStream(piperead, ForReading, &stream_read);
2662 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2663 if (SUCCEEDED(hr))
2665 ok(!!stream_read, "Unexpected stream pointer.\n");
2667 ret = WriteFile(pipewrite, testdata, sizeof(testdata), &written, NULL);
2668 ok(ret, "Failed to write to the pipe.\n");
2669 ok(written == sizeof(testdata), "Write to anonymous pipe wrote %ld bytes.\n", written);
2671 hr = ITextStream_Read(stream_read, 4, &str);
2672 todo_wine
2673 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2674 if (SUCCEEDED(hr))
2676 ok(!wcscmp(str, L"test"), "Unexpected data read %s.\n", wine_dbgstr_w(str));
2677 SysFreeString(str);
2680 ITextStream_Release(stream_read);
2683 ret = CloseHandle(pipewrite);
2684 ok(ret, "Unexpected return value.\n");
2685 /* Stream takes ownership. */
2686 ret = CloseHandle(piperead);
2687 ok(!ret, "Unexpected return value.\n");
2689 /* Streams on both ends. */
2690 ret = CreatePipe(&piperead, &pipewrite, &pipe_attr, 0);
2691 ok(ret, "Failed to create pipes.\n");
2693 stream_read = NULL;
2694 hr = pDoOpenPipeStream(piperead, ForReading, &stream_read);
2695 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2697 stream_write = NULL;
2698 hr = pDoOpenPipeStream(pipewrite, ForWriting, &stream_write);
2699 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2701 if (SUCCEEDED(hr))
2703 str = SysAllocString(L"data");
2704 hr = ITextStream_Write(stream_write, str);
2705 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2707 hr = ITextStream_Write(stream_read, str);
2708 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
2710 SysFreeString(str);
2712 hr = ITextStream_Read(stream_write, 1, &str);
2713 todo_wine
2714 ok(hr == CTL_E_BADFILEMODE, "Unexpected hr %#lx.\n", hr);
2716 hr = ITextStream_Read(stream_read, 4, &str);
2717 todo_wine
2718 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2719 if (SUCCEEDED(hr))
2721 ok(!wcscmp(str, L"data"), "Unexpected data.\n");
2722 SysFreeString(str);
2726 if (stream_read)
2727 ITextStream_Release(stream_read);
2728 if (stream_write)
2729 ITextStream_Release(stream_write);
2732 START_TEST(filesystem)
2734 HRESULT hr;
2736 CoInitialize(NULL);
2738 hr = CoCreateInstance(&CLSID_FileSystemObject, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2739 &IID_IFileSystem3, (void**)&fs3);
2740 if(FAILED(hr))
2742 win_skip("Could not create FileSystem object, hr %#lx.\n", hr);
2743 return;
2746 test_interfaces();
2747 test_createfolder();
2748 test_textstream();
2749 test_GetFileVersion();
2750 test_GetParentFolderName();
2751 test_GetFileName();
2752 test_GetBaseName();
2753 test_GetAbsolutePathName();
2754 test_GetFile();
2755 test_GetTempName();
2756 test_CopyFolder();
2757 test_BuildPath();
2758 test_GetFolder();
2759 test_FolderCollection();
2760 test_FileCollection();
2761 test_DriveCollection();
2762 test_CreateTextFile();
2763 test_FolderCreateTextFile();
2764 test_WriteLine();
2765 test_ReadAll();
2766 test_Read();
2767 test_ReadLine();
2768 test_DriveExists();
2769 test_GetDriveName();
2770 test_GetDrive();
2771 test_SerialNumber();
2772 test_GetExtensionName();
2773 test_GetSpecialFolder();
2774 test_MoveFile();
2775 test_DoOpenPipeStream();
2777 IFileSystem3_Release(fs3);
2779 CoUninitialize();