scrrun: Improve OpenTextFile stub.
[wine] / dlls / scrrun / filesystem.c
1 /*
2  * Copyright 2012 Alistair Leslie-Hughes
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20
21 #include "config.h"
22 #include <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "ole2.h"
27 #include "olectl.h"
28 #include "dispex.h"
29 #include "scrrun.h"
30 #include "scrrun_private.h"
31
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(scrrun);
35
36 struct folder {
37     IFolder IFolder_iface;
38     LONG ref;
39 };
40
41 struct textstream {
42     ITextStream ITextStream_iface;
43     LONG ref;
44 };
45
46 static inline struct folder *impl_from_IFolder(IFolder *iface)
47 {
48     return CONTAINING_RECORD(iface, struct folder, IFolder_iface);
49 }
50
51 static inline struct textstream *impl_from_ITextStream(ITextStream *iface)
52 {
53     return CONTAINING_RECORD(iface, struct textstream, ITextStream_iface);
54 }
55
56 static HRESULT WINAPI textstream_QueryInterface(ITextStream *iface, REFIID riid, void **obj)
57 {
58     struct textstream *This = impl_from_ITextStream(iface);
59
60     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
61
62     if (IsEqualIID(riid, &IID_ITextStream) ||
63         IsEqualIID(riid, &IID_IDispatch) ||
64         IsEqualIID(riid, &IID_IUnknown))
65     {
66         *obj = iface;
67         ITextStream_AddRef(iface);
68         return S_OK;
69     }
70
71     *obj = NULL;
72     return E_NOINTERFACE;
73 }
74
75 static ULONG WINAPI textstream_AddRef(ITextStream *iface)
76 {
77     struct textstream *This = impl_from_ITextStream(iface);
78     ULONG ref = InterlockedIncrement(&This->ref);
79     TRACE("(%p)->(%d)\n", This, ref);
80     return ref;
81 }
82
83 static ULONG WINAPI textstream_Release(ITextStream *iface)
84 {
85     struct textstream *This = impl_from_ITextStream(iface);
86     ULONG ref = InterlockedDecrement(&This->ref);
87     TRACE("(%p)->(%d)\n", This, ref);
88
89     if (!ref)
90         heap_free(This);
91
92     return ref;
93 }
94
95 static HRESULT WINAPI textstream_GetTypeInfoCount(ITextStream *iface, UINT *pctinfo)
96 {
97     struct textstream *This = impl_from_ITextStream(iface);
98     TRACE("(%p)->(%p)\n", This, pctinfo);
99     *pctinfo = 1;
100     return S_OK;
101 }
102
103 static HRESULT WINAPI textstream_GetTypeInfo(ITextStream *iface, UINT iTInfo,
104                                         LCID lcid, ITypeInfo **ppTInfo)
105 {
106     struct textstream *This = impl_from_ITextStream(iface);
107     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
108     return get_typeinfo(ITextStream_tid, ppTInfo);
109 }
110
111 static HRESULT WINAPI textstream_GetIDsOfNames(ITextStream *iface, REFIID riid,
112                                         LPOLESTR *rgszNames, UINT cNames,
113                                         LCID lcid, DISPID *rgDispId)
114 {
115     struct textstream *This = impl_from_ITextStream(iface);
116     ITypeInfo *typeinfo;
117     HRESULT hr;
118
119     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
120
121     hr = get_typeinfo(ITextStream_tid, &typeinfo);
122     if(SUCCEEDED(hr))
123     {
124         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
125         ITypeInfo_Release(typeinfo);
126     }
127
128     return hr;
129 }
130
131 static HRESULT WINAPI textstream_Invoke(ITextStream *iface, DISPID dispIdMember,
132                                       REFIID riid, LCID lcid, WORD wFlags,
133                                       DISPPARAMS *pDispParams, VARIANT *pVarResult,
134                                       EXCEPINFO *pExcepInfo, UINT *puArgErr)
135 {
136     struct textstream *This = impl_from_ITextStream(iface);
137     ITypeInfo *typeinfo;
138     HRESULT hr;
139
140     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
141            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
142
143     hr = get_typeinfo(ITextStream_tid, &typeinfo);
144     if(SUCCEEDED(hr))
145     {
146         hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
147                 pDispParams, pVarResult, pExcepInfo, puArgErr);
148         ITypeInfo_Release(typeinfo);
149     }
150
151     return hr;
152 }
153
154 static HRESULT WINAPI textstream_get_Line(ITextStream *iface, LONG *line)
155 {
156     struct textstream *This = impl_from_ITextStream(iface);
157     FIXME("(%p)->(%p): stub\n", This, line);
158     return E_NOTIMPL;
159 }
160
161 static HRESULT WINAPI textstream_get_Column(ITextStream *iface, LONG *column)
162 {
163     struct textstream *This = impl_from_ITextStream(iface);
164     FIXME("(%p)->(%p): stub\n", This, column);
165     return E_NOTIMPL;
166 }
167
168 static HRESULT WINAPI textstream_get_AtEndOfStream(ITextStream *iface, VARIANT_BOOL *eos)
169 {
170     struct textstream *This = impl_from_ITextStream(iface);
171     FIXME("(%p)->(%p): stub\n", This, eos);
172     return E_NOTIMPL;
173 }
174
175 static HRESULT WINAPI textstream_get_AtEndOfLine(ITextStream *iface, VARIANT_BOOL *eol)
176 {
177     struct textstream *This = impl_from_ITextStream(iface);
178     FIXME("(%p)->(%p): stub\n", This, eol);
179     return E_NOTIMPL;
180 }
181
182 static HRESULT WINAPI textstream_Read(ITextStream *iface, LONG len, BSTR *text)
183 {
184     struct textstream *This = impl_from_ITextStream(iface);
185     FIXME("(%p)->(%p): stub\n", This, text);
186     return E_NOTIMPL;
187 }
188
189 static HRESULT WINAPI textstream_ReadLine(ITextStream *iface, BSTR *text)
190 {
191     struct textstream *This = impl_from_ITextStream(iface);
192     FIXME("(%p)->(%p): stub\n", This, text);
193     return E_NOTIMPL;
194 }
195
196 static HRESULT WINAPI textstream_ReadAll(ITextStream *iface, BSTR *text)
197 {
198     struct textstream *This = impl_from_ITextStream(iface);
199     FIXME("(%p)->(%p): stub\n", This, text);
200     return E_NOTIMPL;
201 }
202
203 static HRESULT WINAPI textstream_Write(ITextStream *iface, BSTR text)
204 {
205     struct textstream *This = impl_from_ITextStream(iface);
206     FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
207     return E_NOTIMPL;
208 }
209
210 static HRESULT WINAPI textstream_WriteLine(ITextStream *iface, BSTR text)
211 {
212     struct textstream *This = impl_from_ITextStream(iface);
213     FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
214     return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI textstream_WriteBlankLines(ITextStream *iface, LONG lines)
218 {
219     struct textstream *This = impl_from_ITextStream(iface);
220     FIXME("(%p)->(%d): stub\n", This, lines);
221     return E_NOTIMPL;
222 }
223
224 static HRESULT WINAPI textstream_Skip(ITextStream *iface, LONG count)
225 {
226     struct textstream *This = impl_from_ITextStream(iface);
227     FIXME("(%p)->(%d): stub\n", This, count);
228     return E_NOTIMPL;
229 }
230
231 static HRESULT WINAPI textstream_SkipLine(ITextStream *iface)
232 {
233     struct textstream *This = impl_from_ITextStream(iface);
234     FIXME("(%p): stub\n", This);
235     return E_NOTIMPL;
236 }
237
238 static HRESULT WINAPI textstream_Close(ITextStream *iface)
239 {
240     struct textstream *This = impl_from_ITextStream(iface);
241     FIXME("(%p): stub\n", This);
242     return E_NOTIMPL;
243 }
244
245 static const ITextStreamVtbl textstreamvtbl = {
246     textstream_QueryInterface,
247     textstream_AddRef,
248     textstream_Release,
249     textstream_GetTypeInfoCount,
250     textstream_GetTypeInfo,
251     textstream_GetIDsOfNames,
252     textstream_Invoke,
253     textstream_get_Line,
254     textstream_get_Column,
255     textstream_get_AtEndOfStream,
256     textstream_get_AtEndOfLine,
257     textstream_Read,
258     textstream_ReadLine,
259     textstream_ReadAll,
260     textstream_Write,
261     textstream_WriteLine,
262     textstream_WriteBlankLines,
263     textstream_Skip,
264     textstream_SkipLine,
265     textstream_Close
266 };
267
268 static HRESULT create_textstream(ITextStream **ret)
269 {
270     struct textstream *stream;
271
272     stream = heap_alloc(sizeof(struct textstream));
273     if (!stream) return E_OUTOFMEMORY;
274
275     stream->ITextStream_iface.lpVtbl = &textstreamvtbl;
276     stream->ref = 1;
277
278     *ret = &stream->ITextStream_iface;
279     return S_OK;
280 }
281
282 static HRESULT WINAPI folder_QueryInterface(IFolder *iface, REFIID riid, void **obj)
283 {
284     struct folder *This = impl_from_IFolder(iface);
285
286     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
287
288     *obj = NULL;
289
290     if (IsEqualGUID( riid, &IID_IFolder ) ||
291         IsEqualGUID( riid, &IID_IUnknown))
292     {
293         *obj = iface;
294         IFolder_AddRef(iface);
295     }
296     else
297         return E_NOINTERFACE;
298
299     return S_OK;
300 }
301
302 static ULONG WINAPI folder_AddRef(IFolder *iface)
303 {
304     struct folder *This = impl_from_IFolder(iface);
305     ULONG ref = InterlockedIncrement(&This->ref);
306     TRACE("(%p)->(%d)\n", This, ref);
307     return ref;
308 }
309
310 static ULONG WINAPI folder_Release(IFolder *iface)
311 {
312     struct folder *This = impl_from_IFolder(iface);
313     ULONG ref = InterlockedDecrement(&This->ref);
314     TRACE("(%p)->(%d)\n", This, ref);
315
316     if (!ref)
317         heap_free(This);
318
319     return ref;
320 }
321
322 static HRESULT WINAPI folder_GetTypeInfoCount(IFolder *iface, UINT *pctinfo)
323 {
324     struct folder *This = impl_from_IFolder(iface);
325     TRACE("(%p)->(%p)\n", This, pctinfo);
326     *pctinfo = 1;
327     return S_OK;
328 }
329
330 static HRESULT WINAPI folder_GetTypeInfo(IFolder *iface, UINT iTInfo,
331                                         LCID lcid, ITypeInfo **ppTInfo)
332 {
333     struct folder *This = impl_from_IFolder(iface);
334     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
335     return get_typeinfo(IFolder_tid, ppTInfo);
336 }
337
338 static HRESULT WINAPI folder_GetIDsOfNames(IFolder *iface, REFIID riid,
339                                         LPOLESTR *rgszNames, UINT cNames,
340                                         LCID lcid, DISPID *rgDispId)
341 {
342     struct folder *This = impl_from_IFolder(iface);
343     ITypeInfo *typeinfo;
344     HRESULT hr;
345
346     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
347
348     hr = get_typeinfo(IFolder_tid, &typeinfo);
349     if(SUCCEEDED(hr))
350     {
351         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
352         ITypeInfo_Release(typeinfo);
353     }
354
355     return hr;
356 }
357
358 static HRESULT WINAPI folder_Invoke(IFolder *iface, DISPID dispIdMember,
359                                       REFIID riid, LCID lcid, WORD wFlags,
360                                       DISPPARAMS *pDispParams, VARIANT *pVarResult,
361                                       EXCEPINFO *pExcepInfo, UINT *puArgErr)
362 {
363     struct folder *This = impl_from_IFolder(iface);
364     ITypeInfo *typeinfo;
365     HRESULT hr;
366
367     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
368            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
369
370     hr = get_typeinfo(IFolder_tid, &typeinfo);
371     if(SUCCEEDED(hr))
372     {
373         hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
374                 pDispParams, pVarResult, pExcepInfo, puArgErr);
375         ITypeInfo_Release(typeinfo);
376     }
377
378     return hr;
379 }
380
381 static HRESULT WINAPI folder_get_Path(IFolder *iface, BSTR *path)
382 {
383     struct folder *This = impl_from_IFolder(iface);
384     FIXME("(%p)->(%p): stub\n", This, path);
385     return E_NOTIMPL;
386 }
387
388 static HRESULT WINAPI folder_get_Name(IFolder *iface, BSTR *name)
389 {
390     struct folder *This = impl_from_IFolder(iface);
391     FIXME("(%p)->(%p): stub\n", This, name);
392     return E_NOTIMPL;
393 }
394
395 static HRESULT WINAPI folder_put_Name(IFolder *iface, BSTR name)
396 {
397     struct folder *This = impl_from_IFolder(iface);
398     FIXME("(%p)->(%s): stub\n", This, debugstr_w(name));
399     return E_NOTIMPL;
400 }
401
402 static HRESULT WINAPI folder_get_ShortPath(IFolder *iface, BSTR *path)
403 {
404     struct folder *This = impl_from_IFolder(iface);
405     FIXME("(%p)->(%p): stub\n", This, path);
406     return E_NOTIMPL;
407 }
408
409 static HRESULT WINAPI folder_get_ShortName(IFolder *iface, BSTR *name)
410 {
411     struct folder *This = impl_from_IFolder(iface);
412     FIXME("(%p)->(%p): stub\n", This, name);
413     return E_NOTIMPL;
414 }
415
416 static HRESULT WINAPI folder_get_Drive(IFolder *iface, IDrive **drive)
417 {
418     struct folder *This = impl_from_IFolder(iface);
419     FIXME("(%p)->(%p): stub\n", This, drive);
420     return E_NOTIMPL;
421 }
422
423 static HRESULT WINAPI folder_get_ParentFolder(IFolder *iface, IFolder **parent)
424 {
425     struct folder *This = impl_from_IFolder(iface);
426     FIXME("(%p)->(%p): stub\n", This, parent);
427     return E_NOTIMPL;
428 }
429
430 static HRESULT WINAPI folder_get_Attributes(IFolder *iface, FileAttribute *attr)
431 {
432     struct folder *This = impl_from_IFolder(iface);
433     FIXME("(%p)->(%p): stub\n", This, attr);
434     return E_NOTIMPL;
435 }
436
437 static HRESULT WINAPI folder_put_Attributes(IFolder *iface, FileAttribute attr)
438 {
439     struct folder *This = impl_from_IFolder(iface);
440     FIXME("(%p)->(0x%x): stub\n", This, attr);
441     return E_NOTIMPL;
442 }
443
444 static HRESULT WINAPI folder_get_DateCreated(IFolder *iface, DATE *date)
445 {
446     struct folder *This = impl_from_IFolder(iface);
447     FIXME("(%p)->(%p): stub\n", This, date);
448     return E_NOTIMPL;
449 }
450
451 static HRESULT WINAPI folder_get_DateLastModified(IFolder *iface, DATE *date)
452 {
453     struct folder *This = impl_from_IFolder(iface);
454     FIXME("(%p)->(%p): stub\n", This, date);
455     return E_NOTIMPL;
456 }
457
458 static HRESULT WINAPI folder_get_DateLastAccessed(IFolder *iface, DATE *date)
459 {
460     struct folder *This = impl_from_IFolder(iface);
461     FIXME("(%p)->(%p): stub\n", This, date);
462     return E_NOTIMPL;
463 }
464
465 static HRESULT WINAPI folder_get_Type(IFolder *iface, BSTR *type)
466 {
467     struct folder *This = impl_from_IFolder(iface);
468     FIXME("(%p)->(%p): stub\n", This, type);
469     return E_NOTIMPL;
470 }
471
472 static HRESULT WINAPI folder_Delete(IFolder *iface, VARIANT_BOOL force)
473 {
474     struct folder *This = impl_from_IFolder(iface);
475     FIXME("(%p)->(%x): stub\n", This, force);
476     return E_NOTIMPL;
477 }
478
479 static HRESULT WINAPI folder_Copy(IFolder *iface, BSTR dest, VARIANT_BOOL overwrite)
480 {
481     struct folder *This = impl_from_IFolder(iface);
482     FIXME("(%p)->(%s %x): stub\n", This, debugstr_w(dest), overwrite);
483     return E_NOTIMPL;
484 }
485
486 static HRESULT WINAPI folder_Move(IFolder *iface, BSTR dest)
487 {
488     struct folder *This = impl_from_IFolder(iface);
489     FIXME("(%p)->(%s): stub\n", This, debugstr_w(dest));
490     return E_NOTIMPL;
491 }
492
493 static HRESULT WINAPI folder_get_IsRootFolder(IFolder *iface, VARIANT_BOOL *isroot)
494 {
495     struct folder *This = impl_from_IFolder(iface);
496     FIXME("(%p)->(%p): stub\n", This, isroot);
497     return E_NOTIMPL;
498 }
499
500 static HRESULT WINAPI folder_get_Size(IFolder *iface, VARIANT *size)
501 {
502     struct folder *This = impl_from_IFolder(iface);
503     FIXME("(%p)->(%p): stub\n", This, size);
504     return E_NOTIMPL;
505 }
506
507 static HRESULT WINAPI folder_get_SubFolders(IFolder *iface, IFolderCollection **folders)
508 {
509     struct folder *This = impl_from_IFolder(iface);
510     FIXME("(%p)->(%p): stub\n", This, folders);
511     return E_NOTIMPL;
512 }
513
514 static HRESULT WINAPI folder_get_Files(IFolder *iface, IFileCollection **files)
515 {
516     struct folder *This = impl_from_IFolder(iface);
517     FIXME("(%p)->(%p): stub\n", This, files);
518     return E_NOTIMPL;
519 }
520
521 static HRESULT WINAPI folder_CreateTextFile(IFolder *iface, BSTR filename, VARIANT_BOOL overwrite,
522     VARIANT_BOOL unicode, ITextStream **stream)
523 {
524     struct folder *This = impl_from_IFolder(iface);
525     FIXME("(%p)->(%s %x %x %p): stub\n", This, debugstr_w(filename), overwrite, unicode, stream);
526     return E_NOTIMPL;
527 }
528
529 static const IFolderVtbl foldervtbl = {
530     folder_QueryInterface,
531     folder_AddRef,
532     folder_Release,
533     folder_GetTypeInfoCount,
534     folder_GetTypeInfo,
535     folder_GetIDsOfNames,
536     folder_Invoke,
537     folder_get_Path,
538     folder_get_Name,
539     folder_put_Name,
540     folder_get_ShortPath,
541     folder_get_ShortName,
542     folder_get_Drive,
543     folder_get_ParentFolder,
544     folder_get_Attributes,
545     folder_put_Attributes,
546     folder_get_DateCreated,
547     folder_get_DateLastModified,
548     folder_get_DateLastAccessed,
549     folder_get_Type,
550     folder_Delete,
551     folder_Copy,
552     folder_Move,
553     folder_get_IsRootFolder,
554     folder_get_Size,
555     folder_get_SubFolders,
556     folder_get_Files,
557     folder_CreateTextFile
558 };
559
560 static HRESULT create_folder(IFolder **folder)
561 {
562     struct folder *This;
563
564     This = heap_alloc(sizeof(struct folder));
565     if (!This) return E_OUTOFMEMORY;
566
567     This->IFolder_iface.lpVtbl = &foldervtbl;
568     This->ref = 1;
569
570     *folder = &This->IFolder_iface;
571
572     return S_OK;
573 }
574
575 static HRESULT WINAPI filesys_QueryInterface(IFileSystem3 *iface, REFIID riid, void **ppvObject)
576 {
577     TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
578
579     if ( IsEqualGUID( riid, &IID_IFileSystem3 ) ||
580          IsEqualGUID( riid, &IID_IFileSystem ) ||
581          IsEqualGUID( riid, &IID_IDispatch ) ||
582          IsEqualGUID( riid, &IID_IUnknown ) )
583     {
584         *ppvObject = iface;
585     }
586     else if ( IsEqualGUID( riid, &IID_IDispatchEx ))
587     {
588         TRACE("Interface IDispatchEx not supported - returning NULL\n");
589         *ppvObject = NULL;
590         return E_NOINTERFACE;
591     }
592     else if ( IsEqualGUID( riid, &IID_IObjectWithSite ))
593     {
594         TRACE("Interface IObjectWithSite not supported - returning NULL\n");
595         *ppvObject = NULL;
596         return E_NOINTERFACE;
597     }
598     else
599     {
600         FIXME("Unsupported interface %s\n", debugstr_guid(riid));
601         return E_NOINTERFACE;
602     }
603
604     IFileSystem3_AddRef(iface);
605
606     return S_OK;
607 }
608
609 static ULONG WINAPI filesys_AddRef(IFileSystem3 *iface)
610 {
611     TRACE("%p\n", iface);
612
613     return 2;
614 }
615
616 static ULONG WINAPI filesys_Release(IFileSystem3 *iface)
617 {
618     TRACE("%p\n", iface);
619
620     return 1;
621 }
622
623 static HRESULT WINAPI filesys_GetTypeInfoCount(IFileSystem3 *iface, UINT *pctinfo)
624 {
625     TRACE("(%p)->(%p)\n", iface, pctinfo);
626
627     *pctinfo = 1;
628     return S_OK;
629 }
630
631 static HRESULT WINAPI filesys_GetTypeInfo(IFileSystem3 *iface, UINT iTInfo,
632                                         LCID lcid, ITypeInfo **ppTInfo)
633 {
634     TRACE("(%p)->(%u %u %p)\n", iface, iTInfo, lcid, ppTInfo);
635     return get_typeinfo(IFileSystem3_tid, ppTInfo);
636 }
637
638 static HRESULT WINAPI filesys_GetIDsOfNames(IFileSystem3 *iface, REFIID riid,
639                                         LPOLESTR *rgszNames, UINT cNames,
640                                         LCID lcid, DISPID *rgDispId)
641 {
642     ITypeInfo *typeinfo;
643     HRESULT hr;
644
645     TRACE("(%p)->(%s %p %u %u %p)\n", iface, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
646
647     hr = get_typeinfo(IFileSystem3_tid, &typeinfo);
648     if(SUCCEEDED(hr))
649     {
650         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
651         ITypeInfo_Release(typeinfo);
652     }
653
654     return hr;
655 }
656
657 static HRESULT WINAPI filesys_Invoke(IFileSystem3 *iface, DISPID dispIdMember,
658                                       REFIID riid, LCID lcid, WORD wFlags,
659                                       DISPPARAMS *pDispParams, VARIANT *pVarResult,
660                                       EXCEPINFO *pExcepInfo, UINT *puArgErr)
661 {
662     ITypeInfo *typeinfo;
663     HRESULT hr;
664
665     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", iface, dispIdMember, debugstr_guid(riid),
666            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
667
668     hr = get_typeinfo(IFileSystem3_tid, &typeinfo);
669     if(SUCCEEDED(hr))
670     {
671         hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
672                 pDispParams, pVarResult, pExcepInfo, puArgErr);
673         ITypeInfo_Release(typeinfo);
674     }
675
676     return hr;
677 }
678
679 static HRESULT WINAPI filesys_get_Drives(IFileSystem3 *iface, IDriveCollection **ppdrives)
680 {
681     FIXME("%p %p\n", iface, ppdrives);
682
683     return E_NOTIMPL;
684 }
685
686 static HRESULT WINAPI filesys_BuildPath(IFileSystem3 *iface, BSTR Path,
687                                             BSTR Name, BSTR *pbstrResult)
688 {
689     FIXME("%p %s %s %p\n", iface, debugstr_w(Path), debugstr_w(Name), pbstrResult);
690
691     return E_NOTIMPL;
692 }
693
694 static HRESULT WINAPI filesys_GetDriveName(IFileSystem3 *iface, BSTR Path,
695                                             BSTR *pbstrResult)
696 {
697     FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
698
699     return E_NOTIMPL;
700 }
701
702 static HRESULT WINAPI filesys_GetParentFolderName(IFileSystem3 *iface, BSTR Path,
703                                             BSTR *pbstrResult)
704 {
705     FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
706
707     return E_NOTIMPL;
708 }
709
710 static HRESULT WINAPI filesys_GetFileName(IFileSystem3 *iface, BSTR Path,
711                                             BSTR *pbstrResult)
712 {
713     FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
714
715     return E_NOTIMPL;
716 }
717
718 static HRESULT WINAPI filesys_GetBaseName(IFileSystem3 *iface, BSTR Path,
719                                             BSTR *pbstrResult)
720 {
721     FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
722
723     return E_NOTIMPL;
724 }
725
726 static HRESULT WINAPI filesys_GetExtensionName(IFileSystem3 *iface, BSTR Path,
727                                             BSTR *pbstrResult)
728 {
729     FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
730
731     return E_NOTIMPL;
732 }
733
734 static HRESULT WINAPI filesys_GetAbsolutePathName(IFileSystem3 *iface, BSTR Path,
735                                             BSTR *pbstrResult)
736 {
737     FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
738
739     return E_NOTIMPL;
740 }
741
742 static HRESULT WINAPI filesys_GetTempName(IFileSystem3 *iface, BSTR *pbstrResult)
743 {
744     FIXME("%p %p\n", iface, pbstrResult);
745
746     return E_NOTIMPL;
747 }
748
749 static HRESULT WINAPI filesys_DriveExists(IFileSystem3 *iface, BSTR DriveSpec,
750                                             VARIANT_BOOL *pfExists)
751 {
752     FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), pfExists);
753
754     return E_NOTIMPL;
755 }
756
757 static HRESULT WINAPI filesys_FileExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret)
758 {
759     DWORD attrs;
760     TRACE("%p %s %p\n", iface, debugstr_w(path), ret);
761
762     if (!ret) return E_POINTER;
763
764     attrs = GetFileAttributesW(path);
765     *ret = attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY) ? VARIANT_TRUE : VARIANT_FALSE;
766     return S_OK;
767 }
768
769 static HRESULT WINAPI filesys_FolderExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret)
770 {
771     DWORD attrs;
772     TRACE("%p %s %p\n", iface, debugstr_w(path), ret);
773
774     if (!ret) return E_POINTER;
775
776     attrs = GetFileAttributesW(path);
777     *ret = attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) ? VARIANT_TRUE : VARIANT_FALSE;
778
779     return S_OK;
780 }
781
782 static HRESULT WINAPI filesys_GetDrive(IFileSystem3 *iface, BSTR DriveSpec,
783                                             IDrive **ppdrive)
784 {
785     FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), ppdrive);
786
787     return E_NOTIMPL;
788 }
789
790 static HRESULT WINAPI filesys_GetFile(IFileSystem3 *iface, BSTR FilePath,
791                                             IFile **ppfile)
792 {
793     FIXME("%p %s %p\n", iface, debugstr_w(FilePath), ppfile);
794
795     return E_NOTIMPL;
796 }
797
798 static HRESULT WINAPI filesys_GetFolder(IFileSystem3 *iface, BSTR FolderPath,
799                                             IFolder **ppfolder)
800 {
801     FIXME("%p %s %p\n", iface, debugstr_w(FolderPath), ppfolder);
802
803     return E_NOTIMPL;
804 }
805
806 static HRESULT WINAPI filesys_GetSpecialFolder(IFileSystem3 *iface,
807                                             SpecialFolderConst SpecialFolder,
808                                             IFolder **ppfolder)
809 {
810     FIXME("%p %d %p\n", iface, SpecialFolder, ppfolder);
811
812     return E_NOTIMPL;
813 }
814
815 static HRESULT WINAPI filesys_DeleteFile(IFileSystem3 *iface, BSTR FileSpec,
816                                             VARIANT_BOOL Force)
817 {
818     FIXME("%p %s %d\n", iface, debugstr_w(FileSpec), Force);
819
820     return E_NOTIMPL;
821 }
822
823 static HRESULT WINAPI filesys_DeleteFolder(IFileSystem3 *iface, BSTR FolderSpec,
824                                             VARIANT_BOOL Force)
825 {
826     FIXME("%p %s %d\n", iface, debugstr_w(FolderSpec), Force);
827
828     return E_NOTIMPL;
829 }
830
831 static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR Source,
832                                             BSTR Destination)
833 {
834     FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination));
835
836     return E_NOTIMPL;
837 }
838
839 static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface,BSTR Source,
840                                             BSTR Destination)
841 {
842     FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination));
843
844     return E_NOTIMPL;
845 }
846
847 static HRESULT WINAPI filesys_CopyFile(IFileSystem3 *iface, BSTR Source,
848                                             BSTR Destination, VARIANT_BOOL OverWriteFiles)
849 {
850     FIXME("%p %s %s %d\n", iface, debugstr_w(Source), debugstr_w(Destination), OverWriteFiles);
851
852     return E_NOTIMPL;
853 }
854
855 static HRESULT WINAPI filesys_CopyFolder(IFileSystem3 *iface, BSTR Source,
856                                             BSTR Destination, VARIANT_BOOL OverWriteFiles)
857 {
858     FIXME("%p %s %s %d\n", iface, debugstr_w(Source), debugstr_w(Destination), OverWriteFiles);
859
860     return E_NOTIMPL;
861 }
862
863 static HRESULT WINAPI filesys_CreateFolder(IFileSystem3 *iface, BSTR path,
864                                             IFolder **folder)
865 {
866     BOOL ret;
867
868     TRACE("(%p)->(%s %p)\n", iface, debugstr_w(path), folder);
869
870     ret = CreateDirectoryW(path, NULL);
871     if (!ret)
872     {
873         *folder = NULL;
874         if (GetLastError() == ERROR_ALREADY_EXISTS) return CTL_E_FILEALREADYEXISTS;
875         return HRESULT_FROM_WIN32(GetLastError());
876     }
877
878     return create_folder(folder);
879 }
880
881 static HRESULT WINAPI filesys_CreateTextFile(IFileSystem3 *iface, BSTR FileName,
882                                             VARIANT_BOOL Overwrite, VARIANT_BOOL Unicode,
883                                             ITextStream **ppts)
884 {
885     FIXME("%p %s %d %d %p\n", iface, debugstr_w(FileName), Overwrite, Unicode, ppts);
886
887     return E_NOTIMPL;
888 }
889
890 static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename,
891                                             IOMode mode, VARIANT_BOOL create,
892                                             Tristate format, ITextStream **stream)
893 {
894     FIXME("(%p)->(%s %d %d %d %p)\n", iface, debugstr_w(filename), mode, create, format, stream);
895     return create_textstream(stream);
896 }
897
898 static HRESULT WINAPI filesys_GetStandardStream(IFileSystem3 *iface,
899                                             StandardStreamTypes StandardStreamType,
900                                             VARIANT_BOOL Unicode,
901                                             ITextStream **ppts)
902 {
903     FIXME("%p %d %d %p\n", iface, StandardStreamType, Unicode, ppts);
904
905     return E_NOTIMPL;
906 }
907
908 static HRESULT WINAPI filesys_GetFileVersion(IFileSystem3 *iface, BSTR FileName,
909                                             BSTR *FileVersion)
910 {
911     FIXME("%p %s %p\n", iface, debugstr_w(FileName), FileVersion);
912
913     return E_NOTIMPL;
914 }
915
916 static const struct IFileSystem3Vtbl filesys_vtbl =
917 {
918     filesys_QueryInterface,
919     filesys_AddRef,
920     filesys_Release,
921     filesys_GetTypeInfoCount,
922     filesys_GetTypeInfo,
923     filesys_GetIDsOfNames,
924     filesys_Invoke,
925     filesys_get_Drives,
926     filesys_BuildPath,
927     filesys_GetDriveName,
928     filesys_GetParentFolderName,
929     filesys_GetFileName,
930     filesys_GetBaseName,
931     filesys_GetExtensionName,
932     filesys_GetAbsolutePathName,
933     filesys_GetTempName,
934     filesys_DriveExists,
935     filesys_FileExists,
936     filesys_FolderExists,
937     filesys_GetDrive,
938     filesys_GetFile,
939     filesys_GetFolder,
940     filesys_GetSpecialFolder,
941     filesys_DeleteFile,
942     filesys_DeleteFolder,
943     filesys_MoveFile,
944     filesys_MoveFolder,
945     filesys_CopyFile,
946     filesys_CopyFolder,
947     filesys_CreateFolder,
948     filesys_CreateTextFile,
949     filesys_OpenTextFile,
950     filesys_GetStandardStream,
951     filesys_GetFileVersion
952 };
953
954 static IFileSystem3 filesystem = { &filesys_vtbl };
955
956 HRESULT WINAPI FileSystem_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
957 {
958     TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
959
960     return IFileSystem3_QueryInterface(&filesystem, riid, ppv);
961 }