/*
 * Copyright 2012 Alistair Leslie-Hughes
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include "config.h"
#include <stdarg.h>
#include <limits.h>

#include "windef.h"
#include "winbase.h"
#include "ole2.h"
#include "olectl.h"
#include "dispex.h"
#include "ntsecapi.h"
#include "scrrun.h"
#include "scrrun_private.h"

#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(scrrun);

static const WCHAR bsW[] = {'\\',0};
static const WCHAR utf16bom = 0xfeff;

struct foldercollection {
    IFolderCollection IFolderCollection_iface;
    LONG ref;
    BSTR path;
};

struct filecollection {
    IFileCollection IFileCollection_iface;
    LONG ref;
    BSTR path;
};

struct drivecollection {
    IDriveCollection IDriveCollection_iface;
    LONG ref;
    DWORD drives;
    LONG count;
};

struct enumdata {
    union
    {
        struct
        {
            struct foldercollection *coll;
            HANDLE find;
        } foldercoll;
        struct
        {
            struct filecollection *coll;
            HANDLE find;
        } filecoll;
        struct
        {
            struct drivecollection *coll;
            INT cur;
        } drivecoll;
    } u;
};

struct enumvariant {
    IEnumVARIANT IEnumVARIANT_iface;
    LONG ref;

    struct enumdata data;
};

struct drive {
    IDrive IDrive_iface;
    LONG ref;
    BSTR root;
};

struct folder {
    IFolder IFolder_iface;
    LONG ref;
    BSTR path;
};

struct file {
    IFile IFile_iface;
    LONG ref;

    WCHAR *path;
};

struct textstream {
    ITextStream ITextStream_iface;
    LONG ref;

    IOMode mode;
    BOOL unicode;
    BOOL first_read;
    LARGE_INTEGER size;
    HANDLE file;
};

enum iotype {
    IORead,
    IOWrite
};

static inline struct drive *impl_from_IDrive(IDrive *iface)
{
    return CONTAINING_RECORD(iface, struct drive, IDrive_iface);
}

static inline struct folder *impl_from_IFolder(IFolder *iface)
{
    return CONTAINING_RECORD(iface, struct folder, IFolder_iface);
}

static inline struct file *impl_from_IFile(IFile *iface)
{
    return CONTAINING_RECORD(iface, struct file, IFile_iface);
}

static inline struct textstream *impl_from_ITextStream(ITextStream *iface)
{
    return CONTAINING_RECORD(iface, struct textstream, ITextStream_iface);
}

static inline struct foldercollection *impl_from_IFolderCollection(IFolderCollection *iface)
{
    return CONTAINING_RECORD(iface, struct foldercollection, IFolderCollection_iface);
}

static inline struct filecollection *impl_from_IFileCollection(IFileCollection *iface)
{
    return CONTAINING_RECORD(iface, struct filecollection, IFileCollection_iface);
}

static inline struct drivecollection *impl_from_IDriveCollection(IDriveCollection *iface)
{
    return CONTAINING_RECORD(iface, struct drivecollection, IDriveCollection_iface);
}

static inline struct enumvariant *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
{
    return CONTAINING_RECORD(iface, struct enumvariant, IEnumVARIANT_iface);
}

static inline HRESULT create_error(DWORD err)
{
    switch(err) {
    case ERROR_FILE_NOT_FOUND: return CTL_E_FILENOTFOUND;
    case ERROR_PATH_NOT_FOUND: return CTL_E_PATHNOTFOUND;
    case ERROR_ACCESS_DENIED: return CTL_E_PERMISSIONDENIED;
    case ERROR_FILE_EXISTS: return CTL_E_FILEALREADYEXISTS;
    case ERROR_ALREADY_EXISTS: return CTL_E_FILEALREADYEXISTS;
    default:
        FIXME("Unsupported error code: %d\n", err);
        return E_FAIL;
    }
}

static HRESULT create_folder(const WCHAR*, IFolder**);
static HRESULT create_file(BSTR, IFile**);
static HRESULT create_foldercoll_enum(struct foldercollection*, IUnknown**);
static HRESULT create_filecoll_enum(struct filecollection*, IUnknown**);

static inline BOOL is_dir_data(const WIN32_FIND_DATAW *data)
{
    static const WCHAR dotdotW[] = {'.','.',0};
    static const WCHAR dotW[] = {'.',0};

    return (data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
            strcmpW(data->cFileName, dotdotW) &&
            strcmpW(data->cFileName, dotW);
}

static inline BOOL is_file_data(const WIN32_FIND_DATAW *data)
{
    return !(data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}

static BSTR get_full_path(BSTR path, const WIN32_FIND_DATAW *data)
{
    int len = SysStringLen(path);
    WCHAR buffW[MAX_PATH];

    strcpyW(buffW, path);
    if (path[len-1] != '\\')
        strcatW(buffW, bsW);
    strcatW(buffW, data->cFileName);

    return SysAllocString(buffW);
}

static BOOL textstream_check_iomode(struct textstream *This, enum iotype type)
{
    if (type == IORead)
        return This->mode == ForWriting || This->mode == ForAppending;
    else
        return This->mode == ForReading;
}

static HRESULT WINAPI textstream_QueryInterface(ITextStream *iface, REFIID riid, void **obj)
{
    struct textstream *This = impl_from_ITextStream(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    if (IsEqualIID(riid, &IID_ITextStream) ||
        IsEqualIID(riid, &IID_IDispatch) ||
        IsEqualIID(riid, &IID_IUnknown))
    {
        *obj = iface;
        ITextStream_AddRef(iface);
        return S_OK;
    }

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI textstream_AddRef(ITextStream *iface)
{
    struct textstream *This = impl_from_ITextStream(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI textstream_Release(ITextStream *iface)
{
    struct textstream *This = impl_from_ITextStream(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        CloseHandle(This->file);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI textstream_GetTypeInfoCount(ITextStream *iface, UINT *pctinfo)
{
    struct textstream *This = impl_from_ITextStream(iface);
    TRACE("(%p)->(%p)\n", This, pctinfo);
    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI textstream_GetTypeInfo(ITextStream *iface, UINT iTInfo,
                                        LCID lcid, ITypeInfo **ppTInfo)
{
    struct textstream *This = impl_from_ITextStream(iface);
    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return get_typeinfo(ITextStream_tid, ppTInfo);
}

static HRESULT WINAPI textstream_GetIDsOfNames(ITextStream *iface, REFIID riid,
                                        LPOLESTR *rgszNames, UINT cNames,
                                        LCID lcid, DISPID *rgDispId)
{
    struct textstream *This = impl_from_ITextStream(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(ITextStream_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI textstream_Invoke(ITextStream *iface, DISPID dispIdMember,
                                      REFIID riid, LCID lcid, WORD wFlags,
                                      DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                      EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    struct textstream *This = impl_from_ITextStream(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(ITextStream_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI textstream_get_Line(ITextStream *iface, LONG *line)
{
    struct textstream *This = impl_from_ITextStream(iface);
    FIXME("(%p)->(%p): stub\n", This, line);
    return E_NOTIMPL;
}

static HRESULT WINAPI textstream_get_Column(ITextStream *iface, LONG *column)
{
    struct textstream *This = impl_from_ITextStream(iface);
    FIXME("(%p)->(%p): stub\n", This, column);
    return E_NOTIMPL;
}

static HRESULT WINAPI textstream_get_AtEndOfStream(ITextStream *iface, VARIANT_BOOL *eos)
{
    struct textstream *This = impl_from_ITextStream(iface);
    LARGE_INTEGER pos, dist;

    TRACE("(%p)->(%p)\n", This, eos);

    if (!eos)
        return E_POINTER;

    if (textstream_check_iomode(This, IORead)) {
        *eos = VARIANT_TRUE;
        return CTL_E_BADFILEMODE;
    }

    dist.QuadPart = 0;
    if (!SetFilePointerEx(This->file, dist, &pos, FILE_CURRENT))
        return E_FAIL;

    *eos = This->size.QuadPart == pos.QuadPart ? VARIANT_TRUE : VARIANT_FALSE;
    return S_OK;
}

static HRESULT WINAPI textstream_get_AtEndOfLine(ITextStream *iface, VARIANT_BOOL *eol)
{
    struct textstream *This = impl_from_ITextStream(iface);
    FIXME("(%p)->(%p): stub\n", This, eol);
    return E_NOTIMPL;
}

/*
   Reads 'toread' bytes from a file, converts if needed
   BOM is skipped if 'bof' is set.
 */
static HRESULT textstream_read(struct textstream *stream, LONG toread, BOOL bof, BSTR *text)
{
    HRESULT hr = S_OK;
    DWORD read;
    char *buff;
    BOOL ret;

    if (toread == 0) {
        *text = SysAllocStringLen(NULL, 0);
        return *text ? S_FALSE : E_OUTOFMEMORY;
    }

    if (toread < sizeof(WCHAR))
        return CTL_E_ENDOFFILE;

    buff = heap_alloc(toread);
    if (!buff)
        return E_OUTOFMEMORY;

    ret = ReadFile(stream->file, buff, toread, &read, NULL);
    if (!ret || toread != read) {
        WARN("failed to read from file %d, %d, error %d\n", read, toread, GetLastError());
        heap_free(buff);
        return E_FAIL;
    }

    if (stream->unicode) {
        int i = 0;

        /* skip BOM */
        if (bof && *(WCHAR*)buff == utf16bom) {
            read -= sizeof(WCHAR);
            i += sizeof(WCHAR);
        }

        *text = SysAllocStringLen(read ? (WCHAR*)&buff[i] : NULL, read/sizeof(WCHAR));
        if (!*text) hr = E_OUTOFMEMORY;
    }
    else {
        INT len = MultiByteToWideChar(CP_ACP, 0, buff, read, NULL, 0);
        *text = SysAllocStringLen(NULL, len);
        if (*text)
            MultiByteToWideChar(CP_ACP, 0, buff, read, *text, len);
        else
            hr = E_OUTOFMEMORY;
    }
    heap_free(buff);

    return hr;
}

static HRESULT WINAPI textstream_Read(ITextStream *iface, LONG len, BSTR *text)
{
    struct textstream *This = impl_from_ITextStream(iface);
    LARGE_INTEGER start, end, dist;
    DWORD toread;
    HRESULT hr;

    TRACE("(%p)->(%d %p)\n", This, len, text);

    if (!text)
        return E_POINTER;

    *text = NULL;
    if (len <= 0)
        return len == 0 ? S_OK : E_INVALIDARG;

    if (textstream_check_iomode(This, IORead))
        return CTL_E_BADFILEMODE;

    if (!This->first_read) {
        VARIANT_BOOL eos;

        /* check for EOF */
        hr = ITextStream_get_AtEndOfStream(iface, &eos);
        if (FAILED(hr))
            return hr;

        if (eos == VARIANT_TRUE)
            return CTL_E_ENDOFFILE;
    }

    /* read everything from current position */
    dist.QuadPart = 0;
    SetFilePointerEx(This->file, dist, &start, FILE_CURRENT);
    SetFilePointerEx(This->file, dist, &end, FILE_END);
    toread = end.QuadPart - start.QuadPart;
    /* rewind back */
    dist.QuadPart = start.QuadPart;
    SetFilePointerEx(This->file, dist, NULL, FILE_BEGIN);

    This->first_read = FALSE;
    if (This->unicode) len *= sizeof(WCHAR);

    hr = textstream_read(This, min(toread, len), start.QuadPart == 0, text);
    if (FAILED(hr))
        return hr;
    else
        return toread <= len ? S_FALSE : S_OK;
}

static HRESULT WINAPI textstream_ReadLine(ITextStream *iface, BSTR *text)
{
    struct textstream *This = impl_from_ITextStream(iface);
    VARIANT_BOOL eos;
    HRESULT hr;

    FIXME("(%p)->(%p): stub\n", This, text);

    if (!text)
        return E_POINTER;

    *text = NULL;
    if (textstream_check_iomode(This, IORead))
        return CTL_E_BADFILEMODE;

    /* check for EOF */
    hr = ITextStream_get_AtEndOfStream(iface, &eos);
    if (FAILED(hr))
        return hr;

    if (eos == VARIANT_TRUE)
        return CTL_E_ENDOFFILE;

    return E_NOTIMPL;
}

