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 #include "scrrun_private.h"
24 #include <wine/unicode.h>
26 static const WCHAR bsW
[] = {'\\',0};
27 static const WCHAR utf16bom
= 0xfeff;
29 struct foldercollection
{
30 IFolderCollection IFolderCollection_iface
;
35 struct filecollection
{
36 IFileCollection IFileCollection_iface
;
41 struct drivecollection
{
42 IDriveCollection IDriveCollection_iface
;
53 struct foldercollection
*coll
;
58 struct filecollection
*coll
;
63 struct drivecollection
*coll
;
70 IEnumVARIANT IEnumVARIANT_iface
;
83 IFolder IFolder_iface
;
96 ITextStream ITextStream_iface
;
111 static inline struct drive
*impl_from_IDrive(IDrive
*iface
)
113 return CONTAINING_RECORD(iface
, struct drive
, IDrive_iface
);
116 static inline struct folder
*impl_from_IFolder(IFolder
*iface
)
118 return CONTAINING_RECORD(iface
, struct folder
, IFolder_iface
);
121 static inline struct file
*impl_from_IFile(IFile
*iface
)
123 return CONTAINING_RECORD(iface
, struct file
, IFile_iface
);
126 static inline struct textstream
*impl_from_ITextStream(ITextStream
*iface
)
128 return CONTAINING_RECORD(iface
, struct textstream
, ITextStream_iface
);
131 static inline struct foldercollection
*impl_from_IFolderCollection(IFolderCollection
*iface
)
133 return CONTAINING_RECORD(iface
, struct foldercollection
, IFolderCollection_iface
);
136 static inline struct filecollection
*impl_from_IFileCollection(IFileCollection
*iface
)
138 return CONTAINING_RECORD(iface
, struct filecollection
, IFileCollection_iface
);
141 static inline struct drivecollection
*impl_from_IDriveCollection(IDriveCollection
*iface
)
143 return CONTAINING_RECORD(iface
, struct drivecollection
, IDriveCollection_iface
);
146 static inline struct enumvariant
*impl_from_IEnumVARIANT(IEnumVARIANT
*iface
)
148 return CONTAINING_RECORD(iface
, struct enumvariant
, IEnumVARIANT_iface
);
151 static inline HRESULT
create_error(DWORD err
)
154 case ERROR_FILE_NOT_FOUND
: return CTL_E_FILENOTFOUND
;
155 case ERROR_PATH_NOT_FOUND
: return CTL_E_PATHNOTFOUND
;
156 case ERROR_ACCESS_DENIED
: return CTL_E_PERMISSIONDENIED
;
157 case ERROR_FILE_EXISTS
: return CTL_E_FILEALREADYEXISTS
;
158 case ERROR_ALREADY_EXISTS
: return CTL_E_FILEALREADYEXISTS
;
160 FIXME("Unsupported error code: %d\n", err
);
165 static HRESULT
create_folder(const WCHAR
*, IFolder
**);
166 static HRESULT
create_file(BSTR
, IFile
**);
167 static HRESULT
create_foldercoll_enum(struct foldercollection
*, IUnknown
**);
168 static HRESULT
create_filecoll_enum(struct filecollection
*, IUnknown
**);
170 static inline BOOL
is_dir_data(const WIN32_FIND_DATAW
*data
)
172 static const WCHAR dotdotW
[] = {'.','.',0};
173 static const WCHAR dotW
[] = {'.',0};
175 return (data
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) &&
176 strcmpW(data
->cFileName
, dotdotW
) &&
177 strcmpW(data
->cFileName
, dotW
);
180 static inline BOOL
is_file_data(const WIN32_FIND_DATAW
*data
)
182 return !(data
->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
);
185 static BSTR
get_full_path(BSTR path
, const WIN32_FIND_DATAW
*data
)
187 int len
= SysStringLen(path
);
188 WCHAR buffW
[MAX_PATH
];
190 strcpyW(buffW
, path
);
191 if (path
[len
-1] != '\\')
193 strcatW(buffW
, data
->cFileName
);
195 return SysAllocString(buffW
);
198 static BOOL
textstream_check_iomode(struct textstream
*This
, enum iotype type
)
201 return This
->mode
== ForWriting
|| This
->mode
== ForAppending
;
203 return This
->mode
== ForReading
;
206 static HRESULT WINAPI
textstream_QueryInterface(ITextStream
*iface
, REFIID riid
, void **obj
)
208 struct textstream
*This
= impl_from_ITextStream(iface
);
210 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
212 if (IsEqualIID(riid
, &IID_ITextStream
) ||
213 IsEqualIID(riid
, &IID_IDispatch
) ||
214 IsEqualIID(riid
, &IID_IUnknown
))
217 ITextStream_AddRef(iface
);
222 return E_NOINTERFACE
;
225 static ULONG WINAPI
textstream_AddRef(ITextStream
*iface
)
227 struct textstream
*This
= impl_from_ITextStream(iface
);
228 ULONG ref
= InterlockedIncrement(&This
->ref
);
229 TRACE("(%p)->(%d)\n", This
, ref
);
233 static ULONG WINAPI
textstream_Release(ITextStream
*iface
)
235 struct textstream
*This
= impl_from_ITextStream(iface
);
236 ULONG ref
= InterlockedDecrement(&This
->ref
);
237 TRACE("(%p)->(%d)\n", This
, ref
);
241 CloseHandle(This
->file
);
248 static HRESULT WINAPI
textstream_GetTypeInfoCount(ITextStream
*iface
, UINT
*pctinfo
)
250 struct textstream
*This
= impl_from_ITextStream(iface
);
251 TRACE("(%p)->(%p)\n", This
, pctinfo
);
256 static HRESULT WINAPI
textstream_GetTypeInfo(ITextStream
*iface
, UINT iTInfo
,
257 LCID lcid
, ITypeInfo
**ppTInfo
)
259 struct textstream
*This
= impl_from_ITextStream(iface
);
260 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
261 return get_typeinfo(ITextStream_tid
, ppTInfo
);
264 static HRESULT WINAPI
textstream_GetIDsOfNames(ITextStream
*iface
, REFIID riid
,
265 LPOLESTR
*rgszNames
, UINT cNames
,
266 LCID lcid
, DISPID
*rgDispId
)
268 struct textstream
*This
= impl_from_ITextStream(iface
);
272 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
274 hr
= get_typeinfo(ITextStream_tid
, &typeinfo
);
277 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
278 ITypeInfo_Release(typeinfo
);
284 static HRESULT WINAPI
textstream_Invoke(ITextStream
*iface
, DISPID dispIdMember
,
285 REFIID riid
, LCID lcid
, WORD wFlags
,
286 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
287 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
289 struct textstream
*This
= impl_from_ITextStream(iface
);
293 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
294 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
296 hr
= get_typeinfo(ITextStream_tid
, &typeinfo
);
299 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
300 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
301 ITypeInfo_Release(typeinfo
);
307 static HRESULT WINAPI
textstream_get_Line(ITextStream
*iface
, LONG
*line
)
309 struct textstream
*This
= impl_from_ITextStream(iface
);
310 FIXME("(%p)->(%p): stub\n", This
, line
);
314 static HRESULT WINAPI
textstream_get_Column(ITextStream
*iface
, LONG
*column
)
316 struct textstream
*This
= impl_from_ITextStream(iface
);
317 FIXME("(%p)->(%p): stub\n", This
, column
);
321 static HRESULT WINAPI
textstream_get_AtEndOfStream(ITextStream
*iface
, VARIANT_BOOL
*eos
)
323 struct textstream
*This
= impl_from_ITextStream(iface
);
324 LARGE_INTEGER pos
, dist
;
326 TRACE("(%p)->(%p)\n", This
, eos
);
331 if (textstream_check_iomode(This
, IORead
)) {
333 return CTL_E_BADFILEMODE
;
337 if (!SetFilePointerEx(This
->file
, dist
, &pos
, FILE_CURRENT
))
340 *eos
= This
->size
.QuadPart
== pos
.QuadPart
? VARIANT_TRUE
: VARIANT_FALSE
;
344 static HRESULT WINAPI
textstream_get_AtEndOfLine(ITextStream
*iface
, VARIANT_BOOL
*eol
)
346 struct textstream
*This
= impl_from_ITextStream(iface
);
347 FIXME("(%p)->(%p): stub\n", This
, eol
);
352 Reads 'toread' bytes from a file, converts if needed
353 BOM is skipped if 'bof' is set.
355 static HRESULT
textstream_read(struct textstream
*stream
, LONG toread
, BOOL bof
, BSTR
*text
)
363 *text
= SysAllocStringLen(NULL
, 0);
364 return *text
? S_FALSE
: E_OUTOFMEMORY
;
367 if (toread
< sizeof(WCHAR
))
368 return CTL_E_ENDOFFILE
;
370 buff
= heap_alloc(toread
);
372 return E_OUTOFMEMORY
;
374 ret
= ReadFile(stream
->file
, buff
, toread
, &read
, NULL
);
375 if (!ret
|| toread
!= read
) {
376 WARN("failed to read from file %d, %d, error %d\n", read
, toread
, GetLastError());
381 if (stream
->unicode
) {
385 if (bof
&& *(WCHAR
*)buff
== utf16bom
) {
386 read
-= sizeof(WCHAR
);
390 *text
= SysAllocStringLen(read
? (WCHAR
*)&buff
[i
] : NULL
, read
/sizeof(WCHAR
));
391 if (!*text
) hr
= E_OUTOFMEMORY
;
394 INT len
= MultiByteToWideChar(CP_ACP
, 0, buff
, read
, NULL
, 0);
395 *text
= SysAllocStringLen(NULL
, len
);
397 MultiByteToWideChar(CP_ACP
, 0, buff
, read
, *text
, len
);
406 static HRESULT WINAPI
textstream_Read(ITextStream
*iface
, LONG len
, BSTR
*text
)
408 struct textstream
*This
= impl_from_ITextStream(iface
);
409 LARGE_INTEGER start
, end
, dist
;
413 TRACE("(%p)->(%d %p)\n", This
, len
, text
);
420 return len
== 0 ? S_OK
: E_INVALIDARG
;
422 if (textstream_check_iomode(This
, IORead
))
423 return CTL_E_BADFILEMODE
;
425 if (!This
->first_read
) {
429 hr
= ITextStream_get_AtEndOfStream(iface
, &eos
);
433 if (eos
== VARIANT_TRUE
)
434 return CTL_E_ENDOFFILE
;
437 /* read everything from current position */
439 SetFilePointerEx(This
->file
, dist
, &start
, FILE_CURRENT
);
440 SetFilePointerEx(This
->file
, dist
, &end
, FILE_END
);
441 toread
= end
.QuadPart
- start
.QuadPart
;
443 dist
.QuadPart
= start
.QuadPart
;
444 SetFilePointerEx(This
->file
, dist
, NULL
, FILE_BEGIN
);
446 This
->first_read
= FALSE
;
447 if (This
->unicode
) len
*= sizeof(WCHAR
);
449 hr
= textstream_read(This
, min(toread
, len
), start
.QuadPart
== 0, text
);
453 return toread
<= len
? S_FALSE
: S_OK
;
456 static HRESULT WINAPI
textstream_ReadLine(ITextStream
*iface
, BSTR
*text
)
458 struct textstream
*This
= impl_from_ITextStream(iface
);
462 FIXME("(%p)->(%p): stub\n", This
, text
);
468 if (textstream_check_iomode(This
, IORead
))
469 return CTL_E_BADFILEMODE
;
472 hr
= ITextStream_get_AtEndOfStream(iface
, &eos
);
476 if (eos
== VARIANT_TRUE
)
477 return CTL_E_ENDOFFILE
;
482 static HRESULT WINAPI
textstream_ReadAll(ITextStream
*iface
, BSTR
*text
)
484 struct textstream
*This
= impl_from_ITextStream(iface
);
485 LARGE_INTEGER start
, end
, dist
;
489 TRACE("(%p)->(%p)\n", This
, text
);
495 if (textstream_check_iomode(This
, IORead
))
496 return CTL_E_BADFILEMODE
;
498 if (!This
->first_read
) {
502 hr
= ITextStream_get_AtEndOfStream(iface
, &eos
);
506 if (eos
== VARIANT_TRUE
)
507 return CTL_E_ENDOFFILE
;
510 /* read everything from current position */
512 SetFilePointerEx(This
->file
, dist
, &start
, FILE_CURRENT
);
513 SetFilePointerEx(This
->file
, dist
, &end
, FILE_END
);
514 toread
= end
.QuadPart
- start
.QuadPart
;
516 dist
.QuadPart
= start
.QuadPart
;
517 SetFilePointerEx(This
->file
, dist
, NULL
, FILE_BEGIN
);
519 This
->first_read
= FALSE
;
521 hr
= textstream_read(This
, toread
, start
.QuadPart
== 0, text
);
522 return FAILED(hr
) ? hr
: S_FALSE
;
525 static HRESULT
textstream_writestr(struct textstream
*stream
, BSTR text
)
530 if (stream
->unicode
) {
531 ret
= WriteFile(stream
->file
, text
, SysStringByteLen(text
), &written
, NULL
);
532 return (ret
&& written
== SysStringByteLen(text
)) ? S_OK
: create_error(GetLastError());
534 DWORD len
= WideCharToMultiByte(CP_ACP
, 0, text
, SysStringLen(text
), NULL
, 0, NULL
, NULL
);
538 buffA
= heap_alloc(len
);
540 return E_OUTOFMEMORY
;
542 WideCharToMultiByte(CP_ACP
, 0, text
, SysStringLen(text
), buffA
, len
, NULL
, NULL
);
543 ret
= WriteFile(stream
->file
, buffA
, len
, &written
, NULL
);
544 hr
= (ret
&& written
== len
) ? S_OK
: create_error(GetLastError());
550 static HRESULT WINAPI
textstream_Write(ITextStream
*iface
, BSTR text
)
552 struct textstream
*This
= impl_from_ITextStream(iface
);
554 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
556 if (textstream_check_iomode(This
, IOWrite
))
557 return CTL_E_BADFILEMODE
;
559 return textstream_writestr(This
, text
);
562 static HRESULT
textstream_writecrlf(struct textstream
*stream
)
564 static const WCHAR crlfW
[] = {'\r','\n'};
565 static const char crlfA
[] = {'\r','\n'};
566 DWORD written
= 0, len
;
570 if (stream
->unicode
) {
579 ret
= WriteFile(stream
->file
, ptr
, len
, &written
, NULL
);
580 return (ret
&& written
== len
) ? S_OK
: create_error(GetLastError());
583 static HRESULT WINAPI
textstream_WriteLine(ITextStream
*iface
, BSTR text
)
585 struct textstream
*This
= impl_from_ITextStream(iface
);
588 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
590 if (textstream_check_iomode(This
, IOWrite
))
591 return CTL_E_BADFILEMODE
;
593 hr
= textstream_writestr(This
, text
);
595 hr
= textstream_writecrlf(This
);
599 static HRESULT WINAPI
textstream_WriteBlankLines(ITextStream
*iface
, LONG lines
)
601 struct textstream
*This
= impl_from_ITextStream(iface
);
602 FIXME("(%p)->(%d): stub\n", This
, lines
);
606 static HRESULT WINAPI
textstream_Skip(ITextStream
*iface
, LONG count
)
608 struct textstream
*This
= impl_from_ITextStream(iface
);
609 FIXME("(%p)->(%d): stub\n", This
, count
);
613 static HRESULT WINAPI
textstream_SkipLine(ITextStream
*iface
)
615 struct textstream
*This
= impl_from_ITextStream(iface
);
616 FIXME("(%p): stub\n", This
);
620 static HRESULT WINAPI
textstream_Close(ITextStream
*iface
)
622 struct textstream
*This
= impl_from_ITextStream(iface
);
623 FIXME("(%p): stub\n", This
);
627 static const ITextStreamVtbl textstreamvtbl
= {
628 textstream_QueryInterface
,
631 textstream_GetTypeInfoCount
,
632 textstream_GetTypeInfo
,
633 textstream_GetIDsOfNames
,
636 textstream_get_Column
,
637 textstream_get_AtEndOfStream
,
638 textstream_get_AtEndOfLine
,
643 textstream_WriteLine
,
644 textstream_WriteBlankLines
,
650 static HRESULT
create_textstream(const WCHAR
*filename
, DWORD disposition
, IOMode mode
, BOOL unicode
, ITextStream
**ret
)
652 struct textstream
*stream
;
655 /* map access mode */
659 access
= GENERIC_READ
;
662 access
= GENERIC_WRITE
;
665 access
= FILE_APPEND_DATA
;
671 stream
= heap_alloc(sizeof(struct textstream
));
672 if (!stream
) return E_OUTOFMEMORY
;
674 stream
->ITextStream_iface
.lpVtbl
= &textstreamvtbl
;
677 stream
->unicode
= unicode
;
678 stream
->first_read
= TRUE
;
680 stream
->file
= CreateFileW(filename
, access
, 0, NULL
, disposition
, FILE_ATTRIBUTE_NORMAL
, NULL
);
681 if (stream
->file
== INVALID_HANDLE_VALUE
)
683 HRESULT hr
= create_error(GetLastError());
688 if (mode
== ForReading
)
689 GetFileSizeEx(stream
->file
, &stream
->size
);
691 stream
->size
.QuadPart
= 0;
693 /* Write Unicode BOM */
694 if (unicode
&& mode
== ForWriting
&& (disposition
== CREATE_ALWAYS
|| disposition
== CREATE_NEW
)) {
696 BOOL ret
= WriteFile(stream
->file
, &utf16bom
, sizeof(utf16bom
), &written
, NULL
);
697 if (!ret
|| written
!= sizeof(utf16bom
)) {
698 ITextStream_Release(&stream
->ITextStream_iface
);
699 return create_error(GetLastError());
703 *ret
= &stream
->ITextStream_iface
;
707 static HRESULT WINAPI
drive_QueryInterface(IDrive
*iface
, REFIID riid
, void **obj
)
709 struct drive
*This
= impl_from_IDrive(iface
);
711 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
715 if (IsEqualIID( riid
, &IID_IDrive
) ||
716 IsEqualIID( riid
, &IID_IDispatch
) ||
717 IsEqualIID( riid
, &IID_IUnknown
))
720 IDrive_AddRef(iface
);
723 return E_NOINTERFACE
;
728 static ULONG WINAPI
drive_AddRef(IDrive
*iface
)
730 struct drive
*This
= impl_from_IDrive(iface
);
731 ULONG ref
= InterlockedIncrement(&This
->ref
);
732 TRACE("(%p)->(%d)\n", This
, ref
);
736 static ULONG WINAPI
drive_Release(IDrive
*iface
)
738 struct drive
*This
= impl_from_IDrive(iface
);
739 ULONG ref
= InterlockedDecrement(&This
->ref
);
740 TRACE("(%p)->(%d)\n", This
, ref
);
744 SysFreeString(This
->root
);
751 static HRESULT WINAPI
drive_GetTypeInfoCount(IDrive
*iface
, UINT
*pctinfo
)
753 struct drive
*This
= impl_from_IDrive(iface
);
754 TRACE("(%p)->(%p)\n", This
, pctinfo
);
759 static HRESULT WINAPI
drive_GetTypeInfo(IDrive
*iface
, UINT iTInfo
,
760 LCID lcid
, ITypeInfo
**ppTInfo
)
762 struct drive
*This
= impl_from_IDrive(iface
);
763 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
764 return get_typeinfo(IDrive_tid
, ppTInfo
);
767 static HRESULT WINAPI
drive_GetIDsOfNames(IDrive
*iface
, REFIID riid
,
768 LPOLESTR
*rgszNames
, UINT cNames
,
769 LCID lcid
, DISPID
*rgDispId
)
771 struct drive
*This
= impl_from_IDrive(iface
);
775 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
777 hr
= get_typeinfo(IDrive_tid
, &typeinfo
);
780 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
781 ITypeInfo_Release(typeinfo
);
787 static HRESULT WINAPI
drive_Invoke(IDrive
*iface
, DISPID dispIdMember
,
788 REFIID riid
, LCID lcid
, WORD wFlags
,
789 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
790 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
792 struct drive
*This
= impl_from_IDrive(iface
);
796 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
797 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
799 hr
= get_typeinfo(IDrive_tid
, &typeinfo
);
802 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
803 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
804 ITypeInfo_Release(typeinfo
);
810 static HRESULT WINAPI
drive_get_Path(IDrive
*iface
, BSTR
*path
)
812 struct drive
*This
= impl_from_IDrive(iface
);
813 FIXME("(%p)->(%p): stub\n", This
, path
);
817 static HRESULT WINAPI
drive_get_DriveLetter(IDrive
*iface
, BSTR
*letter
)
819 struct drive
*This
= impl_from_IDrive(iface
);
821 TRACE("(%p)->(%p)\n", This
, letter
);
826 *letter
= SysAllocStringLen(This
->root
, 1);
828 return E_OUTOFMEMORY
;
833 static HRESULT WINAPI
drive_get_ShareName(IDrive
*iface
, BSTR
*share_name
)
835 struct drive
*This
= impl_from_IDrive(iface
);
836 FIXME("(%p)->(%p): stub\n", This
, share_name
);
840 static HRESULT WINAPI
drive_get_DriveType(IDrive
*iface
, DriveTypeConst
*type
)
842 struct drive
*This
= impl_from_IDrive(iface
);
844 TRACE("(%p)->(%p)\n", This
, type
);
846 switch (GetDriveTypeW(This
->root
))
848 case DRIVE_REMOVABLE
:
871 static HRESULT WINAPI
drive_get_RootFolder(IDrive
*iface
, IFolder
**folder
)
873 struct drive
*This
= impl_from_IDrive(iface
);
874 FIXME("(%p)->(%p): stub\n", This
, folder
);
878 static HRESULT WINAPI
drive_get_AvailableSpace(IDrive
*iface
, VARIANT
*v
)
880 struct drive
*This
= impl_from_IDrive(iface
);
881 ULARGE_INTEGER avail
;
883 TRACE("(%p)->(%p)\n", This
, v
);
888 if (!GetDiskFreeSpaceExW(This
->root
, &avail
, NULL
, NULL
))
892 return VarR8FromUI8(avail
.QuadPart
, &V_R8(v
));
895 static HRESULT WINAPI
drive_get_FreeSpace(IDrive
*iface
, VARIANT
*v
)
897 struct drive
*This
= impl_from_IDrive(iface
);
898 ULARGE_INTEGER freespace
;
900 TRACE("(%p)->(%p)\n", This
, v
);
905 if (!GetDiskFreeSpaceExW(This
->root
, &freespace
, NULL
, NULL
))
909 return VarR8FromUI8(freespace
.QuadPart
, &V_R8(v
));
912 static HRESULT WINAPI
drive_get_TotalSize(IDrive
*iface
, VARIANT
*v
)
914 struct drive
*This
= impl_from_IDrive(iface
);
915 ULARGE_INTEGER total
;
917 TRACE("(%p)->(%p)\n", This
, v
);
922 if (!GetDiskFreeSpaceExW(This
->root
, NULL
, &total
, NULL
))
926 return VarR8FromUI8(total
.QuadPart
, &V_R8(v
));
929 static HRESULT WINAPI
drive_get_VolumeName(IDrive
*iface
, BSTR
*name
)
931 struct drive
*This
= impl_from_IDrive(iface
);
932 FIXME("(%p)->(%p): stub\n", This
, name
);
936 static HRESULT WINAPI
drive_put_VolumeName(IDrive
*iface
, BSTR name
)
938 struct drive
*This
= impl_from_IDrive(iface
);
939 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(name
));
943 static HRESULT WINAPI
drive_get_FileSystem(IDrive
*iface
, BSTR
*fs
)
945 struct drive
*This
= impl_from_IDrive(iface
);
946 FIXME("(%p)->(%p): stub\n", This
, fs
);
950 static HRESULT WINAPI
drive_get_SerialNumber(IDrive
*iface
, LONG
*serial
)
952 struct drive
*This
= impl_from_IDrive(iface
);
953 FIXME("(%p)->(%p): stub\n", This
, serial
);
957 static HRESULT WINAPI
drive_get_IsReady(IDrive
*iface
, VARIANT_BOOL
*ready
)
959 struct drive
*This
= impl_from_IDrive(iface
);
960 ULARGE_INTEGER freespace
;
963 TRACE("(%p)->(%p)\n", This
, ready
);
968 ret
= GetDiskFreeSpaceExW(This
->root
, &freespace
, NULL
, NULL
);
969 *ready
= ret
? VARIANT_TRUE
: VARIANT_FALSE
;
973 static const IDriveVtbl drivevtbl
= {
974 drive_QueryInterface
,
977 drive_GetTypeInfoCount
,
982 drive_get_DriveLetter
,
985 drive_get_RootFolder
,
986 drive_get_AvailableSpace
,
989 drive_get_VolumeName
,
990 drive_put_VolumeName
,
991 drive_get_FileSystem
,
992 drive_get_SerialNumber
,
996 static HRESULT
create_drive(WCHAR letter
, IDrive
**drive
)
1002 This
= heap_alloc(sizeof(*This
));
1003 if (!This
) return E_OUTOFMEMORY
;
1005 This
->IDrive_iface
.lpVtbl
= &drivevtbl
;
1007 This
->root
= SysAllocStringLen(NULL
, 3);
1011 return E_OUTOFMEMORY
;
1013 This
->root
[0] = letter
;
1014 This
->root
[1] = ':';
1015 This
->root
[2] = '\\';
1018 *drive
= &This
->IDrive_iface
;
1022 static HRESULT WINAPI
enumvariant_QueryInterface(IEnumVARIANT
*iface
, REFIID riid
, void **obj
)
1024 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1026 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1030 if (IsEqualIID( riid
, &IID_IEnumVARIANT
) ||
1031 IsEqualIID( riid
, &IID_IUnknown
))
1034 IEnumVARIANT_AddRef(iface
);
1037 return E_NOINTERFACE
;
1042 static ULONG WINAPI
enumvariant_AddRef(IEnumVARIANT
*iface
)
1044 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1045 ULONG ref
= InterlockedIncrement(&This
->ref
);
1046 TRACE("(%p)->(%d)\n", This
, ref
);
1050 static ULONG WINAPI
foldercoll_enumvariant_Release(IEnumVARIANT
*iface
)
1052 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1053 ULONG ref
= InterlockedDecrement(&This
->ref
);
1055 TRACE("(%p)->(%d)\n", This
, ref
);
1059 IFolderCollection_Release(&This
->data
.u
.foldercoll
.coll
->IFolderCollection_iface
);
1060 FindClose(This
->data
.u
.foldercoll
.find
);
1067 static HANDLE
start_enumeration(const WCHAR
*path
, WIN32_FIND_DATAW
*data
, BOOL file
)
1069 static const WCHAR allW
[] = {'*',0};
1070 WCHAR pathW
[MAX_PATH
];
1074 strcpyW(pathW
, path
);
1075 len
= strlenW(pathW
);
1076 if (pathW
[len
-1] != '\\')
1077 strcatW(pathW
, bsW
);
1078 strcatW(pathW
, allW
);
1079 handle
= FindFirstFileW(pathW
, data
);
1080 if (handle
== INVALID_HANDLE_VALUE
) return 0;
1082 /* find first dir/file */
1085 if (file
? is_file_data(data
) : is_dir_data(data
))
1088 if (!FindNextFileW(handle
, data
))
1097 static HRESULT WINAPI
foldercoll_enumvariant_Next(IEnumVARIANT
*iface
, ULONG celt
, VARIANT
*var
, ULONG
*fetched
)
1099 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1100 HANDLE handle
= This
->data
.u
.foldercoll
.find
;
1101 WIN32_FIND_DATAW data
;
1104 TRACE("(%p)->(%d %p %p)\n", This
, celt
, var
, fetched
);
1109 if (!celt
) return S_OK
;
1113 handle
= start_enumeration(This
->data
.u
.foldercoll
.coll
->path
, &data
, FALSE
);
1114 if (!handle
) return S_FALSE
;
1116 This
->data
.u
.foldercoll
.find
= handle
;
1120 if (!FindNextFileW(handle
, &data
))
1126 if (is_dir_data(&data
))
1132 str
= get_full_path(This
->data
.u
.foldercoll
.coll
->path
, &data
);
1133 hr
= create_folder(str
, &folder
);
1135 if (FAILED(hr
)) return hr
;
1137 V_VT(&var
[count
]) = VT_DISPATCH
;
1138 V_DISPATCH(&var
[count
]) = (IDispatch
*)folder
;
1141 if (count
>= celt
) break;
1143 } while (FindNextFileW(handle
, &data
));
1148 return (count
< celt
) ? S_FALSE
: S_OK
;
1151 static HRESULT WINAPI
foldercoll_enumvariant_Skip(IEnumVARIANT
*iface
, ULONG celt
)
1153 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1154 HANDLE handle
= This
->data
.u
.foldercoll
.find
;
1155 WIN32_FIND_DATAW data
;
1157 TRACE("(%p)->(%d)\n", This
, celt
);
1159 if (!celt
) return S_OK
;
1163 handle
= start_enumeration(This
->data
.u
.foldercoll
.coll
->path
, &data
, FALSE
);
1164 if (!handle
) return S_FALSE
;
1166 This
->data
.u
.foldercoll
.find
= handle
;
1170 if (!FindNextFileW(handle
, &data
))
1176 if (is_dir_data(&data
))
1180 } while (FindNextFileW(handle
, &data
));
1182 return celt
? S_FALSE
: S_OK
;
1185 static HRESULT WINAPI
foldercoll_enumvariant_Reset(IEnumVARIANT
*iface
)
1187 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1189 TRACE("(%p)\n", This
);
1191 FindClose(This
->data
.u
.foldercoll
.find
);
1192 This
->data
.u
.foldercoll
.find
= NULL
;
1197 static HRESULT WINAPI
foldercoll_enumvariant_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**pclone
)
1199 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1200 TRACE("(%p)->(%p)\n", This
, pclone
);
1201 return create_foldercoll_enum(This
->data
.u
.foldercoll
.coll
, (IUnknown
**)pclone
);
1204 static const IEnumVARIANTVtbl foldercollenumvariantvtbl
= {
1205 enumvariant_QueryInterface
,
1207 foldercoll_enumvariant_Release
,
1208 foldercoll_enumvariant_Next
,
1209 foldercoll_enumvariant_Skip
,
1210 foldercoll_enumvariant_Reset
,
1211 foldercoll_enumvariant_Clone
1214 static HRESULT
create_foldercoll_enum(struct foldercollection
*collection
, IUnknown
**newenum
)
1216 struct enumvariant
*This
;
1220 This
= heap_alloc(sizeof(*This
));
1221 if (!This
) return E_OUTOFMEMORY
;
1223 This
->IEnumVARIANT_iface
.lpVtbl
= &foldercollenumvariantvtbl
;
1225 This
->data
.u
.foldercoll
.find
= NULL
;
1226 This
->data
.u
.foldercoll
.coll
= collection
;
1227 IFolderCollection_AddRef(&collection
->IFolderCollection_iface
);
1229 *newenum
= (IUnknown
*)&This
->IEnumVARIANT_iface
;
1234 static ULONG WINAPI
filecoll_enumvariant_Release(IEnumVARIANT
*iface
)
1236 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1237 ULONG ref
= InterlockedDecrement(&This
->ref
);
1239 TRACE("(%p)->(%d)\n", This
, ref
);
1243 IFileCollection_Release(&This
->data
.u
.filecoll
.coll
->IFileCollection_iface
);
1244 FindClose(This
->data
.u
.filecoll
.find
);
1251 static HRESULT WINAPI
filecoll_enumvariant_Next(IEnumVARIANT
*iface
, ULONG celt
, VARIANT
*var
, ULONG
*fetched
)
1253 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1254 HANDLE handle
= This
->data
.u
.filecoll
.find
;
1255 WIN32_FIND_DATAW data
;
1258 TRACE("(%p)->(%d %p %p)\n", This
, celt
, var
, fetched
);
1263 if (!celt
) return S_OK
;
1267 handle
= start_enumeration(This
->data
.u
.filecoll
.coll
->path
, &data
, TRUE
);
1268 if (!handle
) return S_FALSE
;
1269 This
->data
.u
.filecoll
.find
= handle
;
1271 else if (!FindNextFileW(handle
, &data
))
1276 if (is_file_data(&data
))
1282 str
= get_full_path(This
->data
.u
.filecoll
.coll
->path
, &data
);
1283 hr
= create_file(str
, &file
);
1285 if (FAILED(hr
)) return hr
;
1287 V_VT(&var
[count
]) = VT_DISPATCH
;
1288 V_DISPATCH(&var
[count
]) = (IDispatch
*)file
;
1289 if (++count
>= celt
) break;
1291 } while (FindNextFileW(handle
, &data
));
1296 return (count
< celt
) ? S_FALSE
: S_OK
;
1299 static HRESULT WINAPI
filecoll_enumvariant_Skip(IEnumVARIANT
*iface
, ULONG celt
)
1301 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1302 HANDLE handle
= This
->data
.u
.filecoll
.find
;
1303 WIN32_FIND_DATAW data
;
1305 TRACE("(%p)->(%d)\n", This
, celt
);
1307 if (!celt
) return S_OK
;
1311 handle
= start_enumeration(This
->data
.u
.filecoll
.coll
->path
, &data
, TRUE
);
1312 if (!handle
) return S_FALSE
;
1313 This
->data
.u
.filecoll
.find
= handle
;
1315 else if (!FindNextFileW(handle
, &data
))
1320 if (is_file_data(&data
))
1322 } while (celt
&& FindNextFileW(handle
, &data
));
1324 return celt
? S_FALSE
: S_OK
;
1327 static HRESULT WINAPI
filecoll_enumvariant_Reset(IEnumVARIANT
*iface
)
1329 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1331 TRACE("(%p)\n", This
);
1333 FindClose(This
->data
.u
.filecoll
.find
);
1334 This
->data
.u
.filecoll
.find
= NULL
;
1339 static HRESULT WINAPI
filecoll_enumvariant_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**pclone
)
1341 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1342 TRACE("(%p)->(%p)\n", This
, pclone
);
1343 return create_filecoll_enum(This
->data
.u
.filecoll
.coll
, (IUnknown
**)pclone
);
1346 static const IEnumVARIANTVtbl filecollenumvariantvtbl
= {
1347 enumvariant_QueryInterface
,
1349 filecoll_enumvariant_Release
,
1350 filecoll_enumvariant_Next
,
1351 filecoll_enumvariant_Skip
,
1352 filecoll_enumvariant_Reset
,
1353 filecoll_enumvariant_Clone
1356 static HRESULT
create_filecoll_enum(struct filecollection
*collection
, IUnknown
**newenum
)
1358 struct enumvariant
*This
;
1362 This
= heap_alloc(sizeof(*This
));
1363 if (!This
) return E_OUTOFMEMORY
;
1365 This
->IEnumVARIANT_iface
.lpVtbl
= &filecollenumvariantvtbl
;
1367 This
->data
.u
.filecoll
.find
= NULL
;
1368 This
->data
.u
.filecoll
.coll
= collection
;
1369 IFileCollection_AddRef(&collection
->IFileCollection_iface
);
1371 *newenum
= (IUnknown
*)&This
->IEnumVARIANT_iface
;
1376 static ULONG WINAPI
drivecoll_enumvariant_Release(IEnumVARIANT
*iface
)
1378 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1379 ULONG ref
= InterlockedDecrement(&This
->ref
);
1381 TRACE("(%p)->(%d)\n", This
, ref
);
1385 IDriveCollection_Release(&This
->data
.u
.drivecoll
.coll
->IDriveCollection_iface
);
1392 static HRESULT
find_next_drive(struct enumvariant
*penum
)
1394 int i
= penum
->data
.u
.drivecoll
.cur
== -1 ? 0 : penum
->data
.u
.drivecoll
.cur
+ 1;
1397 if (penum
->data
.u
.drivecoll
.coll
->drives
& (1 << i
))
1399 penum
->data
.u
.drivecoll
.cur
= i
;
1406 static HRESULT WINAPI
drivecoll_enumvariant_Next(IEnumVARIANT
*iface
, ULONG celt
, VARIANT
*var
, ULONG
*fetched
)
1408 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1411 TRACE("(%p)->(%d %p %p)\n", This
, celt
, var
, fetched
);
1416 if (!celt
) return S_OK
;
1418 while (find_next_drive(This
) == S_OK
)
1423 hr
= create_drive('A' + This
->data
.u
.drivecoll
.cur
, &drive
);
1424 if (FAILED(hr
)) return hr
;
1426 V_VT(&var
[count
]) = VT_DISPATCH
;
1427 V_DISPATCH(&var
[count
]) = (IDispatch
*)drive
;
1429 if (++count
>= celt
) break;
1435 return (count
< celt
) ? S_FALSE
: S_OK
;
1438 static HRESULT WINAPI
drivecoll_enumvariant_Skip(IEnumVARIANT
*iface
, ULONG celt
)
1440 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1442 TRACE("(%p)->(%d)\n", This
, celt
);
1444 if (!celt
) return S_OK
;
1446 while (celt
&& find_next_drive(This
) == S_OK
)
1449 return celt
? S_FALSE
: S_OK
;
1452 static HRESULT WINAPI
drivecoll_enumvariant_Reset(IEnumVARIANT
*iface
)
1454 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1456 TRACE("(%p)\n", This
);
1458 This
->data
.u
.drivecoll
.cur
= -1;
1462 static HRESULT WINAPI
drivecoll_enumvariant_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**pclone
)
1464 struct enumvariant
*This
= impl_from_IEnumVARIANT(iface
);
1465 FIXME("(%p)->(%p): stub\n", This
, pclone
);
1469 static const IEnumVARIANTVtbl drivecollenumvariantvtbl
= {
1470 enumvariant_QueryInterface
,
1472 drivecoll_enumvariant_Release
,
1473 drivecoll_enumvariant_Next
,
1474 drivecoll_enumvariant_Skip
,
1475 drivecoll_enumvariant_Reset
,
1476 drivecoll_enumvariant_Clone
1479 static HRESULT
create_drivecoll_enum(struct drivecollection
*collection
, IUnknown
**newenum
)
1481 struct enumvariant
*This
;
1485 This
= heap_alloc(sizeof(*This
));
1486 if (!This
) return E_OUTOFMEMORY
;
1488 This
->IEnumVARIANT_iface
.lpVtbl
= &drivecollenumvariantvtbl
;
1490 This
->data
.u
.drivecoll
.coll
= collection
;
1491 This
->data
.u
.drivecoll
.cur
= -1;
1492 IDriveCollection_AddRef(&collection
->IDriveCollection_iface
);
1494 *newenum
= (IUnknown
*)&This
->IEnumVARIANT_iface
;
1499 static HRESULT WINAPI
foldercoll_QueryInterface(IFolderCollection
*iface
, REFIID riid
, void **obj
)
1501 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1503 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1507 if (IsEqualIID( riid
, &IID_IFolderCollection
) ||
1508 IsEqualIID( riid
, &IID_IDispatch
) ||
1509 IsEqualIID( riid
, &IID_IUnknown
))
1512 IFolderCollection_AddRef(iface
);
1515 return E_NOINTERFACE
;
1520 static ULONG WINAPI
foldercoll_AddRef(IFolderCollection
*iface
)
1522 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1523 ULONG ref
= InterlockedIncrement(&This
->ref
);
1524 TRACE("(%p)->(%d)\n", This
, ref
);
1528 static ULONG WINAPI
foldercoll_Release(IFolderCollection
*iface
)
1530 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1531 ULONG ref
= InterlockedDecrement(&This
->ref
);
1532 TRACE("(%p)->(%d)\n", This
, ref
);
1536 SysFreeString(This
->path
);
1543 static HRESULT WINAPI
foldercoll_GetTypeInfoCount(IFolderCollection
*iface
, UINT
*pctinfo
)
1545 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1546 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1551 static HRESULT WINAPI
foldercoll_GetTypeInfo(IFolderCollection
*iface
, UINT iTInfo
,
1552 LCID lcid
, ITypeInfo
**ppTInfo
)
1554 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1555 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1556 return get_typeinfo(IFolderCollection_tid
, ppTInfo
);
1559 static HRESULT WINAPI
foldercoll_GetIDsOfNames(IFolderCollection
*iface
, REFIID riid
,
1560 LPOLESTR
*rgszNames
, UINT cNames
,
1561 LCID lcid
, DISPID
*rgDispId
)
1563 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1564 ITypeInfo
*typeinfo
;
1567 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1569 hr
= get_typeinfo(IFolderCollection_tid
, &typeinfo
);
1572 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1573 ITypeInfo_Release(typeinfo
);
1579 static HRESULT WINAPI
foldercoll_Invoke(IFolderCollection
*iface
, DISPID dispIdMember
,
1580 REFIID riid
, LCID lcid
, WORD wFlags
,
1581 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1582 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1584 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1585 ITypeInfo
*typeinfo
;
1588 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1589 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1591 hr
= get_typeinfo(IFolderCollection_tid
, &typeinfo
);
1594 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
1595 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1596 ITypeInfo_Release(typeinfo
);
1602 static HRESULT WINAPI
foldercoll_Add(IFolderCollection
*iface
, BSTR name
, IFolder
**folder
)
1604 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1605 FIXME("(%p)->(%s %p): stub\n", This
, debugstr_w(name
), folder
);
1609 static HRESULT WINAPI
foldercoll_get_Item(IFolderCollection
*iface
, VARIANT key
, IFolder
**folder
)
1611 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1612 FIXME("(%p)->(%p): stub\n", This
, folder
);
1616 static HRESULT WINAPI
foldercoll_get__NewEnum(IFolderCollection
*iface
, IUnknown
**newenum
)
1618 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1620 TRACE("(%p)->(%p)\n", This
, newenum
);
1625 return create_foldercoll_enum(This
, newenum
);
1628 static HRESULT WINAPI
foldercoll_get_Count(IFolderCollection
*iface
, LONG
*count
)
1630 struct foldercollection
*This
= impl_from_IFolderCollection(iface
);
1631 static const WCHAR allW
[] = {'\\','*',0};
1632 WIN32_FIND_DATAW data
;
1633 WCHAR pathW
[MAX_PATH
];
1636 TRACE("(%p)->(%p)\n", This
, count
);
1643 strcpyW(pathW
, This
->path
);
1644 strcatW(pathW
, allW
);
1645 handle
= FindFirstFileW(pathW
, &data
);
1646 if (handle
== INVALID_HANDLE_VALUE
)
1647 return HRESULT_FROM_WIN32(GetLastError());
1651 if (is_dir_data(&data
))
1653 } while (FindNextFileW(handle
, &data
));
1659 static const IFolderCollectionVtbl foldercollvtbl
= {
1660 foldercoll_QueryInterface
,
1663 foldercoll_GetTypeInfoCount
,
1664 foldercoll_GetTypeInfo
,
1665 foldercoll_GetIDsOfNames
,
1668 foldercoll_get_Item
,
1669 foldercoll_get__NewEnum
,
1670 foldercoll_get_Count
1673 static HRESULT
create_foldercoll(BSTR path
, IFolderCollection
**folders
)
1675 struct foldercollection
*This
;
1679 This
= heap_alloc(sizeof(struct foldercollection
));
1680 if (!This
) return E_OUTOFMEMORY
;
1682 This
->IFolderCollection_iface
.lpVtbl
= &foldercollvtbl
;
1684 This
->path
= SysAllocString(path
);
1688 return E_OUTOFMEMORY
;
1691 *folders
= &This
->IFolderCollection_iface
;
1696 static HRESULT WINAPI
filecoll_QueryInterface(IFileCollection
*iface
, REFIID riid
, void **obj
)
1698 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1700 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1704 if (IsEqualIID( riid
, &IID_IFileCollection
) ||
1705 IsEqualIID( riid
, &IID_IDispatch
) ||
1706 IsEqualIID( riid
, &IID_IUnknown
))
1709 IFileCollection_AddRef(iface
);
1712 return E_NOINTERFACE
;
1717 static ULONG WINAPI
filecoll_AddRef(IFileCollection
*iface
)
1719 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1720 ULONG ref
= InterlockedIncrement(&This
->ref
);
1721 TRACE("(%p)->(%d)\n", This
, ref
);
1725 static ULONG WINAPI
filecoll_Release(IFileCollection
*iface
)
1727 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1728 ULONG ref
= InterlockedDecrement(&This
->ref
);
1729 TRACE("(%p)->(%d)\n", This
, ref
);
1733 SysFreeString(This
->path
);
1740 static HRESULT WINAPI
filecoll_GetTypeInfoCount(IFileCollection
*iface
, UINT
*pctinfo
)
1742 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1743 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1748 static HRESULT WINAPI
filecoll_GetTypeInfo(IFileCollection
*iface
, UINT iTInfo
,
1749 LCID lcid
, ITypeInfo
**ppTInfo
)
1751 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1752 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1753 return get_typeinfo(IFileCollection_tid
, ppTInfo
);
1756 static HRESULT WINAPI
filecoll_GetIDsOfNames(IFileCollection
*iface
, REFIID riid
,
1757 LPOLESTR
*rgszNames
, UINT cNames
,
1758 LCID lcid
, DISPID
*rgDispId
)
1760 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1761 ITypeInfo
*typeinfo
;
1764 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1766 hr
= get_typeinfo(IFileCollection_tid
, &typeinfo
);
1769 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1770 ITypeInfo_Release(typeinfo
);
1776 static HRESULT WINAPI
filecoll_Invoke(IFileCollection
*iface
, DISPID dispIdMember
,
1777 REFIID riid
, LCID lcid
, WORD wFlags
,
1778 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1779 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1781 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1782 ITypeInfo
*typeinfo
;
1785 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1786 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1788 hr
= get_typeinfo(IFileCollection_tid
, &typeinfo
);
1791 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
1792 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1793 ITypeInfo_Release(typeinfo
);
1799 static HRESULT WINAPI
filecoll_get_Item(IFileCollection
*iface
, VARIANT Key
, IFile
**file
)
1801 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1802 FIXME("(%p)->(%p)\n", This
, file
);
1806 static HRESULT WINAPI
filecoll_get__NewEnum(IFileCollection
*iface
, IUnknown
**ppenum
)
1808 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1810 TRACE("(%p)->(%p)\n", This
, ppenum
);
1815 return create_filecoll_enum(This
, ppenum
);
1818 static HRESULT WINAPI
filecoll_get_Count(IFileCollection
*iface
, LONG
*count
)
1820 struct filecollection
*This
= impl_from_IFileCollection(iface
);
1821 FIXME("(%p)->(%p)\n", This
, count
);
1825 static const IFileCollectionVtbl filecollectionvtbl
= {
1826 filecoll_QueryInterface
,
1829 filecoll_GetTypeInfoCount
,
1830 filecoll_GetTypeInfo
,
1831 filecoll_GetIDsOfNames
,
1834 filecoll_get__NewEnum
,
1838 static HRESULT
create_filecoll(BSTR path
, IFileCollection
**files
)
1840 struct filecollection
*This
;
1844 This
= heap_alloc(sizeof(*This
));
1845 if (!This
) return E_OUTOFMEMORY
;
1847 This
->IFileCollection_iface
.lpVtbl
= &filecollectionvtbl
;
1849 This
->path
= SysAllocString(path
);
1853 return E_OUTOFMEMORY
;
1856 *files
= &This
->IFileCollection_iface
;
1860 static HRESULT WINAPI
drivecoll_QueryInterface(IDriveCollection
*iface
, REFIID riid
, void **obj
)
1862 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1864 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
1868 if (IsEqualIID( riid
, &IID_IDriveCollection
) ||
1869 IsEqualIID( riid
, &IID_IDispatch
) ||
1870 IsEqualIID( riid
, &IID_IUnknown
))
1873 IDriveCollection_AddRef(iface
);
1876 return E_NOINTERFACE
;
1881 static ULONG WINAPI
drivecoll_AddRef(IDriveCollection
*iface
)
1883 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1884 ULONG ref
= InterlockedIncrement(&This
->ref
);
1885 TRACE("(%p)->(%d)\n", This
, ref
);
1889 static ULONG WINAPI
drivecoll_Release(IDriveCollection
*iface
)
1891 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1892 ULONG ref
= InterlockedDecrement(&This
->ref
);
1893 TRACE("(%p)->(%d)\n", This
, ref
);
1901 static HRESULT WINAPI
drivecoll_GetTypeInfoCount(IDriveCollection
*iface
, UINT
*pctinfo
)
1903 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1904 TRACE("(%p)->(%p)\n", This
, pctinfo
);
1909 static HRESULT WINAPI
drivecoll_GetTypeInfo(IDriveCollection
*iface
, UINT iTInfo
,
1910 LCID lcid
, ITypeInfo
**ppTInfo
)
1912 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1913 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1914 return get_typeinfo(IDriveCollection_tid
, ppTInfo
);
1917 static HRESULT WINAPI
drivecoll_GetIDsOfNames(IDriveCollection
*iface
, REFIID riid
,
1918 LPOLESTR
*rgszNames
, UINT cNames
,
1919 LCID lcid
, DISPID
*rgDispId
)
1921 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1922 ITypeInfo
*typeinfo
;
1925 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1927 hr
= get_typeinfo(IDriveCollection_tid
, &typeinfo
);
1930 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1931 ITypeInfo_Release(typeinfo
);
1937 static HRESULT WINAPI
drivecoll_Invoke(IDriveCollection
*iface
, DISPID dispIdMember
,
1938 REFIID riid
, LCID lcid
, WORD wFlags
,
1939 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1940 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1942 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1943 ITypeInfo
*typeinfo
;
1946 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1947 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1949 hr
= get_typeinfo(IDriveCollection_tid
, &typeinfo
);
1952 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
1953 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1954 ITypeInfo_Release(typeinfo
);
1960 static HRESULT WINAPI
drivecoll_get_Item(IDriveCollection
*iface
, VARIANT key
, IDrive
**drive
)
1962 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1963 FIXME("(%p)->(%p): stub\n", This
, drive
);
1967 static HRESULT WINAPI
drivecoll_get__NewEnum(IDriveCollection
*iface
, IUnknown
**ppenum
)
1969 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1971 TRACE("(%p)->(%p)\n", This
, ppenum
);
1976 return create_drivecoll_enum(This
, ppenum
);
1979 static HRESULT WINAPI
drivecoll_get_Count(IDriveCollection
*iface
, LONG
*count
)
1981 struct drivecollection
*This
= impl_from_IDriveCollection(iface
);
1983 TRACE("(%p)->(%p)\n", This
, count
);
1985 if (!count
) return E_POINTER
;
1987 *count
= This
->count
;
1991 static const IDriveCollectionVtbl drivecollectionvtbl
= {
1992 drivecoll_QueryInterface
,
1995 drivecoll_GetTypeInfoCount
,
1996 drivecoll_GetTypeInfo
,
1997 drivecoll_GetIDsOfNames
,
2000 drivecoll_get__NewEnum
,
2004 static HRESULT
create_drivecoll(IDriveCollection
**drives
)
2006 struct drivecollection
*This
;
2011 This
= heap_alloc(sizeof(*This
));
2012 if (!This
) return E_OUTOFMEMORY
;
2014 This
->IDriveCollection_iface
.lpVtbl
= &drivecollectionvtbl
;
2016 This
->drives
= mask
= GetLogicalDrives();
2017 /* count set bits */
2018 for (This
->count
= 0; mask
; This
->count
++)
2021 *drives
= &This
->IDriveCollection_iface
;
2025 static HRESULT WINAPI
folder_QueryInterface(IFolder
*iface
, REFIID riid
, void **obj
)
2027 struct folder
*This
= impl_from_IFolder(iface
);
2029 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
2033 if (IsEqualIID( riid
, &IID_IFolder
) ||
2034 IsEqualIID( riid
, &IID_IDispatch
) ||
2035 IsEqualIID( riid
, &IID_IUnknown
))
2038 IFolder_AddRef(iface
);
2041 return E_NOINTERFACE
;
2046 static ULONG WINAPI
folder_AddRef(IFolder
*iface
)
2048 struct folder
*This
= impl_from_IFolder(iface
);
2049 ULONG ref
= InterlockedIncrement(&This
->ref
);
2050 TRACE("(%p)->(%d)\n", This
, ref
);
2054 static ULONG WINAPI
folder_Release(IFolder
*iface
)
2056 struct folder
*This
= impl_from_IFolder(iface
);
2057 ULONG ref
= InterlockedDecrement(&This
->ref
);
2058 TRACE("(%p)->(%d)\n", This
, ref
);
2062 SysFreeString(This
->path
);
2069 static HRESULT WINAPI
folder_GetTypeInfoCount(IFolder
*iface
, UINT
*pctinfo
)
2071 struct folder
*This
= impl_from_IFolder(iface
);
2072 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2077 static HRESULT WINAPI
folder_GetTypeInfo(IFolder
*iface
, UINT iTInfo
,
2078 LCID lcid
, ITypeInfo
**ppTInfo
)
2080 struct folder
*This
= impl_from_IFolder(iface
);
2081 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2082 return get_typeinfo(IFolder_tid
, ppTInfo
);
2085 static HRESULT WINAPI
folder_GetIDsOfNames(IFolder
*iface
, REFIID riid
,
2086 LPOLESTR
*rgszNames
, UINT cNames
,
2087 LCID lcid
, DISPID
*rgDispId
)
2089 struct folder
*This
= impl_from_IFolder(iface
);
2090 ITypeInfo
*typeinfo
;
2093 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
2095 hr
= get_typeinfo(IFolder_tid
, &typeinfo
);
2098 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2099 ITypeInfo_Release(typeinfo
);
2105 static HRESULT WINAPI
folder_Invoke(IFolder
*iface
, DISPID dispIdMember
,
2106 REFIID riid
, LCID lcid
, WORD wFlags
,
2107 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2108 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2110 struct folder
*This
= impl_from_IFolder(iface
);
2111 ITypeInfo
*typeinfo
;
2114 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2115 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2117 hr
= get_typeinfo(IFolder_tid
, &typeinfo
);
2120 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
2121 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2122 ITypeInfo_Release(typeinfo
);
2128 static HRESULT WINAPI
folder_get_Path(IFolder
*iface
, BSTR
*path
)
2130 struct folder
*This
= impl_from_IFolder(iface
);
2132 TRACE("(%p)->(%p)\n", This
, path
);
2137 *path
= SysAllocString(This
->path
);
2138 return *path
? S_OK
: E_OUTOFMEMORY
;
2141 static HRESULT WINAPI
folder_get_Name(IFolder
*iface
, BSTR
*name
)
2143 struct folder
*This
= impl_from_IFolder(iface
);
2146 TRACE("(%p)->(%p)\n", This
, name
);
2153 ptr
= strrchrW(This
->path
, '\\');
2156 *name
= SysAllocString(ptr
+1);
2157 TRACE("%s\n", debugstr_w(*name
));
2158 if (!*name
) return E_OUTOFMEMORY
;
2166 static HRESULT WINAPI
folder_put_Name(IFolder
*iface
, BSTR name
)
2168 struct folder
*This
= impl_from_IFolder(iface
);
2169 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(name
));
2173 static HRESULT WINAPI
folder_get_ShortPath(IFolder
*iface
, BSTR
*path
)
2175 struct folder
*This
= impl_from_IFolder(iface
);
2176 FIXME("(%p)->(%p): stub\n", This
, path
);
2180 static HRESULT WINAPI
folder_get_ShortName(IFolder
*iface
, BSTR
*name
)
2182 struct folder
*This
= impl_from_IFolder(iface
);
2183 FIXME("(%p)->(%p): stub\n", This
, name
);
2187 static HRESULT WINAPI
folder_get_Drive(IFolder
*iface
, IDrive
**drive
)
2189 struct folder
*This
= impl_from_IFolder(iface
);
2190 FIXME("(%p)->(%p): stub\n", This
, drive
);
2194 static HRESULT WINAPI
folder_get_ParentFolder(IFolder
*iface
, IFolder
**parent
)
2196 struct folder
*This
= impl_from_IFolder(iface
);
2197 FIXME("(%p)->(%p): stub\n", This
, parent
);
2201 static HRESULT WINAPI
folder_get_Attributes(IFolder
*iface
, FileAttribute
*attr
)
2203 struct folder
*This
= impl_from_IFolder(iface
);
2204 FIXME("(%p)->(%p): stub\n", This
, attr
);
2208 static HRESULT WINAPI
folder_put_Attributes(IFolder
*iface
, FileAttribute attr
)
2210 struct folder
*This
= impl_from_IFolder(iface
);
2211 FIXME("(%p)->(0x%x): stub\n", This
, attr
);
2215 static HRESULT WINAPI
folder_get_DateCreated(IFolder
*iface
, DATE
*date
)
2217 struct folder
*This
= impl_from_IFolder(iface
);
2218 FIXME("(%p)->(%p): stub\n", This
, date
);
2222 static HRESULT WINAPI
folder_get_DateLastModified(IFolder
*iface
, DATE
*date
)
2224 struct folder
*This
= impl_from_IFolder(iface
);
2225 FIXME("(%p)->(%p): stub\n", This
, date
);
2229 static HRESULT WINAPI
folder_get_DateLastAccessed(IFolder
*iface
, DATE
*date
)
2231 struct folder
*This
= impl_from_IFolder(iface
);
2232 FIXME("(%p)->(%p): stub\n", This
, date
);
2236 static HRESULT WINAPI
folder_get_Type(IFolder
*iface
, BSTR
*type
)
2238 struct folder
*This
= impl_from_IFolder(iface
);
2239 FIXME("(%p)->(%p): stub\n", This
, type
);
2243 static HRESULT WINAPI
folder_Delete(IFolder
*iface
, VARIANT_BOOL force
)
2245 struct folder
*This
= impl_from_IFolder(iface
);
2246 FIXME("(%p)->(%x): stub\n", This
, force
);
2250 static HRESULT WINAPI
folder_Copy(IFolder
*iface
, BSTR dest
, VARIANT_BOOL overwrite
)
2252 struct folder
*This
= impl_from_IFolder(iface
);
2253 FIXME("(%p)->(%s %x): stub\n", This
, debugstr_w(dest
), overwrite
);
2257 static HRESULT WINAPI
folder_Move(IFolder
*iface
, BSTR dest
)
2259 struct folder
*This
= impl_from_IFolder(iface
);
2260 FIXME("(%p)->(%s): stub\n", This
, debugstr_w(dest
));
2264 static HRESULT WINAPI
folder_get_IsRootFolder(IFolder
*iface
, VARIANT_BOOL
*isroot
)
2266 struct folder
*This
= impl_from_IFolder(iface
);
2267 FIXME("(%p)->(%p): stub\n", This
, isroot
);
2271 static HRESULT WINAPI
folder_get_Size(IFolder
*iface
, VARIANT
*size
)
2273 struct folder
*This
= impl_from_IFolder(iface
);
2274 FIXME("(%p)->(%p): stub\n", This
, size
);
2278 static HRESULT WINAPI
folder_get_SubFolders(IFolder
*iface
, IFolderCollection
**folders
)
2280 struct folder
*This
= impl_from_IFolder(iface
);
2282 TRACE("(%p)->(%p)\n", This
, folders
);
2287 return create_foldercoll(This
->path
, folders
);
2290 static HRESULT WINAPI
folder_get_Files(IFolder
*iface
, IFileCollection
**files
)
2292 struct folder
*This
= impl_from_IFolder(iface
);
2294 TRACE("(%p)->(%p)\n", This
, files
);
2299 return create_filecoll(This
->path
, files
);
2302 static HRESULT WINAPI
folder_CreateTextFile(IFolder
*iface
, BSTR filename
, VARIANT_BOOL overwrite
,
2303 VARIANT_BOOL unicode
, ITextStream
**stream
)
2305 struct folder
*This
= impl_from_IFolder(iface
);
2306 FIXME("(%p)->(%s %x %x %p): stub\n", This
, debugstr_w(filename
), overwrite
, unicode
, stream
);
2310 static const IFolderVtbl foldervtbl
= {
2311 folder_QueryInterface
,
2314 folder_GetTypeInfoCount
,
2316 folder_GetIDsOfNames
,
2321 folder_get_ShortPath
,
2322 folder_get_ShortName
,
2324 folder_get_ParentFolder
,
2325 folder_get_Attributes
,
2326 folder_put_Attributes
,
2327 folder_get_DateCreated
,
2328 folder_get_DateLastModified
,
2329 folder_get_DateLastAccessed
,
2334 folder_get_IsRootFolder
,
2336 folder_get_SubFolders
,
2338 folder_CreateTextFile
2341 HRESULT
create_folder(const WCHAR
*path
, IFolder
**folder
)
2343 struct folder
*This
;
2347 TRACE("%s\n", debugstr_w(path
));
2349 This
= heap_alloc(sizeof(struct folder
));
2350 if (!This
) return E_OUTOFMEMORY
;
2352 This
->IFolder_iface
.lpVtbl
= &foldervtbl
;
2354 This
->path
= SysAllocString(path
);
2358 return E_OUTOFMEMORY
;
2361 *folder
= &This
->IFolder_iface
;
2366 static HRESULT WINAPI
file_QueryInterface(IFile
*iface
, REFIID riid
, void **obj
)
2368 struct file
*This
= impl_from_IFile(iface
);
2370 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), obj
);
2372 if (IsEqualIID(riid
, &IID_IFile
) ||
2373 IsEqualIID(riid
, &IID_IDispatch
) ||
2374 IsEqualIID(riid
, &IID_IUnknown
))
2377 IFile_AddRef(iface
);
2382 return E_NOINTERFACE
;
2385 static ULONG WINAPI
file_AddRef(IFile
*iface
)
2387 struct file
*This
= impl_from_IFile(iface
);
2388 LONG ref
= InterlockedIncrement(&This
->ref
);
2390 TRACE("(%p) ref=%d\n", This
, ref
);
2395 static ULONG WINAPI
file_Release(IFile
*iface
)
2397 struct file
*This
= impl_from_IFile(iface
);
2398 LONG ref
= InterlockedDecrement(&This
->ref
);
2400 TRACE("(%p) ref=%d\n", This
, ref
);
2404 heap_free(This
->path
);
2411 static HRESULT WINAPI
file_GetTypeInfoCount(IFile
*iface
, UINT
*pctinfo
)
2413 struct file
*This
= impl_from_IFile(iface
);
2415 TRACE("(%p)->(%p)\n", This
, pctinfo
);
2421 static HRESULT WINAPI
file_GetTypeInfo(IFile
*iface
,
2422 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
2424 struct file
*This
= impl_from_IFile(iface
);
2426 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
2428 return get_typeinfo(IFile_tid
, ppTInfo
);
2431 static HRESULT WINAPI
file_GetIDsOfNames(IFile
*iface
, REFIID riid
,
2432 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2434 struct file
*This
= impl_from_IFile(iface
);
2435 ITypeInfo
*typeinfo
;
2438 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
),
2439 rgszNames
, cNames
, lcid
, rgDispId
);
2441 hr
= get_typeinfo(IFile_tid
, &typeinfo
);
2443 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2444 ITypeInfo_Release(typeinfo
);
2449 static HRESULT WINAPI
file_Invoke(IFile
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2451 struct file
*This
= impl_from_IFile(iface
);
2452 ITypeInfo
*typeinfo
;
2455 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
2456 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2458 hr
= get_typeinfo(IFile_tid
, &typeinfo
);
2461 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
2462 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2463 ITypeInfo_Release(typeinfo
);
2468 static HRESULT WINAPI
file_get_Path(IFile
*iface
, BSTR
*pbstrPath
)
2470 struct file
*This
= impl_from_IFile(iface
);
2471 FIXME("(%p)->(%p)\n", This
, pbstrPath
);
2475 static HRESULT WINAPI
file_get_Name(IFile
*iface
, BSTR
*name
)
2477 struct file
*This
= impl_from_IFile(iface
);
2480 TRACE("(%p)->(%p)\n", This
, name
);
2487 ptr
= strrchrW(This
->path
, '\\');
2490 *name
= SysAllocString(ptr
+1);
2491 TRACE("%s\n", debugstr_w(*name
));
2492 if (!*name
) return E_OUTOFMEMORY
;
2500 static HRESULT WINAPI
file_put_Name(IFile
*iface
, BSTR pbstrName
)
2502 struct file
*This
= impl_from_IFile(iface
);
2503 FIXME("(%p)->(%s)\n", This
, debugstr_w(pbstrName
));
2507 static HRESULT WINAPI
file_get_ShortPath(IFile
*iface
, BSTR
*pbstrPath
)
2509 struct file
*This
= impl_from_IFile(iface
);
2510 FIXME("(%p)->(%p)\n", This
, pbstrPath
);
2514 static HRESULT WINAPI
file_get_ShortName(IFile
*iface
, BSTR
*pbstrName
)
2516 struct file
*This
= impl_from_IFile(iface
);
2517 FIXME("(%p)->(%p)\n", This
, pbstrName
);
2521 static HRESULT WINAPI
file_get_Drive(IFile
*iface
, IDrive
**ppdrive
)
2523 struct file
*This
= impl_from_IFile(iface
);
2524 FIXME("(%p)->(%p)\n", This
, ppdrive
);
2528 static HRESULT WINAPI
file_get_ParentFolder(IFile
*iface
, IFolder
**ppfolder
)
2530 struct file
*This
= impl_from_IFile(iface
);
2531 FIXME("(%p)->(%p)\n", This
, ppfolder
);
2535 static HRESULT WINAPI
file_get_Attributes(IFile
*iface
, FileAttribute
*pfa
)
2537 struct file
*This
= impl_from_IFile(iface
);
2540 TRACE("(%p)->(%p)\n", This
, pfa
);
2545 fa
= GetFileAttributesW(This
->path
);
2546 if(fa
== INVALID_FILE_ATTRIBUTES
)
2547 return create_error(GetLastError());
2549 *pfa
= fa
& (FILE_ATTRIBUTE_READONLY
| FILE_ATTRIBUTE_HIDDEN
|
2550 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_ARCHIVE
|
2551 FILE_ATTRIBUTE_REPARSE_POINT
| FILE_ATTRIBUTE_COMPRESSED
);
2555 static HRESULT WINAPI
file_put_Attributes(IFile
*iface
, FileAttribute pfa
)
2557 struct file
*This
= impl_from_IFile(iface
);
2558 FIXME("(%p)->(%x)\n", This
, pfa
);
2562 static HRESULT WINAPI
file_get_DateCreated(IFile
*iface
, DATE
*pdate
)
2564 struct file
*This
= impl_from_IFile(iface
);
2565 FIXME("(%p)->(%p)\n", This
, pdate
);
2569 static HRESULT WINAPI
file_get_DateLastModified(IFile
*iface
, DATE
*pdate
)
2571 struct file
*This
= impl_from_IFile(iface
);
2572 FIXME("(%p)->(%p)\n", This
, pdate
);
2576 static HRESULT WINAPI
file_get_DateLastAccessed(IFile
*iface
, DATE
*pdate
)
2578 struct file
*This
= impl_from_IFile(iface
);
2579 FIXME("(%p)->(%p)\n", This
, pdate
);
2583 static HRESULT WINAPI
file_get_Size(IFile
*iface
, VARIANT
*pvarSize
)
2585 struct file
*This
= impl_from_IFile(iface
);
2586 WIN32_FIND_DATAW fd
;
2589 TRACE("(%p)->(%p)\n", This
, pvarSize
);
2594 f
= FindFirstFileW(This
->path
, &fd
);
2595 if(f
== INVALID_HANDLE_VALUE
)
2596 return create_error(GetLastError());
2599 if(fd
.nFileSizeHigh
|| fd
.nFileSizeLow
>INT_MAX
) {
2600 V_VT(pvarSize
) = VT_R8
;
2601 V_R8(pvarSize
) = ((ULONGLONG
)fd
.nFileSizeHigh
<<32) + fd
.nFileSizeLow
;
2603 V_VT(pvarSize
) = VT_I4
;
2604 V_I4(pvarSize
) = fd
.nFileSizeLow
;
2609 static HRESULT WINAPI
file_get_Type(IFile
*iface
, BSTR
*pbstrType
)
2611 struct file
*This
= impl_from_IFile(iface
);
2612 FIXME("(%p)->(%p)\n", This
, pbstrType
);
2616 static HRESULT WINAPI
file_Delete(IFile
*iface
, VARIANT_BOOL Force
)
2618 struct file
*This
= impl_from_IFile(iface
);
2619 FIXME("(%p)->(%x)\n", This
, Force
);
2623 static HRESULT WINAPI
file_Copy(IFile
*iface
, BSTR Destination
, VARIANT_BOOL OverWriteFiles
)
2625 struct file
*This
= impl_from_IFile(iface
);
2626 FIXME("(%p)->(%s %x)\n", This
, debugstr_w(Destination
), OverWriteFiles
);
2630 static HRESULT WINAPI
file_Move(IFile
*iface
, BSTR Destination
)
2632 struct file
*This
= impl_from_IFile(iface
);
2633 FIXME("(%p)->(%s)\n", This
, debugstr_w(Destination
));
2637 static HRESULT WINAPI
file_OpenAsTextStream(IFile
*iface
, IOMode mode
, Tristate format
, ITextStream
**stream
)
2639 struct file
*This
= impl_from_IFile(iface
);
2641 TRACE("(%p)->(%d %d %p)\n", This
, mode
, format
, stream
);
2643 if (format
== TristateUseDefault
) {
2644 FIXME("default format not handled, defaulting to unicode\n");
2645 format
= TristateTrue
;
2648 return create_textstream(This
->path
, OPEN_EXISTING
, mode
, format
== TristateTrue
, stream
);
2651 static const IFileVtbl file_vtbl
= {
2652 file_QueryInterface
,
2655 file_GetTypeInfoCount
,
2665 file_get_ParentFolder
,
2666 file_get_Attributes
,
2667 file_put_Attributes
,
2668 file_get_DateCreated
,
2669 file_get_DateLastModified
,
2670 file_get_DateLastAccessed
,
2676 file_OpenAsTextStream
2679 static HRESULT
create_file(BSTR path
, IFile
**file
)
2686 f
= heap_alloc(sizeof(struct file
));
2688 return E_OUTOFMEMORY
;
2690 f
->IFile_iface
.lpVtbl
= &file_vtbl
;
2693 len
= GetFullPathNameW(path
, 0, NULL
, NULL
);
2699 f
->path
= heap_alloc(len
*sizeof(WCHAR
));
2702 return E_OUTOFMEMORY
;
2705 if(!GetFullPathNameW(path
, len
, f
->path
, NULL
)) {
2711 if(path
[len
-1]=='/' || path
[len
-1]=='\\')
2714 attrs
= GetFileAttributesW(f
->path
);
2715 if(attrs
==INVALID_FILE_ATTRIBUTES
||
2716 (attrs
&(FILE_ATTRIBUTE_DIRECTORY
|FILE_ATTRIBUTE_DEVICE
))) {
2719 return create_error(GetLastError());
2722 *file
= &f
->IFile_iface
;
2726 static HRESULT WINAPI
filesys_QueryInterface(IFileSystem3
*iface
, REFIID riid
, void **ppvObject
)
2728 TRACE("%p %s %p\n", iface
, debugstr_guid(riid
), ppvObject
);
2730 if ( IsEqualGUID( riid
, &IID_IFileSystem3
) ||
2731 IsEqualGUID( riid
, &IID_IFileSystem
) ||
2732 IsEqualGUID( riid
, &IID_IDispatch
) ||
2733 IsEqualGUID( riid
, &IID_IUnknown
) )
2737 else if ( IsEqualGUID( riid
, &IID_IDispatchEx
))
2739 TRACE("Interface IDispatchEx not supported - returning NULL\n");
2741 return E_NOINTERFACE
;
2743 else if ( IsEqualGUID( riid
, &IID_IObjectWithSite
))
2745 TRACE("Interface IObjectWithSite not supported - returning NULL\n");
2747 return E_NOINTERFACE
;
2751 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
2752 return E_NOINTERFACE
;
2755 IFileSystem3_AddRef(iface
);
2760 static ULONG WINAPI
filesys_AddRef(IFileSystem3
*iface
)
2762 TRACE("%p\n", iface
);
2767 static ULONG WINAPI
filesys_Release(IFileSystem3
*iface
)
2769 TRACE("%p\n", iface
);
2774 static HRESULT WINAPI
filesys_GetTypeInfoCount(IFileSystem3
*iface
, UINT
*pctinfo
)
2776 TRACE("(%p)->(%p)\n", iface
, pctinfo
);
2782 static HRESULT WINAPI
filesys_GetTypeInfo(IFileSystem3
*iface
, UINT iTInfo
,
2783 LCID lcid
, ITypeInfo
**ppTInfo
)
2785 TRACE("(%p)->(%u %u %p)\n", iface
, iTInfo
, lcid
, ppTInfo
);
2786 return get_typeinfo(IFileSystem3_tid
, ppTInfo
);
2789 static HRESULT WINAPI
filesys_GetIDsOfNames(IFileSystem3
*iface
, REFIID riid
,
2790 LPOLESTR
*rgszNames
, UINT cNames
,
2791 LCID lcid
, DISPID
*rgDispId
)
2793 ITypeInfo
*typeinfo
;
2796 TRACE("(%p)->(%s %p %u %u %p)\n", iface
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
2798 hr
= get_typeinfo(IFileSystem3_tid
, &typeinfo
);
2801 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2802 ITypeInfo_Release(typeinfo
);
2808 static HRESULT WINAPI
filesys_Invoke(IFileSystem3
*iface
, DISPID dispIdMember
,
2809 REFIID riid
, LCID lcid
, WORD wFlags
,
2810 DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2811 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2813 ITypeInfo
*typeinfo
;
2816 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", iface
, dispIdMember
, debugstr_guid(riid
),
2817 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2819 hr
= get_typeinfo(IFileSystem3_tid
, &typeinfo
);
2822 hr
= ITypeInfo_Invoke(typeinfo
, iface
, dispIdMember
, wFlags
,
2823 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2824 ITypeInfo_Release(typeinfo
);
2830 static HRESULT WINAPI
filesys_get_Drives(IFileSystem3
*iface
, IDriveCollection
**ppdrives
)
2832 TRACE("%p %p\n", iface
, ppdrives
);
2833 return create_drivecoll(ppdrives
);
2836 static HRESULT WINAPI
filesys_BuildPath(IFileSystem3
*iface
, BSTR Path
,
2837 BSTR Name
, BSTR
*Result
)
2841 TRACE("%p %s %s %p\n", iface
, debugstr_w(Path
), debugstr_w(Name
), Result
);
2843 if (!Result
) return E_POINTER
;
2847 int path_len
= SysStringLen(Path
), name_len
= SysStringLen(Name
);
2849 /* if both parts have backslashes strip one from Path */
2850 if (Path
[path_len
-1] == '\\' && Name
[0] == '\\')
2854 ret
= SysAllocStringLen(NULL
, path_len
+ name_len
);
2862 else if (Path
[path_len
-1] != '\\' && Name
[0] != '\\')
2864 ret
= SysAllocStringLen(NULL
, path_len
+ name_len
+ 1);
2868 if (Path
[path_len
-1] != ':')
2875 ret
= SysAllocStringLen(NULL
, path_len
+ name_len
);
2883 else if (Path
|| Name
)
2884 ret
= SysAllocString(Path
? Path
: Name
);
2886 ret
= SysAllocStringLen(NULL
, 0);
2888 if (!ret
) return E_OUTOFMEMORY
;
2894 static HRESULT WINAPI
filesys_GetDriveName(IFileSystem3
*iface
, BSTR Path
,
2897 FIXME("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2902 static inline DWORD
get_parent_folder_name(const WCHAR
*path
, DWORD len
)
2909 for(i
=len
-1; i
>=0; i
--)
2910 if(path
[i
]!='/' && path
[i
]!='\\')
2914 if(path
[i
]=='/' || path
[i
]=='\\')
2918 if(path
[i
]!='/' && path
[i
]!='\\')
2924 if(path
[i
]==':' && i
==1)
2929 static HRESULT WINAPI
filesys_GetParentFolderName(IFileSystem3
*iface
, BSTR Path
,
2934 TRACE("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2939 len
= get_parent_folder_name(Path
, SysStringLen(Path
));
2941 *pbstrResult
= NULL
;
2945 *pbstrResult
= SysAllocStringLen(Path
, len
);
2947 return E_OUTOFMEMORY
;
2951 static HRESULT WINAPI
filesys_GetFileName(IFileSystem3
*iface
, BSTR Path
,
2956 TRACE("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2962 *pbstrResult
= NULL
;
2966 for(end
=strlenW(Path
)-1; end
>=0; end
--)
2967 if(Path
[end
]!='/' && Path
[end
]!='\\')
2970 for(i
=end
; i
>=0; i
--)
2971 if(Path
[i
]=='/' || Path
[i
]=='\\')
2975 if(i
>end
|| (i
==0 && end
==1 && Path
[1]==':')) {
2976 *pbstrResult
= NULL
;
2980 *pbstrResult
= SysAllocStringLen(Path
+i
, end
-i
+1);
2982 return E_OUTOFMEMORY
;
2986 static HRESULT WINAPI
filesys_GetBaseName(IFileSystem3
*iface
, BSTR Path
,
2991 TRACE("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
2997 *pbstrResult
= NULL
;
3001 for(end
=strlenW(Path
)-1; end
>=0; end
--)
3002 if(Path
[end
]!='/' && Path
[end
]!='\\')
3005 for(i
=end
; i
>=0; i
--) {
3006 if(Path
[i
]=='.' && Path
[end
+1]!='.')
3008 if(Path
[i
]=='/' || Path
[i
]=='\\')
3013 if((i
>end
&& Path
[end
+1]!='.') || (i
==0 && end
==1 && Path
[1]==':')) {
3014 *pbstrResult
= NULL
;
3018 *pbstrResult
= SysAllocStringLen(Path
+i
, end
-i
+1);
3020 return E_OUTOFMEMORY
;
3024 static HRESULT WINAPI
filesys_GetExtensionName(IFileSystem3
*iface
, BSTR Path
,
3027 FIXME("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
3032 static HRESULT WINAPI
filesys_GetAbsolutePathName(IFileSystem3
*iface
, BSTR Path
,
3035 static const WCHAR cur_path
[] = {'.',0};
3037 WCHAR buf
[MAX_PATH
], ch
;
3039 DWORD i
, beg
, len
, exp_len
;
3040 WIN32_FIND_DATAW fdata
;
3043 TRACE("%p %s %p\n", iface
, debugstr_w(Path
), pbstrResult
);
3053 len
= GetFullPathNameW(path
, MAX_PATH
, buf
, NULL
);
3057 buf
[0] = toupperW(buf
[0]);
3058 if(len
>3 && buf
[len
-1] == '\\')
3061 for(beg
=3, i
=3; i
<=len
; i
++) {
3062 if(buf
[i
]!='\\' && buf
[i
])
3067 fh
= FindFirstFileW(buf
, &fdata
);
3068 if(fh
== INVALID_HANDLE_VALUE
)
3071 exp_len
= strlenW(fdata
.cFileName
);
3072 if(exp_len
== i
-beg
)
3073 memcpy(buf
+beg
, fdata
.cFileName
, exp_len
*sizeof(WCHAR
));
3079 *pbstrResult
= SysAllocString(buf
);
3081 return E_OUTOFMEMORY
;
3085 static HRESULT WINAPI
filesys_GetTempName(IFileSystem3
*iface
, BSTR
*pbstrResult
)
3087 static const WCHAR fmt
[] = {'r','a','d','%','0','5','X','.','t','x','t',0};
3091 TRACE("%p %p\n", iface
, pbstrResult
);
3096 *pbstrResult
= SysAllocStringLen(NULL
, 12);
3098 return E_OUTOFMEMORY
;
3100 if(!RtlGenRandom(&random
, sizeof(random
)))
3102 sprintfW(*pbstrResult
, fmt
, random
& 0xfffff);
3106 static HRESULT WINAPI
filesys_DriveExists(IFileSystem3
*iface
, BSTR DriveSpec
,
3107 VARIANT_BOOL
*pfExists
)
3109 FIXME("%p %s %p\n", iface
, debugstr_w(DriveSpec
), pfExists
);
3114 static HRESULT WINAPI
filesys_FileExists(IFileSystem3
*iface
, BSTR path
, VARIANT_BOOL
*ret
)
3117 TRACE("%p %s %p\n", iface
, debugstr_w(path
), ret
);
3119 if (!ret
) return E_POINTER
;
3121 attrs
= GetFileAttributesW(path
);
3122 *ret
= attrs
!= INVALID_FILE_ATTRIBUTES
&& !(attrs
& FILE_ATTRIBUTE_DIRECTORY
) ? VARIANT_TRUE
: VARIANT_FALSE
;