/*
 * IShellDispatch implementation
 *
 * Copyright 2010 Alexander Morozov for Etersoft
 *
 * 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
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winsvc.h"
#include "shlwapi.h"
#include "shlobj.h"
#include "shldisp.h"
#include "debughlp.h"

#include "shell32_main.h"
#include "pidl.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(shell);

static ITypeLib *typelib;
static const IID * const tid_ids[] =
{
    &IID_NULL,
    &IID_IShellDispatch6,
    &IID_IShellFolderViewDual3,
    &IID_Folder3,
    &IID_FolderItem2,
    &IID_FolderItems3,
    &IID_FolderItemVerb,
    &IID_FolderItemVerbs
};
static ITypeInfo *typeinfos[LAST_tid];

typedef struct {
    IShellDispatch6 IShellDispatch6_iface;
    LONG ref;
} ShellDispatch;

typedef struct {
    Folder3 Folder3_iface;
    LONG ref;
    IDispatch *application;
    IShellFolder2 *folder;
    PIDLIST_ABSOLUTE pidl;
    BSTR path;
} FolderImpl;

typedef struct {
    FolderItems3 FolderItems3_iface;
    LONG ref;
    FolderImpl *folder;
    BSTR *item_names;
    LONG item_count;
} FolderItemsImpl;

typedef struct {
    FolderItem2 FolderItem2_iface;
    LONG ref;
    FolderImpl *folder;
    WCHAR *path; /* if NULL, folder path is used */
    DWORD attributes;
} FolderItemImpl;

typedef struct {
    FolderItemVerbs FolderItemVerbs_iface;
    LONG ref;

    IContextMenu *contextmenu;
    HMENU hMenu;
    LONG count;
} FolderItemVerbsImpl;

typedef struct {
    FolderItemVerb FolderItemVerb_iface;
    LONG ref;

    IContextMenu *contextmenu;
    BSTR name;
} FolderItemVerbImpl;

static inline ShellDispatch *impl_from_IShellDispatch6(IShellDispatch6 *iface)
{
    return CONTAINING_RECORD(iface, ShellDispatch, IShellDispatch6_iface);
}

static inline FolderImpl *impl_from_Folder(Folder3 *iface)
{
    return CONTAINING_RECORD(iface, FolderImpl, Folder3_iface);
}

static inline FolderItemsImpl *impl_from_FolderItems(FolderItems3 *iface)
{
    return CONTAINING_RECORD(iface, FolderItemsImpl, FolderItems3_iface);
}

static inline FolderItemImpl *impl_from_FolderItem(FolderItem2 *iface)
{
    return CONTAINING_RECORD(iface, FolderItemImpl, FolderItem2_iface);
}

static inline FolderItemVerbsImpl *impl_from_FolderItemVerbs(FolderItemVerbs *iface)
{
    return CONTAINING_RECORD(iface, FolderItemVerbsImpl, FolderItemVerbs_iface);
}

static inline FolderItemVerbImpl *impl_from_FolderItemVerb(FolderItemVerb *iface)
{
    return CONTAINING_RECORD(iface, FolderItemVerbImpl, FolderItemVerb_iface);
}