static HRESULT WINAPI textstream_ReadAll(ITextStream *iface, BSTR *text)
{
    struct textstream *This = impl_from_ITextStream(iface);
    LARGE_INTEGER start, end, dist;
    DWORD toread;
    HRESULT hr;

    TRACE("(%p)->(%p)\n", This, text);

    if (!text)
        return E_POINTER;

    *text = NULL;
    if (textstream_check_iomode(This, IORead))
        return CTL_E_BADFILEMODE;

    if (!This->first_read) {
        VARIANT_BOOL eos;

        /* check for EOF */
        hr = ITextStream_get_AtEndOfStream(iface, &eos);
        if (FAILED(hr))
            return hr;

        if (eos == VARIANT_TRUE)
            return CTL_E_ENDOFFILE;
    }

    /* read everything from current position */
    dist.QuadPart = 0;
    SetFilePointerEx(This->file, dist, &start, FILE_CURRENT);
    SetFilePointerEx(This->file, dist, &end, FILE_END);
    toread = end.QuadPart - start.QuadPart;
    /* rewind back */
    dist.QuadPart = start.QuadPart;
    SetFilePointerEx(This->file, dist, NULL, FILE_BEGIN);

    This->first_read = FALSE;

    hr = textstream_read(This, toread, start.QuadPart == 0, text);
    return FAILED(hr) ? hr : S_FALSE;
}

static HRESULT textstream_writestr(struct textstream *stream, BSTR text)
{
    DWORD written = 0;
    BOOL ret;

    if (stream->unicode) {
        ret = WriteFile(stream->file, text, SysStringByteLen(text), &written, NULL);
        return (ret && written == SysStringByteLen(text)) ? S_OK : create_error(GetLastError());
    } else {
        DWORD len = WideCharToMultiByte(CP_ACP, 0, text, SysStringLen(text), NULL, 0, NULL, NULL);
        char *buffA;
        HRESULT hr;

        buffA = heap_alloc(len);
        if (!buffA)
            return E_OUTOFMEMORY;

        WideCharToMultiByte(CP_ACP, 0, text, SysStringLen(text), buffA, len, NULL, NULL);
        ret = WriteFile(stream->file, buffA, len, &written, NULL);
        hr = (ret && written == len) ? S_OK : create_error(GetLastError());
        heap_free(buffA);
        return hr;
    }
}

static HRESULT WINAPI textstream_Write(ITextStream *iface, BSTR text)
{
    struct textstream *This = impl_from_ITextStream(iface);

    TRACE("(%p)->(%s)\n", This, debugstr_w(text));

    if (textstream_check_iomode(This, IOWrite))
        return CTL_E_BADFILEMODE;

    return textstream_writestr(This, text);
}

static HRESULT textstream_writecrlf(struct textstream *stream)
{
    static const WCHAR crlfW[] = {'\r','\n'};
    static const char crlfA[] = {'\r','\n'};
    DWORD written = 0, len;
    const void *ptr;
    BOOL ret;

    if (stream->unicode) {
        ptr = crlfW;
        len = sizeof(crlfW);
    }
    else {
        ptr = crlfA;
        len = sizeof(crlfA);
    }

    ret = WriteFile(stream->file, ptr, len, &written, NULL);
    return (ret && written == len) ? S_OK : create_error(GetLastError());
}

static HRESULT WINAPI textstream_WriteLine(ITextStream *iface, BSTR text)
{
    struct textstream *This = impl_from_ITextStream(iface);
    HRESULT hr;

    TRACE("(%p)->(%s)\n", This, debugstr_w(text));

    if (textstream_check_iomode(This, IOWrite))
        return CTL_E_BADFILEMODE;

    hr = textstream_writestr(This, text);
    if (SUCCEEDED(hr))
        hr = textstream_writecrlf(This);
    return hr;
}

static HRESULT WINAPI textstream_WriteBlankLines(ITextStream *iface, LONG lines)
{
    struct textstream *This = impl_from_ITextStream(iface);
    FIXME("(%p)->(%d): stub\n", This, lines);
    return E_NOTIMPL;
}

static HRESULT WINAPI textstream_Skip(ITextStream *iface, LONG count)
{
    struct textstream *This = impl_from_ITextStream(iface);
    FIXME("(%p)->(%d): stub\n", This, count);
    return E_NOTIMPL;
}

