ole32: Avoid a deadlock when a being loaded DLL calls CoRegisterClassObject from...
[wine.git] / dlls / scrrun / filesystem.c
blob4f0b1636c1a169789e7887e629359b65970b1498
1 /*
2 * Copyright 2012 Alistair Leslie-Hughes
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.
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.
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
19 #define COBJMACROS
21 #include "config.h"
22 #include <stdarg.h>
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"
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(scrrun);
37 struct folder {
38 IFolder IFolder_iface;
39 LONG ref;
42 struct textstream {
43 ITextStream ITextStream_iface;
44 LONG ref;
46 IOMode mode;
49 enum iotype {
50 IORead,
51 IOWrite
54 static inline struct folder *impl_from_IFolder(IFolder *iface)
56 return CONTAINING_RECORD(iface, struct folder, IFolder_iface);
59 static inline struct textstream *impl_from_ITextStream(ITextStream *iface)
61 return CONTAINING_RECORD(iface, struct textstream, ITextStream_iface);
64 static int textstream_check_iomode(struct textstream *This, enum iotype type)
66 if (type == IORead)
67 return This->mode == ForWriting || This->mode == ForAppending;
68 else
69 return 1;
72 static HRESULT WINAPI textstream_QueryInterface(ITextStream *iface, REFIID riid, void **obj)
74 struct textstream *This = impl_from_ITextStream(iface);
76 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
78 if (IsEqualIID(riid, &IID_ITextStream) ||
79 IsEqualIID(riid, &IID_IDispatch) ||
80 IsEqualIID(riid, &IID_IUnknown))
82 *obj = iface;
83 ITextStream_AddRef(iface);
84 return S_OK;
87 *obj = NULL;
88 return E_NOINTERFACE;
91 static ULONG WINAPI textstream_AddRef(ITextStream *iface)
93 struct textstream *This = impl_from_ITextStream(iface);
94 ULONG ref = InterlockedIncrement(&This->ref);
95 TRACE("(%p)->(%d)\n", This, ref);
96 return ref;
99 static ULONG WINAPI textstream_Release(ITextStream *iface)
101 struct textstream *This = impl_from_ITextStream(iface);
102 ULONG ref = InterlockedDecrement(&This->ref);
103 TRACE("(%p)->(%d)\n", This, ref);
105 if (!ref)
106 heap_free(This);
108 return ref;
111 static HRESULT WINAPI textstream_GetTypeInfoCount(ITextStream *iface, UINT *pctinfo)
113 struct textstream *This = impl_from_ITextStream(iface);
114 TRACE("(%p)->(%p)\n", This, pctinfo);
115 *pctinfo = 1;
116 return S_OK;
119 static HRESULT WINAPI textstream_GetTypeInfo(ITextStream *iface, UINT iTInfo,
120 LCID lcid, ITypeInfo **ppTInfo)
122 struct textstream *This = impl_from_ITextStream(iface);
123 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
124 return get_typeinfo(ITextStream_tid, ppTInfo);
127 static HRESULT WINAPI textstream_GetIDsOfNames(ITextStream *iface, REFIID riid,
128 LPOLESTR *rgszNames, UINT cNames,
129 LCID lcid, DISPID *rgDispId)
131 struct textstream *This = impl_from_ITextStream(iface);
132 ITypeInfo *typeinfo;
133 HRESULT hr;
135 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
137 hr = get_typeinfo(ITextStream_tid, &typeinfo);
138 if(SUCCEEDED(hr))
140 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
141 ITypeInfo_Release(typeinfo);
144 return hr;
147 static HRESULT WINAPI textstream_Invoke(ITextStream *iface, DISPID dispIdMember,
148 REFIID riid, LCID lcid, WORD wFlags,
149 DISPPARAMS *pDispParams, VARIANT *pVarResult,
150 EXCEPINFO *pExcepInfo, UINT *puArgErr)
152 struct textstream *This = impl_from_ITextStream(iface);
153 ITypeInfo *typeinfo;
154 HRESULT hr;
156 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
157 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
159 hr = get_typeinfo(ITextStream_tid, &typeinfo);
160 if(SUCCEEDED(hr))
162 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
163 pDispParams, pVarResult, pExcepInfo, puArgErr);
164 ITypeInfo_Release(typeinfo);
167 return hr;
170 static HRESULT WINAPI textstream_get_Line(ITextStream *iface, LONG *line)
172 struct textstream *This = impl_from_ITextStream(iface);
173 FIXME("(%p)->(%p): stub\n", This, line);
174 return E_NOTIMPL;
177 static HRESULT WINAPI textstream_get_Column(ITextStream *iface, LONG *column)
179 struct textstream *This = impl_from_ITextStream(iface);
180 FIXME("(%p)->(%p): stub\n", This, column);
181 return E_NOTIMPL;
184 static HRESULT WINAPI textstream_get_AtEndOfStream(ITextStream *iface, VARIANT_BOOL *eos)
186 struct textstream *This = impl_from_ITextStream(iface);
187 FIXME("(%p)->(%p): stub\n", This, eos);
188 return E_NOTIMPL;
191 static HRESULT WINAPI textstream_get_AtEndOfLine(ITextStream *iface, VARIANT_BOOL *eol)
193 struct textstream *This = impl_from_ITextStream(iface);
194 FIXME("(%p)->(%p): stub\n", This, eol);
195 return E_NOTIMPL;
198 static HRESULT WINAPI textstream_Read(ITextStream *iface, LONG len, BSTR *text)
200 struct textstream *This = impl_from_ITextStream(iface);
201 FIXME("(%p)->(%p): stub\n", This, text);
203 if (textstream_check_iomode(This, IORead))
204 return CTL_E_BADFILEMODE;
206 return E_NOTIMPL;
209 static HRESULT WINAPI textstream_ReadLine(ITextStream *iface, BSTR *text)
211 struct textstream *This = impl_from_ITextStream(iface);
212 FIXME("(%p)->(%p): stub\n", This, text);
214 if (textstream_check_iomode(This, IORead))
215 return CTL_E_BADFILEMODE;
217 return E_NOTIMPL;
220 static HRESULT WINAPI textstream_ReadAll(ITextStream *iface, BSTR *text)
222 struct textstream *This = impl_from_ITextStream(iface);
223 FIXME("(%p)->(%p): stub\n", This, text);
225 if (textstream_check_iomode(This, IORead))
226 return CTL_E_BADFILEMODE;
228 return E_NOTIMPL;
231 static HRESULT WINAPI textstream_Write(ITextStream *iface, BSTR text)
233 struct textstream *This = impl_from_ITextStream(iface);
234 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
235 return E_NOTIMPL;
238 static HRESULT WINAPI textstream_WriteLine(ITextStream *iface, BSTR text)
240 struct textstream *This = impl_from_ITextStream(iface);
241 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text));
242 return E_NOTIMPL;
245 static HRESULT WINAPI textstream_WriteBlankLines(ITextStream *iface, LONG lines)
247 struct textstream *This = impl_from_ITextStream(iface);
248 FIXME("(%p)->(%d): stub\n", This, lines);
249 return E_NOTIMPL;
252 static HRESULT WINAPI textstream_Skip(ITextStream *iface, LONG count)
254 struct textstream *This = impl_from_ITextStream(iface);
255 FIXME("(%p)->(%d): stub\n", This, count);
256 return E_NOTIMPL;
259 static HRESULT WINAPI textstream_SkipLine(ITextStream *iface)
261 struct textstream *This = impl_from_ITextStream(iface);
262 FIXME("(%p): stub\n", This);
263 return E_NOTIMPL;
266 static HRESULT WINAPI textstream_Close(ITextStream *iface)
268 struct textstream *This = impl_from_ITextStream(iface);
269 FIXME("(%p): stub\n", This);
270 return E_NOTIMPL;
273 static const ITextStreamVtbl textstreamvtbl = {
274 textstream_QueryInterface,
275 textstream_AddRef,
276 textstream_Release,
277 textstream_GetTypeInfoCount,
278 textstream_GetTypeInfo,
279 textstream_GetIDsOfNames,
280 textstream_Invoke,
281 textstream_get_Line,
282 textstream_get_Column,
283 textstream_get_AtEndOfStream,
284 textstream_get_AtEndOfLine,
285 textstream_Read,
286 textstream_ReadLine,
287 textstream_ReadAll,
288 textstream_Write,
289 textstream_WriteLine,
290 textstream_WriteBlankLines,
291 textstream_Skip,
292 textstream_SkipLine,
293 textstream_Close
296 static HRESULT create_textstream(IOMode mode, ITextStream **ret)
298 struct textstream *stream;
300 stream = heap_alloc(sizeof(struct textstream));
301 if (!stream) return E_OUTOFMEMORY;
303 stream->ITextStream_iface.lpVtbl = &textstreamvtbl;
304 stream->ref = 1;
305 stream->mode = mode;
307 *ret = &stream->ITextStream_iface;
308 return S_OK;
311 static HRESULT WINAPI folder_QueryInterface(IFolder *iface, REFIID riid, void **obj)
313 struct folder *This = impl_from_IFolder(iface);
315 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
317 *obj = NULL;
319 if (IsEqualGUID( riid, &IID_IFolder ) ||
320 IsEqualGUID( riid, &IID_IUnknown))
322 *obj = iface;
323 IFolder_AddRef(iface);
325 else
326 return E_NOINTERFACE;
328 return S_OK;
331 static ULONG WINAPI folder_AddRef(IFolder *iface)
333 struct folder *This = impl_from_IFolder(iface);
334 ULONG ref = InterlockedIncrement(&This->ref);
335 TRACE("(%p)->(%d)\n", This, ref);
336 return ref;
339 static ULONG WINAPI folder_Release(IFolder *iface)
341 struct folder *This = impl_from_IFolder(iface);
342 ULONG ref = InterlockedDecrement(&This->ref);
343 TRACE("(%p)->(%d)\n", This, ref);
345 if (!ref)
346 heap_free(This);
348 return ref;
351 static HRESULT WINAPI folder_GetTypeInfoCount(IFolder *iface, UINT *pctinfo)
353 struct folder *This = impl_from_IFolder(iface);
354 TRACE("(%p)->(%p)\n", This, pctinfo);
355 *pctinfo = 1;
356 return S_OK;
359 static HRESULT WINAPI folder_GetTypeInfo(IFolder *iface, UINT iTInfo,
360 LCID lcid, ITypeInfo **ppTInfo)
362 struct folder *This = impl_from_IFolder(iface);
363 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
364 return get_typeinfo(IFolder_tid, ppTInfo);
367 static HRESULT WINAPI folder_GetIDsOfNames(IFolder *iface, REFIID riid,
368 LPOLESTR *rgszNames, UINT cNames,
369 LCID lcid, DISPID *rgDispId)
371 struct folder *This = impl_from_IFolder(iface);
372 ITypeInfo *typeinfo;
373 HRESULT hr;
375 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
377 hr = get_typeinfo(IFolder_tid, &typeinfo);
378 if(SUCCEEDED(hr))
380 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
381 ITypeInfo_Release(typeinfo);
384 return hr;
387 static HRESULT WINAPI folder_Invoke(IFolder *iface, DISPID dispIdMember,
388 REFIID riid, LCID lcid, WORD wFlags,
389 DISPPARAMS *pDispParams, VARIANT *pVarResult,
390 EXCEPINFO *pExcepInfo, UINT *puArgErr)
392 struct folder *This = impl_from_IFolder(iface);
393 ITypeInfo *typeinfo;
394 HRESULT hr;
396 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
397 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
399 hr = get_typeinfo(IFolder_tid, &typeinfo);
400 if(SUCCEEDED(hr))
402 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
403 pDispParams, pVarResult, pExcepInfo, puArgErr);
404 ITypeInfo_Release(typeinfo);
407 return hr;
410 static HRESULT WINAPI folder_get_Path(IFolder *iface, BSTR *path)
412 struct folder *This = impl_from_IFolder(iface);
413 FIXME("(%p)->(%p): stub\n", This, path);
414 return E_NOTIMPL;
417 static HRESULT WINAPI folder_get_Name(IFolder *iface, BSTR *name)
419 struct folder *This = impl_from_IFolder(iface);
420 FIXME("(%p)->(%p): stub\n", This, name);
421 return E_NOTIMPL;
424 static HRESULT WINAPI folder_put_Name(IFolder *iface, BSTR name)
426 struct folder *This = impl_from_IFolder(iface);
427 FIXME("(%p)->(%s): stub\n", This, debugstr_w(name));
428 return E_NOTIMPL;
431 static HRESULT WINAPI folder_get_ShortPath(IFolder *iface, BSTR *path)
433 struct folder *This = impl_from_IFolder(iface);
434 FIXME("(%p)->(%p): stub\n", This, path);
435 return E_NOTIMPL;
438 static HRESULT WINAPI folder_get_ShortName(IFolder *iface, BSTR *name)
440 struct folder *This = impl_from_IFolder(iface);
441 FIXME("(%p)->(%p): stub\n", This, name);
442 return E_NOTIMPL;
445 static HRESULT WINAPI folder_get_Drive(IFolder *iface, IDrive **drive)
447 struct folder *This = impl_from_IFolder(iface);
448 FIXME("(%p)->(%p): stub\n", This, drive);
449 return E_NOTIMPL;
452 static HRESULT WINAPI folder_get_ParentFolder(IFolder *iface, IFolder **parent)
454 struct folder *This = impl_from_IFolder(iface);
455 FIXME("(%p)->(%p): stub\n", This, parent);
456 return E_NOTIMPL;
459 static HRESULT WINAPI folder_get_Attributes(IFolder *iface, FileAttribute *attr)
461 struct folder *This = impl_from_IFolder(iface);
462 FIXME("(%p)->(%p): stub\n", This, attr);
463 return E_NOTIMPL;
466 static HRESULT WINAPI folder_put_Attributes(IFolder *iface, FileAttribute attr)
468 struct folder *This = impl_from_IFolder(iface);
469 FIXME("(%p)->(0x%x): stub\n", This, attr);
470 return E_NOTIMPL;
473 static HRESULT WINAPI folder_get_DateCreated(IFolder *iface, DATE *date)
475 struct folder *This = impl_from_IFolder(iface);
476 FIXME("(%p)->(%p): stub\n", This, date);
477 return E_NOTIMPL;
480 static HRESULT WINAPI folder_get_DateLastModified(IFolder *iface, DATE *date)
482 struct folder *This = impl_from_IFolder(iface);
483 FIXME("(%p)->(%p): stub\n", This, date);
484 return E_NOTIMPL;
487 static HRESULT WINAPI folder_get_DateLastAccessed(IFolder *iface, DATE *date)
489 struct folder *This = impl_from_IFolder(iface);
490 FIXME("(%p)->(%p): stub\n", This, date);
491 return E_NOTIMPL;
494 static HRESULT WINAPI folder_get_Type(IFolder *iface, BSTR *type)
496 struct folder *This = impl_from_IFolder(iface);
497 FIXME("(%p)->(%p): stub\n", This, type);
498 return E_NOTIMPL;
501 static HRESULT WINAPI folder_Delete(IFolder *iface, VARIANT_BOOL force)
503 struct folder *This = impl_from_IFolder(iface);
504 FIXME("(%p)->(%x): stub\n", This, force);
505 return E_NOTIMPL;
508 static HRESULT WINAPI folder_Copy(IFolder *iface, BSTR dest, VARIANT_BOOL overwrite)
510 struct folder *This = impl_from_IFolder(iface);
511 FIXME("(%p)->(%s %x): stub\n", This, debugstr_w(dest), overwrite);
512 return E_NOTIMPL;
515 static HRESULT WINAPI folder_Move(IFolder *iface, BSTR dest)
517 struct folder *This = impl_from_IFolder(iface);
518 FIXME("(%p)->(%s): stub\n", This, debugstr_w(dest));
519 return E_NOTIMPL;
522 static HRESULT WINAPI folder_get_IsRootFolder(IFolder *iface, VARIANT_BOOL *isroot)
524 struct folder *This = impl_from_IFolder(iface);
525 FIXME("(%p)->(%p): stub\n", This, isroot);
526 return E_NOTIMPL;
529 static HRESULT WINAPI folder_get_Size(IFolder *iface, VARIANT *size)
531 struct folder *This = impl_from_IFolder(iface);
532 FIXME("(%p)->(%p): stub\n", This, size);
533 return E_NOTIMPL;
536 static HRESULT WINAPI folder_get_SubFolders(IFolder *iface, IFolderCollection **folders)
538 struct folder *This = impl_from_IFolder(iface);
539 FIXME("(%p)->(%p): stub\n", This, folders);
540 return E_NOTIMPL;
543 static HRESULT WINAPI folder_get_Files(IFolder *iface, IFileCollection **files)
545 struct folder *This = impl_from_IFolder(iface);
546 FIXME("(%p)->(%p): stub\n", This, files);
547 return E_NOTIMPL;
550 static HRESULT WINAPI folder_CreateTextFile(IFolder *iface, BSTR filename, VARIANT_BOOL overwrite,
551 VARIANT_BOOL unicode, ITextStream **stream)
553 struct folder *This = impl_from_IFolder(iface);
554 FIXME("(%p)->(%s %x %x %p): stub\n", This, debugstr_w(filename), overwrite, unicode, stream);
555 return E_NOTIMPL;
558 static const IFolderVtbl foldervtbl = {
559 folder_QueryInterface,
560 folder_AddRef,
561 folder_Release,
562 folder_GetTypeInfoCount,
563 folder_GetTypeInfo,
564 folder_GetIDsOfNames,
565 folder_Invoke,
566 folder_get_Path,
567 folder_get_Name,
568 folder_put_Name,
569 folder_get_ShortPath,
570 folder_get_ShortName,
571 folder_get_Drive,
572 folder_get_ParentFolder,
573 folder_get_Attributes,
574 folder_put_Attributes,
575 folder_get_DateCreated,
576 folder_get_DateLastModified,
577 folder_get_DateLastAccessed,
578 folder_get_Type,
579 folder_Delete,
580 folder_Copy,
581 folder_Move,
582 folder_get_IsRootFolder,
583 folder_get_Size,
584 folder_get_SubFolders,
585 folder_get_Files,
586 folder_CreateTextFile
589 static HRESULT create_folder(IFolder **folder)
591 struct folder *This;
593 This = heap_alloc(sizeof(struct folder));
594 if (!This) return E_OUTOFMEMORY;
596 This->IFolder_iface.lpVtbl = &foldervtbl;
597 This->ref = 1;
599 *folder = &This->IFolder_iface;
601 return S_OK;
604 static HRESULT WINAPI filesys_QueryInterface(IFileSystem3 *iface, REFIID riid, void **ppvObject)
606 TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
608 if ( IsEqualGUID( riid, &IID_IFileSystem3 ) ||
609 IsEqualGUID( riid, &IID_IFileSystem ) ||
610 IsEqualGUID( riid, &IID_IDispatch ) ||
611 IsEqualGUID( riid, &IID_IUnknown ) )
613 *ppvObject = iface;
615 else if ( IsEqualGUID( riid, &IID_IDispatchEx ))
617 TRACE("Interface IDispatchEx not supported - returning NULL\n");
618 *ppvObject = NULL;
619 return E_NOINTERFACE;
621 else if ( IsEqualGUID( riid, &IID_IObjectWithSite ))
623 TRACE("Interface IObjectWithSite not supported - returning NULL\n");
624 *ppvObject = NULL;
625 return E_NOINTERFACE;
627 else
629 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
630 return E_NOINTERFACE;
633 IFileSystem3_AddRef(iface);
635 return S_OK;
638 static ULONG WINAPI filesys_AddRef(IFileSystem3 *iface)
640 TRACE("%p\n", iface);
642 return 2;
645 static ULONG WINAPI filesys_Release(IFileSystem3 *iface)
647 TRACE("%p\n", iface);
649 return 1;
652 static HRESULT WINAPI filesys_GetTypeInfoCount(IFileSystem3 *iface, UINT *pctinfo)
654 TRACE("(%p)->(%p)\n", iface, pctinfo);
656 *pctinfo = 1;
657 return S_OK;
660 static HRESULT WINAPI filesys_GetTypeInfo(IFileSystem3 *iface, UINT iTInfo,
661 LCID lcid, ITypeInfo **ppTInfo)
663 TRACE("(%p)->(%u %u %p)\n", iface, iTInfo, lcid, ppTInfo);
664 return get_typeinfo(IFileSystem3_tid, ppTInfo);
667 static HRESULT WINAPI filesys_GetIDsOfNames(IFileSystem3 *iface, REFIID riid,
668 LPOLESTR *rgszNames, UINT cNames,
669 LCID lcid, DISPID *rgDispId)
671 ITypeInfo *typeinfo;
672 HRESULT hr;
674 TRACE("(%p)->(%s %p %u %u %p)\n", iface, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
676 hr = get_typeinfo(IFileSystem3_tid, &typeinfo);
677 if(SUCCEEDED(hr))
679 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
680 ITypeInfo_Release(typeinfo);
683 return hr;
686 static HRESULT WINAPI filesys_Invoke(IFileSystem3 *iface, DISPID dispIdMember,
687 REFIID riid, LCID lcid, WORD wFlags,
688 DISPPARAMS *pDispParams, VARIANT *pVarResult,
689 EXCEPINFO *pExcepInfo, UINT *puArgErr)
691 ITypeInfo *typeinfo;
692 HRESULT hr;
694 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", iface, dispIdMember, debugstr_guid(riid),
695 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
697 hr = get_typeinfo(IFileSystem3_tid, &typeinfo);
698 if(SUCCEEDED(hr))
700 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
701 pDispParams, pVarResult, pExcepInfo, puArgErr);
702 ITypeInfo_Release(typeinfo);
705 return hr;
708 static HRESULT WINAPI filesys_get_Drives(IFileSystem3 *iface, IDriveCollection **ppdrives)
710 FIXME("%p %p\n", iface, ppdrives);
712 return E_NOTIMPL;
715 static HRESULT WINAPI filesys_BuildPath(IFileSystem3 *iface, BSTR Path,
716 BSTR Name, BSTR *pbstrResult)
718 FIXME("%p %s %s %p\n", iface, debugstr_w(Path), debugstr_w(Name), pbstrResult);
720 return E_NOTIMPL;
723 static HRESULT WINAPI filesys_GetDriveName(IFileSystem3 *iface, BSTR Path,
724 BSTR *pbstrResult)
726 FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
728 return E_NOTIMPL;
731 static HRESULT WINAPI filesys_GetParentFolderName(IFileSystem3 *iface, BSTR Path,
732 BSTR *pbstrResult)
734 FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
736 return E_NOTIMPL;
739 static HRESULT WINAPI filesys_GetFileName(IFileSystem3 *iface, BSTR Path,
740 BSTR *pbstrResult)
742 FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
744 return E_NOTIMPL;
747 static HRESULT WINAPI filesys_GetBaseName(IFileSystem3 *iface, BSTR Path,
748 BSTR *pbstrResult)
750 FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
752 return E_NOTIMPL;
755 static HRESULT WINAPI filesys_GetExtensionName(IFileSystem3 *iface, BSTR Path,
756 BSTR *pbstrResult)
758 FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
760 return E_NOTIMPL;
763 static HRESULT WINAPI filesys_GetAbsolutePathName(IFileSystem3 *iface, BSTR Path,
764 BSTR *pbstrResult)
766 FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
768 return E_NOTIMPL;
771 static HRESULT WINAPI filesys_GetTempName(IFileSystem3 *iface, BSTR *pbstrResult)
773 FIXME("%p %p\n", iface, pbstrResult);
775 return E_NOTIMPL;
778 static HRESULT WINAPI filesys_DriveExists(IFileSystem3 *iface, BSTR DriveSpec,
779 VARIANT_BOOL *pfExists)
781 FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), pfExists);
783 return E_NOTIMPL;
786 static HRESULT WINAPI filesys_FileExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret)
788 DWORD attrs;
789 TRACE("%p %s %p\n", iface, debugstr_w(path), ret);
791 if (!ret) return E_POINTER;
793 attrs = GetFileAttributesW(path);
794 *ret = attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY) ? VARIANT_TRUE : VARIANT_FALSE;
795 return S_OK;
798 static HRESULT WINAPI filesys_FolderExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret)
800 DWORD attrs;
801 TRACE("%p %s %p\n", iface, debugstr_w(path), ret);
803 if (!ret) return E_POINTER;
805 attrs = GetFileAttributesW(path);
806 *ret = attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) ? VARIANT_TRUE : VARIANT_FALSE;
808 return S_OK;
811 static HRESULT WINAPI filesys_GetDrive(IFileSystem3 *iface, BSTR DriveSpec,
812 IDrive **ppdrive)
814 FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), ppdrive);
816 return E_NOTIMPL;
819 static HRESULT WINAPI filesys_GetFile(IFileSystem3 *iface, BSTR FilePath,
820 IFile **ppfile)
822 FIXME("%p %s %p\n", iface, debugstr_w(FilePath), ppfile);
824 return E_NOTIMPL;
827 static HRESULT WINAPI filesys_GetFolder(IFileSystem3 *iface, BSTR FolderPath,
828 IFolder **ppfolder)
830 FIXME("%p %s %p\n", iface, debugstr_w(FolderPath), ppfolder);
832 return E_NOTIMPL;
835 static HRESULT WINAPI filesys_GetSpecialFolder(IFileSystem3 *iface,
836 SpecialFolderConst SpecialFolder,
837 IFolder **ppfolder)
839 FIXME("%p %d %p\n", iface, SpecialFolder, ppfolder);
841 return E_NOTIMPL;
844 static HRESULT WINAPI filesys_DeleteFile(IFileSystem3 *iface, BSTR FileSpec,
845 VARIANT_BOOL Force)
847 FIXME("%p %s %d\n", iface, debugstr_w(FileSpec), Force);
849 return E_NOTIMPL;
852 static HRESULT WINAPI filesys_DeleteFolder(IFileSystem3 *iface, BSTR FolderSpec,
853 VARIANT_BOOL Force)
855 FIXME("%p %s %d\n", iface, debugstr_w(FolderSpec), Force);
857 return E_NOTIMPL;
860 static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR Source,
861 BSTR Destination)
863 FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination));
865 return E_NOTIMPL;
868 static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface,BSTR Source,
869 BSTR Destination)
871 FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination));
873 return E_NOTIMPL;
876 static HRESULT WINAPI filesys_CopyFile(IFileSystem3 *iface, BSTR Source,
877 BSTR Destination, VARIANT_BOOL OverWriteFiles)
879 FIXME("%p %s %s %d\n", iface, debugstr_w(Source), debugstr_w(Destination), OverWriteFiles);
881 return E_NOTIMPL;
884 static HRESULT WINAPI filesys_CopyFolder(IFileSystem3 *iface, BSTR Source,
885 BSTR Destination, VARIANT_BOOL OverWriteFiles)
887 FIXME("%p %s %s %d\n", iface, debugstr_w(Source), debugstr_w(Destination), OverWriteFiles);
889 return E_NOTIMPL;
892 static HRESULT WINAPI filesys_CreateFolder(IFileSystem3 *iface, BSTR path,
893 IFolder **folder)
895 BOOL ret;
897 TRACE("(%p)->(%s %p)\n", iface, debugstr_w(path), folder);
899 ret = CreateDirectoryW(path, NULL);
900 if (!ret)
902 *folder = NULL;
903 if (GetLastError() == ERROR_ALREADY_EXISTS) return CTL_E_FILEALREADYEXISTS;
904 return HRESULT_FROM_WIN32(GetLastError());
907 return create_folder(folder);
910 static HRESULT WINAPI filesys_CreateTextFile(IFileSystem3 *iface, BSTR FileName,
911 VARIANT_BOOL Overwrite, VARIANT_BOOL Unicode,
912 ITextStream **ppts)
914 FIXME("%p %s %d %d %p\n", iface, debugstr_w(FileName), Overwrite, Unicode, ppts);
916 return E_NOTIMPL;
919 static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename,
920 IOMode mode, VARIANT_BOOL create,
921 Tristate format, ITextStream **stream)
923 FIXME("(%p)->(%s %d %d %d %p)\n", iface, debugstr_w(filename), mode, create, format, stream);
924 return create_textstream(mode, stream);
927 static HRESULT WINAPI filesys_GetStandardStream(IFileSystem3 *iface,
928 StandardStreamTypes StandardStreamType,
929 VARIANT_BOOL Unicode,
930 ITextStream **ppts)
932 FIXME("%p %d %d %p\n", iface, StandardStreamType, Unicode, ppts);
934 return E_NOTIMPL;
937 static void get_versionstring(VS_FIXEDFILEINFO *info, WCHAR *ver)
939 static WCHAR fmtW[] = {'%','d','.','%','d','.','%','d','.','%','d',0};
940 DWORDLONG version;
941 WORD a, b, c, d;
943 version = (((DWORDLONG)info->dwFileVersionMS) << 32) + info->dwFileVersionLS;
944 a = (WORD)( version >> 48);
945 b = (WORD)((version >> 32) & 0xffff);
946 c = (WORD)((version >> 16) & 0xffff);
947 d = (WORD)( version & 0xffff);
949 sprintfW(ver, fmtW, a, b, c, d);
952 static HRESULT WINAPI filesys_GetFileVersion(IFileSystem3 *iface, BSTR name, BSTR *version)
954 static const WCHAR rootW[] = {'\\',0};
955 VS_FIXEDFILEINFO *info;
956 WCHAR ver[30];
957 void *ptr;
958 DWORD len;
959 BOOL ret;
961 TRACE("%p %s %p\n", iface, debugstr_w(name), version);
963 len = GetFileVersionInfoSizeW(name, NULL);
964 if (!len)
965 return HRESULT_FROM_WIN32(GetLastError());
967 ptr = heap_alloc(len);
968 if (!GetFileVersionInfoW(name, 0, len, ptr))
970 heap_free(ptr);
971 return HRESULT_FROM_WIN32(GetLastError());
974 ret = VerQueryValueW(ptr, rootW, (void**)&info, &len);
975 heap_free(ptr);
976 if (!ret)
977 return HRESULT_FROM_WIN32(GetLastError());
979 get_versionstring(info, ver);
980 *version = SysAllocString(ver);
981 TRACE("version=%s\n", debugstr_w(ver));
983 return S_OK;
986 static const struct IFileSystem3Vtbl filesys_vtbl =
988 filesys_QueryInterface,
989 filesys_AddRef,
990 filesys_Release,
991 filesys_GetTypeInfoCount,
992 filesys_GetTypeInfo,
993 filesys_GetIDsOfNames,
994 filesys_Invoke,
995 filesys_get_Drives,
996 filesys_BuildPath,
997 filesys_GetDriveName,
998 filesys_GetParentFolderName,
999 filesys_GetFileName,
1000 filesys_GetBaseName,
1001 filesys_GetExtensionName,
1002 filesys_GetAbsolutePathName,
1003 filesys_GetTempName,
1004 filesys_DriveExists,
1005 filesys_FileExists,
1006 filesys_FolderExists,
1007 filesys_GetDrive,
1008 filesys_GetFile,
1009 filesys_GetFolder,
1010 filesys_GetSpecialFolder,
1011 filesys_DeleteFile,
1012 filesys_DeleteFolder,
1013 filesys_MoveFile,
1014 filesys_MoveFolder,
1015 filesys_CopyFile,
1016 filesys_CopyFolder,
1017 filesys_CreateFolder,
1018 filesys_CreateTextFile,
1019 filesys_OpenTextFile,
1020 filesys_GetStandardStream,
1021 filesys_GetFileVersion
1024 static IFileSystem3 filesystem = { &filesys_vtbl };
1026 HRESULT WINAPI FileSystem_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
1028 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
1030 return IFileSystem3_QueryInterface(&filesystem, riid, ppv);