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
32 #include "scrrun_private.h"
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(scrrun
);
39 static const WCHAR bsW
[] = {'\\',0};
41 struct foldercollection
{
42 IFolderCollection IFolderCollection_iface
;
47 struct filecollection
{
48 IFileCollection IFileCollection_iface
;
53 struct drivecollection
{
54 IDriveCollection IDriveCollection_iface
;
65 struct foldercollection
*coll
;
70 struct filecollection
*coll
;
75 struct drivecollection
*coll
;
82 IEnumVARIANT IEnumVARIANT_iface
;
95 IFolder IFolder_iface
;
108 ITextStream ITextStream_iface
;
119 static inline struct drive
*impl_from_IDrive(IDrive
*iface
)
121 return CONTAINING_RECORD(iface
, struct drive
, IDrive_iface
);
124 static inline struct folder
*impl_from_IFolder(IFolder
*iface
)
126 return CONTAINING_RECORD(iface
, struct folder
, IFolder_iface
);
129 static inline struct file
*impl_from_IFile(IFile
*iface
)
131 return CONTAINING_RECORD(iface
, struct file
, IFile_iface
);
134 static inline struct textstream
*impl_from_ITextStream(ITextStream
*iface
)
136 return CONTAINING_RECORD(iface
, struct textstream
, ITextStream_iface
);
139 static inline struct foldercollection
*impl_from_IFolderCollection(IFolderCollection
*iface
)
141 return CONTAINING_RECORD(iface
, struct foldercollection
, IFolderCollection_iface
);
144 static inline struct filecollection
*impl_from_IFileCollection(IFileCollection
*iface
)
146 return CONTAINING_RECORD(iface
, struct filecollection
, IFileCollection_iface
);
149 static inline struct drivecollection
*impl_from_IDriveCollection(IDriveCollection
*iface
)
151 return CONTAINING_RECORD(iface
, struct drivecollection
, IDriveCollection_iface
);
154 static inline struct enumvariant
*impl_from_IEnumVARIANT(IEnumVARIANT
*iface
)
156 return CONTAINING_RECORD(iface
, struct enumvariant
, IEnumVARIANT_iface
);
159 static inline HRESULT
create_error(DWORD err
)
162 case ERROR_FILE_NOT_FOUND
: return CTL_E_FILENOTFOUND
;
163 case ERROR_PATH_NOT_FOUND
: return CTL_E_PATHNOTFOUND
;
164 case ERROR_ACCESS_DENIED
: return CTL_E_PERMISSIONDENIED
;
165 case ERROR_FILE_EXISTS
: return CTL_E_FILEALREADYEXISTS
;
166 case ERROR_ALREADY_EXISTS
: return CTL_E_FILEALREADYEXISTS
;
168 FIXME("Unsupported error code: %d\n", err
);
173 static HRESULT
create_folder(const WCHAR
*, IFolder
**);
174 static HRESULT
create_file(BSTR
, IFile
**);
175 static HRESULT
create_foldercoll_enum(struct foldercollection
*, IUnknown
**);
176 static HRESULT
create_filecoll_enum(struct filecollection
*, IUnknown
**);
178 static inline BOOL
is_dir_data(const WIN32_FIND_DATAW
*data
)
180 static const WCHAR dotdotW
[] = {'.','.',0};
181 static const WCHAR dotW
[] = {'.',0};
183 return (data
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) &&
184 strcmpW(data
->cFileName
, dotdotW
) &&
185 strcmpW(data
->cFileName
, dotW
);
188 static inline BOOL
is_file_data(const WIN32_FIND_DATAW
*data
)
190 return !(data
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
);
193 static BSTR
get_full_path(BSTR path
, const WIN32_FIND_DATAW
*data
)
195 int len
= SysStringLen(path
);
196 WCHAR buffW
[MAX_PATH
];
198 strcpyW(buffW
, path
);
199 if (path
[len
-1] != '\\')
201 strcatW(buffW
, data
->cFileName
);
203 return SysAllocString(buffW
);
206 static BOOL
textstream_check_iomode(struct textstream
*This
, enum iotype type
)
209 return This
->mode
== ForWriting
|| This
->mode
== ForAppending
;
214 static HRESULT WINAPI
textstream_QueryInterface(ITextStream
*iface
, REFIID riid
, void **obj
)
216 struct textstream
*This
= impl_from_ITextStream(iface
);
218 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
220 if (IsEqualIID(riid
, &IID_ITextStream
) ||
221 IsEqualIID(riid
, &IID_IDispatch
) ||
222 IsEqualIID(riid
, &IID_IUnknown
))
225 ITextStream_AddRef(iface
);
230 return E_NOINTERFACE
;
233 static ULONG WINAPI
textstream_AddRef(ITextStream
*iface
)
235 struct textstream
*This
= impl_from_ITextStream(iface
);
236 ULONG ref
= InterlockedIncrement(&This
->ref
);
237 TRACE("(%p)->(%d)\n", This
, ref
);
241 static ULONG WINAPI
textstream_Release(ITextStream
*iface
)
243 struct textstream
*This
= impl_from_ITextStream(iface
);
244 ULONG ref
= InterlockedDecrement(&This
->ref
);
245 TRACE("(%p)->(%d)\n", This
, ref
);
253 static HRESULT WINAPI
textstream_GetTypeInfoCount(ITextStream
*iface
, UINT
*pctinfo
)
255 struct textstream
*This
= impl_from_ITextStream(iface
);
256 TRACE("(%p)->(%p)\n", This
, pctinfo
);
261 static HRESULT WINAPI
textstream_GetTypeInfo(ITextStream
*iface
, UINT iTInfo
,
262 LCID lcid
, ITypeInfo
**ppTInfo
)
264 struct textstream
*This
= impl_from_ITextStream(iface
);
265 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
266 return get_typeinfo(ITextStream_tid
, ppTInfo
);
269 static HRESULT WINAPI
textstream_GetIDsOfNames(ITextStream
*iface
, REFIID riid
,
270 LPOLESTR
*rgszNames
, UINT cNames
,
271 LCID lcid
, DISPID
*rgDispId
)
273 struct textstream
*This
= impl_from_ITextStream(iface
);
277 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
279 hr
= get_typeinfo(ITextStream_tid
, &typeinfo
);
282 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
283 ITypeInfo_Release(typeinfo
);
289 static HRESULT WINAPI
textstream_Invoke(ITextStream
*iface
, DISPID dispIdMember
,
290 REFIID riid
, LCID lcid
, WORD wFlags
,
291 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
292 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
294 struct textstream
*This
= impl_from_ITextStream(iface
);
298 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
299 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
301 hr
= get_typeinfo(ITextStream_tid
, &typeinfo
);
304 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
305 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
306 ITypeInfo_Release(typeinfo
);
312 static HRESULT WINAPI
textstream_get_Line(ITextStream
*iface
, LONG
*line
)
314 struct textstream
*This
= impl_from_ITextStream(iface
);
315 FIXME("(%p)->(%p): stub\n", This
, line
);
319 static HRESULT WINAPI
textstream_get_Column(ITextStream
*iface
, LONG
*column
)
321 struct textstream
*This
= impl_from_ITextStream(iface
);
322 FIXME("(%p)->(%p): stub\n", This
, column
);
326 static HRESULT WINAPI
textstream_get_AtEndOfStream(ITextStream
*iface
, VARIANT_BOOL
*eos
)
328 struct textstream
*This
= impl_from_ITextStream(iface
);
329 FIXME("(%p)->(%p): stub\n", This
, eos
);
333 static HRESULT WINAPI
textstream_get_AtEndOfLine(ITextStream
*iface
, VARIANT_BOOL
*eol
)
335 struct textstream
*This
= impl_from_ITextStream(iface
);
336 FIXME("(%p)->(%p): stub\n", This
, eol
);
340 static HRESULT WINAPI
textstream_Read(ITextStream
*iface
, LONG len
, BSTR
*text
)
342 struct textstream
*This
= impl_from_ITextStream(iface
);
343 FIXME("(%p)->(%p): stub\n", This
, text
);
345 if (textstream_check_iomode(This
, IORead
))
346 return CTL_E_BADFILEMODE
;
351 static HRESULT WINAPI
textstream_ReadLine(ITextStream
*iface
, BSTR
*text
)
353 struct textstream
*This
= impl_from_ITextStream(iface
);
354 FIXME("(%p)->(%p): stub\n", This
, text
);
356 if (textstream_check_iomode(This
, IORead
))
357 return CTL_E_BADFILEMODE
;
362 static HRESULT WINAPI
textstream_ReadAll(ITextStream
*iface
, BSTR
*text
)
364 struct textstream
*This
= impl_from_ITextStream(iface
);
365 FIXME("(%p)->(%p): stub\n", This
, text
);
367 if (textstream_check_iomode(This
, IORead
))
368 return CTL_E_BADFILEMODE
;
373 static HRESULT WINAPI
textstream_Write(ITextStream
*iface
, BSTR text
)
375 struct textstream
*This
= impl_from_ITextStream(iface
);
376 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(text
));
380 static HRESULT WINAPI
textstream_WriteLine(ITextStream
*iface
, BSTR text
)
382 struct textstream
*This
= impl_from_ITextStream(iface
);
383 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(text
));
387 static HRESULT WINAPI
textstream_WriteBlankLines(ITextStream
*iface
, LONG lines
)
389 struct textstream
*This
= impl_from_ITextStream(iface
);
390 FIXME("(%p)->(%d): stub\n", This
, lines
);
394 static HRESULT WINAPI
textstream_Skip(ITextStream
*iface
, LONG count
)
396 struct textstream
*This
= impl_from_ITextStream(iface
);
397 FIXME("(%p)->(%d): stub\n", This
, count
);
401 static HRESULT WINAPI
textstream_SkipLine(ITextStream
*iface
)
403 struct textstream
*This
= impl_from_ITextStream(iface
);
404 FIXME("(%p): stub\n", This
);
408 static HRESULT WINAPI
textstream_Close(ITextStream
*iface
)
410 struct textstream
*This
= impl_from_ITextStream(iface
);
411 FIXME("(%p): stub\n", This
);
415 static const ITextStreamVtbl textstreamvtbl
= {
416 textstream_QueryInterface
,
419 textstream_GetTypeInfoCount
,
420 textstream_GetTypeInfo
,
421 textstream_GetIDsOfNames
,
424 textstream_get_Column
,
425 textstream_get_AtEndOfStream
,
426 textstream_get_AtEndOfLine
,
431 textstream_WriteLine
,
432 textstream_WriteBlankLines
,
438 static HRESULT
create_textstream(IOMode mode
, ITextStream
**ret
)
440 struct textstream
*stream
;
442 stream
= heap_alloc(sizeof(struct textstream
));
443 if (!stream
) return E_OUTOFMEMORY
;
445 stream
->ITextStream_iface
.lpVtbl
= &textstreamvtbl
;
449 *ret
= &stream
->ITextStream_iface
;
453 static HRESULT WINAPI
drive_QueryInterface(IDrive
*iface
, REFIID riid
, void **obj
)
455 struct drive
*This
= impl_from_IDrive(iface
);
457 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
461 if (IsEqualIID( riid
, &IID_IDrive
) ||
462 IsEqualIID( riid
, &IID_IDispatch
) ||
463 IsEqualIID( riid
, &IID_IUnknown
))
466 IDrive_AddRef(iface
);
469 return E_NOINTERFACE
;
474 static ULONG WINAPI
drive_AddRef(IDrive
*iface
)
476 struct drive
*This
= impl_from_IDrive(iface
);
477 ULONG ref
= InterlockedIncrement(&This
->ref
);
478 TRACE("(%p)->(%d)\n", This
, ref
);
482 static ULONG WINAPI
drive_Release(IDrive
*iface
)
484 struct drive
*This
= impl_from_IDrive(iface
);
485 ULONG ref
= InterlockedDecrement(&This
->ref
);
486 TRACE("(%p)->(%d)\n", This
, ref
);
490 SysFreeString(This
->root
);
497 static HRESULT WINAPI
drive_GetTypeInfoCount(IDrive
*iface
, UINT
*pctinfo
)
499 struct drive
*This
= impl_from_IDrive(iface
);
500 TRACE("(%p)->(%p)\n", This
, pctinfo
);
505 static HRESULT WINAPI
drive_GetTypeInfo(IDrive
*iface
, UINT iTInfo
,
506 LCID lcid
, ITypeInfo
**ppTInfo
)
508 struct drive
*This
= impl_from_IDrive(iface
);
509 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
510 return get_typeinfo(IDrive_tid
, ppTInfo
);
513 static HRESULT WINAPI
drive_GetIDsOfNames(IDrive
*iface
, REFIID riid
,
514 LPOLESTR
*rgszNames
, UINT cNames
,
515 LCID lcid
, DISPID
*rgDispId
)
517 struct drive
*This
= impl_from_IDrive(iface
);
521 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
523 hr
= get_typeinfo(IDrive_tid
, &typeinfo
);
526 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
527 ITypeInfo_Release(typeinfo
);
533 static HRESULT WINAPI
drive_Invoke(IDrive
*iface
, DISPID dispIdMember
,
534 REFIID riid
, LCID lcid
, WORD wFlags
,
535 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
536 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
538 struct drive
*This
= impl_from_IDrive(iface
);
542 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
543 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
545 hr
= get_typeinfo(IDrive_tid
, &typeinfo
);
548 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
549 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
550 ITypeInfo_Release(typeinfo
);
556 static HRESULT WINAPI
drive_get_Path(IDrive
*iface
, BSTR
*path
)
558 struct drive
*This
= impl_from_IDrive(iface
);
559 FIXME("(%p)->(%p): stub\n", This
, path
);
563 static HRESULT WINAPI
drive_get_DriveLetter(IDrive
*iface
, BSTR
*letter
)
565 struct drive
*This
= impl_from_IDrive(iface
);
566 FIXME("(%p)->(%p): stub\n", This
, letter
);
570 static HRESULT WINAPI
drive_get_ShareName(IDrive
*iface
, BSTR
*share_name
)
572 struct drive
*This
= impl_from_IDrive(iface
);
573 FIXME("(%p)->(%p): stub\n", This
, share_name
);
577 static HRESULT WINAPI
drive_get_DriveType(IDrive
*iface
, DriveTypeConst
*type
)
579 struct drive
*This
= impl_from_IDrive(iface
);
581 TRACE("(%p)->(%p)\n", This
, type
);
583 switch (GetDriveTypeW(This
->root
))
585 case DRIVE_REMOVABLE
:
608 static HRESULT WINAPI
drive_get_RootFolder(IDrive
*iface
, IFolder
**folder
)
610 struct drive
*This
= impl_from_IDrive(iface
);
611 FIXME("(%p)->(%p): stub\n", This
, folder
);
615 static HRESULT WINAPI
drive_get_AvailableSpace(IDrive
*iface
, VARIANT
*avail
)
617 struct drive
*This
= impl_from_IDrive(iface
);
618 FIXME("(%p)->(%p): stub\n", This
, avail
);
622 static HRESULT WINAPI
drive_get_FreeSpace(IDrive
*iface
, VARIANT
*v
)
624 struct drive
*This
= impl_from_IDrive(iface
);
625 FIXME("(%p)->(%p): stub\n", This
, v
);
629 static HRESULT WINAPI
drive_get_TotalSize(IDrive
*iface
, VARIANT
*v
)
631 struct drive
*This
= impl_from_IDrive(iface
);
632 FIXME("(%p)->(%p): stub\n", This
, v
);
636 static HRESULT WINAPI
drive_get_VolumeName(IDrive
*iface
, BSTR
*name
)
638 struct drive
*This
= impl_from_IDrive(iface
);
639 FIXME("(%p)->(%p): stub\n", This
, name
);
643 static HRESULT WINAPI
drive_put_VolumeName(IDrive
*iface
, BSTR name
)
645 struct drive
*This
= impl_from_IDrive(iface
);
646 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(name
));
650 static HRESULT WINAPI
drive_get_FileSystem(IDrive
*iface
, BSTR
*fs
)
652 struct drive
*This
= impl_from_IDrive(iface
);
653 FIXME("(%p)->(%p): stub\n", This
, fs
);
657 static HRESULT WINAPI
drive_get_SerialNumber(IDrive
*iface
, LONG
*serial
)
659 struct drive
*This
= impl_from_IDrive(iface
);
660 FIXME("(%p)->(%p): stub\n", This
, serial
);
664 static HRESULT WINAPI
drive_get_IsReady(IDrive
*iface
, VARIANT_BOOL
*ready
)
666 struct drive
*This
= impl_from_IDrive(iface
);
667 FIXME("(%p)->(%p): stub\n", This
, ready
);
671 static const IDriveVtbl drivevtbl
= {
672 drive_QueryInterface
,
675 drive_GetTypeInfoCount
,
680 drive_get_DriveLetter
,
683 drive_get_RootFolder
,
684 drive_get_AvailableSpace
,
687 drive_get_VolumeName
,
688 drive_put_VolumeName
,
689 drive_get_FileSystem
,
690 drive_get_SerialNumber
,
694 static HRESULT
create_drive(WCHAR letter
, IDrive
**drive
)
700 This
= heap_alloc(sizeof(*This
));
701 if (!This
) return E_OUTOFMEMORY
;
703 This
->IDrive_iface
.lpVtbl
= &drivevtbl
;
705 This
->root
= SysAllocStringLen(NULL
, 3);
709 return E_OUTOFMEMORY
;
711 This
->root
[0] = letter
;
713 This
->root
[2] = '\\';
716 *drive
= &This
->IDrive_iface
;
720 static HRESULT WINAPI
enumvariant_QueryInterface(IEnumVARIANT
*iface
, REFIID riid
, void **obj
)
722 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
724 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
728 if (IsEqualIID( riid
, &IID_IEnumVARIANT
) ||
729 IsEqualIID( riid
, &IID_IUnknown
))
732 IEnumVARIANT_AddRef(iface
);
735 return E_NOINTERFACE
;
740 static ULONG WINAPI
enumvariant_AddRef(IEnumVARIANT
*iface
)
742 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
743 ULONG ref
= InterlockedIncrement(&This
->ref
);
744 TRACE("(%p)->(%d)\n", This
, ref
);
748 static ULONG WINAPI
foldercoll_enumvariant_Release(IEnumVARIANT
*iface
)
750 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
751 ULONG ref
= InterlockedDecrement(&This
->ref
);
753 TRACE("(%p)->(%d)\n", This
, ref
);
757 IFolderCollection_Release(&This
->data
.u
.foldercoll
.coll
->IFolderCollection_iface
);
758 FindClose(This
->data
.u
.foldercoll
.find
);
765 static HANDLE
start_enumeration(const WCHAR
*path
, WIN32_FIND_DATAW
*data
, BOOL file
)
767 static const WCHAR allW
[] = {'*',0};
768 WCHAR pathW
[MAX_PATH
];
772 strcpyW(pathW
, path
);
773 len
= strlenW(pathW
);
774 if (pathW
[len
-1] != '\\')
776 strcatW(pathW
, allW
);
777 handle
= FindFirstFileW(pathW
, data
);
778 if (handle
== INVALID_HANDLE_VALUE
) return 0;
780 /* find first dir/file */
783 if (file
? is_file_data(data
) : is_dir_data(data
))
786 if (!FindNextFileW(handle
, data
))
795 static HRESULT WINAPI
foldercoll_enumvariant_Next(IEnumVARIANT
*iface
, ULONG celt
, VARIANT
*var
, ULONG
*fetched
)
797 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
798 HANDLE handle
= This
->data
.u
.foldercoll
.find
;
799 WIN32_FIND_DATAW data
;
802 TRACE("(%p)->(%d %p %p)\n", This
, celt
, var
, fetched
);
807 if (!celt
) return S_OK
;
811 handle
= start_enumeration(This
->data
.u
.foldercoll
.coll
->path
, &data
, FALSE
);
812 if (!handle
) return S_FALSE
;
814 This
->data
.u
.foldercoll
.find
= handle
;
818 if (!FindNextFileW(handle
, &data
))
824 if (is_dir_data(&data
))
830 str
= get_full_path(This
->data
.u
.foldercoll
.coll
->path
, &data
);
831 hr
= create_folder(str
, &folder
);
833 if (FAILED(hr
)) return hr
;
835 V_VT(&var
[count
]) = VT_DISPATCH
;
836 V_DISPATCH(&var
[count
]) = (IDispatch
*)folder
;
839 if (count
>= celt
) break;
841 } while (FindNextFileW(handle
, &data
));
846 return (count
< celt
) ? S_FALSE
: S_OK
;
849 static HRESULT WINAPI
foldercoll_enumvariant_Skip(IEnumVARIANT
*iface
, ULONG celt
)
851 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
852 HANDLE handle
= This
->data
.u
.foldercoll
.find
;
853 WIN32_FIND_DATAW data
;
855 TRACE("(%p)->(%d)\n", This
, celt
);
857 if (!celt
) return S_OK
;
861 handle
= start_enumeration(This
->data
.u
.foldercoll
.coll
->path
, &data
, FALSE
);
862 if (!handle
) return S_FALSE
;
864 This
->data
.u
.foldercoll
.find
= handle
;
868 if (!FindNextFileW(handle
, &data
))
874 if (is_dir_data(&data
))
878 } while (FindNextFileW(handle
, &data
));
880 return celt
? S_FALSE
: S_OK
;
883 static HRESULT WINAPI
foldercoll_enumvariant_Reset(IEnumVARIANT
*iface
)
885 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
887 TRACE("(%p)\n", This
);
889 FindClose(This
->data
.u
.foldercoll
.find
);
890 This
->data
.u
.foldercoll
.find
= NULL
;
895 static HRESULT WINAPI
foldercoll_enumvariant_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**pclone
)
897 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
898 TRACE("(%p)->(%p)\n", This
, pclone
);
899 return create_foldercoll_enum(This
->data
.u
.foldercoll
.coll
, (IUnknown
**)pclone
);
902 static const IEnumVARIANTVtbl foldercollenumvariantvtbl
= {
903 enumvariant_QueryInterface
,
905 foldercoll_enumvariant_Release
,
906 foldercoll_enumvariant_Next
,
907 foldercoll_enumvariant_Skip
,
908 foldercoll_enumvariant_Reset
,
909 foldercoll_enumvariant_Clone
912 static HRESULT
create_foldercoll_enum(struct foldercollection
*collection
, IUnknown
**newenum
)
914 struct enumvariant
*This
;
918 This
= heap_alloc(sizeof(*This
));
919 if (!This
) return E_OUTOFMEMORY
;
921 This
->IEnumVARIANT_iface
.lpVtbl
= &foldercollenumvariantvtbl
;
923 This
->data
.u
.foldercoll
.find
= NULL
;
924 This
->data
.u
.foldercoll
.coll
= collection
;
925 IFolderCollection_AddRef(&collection
->IFolderCollection_iface
);
927 *newenum
= (IUnknown
*)&This
->IEnumVARIANT_iface
;
932 static ULONG WINAPI
filecoll_enumvariant_Release(IEnumVARIANT
*iface
)
934 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
935 ULONG ref
= InterlockedDecrement(&This
->ref
);
937 TRACE("(%p)->(%d)\n", This
, ref
);
941 IFileCollection_Release(&This
->data
.u
.filecoll
.coll
->IFileCollection_iface
);
942 FindClose(This
->data
.u
.filecoll
.find
);
949 static HRESULT WINAPI
filecoll_enumvariant_Next(IEnumVARIANT
*iface
, ULONG celt
, VARIANT
*var
, ULONG
*fetched
)
951 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
952 HANDLE handle
= This
->data
.u
.filecoll
.find
;
953 WIN32_FIND_DATAW data
;
956 TRACE("(%p)->(%d %p %p)\n", This
, celt
, var
, fetched
);
961 if (!celt
) return S_OK
;
965 handle
= start_enumeration(This
->data
.u
.filecoll
.coll
->path
, &data
, TRUE
);
966 if (!handle
) return S_FALSE
;
967 This
->data
.u
.filecoll
.find
= handle
;
969 else if (!FindNextFileW(handle
, &data
))
974 if (is_file_data(&data
))
980 str
= get_full_path(This
->data
.u
.filecoll
.coll
->path
, &data
);
981 hr
= create_file(str
, &file
);
983 if (FAILED(hr
)) return hr
;
985 V_VT(&var
[count
]) = VT_DISPATCH
;
986 V_DISPATCH(&var
[count
]) = (IDispatch
*)file
;
987 if (++count
>= celt
) break;
989 } while (FindNextFileW(handle
, &data
));
994 return (count
< celt
) ? S_FALSE
: S_OK
;
997 static HRESULT WINAPI
filecoll_enumvariant_Skip(IEnumVARIANT
*iface
, ULONG celt
)
999 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1000 HANDLE handle
= This
->data
.u
.filecoll
.find
;
1001 WIN32_FIND_DATAW data
;
1003 TRACE("(%p)->(%d)\n", This
, celt
);
1005 if (!celt
) return S_OK
;
1009 handle
= start_enumeration(This
->data
.u
.filecoll
.coll
->path
, &data
, TRUE
);
1010 if (!handle
) return S_FALSE
;
1011 This
->data
.u
.filecoll
.find
= handle
;
1013 else if (!FindNextFileW(handle
, &data
))
1018 if (is_file_data(&data
))
1020 } while (celt
&& FindNextFileW(handle
, &data
));
1022 return celt
? S_FALSE
: S_OK
;
1025 static HRESULT WINAPI
filecoll_enumvariant_Reset(IEnumVARIANT
*iface
)
1027 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1029 TRACE("(%p)\n", This
);
1031 FindClose(This
->data
.u
.filecoll
.find
);
1032 This
->data
.u
.filecoll
.find
= NULL
;
1037 static HRESULT WINAPI
filecoll_enumvariant_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**pclone
)
1039 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1040 TRACE("(%p)->(%p)\n", This
, pclone
);
1041 return create_filecoll_enum(This
->data
.u
.filecoll
.coll
, (IUnknown
**)pclone
);
1044 static const IEnumVARIANTVtbl filecollenumvariantvtbl
= {
1045 enumvariant_QueryInterface
,
1047 filecoll_enumvariant_Release
,
1048 filecoll_enumvariant_Next
,
1049 filecoll_enumvariant_Skip
,
1050 filecoll_enumvariant_Reset
,
1051 filecoll_enumvariant_Clone
1054 static HRESULT
create_filecoll_enum(struct filecollection
*collection
, IUnknown
**newenum
)
1056 struct enumvariant
*This
;
1060 This
= heap_alloc(sizeof(*This
));
1061 if (!This
) return E_OUTOFMEMORY
;
1063 This
->IEnumVARIANT_iface
.lpVtbl
= &filecollenumvariantvtbl
;
1065 This
->data
.u
.filecoll
.find
= NULL
;
1066 This
->data
.u
.filecoll
.coll
= collection
;
1067 IFileCollection_AddRef(&collection
->IFileCollection_iface
);
1069 *newenum
= (IUnknown
*)&This
->IEnumVARIANT_iface
;
1074 static ULONG WINAPI
drivecoll_enumvariant_Release(IEnumVARIANT
*iface
)
1076 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1077 ULONG ref
= InterlockedDecrement(&This
->ref
);
1079 TRACE("(%p)->(%d)\n", This
, ref
);
1083 IDriveCollection_Release(&This
->data
.u
.drivecoll
.coll
->IDriveCollection_iface
);
1090 static HRESULT
find_next_drive(struct enumvariant
*penum
)
1092 int i
= penum
->data
.u
.drivecoll
.cur
== -1 ? 0 : penum
->data
.u
.drivecoll
.cur
+ 1;
1095 if (penum
->data
.u
.drivecoll
.coll
->drives
& (1 << i
))
1097 penum
->data
.u
.drivecoll
.cur
= i
;
1104 static HRESULT WINAPI
drivecoll_enumvariant_Next(IEnumVARIANT
*iface
, ULONG celt
, VARIANT
*var
, ULONG
*fetched
)
1106 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1109 TRACE("(%p)->(%d %p %p)\n", This
, celt
, var
, fetched
);
1114 if (!celt
) return S_OK
;
1116 while (find_next_drive(This
) == S_OK
)
1121 hr
= create_drive('A' + This
->data
.u
.drivecoll
.cur
, &drive
);
1122 if (FAILED(hr
)) return hr
;
1124 V_VT(&var
[count
]) = VT_DISPATCH
;
1125 V_DISPATCH(&var
[count
]) = (IDispatch
*)drive
;
1127 if (++count
>= celt
) break;
1133 return (count
< celt
) ? S_FALSE
: S_OK
;
1136 static HRESULT WINAPI
drivecoll_enumvariant_Skip(IEnumVARIANT
*iface
, ULONG celt
)
1138 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1140 TRACE("(%p)->(%d)\n", This
, celt
);
1142 if (!celt
) return S_OK
;
1144 while (celt
&& find_next_drive(This
) == S_OK
)
1147 return celt
? S_FALSE
: S_OK
;
1150 static HRESULT WINAPI
drivecoll_enumvariant_Reset(IEnumVARIANT
*iface
)
1152 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1154 TRACE("(%p)\n", This
);
1156 This
->data
.u
.drivecoll
.cur
= -1;
1160 static HRESULT WINAPI
drivecoll_enumvariant_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**pclone
)
1162 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1163 FIXME("(%p)->(%p): stub\n", This
, pclone
);
1167 static const IEnumVARIANTVtbl drivecollenumvariantvtbl
= {
1168 enumvariant_QueryInterface
,
1170 drivecoll_enumvariant_Release
,
1171 drivecoll_enumvariant_Next
,
1172 drivecoll_enumvariant_Skip
,
1173 drivecoll_enumvariant_Reset
,
1174 drivecoll_enumvariant_Clone
1177 static HRESULT
create_drivecoll_enum(struct drivecollection
*collection
, IUnknown
**newenum
)
1179 struct enumvariant
*This
;
1183 This
= heap_alloc(sizeof(*This
));
1184 if (!This
) return E_OUTOFMEMORY
;
1186 This
->IEnumVARIANT_iface
.lpVtbl
= &drivecollenumvariantvtbl
;
1188 This
->data
.u
.drivecoll
.coll
= collection
;
1189 This
->data
.u
.drivecoll
.cur
= -1;
1190 IDriveCollection_AddRef(&collection
->IDriveCollection_iface
);
1192 *newenum
= (IUnknown
*)&This
->IEnumVARIANT_iface
;
1197 static HRESULT WINAPI
foldercoll_QueryInterface(IFolderCollection
*iface
, REFIID riid
, void **obj
)
1199 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1201 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1205 if (IsEqualIID( riid
, &IID_IFolderCollection
) ||
1206 IsEqualIID( riid
, &IID_IDispatch
) ||
1207 IsEqualIID( riid
, &IID_IUnknown
))
1210 IFolderCollection_AddRef(iface
);
1213 return E_NOINTERFACE
;
1218 static ULONG WINAPI
foldercoll_AddRef(IFolderCollection
*iface
)
1220 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1221 ULONG ref
= InterlockedIncrement(&This
->ref
);
1222 TRACE("(%p)->(%d)\n", This
, ref
);
1226 static ULONG WINAPI
foldercoll_Release(IFolderCollection
*iface
)
1228 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1229 ULONG ref
= InterlockedDecrement(&This
->ref
);
1230 TRACE("(%p)->(%d)\n", This
, ref
);
1234 SysFreeString(This
->path
);
1241 static HRESULT WINAPI
foldercoll_GetTypeInfoCount(IFolderCollection
*iface
, UINT
*pctinfo
)
1243 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1244 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1249 static HRESULT WINAPI
foldercoll_GetTypeInfo(IFolderCollection
*iface
, UINT iTInfo
,
1250 LCID lcid
, ITypeInfo
**ppTInfo
)
1252 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1253 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1254 return get_typeinfo(IFolderCollection_tid
, ppTInfo
);
1257 static HRESULT WINAPI
foldercoll_GetIDsOfNames(IFolderCollection
*iface
, REFIID riid
,
1258 LPOLESTR
*rgszNames
, UINT cNames
,
1259 LCID lcid
, DISPID
*rgDispId
)
1261 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1262 ITypeInfo
*typeinfo
;
1265 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1267 hr
= get_typeinfo(IFolderCollection_tid
, &typeinfo
);
1270 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1271 ITypeInfo_Release(typeinfo
);
1277 static HRESULT WINAPI
foldercoll_Invoke(IFolderCollection
*iface
, DISPID dispIdMember
,
1278 REFIID riid
, LCID lcid
, WORD wFlags
,
1279 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1280 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1282 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1283 ITypeInfo
*typeinfo
;
1286 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1287 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1289 hr
= get_typeinfo(IFolderCollection_tid
, &typeinfo
);
1292 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
1293 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1294 ITypeInfo_Release(typeinfo
);
1300 static HRESULT WINAPI
foldercoll_Add(IFolderCollection
*iface
, BSTR name
, IFolder
**folder
)
1302 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1303 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_w(name
), folder
);
1307 static HRESULT WINAPI
foldercoll_get_Item(IFolderCollection
*iface
, VARIANT key
, IFolder
**folder
)
1309 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1310 FIXME("(%p)->(%p): stub\n", This
, folder
);
1314 static HRESULT WINAPI
foldercoll_get__NewEnum(IFolderCollection
*iface
, IUnknown
**newenum
)
1316 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1318 TRACE("(%p)->(%p)\n", This
, newenum
);
1323 return create_foldercoll_enum(This
, newenum
);
1326 static HRESULT WINAPI
foldercoll_get_Count(IFolderCollection
*iface
, LONG
*count
)
1328 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1329 static const WCHAR allW
[] = {'\\','*',0};
1330 WIN32_FIND_DATAW data
;
1331 WCHAR pathW
[MAX_PATH
];
1334 TRACE("(%p)->(%p)\n", This
, count
);
1341 strcpyW(pathW
, This
->path
);
1342 strcatW(pathW
, allW
);
1343 handle
= FindFirstFileW(pathW
, &data
);
1344 if (handle
== INVALID_HANDLE_VALUE
)
1345 return HRESULT_FROM_WIN32(GetLastError());
1349 if (is_dir_data(&data
))
1351 } while (FindNextFileW(handle
, &data
));
1357 static const IFolderCollectionVtbl foldercollvtbl
= {
1358 foldercoll_QueryInterface
,
1361 foldercoll_GetTypeInfoCount
,
1362 foldercoll_GetTypeInfo
,
1363 foldercoll_GetIDsOfNames
,
1366 foldercoll_get_Item
,
1367 foldercoll_get__NewEnum
,
1368 foldercoll_get_Count
1371 static HRESULT
create_foldercoll(BSTR path
, IFolderCollection
**folders
)
1373 struct foldercollection
*This
;
1377 This
= heap_alloc(sizeof(struct foldercollection
));
1378 if (!This
) return E_OUTOFMEMORY
;
1380 This
->IFolderCollection_iface
.lpVtbl
= &foldercollvtbl
;
1382 This
->path
= SysAllocString(path
);
1386 return E_OUTOFMEMORY
;
1389 *folders
= &This
->IFolderCollection_iface
;
1394 static HRESULT WINAPI
filecoll_QueryInterface(IFileCollection
*iface
, REFIID riid
, void **obj
)
1396 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1398 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1402 if (IsEqualIID( riid
, &IID_IFileCollection
) ||
1403 IsEqualIID( riid
, &IID_IDispatch
) ||
1404 IsEqualIID( riid
, &IID_IUnknown
))
1407 IFileCollection_AddRef(iface
);
1410 return E_NOINTERFACE
;
1415 static ULONG WINAPI
filecoll_AddRef(IFileCollection
*iface
)
1417 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1418 ULONG ref
= InterlockedIncrement(&This
->ref
);
1419 TRACE("(%p)->(%d)\n", This
, ref
);
1423 static ULONG WINAPI
filecoll_Release(IFileCollection
*iface
)
1425 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1426 ULONG ref
= InterlockedDecrement(&This
->ref
);
1427 TRACE("(%p)->(%d)\n", This
, ref
);
1431 SysFreeString(This
->path
);
1438 static HRESULT WINAPI
filecoll_GetTypeInfoCount(IFileCollection
*iface
, UINT
*pctinfo
)
1440 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1441 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1446 static HRESULT WINAPI
filecoll_GetTypeInfo(IFileCollection
*iface
, UINT iTInfo
,
1447 LCID lcid
, ITypeInfo
**ppTInfo
)
1449 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1450 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1451 return get_typeinfo(IFileCollection_tid
, ppTInfo
);
1454 static HRESULT WINAPI
filecoll_GetIDsOfNames(IFileCollection
*iface
, REFIID riid
,
1455 LPOLESTR
*rgszNames
, UINT cNames
,
1456 LCID lcid
, DISPID
*rgDispId
)
1458 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1459 ITypeInfo
*typeinfo
;
1462 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1464 hr
= get_typeinfo(IFileCollection_tid
, &typeinfo
);
1467 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1468 ITypeInfo_Release(typeinfo
);
1474 static HRESULT WINAPI
filecoll_Invoke(IFileCollection
*iface
, DISPID dispIdMember
,
1475 REFIID riid
, LCID lcid
, WORD wFlags
,
1476 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1477 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1479 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1480 ITypeInfo
*typeinfo
;
1483 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1484 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1486 hr
= get_typeinfo(IFileCollection_tid
, &typeinfo
);
1489 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
1490 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1491 ITypeInfo_Release(typeinfo
);
1497 static HRESULT WINAPI
filecoll_get_Item(IFileCollection
*iface
, VARIANT Key
, IFile
**file
)
1499 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1500 FIXME("(%p)->(%p)\n", This
, file
);
1504 static HRESULT WINAPI
filecoll_get__NewEnum(IFileCollection
*iface
, IUnknown
**ppenum
)
1506 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1508 TRACE("(%p)->(%p)\n", This
, ppenum
);
1513 return create_filecoll_enum(This
, ppenum
);
1516 static HRESULT WINAPI
filecoll_get_Count(IFileCollection
*iface
, LONG
*count
)
1518 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1519 FIXME("(%p)->(%p)\n", This
, count
);
1523 static const IFileCollectionVtbl filecollectionvtbl
= {
1524 filecoll_QueryInterface
,
1527 filecoll_GetTypeInfoCount
,
1528 filecoll_GetTypeInfo
,
1529 filecoll_GetIDsOfNames
,
1532 filecoll_get__NewEnum
,
1536 static HRESULT
create_filecoll(BSTR path
, IFileCollection
**files
)
1538 struct filecollection
*This
;
1542 This
= heap_alloc(sizeof(*This
));
1543 if (!This
) return E_OUTOFMEMORY
;
1545 This
->IFileCollection_iface
.lpVtbl
= &filecollectionvtbl
;
1547 This
->path
= SysAllocString(path
);
1551 return E_OUTOFMEMORY
;
1554 *files
= &This
->IFileCollection_iface
;
1558 static HRESULT WINAPI
drivecoll_QueryInterface(IDriveCollection
*iface
, REFIID riid
, void **obj
)
1560 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1562 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1566 if (IsEqualIID( riid
, &IID_IDriveCollection
) ||
1567 IsEqualIID( riid
, &IID_IDispatch
) ||
1568 IsEqualIID( riid
, &IID_IUnknown
))
1571 IDriveCollection_AddRef(iface
);
1574 return E_NOINTERFACE
;
1579 static ULONG WINAPI
drivecoll_AddRef(IDriveCollection
*iface
)
1581 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1582 ULONG ref
= InterlockedIncrement(&This
->ref
);
1583 TRACE("(%p)->(%d)\n", This
, ref
);
1587 static ULONG WINAPI
drivecoll_Release(IDriveCollection
*iface
)
1589 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1590 ULONG ref
= InterlockedDecrement(&This
->ref
);
1591 TRACE("(%p)->(%d)\n", This
, ref
);
1599 static HRESULT WINAPI
drivecoll_GetTypeInfoCount(IDriveCollection
*iface
, UINT
*pctinfo
)
1601 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1602 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1607 static HRESULT WINAPI
drivecoll_GetTypeInfo(IDriveCollection
*iface
, UINT iTInfo
,
1608 LCID lcid
, ITypeInfo
**ppTInfo
)
1610 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1611 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1612 return get_typeinfo(IDriveCollection_tid
, ppTInfo
);
1615 static HRESULT WINAPI
drivecoll_GetIDsOfNames(IDriveCollection
*iface
, REFIID riid
,
1616 LPOLESTR
*rgszNames
, UINT cNames
,
1617 LCID lcid
, DISPID
*rgDispId
)
1619 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1620 ITypeInfo
*typeinfo
;
1623 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1625 hr
= get_typeinfo(IDriveCollection_tid
, &typeinfo
);
1628 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1629 ITypeInfo_Release(typeinfo
);
1635 static HRESULT WINAPI
drivecoll_Invoke(IDriveCollection
*iface
, DISPID dispIdMember
,
1636 REFIID riid
, LCID lcid
, WORD wFlags
,
1637 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1638 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1640 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1641 ITypeInfo
*typeinfo
;
1644 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1645 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1647 hr
= get_typeinfo(IDriveCollection_tid
, &typeinfo
);
1650 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
1651 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1652 ITypeInfo_Release(typeinfo
);
1658 static HRESULT WINAPI
drivecoll_get_Item(IDriveCollection
*iface
, VARIANT key
, IDrive
**drive
)
1660 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1661 FIXME("(%p)->(%p): stub\n", This
, drive
);
1665 static HRESULT WINAPI
drivecoll_get__NewEnum(IDriveCollection
*iface
, IUnknown
**ppenum
)
1667 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1669 TRACE("(%p)->(%p)\n", This
, ppenum
);
1674 return create_drivecoll_enum(This
, ppenum
);
1677 static HRESULT WINAPI
drivecoll_get_Count(IDriveCollection
*iface
, LONG
*count
)
1679 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1681 TRACE("(%p)->(%p)\n", This
, count
);
1683 if (!count
) return E_POINTER
;
1685 *count
= This
->count
;
1689 static const IDriveCollectionVtbl drivecollectionvtbl
= {
1690 drivecoll_QueryInterface
,
1693 drivecoll_GetTypeInfoCount
,
1694 drivecoll_GetTypeInfo
,
1695 drivecoll_GetIDsOfNames
,
1698 drivecoll_get__NewEnum
,
1702 static HRESULT
create_drivecoll(IDriveCollection
**drives
)
1704 struct drivecollection
*This
;
1709 This
= heap_alloc(sizeof(*This
));
1710 if (!This
) return E_OUTOFMEMORY
;
1712 This
->IDriveCollection_iface
.lpVtbl
= &drivecollectionvtbl
;
1714 This
->drives
= mask
= GetLogicalDrives();
1715 /* count set bits */
1716 for (This
->count
= 0; mask
; This
->count
++)
1719 *drives
= &This
->IDriveCollection_iface
;
1723 static HRESULT WINAPI
folder_QueryInterface(IFolder
*iface
, REFIID riid
, void **obj
)
1725 struct folder
*This
= impl_from_IFolder(iface
);
1727 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1731 if (IsEqualIID( riid
, &IID_IFolder
) ||
1732 IsEqualIID( riid
, &IID_IDispatch
) ||
1733 IsEqualIID( riid
, &IID_IUnknown
))
1736 IFolder_AddRef(iface
);
1739 return E_NOINTERFACE
;
1744 static ULONG WINAPI
folder_AddRef(IFolder
*iface
)
1746 struct folder
*This
= impl_from_IFolder(iface
);
1747 ULONG ref
= InterlockedIncrement(&This
->ref
);
1748 TRACE("(%p)->(%d)\n", This
, ref
);
1752 static ULONG WINAPI
folder_Release(IFolder
*iface
)
1754 struct folder
*This
= impl_from_IFolder(iface
);
1755 ULONG ref
= InterlockedDecrement(&This
->ref
);
1756 TRACE("(%p)->(%d)\n", This
, ref
);
1760 SysFreeString(This
->path
);
1767 static HRESULT WINAPI
folder_GetTypeInfoCount(IFolder
*iface
, UINT
*pctinfo
)
1769 struct folder
*This
= impl_from_IFolder(iface
);
1770 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1775 static HRESULT WINAPI
folder_GetTypeInfo(IFolder
*iface
, UINT iTInfo
,
1776 LCID lcid
, ITypeInfo
**ppTInfo
)
1778 struct folder
*This
= impl_from_IFolder(iface
);
1779 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1780 return get_typeinfo(IFolder_tid
, ppTInfo
);
1783 static HRESULT WINAPI
folder_GetIDsOfNames(IFolder
*iface
, REFIID riid
,
1784 LPOLESTR
*rgszNames
, UINT cNames
,
1785 LCID lcid
, DISPID
*rgDispId
)
1787 struct folder
*This
= impl_from_IFolder(iface
);
1788 ITypeInfo
*typeinfo
;
1791 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1793 hr
= get_typeinfo(IFolder_tid
, &typeinfo
);
1796 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1797 ITypeInfo_Release(typeinfo
);
1803 static HRESULT WINAPI
folder_Invoke(IFolder
*iface
, DISPID dispIdMember
,
1804 REFIID riid
, LCID lcid
, WORD wFlags
,
1805 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1806 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1808 struct folder
*This
= impl_from_IFolder(iface
);
1809 ITypeInfo
*typeinfo
;
1812 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1813 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1815 hr
= get_typeinfo(IFolder_tid
, &typeinfo
);
1818 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
1819 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1820 ITypeInfo_Release(typeinfo
);
1826 static HRESULT WINAPI
folder_get_Path(IFolder
*iface
, BSTR
*path
)
1828 struct folder
*This
= impl_from_IFolder(iface
);
1829 FIXME("(%p)->(%p): stub\n", This
, path
);
1833 static HRESULT WINAPI
folder_get_Name(IFolder
*iface
, BSTR
*name
)
1835 struct folder
*This
= impl_from_IFolder(iface
);
1838 TRACE("(%p)->(%p)\n", This
, name
);
1845 ptr
= strrchrW(This
->path
, '\\');
1848 *name
= SysAllocString(ptr
+1);
1849 TRACE("%s\n", debugstr_w(*name
));
1850 if (!*name
) return E_OUTOFMEMORY
;
1858 static HRESULT WINAPI
folder_put_Name(IFolder
*iface
, BSTR name
)
1860 struct folder
*This
= impl_from_IFolder(iface
);
1861 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(name
));
1865 static HRESULT WINAPI
folder_get_ShortPath(IFolder
*iface
, BSTR
*path
)
1867 struct folder
*This
= impl_from_IFolder(iface
);
1868 FIXME("(%p)->(%p): stub\n", This
, path
);
1872 static HRESULT WINAPI
folder_get_ShortName(IFolder
*iface
, BSTR
*name
)
1874 struct folder
*This
= impl_from_IFolder(iface
);
1875 FIXME("(%p)->(%p): stub\n", This
, name
);
1879 static HRESULT WINAPI
folder_get_Drive(IFolder
*iface
, IDrive
**drive
)
1881 struct folder
*This
= impl_from_IFolder(iface
);
1882 FIXME("(%p)->(%p): stub\n", This
, drive
);
1886 static HRESULT WINAPI
folder_get_ParentFolder(IFolder
*iface
, IFolder
**parent
)
1888 struct folder
*This
= impl_from_IFolder(iface
);
1889 FIXME("(%p)->(%p): stub\n", This
, parent
);
1893 static HRESULT WINAPI
folder_get_Attributes(IFolder
*iface
, FileAttribute
*attr
)
1895 struct folder
*This
= impl_from_IFolder(iface
);
1896 FIXME("(%p)->(%p): stub\n", This
, attr
);
1900 static HRESULT WINAPI
folder_put_Attributes(IFolder
*iface
, FileAttribute attr
)
1902 struct folder
*This
= impl_from_IFolder(iface
);
1903 FIXME("(%p)->(0x%x): stub\n", This
, attr
);
1907 static HRESULT WINAPI
folder_get_DateCreated(IFolder
*iface
, DATE
*date
)
1909 struct folder
*This
= impl_from_IFolder(iface
);
1910 FIXME("(%p)->(%p): stub\n", This
, date
);
1914 static HRESULT WINAPI
folder_get_DateLastModified(IFolder
*iface
, DATE
*date
)
1916 struct folder
*This
= impl_from_IFolder(iface
);
1917 FIXME("(%p)->(%p): stub\n", This
, date
);
1921 static HRESULT WINAPI
folder_get_DateLastAccessed(IFolder
*iface
, DATE
*date
)
1923 struct folder
*This
= impl_from_IFolder(iface
);
1924 FIXME("(%p)->(%p): stub\n", This
, date
);
1928 static HRESULT WINAPI
folder_get_Type(IFolder
*iface
, BSTR
*type
)
1930 struct folder
*This
= impl_from_IFolder(iface
);
1931 FIXME("(%p)->(%p): stub\n", This
, type
);
1935 static HRESULT WINAPI
folder_Delete(IFolder
*iface
, VARIANT_BOOL force
)
1937 struct folder
*This
= impl_from_IFolder(iface
);
1938 FIXME("(%p)->(%x): stub\n", This
, force
);
1942 static HRESULT WINAPI
folder_Copy(IFolder
*iface
, BSTR dest
, VARIANT_BOOL overwrite
)
1944 struct folder
*This
= impl_from_IFolder(iface
);
1945 FIXME("(%p)->(%s %x): stub\n", This
, debugstr_w(dest
), overwrite
);
1949 static HRESULT WINAPI
folder_Move(IFolder
*iface
, BSTR dest
)
1951 struct folder
*This
= impl_from_IFolder(iface
);
1952 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(dest
));
1956 static HRESULT WINAPI
folder_get_IsRootFolder(IFolder
*iface
, VARIANT_BOOL
*isroot
)
1958 struct folder
*This
= impl_from_IFolder(iface
);
1959 FIXME("(%p)->(%p): stub\n", This
, isroot
);
1963 static HRESULT WINAPI
folder_get_Size(IFolder
*iface
, VARIANT
*size
)
1965 struct folder
*This
= impl_from_IFolder(iface
);
1966 FIXME("(%p)->(%p): stub\n", This
, size
);
1970 static HRESULT WINAPI
folder_get_SubFolders(IFolder
*iface
, IFolderCollection
**folders
)
1972 struct folder
*This
= impl_from_IFolder(iface
);
1974 TRACE("(%p)->(%p)\n", This
, folders
);
1979 return create_foldercoll(This
->path
, folders
);
1982 static HRESULT WINAPI
folder_get_Files(IFolder
*iface
, IFileCollection
**files
)
1984 struct folder
*This
= impl_from_IFolder(iface
);
1986 TRACE("(%p)->(%p)\n", This
, files
);
1991 return create_filecoll(This
->path
, files
);
1994 static HRESULT WINAPI
folder_CreateTextFile(IFolder
*iface
, BSTR filename
, VARIANT_BOOL overwrite
,
1995 VARIANT_BOOL unicode
, ITextStream
**stream
)
1997 struct folder
*This
= impl_from_IFolder(iface
);
1998 FIXME("(%p)->(%s %x %x %p): stub\n", This
, debugstr_w(filename
), overwrite
, unicode
, stream
);
2002 static const IFolderVtbl foldervtbl
= {
2003 folder_QueryInterface
,
2006 folder_GetTypeInfoCount
,
2008 folder_GetIDsOfNames
,
2013 folder_get_ShortPath
,
2014 folder_get_ShortName
,
2016 folder_get_ParentFolder
,
2017 folder_get_Attributes
,
2018 folder_put_Attributes
,
2019 folder_get_DateCreated
,
2020 folder_get_DateLastModified
,
2021 folder_get_DateLastAccessed
,
2026 folder_get_IsRootFolder
,
2028 folder_get_SubFolders
,
2030 folder_CreateTextFile
2033 HRESULT
create_folder(const WCHAR
*path
, IFolder
**folder
)
2035 struct folder
*This
;
2039 TRACE("%s\n", debugstr_w(path
));
2041 This
= heap_alloc(sizeof(struct folder
));
2042 if (!This
) return E_OUTOFMEMORY
;
2044 This
->IFolder_iface
.lpVtbl
= &foldervtbl
;
2046 This
->path
= SysAllocString(path
);
2050 return E_OUTOFMEMORY
;
2053 *folder
= &This
->IFolder_iface
;
2058 static HRESULT WINAPI
file_QueryInterface(IFile
*iface
, REFIID riid
, void **obj
)
2060 struct file
*This
= impl_from_IFile(iface
);
2062 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
2064 if (IsEqualIID(riid
, &IID_IFile
) ||
2065 IsEqualIID(riid
, &IID_IDispatch
) ||
2066 IsEqualIID(riid
, &IID_IUnknown
))
2069 IFile_AddRef(iface
);
2074 return E_NOINTERFACE
;
2077 static ULONG WINAPI
file_AddRef(IFile
*iface
)
2079 struct file
*This
= impl_from_IFile(iface
);
2080 LONG ref
= InterlockedIncrement(&This
->ref
);
2082 TRACE("(%p) ref=%d\n", This
, ref
);
2087 static ULONG WINAPI
file_Release(IFile
*iface
)
2089 struct file
*This
= impl_from_IFile(iface
);
2090 LONG ref
= InterlockedDecrement(&This
->ref
);
2092 TRACE("(%p) ref=%d\n", This
, ref
);
2096 heap_free(This
->path
);
2103 static HRESULT WINAPI
file_GetTypeInfoCount(IFile
*iface
, UINT
*pctinfo
)
2105 struct file
*This
= impl_from_IFile(iface
);
2107 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2113 static HRESULT WINAPI
file_GetTypeInfo(IFile
*iface
,
2114 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
2116 struct file
*This
= impl_from_IFile(iface
);
2118 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2120 return get_typeinfo(IFile_tid
, ppTInfo
);
2123 static HRESULT WINAPI
file_GetIDsOfNames(IFile
*iface
, REFIID riid
,
2124 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2126 struct file
*This
= impl_from_IFile(iface
);
2127 ITypeInfo
*typeinfo
;
2130 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
),
2131 rgszNames
, cNames
, lcid
, rgDispId
);
2133 hr
= get_typeinfo(IFile_tid
, &typeinfo
);
2135 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2136 ITypeInfo_Release(typeinfo
);
2141 static HRESULT WINAPI
file_Invoke(IFile
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2143 struct file
*This
= impl_from_IFile(iface
);
2144 ITypeInfo
*typeinfo
;
2147 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2148 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2150 hr
= get_typeinfo(IFile_tid
, &typeinfo
);
2153 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
2154 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2155 ITypeInfo_Release(typeinfo
);
2160 static HRESULT WINAPI
file_get_Path(IFile
*iface
, BSTR
*pbstrPath
)
2162 struct file
*This
= impl_from_IFile(iface
);
2163 FIXME("(%p)->(%p)\n", This
, pbstrPath
);
2167 static HRESULT WINAPI
file_get_Name(IFile
*iface
, BSTR
*name
)
2169 struct file
*This
= impl_from_IFile(iface
);
2172 TRACE("(%p)->(%p)\n", This
, name
);
2179 ptr
= strrchrW(This
->path
, '\\');
2182 *name
= SysAllocString(ptr
+1);
2183 TRACE("%s\n", debugstr_w(*name
));
2184 if (!*name
) return E_OUTOFMEMORY
;
2192 static HRESULT WINAPI
file_put_Name(IFile
*iface
, BSTR pbstrName
)
2194 struct file
*This
= impl_from_IFile(iface
);
2195 FIXME("(%p)->(%s)\n", This
, debugstr_w(pbstrName
));
2199 static HRESULT WINAPI
file_get_ShortPath(IFile
*iface
, BSTR
*pbstrPath
)
2201 struct file
*This
= impl_from_IFile(iface
);
2202 FIXME("(%p)->(%p)\n", This
, pbstrPath
);
2206 static HRESULT WINAPI
file_get_ShortName(IFile
*iface
, BSTR
*pbstrName
)
2208 struct file
*This
= impl_from_IFile(iface
);
2209 FIXME("(%p)->(%p)\n", This
, pbstrName
);
2213 static HRESULT WINAPI
file_get_Drive(IFile
*iface
, IDrive
**ppdrive
)
2215 struct file
*This
= impl_from_IFile(iface
);
2216 FIXME("(%p)->(%p)\n", This
, ppdrive
);
2220 static HRESULT WINAPI
file_get_ParentFolder(IFile
*iface
, IFolder
**ppfolder
)
2222 struct file
*This
= impl_from_IFile(iface
);
2223 FIXME("(%p)->(%p)\n", This
, ppfolder
);
2227 static HRESULT WINAPI
file_get_Attributes(IFile
*iface
, FileAttribute
*pfa
)
2229 struct file
*This
= impl_from_IFile(iface
);
2232 TRACE("(%p)->(%p)\n", This
, pfa
);
2237 fa
= GetFileAttributesW(This
->path
);
2238 if(fa
== INVALID_FILE_ATTRIBUTES
)
2239 return create_error(GetLastError());
2241 *pfa
= fa
& (FILE_ATTRIBUTE_READONLY
| FILE_ATTRIBUTE_HIDDEN
|
2242 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_ARCHIVE
|
2243 FILE_ATTRIBUTE_REPARSE_POINT
| FILE_ATTRIBUTE_COMPRESSED
);
2247 static HRESULT WINAPI
file_put_Attributes(IFile
*iface
, FileAttribute pfa
)
2249 struct file
*This
= impl_from_IFile(iface
);
2250 FIXME("(%p)->(%x)\n", This
, pfa
);
2254 static HRESULT WINAPI
file_get_DateCreated(IFile
*iface
, DATE
*pdate
)
2256 struct file
*This
= impl_from_IFile(iface
);
2257 FIXME("(%p)->(%p)\n", This
, pdate
);
2261 static HRESULT WINAPI
file_get_DateLastModified(IFile
*iface
, DATE
*pdate
)
2263 struct file
*This
= impl_from_IFile(iface
);
2264 FIXME("(%p)->(%p)\n", This
, pdate
);
2268 static HRESULT WINAPI
file_get_DateLastAccessed(IFile
*iface
, DATE
*pdate
)
2270 struct file
*This
= impl_from_IFile(iface
);
2271 FIXME("(%p)->(%p)\n", This
, pdate
);
2275 static HRESULT WINAPI
file_get_Size(IFile
*iface
, VARIANT
*pvarSize
)
2277 struct file
*This
= impl_from_IFile(iface
);
2278 WIN32_FIND_DATAW fd
;
2281 TRACE("(%p)->(%p)\n", This
, pvarSize
);
2286 f
= FindFirstFileW(This
->path
, &fd
);
2287 if(f
== INVALID_HANDLE_VALUE
)
2288 return create_error(GetLastError());
2291 if(fd
.nFileSizeHigh
|| fd
.nFileSizeLow
>INT_MAX
) {
2292 V_VT(pvarSize
) = VT_R8
;
2293 V_R8(pvarSize
) = ((ULONGLONG
)fd
.nFileSizeHigh
<<32) + fd
.nFileSizeLow
;
2295 V_VT(pvarSize
) = VT_I4
;
2296 V_I4(pvarSize
) = fd
.nFileSizeLow
;
2301 static HRESULT WINAPI
file_get_Type(IFile
*iface
, BSTR
*pbstrType
)
2303 struct file
*This
= impl_from_IFile(iface
);
2304 FIXME("(%p)->(%p)\n", This
, pbstrType
);
2308 static HRESULT WINAPI
file_Delete(IFile
*iface
, VARIANT_BOOL Force
)
2310 struct file
*This
= impl_from_IFile(iface
);
2311 FIXME("(%p)->(%x)\n", This
, Force
);
2315 static HRESULT WINAPI
file_Copy(IFile
*iface
, BSTR Destination
, VARIANT_BOOL OverWriteFiles
)
2317 struct file
*This
= impl_from_IFile(iface
);
2318 FIXME("(%p)->(%s %x)\n", This
, debugstr_w(Destination
), OverWriteFiles
);
2322 static HRESULT WINAPI
file_Move(IFile
*iface
, BSTR Destination
)
2324 struct file
*This
= impl_from_IFile(iface
);
2325 FIXME("(%p)->(%s)\n", This
, debugstr_w(Destination
));
2329 static HRESULT WINAPI
file_OpenAsTextStream(IFile
*iface
, IOMode IOMode
, Tristate Format
, ITextStream
**ppts
)
2331 struct file
*This
= impl_from_IFile(iface
);
2332 FIXME("(%p)->(%x %x %p)\n", This
, IOMode
, Format
, ppts
);
2336 static const IFileVtbl file_vtbl
= {
2337 file_QueryInterface
,
2340 file_GetTypeInfoCount
,
2350 file_get_ParentFolder
,
2351 file_get_Attributes
,
2352 file_put_Attributes
,
2353 file_get_DateCreated
,
2354 file_get_DateLastModified
,
2355 file_get_DateLastAccessed
,
2361 file_OpenAsTextStream
2364 static HRESULT
create_file(BSTR path
, IFile
**file
)
2371 f
= heap_alloc(sizeof(struct file
));
2373 return E_OUTOFMEMORY
;
2375 f
->IFile_iface
.lpVtbl
= &file_vtbl
;
2378 len
= GetFullPathNameW(path
, 0, NULL
, NULL
);
2384 f
->path
= heap_alloc(len
*sizeof(WCHAR
));
2387 return E_OUTOFMEMORY
;
2390 if(!GetFullPathNameW(path
, len
, f
->path
, NULL
)) {
2396 if(path
[len
-1]=='/' || path
[len
-1]=='\\')
2399 attrs
= GetFileAttributesW(f
->path
);
2400 if(attrs
==INVALID_FILE_ATTRIBUTES
||
2401 (attrs
&(FILE_ATTRIBUTE_DIRECTORY
|FILE_ATTRIBUTE_DEVICE
))) {
2404 return create_error(GetLastError());
2407 *file
= &f
->IFile_iface
;
2411 static HRESULT WINAPI
filesys_QueryInterface(IFileSystem3
*iface
, REFIID riid
, void **ppvObject
)
2413 TRACE("%p %s %p\n", iface
, debugstr_guid(riid
), ppvObject
);
2415 if ( IsEqualGUID( riid
, &IID_IFileSystem3
) ||
2416 IsEqualGUID( riid
, &IID_IFileSystem
) ||
2417 IsEqualGUID( riid
, &IID_IDispatch
) ||
2418 IsEqualGUID( riid
, &IID_IUnknown
) )
2422 else if ( IsEqualGUID( riid
, &IID_IDispatchEx
))
2424 TRACE("Interface IDispatchEx not supported - returning NULL\n");
2426 return E_NOINTERFACE
;
2428 else if ( IsEqualGUID( riid
, &IID_IObjectWithSite
))
2430 TRACE("Interface IObjectWithSite not supported - returning NULL\n");
2432 return E_NOINTERFACE
;
2436 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
2437 return E_NOINTERFACE
;
2440 IFileSystem3_AddRef(iface
);
2445 static ULONG WINAPI
filesys_AddRef(IFileSystem3
*iface
)
2447 TRACE("%p\n", iface
);
2452 static ULONG WINAPI
filesys_Release(IFileSystem3
*iface
)
2454 TRACE("%p\n", iface
);
2459 static HRESULT WINAPI
filesys_GetTypeInfoCount(IFileSystem3
*iface
, UINT
*pctinfo
)
2461 TRACE("(%p)->(%p)\n", iface
, pctinfo
);
2467 static HRESULT WINAPI
filesys_GetTypeInfo(IFileSystem3
*iface
, UINT iTInfo
,
2468 LCID lcid
, ITypeInfo
**ppTInfo
)
2470 TRACE("(%p)->(%u %u %p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
2471 return get_typeinfo(IFileSystem3_tid
, ppTInfo
);
2474 static HRESULT WINAPI
filesys_GetIDsOfNames(IFileSystem3
*iface
, REFIID riid
,
2475 LPOLESTR
*rgszNames
, UINT cNames
,
2476 LCID lcid
, DISPID
*rgDispId
)
2478 ITypeInfo
*typeinfo
;
2481 TRACE("(%p)->(%s %p %u %u %p)\n", iface
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
2483 hr
= get_typeinfo(IFileSystem3_tid
, &typeinfo
);
2486 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2487 ITypeInfo_Release(typeinfo
);
2493 static HRESULT WINAPI
filesys_Invoke(IFileSystem3
*iface
, DISPID dispIdMember
,
2494 REFIID riid
, LCID lcid
, WORD wFlags
,
2495 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2496 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2498 ITypeInfo
*typeinfo
;
2501 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", iface
, dispIdMember
, debugstr_guid(riid
),
2502 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2504 hr
= get_typeinfo(IFileSystem3_tid
, &typeinfo
);
2507 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
2508 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2509 ITypeInfo_Release(typeinfo
);
2515 static HRESULT WINAPI
filesys_get_Drives(IFileSystem3
*iface
, IDriveCollection
**ppdrives
)
2517 TRACE("%p %p\n", iface
, ppdrives
);
2518 return create_drivecoll(ppdrives
);
2521 static HRESULT WINAPI
filesys_BuildPath(IFileSystem3
*iface
, BSTR Path
,
2522 BSTR Name
, BSTR
*Result
)
2526 TRACE("%p %s %s %p\n", iface
, debugstr_w(Path
), debugstr_w(Name
), Result
);
2528 if (!Result
) return E_POINTER
;
2532 int path_len
= SysStringLen(Path
), name_len
= SysStringLen(Name
);
2534 /* if both parts have backslashes strip one from Path */
2535 if (Path
[path_len
-1] == '\\' && Name
[0] == '\\')
2539 ret
= SysAllocStringLen(NULL
, path_len
+ name_len
);
2547 else if (Path
[path_len
-1] != '\\' && Name
[0] != '\\')
2549 ret
= SysAllocStringLen(NULL
, path_len
+ name_len
+ 1);
2553 if (Path
[path_len
-1] != ':')
2560 ret
= SysAllocStringLen(NULL
, path_len
+ name_len
);
2568 else if (Path
|| Name
)
2569 ret
= SysAllocString(Path
? Path
: Name
);
2571 ret
= SysAllocStringLen(NULL
, 0);
2573 if (!ret
) return E_OUTOFMEMORY
;
2579 static HRESULT WINAPI
filesys_GetDriveName(IFileSystem3
*iface
, BSTR Path
,
2582 FIXME("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2587 static inline DWORD
get_parent_folder_name(const WCHAR
*path
, DWORD len
)
2594 for(i
=len
-1; i
>=0; i
--)
2595 if(path
[i
]!='/' && path
[i
]!='\\')
2599 if(path
[i
]=='/' || path
[i
]=='\\')
2603 if(path
[i
]!='/' && path
[i
]!='\\')
2609 if(path
[i
]==':' && i
==1)
2614 static HRESULT WINAPI
filesys_GetParentFolderName(IFileSystem3
*iface
, BSTR Path
,
2619 TRACE("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2624 len
= get_parent_folder_name(Path
, SysStringLen(Path
));
2626 *pbstrResult
= NULL
;
2630 *pbstrResult
= SysAllocStringLen(Path
, len
);
2632 return E_OUTOFMEMORY
;
2636 static HRESULT WINAPI
filesys_GetFileName(IFileSystem3
*iface
, BSTR Path
,
2641 TRACE("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2647 *pbstrResult
= NULL
;
2651 for(end
=strlenW(Path
)-1; end
>=0; end
--)
2652 if(Path
[end
]!='/' && Path
[end
]!='\\')
2655 for(i
=end
; i
>=0; i
--)
2656 if(Path
[i
]=='/' || Path
[i
]=='\\')
2660 if(i
>end
|| (i
==0 && end
==1 && Path
[1]==':')) {
2661 *pbstrResult
= NULL
;
2665 *pbstrResult
= SysAllocStringLen(Path
+i
, end
-i
+1);
2667 return E_OUTOFMEMORY
;
2671 static HRESULT WINAPI
filesys_GetBaseName(IFileSystem3
*iface
, BSTR Path
,
2676 TRACE("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2682 *pbstrResult
= NULL
;
2686 for(end
=strlenW(Path
)-1; end
>=0; end
--)
2687 if(Path
[end
]!='/' && Path
[end
]!='\\')
2690 for(i
=end
; i
>=0; i
--) {
2691 if(Path
[i
]=='.' && Path
[end
+1]!='.')
2693 if(Path
[i
]=='/' || Path
[i
]=='\\')
2698 if((i
>end
&& Path
[end
+1]!='.') || (i
==0 && end
==1 && Path
[1]==':')) {
2699 *pbstrResult
= NULL
;
2703 *pbstrResult
= SysAllocStringLen(Path
+i
, end
-i
+1);
2705 return E_OUTOFMEMORY
;
2709 static HRESULT WINAPI
filesys_GetExtensionName(IFileSystem3
*iface
, BSTR Path
,
2712 FIXME("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2717 static HRESULT WINAPI
filesys_GetAbsolutePathName(IFileSystem3
*iface
, BSTR Path
,
2720 static const WCHAR cur_path
[] = {'.',0};
2722 WCHAR buf
[MAX_PATH
], ch
;
2724 DWORD i
, beg
, len
, exp_len
;
2725 WIN32_FIND_DATAW fdata
;
2728 TRACE("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2738 len
= GetFullPathNameW(path
, MAX_PATH
, buf
, NULL
);
2742 buf
[0] = toupperW(buf
[0]);
2743 if(len
>3 && buf
[len
-1] == '\\')
2746 for(beg
=3, i
=3; i
<=len
; i
++) {
2747 if(buf
[i
]!='\\' && buf
[i
])
2752 fh
= FindFirstFileW(buf
, &fdata
);
2753 if(fh
== INVALID_HANDLE_VALUE
)
2756 exp_len
= strlenW(fdata
.cFileName
);
2757 if(exp_len
== i
-beg
)
2758 memcpy(buf
+beg
, fdata
.cFileName
, exp_len
*sizeof(WCHAR
));
2764 *pbstrResult
= SysAllocString(buf
);
2766 return E_OUTOFMEMORY
;
2770 static HRESULT WINAPI
filesys_GetTempName(IFileSystem3
*iface
, BSTR
*pbstrResult
)
2772 static const WCHAR fmt
[] = {'r','a','d','%','0','5','X','.','t','x','t',0};
2776 TRACE("%p %p\n", iface
, pbstrResult
);
2781 *pbstrResult
= SysAllocStringLen(NULL
, 12);
2783 return E_OUTOFMEMORY
;
2785 if(!RtlGenRandom(&random
, sizeof(random
)))
2787 sprintfW(*pbstrResult
, fmt
, random
& 0xfffff);
2791 static HRESULT WINAPI
filesys_DriveExists(IFileSystem3
*iface
, BSTR DriveSpec
,
2792 VARIANT_BOOL
*pfExists
)
2794 FIXME("%p %s %p\n", iface
, debugstr_w(DriveSpec
), pfExists
);
2799 static HRESULT WINAPI
filesys_FileExists(IFileSystem3
*iface
, BSTR path
, VARIANT_BOOL
*ret
)
2802 TRACE("%p %s %p\n", iface
, debugstr_w(path
), ret
);
2804 if (!ret
) return E_POINTER
;
2806 attrs
= GetFileAttributesW(path
);
2807 *ret
= attrs
!= INVALID_FILE_ATTRIBUTES
&& !(attrs
& FILE_ATTRIBUTE_DIRECTORY
) ? VARIANT_TRUE
: VARIANT_FALSE
;
2811 static HRESULT WINAPI
filesys_FolderExists(IFileSystem3
*iface
, BSTR path
, VARIANT_BOOL
*ret
)
2814 TRACE("%p %s %p\n", iface
, debugstr_w(path
), ret
);
2816 if (!ret
) return E_POINTER
;
2818 attrs
= GetFileAttributesW(path
);
2819 *ret
= attrs
!= INVALID_FILE_ATTRIBUTES
&& (attrs
& FILE_ATTRIBUTE_DIRECTORY
) ? VARIANT_TRUE
: VARIANT_FALSE
;
2824 static HRESULT WINAPI
filesys_GetDrive(IFileSystem3
*iface
, BSTR DriveSpec
,
2827 FIXME("%p %s %p\n", iface
, debugstr_w(DriveSpec
), ppdrive
);
2832 static HRESULT WINAPI
filesys_GetFile(IFileSystem3
*iface
, BSTR FilePath
,
2835 TRACE("%p %s %p\n", iface
, debugstr_w(FilePath
), ppfile
);
2840 return E_INVALIDARG
;
2842 return create_file(FilePath
, ppfile
);
2845 static HRESULT WINAPI
filesys_GetFolder(IFileSystem3
*iface
, BSTR FolderPath
,
2850 TRACE("%p %s %p\n", iface
, debugstr_w(FolderPath
), folder
);
2857 return E_INVALIDARG
;
2859 attrs
= GetFileAttributesW(FolderPath
);
2860 if((attrs
== INVALID_FILE_ATTRIBUTES
) || !(attrs
& FILE_ATTRIBUTE_DIRECTORY
))
2861 return CTL_E_PATHNOTFOUND
;
2863 return create_folder(FolderPath
, folder
);
2866 static HRESULT WINAPI
filesys_GetSpecialFolder(IFileSystem3
*iface
,
2867 SpecialFolderConst SpecialFolder
,
2870 FIXME("%p %d %p\n", iface
, SpecialFolder
, ppfolder
);
2875 static inline HRESULT
delete_file(const WCHAR
*file
, DWORD file_len
, VARIANT_BOOL force
)
2877 WCHAR path
[MAX_PATH
];
2878 DWORD len
, name_len
;
2879 WIN32_FIND_DATAW ffd
;
2882 f
= FindFirstFileW(file
, &ffd
);
2883 if(f
== INVALID_HANDLE_VALUE
)
2884 return create_error(GetLastError());
2886 len
= get_parent_folder_name(file
, file_len
);
2887 if(len
+1 >= MAX_PATH
) {
2892 memcpy(path
, file
, len
*sizeof(WCHAR
));
2897 if(ffd
.dwFileAttributes
& (FILE_ATTRIBUTE_DIRECTORY
|FILE_ATTRIBUTE_DEVICE
))
2900 name_len
= strlenW(ffd
.cFileName
);
2901 if(len
+name_len
+1 >= MAX_PATH
) {
2905 memcpy(path
+len
, ffd
.cFileName
, (name_len
+1)*sizeof(WCHAR
));
2907 TRACE("deleting %s\n", debugstr_w(path
));
2909 if(!DeleteFileW(path
)) {
2910 if(!force
|| !SetFileAttributesW(path
, FILE_ATTRIBUTE_NORMAL
)
2911 || !DeleteFileW(path
)) {
2913 return create_error(GetLastError());
2916 } while(FindNextFileW(f
, &ffd
));
2922 static HRESULT WINAPI
filesys_DeleteFile(IFileSystem3
*iface
, BSTR FileSpec
,
2925 TRACE("%p %s %d\n", iface
, debugstr_w(FileSpec
), Force
);
2930 return delete_file(FileSpec
, SysStringLen(FileSpec
), Force
);
2933 static HRESULT
delete_folder(const WCHAR
*folder
, DWORD folder_len
, VARIANT_BOOL force
)
2935 WCHAR path
[MAX_PATH
];
2936 DWORD len
, name_len
;
2937 WIN32_FIND_DATAW ffd
;
2941 f
= FindFirstFileW(folder
, &ffd
);
2942 if(f
== INVALID_HANDLE_VALUE
)
2943 return create_error(GetLastError());
2945 len
= get_parent_folder_name(folder
, folder_len
);
2946 if(len
+1 >= MAX_PATH
) {
2951 memcpy(path
, folder
, len
*sizeof(WCHAR
));
2956 if(!(ffd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
2958 if(ffd
.cFileName
[0]=='.' && (ffd
.cFileName
[1]==0 ||
2959 (ffd
.cFileName
[1]=='.' && ffd
.cFileName
[2]==0)))
2962 name_len
= strlenW(ffd
.cFileName
);
2963 if(len
+name_len
+3 >= MAX_PATH
) {
2967 memcpy(path
+len
, ffd
.cFileName
, name_len
*sizeof(WCHAR
));
2968 path
[len
+name_len
] = '\\';
2969 path
[len
+name_len
+1] = '*';
2970 path
[len
+name_len
+2] = 0;
2972 hr
= delete_file(path
, len
+name_len
+2, force
);
2978 hr
= delete_folder(path
, len
+name_len
+2, force
);
2984 path
[len
+name_len
] = 0;
2985 TRACE("deleting %s\n", debugstr_w(path
));
2987 if(!RemoveDirectoryW(path
)) {
2989 return create_error(GetLastError());
2991 } while(FindNextFileW(f
, &ffd
));
2997 static HRESULT WINAPI
filesys_DeleteFolder(IFileSystem3
*iface
, BSTR FolderSpec
,
3000 TRACE("%p %s %d\n", iface
, debugstr_w(FolderSpec
), Force
);
3005 return delete_folder(FolderSpec
, SysStringLen(FolderSpec
), Force
);
3008 static HRESULT WINAPI
filesys_MoveFile(IFileSystem3
*iface
, BSTR Source
,
3011 FIXME("%p %s %s\n", iface
, debugstr_w(Source
), debugstr_w(Destination
));
3016 static HRESULT WINAPI
filesys_MoveFolder(IFileSystem3
*iface
,BSTR Source
,
3019 FIXME("%p %s %s\n", iface
, debugstr_w(Source
), debugstr_w(Destination
));
3024 static inline HRESULT
copy_file(const WCHAR
*source
, DWORD source_len
,
3025 const WCHAR
*destination
, DWORD destination_len
, VARIANT_BOOL overwrite
)
3028 WCHAR src_path
[MAX_PATH
], dst_path
[MAX_PATH
];
3029 DWORD src_len
, dst_len
, name_len
;
3030 WIN32_FIND_DATAW ffd
;
3034 if(!source
[0] || !destination
[0])
3035 return E_INVALIDARG
;
3037 attrs
= GetFileAttributesW(destination
);
3038 if(attrs
==INVALID_FILE_ATTRIBUTES
|| !(attrs
& FILE_ATTRIBUTE_DIRECTORY
)) {
3039 attrs
= GetFileAttributesW(source
);
3040 if(attrs
== INVALID_FILE_ATTRIBUTES
)
3041 return create_error(GetLastError());
3042 else if(attrs
& FILE_ATTRIBUTE_DIRECTORY
)
3043 return CTL_E_FILENOTFOUND
;
3045 if(!CopyFileW(source
, destination
, !overwrite
))
3046 return create_error(GetLastError());
3050 f
= FindFirstFileW(source
, &ffd
);
3051 if(f
== INVALID_HANDLE_VALUE
)
3052 return CTL_E_FILENOTFOUND
;
3054 src_len
= get_parent_folder_name(source
, source_len
);
3055 if(src_len
+1 >= MAX_PATH
)
3058 memcpy(src_path
, source
, src_len
*sizeof(WCHAR
));
3059 src_path
[src_len
++] = '\\';
3062 dst_len
= destination_len
;
3063 if(dst_len
+1 >= MAX_PATH
) {
3067 memcpy(dst_path
, destination
, dst_len
*sizeof(WCHAR
));
3068 if(dst_path
[dst_len
-1]!= '\\' && dst_path
[dst_len
-1]!='/')
3069 dst_path
[dst_len
++] = '\\';
3071 hr
= CTL_E_FILENOTFOUND
;
3073 if(ffd
.dwFileAttributes
& (FILE_ATTRIBUTE_DIRECTORY
|FILE_ATTRIBUTE_DEVICE
))
3076 name_len
= strlenW(ffd
.cFileName
);
3077 if(src_len
+name_len
+1>=MAX_PATH
|| dst_len
+name_len
+1>=MAX_PATH
) {
3081 memcpy(src_path
+src_len
, ffd
.cFileName
, (name_len
+1)*sizeof(WCHAR
));
3082 memcpy(dst_path
+dst_len
, ffd
.cFileName
, (name_len
+1)*sizeof(WCHAR
));
3084 TRACE("copying %s to %s\n", debugstr_w(src_path
), debugstr_w(dst_path
));
3086 if(!CopyFileW(src_path
, dst_path
, !overwrite
)) {
3088 return create_error(GetLastError());
3092 } while(FindNextFileW(f
, &ffd
));
3098 static HRESULT WINAPI
filesys_CopyFile(IFileSystem3
*iface
, BSTR Source
,
3099 BSTR Destination
, VARIANT_BOOL OverWriteFiles
)
3101 TRACE("%p %s %s %d\n", iface
, debugstr_w(Source
), debugstr_w(Destination
), OverWriteFiles
);
3103 if(!Source
|| !Destination
)
3106 return copy_file(Source
, SysStringLen(Source
), Destination
,
3107 SysStringLen(Destination
), OverWriteFiles
);
3110 static HRESULT
copy_folder(const WCHAR
*source
, DWORD source_len
, const WCHAR
*destination
,
3111 DWORD destination_len
, VARIANT_BOOL overwrite
)
3113 DWORD tmp
, src_len
, dst_len
, name_len
;
3114 WCHAR src
[MAX_PATH
], dst
[MAX_PATH
];
3115 WIN32_FIND_DATAW ffd
;
3118 BOOL copied
= FALSE
;
3120 if(!source
[0] || !destination
[0])
3121 return E_INVALIDARG
;
3123 dst_len
= destination_len
;
3124 if(dst_len
+1 >= MAX_PATH
)
3126 memcpy(dst
, destination
, (dst_len
+1)*sizeof(WCHAR
));
3128 if(dst
[dst_len
-1]!='\\' && dst
[dst_len
-1]!='/' &&
3129 (tmp
= GetFileAttributesW(source
))!=INVALID_FILE_ATTRIBUTES
&&
3130 tmp
&FILE_ATTRIBUTE_DIRECTORY
) {
3131 if(!CreateDirectoryW(dst
, NULL
)) {
3132 if(overwrite
&& GetLastError()==ERROR_ALREADY_EXISTS
) {
3133 tmp
= GetFileAttributesW(dst
);
3134 if(tmp
==INVALID_FILE_ATTRIBUTES
|| !(tmp
&FILE_ATTRIBUTE_DIRECTORY
))
3135 return CTL_E_FILEALREADYEXISTS
;
3137 return create_error(GetLastError());
3142 src_len
= source_len
;
3143 if(src_len
+2 >= MAX_PATH
)
3145 memcpy(src
, source
, src_len
*sizeof(WCHAR
));
3146 src
[src_len
++] = '\\';
3150 hr
= copy_file(src
, src_len
+1, dst
, dst_len
, overwrite
);
3151 if(FAILED(hr
) && hr
!=CTL_E_FILENOTFOUND
)
3152 return create_error(GetLastError());
3154 f
= FindFirstFileW(src
, &ffd
);
3156 src_len
= get_parent_folder_name(source
, source_len
);
3157 if(src_len
+2 >= MAX_PATH
)
3159 memcpy(src
, source
, src_len
*sizeof(WCHAR
));
3161 src
[src_len
++] = '\\';
3163 f
= FindFirstFileW(source
, &ffd
);
3165 if(f
== INVALID_HANDLE_VALUE
)
3166 return CTL_E_PATHNOTFOUND
;
3168 dst
[dst_len
++] = '\\';
3172 if(!(ffd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
3174 if(ffd
.cFileName
[0]=='.' && (ffd
.cFileName
[1]==0 ||
3175 (ffd
.cFileName
[1]=='.' && ffd
.cFileName
[2]==0)))
3178 name_len
= strlenW(ffd
.cFileName
);
3179 if(dst_len
+name_len
>=MAX_PATH
|| src_len
+name_len
+2>=MAX_PATH
) {
3183 memcpy(dst
+dst_len
, ffd
.cFileName
, name_len
*sizeof(WCHAR
));
3184 dst
[dst_len
+name_len
] = 0;
3185 memcpy(src
+src_len
, ffd
.cFileName
, name_len
*sizeof(WCHAR
));
3186 src
[src_len
+name_len
] = '\\';
3187 src
[src_len
+name_len
+1] = '*';
3188 src
[src_len
+name_len
+2] = 0;
3190 TRACE("copying %s to %s\n", debugstr_w(src
), debugstr_w(dst
));
3192 if(!CreateDirectoryW(dst
, NULL
)) {
3193 if(overwrite
&& GetLastError()==ERROR_ALREADY_EXISTS
) {
3194 tmp
= GetFileAttributesW(dst
);
3195 if(tmp
==INVALID_FILE_ATTRIBUTES
|| !(tmp
&FILE_ATTRIBUTE_DIRECTORY
)) {
3197 return CTL_E_FILEALREADYEXISTS
;
3201 return create_error(GetLastError());
3203 return create_error(GetLastError());
3207 hr
= copy_file(src
, src_len
+name_len
+2, dst
, dst_len
+name_len
, overwrite
);
3208 if(FAILED(hr
) && hr
!=CTL_E_FILENOTFOUND
) {
3213 hr
= copy_folder(src
, src_len
+name_len
+2, dst
, dst_len
+name_len
, overwrite
);
3214 if(FAILED(hr
) && hr
!=CTL_E_PATHNOTFOUND
) {
3218 } while(FindNextFileW(f
, &ffd
));
3221 return copied
? S_OK
: CTL_E_PATHNOTFOUND
;
3224 static HRESULT WINAPI
filesys_CopyFolder(IFileSystem3
*iface
, BSTR Source
,
3225 BSTR Destination
, VARIANT_BOOL OverWriteFiles
)
3227 TRACE("%p %s %s %d\n", iface
, debugstr_w(Source
), debugstr_w(Destination
), OverWriteFiles
);
3229 if(!Source
|| !Destination
)
3232 return copy_folder(Source
, SysStringLen(Source
), Destination
,
3233 SysStringLen(Destination
), OverWriteFiles
);
3236 static HRESULT WINAPI
filesys_CreateFolder(IFileSystem3
*iface
, BSTR path
,
3241 TRACE("(%p)->(%s %p)\n", iface
, debugstr_w(path
), folder
);
3243 ret
= CreateDirectoryW(path
, NULL
);
3247 if (GetLastError() == ERROR_ALREADY_EXISTS
) return CTL_E_FILEALREADYEXISTS
;
3248 return HRESULT_FROM_WIN32(GetLastError());
3251 return create_folder(path
, folder
);
3254 static HRESULT WINAPI
filesys_CreateTextFile(IFileSystem3
*iface
, BSTR FileName
,
3255 VARIANT_BOOL Overwrite
, VARIANT_BOOL Unicode
,
3258 FIXME("%p %s %d %d %p\n", iface
, debugstr_w(FileName
), Overwrite
, Unicode
, ppts
);
3263 static HRESULT WINAPI
filesys_OpenTextFile(IFileSystem3
*iface
, BSTR filename
,
3264 IOMode mode
, VARIANT_BOOL create
,
3265 Tristate format
, ITextStream
**stream
)
3267 FIXME("(%p)->(%s %d %d %d %p)\n", iface
, debugstr_w(filename
), mode
, create
, format
, stream
);
3268 return create_textstream(mode
, stream
);
3271 static HRESULT WINAPI
filesys_GetStandardStream(IFileSystem3
*iface
,
3272 StandardStreamTypes StandardStreamType
,
3273 VARIANT_BOOL Unicode
,
3276 FIXME("%p %d %d %p\n", iface
, StandardStreamType
, Unicode
, ppts
);
3281 static void get_versionstring(VS_FIXEDFILEINFO
*info
, WCHAR
*ver
)
3283 static const WCHAR fmtW
[] = {'%','d','.','%','d','.','%','d','.','%','d',0};
3287 version
= (((DWORDLONG
)info
->dwFileVersionMS
) << 32) + info
->dwFileVersionLS
;
3288 a
= (WORD
)( version
>> 48);
3289 b
= (WORD
)((version
>> 32) & 0xffff);
3290 c
= (WORD
)((version
>> 16) & 0xffff);
3291 d
= (WORD
)( version
& 0xffff);
3293 sprintfW(ver
, fmtW
, a
, b
, c
, d
);
3296 static HRESULT WINAPI
filesys_GetFileVersion(IFileSystem3
*iface
, BSTR name
, BSTR
*version
)
3298 static const WCHAR rootW
[] = {'\\',0};
3299 VS_FIXEDFILEINFO
*info
;
3305 TRACE("%p %s %p\n", iface
, debugstr_w(name
), version
);
3307 len
= GetFileVersionInfoSizeW(name
, NULL
);
3309 return HRESULT_FROM_WIN32(GetLastError());
3311 ptr
= heap_alloc(len
);
3312 if (!GetFileVersionInfoW(name
, 0, len
, ptr
))
3315 return HRESULT_FROM_WIN32(GetLastError());
3318 ret
= VerQueryValueW(ptr
, rootW
, (void**)&info
, &len
);
3321 return HRESULT_FROM_WIN32(GetLastError());
3323 get_versionstring(info
, ver
);
3324 *version
= SysAllocString(ver
);
3325 TRACE("version=%s\n", debugstr_w(ver
));
3330 static const struct IFileSystem3Vtbl filesys_vtbl
=
3332 filesys_QueryInterface
,
3335 filesys_GetTypeInfoCount
,
3336 filesys_GetTypeInfo
,
3337 filesys_GetIDsOfNames
,
3341 filesys_GetDriveName
,
3342 filesys_GetParentFolderName
,
3343 filesys_GetFileName
,
3344 filesys_GetBaseName
,
3345 filesys_GetExtensionName
,
3346 filesys_GetAbsolutePathName
,
3347 filesys_GetTempName
,
3348 filesys_DriveExists
,
3350 filesys_FolderExists
,
3354 filesys_GetSpecialFolder
,
3356 filesys_DeleteFolder
,
3361 filesys_CreateFolder
,
3362 filesys_CreateTextFile
,
3363 filesys_OpenTextFile
,
3364 filesys_GetStandardStream
,
3365 filesys_GetFileVersion
3368 static IFileSystem3 filesystem
= { &filesys_vtbl
};
3370 HRESULT WINAPI
FileSystem_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID riid
, void **ppv
)
3372 TRACE("(%p %s %p)\n", outer
, debugstr_guid(riid
), ppv
);
3374 return IFileSystem3_QueryInterface(&filesystem
, riid
, ppv
);