static HRESULT WINAPI textstream_SkipLine(ITextStream *iface)
{
    struct textstream *This = impl_from_ITextStream(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI textstream_Close(ITextStream *iface)
{
    struct textstream *This = impl_from_ITextStream(iface);
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static const ITextStreamVtbl textstreamvtbl = {
    textstream_QueryInterface,
    textstream_AddRef,
    textstream_Release,
    textstream_GetTypeInfoCount,
    textstream_GetTypeInfo,
    textstream_GetIDsOfNames,
    textstream_Invoke,
    textstream_get_Line,
    textstream_get_Column,
    textstream_get_AtEndOfStream,
    textstream_get_AtEndOfLine,
    textstream_Read,
    textstream_ReadLine,
    textstream_ReadAll,
    textstream_Write,
    textstream_WriteLine,
    textstream_WriteBlankLines,
    textstream_Skip,
    textstream_SkipLine,
    textstream_Close
};

static HRESULT create_textstream(const WCHAR *filename, DWORD disposition, IOMode mode, BOOL unicode, ITextStream **ret)
{
    struct textstream *stream;
    DWORD access = 0;

    /* map access mode */
    switch (mode)
    {
    case ForReading:
        access = GENERIC_READ;
        break;
    case ForWriting:
        access = GENERIC_WRITE;
        break;
    case ForAppending:
        access = FILE_APPEND_DATA;
        break;
    default:
        return E_INVALIDARG;
    }

    stream = heap_alloc(sizeof(struct textstream));
    if (!stream) return E_OUTOFMEMORY;

    stream->ITextStream_iface.lpVtbl = &textstreamvtbl;
    stream->ref = 1;
    stream->mode = mode;
    stream->unicode = unicode;
    stream->first_read = TRUE;

    stream->file = CreateFileW(filename, access, 0, NULL, disposition, FILE_ATTRIBUTE_NORMAL, NULL);
    if (stream->file == INVALID_HANDLE_VALUE)
    {
        HRESULT hr = create_error(GetLastError());
        heap_free(stream);
        return hr;
    }

    if (mode == ForReading)
        GetFileSizeEx(stream->file, &stream->size);
    else
        stream->size.QuadPart = 0;

    /* Write Unicode BOM */
    if (unicode && mode == ForWriting && (disposition == CREATE_ALWAYS || disposition == CREATE_NEW)) {
        DWORD written = 0;
        BOOL ret = WriteFile(stream->file, &utf16bom, sizeof(utf16bom), &written, NULL);
        if (!ret || written != sizeof(utf16bom)) {
            ITextStream_Release(&stream->ITextStream_iface);
            return create_error(GetLastError());
        }
    }

    *ret = &stream->ITextStream_iface;
    return S_OK;
}

static HRESULT WINAPI drive_QueryInterface(IDrive *iface, REFIID riid, void **obj)
{
    struct drive *This = impl_from_IDrive(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID( riid, &IID_IDrive ) ||
        IsEqualIID( riid, &IID_IDispatch ) ||
        IsEqualIID( riid, &IID_IUnknown))
    {
        *obj = iface;
        IDrive_AddRef(iface);
    }
    else
        return E_NOINTERFACE;

    return S_OK;
}

static ULONG WINAPI drive_AddRef(IDrive *iface)
{
    struct drive *This = impl_from_IDrive(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI drive_Release(IDrive *iface)
{
    struct drive *This = impl_from_IDrive(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        SysFreeString(This->root);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI drive_GetTypeInfoCount(IDrive *iface, UINT *pctinfo)
{
    struct drive *This = impl_from_IDrive(iface);
    TRACE("(%p)->(%p)\n", This, pctinfo);
    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI drive_GetTypeInfo(IDrive *iface, UINT iTInfo,
                                        LCID lcid, ITypeInfo **ppTInfo)
{
    struct drive *This = impl_from_IDrive(iface);
    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return get_typeinfo(IDrive_tid, ppTInfo);
}

static HRESULT WINAPI drive_GetIDsOfNames(IDrive *iface, REFIID riid,
                                        LPOLESTR *rgszNames, UINT cNames,
                                        LCID lcid, DISPID *rgDispId)
{
    struct drive *This = impl_from_IDrive(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(IDrive_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI drive_Invoke(IDrive *iface, DISPID dispIdMember,
                                      REFIID riid, LCID lcid, WORD wFlags,
                                      DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                      EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    struct drive *This = impl_from_IDrive(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IDrive_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI drive_get_Path(IDrive *iface, BSTR *path)
{
    struct drive *This = impl_from_IDrive(iface);
    FIXME("(%p)->(%p): stub\n", This, path);
    return E_NOTIMPL;
}

static HRESULT WINAPI drive_get_DriveLetter(IDrive *iface, BSTR *letter)
{
    struct drive *This = impl_from_IDrive(iface);

    TRACE("(%p)->(%p)\n", This, letter);

    if (!letter)
        return E_POINTER;

    *letter = SysAllocStringLen(This->root, 1);
    if (!*letter)
        return E_OUTOFMEMORY;

    return S_OK;
}

static HRESULT WINAPI drive_get_ShareName(IDrive *iface, BSTR *share_name)
{
    struct drive *This = impl_from_IDrive(iface);
    FIXME("(%p)->(%p): stub\n", This, share_name);
    return E_NOTIMPL;
}

static HRESULT WINAPI drive_get_DriveType(IDrive *iface, DriveTypeConst *type)
{
    struct drive *This = impl_from_IDrive(iface);

    TRACE("(%p)->(%p)\n", This, type);

    switch (GetDriveTypeW(This->root))
    {
    case DRIVE_REMOVABLE:
        *type = Removable;
        break;
    case DRIVE_FIXED:
        *type = Fixed;
        break;
    case DRIVE_REMOTE:
        *type = Remote;
        break;
    case DRIVE_CDROM:
        *type = CDRom;
        break;
    case DRIVE_RAMDISK:
        *type = RamDisk;
        break;
    default:
        *type = UnknownType;
        break;
    }

    return S_OK;
}

static HRESULT WINAPI drive_get_RootFolder(IDrive *iface, IFolder **folder)
{
    struct drive *This = impl_from_IDrive(iface);
    FIXME("(%p)->(%p): stub\n", This, folder);
    return E_NOTIMPL;
}

static HRESULT variant_from_largeint(const ULARGE_INTEGER *src, VARIANT *v)
{
    HRESULT hr = S_OK;

    if (src->u.HighPart || src->u.LowPart > INT_MAX)
    {
        V_VT(v) = VT_R8;
        hr = VarR8FromUI8(src->QuadPart, &V_R8(v));
    }
    else
    {
        V_VT(v) = VT_I4;
        V_I4(v) = src->u.LowPart;
    }

    return hr;
}

static HRESULT WINAPI drive_get_AvailableSpace(IDrive *iface, VARIANT *v)
{
    struct drive *This = impl_from_IDrive(iface);
    ULARGE_INTEGER avail;

    TRACE("(%p)->(%p)\n", This, v);

    if (!v)
        return E_POINTER;

    if (!GetDiskFreeSpaceExW(This->root, &avail, NULL, NULL))
        return E_FAIL;

    return variant_from_largeint(&avail, v);
}

static HRESULT WINAPI drive_get_FreeSpace(IDrive *iface, VARIANT *v)
{
    struct drive *This = impl_from_IDrive(iface);
    ULARGE_INTEGER freespace;

    TRACE("(%p)->(%p)\n", This, v);

    if (!v)
        return E_POINTER;

    if (!GetDiskFreeSpaceExW(This->root, &freespace, NULL, NULL))
        return E_FAIL;

    return variant_from_largeint(&freespace, v);
}

static HRESULT WINAPI drive_get_TotalSize(IDrive *iface, VARIANT *v)
{
    struct drive *This = impl_from_IDrive(iface);
    ULARGE_INTEGER total;

    TRACE("(%p)->(%p)\n", This, v);

    if (!v)
        return E_POINTER;

    if (!GetDiskFreeSpaceExW(This->root, NULL, &total, NULL))
        return E_FAIL;

    return variant_from_largeint(&total, v);
}

static HRESULT WINAPI drive_get_VolumeName(IDrive *iface, BSTR *name)
{
    struct drive *This = impl_from_IDrive(iface);
    WCHAR nameW[MAX_PATH+1];
    BOOL ret;

    TRACE("(%p)->(%p)\n", This, name);

    if (!name)
        return E_POINTER;

    *name = NULL;
    ret = GetVolumeInformationW(This->root, nameW, sizeof(nameW)/sizeof(WCHAR), NULL, NULL, NULL, NULL, 0);
    if (ret)
        *name = SysAllocString(nameW);
    return ret ? S_OK : E_FAIL;
}

static HRESULT WINAPI drive_put_VolumeName(IDrive *iface, BSTR name)
{
    struct drive *This = impl_from_IDrive(iface);
    FIXME("(%p)->(%s): stub\n", This, debugstr_w(name));
    return E_NOTIMPL;
}

static HRESULT WINAPI drive_get_FileSystem(IDrive *iface, BSTR *fs)
{
    struct drive *This = impl_from_IDrive(iface);
    WCHAR nameW[MAX_PATH+1];
    BOOL ret;

    TRACE("(%p)->(%p)\n", This, fs);

    if (!fs)
        return E_POINTER;

    *fs = NULL;
    ret = GetVolumeInformationW(This->root, NULL, 0, NULL, NULL, NULL, nameW, sizeof(nameW)/sizeof(WCHAR));
    if (ret)
        *fs = SysAllocString(nameW);
    return ret ? S_OK : E_FAIL;
}

static HRESULT WINAPI drive_get_SerialNumber(IDrive *iface, LONG *serial)
{
    struct drive *This = impl_from_IDrive(iface);
    BOOL ret;

    TRACE("(%p)->(%p)\n", This, serial);

    if (!serial)
        return E_POINTER;

    ret = GetVolumeInformationW(This->root, NULL, 0, (DWORD*)serial, NULL, NULL, NULL, 0);
    return ret ? S_OK : E_FAIL;
}

static HRESULT WINAPI drive_get_IsReady(IDrive *iface, VARIANT_BOOL *ready)
{
    struct drive *This = impl_from_IDrive(iface);
    ULARGE_INTEGER freespace;
    BOOL ret;

    TRACE("(%p)->(%p)\n", This, ready);

    if (!ready)
        return E_POINTER;

    ret = GetDiskFreeSpaceExW(This->root, &freespace, NULL, NULL);
    *ready = ret ? VARIANT_TRUE : VARIANT_FALSE;
    return S_OK;
}

static const IDriveVtbl drivevtbl = {
    drive_QueryInterface,
    drive_AddRef,
    drive_Release,
    drive_GetTypeInfoCount,
    drive_GetTypeInfo,
    drive_GetIDsOfNames,
    drive_Invoke,
    drive_get_Path,
    drive_get_DriveLetter,
    drive_get_ShareName,
    drive_get_DriveType,
    drive_get_RootFolder,
    drive_get_AvailableSpace,
    drive_get_FreeSpace,
    drive_get_TotalSize,
    drive_get_VolumeName,
    drive_put_VolumeName,
    drive_get_FileSystem,
    drive_get_SerialNumber,
    drive_get_IsReady
};

static HRESULT create_drive(WCHAR letter, IDrive **drive)
{
    struct drive *This;

    *drive = NULL;

    This = heap_alloc(sizeof(*This));
    if (!This) return E_OUTOFMEMORY;

    This->IDrive_iface.lpVtbl = &drivevtbl;
    This->ref = 1;
    This->root = SysAllocStringLen(NULL, 3);
    if (!This->root)
    {
        heap_free(This);
        return E_OUTOFMEMORY;
    }
    This->root[0] = letter;
    This->root[1] = ':';
    This->root[2] = '\\';
    This->root[3] = 0;

    *drive = &This->IDrive_iface;
    return S_OK;
}

static HRESULT WINAPI enumvariant_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **obj)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID( riid, &IID_IEnumVARIANT ) ||
        IsEqualIID( riid, &IID_IUnknown ))
    {
        *obj = iface;
        IEnumVARIANT_AddRef(iface);
    }
    else
        return E_NOINTERFACE;

    return S_OK;
}

static ULONG WINAPI enumvariant_AddRef(IEnumVARIANT *iface)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI foldercoll_enumvariant_Release(IEnumVARIANT *iface)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        IFolderCollection_Release(&This->data.u.foldercoll.coll->IFolderCollection_iface);
        FindClose(This->data.u.foldercoll.find);
        heap_free(This);
    }

    return ref;
}

static HANDLE start_enumeration(const WCHAR *path, WIN32_FIND_DATAW *data, BOOL file)
{
    static const WCHAR allW[] = {'*',0};
    WCHAR pathW[MAX_PATH];
    int len;
    HANDLE handle;

    strcpyW(pathW, path);
    len = strlenW(pathW);
    if (len && pathW[len-1] != '\\')
        strcatW(pathW, bsW);
    strcatW(pathW, allW);
    handle = FindFirstFileW(pathW, data);
    if (handle == INVALID_HANDLE_VALUE) return 0;

    /* find first dir/file */
    while (1)
    {
        if (file ? is_file_data(data) : is_dir_data(data))
            break;

        if (!FindNextFileW(handle, data))
        {
            FindClose(handle);
            return 0;
        }
    }
    return handle;
}

static HRESULT WINAPI foldercoll_enumvariant_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    HANDLE handle = This->data.u.foldercoll.find;
    WIN32_FIND_DATAW data;
    ULONG count = 0;

    TRACE("(%p)->(%d %p %p)\n", This, celt, var, fetched);

    if (fetched)
        *fetched = 0;

    if (!celt) return S_OK;

    if (!handle)
    {
        handle = start_enumeration(This->data.u.foldercoll.coll->path, &data, FALSE);
        if (!handle) return S_FALSE;

        This->data.u.foldercoll.find = handle;
    }
    else
    {
        if (!FindNextFileW(handle, &data))
            return S_FALSE;
    }

    do
    {
        if (is_dir_data(&data))
        {
            IFolder *folder;
            HRESULT hr;
            BSTR str;

            str = get_full_path(This->data.u.foldercoll.coll->path, &data);
            hr = create_folder(str, &folder);
            SysFreeString(str);
            if (FAILED(hr)) return hr;

            V_VT(&var[count]) = VT_DISPATCH;
            V_DISPATCH(&var[count]) = (IDispatch*)folder;
            count++;

            if (count >= celt) break;
        }
    } while (FindNextFileW(handle, &data));

    if (fetched)
        *fetched = count;

    return (count < celt) ? S_FALSE : S_OK;
}

static HRESULT WINAPI foldercoll_enumvariant_Skip(IEnumVARIANT *iface, ULONG celt)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    HANDLE handle = This->data.u.foldercoll.find;
    WIN32_FIND_DATAW data;

    TRACE("(%p)->(%d)\n", This, celt);

    if (!celt) return S_OK;

    if (!handle)
    {
        handle = start_enumeration(This->data.u.foldercoll.coll->path, &data, FALSE);
        if (!handle) return S_FALSE;

        This->data.u.foldercoll.find = handle;
    }
    else
    {
        if (!FindNextFileW(handle, &data))
            return S_FALSE;
    }

    do
    {
        if (is_dir_data(&data))
            --celt;

        if (!celt) break;
    } while (FindNextFileW(handle, &data));

    return celt ? S_FALSE : S_OK;
}

static HRESULT WINAPI foldercoll_enumvariant_Reset(IEnumVARIANT *iface)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);

    TRACE("(%p)\n", This);

    FindClose(This->data.u.foldercoll.find);
    This->data.u.foldercoll.find = NULL;

    return S_OK;
}

static HRESULT WINAPI foldercoll_enumvariant_Clone(IEnumVARIANT *iface, IEnumVARIANT **pclone)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    TRACE("(%p)->(%p)\n", This, pclone);
    return create_foldercoll_enum(This->data.u.foldercoll.coll, (IUnknown**)pclone);
}

static const IEnumVARIANTVtbl foldercollenumvariantvtbl = {
    enumvariant_QueryInterface,
    enumvariant_AddRef,
    foldercoll_enumvariant_Release,
    foldercoll_enumvariant_Next,
    foldercoll_enumvariant_Skip,
    foldercoll_enumvariant_Reset,
    foldercoll_enumvariant_Clone
};

static HRESULT create_foldercoll_enum(struct foldercollection *collection, IUnknown **newenum)
{
    struct enumvariant *This;

    *newenum = NULL;

    This = heap_alloc(sizeof(*This));
    if (!This) return E_OUTOFMEMORY;

    This->IEnumVARIANT_iface.lpVtbl = &foldercollenumvariantvtbl;
    This->ref = 1;
    This->data.u.foldercoll.find = NULL;
    This->data.u.foldercoll.coll = collection;
    IFolderCollection_AddRef(&collection->IFolderCollection_iface);

    *newenum = (IUnknown*)&This->IEnumVARIANT_iface;

    return S_OK;
}

static ULONG WINAPI filecoll_enumvariant_Release(IEnumVARIANT *iface)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        IFileCollection_Release(&This->data.u.filecoll.coll->IFileCollection_iface);
        FindClose(This->data.u.filecoll.find);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI filecoll_enumvariant_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    HANDLE handle = This->data.u.filecoll.find;
    WIN32_FIND_DATAW data;
    ULONG count = 0;

    TRACE("(%p)->(%d %p %p)\n", This, celt, var, fetched);

    if (fetched)
        *fetched = 0;

    if (!celt) return S_OK;

    if (!handle)
    {
        handle = start_enumeration(This->data.u.filecoll.coll->path, &data, TRUE);
        if (!handle) return S_FALSE;
        This->data.u.filecoll.find = handle;
    }
    else if (!FindNextFileW(handle, &data))
        return S_FALSE;

    do
    {
        if (is_file_data(&data))
        {
            IFile *file;
            HRESULT hr;
            BSTR str;

            str = get_full_path(This->data.u.filecoll.coll->path, &data);
            hr = create_file(str, &file);
            SysFreeString(str);
            if (FAILED(hr)) return hr;

            V_VT(&var[count]) = VT_DISPATCH;
            V_DISPATCH(&var[count]) = (IDispatch*)file;
            if (++count >= celt) break;
        }
    } while (FindNextFileW(handle, &data));

    if (fetched)
        *fetched = count;

    return (count < celt) ? S_FALSE : S_OK;
}

static HRESULT WINAPI filecoll_enumvariant_Skip(IEnumVARIANT *iface, ULONG celt)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    HANDLE handle = This->data.u.filecoll.find;
    WIN32_FIND_DATAW data;

    TRACE("(%p)->(%d)\n", This, celt);

    if (!celt) return S_OK;

    if (!handle)
    {
        handle = start_enumeration(This->data.u.filecoll.coll->path, &data, TRUE);
        if (!handle) return S_FALSE;
        This->data.u.filecoll.find = handle;
    }
    else if (!FindNextFileW(handle, &data))
        return S_FALSE;

    do
    {
        if (is_file_data(&data))
            --celt;
    } while (celt && FindNextFileW(handle, &data));

    return celt ? S_FALSE : S_OK;
}

static HRESULT WINAPI filecoll_enumvariant_Reset(IEnumVARIANT *iface)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);

    TRACE("(%p)\n", This);

    FindClose(This->data.u.filecoll.find);
    This->data.u.filecoll.find = NULL;

    return S_OK;
}