static HRESULT load_typelib(void)
{
    ITypeLib *tl;
    HRESULT hr;

    hr = LoadRegTypeLib(&LIBID_Shell32, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
    if (FAILED(hr)) {
        ERR("LoadRegTypeLib failed: %08x\n", hr);
        return hr;
    }

    if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
        ITypeLib_Release(tl);
    return hr;
}

void release_typelib(void)
{
    unsigned i;

    if (!typelib)
        return;

    for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
        if (typeinfos[i])
            ITypeInfo_Release(typeinfos[i]);

    ITypeLib_Release(typelib);
}

HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
{
    HRESULT hr;

    if (!typelib)
        hr = load_typelib();
    if (!typelib)
        return hr;

    if (!typeinfos[tid])
    {
        ITypeInfo *ti;

        hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
        if (FAILED(hr))
        {
            ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
            return hr;
        }

        if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
            ITypeInfo_Release(ti);
    }

    *typeinfo = typeinfos[tid];
    return S_OK;
}

/* FolderItemVerb */
static HRESULT WINAPI FolderItemVerbImpl_QueryInterface(FolderItemVerb *iface,
    REFIID riid, void **ppv)
{
    FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IDispatch, riid) ||
        IsEqualIID(&IID_FolderItemVerb, riid))
        *ppv = &This->FolderItemVerb_iface;
    else
    {
        WARN("not implemented for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI FolderItemVerbImpl_AddRef(FolderItemVerb *iface)
{
    FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    return ref;
}

static ULONG WINAPI FolderItemVerbImpl_Release(FolderItemVerb *iface)
{
    FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    if (!ref)
    {
        IContextMenu_Release(This->contextmenu);
        SysFreeString(This->name);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfoCount(FolderItemVerb *iface, UINT *pctinfo)
{
    TRACE("(%p,%p)\n", iface, pctinfo);
    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI FolderItemVerbImpl_GetTypeInfo(FolderItemVerb *iface, UINT iTInfo,
        LCID lcid, ITypeInfo **ppTInfo)
{
    HRESULT hr;

    TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);

    hr = get_typeinfo(FolderItemVerb_tid, ppTInfo);
    if (SUCCEEDED(hr))
        ITypeInfo_AddRef(*ppTInfo);
    return hr;
}

static HRESULT WINAPI FolderItemVerbImpl_GetIDsOfNames(FolderItemVerb *iface,
        REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    ITypeInfo *ti;
    HRESULT hr;

    TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
            rgDispId);

    hr = get_typeinfo(FolderItemVerb_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
    return hr;
}

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

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

    hr = get_typeinfo(FolderItemVerb_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
    return hr;
}

static HRESULT WINAPI FolderItemVerbImpl_get_Application(FolderItemVerb *iface, IDispatch **disp)
{
    TRACE("(%p, %p)\n", iface, disp);

    if (disp)
        *disp = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemVerbImpl_get_Parent(FolderItemVerb *iface, IDispatch **disp)
{
    TRACE("(%p, %p)\n", iface, disp);

    if (disp)
        *disp = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemVerbImpl_get_Name(FolderItemVerb *iface, BSTR *name)
{
    FolderItemVerbImpl *This = impl_from_FolderItemVerb(iface);

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

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

static HRESULT WINAPI FolderItemVerbImpl_DoIt(FolderItemVerb *iface)
{
    FIXME("(%p)\n", iface);
    return E_NOTIMPL;
}

static FolderItemVerbVtbl folderitemverbvtbl = {
    FolderItemVerbImpl_QueryInterface,
    FolderItemVerbImpl_AddRef,
    FolderItemVerbImpl_Release,
    FolderItemVerbImpl_GetTypeInfoCount,
    FolderItemVerbImpl_GetTypeInfo,
    FolderItemVerbImpl_GetIDsOfNames,
    FolderItemVerbImpl_Invoke,
    FolderItemVerbImpl_get_Application,
    FolderItemVerbImpl_get_Parent,
    FolderItemVerbImpl_get_Name,
    FolderItemVerbImpl_DoIt
};

static HRESULT FolderItemVerb_Constructor(IContextMenu *contextmenu, BSTR name, FolderItemVerb **verb)
{
    FolderItemVerbImpl *This;

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

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbImpl));
    if (!This)
        return E_OUTOFMEMORY;

    This->FolderItemVerb_iface.lpVtbl = &folderitemverbvtbl;
    This->ref = 1;
    This->contextmenu = contextmenu;
    IContextMenu_AddRef(contextmenu);
    This->name = name;

    *verb = &This->FolderItemVerb_iface;
    return S_OK;
}

/* FolderItemVerbs */
static HRESULT WINAPI FolderItemVerbsImpl_QueryInterface(FolderItemVerbs *iface,
    REFIID riid, void **ppv)
{
    FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IDispatch, riid) ||
        IsEqualIID(&IID_FolderItemVerbs, riid))
        *ppv = &This->FolderItemVerbs_iface;
    else
    {
        WARN("not implemented for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI FolderItemVerbsImpl_AddRef(FolderItemVerbs *iface)
{
    FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    return ref;
}

static ULONG WINAPI FolderItemVerbsImpl_Release(FolderItemVerbs *iface)
{
    FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    if (!ref)
    {
        IContextMenu_Release(This->contextmenu);
        DestroyMenu(This->hMenu);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfoCount(FolderItemVerbs *iface, UINT *pctinfo)
{
    TRACE("(%p,%p)\n", iface, pctinfo);
    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI FolderItemVerbsImpl_GetTypeInfo(FolderItemVerbs *iface, UINT iTInfo,
        LCID lcid, ITypeInfo **ppTInfo)
{
    HRESULT hr;

    TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);

    hr = get_typeinfo(FolderItemVerbs_tid, ppTInfo);
    if (SUCCEEDED(hr))
        ITypeInfo_AddRef(*ppTInfo);
    return hr;
}

static HRESULT WINAPI FolderItemVerbsImpl_GetIDsOfNames(FolderItemVerbs *iface,
        REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    ITypeInfo *ti;
    HRESULT hr;

    TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
            rgDispId);

    hr = get_typeinfo(FolderItemVerbs_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
    return hr;
}

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

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

    hr = get_typeinfo(FolderItemVerbs_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
    return hr;
}

static HRESULT WINAPI FolderItemVerbsImpl_get_Count(FolderItemVerbs *iface, LONG *count)
{
    FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);

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

    if (!count)
        return E_INVALIDARG;

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

static HRESULT WINAPI FolderItemVerbsImpl_get_Application(FolderItemVerbs *iface, IDispatch **disp)
{
    TRACE("(%p, %p)\n", iface, disp);

    if (disp)
        *disp = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemVerbsImpl_get_Parent(FolderItemVerbs *iface, IDispatch **disp)
{
    TRACE("(%p, %p)\n", iface, disp);

    if (disp)
        *disp = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemVerbsImpl_Item(FolderItemVerbs *iface, VARIANT index, FolderItemVerb **verb)
{
    FolderItemVerbsImpl *This = impl_from_FolderItemVerbs(iface);
    MENUITEMINFOW info;
    HRESULT hr;
    VARIANT v;
    BSTR name;

    TRACE("(%p, %s, %p)\n", iface, debugstr_variant(&index), verb);

    if (!verb)
        return E_INVALIDARG;

    *verb = NULL;

    VariantInit(&v);
    VariantCopyInd(&v, &index);

    hr = VariantChangeType(&v, &v, 0, VT_I4);
    if (FAILED(hr))
    {
        FIXME("failed to coerce to VT_I4, %s\n", debugstr_variant(&v));
        return hr;
    }

    if (V_I4(&v) > This->count)
        return S_OK;

    if (V_I4(&v) == This->count)
        name = SysAllocStringLen(NULL, 0);
    else
    {
        /* get item name */
        memset(&info, 0, sizeof(info));
        info.cbSize = sizeof(info);
        info.fMask = MIIM_STRING;
        if (!GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info))
            return E_FAIL;

        name = SysAllocStringLen(NULL, info.cch);
        if (name)
        {
            info.dwTypeData = name;
            info.cch++;
            GetMenuItemInfoW(This->hMenu, V_I4(&v), TRUE, &info);
        }
    }

    if (!name)
        return E_OUTOFMEMORY;

    return FolderItemVerb_Constructor(This->contextmenu, name, verb);
}

static HRESULT WINAPI FolderItemVerbsImpl__NewEnum(FolderItemVerbs *iface, IUnknown **ret)
{
    FIXME("(%p, %p)\n", iface, ret);
    return E_NOTIMPL;
}

static FolderItemVerbsVtbl folderitemverbsvtbl = {
    FolderItemVerbsImpl_QueryInterface,
    FolderItemVerbsImpl_AddRef,
    FolderItemVerbsImpl_Release,
    FolderItemVerbsImpl_GetTypeInfoCount,
    FolderItemVerbsImpl_GetTypeInfo,
    FolderItemVerbsImpl_GetIDsOfNames,
    FolderItemVerbsImpl_Invoke,
    FolderItemVerbsImpl_get_Count,
    FolderItemVerbsImpl_get_Application,
    FolderItemVerbsImpl_get_Parent,
    FolderItemVerbsImpl_Item,
    FolderItemVerbsImpl__NewEnum
};

static HRESULT FolderItemVerbs_Constructor(BSTR path, FolderItemVerbs **verbs)
{
    FolderItemVerbsImpl *This;
    IShellFolder *folder;
    LPCITEMIDLIST child;
    LPITEMIDLIST pidl;
    HRESULT hr;

    *verbs = NULL;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemVerbsImpl));
    if (!This)
        return E_OUTOFMEMORY;

    This->FolderItemVerbs_iface.lpVtbl = &folderitemverbsvtbl;
    This->ref = 1;

    /* build context menu for this path */
    hr = SHParseDisplayName(path, NULL, &pidl, 0, NULL);
    if (FAILED(hr))
        goto failed;

    hr = SHBindToParent(pidl, &IID_IShellFolder, (void**)&folder, &child);
    CoTaskMemFree(pidl);
    if (FAILED(hr))
        goto failed;

    hr = IShellFolder_GetUIObjectOf(folder, NULL, 1, &child, &IID_IContextMenu, NULL, (void**)&This->contextmenu);
    IShellFolder_Release(folder);
    if (FAILED(hr))
        goto failed;

    This->hMenu = CreatePopupMenu();
    hr = IContextMenu_QueryContextMenu(This->contextmenu, This->hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
    if (FAILED(hr))
    {
        FolderItemVerbs_Release(&This->FolderItemVerbs_iface);
        return hr;
    }

    This->count = GetMenuItemCount(This->hMenu);
    *verbs = &This->FolderItemVerbs_iface;
    return S_OK;

failed:
    HeapFree(GetProcessHeap(), 0, This);
    return hr;
}

static HRESULT WINAPI FolderItemImpl_QueryInterface(FolderItem2 *iface,
        REFIID riid, LPVOID *ppv)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IDispatch, riid) ||
        IsEqualIID(&IID_FolderItem, riid) ||
        IsEqualIID(&IID_FolderItem2, riid))
        *ppv = &This->FolderItem2_iface;
    else
    {
        WARN("not implemented for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }
    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI FolderItemImpl_AddRef(FolderItem2 *iface)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    return ref;
}

static ULONG WINAPI FolderItemImpl_Release(FolderItem2 *iface)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    if (!ref)
    {
        Folder3_Release(&This->folder->Folder3_iface);
        HeapFree(GetProcessHeap(), 0, This->path);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

static HRESULT WINAPI FolderItemImpl_GetTypeInfoCount(FolderItem2 *iface,
        UINT *pctinfo)
{
    TRACE("(%p,%p)\n", iface, pctinfo);

    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI FolderItemImpl_GetTypeInfo(FolderItem2 *iface, UINT iTInfo,
        LCID lcid, ITypeInfo **ppTInfo)
{
    HRESULT hr;

    TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);

    hr = get_typeinfo(FolderItem2_tid, ppTInfo);
    if (SUCCEEDED(hr))
        ITypeInfo_AddRef(*ppTInfo);
    return hr;
}

static HRESULT WINAPI FolderItemImpl_GetIDsOfNames(FolderItem2 *iface,
        REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
        DISPID *rgDispId)
{
    ITypeInfo *ti;
    HRESULT hr;

    TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
            rgDispId);

    hr = get_typeinfo(FolderItem2_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
    return hr;
}

static HRESULT WINAPI FolderItemImpl_Invoke(FolderItem2 *iface,
        DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
        DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
        UINT *puArgErr)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);
    ITypeInfo *ti;
    HRESULT hr;

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

    hr = get_typeinfo(FolderItem2_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
    return hr;
}

static HRESULT WINAPI FolderItemImpl_get_Application(FolderItem2 *iface, IDispatch **disp)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

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

    return Folder3_get_Application(&This->folder->Folder3_iface, disp);
}

static HRESULT WINAPI FolderItemImpl_get_Parent(FolderItem2 *iface, IDispatch **disp)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

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

    if (disp)
    {
        *disp = (IDispatch *)&This->folder->Folder3_iface;
        IDispatch_AddRef(*disp);
    }

    return S_OK;
}

static HRESULT WINAPI FolderItemImpl_get_Name(FolderItem2 *iface, BSTR *name)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);
    LPCITEMIDLIST last_part;
    IShellFolder2 *parent;
    HRESULT hr = S_OK;
    LPITEMIDLIST pidl;
    STRRET strret;

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

    *name = NULL;

    if (This->path)
        hr = SHParseDisplayName(This->path, NULL, &pidl, 0, NULL);
    else
        pidl = This->folder->pidl;

    if (FAILED(hr))
        return S_FALSE;

    hr = SHBindToParent(pidl, &IID_IShellFolder2, (void **)&parent, &last_part);
    if (hr == S_OK)
        hr = IShellFolder2_GetDisplayNameOf(parent, last_part, SHGDN_INFOLDER, &strret);

    IShellFolder2_Release(parent);

    if (hr == S_OK)
        hr = StrRetToBSTR(&strret, last_part, name);

    if (This->path)
        ILFree(pidl);

    return hr;
}

static HRESULT WINAPI FolderItemImpl_put_Name(FolderItem2 *iface, BSTR bs)
{
    FIXME("(%p,%s)\n", iface, debugstr_w(bs));

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem2 *iface, BSTR *path)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

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

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

static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem2 *iface,
        IDispatch **ppid)
{
    FIXME("(%p,%p)\n", iface, ppid);

    *ppid = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_get_GetFolder(FolderItem2 *iface,
        IDispatch **ppid)
{
    FIXME("(%p,%p)\n", iface, ppid);

    *ppid = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_get_IsLink(FolderItem2 *iface, VARIANT_BOOL *b)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

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

    *b = This->attributes & SFGAO_LINK ? VARIANT_TRUE : VARIANT_FALSE;

    return S_OK;
}

static HRESULT WINAPI FolderItemImpl_get_IsFolder(FolderItem2 *iface, VARIANT_BOOL *b)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

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

    *b = This->attributes & SFGAO_FOLDER ? VARIANT_TRUE : VARIANT_FALSE;

    return S_OK;
}

static HRESULT WINAPI FolderItemImpl_get_IsFileSystem(FolderItem2 *iface, VARIANT_BOOL *b)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

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

    *b = This->attributes & SFGAO_FILESYSTEM ? VARIANT_TRUE : VARIANT_FALSE;

    return S_OK;
}

static HRESULT WINAPI FolderItemImpl_get_IsBrowsable(FolderItem2 *iface, VARIANT_BOOL *b)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

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

    *b = This->attributes & SFGAO_BROWSABLE ? VARIANT_TRUE : VARIANT_FALSE;

    return S_OK;
}