static HRESULT WINAPI filecoll_enumvariant_Clone(IEnumVARIANT *iface, IEnumVARIANT **pclone)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    TRACE("(%p)->(%p)\n", This, pclone);
    return create_filecoll_enum(This->data.u.filecoll.coll, (IUnknown**)pclone);
}

static const IEnumVARIANTVtbl filecollenumvariantvtbl = {
    enumvariant_QueryInterface,
    enumvariant_AddRef,
    filecoll_enumvariant_Release,
    filecoll_enumvariant_Next,
    filecoll_enumvariant_Skip,
    filecoll_enumvariant_Reset,
    filecoll_enumvariant_Clone
};

static HRESULT create_filecoll_enum(struct filecollection *collection, IUnknown **newenum)
{
    struct enumvariant *This;

    *newenum = NULL;

    This = heap_alloc(sizeof(*This));
    if (!This) return E_OUTOFMEMORY;

    This->IEnumVARIANT_iface.lpVtbl = &filecollenumvariantvtbl;
    This->ref = 1;
    This->data.u.filecoll.find = NULL;
    This->data.u.filecoll.coll = collection;
    IFileCollection_AddRef(&collection->IFileCollection_iface);

    *newenum = (IUnknown*)&This->IEnumVARIANT_iface;

    return S_OK;
}

static ULONG WINAPI drivecoll_enumvariant_Release(IEnumVARIANT *iface)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        IDriveCollection_Release(&This->data.u.drivecoll.coll->IDriveCollection_iface);
        heap_free(This);
    }

    return ref;
}

static HRESULT find_next_drive(struct enumvariant *penum)
{
    int i = penum->data.u.drivecoll.cur == -1 ? 0 : penum->data.u.drivecoll.cur + 1;

    for (; i < 32; i++)
        if (penum->data.u.drivecoll.coll->drives & (1 << i))
        {
            penum->data.u.drivecoll.cur = i;
            return S_OK;
        }

    return S_FALSE;
}

static HRESULT WINAPI drivecoll_enumvariant_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    ULONG count = 0;

    TRACE("(%p)->(%d %p %p)\n", This, celt, var, fetched);

    if (fetched)
        *fetched = 0;

    if (!celt) return S_OK;

    while (find_next_drive(This) == S_OK)
    {
        IDrive *drive;
        HRESULT hr;

        hr = create_drive('A' + This->data.u.drivecoll.cur, &drive);
        if (FAILED(hr)) return hr;

        V_VT(&var[count]) = VT_DISPATCH;
        V_DISPATCH(&var[count]) = (IDispatch*)drive;

        if (++count >= celt) break;
    }

    if (fetched)
        *fetched = count;

    return (count < celt) ? S_FALSE : S_OK;
}

static HRESULT WINAPI drivecoll_enumvariant_Skip(IEnumVARIANT *iface, ULONG celt)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);

    TRACE("(%p)->(%d)\n", This, celt);

    if (!celt) return S_OK;

    while (celt && find_next_drive(This) == S_OK)
        celt--;

    return celt ? S_FALSE : S_OK;
}

static HRESULT WINAPI drivecoll_enumvariant_Reset(IEnumVARIANT *iface)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);

    TRACE("(%p)\n", This);

    This->data.u.drivecoll.cur = -1;
    return S_OK;
}

static HRESULT WINAPI drivecoll_enumvariant_Clone(IEnumVARIANT *iface, IEnumVARIANT **pclone)
{
    struct enumvariant *This = impl_from_IEnumVARIANT(iface);
    FIXME("(%p)->(%p): stub\n", This, pclone);
    return E_NOTIMPL;
}

static const IEnumVARIANTVtbl drivecollenumvariantvtbl = {
    enumvariant_QueryInterface,
    enumvariant_AddRef,
    drivecoll_enumvariant_Release,
    drivecoll_enumvariant_Next,
    drivecoll_enumvariant_Skip,
    drivecoll_enumvariant_Reset,
    drivecoll_enumvariant_Clone
};

static HRESULT create_drivecoll_enum(struct drivecollection *collection, IUnknown **newenum)
{
    struct enumvariant *This;

    *newenum = NULL;

    This = heap_alloc(sizeof(*This));
    if (!This) return E_OUTOFMEMORY;

    This->IEnumVARIANT_iface.lpVtbl = &drivecollenumvariantvtbl;
    This->ref = 1;
    This->data.u.drivecoll.coll = collection;
    This->data.u.drivecoll.cur = -1;
    IDriveCollection_AddRef(&collection->IDriveCollection_iface);

    *newenum = (IUnknown*)&This->IEnumVARIANT_iface;

    return S_OK;
}

static HRESULT WINAPI foldercoll_QueryInterface(IFolderCollection *iface, REFIID riid, void **obj)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID( riid, &IID_IFolderCollection ) ||
        IsEqualIID( riid, &IID_IDispatch ) ||
        IsEqualIID( riid, &IID_IUnknown ))
    {
        *obj = iface;
        IFolderCollection_AddRef(iface);
    }
    else
        return E_NOINTERFACE;

    return S_OK;
}

static ULONG WINAPI foldercoll_AddRef(IFolderCollection *iface)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI foldercoll_Release(IFolderCollection *iface)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        SysFreeString(This->path);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI foldercoll_GetTypeInfoCount(IFolderCollection *iface, UINT *pctinfo)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    TRACE("(%p)->(%p)\n", This, pctinfo);
    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI foldercoll_GetTypeInfo(IFolderCollection *iface, UINT iTInfo,
                                        LCID lcid, ITypeInfo **ppTInfo)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return get_typeinfo(IFolderCollection_tid, ppTInfo);
}

static HRESULT WINAPI foldercoll_GetIDsOfNames(IFolderCollection *iface, REFIID riid,
                                        LPOLESTR *rgszNames, UINT cNames,
                                        LCID lcid, DISPID *rgDispId)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(IFolderCollection_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI foldercoll_Invoke(IFolderCollection *iface, DISPID dispIdMember,
                                      REFIID riid, LCID lcid, WORD wFlags,
                                      DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                      EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IFolderCollection_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI foldercoll_Add(IFolderCollection *iface, BSTR name, IFolder **folder)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    FIXME("(%p)->(%s %p): stub\n", This, debugstr_w(name), folder);
    return E_NOTIMPL;
}

static HRESULT WINAPI foldercoll_get_Item(IFolderCollection *iface, VARIANT key, IFolder **folder)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    FIXME("(%p)->(%p): stub\n", This, folder);
    return E_NOTIMPL;
}

static HRESULT WINAPI foldercoll_get__NewEnum(IFolderCollection *iface, IUnknown **newenum)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);

    TRACE("(%p)->(%p)\n", This, newenum);

    if(!newenum)
        return E_POINTER;

    return create_foldercoll_enum(This, newenum);
}

static HRESULT WINAPI foldercoll_get_Count(IFolderCollection *iface, LONG *count)
{
    struct foldercollection *This = impl_from_IFolderCollection(iface);
    static const WCHAR allW[] = {'\\','*',0};
    WIN32_FIND_DATAW data;
    WCHAR pathW[MAX_PATH];
    HANDLE handle;

    TRACE("(%p)->(%p)\n", This, count);

    if(!count)
        return E_POINTER;

    *count = 0;

    strcpyW(pathW, This->path);
    strcatW(pathW, allW);
    handle = FindFirstFileW(pathW, &data);
    if (handle == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(GetLastError());

    do
    {
        if (is_dir_data(&data))
            *count += 1;
    } while (FindNextFileW(handle, &data));
    FindClose(handle);

    return S_OK;
}

static const IFolderCollectionVtbl foldercollvtbl = {
    foldercoll_QueryInterface,
    foldercoll_AddRef,
    foldercoll_Release,
    foldercoll_GetTypeInfoCount,
    foldercoll_GetTypeInfo,
    foldercoll_GetIDsOfNames,
    foldercoll_Invoke,
    foldercoll_Add,
    foldercoll_get_Item,
    foldercoll_get__NewEnum,
    foldercoll_get_Count
};

static HRESULT create_foldercoll(BSTR path, IFolderCollection **folders)
{
    struct foldercollection *This;

    *folders = NULL;

    This = heap_alloc(sizeof(struct foldercollection));
    if (!This) return E_OUTOFMEMORY;

    This->IFolderCollection_iface.lpVtbl = &foldercollvtbl;
    This->ref = 1;
    This->path = SysAllocString(path);
    if (!This->path)
    {
        heap_free(This);
        return E_OUTOFMEMORY;
    }

    *folders = &This->IFolderCollection_iface;

    return S_OK;
}

static HRESULT WINAPI filecoll_QueryInterface(IFileCollection *iface, REFIID riid, void **obj)
{
    struct filecollection *This = impl_from_IFileCollection(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID( riid, &IID_IFileCollection ) ||
        IsEqualIID( riid, &IID_IDispatch ) ||
        IsEqualIID( riid, &IID_IUnknown ))
    {
        *obj = iface;
        IFileCollection_AddRef(iface);
    }
    else
        return E_NOINTERFACE;

    return S_OK;
}

static ULONG WINAPI filecoll_AddRef(IFileCollection *iface)
{
    struct filecollection *This = impl_from_IFileCollection(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI filecoll_Release(IFileCollection *iface)
{
    struct filecollection *This = impl_from_IFileCollection(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        SysFreeString(This->path);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI filecoll_GetTypeInfoCount(IFileCollection *iface, UINT *pctinfo)
{
    struct filecollection *This = impl_from_IFileCollection(iface);
    TRACE("(%p)->(%p)\n", This, pctinfo);
    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI filecoll_GetTypeInfo(IFileCollection *iface, UINT iTInfo,
                                        LCID lcid, ITypeInfo **ppTInfo)
{
    struct filecollection *This = impl_from_IFileCollection(iface);
    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return get_typeinfo(IFileCollection_tid, ppTInfo);
}

static HRESULT WINAPI filecoll_GetIDsOfNames(IFileCollection *iface, REFIID riid,
                                        LPOLESTR *rgszNames, UINT cNames,
                                        LCID lcid, DISPID *rgDispId)
{
    struct filecollection *This = impl_from_IFileCollection(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(IFileCollection_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI filecoll_Invoke(IFileCollection *iface, DISPID dispIdMember,
                                      REFIID riid, LCID lcid, WORD wFlags,
                                      DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                      EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    struct filecollection *This = impl_from_IFileCollection(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IFileCollection_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI filecoll_get_Item(IFileCollection *iface, VARIANT Key, IFile **file)
{
    struct filecollection *This = impl_from_IFileCollection(iface);
    FIXME("(%p)->(%p)\n", This, file);
    return E_NOTIMPL;
}

static HRESULT WINAPI filecoll_get__NewEnum(IFileCollection *iface, IUnknown **ppenum)
{
    struct filecollection *This = impl_from_IFileCollection(iface);

    TRACE("(%p)->(%p)\n", This, ppenum);

    if(!ppenum)
        return E_POINTER;

    return create_filecoll_enum(This, ppenum);
}

static HRESULT WINAPI filecoll_get_Count(IFileCollection *iface, LONG *count)
{
    struct filecollection *This = impl_from_IFileCollection(iface);
    static const WCHAR allW[] = {'\\','*',0};
    WIN32_FIND_DATAW data;
    WCHAR pathW[MAX_PATH];
    HANDLE handle;

    TRACE("(%p)->(%p)\n", This, count);

    if(!count)
        return E_POINTER;

    *count = 0;

    strcpyW(pathW, This->path);
    strcatW(pathW, allW);
    handle = FindFirstFileW(pathW, &data);
    if (handle == INVALID_HANDLE_VALUE)
        return HRESULT_FROM_WIN32(GetLastError());

    do
    {
        if (is_file_data(&data))
            *count += 1;
    } while (FindNextFileW(handle, &data));
    FindClose(handle);

    return S_OK;
}

static const IFileCollectionVtbl filecollectionvtbl = {
    filecoll_QueryInterface,
    filecoll_AddRef,
    filecoll_Release,
    filecoll_GetTypeInfoCount,
    filecoll_GetTypeInfo,
    filecoll_GetIDsOfNames,
    filecoll_Invoke,
    filecoll_get_Item,
    filecoll_get__NewEnum,
    filecoll_get_Count
};

static HRESULT create_filecoll(BSTR path, IFileCollection **files)
{
    struct filecollection *This;

    *files = NULL;

    This = heap_alloc(sizeof(*This));
    if (!This) return E_OUTOFMEMORY;

    This->IFileCollection_iface.lpVtbl = &filecollectionvtbl;
    This->ref = 1;
    This->path = SysAllocString(path);
    if (!This->path)
    {
        heap_free(This);
        return E_OUTOFMEMORY;
    }

    *files = &This->IFileCollection_iface;
    return S_OK;
}

static HRESULT WINAPI drivecoll_QueryInterface(IDriveCollection *iface, REFIID riid, void **obj)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID( riid, &IID_IDriveCollection ) ||
        IsEqualIID( riid, &IID_IDispatch ) ||
        IsEqualIID( riid, &IID_IUnknown ))
    {
        *obj = iface;
        IDriveCollection_AddRef(iface);
    }
    else
        return E_NOINTERFACE;

    return S_OK;
}

static ULONG WINAPI drivecoll_AddRef(IDriveCollection *iface)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI drivecoll_Release(IDriveCollection *iface)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
        heap_free(This);

    return ref;
}

static HRESULT WINAPI drivecoll_GetTypeInfoCount(IDriveCollection *iface, UINT *pctinfo)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);
    TRACE("(%p)->(%p)\n", This, pctinfo);
    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI drivecoll_GetTypeInfo(IDriveCollection *iface, UINT iTInfo,
                                        LCID lcid, ITypeInfo **ppTInfo)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);
    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return get_typeinfo(IDriveCollection_tid, ppTInfo);
}

static HRESULT WINAPI drivecoll_GetIDsOfNames(IDriveCollection *iface, REFIID riid,
                                        LPOLESTR *rgszNames, UINT cNames,
                                        LCID lcid, DISPID *rgDispId)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(IDriveCollection_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI drivecoll_Invoke(IDriveCollection *iface, DISPID dispIdMember,
                                      REFIID riid, LCID lcid, WORD wFlags,
                                      DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                      EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IDriveCollection_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI drivecoll_get_Item(IDriveCollection *iface, VARIANT key, IDrive **drive)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);
    FIXME("(%p)->(%p): stub\n", This, drive);
    return E_NOTIMPL;
}

static HRESULT WINAPI drivecoll_get__NewEnum(IDriveCollection *iface, IUnknown **ppenum)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);

    TRACE("(%p)->(%p)\n", This, ppenum);

    if(!ppenum)
        return E_POINTER;

    return create_drivecoll_enum(This, ppenum);
}

static HRESULT WINAPI drivecoll_get_Count(IDriveCollection *iface, LONG *count)
{
    struct drivecollection *This = impl_from_IDriveCollection(iface);

    TRACE("(%p)->(%p)\n", This, count);

    if (!count) return E_POINTER;

    *count = This->count;
    return S_OK;
}

static const IDriveCollectionVtbl drivecollectionvtbl = {
    drivecoll_QueryInterface,
    drivecoll_AddRef,
    drivecoll_Release,
    drivecoll_GetTypeInfoCount,
    drivecoll_GetTypeInfo,
    drivecoll_GetIDsOfNames,
    drivecoll_Invoke,
    drivecoll_get_Item,
    drivecoll_get__NewEnum,
    drivecoll_get_Count
};

static HRESULT create_drivecoll(IDriveCollection **drives)
{
    struct drivecollection *This;
    DWORD mask;

    *drives = NULL;

    This = heap_alloc(sizeof(*This));
    if (!This) return E_OUTOFMEMORY;

    This->IDriveCollection_iface.lpVtbl = &drivecollectionvtbl;
    This->ref = 1;
    This->drives = mask = GetLogicalDrives();
    /* count set bits */
    for (This->count = 0; mask; This->count++)
        mask &= mask - 1;

    *drives = &This->IDriveCollection_iface;
    return S_OK;
}

static HRESULT WINAPI folder_QueryInterface(IFolder *iface, REFIID riid, void **obj)
{
    struct folder *This = impl_from_IFolder(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID( riid, &IID_IFolder ) ||
        IsEqualIID( riid, &IID_IDispatch ) ||
        IsEqualIID( riid, &IID_IUnknown))
    {
        *obj = iface;
        IFolder_AddRef(iface);
    }
    else
        return E_NOINTERFACE;

    return S_OK;
}

static ULONG WINAPI folder_AddRef(IFolder *iface)
{
    struct folder *This = impl_from_IFolder(iface);
    ULONG ref = InterlockedIncrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI folder_Release(IFolder *iface)
{
    struct folder *This = impl_from_IFolder(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    TRACE("(%p)->(%d)\n", This, ref);

    if (!ref)
    {
        SysFreeString(This->path);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI folder_GetTypeInfoCount(IFolder *iface, UINT *pctinfo)
{
    struct folder *This = impl_from_IFolder(iface);
    TRACE("(%p)->(%p)\n", This, pctinfo);
    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI folder_GetTypeInfo(IFolder *iface, UINT iTInfo,
                                        LCID lcid, ITypeInfo **ppTInfo)
{
    struct folder *This = impl_from_IFolder(iface);
    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
    return get_typeinfo(IFolder_tid, ppTInfo);
}

static HRESULT WINAPI folder_GetIDsOfNames(IFolder *iface, REFIID riid,
                                        LPOLESTR *rgszNames, UINT cNames,
                                        LCID lcid, DISPID *rgDispId)
{
    struct folder *This = impl_from_IFolder(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(IFolder_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI folder_Invoke(IFolder *iface, DISPID dispIdMember,
                                      REFIID riid, LCID lcid, WORD wFlags,
                                      DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                      EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    struct folder *This = impl_from_IFolder(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IFolder_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI folder_get_Path(IFolder *iface, BSTR *path)
{
    struct folder *This = impl_from_IFolder(iface);

    TRACE("(%p)->(%p)\n", This, path);

    if(!path)
        return E_POINTER;

    *path = SysAllocString(This->path);
    return *path ? S_OK : E_OUTOFMEMORY;
}

static HRESULT WINAPI folder_get_Name(IFolder *iface, BSTR *name)
{
    struct folder *This = impl_from_IFolder(iface);
    WCHAR *ptr;

    TRACE("(%p)->(%p)\n", This, name);

    if(!name)
        return E_POINTER;

    *name = NULL;

    ptr = strrchrW(This->path, '\\');
    if (ptr)
    {
        *name = SysAllocString(ptr+1);
        TRACE("%s\n", debugstr_w(*name));
        if (!*name) return E_OUTOFMEMORY;
    }
    else
        return E_FAIL;

    return S_OK;
}

static HRESULT WINAPI folder_put_Name(IFolder *iface, BSTR name)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%s): stub\n", This, debugstr_w(name));
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_ShortPath(IFolder *iface, BSTR *path)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, path);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_ShortName(IFolder *iface, BSTR *name)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, name);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_Drive(IFolder *iface, IDrive **drive)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, drive);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_ParentFolder(IFolder *iface, IFolder **parent)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, parent);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_Attributes(IFolder *iface, FileAttribute *attr)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, attr);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_put_Attributes(IFolder *iface, FileAttribute attr)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(0x%x): stub\n", This, attr);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_DateCreated(IFolder *iface, DATE *date)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, date);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_DateLastModified(IFolder *iface, DATE *date)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, date);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_DateLastAccessed(IFolder *iface, DATE *date)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, date);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_Type(IFolder *iface, BSTR *type)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, type);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_Delete(IFolder *iface, VARIANT_BOOL force)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%x): stub\n", This, force);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_Copy(IFolder *iface, BSTR dest, VARIANT_BOOL overwrite)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%s %x): stub\n", This, debugstr_w(dest), overwrite);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_Move(IFolder *iface, BSTR dest)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%s): stub\n", This, debugstr_w(dest));
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_IsRootFolder(IFolder *iface, VARIANT_BOOL *isroot)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, isroot);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_Size(IFolder *iface, VARIANT *size)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%p): stub\n", This, size);
    return E_NOTIMPL;
}

static HRESULT WINAPI folder_get_SubFolders(IFolder *iface, IFolderCollection **folders)
{
    struct folder *This = impl_from_IFolder(iface);

    TRACE("(%p)->(%p)\n", This, folders);

    if(!folders)
        return E_POINTER;

    return create_foldercoll(This->path, folders);
}

static HRESULT WINAPI folder_get_Files(IFolder *iface, IFileCollection **files)
{
    struct folder *This = impl_from_IFolder(iface);

    TRACE("(%p)->(%p)\n", This, files);

    if(!files)
        return E_POINTER;

    return create_filecoll(This->path, files);
}

static HRESULT WINAPI folder_CreateTextFile(IFolder *iface, BSTR filename, VARIANT_BOOL overwrite,
    VARIANT_BOOL unicode, ITextStream **stream)
{
    struct folder *This = impl_from_IFolder(iface);
    FIXME("(%p)->(%s %x %x %p): stub\n", This, debugstr_w(filename), overwrite, unicode, stream);
    return E_NOTIMPL;
}

static const IFolderVtbl foldervtbl = {
    folder_QueryInterface,
    folder_AddRef,
    folder_Release,
    folder_GetTypeInfoCount,
    folder_GetTypeInfo,
    folder_GetIDsOfNames,
    folder_Invoke,
    folder_get_Path,
    folder_get_Name,
    folder_put_Name,
    folder_get_ShortPath,
    folder_get_ShortName,
    folder_get_Drive,
    folder_get_ParentFolder,
    folder_get_Attributes,
    folder_put_Attributes,
    folder_get_DateCreated,
    folder_get_DateLastModified,
    folder_get_DateLastAccessed,
    folder_get_Type,
    folder_Delete,
    folder_Copy,
    folder_Move,
    folder_get_IsRootFolder,
    folder_get_Size,
    folder_get_SubFolders,
    folder_get_Files,
    folder_CreateTextFile
};

HRESULT create_folder(const WCHAR *path, IFolder **folder)
{
    struct folder *This;

    *folder = NULL;

    TRACE("%s\n", debugstr_w(path));

    This = heap_alloc(sizeof(struct folder));
    if (!This) return E_OUTOFMEMORY;

    This->IFolder_iface.lpVtbl = &foldervtbl;
    This->ref = 1;
    This->path = SysAllocString(path);
    if (!This->path)
    {
        heap_free(This);
        return E_OUTOFMEMORY;
    }

    *folder = &This->IFolder_iface;

    return S_OK;
}

static HRESULT WINAPI file_QueryInterface(IFile *iface, REFIID riid, void **obj)
{
    struct file *This = impl_from_IFile(iface);

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);

    if (IsEqualIID(riid, &IID_IFile) ||
            IsEqualIID(riid, &IID_IDispatch) ||
            IsEqualIID(riid, &IID_IUnknown))
    {
        *obj = iface;
        IFile_AddRef(iface);
        return S_OK;
    }

    *obj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI file_AddRef(IFile *iface)
{
    struct file *This = impl_from_IFile(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI file_Release(IFile *iface)
{
    struct file *This = impl_from_IFile(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref)
    {
        heap_free(This->path);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI file_GetTypeInfoCount(IFile *iface, UINT *pctinfo)
{
    struct file *This = impl_from_IFile(iface);

    TRACE("(%p)->(%p)\n", This, pctinfo);

    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI file_GetTypeInfo(IFile *iface,
        UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
    struct file *This = impl_from_IFile(iface);

    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);

    return get_typeinfo(IFile_tid, ppTInfo);
}

static HRESULT WINAPI file_GetIDsOfNames(IFile *iface, REFIID riid,
        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    struct file *This = impl_from_IFile(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid),
            rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(IFile_tid, &typeinfo);
    if(SUCCEEDED(hr)) {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }
    return hr;
}

static HRESULT WINAPI file_Invoke(IFile *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    struct file *This = impl_from_IFile(iface);
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IFile_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }
    return hr;
}

static HRESULT WINAPI file_get_Path(IFile *iface, BSTR *pbstrPath)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, pbstrPath);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_Name(IFile *iface, BSTR *name)
{
    struct file *This = impl_from_IFile(iface);
    WCHAR *ptr;

    TRACE("(%p)->(%p)\n", This, name);

    if(!name)
        return E_POINTER;

    *name = NULL;

    ptr = strrchrW(This->path, '\\');
    if (ptr)
    {
        *name = SysAllocString(ptr+1);
        TRACE("%s\n", debugstr_w(*name));
        if (!*name) return E_OUTOFMEMORY;
    }
    else
        return E_FAIL;

    return S_OK;
}

static HRESULT WINAPI file_put_Name(IFile *iface, BSTR pbstrName)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(pbstrName));
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_ShortPath(IFile *iface, BSTR *pbstrPath)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, pbstrPath);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_ShortName(IFile *iface, BSTR *pbstrName)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, pbstrName);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_Drive(IFile *iface, IDrive **ppdrive)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, ppdrive);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_ParentFolder(IFile *iface, IFolder **ppfolder)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, ppfolder);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_Attributes(IFile *iface, FileAttribute *pfa)
{
    struct file *This = impl_from_IFile(iface);
    DWORD fa;

    TRACE("(%p)->(%p)\n", This, pfa);

    if(!pfa)
        return E_POINTER;

    fa = GetFileAttributesW(This->path);
    if(fa == INVALID_FILE_ATTRIBUTES)
        return create_error(GetLastError());

    *pfa = fa & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN |
            FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE |
            FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_COMPRESSED);
    return S_OK;
}