static HRESULT WINAPI FolderItemImpl_get_ModifyDate(FolderItem2 *iface,
        DATE *pdt)
{
    FIXME("(%p,%p)\n", iface, pdt);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_put_ModifyDate(FolderItem2 *iface, DATE dt)
{
    FIXME("(%p,%f)\n", iface, dt);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_get_Size(FolderItem2 *iface, LONG *pul)
{
    FIXME("(%p,%p)\n", iface, pul);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_get_Type(FolderItem2 *iface, BSTR *pbs)
{
    FIXME("(%p,%p)\n", iface, pbs);

    *pbs = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_Verbs(FolderItem2 *iface, FolderItemVerbs **verbs)
{
    FolderItemImpl *This = impl_from_FolderItem(iface);

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

    if (!verbs)
        return E_INVALIDARG;

    return FolderItemVerbs_Constructor(This->path ? This->path : This->folder->path, verbs);
}

static HRESULT WINAPI FolderItemImpl_InvokeVerb(FolderItem2 *iface,
        VARIANT vVerb)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_InvokeVerbEx(FolderItem2 *iface, VARIANT verb, VARIANT args)
{
    FIXME("(%p): stub\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemImpl_ExtendedProperty(FolderItem2 *iface, BSTR propname, VARIANT *ret)
{
    FIXME("(%p)->(%s %p): stub\n", iface, debugstr_w(propname), ret);

    return E_NOTIMPL;
}

static const FolderItem2Vtbl FolderItemImpl_Vtbl = {
    FolderItemImpl_QueryInterface,
    FolderItemImpl_AddRef,
    FolderItemImpl_Release,
    FolderItemImpl_GetTypeInfoCount,
    FolderItemImpl_GetTypeInfo,
    FolderItemImpl_GetIDsOfNames,
    FolderItemImpl_Invoke,
    FolderItemImpl_get_Application,
    FolderItemImpl_get_Parent,
    FolderItemImpl_get_Name,
    FolderItemImpl_put_Name,
    FolderItemImpl_get_Path,
    FolderItemImpl_get_GetLink,
    FolderItemImpl_get_GetFolder,
    FolderItemImpl_get_IsLink,
    FolderItemImpl_get_IsFolder,
    FolderItemImpl_get_IsFileSystem,
    FolderItemImpl_get_IsBrowsable,
    FolderItemImpl_get_ModifyDate,
    FolderItemImpl_put_ModifyDate,
    FolderItemImpl_get_Size,
    FolderItemImpl_get_Type,
    FolderItemImpl_Verbs,
    FolderItemImpl_InvokeVerb,
    FolderItemImpl_InvokeVerbEx,
    FolderItemImpl_ExtendedProperty
};

static HRESULT FolderItem_Constructor(FolderImpl *folder, const WCHAR *path, FolderItem **item)
{
    PIDLIST_ABSOLUTE pidl;
    FolderItemImpl *This;

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

    *item = NULL;

    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;

    This->FolderItem2_iface.lpVtbl = &FolderItemImpl_Vtbl;
    This->ref = 1;
    if (path)
        This->path = strdupW(path);

    This->folder = folder;
    Folder3_AddRef(&folder->Folder3_iface);

    if (SHParseDisplayName(This->path, NULL, &pidl, ~0u, &This->attributes) == S_OK)
        ILFree(pidl);

    *item = (FolderItem *)&This->FolderItem2_iface;
    return S_OK;
}

static HRESULT WINAPI FolderItemsImpl_QueryInterface(FolderItems3 *iface,
        REFIID riid, LPVOID *ppv)
{
    FolderItemsImpl *This = impl_from_FolderItems(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IDispatch, riid) ||
        IsEqualIID(&IID_FolderItems, riid) ||
        IsEqualIID(&IID_FolderItems2, riid) ||
        IsEqualIID(&IID_FolderItems3, riid))
        *ppv = &This->FolderItems3_iface;
    else
    {
        WARN("not implemented for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }
    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI FolderItemsImpl_AddRef(FolderItems3 *iface)
{
    FolderItemsImpl *This = impl_from_FolderItems(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    return ref;
}

static ULONG WINAPI FolderItemsImpl_Release(FolderItems3 *iface)
{
    FolderItemsImpl *This = impl_from_FolderItems(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    LONG i;

    TRACE("(%p), new refcount=%i\n", iface, ref);

    if (!ref)
    {
        Folder3_Release(&This->folder->Folder3_iface);
        for (i = 0; i < This->item_count; i++)
            SysFreeString(This->item_names[i]);
        HeapFree(GetProcessHeap(), 0, This->item_names);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

static HRESULT WINAPI FolderItemsImpl_GetTypeInfoCount(FolderItems3 *iface,
        UINT *count)
{
    TRACE("(%p,%p)\n", iface, count);

    *count = 1;
    return S_OK;
}

static HRESULT WINAPI FolderItemsImpl_GetTypeInfo(FolderItems3 *iface,
        UINT type, LCID lcid, ITypeInfo **ppti)
{
    HRESULT hr;

    TRACE("(%p,%u,%d,%p)\n", iface, type, lcid, ppti);

    hr = get_typeinfo(FolderItems3_tid, ppti);
    if (SUCCEEDED(hr))
        ITypeInfo_AddRef(*ppti);
    return hr;
}

static HRESULT WINAPI FolderItemsImpl_GetIDsOfNames(FolderItems3 *iface,
        REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid)
{
    ITypeInfo *ti;
    HRESULT hr;

    TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), names, count, lcid, dispid);

    hr = get_typeinfo(FolderItems3_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_GetIDsOfNames(ti, names, count, dispid);
    return hr;
}

static HRESULT WINAPI FolderItemsImpl_Invoke(FolderItems3 *iface,
        DISPID dispid, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params,
        VARIANT *result, EXCEPINFO *ei, UINT *err)
{
    FolderItemsImpl *This = impl_from_FolderItems(iface);
    ITypeInfo *ti;
    HRESULT hr;

    TRACE("(%p,%d,%s,%d,%u,%p,%p,%p,%p)\n", iface, dispid, shdebugstr_guid(riid), lcid, flags, params, result, ei, err);

    hr = get_typeinfo(FolderItems3_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_Invoke(ti, This, dispid, flags, params, result, ei, err);
    return hr;
}

static BOOL shellfolder_exists(const WCHAR *path)
{
    PIDLIST_ABSOLUTE pidl = NULL;
    HRESULT hr;

    hr = SHParseDisplayName(path, NULL, &pidl, 0, NULL);
    ILFree(pidl);

    return SUCCEEDED(hr);
}

static HRESULT WINAPI FolderItemsImpl_get_Count(FolderItems3 *iface, LONG *count)
{
    FolderItemsImpl *This = impl_from_FolderItems(iface);

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

    *count = shellfolder_exists(This->folder->path) ? This->item_count : 0;
    return S_OK;
}

static HRESULT WINAPI FolderItemsImpl_get_Application(FolderItems3 *iface, IDispatch **disp)
{
    FolderItemsImpl *This = impl_from_FolderItems(iface);

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

    return Folder3_get_Application(&This->folder->Folder3_iface, disp);
}

static HRESULT WINAPI FolderItemsImpl_get_Parent(FolderItems3 *iface, IDispatch **ppid)
{
    TRACE("(%p,%p)\n", iface, ppid);

    if (ppid)
        *ppid = NULL;

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemsImpl_Item(FolderItems3 *iface, VARIANT index, FolderItem **item)
{
    FolderItemsImpl *This = impl_from_FolderItems(iface);
    BSTR display_name = NULL;
    HRESULT hr;

    TRACE("(%p,%s,%p)\n", iface, debugstr_variant(&index), item);

    *item = NULL;

    if (!shellfolder_exists(This->folder->path))
        return S_FALSE;

    switch (V_VT(&index))
    {
        case VT_I2:
            VariantChangeType(&index, &index, 0, VT_I4);
            /* fall through */

        case VT_I4:
            if (V_I4(&index) >= This->item_count || V_I4(&index) < 0)
                return S_FALSE;

            display_name = SysAllocString(This->item_names[V_I4(&index)]);
            break;

        case VT_BSTR:
        {
            LPITEMIDLIST pidl;
            STRRET strret;

            if (!V_BSTR(&index))
                return S_FALSE;

            if (FAILED(hr = IShellFolder2_ParseDisplayName(This->folder->folder, NULL, NULL, V_BSTR(&index),
                    NULL, &pidl, NULL)))
                return S_FALSE;

            if (IShellFolder2_GetDisplayNameOf(This->folder->folder, pidl, SHGDN_FORPARSING, &strret) == S_OK)
                StrRetToBSTR(&strret, pidl, &display_name);
            ILFree(pidl);
            break;
        }
        case VT_ERROR:
            break;

        default:
            FIXME("Index type %d not handled.\n", V_VT(&index));
            /* fall through */
        case VT_EMPTY:
            return E_NOTIMPL;
    }

    hr = FolderItem_Constructor(This->folder, display_name, item);
    SysFreeString(display_name);
    return hr;
}

static HRESULT WINAPI FolderItemsImpl__NewEnum(FolderItems3 *iface, IUnknown **ppunk)
{
    FIXME("(%p,%p)\n", iface, ppunk);

    if (!ppunk)
        return E_INVALIDARG;

    *ppunk = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemsImpl_InvokeVerbEx(FolderItems3 *iface, VARIANT verb, VARIANT args)
{
    FIXME("(%p,%s,%s)\n", iface, debugstr_variant(&verb), debugstr_variant(&args));

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemsImpl_Filter(FolderItems3 *iface, LONG flags, BSTR spec)
{
    FIXME("(%p,%d,%s)\n", iface, flags, wine_dbgstr_w(spec));

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderItemsImpl_get_Verbs(FolderItems3 *iface, FolderItemVerbs **ppfic)
{
    FIXME("(%p,%p)\n", iface, ppfic);

    if (!ppfic)
        return E_INVALIDARG;

    *ppfic = NULL;
    return E_NOTIMPL;
}

static const FolderItems3Vtbl FolderItemsImpl_Vtbl = {
    FolderItemsImpl_QueryInterface,
    FolderItemsImpl_AddRef,
    FolderItemsImpl_Release,
    FolderItemsImpl_GetTypeInfoCount,
    FolderItemsImpl_GetTypeInfo,
    FolderItemsImpl_GetIDsOfNames,
    FolderItemsImpl_Invoke,
    FolderItemsImpl_get_Count,
    FolderItemsImpl_get_Application,
    FolderItemsImpl_get_Parent,
    FolderItemsImpl_Item,
    FolderItemsImpl__NewEnum,
    FolderItemsImpl_InvokeVerbEx,
    FolderItemsImpl_Filter,
    FolderItemsImpl_get_Verbs
};

static void idlist_sort(LPITEMIDLIST *idlist, unsigned int l, unsigned int r, IShellFolder2 *folder)
{
    unsigned int m;

    if (l == r)
        return;

    if (r < l)
    {
        idlist_sort(idlist, r, l, folder);
        return;
    }

    m = (l + r) / 2;
    idlist_sort(idlist, l, m, folder);
    idlist_sort(idlist, m + 1, r, folder);

    /* join the two sides */
    while (l <= m && m < r)
    {
        if ((short)IShellFolder2_CompareIDs(folder, 0, idlist[l], idlist[m + 1]) > 0)
        {
            LPITEMIDLIST t = idlist[m + 1];
            memmove(&idlist[l + 1], &idlist[l], (m - l + 1) * sizeof(idlist[l]));
            idlist[l] = t;

            m++;
        }
        l++;
    }
}

static HRESULT FolderItems_Constructor(FolderImpl *folder, FolderItems **ret)
{
    IEnumIDList *enumidlist;
    FolderItemsImpl *This;
    LPITEMIDLIST pidl;
    unsigned int i;
    HRESULT hr;

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

    *ret = NULL;

    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;

    This->FolderItems3_iface.lpVtbl = &FolderItemsImpl_Vtbl;
    This->ref = 1;
    This->folder = folder;
    Folder3_AddRef(&folder->Folder3_iface);

    enumidlist = NULL;
    if (FAILED(hr = IShellFolder2_EnumObjects(folder->folder, NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,
            &enumidlist)))
    {
        goto failed;
    }

    while (IEnumIDList_Next(enumidlist, 1, &pidl, NULL) == S_OK)
    {
        This->item_count++;
        ILFree(pidl);
    }

    if (This->item_count)
    {
        LPITEMIDLIST *pidls;
        ULONG fetched;

        pidls = HeapAlloc(GetProcessHeap(), 0, This->item_count * sizeof(*pidls));
        This->item_names = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->item_count * sizeof(*This->item_names));

        if (!pidls || !This->item_names)
        {
            HeapFree(GetProcessHeap(), 0, pidls);
            HeapFree(GetProcessHeap(), 0, This->item_names);
            hr = E_OUTOFMEMORY;
            goto failed;
        }

        IEnumIDList_Reset(enumidlist);
        if (IEnumIDList_Next(enumidlist, This->item_count, pidls, &fetched) == S_OK)
            idlist_sort(pidls, 0, This->item_count - 1, folder->folder);

        for (i = 0; i < This->item_count; i++)
        {
            STRRET strret;

            if (IShellFolder2_GetDisplayNameOf(folder->folder, pidls[i], SHGDN_FORPARSING, &strret) == S_OK)
                StrRetToBSTR(&strret, pidls[i], &This->item_names[i]);

            ILFree(pidls[i]);
        }
        HeapFree(GetProcessHeap(), 0, pidls);
    }
    IEnumIDList_Release(enumidlist);

    *ret = (FolderItems *)&This->FolderItems3_iface;
    return S_OK;

failed:
    if (enumidlist)
        IEnumIDList_Release(enumidlist);
    return hr;
}

static HRESULT WINAPI FolderImpl_QueryInterface(Folder3 *iface, REFIID riid,
        LPVOID *ppv)
{
    FolderImpl *This = impl_from_Folder(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IDispatch, riid) ||
        IsEqualIID(&IID_Folder, riid) ||
        IsEqualIID(&IID_Folder2, riid) ||
        IsEqualIID(&IID_Folder3, riid))
        *ppv = &This->Folder3_iface;
    else
    {
        WARN("not implemented for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }
    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI FolderImpl_AddRef(Folder3 *iface)
{
    FolderImpl *This = impl_from_Folder(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    return ref;
}

static ULONG WINAPI FolderImpl_Release(Folder3 *iface)
{
    FolderImpl *This = impl_from_Folder(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    if (!ref)
    {
        ILFree(This->pidl);
        SysFreeString(This->path);
        IShellFolder2_Release(This->folder);
        IDispatch_Release(This->application);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

static HRESULT WINAPI FolderImpl_GetTypeInfoCount(Folder3 *iface, UINT *pctinfo)
{
    TRACE("(%p,%p)\n", iface, pctinfo);

    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI FolderImpl_GetTypeInfo(Folder3 *iface, UINT iTInfo,
        LCID lcid, ITypeInfo **ppTInfo)
{
    HRESULT hr;

    TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);

    hr = get_typeinfo(Folder3_tid, ppTInfo);
    if (SUCCEEDED(hr))
        ITypeInfo_AddRef(*ppTInfo);

    return hr;
}

static HRESULT WINAPI FolderImpl_GetIDsOfNames(Folder3 *iface, REFIID riid,
        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    ITypeInfo *ti;
    HRESULT hr;

    TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
            rgDispId);

    hr = get_typeinfo(Folder3_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
    return hr;
}

static HRESULT WINAPI FolderImpl_Invoke(Folder3 *iface, DISPID dispIdMember,
        REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
        VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    FolderImpl *This = impl_from_Folder(iface);
    ITypeInfo *ti;
    HRESULT hr;

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

    hr = get_typeinfo(Folder3_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_Invoke(ti, This, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
    return hr;
}

static HRESULT WINAPI FolderImpl_get_Title(Folder3 *iface, BSTR *title)
{
    FolderImpl *This = impl_from_Folder(iface);
    PCUITEMID_CHILD last_part;
    IShellFolder2 *parent;
    SHELLDETAILS sd;
    HRESULT hr;

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

    *title = NULL;

    if (FAILED(hr = SHBindToParent(This->pidl, &IID_IShellFolder2, (void **)&parent, &last_part)))
        return hr;

    hr = IShellFolder2_GetDetailsOf(parent, last_part, 0, &sd);
    IShellFolder2_Release(parent);
    if (FAILED(hr))
        return hr;

    return StrRetToBSTR(&sd.str, last_part, title);
}

static HRESULT WINAPI FolderImpl_get_Application(Folder3 *iface, IDispatch **disp)
{
    FolderImpl *This = impl_from_Folder(iface);

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

    if (!disp)
        return E_INVALIDARG;

    *disp = This->application;
    IDispatch_AddRef(*disp);

    return S_OK;
}

static HRESULT WINAPI FolderImpl_get_Parent(Folder3 *iface, IDispatch **disp)
{
    TRACE("(%p,%p)\n", iface, disp);

    if (disp)
        *disp = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_get_ParentFolder(Folder3 *iface, Folder **ppsf)
{
    FIXME("(%p,%p)\n", iface, ppsf);

    *ppsf = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_Items(Folder3 *iface, FolderItems **ppid)
{
    FolderImpl *This = impl_from_Folder(iface);

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

    return FolderItems_Constructor(This, ppid);
}

static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem **item)
{
    FolderImpl *This = impl_from_Folder(iface);
    LPITEMIDLIST pidl;
    STRRET strret;
    HRESULT hr;
    BSTR path;

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

    *item = NULL;

    if (FAILED(IShellFolder2_ParseDisplayName(This->folder, NULL, NULL, name, NULL, &pidl, NULL)))
        return S_FALSE;

    if ((hr = IShellFolder2_GetDisplayNameOf(This->folder, pidl, SHGDN_FORPARSING, &strret)) == S_OK)
        hr = StrRetToBSTR(&strret, pidl, &path);

    ILFree(pidl);
    if (hr != S_OK)
        return S_FALSE;

    hr = FolderItem_Constructor(This, path, item);
    SysFreeString(path);
    return hr;
}

static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR name, VARIANT options)
{
    FIXME("(%p,%s,%s)\n", iface, debugstr_w(name), debugstr_variant(&options));

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_MoveHere(Folder3 *iface, VARIANT item, VARIANT options)
{
    FIXME("(%p,%s,%s)\n", iface, debugstr_variant(&item), debugstr_variant(&options));

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_CopyHere(Folder3 *iface, VARIANT item, VARIANT options)
{
    FIXME("(%p,%s,%s)\n", iface, debugstr_variant(&item), debugstr_variant(&options));

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_GetDetailsOf(Folder3 *iface, VARIANT item, int column, BSTR *str)
{
    FIXME("(%p,%s,%d,%p)\n", iface, debugstr_variant(&item), column, str);

    *str = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **item)
{
    FolderImpl *This = impl_from_Folder(iface);

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

    return FolderItem_Constructor(This, NULL, item);
}

static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
{
    FIXME("(%p,%p)\n", iface, pul);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_Synchronize(Folder3 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_get_HaveToShowWebViewBarricade(Folder3 *iface,
        VARIANT_BOOL *pbHaveToShowWebViewBarricade)
{
    FIXME("(%p,%p)\n", iface, pbHaveToShowWebViewBarricade);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_DismissedWebViewBarricade(Folder3 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_get_ShowWebViewBarricade(Folder3 *iface,
        VARIANT_BOOL *pbShowWebViewBarricade)
{
    FIXME("(%p,%p)\n", iface, pbShowWebViewBarricade);

    return E_NOTIMPL;
}

static HRESULT WINAPI FolderImpl_put_ShowWebViewBarricade(Folder3 *iface,
        VARIANT_BOOL bShowWebViewBarricade)
{
    FIXME("(%p,%d)\n", iface, bShowWebViewBarricade);

    return E_NOTIMPL;
}

static const Folder3Vtbl FolderImpl_Vtbl = {
    FolderImpl_QueryInterface,
    FolderImpl_AddRef,
    FolderImpl_Release,
    FolderImpl_GetTypeInfoCount,
    FolderImpl_GetTypeInfo,
    FolderImpl_GetIDsOfNames,
    FolderImpl_Invoke,
    FolderImpl_get_Title,
    FolderImpl_get_Application,
    FolderImpl_get_Parent,
    FolderImpl_get_ParentFolder,
    FolderImpl_Items,
    FolderImpl_ParseName,
    FolderImpl_NewFolder,
    FolderImpl_MoveHere,
    FolderImpl_CopyHere,
    FolderImpl_GetDetailsOf,
    FolderImpl_get_Self,
    FolderImpl_get_OfflineStatus,
    FolderImpl_Synchronize,
    FolderImpl_get_HaveToShowWebViewBarricade,
    FolderImpl_DismissedWebViewBarricade,
    FolderImpl_get_ShowWebViewBarricade,
    FolderImpl_put_ShowWebViewBarricade
};

static HRESULT Folder_Constructor(IShellFolder2 *folder, LPITEMIDLIST pidl, Folder **ret)
{
    PCUITEMID_CHILD last_part;
    IShellFolder2 *parent;
    FolderImpl *This;
    STRRET strret;
    HRESULT hr;

    *ret = NULL;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;

    This->Folder3_iface.lpVtbl = &FolderImpl_Vtbl;
    This->ref = 1;
    This->folder = folder;
    This->pidl = pidl;

    hr = SHBindToParent(pidl, &IID_IShellFolder2, (void **)&parent, &last_part);
    IShellFolder2_GetDisplayNameOf(parent, last_part, SHGDN_FORPARSING, &strret);
    StrRetToBSTR(&strret, last_part, &This->path);
    IShellFolder2_Release(parent);

    IShellDispatch_Constructor(NULL, &IID_IDispatch, (void **)&This->application);

    *ret = (Folder *)&This->Folder3_iface;
    return hr;
}

static HRESULT WINAPI ShellDispatch_QueryInterface(IShellDispatch6 *iface,
        REFIID riid, LPVOID *ppv)
{
    ShellDispatch *This = impl_from_IShellDispatch6(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IDispatch, riid) ||
        IsEqualIID(&IID_IShellDispatch, riid) ||
        IsEqualIID(&IID_IShellDispatch2, riid) ||
        IsEqualIID(&IID_IShellDispatch3, riid) ||
        IsEqualIID(&IID_IShellDispatch4, riid) ||
        IsEqualIID(&IID_IShellDispatch5, riid) ||
        IsEqualIID(&IID_IShellDispatch6, riid))
        *ppv = &This->IShellDispatch6_iface;
    else
    {
        WARN("not implemented for %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IShellDispatch6_AddRef(iface);
    return S_OK;
}

static ULONG WINAPI ShellDispatch_AddRef(IShellDispatch6 *iface)
{
    ShellDispatch *This = impl_from_IShellDispatch6(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    return ref;
}

static ULONG WINAPI ShellDispatch_Release(IShellDispatch6 *iface)
{
    ShellDispatch *This = impl_from_IShellDispatch6(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p), new refcount=%i\n", iface, ref);

    if (!ref)
        HeapFree(GetProcessHeap(), 0, This);

    return ref;
}

static HRESULT WINAPI ShellDispatch_GetTypeInfoCount(IShellDispatch6 *iface,
        UINT *pctinfo)
{
    TRACE("(%p,%p)\n", iface, pctinfo);

    *pctinfo = 1;
    return S_OK;
}

static HRESULT WINAPI ShellDispatch_GetTypeInfo(IShellDispatch6 *iface,
        UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
    HRESULT hr;

    TRACE("(%p,%u,%d,%p)\n", iface, iTInfo, lcid, ppTInfo);

    hr = get_typeinfo(IShellDispatch6_tid, ppTInfo);
    if (SUCCEEDED(hr))
        ITypeInfo_AddRef(*ppTInfo);
    return hr;
}

static HRESULT WINAPI ShellDispatch_GetIDsOfNames(IShellDispatch6 *iface,
        REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    ITypeInfo *ti;
    HRESULT hr;

    TRACE("(%p,%s,%p,%u,%d,%p)\n", iface, shdebugstr_guid(riid), rgszNames, cNames, lcid,
            rgDispId);

    hr = get_typeinfo(IShellDispatch6_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
    return hr;
}

static HRESULT WINAPI ShellDispatch_Invoke(IShellDispatch6 *iface,
        DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
        DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
        UINT *puArgErr)
{
    ShellDispatch *This = impl_from_IShellDispatch6(iface);
    ITypeInfo *ti;
    HRESULT hr;

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

    hr = get_typeinfo(IShellDispatch6_tid, &ti);
    if (SUCCEEDED(hr))
        hr = ITypeInfo_Invoke(ti, &This->IShellDispatch6_iface, dispIdMember, wFlags, pDispParams,
            pVarResult, pExcepInfo, puArgErr);
    return hr;
}

static HRESULT WINAPI ShellDispatch_get_Application(IShellDispatch6 *iface, IDispatch **disp)
{
    TRACE("(%p,%p)\n", iface, disp);

    if (!disp)
        return E_INVALIDARG;

    *disp = (IDispatch *)iface;
    IDispatch_AddRef(*disp);
    return S_OK;
}

static HRESULT WINAPI ShellDispatch_get_Parent(IShellDispatch6 *iface, IDispatch **disp)
{
    TRACE("(%p,%p)\n", iface, disp);

    if (disp)
    {
        *disp = (IDispatch *)iface;
        IDispatch_AddRef(*disp);
    }

    return S_OK;
}

static HRESULT WINAPI ShellDispatch_NameSpace(IShellDispatch6 *iface,
        VARIANT dir, Folder **ret)
{
    IShellFolder2 *folder;
    IShellFolder *desktop;
    LPITEMIDLIST pidl;
    HRESULT hr;

    TRACE("(%p,%s,%p)\n", iface, debugstr_variant(&dir), ret);

    *ret = NULL;

    switch (V_VT(&dir))
    {
        case VT_I2:
            if (FAILED(hr = VariantChangeType(&dir, &dir, 0, VT_I4)))
                return hr;

            /* fallthrough */
        case VT_I4:
            if (FAILED(hr = SHGetFolderLocation(NULL, V_I4(&dir), NULL, 0, &pidl)))
                return S_FALSE;

            break;
        case VT_BSTR:
            if (FAILED(hr = SHParseDisplayName(V_BSTR(&dir), NULL, &pidl, 0, NULL)))
                return S_FALSE;

            break;
        default:
            WARN("Ignoring directory value %s\n", debugstr_variant(&dir));
            return S_FALSE;
    }

    if (FAILED(hr = SHGetDesktopFolder(&desktop)))
        return hr;

    if (_ILIsDesktop(pidl))
        hr = IShellFolder_QueryInterface(desktop, &IID_IShellFolder2, (void **)&folder);
    else
        hr = IShellFolder_BindToObject(desktop, pidl, NULL, &IID_IShellFolder2, (void **)&folder);

    IShellFolder_Release(desktop);

    if (FAILED(hr))
        return S_FALSE;

    return Folder_Constructor(folder, pidl, ret);
}

static HRESULT WINAPI ShellDispatch_BrowseForFolder(IShellDispatch6 *iface,
        LONG Hwnd, BSTR Title, LONG Options, VARIANT RootFolder, Folder **ppsdf)
{
    FIXME("(%p,%x,%s,%x,%s,%p)\n", iface, Hwnd, debugstr_w(Title), Options, debugstr_variant(&RootFolder), ppsdf);

    *ppsdf = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_Windows(IShellDispatch6 *iface,
        IDispatch **ppid)
{
    FIXME("(%p,%p)\n", iface, ppid);

    *ppid = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_Open(IShellDispatch6 *iface, VARIANT dir)
{
    FIXME("(%p,%s)\n", iface, debugstr_variant(&dir));

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_Explore(IShellDispatch6 *iface, VARIANT dir)
{
    FIXME("(%p,%s)\n", iface, debugstr_variant(&dir));

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_MinimizeAll(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_UndoMinimizeALL(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_FileRun(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_CascadeWindows(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_TileVertically(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_TileHorizontally(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_ShutdownWindows(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_Suspend(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_EjectPC(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_SetTime(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_TrayProperties(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_Help(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_FindFiles(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_FindComputer(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_RefreshMenu(IShellDispatch6 *iface)
{
    FIXME("(%p)\n", iface);

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_ControlPanelItem(IShellDispatch6 *iface,
        BSTR szDir)
{
    FIXME("(%p,%s)\n", iface, debugstr_w(szDir));

    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_IsRestricted(IShellDispatch6 *iface, BSTR group, BSTR restriction, LONG *value)
{
    FIXME("(%s, %s, %p): stub\n", debugstr_w(group), debugstr_w(restriction), value);
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_ShellExecute(IShellDispatch6 *iface,
        BSTR file, VARIANT v_args, VARIANT v_dir, VARIANT v_op, VARIANT v_show)
{
    VARIANT args_str, dir_str, op_str, show_int;
    WCHAR *args = NULL, *dir = NULL, *op = NULL;
    INT show = 0;
    HINSTANCE ret;

    TRACE("(%s, %s, %s, %s, %s)\n", debugstr_w(file), debugstr_variant(&v_args),
            debugstr_variant(&v_dir), debugstr_variant(&v_op), debugstr_variant(&v_show));

    VariantInit(&args_str);
    VariantChangeType(&args_str, &v_args, 0, VT_BSTR);
    if (V_VT(&args_str) == VT_BSTR)
        args = V_BSTR(&args_str);

    VariantInit(&dir_str);
    VariantChangeType(&dir_str, &v_dir, 0, VT_BSTR);
    if (V_VT(&dir_str) == VT_BSTR)
        dir = V_BSTR(&dir_str);

    VariantInit(&op_str);
    VariantChangeType(&op_str, &v_op, 0, VT_BSTR);
    if (V_VT(&op_str) == VT_BSTR)
        op = V_BSTR(&op_str);

    VariantInit(&show_int);
    VariantChangeType(&show_int, &v_show, 0, VT_I4);
    if (V_VT(&show_int) == VT_I4)
        show = V_I4(&show_int);

    ret = ShellExecuteW(NULL, op, file, args, dir, show);

    VariantClear(&args_str);
    VariantClear(&dir_str);
    VariantClear(&op_str);
    VariantClear(&show_int);

    return (ULONG_PTR)ret > 32 ? S_OK : S_FALSE;
}

static HRESULT WINAPI ShellDispatch_FindPrinter(IShellDispatch6 *iface, BSTR name, BSTR location, BSTR model)
{
    FIXME("(%s, %s, %s): stub\n", debugstr_w(name), debugstr_w(location), debugstr_w(model));
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_GetSystemInformation(IShellDispatch6 *iface, BSTR name, VARIANT *ret)
{
    FIXME("(%s, %p): stub\n", debugstr_w(name), ret);
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_ServiceStart(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
{
    FIXME("(%s, %s, %p): stub\n", debugstr_w(service), debugstr_variant(&persistent), ret);
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_ServiceStop(IShellDispatch6 *iface, BSTR service, VARIANT persistent, VARIANT *ret)
{
    FIXME("(%s, %s, %p): stub\n", debugstr_w(service), debugstr_variant(&persistent), ret);
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_IsServiceRunning(IShellDispatch6 *iface, BSTR name, VARIANT *running)
{
    SERVICE_STATUS_PROCESS status;
    SC_HANDLE scm, service;
    DWORD dummy;

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

    V_VT(running) = VT_BOOL;
    V_BOOL(running) = VARIANT_FALSE;

    scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
    if (!scm)
    {
        ERR("failed to connect to service manager\n");
        return S_OK;
    }

    service = OpenServiceW(scm, name, SERVICE_QUERY_STATUS);
    if (!service)
    {
        ERR("Failed to open service %s (%u)\n", debugstr_w(name), GetLastError());
        CloseServiceHandle(scm);
        return S_OK;
    }

    if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status,
             sizeof(SERVICE_STATUS_PROCESS), &dummy))
    {
        TRACE("failed to query service status (%u)\n", GetLastError());
        CloseServiceHandle(service);
        CloseServiceHandle(scm);
        return S_OK;
    }

    if (status.dwCurrentState == SERVICE_RUNNING)
       V_BOOL(running) = VARIANT_TRUE;

    CloseServiceHandle(service);
    CloseServiceHandle(scm);

    return S_OK;
}

static HRESULT WINAPI ShellDispatch_CanStartStopService(IShellDispatch6 *iface, BSTR service, VARIANT *ret)
{
    FIXME("(%s, %p): stub\n", debugstr_w(service), ret);
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_ShowBrowserBar(IShellDispatch6 *iface, BSTR clsid, VARIANT show, VARIANT *ret)
{
    FIXME("(%s, %s, %p): stub\n", debugstr_w(clsid), debugstr_variant(&show), ret);
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_AddToRecent(IShellDispatch6 *iface, VARIANT file, BSTR category)
{
    FIXME("(%s, %s): stub\n", debugstr_variant(&file), debugstr_w(category));
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_WindowsSecurity(IShellDispatch6 *iface)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_ToggleDesktop(IShellDispatch6 *iface)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_ExplorerPolicy(IShellDispatch6 *iface, BSTR policy, VARIANT *value)
{
    FIXME("(%s, %p): stub\n", debugstr_w(policy), value);
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_GetSetting(IShellDispatch6 *iface, LONG setting, VARIANT_BOOL *result)
{
    FIXME("(%d %p): stub\n", setting, result);
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_WindowSwitcher(IShellDispatch6 *iface)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ShellDispatch_SearchCommand(IShellDispatch6 *iface)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static const IShellDispatch6Vtbl ShellDispatchVtbl = {
    ShellDispatch_QueryInterface,
    ShellDispatch_AddRef,
    ShellDispatch_Release,
    ShellDispatch_GetTypeInfoCount,
    ShellDispatch_GetTypeInfo,
    ShellDispatch_GetIDsOfNames,
    ShellDispatch_Invoke,
    ShellDispatch_get_Application,
    ShellDispatch_get_Parent,
    ShellDispatch_NameSpace,
    ShellDispatch_BrowseForFolder,
    ShellDispatch_Windows,
    ShellDispatch_Open,
    ShellDispatch_Explore,
    ShellDispatch_MinimizeAll,
    ShellDispatch_UndoMinimizeALL,
    ShellDispatch_FileRun,
    ShellDispatch_CascadeWindows,
    ShellDispatch_TileVertically,
    ShellDispatch_TileHorizontally,
    ShellDispatch_ShutdownWindows,
    ShellDispatch_Suspend,
    ShellDispatch_EjectPC,
    ShellDispatch_SetTime,
    ShellDispatch_TrayProperties,
    ShellDispatch_Help,
    ShellDispatch_FindFiles,
    ShellDispatch_FindComputer,
    ShellDispatch_RefreshMenu,
    ShellDispatch_ControlPanelItem,
    ShellDispatch_IsRestricted,
    ShellDispatch_ShellExecute,
    ShellDispatch_FindPrinter,
    ShellDispatch_GetSystemInformation,
    ShellDispatch_ServiceStart,
    ShellDispatch_ServiceStop,
    ShellDispatch_IsServiceRunning,
    ShellDispatch_CanStartStopService,
    ShellDispatch_ShowBrowserBar,
    ShellDispatch_AddToRecent,
    ShellDispatch_WindowsSecurity,
    ShellDispatch_ToggleDesktop,
    ShellDispatch_ExplorerPolicy,
    ShellDispatch_GetSetting,
    ShellDispatch_WindowSwitcher,
    ShellDispatch_SearchCommand
};

HRESULT WINAPI IShellDispatch_Constructor(IUnknown *outer, REFIID riid, void **ppv)
{
    ShellDispatch *This;
    HRESULT ret;

    TRACE("(%p, %s)\n", outer, debugstr_guid(riid));

    *ppv = NULL;

    if (outer) return CLASS_E_NOAGGREGATION;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellDispatch));
    if (!This) return E_OUTOFMEMORY;
    This->IShellDispatch6_iface.lpVtbl = &ShellDispatchVtbl;
    This->ref = 1;

    ret = IShellDispatch6_QueryInterface(&This->IShellDispatch6_iface, riid, ppv);
    IShellDispatch6_Release(&This->IShellDispatch6_iface);
    return ret;
}