static HRESULT WINAPI file_put_Attributes(IFile *iface, FileAttribute pfa)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%x)\n", This, pfa);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_DateCreated(IFile *iface, DATE *pdate)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, pdate);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_DateLastModified(IFile *iface, DATE *pdate)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, pdate);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_DateLastAccessed(IFile *iface, DATE *pdate)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, pdate);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_get_Size(IFile *iface, VARIANT *pvarSize)
{
    struct file *This = impl_from_IFile(iface);
    ULARGE_INTEGER size;
    WIN32_FIND_DATAW fd;
    HANDLE f;

    TRACE("(%p)->(%p)\n", This, pvarSize);

    if(!pvarSize)
        return E_POINTER;

    f = FindFirstFileW(This->path, &fd);
    if(f == INVALID_HANDLE_VALUE)
        return create_error(GetLastError());
    FindClose(f);

    size.u.LowPart = fd.nFileSizeLow;
    size.u.HighPart = fd.nFileSizeHigh;

    return variant_from_largeint(&size, pvarSize);
}

static HRESULT WINAPI file_get_Type(IFile *iface, BSTR *pbstrType)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%p)\n", This, pbstrType);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_Delete(IFile *iface, VARIANT_BOOL Force)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%x)\n", This, Force);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_Copy(IFile *iface, BSTR Destination, VARIANT_BOOL OverWriteFiles)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%s %x)\n", This, debugstr_w(Destination), OverWriteFiles);
    return E_NOTIMPL;
}

static HRESULT WINAPI file_Move(IFile *iface, BSTR Destination)
{
    struct file *This = impl_from_IFile(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(Destination));
    return E_NOTIMPL;
}

static HRESULT WINAPI file_OpenAsTextStream(IFile *iface, IOMode mode, Tristate format, ITextStream **stream)
{
    struct file *This = impl_from_IFile(iface);

    TRACE("(%p)->(%d %d %p)\n", This, mode, format, stream);

    if (format == TristateUseDefault) {
        FIXME("default format not handled, defaulting to unicode\n");
        format = TristateTrue;
    }

    return create_textstream(This->path, OPEN_EXISTING, mode, format == TristateTrue, stream);
}

static const IFileVtbl file_vtbl = {
    file_QueryInterface,
    file_AddRef,
    file_Release,
    file_GetTypeInfoCount,
    file_GetTypeInfo,
    file_GetIDsOfNames,
    file_Invoke,
    file_get_Path,
    file_get_Name,
    file_put_Name,
    file_get_ShortPath,
    file_get_ShortName,
    file_get_Drive,
    file_get_ParentFolder,
    file_get_Attributes,
    file_put_Attributes,
    file_get_DateCreated,
    file_get_DateLastModified,
    file_get_DateLastAccessed,
    file_get_Size,
    file_get_Type,
    file_Delete,
    file_Copy,
    file_Move,
    file_OpenAsTextStream
};

static HRESULT create_file(BSTR path, IFile **file)
{
    struct file *f;
    DWORD len, attrs;

    *file = NULL;

    f = heap_alloc(sizeof(struct file));
    if(!f)
        return E_OUTOFMEMORY;

    f->IFile_iface.lpVtbl = &file_vtbl;
    f->ref = 1;

    len = GetFullPathNameW(path, 0, NULL, NULL);
    if(!len) {
        heap_free(f);
        return E_FAIL;
    }

    f->path = heap_alloc(len*sizeof(WCHAR));
    if(!f->path) {
        heap_free(f);
        return E_OUTOFMEMORY;
    }

    if(!GetFullPathNameW(path, len, f->path, NULL)) {
        heap_free(f->path);
        heap_free(f);
        return E_FAIL;
    }

    attrs = GetFileAttributesW(f->path);
    if(attrs==INVALID_FILE_ATTRIBUTES ||
            (attrs&(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))) {
        heap_free(f->path);
        heap_free(f);
        return create_error(GetLastError());
    }

    *file = &f->IFile_iface;
    return S_OK;
}

static HRESULT WINAPI filesys_QueryInterface(IFileSystem3 *iface, REFIID riid, void **ppvObject)
{
    TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);

    if ( IsEqualGUID( riid, &IID_IFileSystem3 ) ||
         IsEqualGUID( riid, &IID_IFileSystem ) ||
         IsEqualGUID( riid, &IID_IDispatch ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *ppvObject = iface;
    }
    else if ( IsEqualGUID( riid, &IID_IDispatchEx ))
    {
        TRACE("Interface IDispatchEx not supported - returning NULL\n");
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }
    else if ( IsEqualGUID( riid, &IID_IObjectWithSite ))
    {
        TRACE("Interface IObjectWithSite not supported - returning NULL\n");
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }
    else
    {
        FIXME("Unsupported interface %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IFileSystem3_AddRef(iface);

    return S_OK;
}

static ULONG WINAPI filesys_AddRef(IFileSystem3 *iface)
{
    TRACE("%p\n", iface);

    return 2;
}

static ULONG WINAPI filesys_Release(IFileSystem3 *iface)
{
    TRACE("%p\n", iface);

    return 1;
}

static HRESULT WINAPI filesys_GetTypeInfoCount(IFileSystem3 *iface, UINT *pctinfo)
{
    TRACE("(%p)->(%p)\n", iface, pctinfo);

    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI filesys_GetTypeInfo(IFileSystem3 *iface, UINT iTInfo,
                                        LCID lcid, ITypeInfo **ppTInfo)
{
    TRACE("(%p)->(%u %u %p)\n", iface, iTInfo, lcid, ppTInfo);
    return get_typeinfo(IFileSystem3_tid, ppTInfo);
}

static HRESULT WINAPI filesys_GetIDsOfNames(IFileSystem3 *iface, REFIID riid,
                                        LPOLESTR *rgszNames, UINT cNames,
                                        LCID lcid, DISPID *rgDispId)
{
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%s %p %u %u %p)\n", iface, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);

    hr = get_typeinfo(IFileSystem3_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI filesys_Invoke(IFileSystem3 *iface, DISPID dispIdMember,
                                      REFIID riid, LCID lcid, WORD wFlags,
                                      DISPPARAMS *pDispParams, VARIANT *pVarResult,
                                      EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    ITypeInfo *typeinfo;
    HRESULT hr;

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", iface, dispIdMember, debugstr_guid(riid),
           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    hr = get_typeinfo(IFileSystem3_tid, &typeinfo);
    if(SUCCEEDED(hr))
    {
        hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
                pDispParams, pVarResult, pExcepInfo, puArgErr);
        ITypeInfo_Release(typeinfo);
    }

    return hr;
}

static HRESULT WINAPI filesys_get_Drives(IFileSystem3 *iface, IDriveCollection **ppdrives)
{
    TRACE("%p %p\n", iface, ppdrives);
    return create_drivecoll(ppdrives);
}

static HRESULT WINAPI filesys_BuildPath(IFileSystem3 *iface, BSTR Path,
                                            BSTR Name, BSTR *Result)
{
    BSTR ret;

    TRACE("%p %s %s %p\n", iface, debugstr_w(Path), debugstr_w(Name), Result);

    if (!Result) return E_POINTER;

    if (Path && Name)
    {
        int path_len = SysStringLen(Path), name_len = SysStringLen(Name);

        /* if both parts have backslashes strip one from Path */
        if (Path[path_len-1] == '\\' && Name[0] == '\\')
        {
            path_len -= 1;

            ret = SysAllocStringLen(NULL, path_len + name_len);
            if (ret)
            {
                strcpyW(ret, Path);
                ret[path_len] = 0;
                strcatW(ret, Name);
            }
        }
        else if (Path[path_len-1] != '\\' && Name[0] != '\\')
        {
            ret = SysAllocStringLen(NULL, path_len + name_len + 1);
            if (ret)
            {
                strcpyW(ret, Path);
                if (Path[path_len-1] != ':')
                    strcatW(ret, bsW);
                strcatW(ret, Name);
            }
        }
        else
        {
            ret = SysAllocStringLen(NULL, path_len + name_len);
            if (ret)
            {
                strcpyW(ret, Path);
                strcatW(ret, Name);
            }
        }
    }
    else if (Path || Name)
        ret = SysAllocString(Path ? Path : Name);
    else
        ret = SysAllocStringLen(NULL, 0);

    if (!ret) return E_OUTOFMEMORY;
    *Result = ret;

    return S_OK;
}

static HRESULT WINAPI filesys_GetDriveName(IFileSystem3 *iface, BSTR path, BSTR *drive)
{
    TRACE("(%p)->(%s %p)\n", iface, debugstr_w(path), drive);

    if (!drive)
        return E_POINTER;

    *drive = NULL;

    if (path && strlenW(path) > 1 && path[1] == ':')
        *drive = SysAllocStringLen(path, 2);

    return S_OK;
}

static inline DWORD get_parent_folder_name(const WCHAR *path, DWORD len)
{
    int i;

    if(!path)
        return 0;

    for(i=len-1; i>=0; i--)
        if(path[i]!='/' && path[i]!='\\')
            break;

    for(; i>=0; i--)
        if(path[i]=='/' || path[i]=='\\')
            break;

    for(; i>=0; i--)
        if(path[i]!='/' && path[i]!='\\')
            break;

    if(i < 0)
        return 0;

    if(path[i]==':' && i==1)
        i++;
    return i+1;
}

static HRESULT WINAPI filesys_GetParentFolderName(IFileSystem3 *iface, BSTR Path,
                                            BSTR *pbstrResult)
{
    DWORD len;

    TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);

    if(!pbstrResult)
        return E_POINTER;

    len = get_parent_folder_name(Path, SysStringLen(Path));
    if(!len) {
        *pbstrResult = NULL;
        return S_OK;
    }

    *pbstrResult = SysAllocStringLen(Path, len);
    if(!*pbstrResult)
        return E_OUTOFMEMORY;
    return S_OK;
}

static HRESULT WINAPI filesys_GetFileName(IFileSystem3 *iface, BSTR Path,
                                            BSTR *pbstrResult)
{
    int i, end;

    TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);

    if(!pbstrResult)
        return E_POINTER;

    if(!Path) {
        *pbstrResult = NULL;
        return S_OK;
    }

    for(end=strlenW(Path)-1; end>=0; end--)
        if(Path[end]!='/' && Path[end]!='\\')
            break;

    for(i=end; i>=0; i--)
        if(Path[i]=='/' || Path[i]=='\\')
            break;
    i++;

    if(i>end || (i==0 && end==1 && Path[1]==':')) {
        *pbstrResult = NULL;
        return S_OK;
    }

    *pbstrResult = SysAllocStringLen(Path+i, end-i+1);
    if(!*pbstrResult)
        return E_OUTOFMEMORY;
    return S_OK;
}

static HRESULT WINAPI filesys_GetBaseName(IFileSystem3 *iface, BSTR Path,
                                            BSTR *pbstrResult)
{
    int i, end;

    TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);

    if(!pbstrResult)
        return E_POINTER;

    if(!Path) {
        *pbstrResult = NULL;
        return S_OK;
    }

    for(end=strlenW(Path)-1; end>=0; end--)
        if(Path[end]!='/' && Path[end]!='\\')
            break;

    for(i=end; i>=0; i--) {
        if(Path[i]=='.' && Path[end+1]!='.')
            end = i-1;
        if(Path[i]=='/' || Path[i]=='\\')
            break;
    }
    i++;

    if((i>end && Path[end+1]!='.') || (i==0 && end==1 && Path[1]==':')) {
        *pbstrResult = NULL;
        return S_OK;
    }

    *pbstrResult = SysAllocStringLen(Path+i, end-i+1);
    if(!*pbstrResult)
        return E_OUTOFMEMORY;
    return S_OK;
}

static HRESULT WINAPI filesys_GetExtensionName(IFileSystem3 *iface, BSTR path,
                                            BSTR *ext)
{
    INT len;

    TRACE("%p %s %p\n", iface, debugstr_w(path), ext);

    *ext = NULL;
    len = SysStringLen(path);
    while (len) {
        if (path[len-1] == '.') {
            *ext = SysAllocString(&path[len]);
            if (!*ext)
                return E_OUTOFMEMORY;
            break;
        }
        len--;
    }

    return S_OK;
}

static HRESULT WINAPI filesys_GetAbsolutePathName(IFileSystem3 *iface, BSTR Path,
                                            BSTR *pbstrResult)
{
    static const WCHAR cur_path[] = {'.',0};

    WCHAR buf[MAX_PATH], ch;
    const WCHAR *path;
    DWORD i, beg, len, exp_len;
    WIN32_FIND_DATAW fdata;
    HANDLE fh;

    TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);

    if(!pbstrResult)
        return E_POINTER;

    if(!Path)
        path = cur_path;
    else
        path = Path;

    len = GetFullPathNameW(path, MAX_PATH, buf, NULL);
    if(!len)
        return E_FAIL;

    buf[0] = toupperW(buf[0]);
    if(len>3 && buf[len-1] == '\\')
        buf[--len] = 0;

    for(beg=3, i=3; i<=len; i++) {
        if(buf[i]!='\\' && buf[i])
            continue;

        ch = buf[i];
        buf[i] = 0;
        fh = FindFirstFileW(buf, &fdata);
        if(fh == INVALID_HANDLE_VALUE)
            break;

        exp_len = strlenW(fdata.cFileName);
        if(exp_len == i-beg)
            memcpy(buf+beg, fdata.cFileName, exp_len*sizeof(WCHAR));
        FindClose(fh);
        buf[i] = ch;
        beg = i+1;
    }

    *pbstrResult = SysAllocString(buf);
    if(!*pbstrResult)
        return E_OUTOFMEMORY;
    return S_OK;
}

static HRESULT WINAPI filesys_GetTempName(IFileSystem3 *iface, BSTR *pbstrResult)
{
    static const WCHAR fmt[] = {'r','a','d','%','0','5','X','.','t','x','t',0};

    DWORD random;

    TRACE("%p %p\n", iface, pbstrResult);

    if(!pbstrResult)
        return E_POINTER;

    *pbstrResult = SysAllocStringLen(NULL, 12);
    if(!*pbstrResult)
        return E_OUTOFMEMORY;

    if(!RtlGenRandom(&random, sizeof(random)))
        return E_FAIL;
    sprintfW(*pbstrResult, fmt, random & 0xfffff);
    return S_OK;
}

static HRESULT WINAPI filesys_DriveExists(IFileSystem3 *iface, BSTR DriveSpec,
                                            VARIANT_BOOL *pfExists)
{
    FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), pfExists);

    return E_NOTIMPL;
}

static HRESULT WINAPI filesys_FileExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret)
{
    DWORD attrs;
    TRACE("%p %s %p\n", iface, debugstr_w(path), ret);

    if (!ret) return E_POINTER;

    attrs = GetFileAttributesW(path);
    *ret = attrs != INVALID_FILE_ATTRIBUTES && !(attrs & FILE_ATTRIBUTE_DIRECTORY) ? VARIANT_TRUE : VARIANT_FALSE;
    return S_OK;
}

static HRESULT WINAPI filesys_FolderExists(IFileSystem3 *iface, BSTR path, VARIANT_BOOL *ret)
{
    DWORD attrs;
    TRACE("%p %s %p\n", iface, debugstr_w(path), ret);

    if (!ret) return E_POINTER;

    attrs = GetFileAttributesW(path);
    *ret = attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) ? VARIANT_TRUE : VARIANT_FALSE;

    return S_OK;
}

static HRESULT WINAPI filesys_GetDrive(IFileSystem3 *iface, BSTR DriveSpec,
                                            IDrive **ppdrive)
{
    FIXME("%p %s %p\n", iface, debugstr_w(DriveSpec), ppdrive);

    return E_NOTIMPL;
}

static HRESULT WINAPI filesys_GetFile(IFileSystem3 *iface, BSTR FilePath,
                                            IFile **ppfile)
{
    TRACE("%p %s %p\n", iface, debugstr_w(FilePath), ppfile);

    if(!ppfile)
        return E_POINTER;
    if(!FilePath)
        return E_INVALIDARG;

    return create_file(FilePath, ppfile);
}

static HRESULT WINAPI filesys_GetFolder(IFileSystem3 *iface, BSTR FolderPath,
                                            IFolder **folder)
{
    DWORD attrs;

    TRACE("%p %s %p\n", iface, debugstr_w(FolderPath), folder);

    if(!folder)
        return E_POINTER;

    *folder = NULL;
    if(!FolderPath)
        return E_INVALIDARG;

    attrs = GetFileAttributesW(FolderPath);
    if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY))
        return CTL_E_PATHNOTFOUND;

    return create_folder(FolderPath, folder);
}

static HRESULT WINAPI filesys_GetSpecialFolder(IFileSystem3 *iface,
                                            SpecialFolderConst SpecialFolder,
                                            IFolder **ppfolder)
{
    FIXME("%p %d %p\n", iface, SpecialFolder, ppfolder);

    return E_NOTIMPL;
}

static inline HRESULT delete_file(const WCHAR *file, DWORD file_len, VARIANT_BOOL force)
{
    WCHAR path[MAX_PATH];
    DWORD len, name_len;
    WIN32_FIND_DATAW ffd;
    HANDLE f;

    f = FindFirstFileW(file, &ffd);
    if(f == INVALID_HANDLE_VALUE)
        return create_error(GetLastError());

    len = get_parent_folder_name(file, file_len);
    if(len+1 >= MAX_PATH) {
        FindClose(f);
        return E_FAIL;
    }
    if(len) {
        memcpy(path, file, len*sizeof(WCHAR));
        path[len++] = '\\';
    }

    do {
        if(ffd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
            continue;

        name_len = strlenW(ffd.cFileName);
        if(len+name_len+1 >= MAX_PATH) {
            FindClose(f);
            return E_FAIL;
        }
        memcpy(path+len, ffd.cFileName, (name_len+1)*sizeof(WCHAR));

        TRACE("deleting %s\n", debugstr_w(path));

        if(!DeleteFileW(path)) {
            if(!force || !SetFileAttributesW(path, FILE_ATTRIBUTE_NORMAL)
                    || !DeleteFileW(path)) {
                FindClose(f);
                return create_error(GetLastError());
            }
        }
    } while(FindNextFileW(f, &ffd));
    FindClose(f);

    return S_OK;
}

static HRESULT WINAPI filesys_DeleteFile(IFileSystem3 *iface, BSTR FileSpec,
                                            VARIANT_BOOL Force)
{
    TRACE("%p %s %d\n", iface, debugstr_w(FileSpec), Force);

    if(!FileSpec)
        return E_POINTER;

    return delete_file(FileSpec, SysStringLen(FileSpec), Force);
}

static HRESULT delete_folder(const WCHAR *folder, DWORD folder_len, VARIANT_BOOL force)
{
    WCHAR path[MAX_PATH];
    DWORD len, name_len;
    WIN32_FIND_DATAW ffd;
    HANDLE f;
    HRESULT hr;

    f = FindFirstFileW(folder, &ffd);
    if(f == INVALID_HANDLE_VALUE)
        return create_error(GetLastError());

    len = get_parent_folder_name(folder, folder_len);
    if(len+1 >= MAX_PATH) {
        FindClose(f);
        return E_FAIL;
    }
    if(len) {
        memcpy(path, folder, len*sizeof(WCHAR));
        path[len++] = '\\';
    }

    do {
        if(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
            continue;
        if(ffd.cFileName[0]=='.' && (ffd.cFileName[1]==0 ||
                    (ffd.cFileName[1]=='.' && ffd.cFileName[2]==0)))
            continue;

        name_len = strlenW(ffd.cFileName);
        if(len+name_len+3 >= MAX_PATH) {
            FindClose(f);
            return E_FAIL;
        }
        memcpy(path+len, ffd.cFileName, name_len*sizeof(WCHAR));
        path[len+name_len] = '\\';
        path[len+name_len+1] = '*';
        path[len+name_len+2] = 0;

        hr = delete_file(path, len+name_len+2, force);
        if(FAILED(hr)) {
            FindClose(f);
            return hr;
        }

        hr = delete_folder(path, len+name_len+2, force);
        if(FAILED(hr)) {
            FindClose(f);
            return hr;
        }

        path[len+name_len] = 0;
        TRACE("deleting %s\n", debugstr_w(path));

        if(!RemoveDirectoryW(path)) {
            FindClose(f);
            return create_error(GetLastError());
        }
    } while(FindNextFileW(f, &ffd));
    FindClose(f);

    return S_OK;
}

static HRESULT WINAPI filesys_DeleteFolder(IFileSystem3 *iface, BSTR FolderSpec,
                                            VARIANT_BOOL Force)
{
    TRACE("%p %s %d\n", iface, debugstr_w(FolderSpec), Force);

    if(!FolderSpec)
        return E_POINTER;

    return delete_folder(FolderSpec, SysStringLen(FolderSpec), Force);
}

static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR Source,
                                            BSTR Destination)
{
    FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination));

    return E_NOTIMPL;
}

static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface,BSTR Source,
                                            BSTR Destination)
{
    FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination));

    return E_NOTIMPL;
}

static inline HRESULT copy_file(const WCHAR *source, DWORD source_len,
        const WCHAR *destination, DWORD destination_len, VARIANT_BOOL overwrite)
{
    DWORD attrs;
    WCHAR src_path[MAX_PATH], dst_path[MAX_PATH];
    DWORD src_len, dst_len, name_len;
    WIN32_FIND_DATAW ffd;
    HANDLE f;
    HRESULT hr;

    if(!source[0] || !destination[0])
        return E_INVALIDARG;

    attrs = GetFileAttributesW(destination);
    if(attrs==INVALID_FILE_ATTRIBUTES || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) {
        attrs = GetFileAttributesW(source);
        if(attrs == INVALID_FILE_ATTRIBUTES)
            return create_error(GetLastError());
        else if(attrs & FILE_ATTRIBUTE_DIRECTORY)
            return CTL_E_FILENOTFOUND;

        if(!CopyFileW(source, destination, !overwrite))
            return create_error(GetLastError());
        return S_OK;
    }

    f = FindFirstFileW(source, &ffd);
    if(f == INVALID_HANDLE_VALUE)
        return CTL_E_FILENOTFOUND;

    src_len = get_parent_folder_name(source, source_len);
    if(src_len+1 >= MAX_PATH) {
        FindClose(f);
        return E_FAIL;
    }
    if(src_len) {
        memcpy(src_path, source, src_len*sizeof(WCHAR));
        src_path[src_len++] = '\\';
    }

    dst_len = destination_len;
    if(dst_len+1 >= MAX_PATH) {
        FindClose(f);
        return E_FAIL;
    }
    memcpy(dst_path, destination, dst_len*sizeof(WCHAR));
    if(dst_path[dst_len-1]!= '\\' && dst_path[dst_len-1]!='/')
        dst_path[dst_len++] = '\\';

    hr = CTL_E_FILENOTFOUND;
    do {
        if(ffd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
            continue;

        name_len = strlenW(ffd.cFileName);
        if(src_len+name_len+1>=MAX_PATH || dst_len+name_len+1>=MAX_PATH) {
            FindClose(f);
            return E_FAIL;
        }
        memcpy(src_path+src_len, ffd.cFileName, (name_len+1)*sizeof(WCHAR));
        memcpy(dst_path+dst_len, ffd.cFileName, (name_len+1)*sizeof(WCHAR));

        TRACE("copying %s to %s\n", debugstr_w(src_path), debugstr_w(dst_path));

        if(!CopyFileW(src_path, dst_path, !overwrite)) {
            FindClose(f);
            return create_error(GetLastError());
        }else {
            hr = S_OK;
        }
    } while(FindNextFileW(f, &ffd));
    FindClose(f);

    return hr;
}

static HRESULT WINAPI filesys_CopyFile(IFileSystem3 *iface, BSTR Source,
                                            BSTR Destination, VARIANT_BOOL OverWriteFiles)
{
    TRACE("%p %s %s %d\n", iface, debugstr_w(Source), debugstr_w(Destination), OverWriteFiles);

    if(!Source || !Destination)
        return E_POINTER;

    return copy_file(Source, SysStringLen(Source), Destination,
            SysStringLen(Destination), OverWriteFiles);
}

static HRESULT copy_folder(const WCHAR *source, DWORD source_len, const WCHAR *destination,
        DWORD destination_len, VARIANT_BOOL overwrite)
{
    DWORD tmp, src_len, dst_len, name_len;
    WCHAR src[MAX_PATH], dst[MAX_PATH];
    WIN32_FIND_DATAW ffd;
    HANDLE f;
    HRESULT hr;
    BOOL copied = FALSE;

    if(!source[0] || !destination[0])
        return E_INVALIDARG;

    dst_len = destination_len;
    if(dst_len+1 >= MAX_PATH)
        return E_FAIL;
    memcpy(dst, destination, (dst_len+1)*sizeof(WCHAR));

    if(dst[dst_len-1]!='\\' && dst[dst_len-1]!='/' &&
            (tmp = GetFileAttributesW(source))!=INVALID_FILE_ATTRIBUTES &&
            tmp&FILE_ATTRIBUTE_DIRECTORY) {
        if(!CreateDirectoryW(dst, NULL)) {
            if(overwrite && GetLastError()==ERROR_ALREADY_EXISTS) {
                tmp = GetFileAttributesW(dst);
                if(tmp==INVALID_FILE_ATTRIBUTES || !(tmp&FILE_ATTRIBUTE_DIRECTORY))
                    return CTL_E_FILEALREADYEXISTS;
            }else {
                return create_error(GetLastError());
            }
        }
        copied = TRUE;

        src_len = source_len;
        if(src_len+2 >= MAX_PATH)
            return E_FAIL;
        memcpy(src, source, src_len*sizeof(WCHAR));
        src[src_len++] = '\\';
        src[src_len] = '*';
        src[src_len+1] = 0;

        hr = copy_file(src, src_len+1, dst, dst_len, overwrite);
        if(FAILED(hr) && hr!=CTL_E_FILENOTFOUND)
            return create_error(GetLastError());

        f = FindFirstFileW(src, &ffd);
    }else {
        src_len = get_parent_folder_name(source, source_len);
        if(src_len+2 >= MAX_PATH)
            return E_FAIL;
        memcpy(src, source, src_len*sizeof(WCHAR));
        if(src_len)
            src[src_len++] = '\\';

        f = FindFirstFileW(source, &ffd);
    }
    if(f == INVALID_HANDLE_VALUE)
        return CTL_E_PATHNOTFOUND;

    dst[dst_len++] = '\\';
    dst[dst_len] = 0;

    do {
        if(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
            continue;
        if(ffd.cFileName[0]=='.' && (ffd.cFileName[1]==0 ||
                    (ffd.cFileName[1]=='.' && ffd.cFileName[2]==0)))
            continue;

        name_len = strlenW(ffd.cFileName);
        if(dst_len+name_len>=MAX_PATH || src_len+name_len+2>=MAX_PATH) {
            FindClose(f);
            return E_FAIL;
        }
        memcpy(dst+dst_len, ffd.cFileName, name_len*sizeof(WCHAR));
        dst[dst_len+name_len] = 0;
        memcpy(src+src_len, ffd.cFileName, name_len*sizeof(WCHAR));
        src[src_len+name_len] = '\\';
        src[src_len+name_len+1] = '*';
        src[src_len+name_len+2] = 0;

        TRACE("copying %s to %s\n", debugstr_w(src), debugstr_w(dst));

        if(!CreateDirectoryW(dst, NULL)) {
            if(overwrite && GetLastError()==ERROR_ALREADY_EXISTS) {
                tmp = GetFileAttributesW(dst);
                if(tmp==INVALID_FILE_ATTRIBUTES || !(tmp&FILE_ATTRIBUTE_DIRECTORY)) {
                    FindClose(f);
                    return CTL_E_FILEALREADYEXISTS;
                }
            }

            FindClose(f);
            return create_error(GetLastError());
        }
        copied = TRUE;

        hr = copy_file(src, src_len+name_len+2, dst, dst_len+name_len, overwrite);
        if(FAILED(hr) && hr!=CTL_E_FILENOTFOUND) {
            FindClose(f);
            return hr;
        }

        hr = copy_folder(src, src_len+name_len+2, dst, dst_len+name_len, overwrite);
        if(FAILED(hr) && hr!=CTL_E_PATHNOTFOUND) {
            FindClose(f);
            return hr;
        }
    } while(FindNextFileW(f, &ffd));
    FindClose(f);

    return copied ? S_OK : CTL_E_PATHNOTFOUND;
}

static HRESULT WINAPI filesys_CopyFolder(IFileSystem3 *iface, BSTR Source,
                                            BSTR Destination, VARIANT_BOOL OverWriteFiles)
{
    TRACE("%p %s %s %d\n", iface, debugstr_w(Source), debugstr_w(Destination), OverWriteFiles);

    if(!Source || !Destination)
        return E_POINTER;

    return copy_folder(Source, SysStringLen(Source), Destination,
            SysStringLen(Destination), OverWriteFiles);
}

static HRESULT WINAPI filesys_CreateFolder(IFileSystem3 *iface, BSTR path,
                                            IFolder **folder)
{
    BOOL ret;

    TRACE("(%p)->(%s %p)\n", iface, debugstr_w(path), folder);

    ret = CreateDirectoryW(path, NULL);
    if (!ret)
    {
        *folder = NULL;
        if (GetLastError() == ERROR_ALREADY_EXISTS) return CTL_E_FILEALREADYEXISTS;
        return HRESULT_FROM_WIN32(GetLastError());
    }

    return create_folder(path, folder);
}

static HRESULT WINAPI filesys_CreateTextFile(IFileSystem3 *iface, BSTR filename,
                                            VARIANT_BOOL overwrite, VARIANT_BOOL unicode,
                                            ITextStream **stream)
{
    DWORD disposition;

    TRACE("%p %s %d %d %p\n", iface, debugstr_w(filename), overwrite, unicode, stream);

    disposition = overwrite == VARIANT_TRUE ? CREATE_ALWAYS : CREATE_NEW;
    return create_textstream(filename, disposition, ForWriting, !!unicode, stream);
}

static HRESULT WINAPI filesys_OpenTextFile(IFileSystem3 *iface, BSTR filename,
                                            IOMode mode, VARIANT_BOOL create,
                                            Tristate format, ITextStream **stream)
{
    DWORD disposition;

    TRACE("(%p)->(%s %d %d %d %p)\n", iface, debugstr_w(filename), mode, create, format, stream);
    disposition = create == VARIANT_TRUE ? OPEN_ALWAYS : OPEN_EXISTING;

    if (format == TristateUseDefault) {
        FIXME("default format not handled, defaulting to unicode\n");
        format = TristateTrue;
    }

    return create_textstream(filename, disposition, mode, format == TristateTrue, stream);
}

static HRESULT WINAPI filesys_GetStandardStream(IFileSystem3 *iface,
                                            StandardStreamTypes StandardStreamType,
                                            VARIANT_BOOL Unicode,
                                            ITextStream **ppts)
{
    FIXME("%p %d %d %p\n", iface, StandardStreamType, Unicode, ppts);

    return E_NOTIMPL;
}

static void get_versionstring(VS_FIXEDFILEINFO *info, WCHAR *ver)
{
    static const WCHAR fmtW[] = {'%','d','.','%','d','.','%','d','.','%','d',0};
    DWORDLONG version;
    WORD a, b, c, d;

    version = (((DWORDLONG)info->dwFileVersionMS) << 32) + info->dwFileVersionLS;
    a = (WORD)( version >> 48);
    b = (WORD)((version >> 32) & 0xffff);
    c = (WORD)((version >> 16) & 0xffff);
    d = (WORD)( version & 0xffff);

    sprintfW(ver, fmtW, a, b, c, d);
}

static HRESULT WINAPI filesys_GetFileVersion(IFileSystem3 *iface, BSTR name, BSTR *version)
{
    static const WCHAR rootW[] = {'\\',0};
    VS_FIXEDFILEINFO *info;
    WCHAR ver[30];
    void *ptr;
    DWORD len;
    BOOL ret;

    TRACE("%p %s %p\n", iface, debugstr_w(name), version);

    len = GetFileVersionInfoSizeW(name, NULL);
    if (!len)
        return HRESULT_FROM_WIN32(GetLastError());

    ptr = heap_alloc(len);
    if (!GetFileVersionInfoW(name, 0, len, ptr))
    {
        heap_free(ptr);
        return HRESULT_FROM_WIN32(GetLastError());
    }

    ret = VerQueryValueW(ptr, rootW, (void**)&info, &len);
    if (!ret)
    {
        heap_free(ptr);
        return HRESULT_FROM_WIN32(GetLastError());
    }

    get_versionstring(info, ver);
    heap_free(ptr);

    *version = SysAllocString(ver);
    TRACE("version=%s\n", debugstr_w(ver));

    return S_OK;
}

static const struct IFileSystem3Vtbl filesys_vtbl =
{
    filesys_QueryInterface,
    filesys_AddRef,
    filesys_Release,
    filesys_GetTypeInfoCount,
    filesys_GetTypeInfo,
    filesys_GetIDsOfNames,
    filesys_Invoke,
    filesys_get_Drives,
    filesys_BuildPath,
    filesys_GetDriveName,
    filesys_GetParentFolderName,
    filesys_GetFileName,
    filesys_GetBaseName,
    filesys_GetExtensionName,
    filesys_GetAbsolutePathName,
    filesys_GetTempName,
    filesys_DriveExists,
    filesys_FileExists,
    filesys_FolderExists,
    filesys_GetDrive,
    filesys_GetFile,
    filesys_GetFolder,
    filesys_GetSpecialFolder,
    filesys_DeleteFile,
    filesys_DeleteFolder,
    filesys_MoveFile,
    filesys_MoveFolder,
    filesys_CopyFile,
    filesys_CopyFolder,
    filesys_CreateFolder,
    filesys_CreateTextFile,
    filesys_OpenTextFile,
    filesys_GetStandardStream,
    filesys_GetFileVersion
};

static IFileSystem3 filesystem = { &filesys_vtbl };

HRESULT WINAPI FileSystem_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
{
    TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);

    return IFileSystem3_QueryInterface(&filesystem, riid, ppv);
}
