
/*
 * file system folder
 *
 * Copyright 1997             Marcus Meissner
 * Copyright 1998, 1999, 2002 Juergen Schmied
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

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

#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"

#include "ole2.h"
#include "shlguid.h"

#include "enumidlist.h"
#include "pidl.h"
#include "undocshell.h"
#include "shell32_main.h"
#include "shresdef.h"
#include "shlwapi.h"
#include "shellfolder.h"
#include "wine/debug.h"
#include "debughlp.h"
#include "shfldr.h"

WINE_DEFAULT_DEBUG_CHANNEL (shell);

/***********************************************************************
*   IShellFolder implementation
*/

typedef struct {
    IUnknownVtbl        *lpVtbl;
    DWORD                ref;
    IShellFolder2Vtbl   *lpvtblShellFolder;
    IPersistFolder3Vtbl *lpvtblPersistFolder3;
    IDropTargetVtbl     *lpvtblDropTarget;
    ISFHelperVtbl       *lpvtblSFHelper;

    IUnknown *pUnkOuter; /* used for aggregation */

    CLSID *pclsid;

    /* both paths are parsible from the desktop */
    LPSTR sPathTarget;     /* complete path to target used for enumeration and ChangeNotify */

    LPITEMIDLIST pidlRoot; /* absolute pidl */

    int dwAttributes;      /* attributes returned by GetAttributesOf FIXME: use it */

    UINT cfShellIDList;    /* clipboardformat for IDropTarget */
    BOOL fAcceptFmt;       /* flag for pending Drop */
} IGenericSFImpl;

static struct IUnknownVtbl unkvt;
static struct IShellFolder2Vtbl sfvt;
static struct IPersistFolder3Vtbl vt_FSFldr_PersistFolder3; /* IPersistFolder3 for a FS_Folder */
static struct IDropTargetVtbl dtvt;
static struct ISFHelperVtbl shvt;

#define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
#define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);

#define _IPersistFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder3)))
#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset);

#define _IPersistFolder3_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder3)))
#define _ICOM_THIS_From_IPersistFolder3(class, name) class* This = (class*)(((char*)name)-_IPersistFolder3_Offset);

#define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
#define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);

#define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
#define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);

/*
  converts This to an interface pointer
*/
#define _IUnknown_(This)        (IUnknown*)&(This->lpVtbl)
#define _IShellFolder_(This)    (IShellFolder*)&(This->lpvtblShellFolder)
#define _IShellFolder2_(This)   (IShellFolder2*)&(This->lpvtblShellFolder)
#define _IPersist_(This)        (IPersist*)&(This->lpvtblPersistFolder3)
#define _IPersistFolder_(This)  (IPersistFolder*)&(This->lpvtblPersistFolder3)
#define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder3)
#define _IPersistFolder3_(This) (IPersistFolder3*)&(This->lpvtblPersistFolder3)
#define _IDropTarget_(This)     (IDropTarget*)&(This->lpvtblDropTarget)
#define _ISFHelper_(This)       (ISFHelper*)&(This->lpvtblSFHelper)

/**************************************************************************
* registers clipboardformat once
*/
static void SF_RegisterClipFmt (IGenericSFImpl * This)
{
    TRACE ("(%p)\n", This);

    if (!This->cfShellIDList) {
        This->cfShellIDList = RegisterClipboardFormatA (CFSTR_SHELLIDLIST);
    }
}

/**************************************************************************
* we need a separate IUnknown to handle aggregation
* (inner IUnknown)
*/
static HRESULT WINAPI IUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppvObj)
{
    IGenericSFImpl *This = (IGenericSFImpl *)iface;

    TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);

    *ppvObj = NULL;

    if (IsEqualIID (riid, &IID_IUnknown))
        *ppvObj = _IUnknown_ (This);
    else if (IsEqualIID (riid, &IID_IShellFolder))
        *ppvObj = _IShellFolder_ (This);
    else if (IsEqualIID (riid, &IID_IShellFolder2))
        *ppvObj = _IShellFolder_ (This);
    else if (IsEqualIID (riid, &IID_IPersist))
        *ppvObj = _IPersist_ (This);
    else if (IsEqualIID (riid, &IID_IPersistFolder))
        *ppvObj = _IPersistFolder_ (This);
    else if (IsEqualIID (riid, &IID_IPersistFolder2))
        *ppvObj = _IPersistFolder2_ (This);
    else if (IsEqualIID (riid, &IID_IPersistFolder3))
        *ppvObj = _IPersistFolder3_ (This);
    else if (IsEqualIID (riid, &IID_ISFHelper))
        *ppvObj = _ISFHelper_ (This);
    else if (IsEqualIID (riid, &IID_IDropTarget)) {
        *ppvObj = _IDropTarget_ (This);
        SF_RegisterClipFmt (This);
    }

    if (*ppvObj) {
        IUnknown_AddRef ((IUnknown *) (*ppvObj));
        TRACE ("-- Interface = %p\n", *ppvObj);
        return S_OK;
    }
    TRACE ("-- Interface: E_NOINTERFACE\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI IUnknown_fnAddRef (IUnknown * iface)
{
    IGenericSFImpl *This = (IGenericSFImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE ("(%p)->(count=%lu)\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IUnknown_fnRelease (IUnknown * iface)
{
    IGenericSFImpl *This = (IGenericSFImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE ("(%p)->(count=%lu)\n", This, refCount + 1);

    if (!refCount) {
        TRACE ("-- destroying IShellFolder(%p)\n", This);

        if (This->pidlRoot)
            SHFree (This->pidlRoot);
        if (This->sPathTarget)
            SHFree (This->sPathTarget);
        LocalFree ((HLOCAL) This);
    }
    return refCount;
}

static IUnknownVtbl unkvt =
{
      IUnknown_fnQueryInterface,
      IUnknown_fnAddRef,
      IUnknown_fnRelease,
};

static shvheader GenericSFHeader[] = {
    {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
    {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
    {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
    {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
    {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
};

#define GENERICSHELLVIEWCOLUMNS 5

/**************************************************************************
* IFSFolder_Constructor
*
* NOTES
*  creating undocumented ShellFS_Folder as part of an aggregation
*  {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
*
*/
HRESULT WINAPI
IFSFolder_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
{
    IGenericSFImpl *sf;

    TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));

    if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
        return CLASS_E_NOAGGREGATION;
    sf = (IGenericSFImpl *) LocalAlloc (LMEM_ZEROINIT, sizeof (IGenericSFImpl));
    if (!sf)
        return E_OUTOFMEMORY;

    sf->ref = 0;
    sf->lpVtbl = &unkvt;
    sf->lpvtblShellFolder = &sfvt;
    sf->lpvtblPersistFolder3 = &vt_FSFldr_PersistFolder3;
    sf->lpvtblDropTarget = &dtvt;
    sf->lpvtblSFHelper = &shvt;
    sf->pclsid = (CLSID *) & CLSID_ShellFSFolder;
    sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_ (sf);

    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv))) {
        IUnknown_Release (_IUnknown_ (sf));
        return E_NOINTERFACE;
    }

    TRACE ("--%p\n", *ppv);
    return S_OK;
}

/**************************************************************************
 *  IShellFolder_fnQueryInterface
 *
 * PARAMETERS
 *  REFIID riid       [in ] Requested InterfaceID
 *  LPVOID* ppvObject [out] Interface* to hold the result
 */
static HRESULT WINAPI
IShellFolder_fnQueryInterface (IShellFolder2 * iface, REFIID riid,
                               LPVOID * ppvObj)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);

    return IUnknown_QueryInterface (This->pUnkOuter, riid, ppvObj);
}

/**************************************************************************
*  IShellFolder_AddRef
*/

static ULONG WINAPI IShellFolder_fnAddRef (IShellFolder2 * iface)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

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

    return IUnknown_AddRef (This->pUnkOuter);
}

/**************************************************************************
 *  IShellFolder_fnRelease
 */
static ULONG WINAPI IShellFolder_fnRelease (IShellFolder2 * iface)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

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

    return IUnknown_Release (This->pUnkOuter);
}

/**************************************************************************
 *  SHELL32_CreatePidlFromBindCtx  [internal]
 *
 *  If the caller bound File System Bind Data, assume it is the 
 *   find data for the path.
 *  This allows binding of paths that don't exist.
 */
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path)
{
    static const WCHAR szfsbc[] = {
        'F','i','l','e',' ','S','y','s','t','e','m',' ',
        'B','i','n','d',' ','D','a','t','a',0 };
    IFileSystemBindData *fsbd = NULL;
    LPITEMIDLIST pidl = NULL;
    IUnknown *param = NULL;
    WIN32_FIND_DATAW wfd;
    HRESULT r;

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

    if (!pbc)
        return NULL;

    /* see if the caller bound File System Bind Data */
    r = IBindCtx_GetObjectParam( pbc, (LPOLESTR) szfsbc, &param );
    if (FAILED(r))
        return NULL;

    r = IUnknown_QueryInterface( param, &IID_IFileSystemBindData,
                                 (LPVOID*) &fsbd );
    if (SUCCEEDED(r))
    {
        r = IFileSystemBindData_GetFindData( fsbd, &wfd );
        if (SUCCEEDED(r))
        {
            lstrcpynW( &wfd.cFileName[0], path, MAX_PATH );
            pidl = _ILCreateFromFindDataW( &wfd );
        }
        IFileSystemBindData_Release( fsbd );
    }
    
    return pidl;
}

/**************************************************************************
* IShellFolder_ParseDisplayName {SHELL32}
*
* Parse a display name.
*
* PARAMS
*  hwndOwner       [in]  Parent window for any message's
*  pbc             [in]  optional FileSystemBindData context
*  lpszDisplayName [in]  Unicode displayname.
*  pchEaten        [out] (unicode) characters processed
*  ppidl           [out] complex pidl to item
*  pdwAttributes   [out] items attributes
*
* NOTES
*  Every folder tries to parse only its own (the leftmost) pidl and creates a
*  subfolder to evaluate the remaining parts.
*  Now we can parse into namespaces implemented by shell extensions
*
*  Behaviour on win98: lpszDisplayName=NULL -> crash
*                      lpszDisplayName="" -> returns mycoputer-pidl
*
* FIXME
*    pdwAttributes is not set
*    pchEaten is not set like in windows
*/
static HRESULT WINAPI
IShellFolder_fnParseDisplayName (IShellFolder2 * iface,
                                 HWND hwndOwner,
                                 LPBC pbc,
                                 LPOLESTR lpszDisplayName,
                                 DWORD * pchEaten, LPITEMIDLIST * ppidl,
                                 DWORD * pdwAttributes)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    HRESULT hr = E_INVALIDARG;
    LPCWSTR szNext = NULL;
    WCHAR szElement[MAX_PATH];
    WCHAR szPath[MAX_PATH];
    LPITEMIDLIST pidlTemp = NULL;
    DWORD len;

    TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
     This, hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
     pchEaten, ppidl, pdwAttributes);

    if (!lpszDisplayName || !ppidl)
        return E_INVALIDARG;

    if (pchEaten)
        *pchEaten = 0; /* strange but like the original */

    pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName);
    if (!pidlTemp && *lpszDisplayName)
    {
        /* get the next element */
        szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);

        /* build the full pathname to the element */
        /* lstrcpyW(szPath, This->sPathTarget); */
        MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szPath, MAX_PATH);
        PathAddBackslashW(szPath);
        len = lstrlenW(szPath);
        lstrcpynW(szPath + len, szElement, MAX_PATH - len);

        /* get the pidl */
        hr = _ILCreateFromPathW(szPath, &pidlTemp);

        if (SUCCEEDED(hr)) {
            if (szNext && *szNext) {
                /* try to analyse the next element */
                hr = SHELL32_ParseNextElement (iface, hwndOwner, pbc,
                 &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
            } else {
                /* it's the last element */
                if (pdwAttributes && *pdwAttributes) {
                    hr = SHELL32_GetItemAttributes (_IShellFolder_ (This),
                     pidlTemp, pdwAttributes);
                }
            }
        }
    }

    if (SUCCEEDED(hr))
        *ppidl = pidlTemp;
    else
        *ppidl = NULL;

    TRACE ("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl ? *ppidl : 0, hr);

    return hr;
}

/**************************************************************************
* IShellFolder_fnEnumObjects
* PARAMETERS
*  HWND          hwndOwner,    //[in ] Parent Window
*  DWORD         grfFlags,     //[in ] SHCONTF enumeration mask
*  LPENUMIDLIST* ppenumIDList  //[out] IEnumIDList interface
*/
static HRESULT WINAPI
IShellFolder_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner,
                            DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner,
     dwFlags, ppEnumIDList);

    *ppEnumIDList = IEnumIDList_Constructor();
    if (*ppEnumIDList)
    {
        WCHAR path[MAX_PATH];
        MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, path, MAX_PATH);
        CreateFolderEnumList(*ppEnumIDList, path, dwFlags);
    }

    TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);

    return *ppEnumIDList ? S_OK : E_OUTOFMEMORY;
}

/**************************************************************************
* IShellFolder_fnBindToObject
* PARAMETERS
*  LPCITEMIDLIST pidl,       //[in ] relative pidl to open
*  LPBC          pbc,        //[in ] optional FileSystemBindData context
*  REFIID        riid,       //[in ] Initial Interface
*  LPVOID*       ppvObject   //[out] Interface*
*/
static HRESULT WINAPI
IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl,
                             LPBC pbc, REFIID riid, LPVOID * ppvOut)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbc,
     shdebugstr_guid (riid), ppvOut);

    return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid,
     ppvOut);
}

/**************************************************************************
*  IShellFolder_fnBindToStorage
* PARAMETERS
*  LPCITEMIDLIST pidl,       //[in ] complex pidl to store
*  LPBC          pbc,        //[in ] reserved
*  REFIID        riid,       //[in ] Initial storage interface
*  LPVOID*       ppvObject   //[out] Interface* returned
*/
static HRESULT WINAPI
IShellFolder_fnBindToStorage (IShellFolder2 * iface, LPCITEMIDLIST pidl,
                              LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved,
     shdebugstr_guid (riid), ppvOut);

    *ppvOut = NULL;
    return E_NOTIMPL;
}

/**************************************************************************
*  IShellFolder_fnCompareIDs
*/

static HRESULT WINAPI
IShellFolder_fnCompareIDs (IShellFolder2 * iface, LPARAM lParam,
                           LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    int nReturn;

    TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
    nReturn = SHELL32_CompareIDs (_IShellFolder_ (This), lParam, pidl1, pidl2);
    TRACE ("-- %i\n", nReturn);
    return nReturn;
}

/**************************************************************************
* IShellFolder_fnCreateViewObject
*/
static HRESULT WINAPI
IShellFolder_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner,
                                 REFIID riid, LPVOID * ppvOut)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    LPSHELLVIEW pShellView;
    HRESULT hr = E_INVALIDARG;

    TRACE ("(%p)->(hwnd=%p,%s,%p)\n", This, hwndOwner, shdebugstr_guid (riid),
     ppvOut);

    if (ppvOut) {
        *ppvOut = NULL;

        if (IsEqualIID (riid, &IID_IDropTarget)) {
            hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, ppvOut);
        } else if (IsEqualIID (riid, &IID_IContextMenu)) {
            FIXME ("IContextMenu not implemented\n");
            hr = E_NOTIMPL;
        } else if (IsEqualIID (riid, &IID_IShellView)) {
            pShellView = IShellView_Constructor ((IShellFolder *) iface);
            if (pShellView) {
                hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
                IShellView_Release (pShellView);
            }
        }
    }
    TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
    return hr;
}

/**************************************************************************
*  IShellFolder_fnGetAttributesOf
*
* PARAMETERS
*  UINT            cidl,     //[in ] num elements in pidl array
*  LPCITEMIDLIST*  apidl,    //[in ] simple pidl array
*  ULONG*          rgfInOut) //[out] result array
*
*/
static HRESULT WINAPI
IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl,
                                LPCITEMIDLIST * apidl, DWORD * rgfInOut)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    HRESULT hr = S_OK;

    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl,
     *rgfInOut);

    if ((!cidl) || (!apidl) || (!rgfInOut))
        return E_INVALIDARG;

    if (*rgfInOut == 0)
        *rgfInOut = ~0;

    while (cidl > 0 && *apidl) {
        pdump (*apidl);
        SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
        apidl++;
        cidl--;
    }

    TRACE ("-- result=0x%08lx\n", *rgfInOut);

    return hr;
}

/**************************************************************************
*  IShellFolder_fnGetUIObjectOf
*
* PARAMETERS
*  HWND           hwndOwner, //[in ] Parent window for any output
*  UINT           cidl,      //[in ] array size
*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
*  REFIID         riid,      //[in ] Requested Interface
*  UINT*          prgfInOut, //[   ] reserved
*  LPVOID*        ppvObject) //[out] Resulting Interface
*
* NOTES
*  This function gets asked to return "view objects" for one or more (multiple
*  select) items:
*  The viewobject typically is an COM object with one of the following
*  interfaces:
*  IExtractIcon,IDataObject,IContextMenu
*  In order to support icon positions in the default Listview your DataObject
*  must implement the SetData method (in addition to GetData :) - the shell
*  passes a barely documented "Icon positions" structure to SetData when the
*  drag starts, and GetData's it if the drop is in another explorer window that
*  needs the positions.
*/
static HRESULT WINAPI
IShellFolder_fnGetUIObjectOf (IShellFolder2 * iface,
                              HWND hwndOwner,
                              UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
                              UINT * prgfInOut, LPVOID * ppvOut)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    LPITEMIDLIST pidl;
    IUnknown *pObj = NULL;
    HRESULT hr = E_INVALIDARG;

    TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
     This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);

    if (ppvOut) {
        *ppvOut = NULL;

        if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
            pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
             This->pidlRoot, apidl, cidl);
            hr = S_OK;
        } else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
            pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner,
             This->pidlRoot, apidl, cidl);
            hr = S_OK;
        } else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
            pidl = ILCombine (This->pidlRoot, apidl[0]);
            pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
            SHFree (pidl);
            hr = S_OK;
        } else if (IsEqualIID (riid, &IID_IExtractIconW) && (cidl == 1)) {
            pidl = ILCombine (This->pidlRoot, apidl[0]);
            pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
            SHFree (pidl);
            hr = S_OK;
        } else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1)) {
            hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget,
             (LPVOID *) & pObj);
        } else if ((IsEqualIID(riid,&IID_IShellLinkW) ||
         IsEqualIID(riid,&IID_IShellLinkA)) && (cidl == 1)) {
            pidl = ILCombine (This->pidlRoot, apidl[0]);
            hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
            SHFree (pidl);
        } else {
            hr = E_NOINTERFACE;
        }

        if (SUCCEEDED(hr) && !pObj)
            hr = E_OUTOFMEMORY;

        *ppvOut = pObj;
    }
    TRACE ("(%p)->hr=0x%08lx\n", This, hr);
    return hr;
}

static const WCHAR AdvancedW[] = { 'S','O','F','T','W','A','R','E',
 '\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l',
 'o','r','e','r','\\','A','d','v','a','n','c','e','d',0 };
static const WCHAR HideFileExtW[] = { 'H','i','d','e','F','i','l','e','E','x',
 't',0 };
static const WCHAR NeverShowExtW[] = { 'N','e','v','e','r','S','h','o','w','E',
 'x','t',0 };

void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags)
{
    /*FIXME: MSDN also mentions SHGDN_FOREDITING which is not yet handled. */
    if (!(dwFlags & SHGDN_FORPARSING) &&
        ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) {
        HKEY hKey;
        DWORD dwData;
        DWORD dwDataSize = sizeof (DWORD);
        BOOL doHide = FALSE; /* The default value is FALSE (win98 at least) */

        if (!RegCreateKeyExW (HKEY_CURRENT_USER, AdvancedW,
         0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0)) {
            if (!RegQueryValueExW (hKey, HideFileExtW, 0, 0, (LPBYTE) &dwData,
             &dwDataSize))
                doHide = dwData;

            RegCloseKey (hKey);
        }

        if (!doHide) {
            LPSTR ext = PathFindExtensionA(szPath);

            if (ext) {
                char classname[MAX_PATH];
                LONG classlen = MAX_PATH;

                if (!RegQueryValueA(HKEY_CLASSES_ROOT, ext, classname,
                 &classlen))
                    if (!RegOpenKeyA(HKEY_CLASSES_ROOT, classname, &hKey)) {
                        if (!RegQueryValueExW(hKey, NeverShowExtW, 0, NULL,
                         NULL, NULL))
                            doHide = TRUE;

                        RegCloseKey(hKey);
                    }
            }
        }

        if (doHide && szPath[0] != '.')
            PathRemoveExtensionA (szPath);
    }
}

/**************************************************************************
*  IShellFolder_fnGetDisplayNameOf
*  Retrieves the display name for the specified file object or subfolder
*
* PARAMETERS
*  LPCITEMIDLIST pidl,    //[in ] complex pidl to item
*  DWORD         dwFlags, //[in ] SHGNO formatting flags
*  LPSTRRET      lpName)  //[out] Returned display name
*
* FIXME
*  if the name is in the pidl the ret value should be a STRRET_OFFSET
*/

static HRESULT WINAPI
IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl,
                                 DWORD dwFlags, LPSTRRET strRet)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    CHAR szPath[MAX_PATH];
    int len = 0;
    BOOL bSimplePidl;

    *szPath = '\0';

    TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
    pdump (pidl);

    if (!pidl || !strRet)
        return E_INVALIDARG;

    bSimplePidl = _ILIsPidlSimple (pidl);

    /* take names of special folders only if its only this folder */
    if (_ILIsSpecialFolder (pidl)) {
        if (bSimplePidl) {
            _ILSimpleGetText (pidl, szPath, MAX_PATH); /* append my own path */
        } else {
            FIXME ("special pidl\n");
        }
    } else {
        if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) &&
         This->sPathTarget) {
            /* get path to root */
            lstrcpyA (szPath, This->sPathTarget);
            PathAddBackslashA (szPath);
            len = lstrlenA (szPath);
        }
        /* append my own path */
        _ILSimpleGetText (pidl, szPath + len, MAX_PATH - len);

        if (!_ILIsFolder(pidl))
            SHELL_FS_ProcessDisplayFilename(szPath, dwFlags);
    }

    /* go deeper if needed */
    if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) {
        PathAddBackslashA (szPath);
        len = lstrlenA (szPath);

        if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild (iface, pidl,
         dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len)))
            return E_OUTOFMEMORY;
    }
    strRet->uType = STRRET_CSTR;
    lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);

    TRACE ("-- (%p)->(%s)\n", This, szPath);
    return S_OK;
}

/**************************************************************************
*  IShellFolder_fnSetNameOf
*  Changes the name of a file object or subfolder, possibly changing its item
*  identifier in the process.
*
* PARAMETERS
*  HWND          hwndOwner,  //[in ] Owner window for output
*  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
*  LPCOLESTR     lpszName,   //[in ] the items new display name
*  DWORD         dwFlags,    //[in ] SHGNO formatting flags
*  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
*/
static HRESULT WINAPI IShellFolder_fnSetNameOf (IShellFolder2 * iface,
                                                HWND hwndOwner,
                                                LPCITEMIDLIST pidl,
                                                LPCOLESTR lpName,
                                                DWORD dwFlags,
                                                LPITEMIDLIST * pPidlOut)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
    WCHAR szSrc[MAX_PATH], szDest[MAX_PATH];
    LPWSTR ptr;
    BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl));

    TRACE ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl,
     debugstr_w (lpName), dwFlags, pPidlOut);

    /* build source path */
    if (dwFlags & SHGDN_INFOLDER) {
        MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szSrc, MAX_PATH);
        ptr = PathAddBackslashW (szSrc);
        if (ptr)
            _ILSimpleGetTextW (pidl, ptr, MAX_PATH - (ptr - szSrc));
    } else {
        /* FIXME: Can this work with a simple PIDL? */
        SHGetPathFromIDListW (pidl, szSrc);
    }

    /* build destination path */
    MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szDest, MAX_PATH);
    ptr = PathAddBackslashW (szDest);
    if (ptr)
        lstrcpynW(ptr, lpName, MAX_PATH - (ptr - szDest));
    TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest));
    if (MoveFileW (szSrc, szDest)) {
        HRESULT hr = S_OK;

        if (pPidlOut)
            hr = _ILCreateFromPathW(szDest, pPidlOut);

        SHChangeNotify (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM,
         SHCNF_PATHW, szSrc, szDest);

        return hr;
    }

    return E_FAIL;
}

static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID (IShellFolder2 *iface,
                                                           GUID * pguid)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
    FIXME ("(%p)\n", This);
    return E_NOTIMPL;
}
static HRESULT WINAPI IShellFolder_fnEnumSearches (IShellFolder2 * iface,
                                                   IEnumExtraSearch ** ppenum)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
    FIXME ("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI
IShellFolder_fnGetDefaultColumn (IShellFolder2 * iface, DWORD dwRes,
                                 ULONG * pSort, ULONG * pDisplay)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

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

    if (pSort)
        *pSort = 0;
    if (pDisplay)
        *pDisplay = 0;

    return S_OK;
}

static HRESULT WINAPI
IShellFolder_fnGetDefaultColumnState (IShellFolder2 * iface, UINT iColumn,
                                      DWORD * pcsFlags)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

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

    if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS)
        return E_INVALIDARG;

    *pcsFlags = GenericSFHeader[iColumn].pcsFlags;

    return S_OK;
}

static HRESULT WINAPI
IShellFolder_fnGetDetailsEx (IShellFolder2 * iface, LPCITEMIDLIST pidl,
                             const SHCOLUMNID * pscid, VARIANT * pv)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
    FIXME ("(%p)\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI
IShellFolder_fnGetDetailsOf (IShellFolder2 * iface, LPCITEMIDLIST pidl,
                             UINT iColumn, SHELLDETAILS * psd)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
    HRESULT hr = E_FAIL;

    TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);

    if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS)
        return E_INVALIDARG;

    if (!pidl) {
        /* the header titles */
        psd->fmt = GenericSFHeader[iColumn].fmt;
        psd->cxChar = GenericSFHeader[iColumn].cxChar;
        psd->str.uType = STRRET_CSTR;
        LoadStringA (shell32_hInstance, GenericSFHeader[iColumn].colnameid,
         psd->str.u.cStr, MAX_PATH);
        return S_OK;
    } else {
        /* the data from the pidl */
        switch (iColumn) {
        case 0:                /* name */
            hr = IShellFolder_GetDisplayNameOf (iface, pidl,
             SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
            break;
        case 1:                /* size */
            _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
            break;
        case 2:                /* type */
            _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
            break;
        case 3:                /* date */
            _ILGetFileDate (pidl, psd->str.u.cStr, MAX_PATH);
            break;
        case 4:                /* attributes */
            _ILGetFileAttributes (pidl, psd->str.u.cStr, MAX_PATH);
            break;
        }
        hr = S_OK;
        psd->str.uType = STRRET_CSTR;
    }

    return hr;
}

static HRESULT WINAPI
IShellFolder_fnMapColumnToSCID (IShellFolder2 * iface, UINT column,
                                SHCOLUMNID * pscid)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
    FIXME ("(%p)\n", This);
    return E_NOTIMPL;
}

static IShellFolder2Vtbl sfvt =
{
    IShellFolder_fnQueryInterface,
    IShellFolder_fnAddRef,
    IShellFolder_fnRelease,
    IShellFolder_fnParseDisplayName,
    IShellFolder_fnEnumObjects,
    IShellFolder_fnBindToObject,
    IShellFolder_fnBindToStorage,
    IShellFolder_fnCompareIDs,
    IShellFolder_fnCreateViewObject,
    IShellFolder_fnGetAttributesOf,
    IShellFolder_fnGetUIObjectOf,
    IShellFolder_fnGetDisplayNameOf,
    IShellFolder_fnSetNameOf,
    /* ShellFolder2 */
    IShellFolder_fnGetDefaultSearchGUID,
    IShellFolder_fnEnumSearches,
    IShellFolder_fnGetDefaultColumn,
    IShellFolder_fnGetDefaultColumnState,
    IShellFolder_fnGetDetailsEx,
    IShellFolder_fnGetDetailsOf,
    IShellFolder_fnMapColumnToSCID
};

/****************************************************************************
 * ISFHelper for IShellFolder implementation
 */

static HRESULT WINAPI
ISFHelper_fnQueryInterface (ISFHelper * iface, REFIID riid, LPVOID * ppvObj)
{
    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);

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

    return IUnknown_QueryInterface (This->pUnkOuter, riid, ppvObj);
}

static ULONG WINAPI ISFHelper_fnAddRef (ISFHelper * iface)
{
    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);

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

    return IUnknown_AddRef (This->pUnkOuter);
}

static ULONG WINAPI ISFHelper_fnRelease (ISFHelper * iface)
{
    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);

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

    return IUnknown_Release (This->pUnkOuter);
}

/****************************************************************************
 * ISFHelper_fnAddFolder
 *
 * creates a unique folder name
 */

static HRESULT WINAPI
ISFHelper_fnGetUniqueName (ISFHelper * iface, LPSTR lpName, UINT uLen)
{
    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
    IEnumIDList *penum;
    HRESULT hr;
    char szText[MAX_PATH];
    char *szNewFolder = "New Folder";

    TRACE ("(%p)(%s %u)\n", This, lpName, uLen);

    if (uLen < strlen (szNewFolder) + 4)
        return E_POINTER;

    strcpy (lpName, szNewFolder);

    hr = IShellFolder_fnEnumObjects (_IShellFolder2_ (This), 0,
     SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
    if (penum) {
        LPITEMIDLIST pidl;
        DWORD dwFetched;
        int i = 1;

next:
        IEnumIDList_Reset (penum);
        while (S_OK == IEnumIDList_Next (penum, 1, &pidl, &dwFetched) &&
         dwFetched) {
            _ILSimpleGetText (pidl, szText, MAX_PATH);
            if (0 == strcasecmp (szText, lpName)) {
                sprintf (lpName, "%s %d", szNewFolder, i++);
                if (i > 99) {
                    hr = E_FAIL;
                    break;
                }
                goto next;
            }
        }

        IEnumIDList_Release (penum);
    }
    return hr;
}

/****************************************************************************
 * ISFHelper_fnAddFolder
 *
 * adds a new folder.
 */

static HRESULT WINAPI
ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCSTR lpName,
                       LPITEMIDLIST * ppidlOut)
{
    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
    char lpstrNewDir[MAX_PATH];
    DWORD bRes;
    HRESULT hres = E_FAIL;

    TRACE ("(%p)(%s %p)\n", This, lpName, ppidlOut);

    strcpy (lpstrNewDir, This->sPathTarget);
    PathAppendA(lpstrNewDir, lpName);

    bRes = CreateDirectoryA (lpstrNewDir, NULL);
    if (bRes) {
        SHChangeNotify (SHCNE_MKDIR, SHCNF_PATHA, lpstrNewDir, NULL);

        hres = S_OK;

        if (ppidlOut)
                hres = _ILCreateFromPathA(lpstrNewDir, ppidlOut);
    } else {
        char lpstrText[128 + MAX_PATH];
        char lpstrTempText[128];
        char lpstrCaption[256];

        /* Cannot Create folder because of permissions */
        LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText,
         sizeof (lpstrTempText));
        LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption,
         sizeof (lpstrCaption));
        sprintf (lpstrText, lpstrTempText, lpstrNewDir);
        MessageBoxA (hwnd, lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
    }

    return hres;
}

/****************************************************************************
 * ISFHelper_fnDeleteItems
 *
 * deletes items in folder
 */
static HRESULT WINAPI
ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
{
    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
    UINT i;
    char szPath[MAX_PATH];
    BOOL bConfirm = TRUE;

    TRACE ("(%p)(%u %p)\n", This, cidl, apidl);

    /* deleting multiple items so give a slightly different warning */
    if (cidl != 1) {
        char tmp[8];

        snprintf (tmp, sizeof (tmp), "%d", cidl);
        if (!SHELL_ConfirmDialog(ASK_DELETE_MULTIPLE_ITEM, tmp))
            return E_FAIL;
        bConfirm = FALSE;
    }

    for (i = 0; i < cidl; i++) {
        strcpy (szPath, This->sPathTarget);
        PathAddBackslashA (szPath);
        _ILSimpleGetText (apidl[i], szPath + strlen (szPath), MAX_PATH);

        if (_ILIsFolder (apidl[i])) {
            LPITEMIDLIST pidl;

            TRACE ("delete %s\n", szPath);
            if (!SHELL_DeleteDirectoryA (szPath, bConfirm)) {
                TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
                return E_FAIL;
            }
            pidl = ILCombine (This->pidlRoot, apidl[i]);
            SHChangeNotify (SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
            SHFree (pidl);
        } else if (_ILIsValue (apidl[i])) {
            LPITEMIDLIST pidl;

            TRACE ("delete %s\n", szPath);
            if (!SHELL_DeleteFileA (szPath, bConfirm)) {
                TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
                return E_FAIL;
            }
            pidl = ILCombine (This->pidlRoot, apidl[i]);
            SHChangeNotify (SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
            SHFree (pidl);
        }

    }
    return S_OK;
}

/****************************************************************************
 * ISFHelper_fnCopyItems
 *
 * copies items to this folder
 */
static HRESULT WINAPI
ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl,
                       LPCITEMIDLIST * apidl)
{
    UINT i;
    IPersistFolder2 *ppf2 = NULL;
    char szSrcPath[MAX_PATH],
      szDstPath[MAX_PATH];

    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);

    TRACE ("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);

    IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2,
     (LPVOID *) & ppf2);
    if (ppf2) {
        LPITEMIDLIST pidl;

        if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
            for (i = 0; i < cidl; i++) {
                SHGetPathFromIDListA (pidl, szSrcPath);
                PathAddBackslashA (szSrcPath);
                _ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath),
                 MAX_PATH);

                strcpy (szDstPath, This->sPathTarget);
                PathAddBackslashA (szDstPath);
                _ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath),
                 MAX_PATH);
                MESSAGE ("would copy %s to %s\n", szSrcPath, szDstPath);
            }
            SHFree (pidl);
        }
        IPersistFolder2_Release (ppf2);
    }
    return S_OK;
}

static ISFHelperVtbl shvt =
{
    ISFHelper_fnQueryInterface,
    ISFHelper_fnAddRef,
    ISFHelper_fnRelease,
    ISFHelper_fnGetUniqueName,
    ISFHelper_fnAddFolder,
    ISFHelper_fnDeleteItems,
    ISFHelper_fnCopyItems
};

/************************************************************************
 * IFSFldr_PersistFolder3_QueryInterface
 *
 */
static HRESULT WINAPI
IFSFldr_PersistFolder3_QueryInterface (IPersistFolder3 * iface, REFIID iid,
                                       LPVOID * ppvObj)
{
    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);

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

    return IUnknown_QueryInterface (This->pUnkOuter, iid, ppvObj);
}

/************************************************************************
 * IFSFldr_PersistFolder3_AddRef
 *
 */
static ULONG WINAPI
IFSFldr_PersistFolder3_AddRef (IPersistFolder3 * iface)
{
    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);

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

    return IUnknown_AddRef (This->pUnkOuter);
}

/************************************************************************
 * IFSFldr_PersistFolder3_Release
 *
 */
static ULONG WINAPI
IFSFldr_PersistFolder3_Release (IPersistFolder3 * iface)
{
    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);

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

    return IUnknown_Release (This->pUnkOuter);
}

/************************************************************************
 * IFSFldr_PersistFolder3_GetClassID
 */
static HRESULT WINAPI
IFSFldr_PersistFolder3_GetClassID (IPersistFolder3 * iface, CLSID * lpClassId)
{
    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);

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

    if (!lpClassId)
        return E_POINTER;
    *lpClassId = *This->pclsid;

    return S_OK;
}

/************************************************************************
 * IFSFldr_PersistFolder3_Initialize
 *
 * NOTES
 *  sPathTarget is not set. Don't know how to handle in a non rooted environment.
 */
static HRESULT WINAPI
IFSFldr_PersistFolder3_Initialize (IPersistFolder3 * iface, LPCITEMIDLIST pidl)
{
    char sTemp[MAX_PATH];

    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);

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

    if (This->pidlRoot)
        SHFree (This->pidlRoot);     /* free the old pidl */
    This->pidlRoot = ILClone (pidl); /* set my pidl */

    if (This->sPathTarget)
        SHFree (This->sPathTarget);

    /* set my path */
    if (SHGetPathFromIDListA (pidl, sTemp)) {
        This->sPathTarget = SHAlloc (strlen (sTemp) + 1);
        strcpy (This->sPathTarget, sTemp);
    }

    TRACE ("--(%p)->(%s)\n", This, This->sPathTarget);
    return S_OK;
}

/**************************************************************************
 * IFSFldr_PersistFolder3_GetCurFolder
 */
static HRESULT WINAPI
IFSFldr_PersistFolder3_fnGetCurFolder (IPersistFolder3 * iface,
                                       LPITEMIDLIST * pidl)
{
    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);

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

    if (!pidl) return E_POINTER;
    *pidl = ILClone (This->pidlRoot);
    return S_OK;
}

/**************************************************************************
 * IFSFldr_PersistFolder3_InitializeEx
 *
 * FIXME: error handling
 */
static HRESULT WINAPI
IFSFldr_PersistFolder3_InitializeEx (IPersistFolder3 * iface,
                                     IBindCtx * pbc, LPCITEMIDLIST pidlRoot,
                                     const PERSIST_FOLDER_TARGET_INFO * ppfti)
{
    char sTemp[MAX_PATH];

    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);

    TRACE ("(%p)->(%p,%p,%p)\n", This, pbc, pidlRoot, ppfti);
    if (ppfti)
        TRACE ("--%p %s %s 0x%08lx 0x%08x\n",
         ppfti->pidlTargetFolder, debugstr_w (ppfti->szTargetParsingName),
         debugstr_w (ppfti->szNetworkProvider), ppfti->dwAttributes,
         ppfti->csidl);

    pdump (pidlRoot);
    if (ppfti && ppfti->pidlTargetFolder)
        pdump (ppfti->pidlTargetFolder);

    if (This->pidlRoot)
        __SHFreeAndNil (&This->pidlRoot);    /* free the old */
    if (This->sPathTarget)
        __SHFreeAndNil (&This->sPathTarget);

    /*
     * Root path and pidl
     */
    This->pidlRoot = ILClone (pidlRoot);

    /*
     *  the target folder is spezified in csidl OR pidlTargetFolder OR
     *  szTargetParsingName
     */
    if (ppfti) {
        if (ppfti->csidl != -1) {
            if (SHGetSpecialFolderPathA (0, sTemp, ppfti->csidl,
             ppfti->csidl & CSIDL_FLAG_CREATE)) {
                __SHCloneStrA (&This->sPathTarget, sTemp);
            }
        } else if (ppfti->szTargetParsingName[0]) {
            __SHCloneStrWtoA (&This->sPathTarget, ppfti->szTargetParsingName);
        } else if (ppfti->pidlTargetFolder) {
            if (SHGetPathFromIDListA (ppfti->pidlTargetFolder, sTemp)) {
                __SHCloneStrA (&This->sPathTarget, sTemp);
            }
        }
    }

    TRACE ("--(%p)->(target=%s)\n", This, debugstr_a (This->sPathTarget));
    pdump (This->pidlRoot);
    return (This->sPathTarget) ? S_OK : E_FAIL;
}

static HRESULT WINAPI
IFSFldr_PersistFolder3_GetFolderTargetInfo (IPersistFolder3 * iface,
                                            PERSIST_FOLDER_TARGET_INFO * ppfti)
{
    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
    FIXME ("(%p)->(%p)\n", This, ppfti);
    ZeroMemory (ppfti, sizeof (ppfti));
    return E_NOTIMPL;
}

static IPersistFolder3Vtbl vt_FSFldr_PersistFolder3 =
{
    IFSFldr_PersistFolder3_QueryInterface,
    IFSFldr_PersistFolder3_AddRef,
    IFSFldr_PersistFolder3_Release,
    IFSFldr_PersistFolder3_GetClassID,
    IFSFldr_PersistFolder3_Initialize,
    IFSFldr_PersistFolder3_fnGetCurFolder,
    IFSFldr_PersistFolder3_InitializeEx,
    IFSFldr_PersistFolder3_GetFolderTargetInfo
};

/****************************************************************************
 * ISFDropTarget implementation
 */
static BOOL
ISFDropTarget_QueryDrop (IDropTarget * iface, DWORD dwKeyState,
                         LPDWORD pdwEffect)
{
    DWORD dwEffect = *pdwEffect;

    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);

    *pdwEffect = DROPEFFECT_NONE;

    if (This->fAcceptFmt) { /* Does our interpretation of the keystate ... */
        *pdwEffect = KeyStateToDropEffect (dwKeyState);

        /* ... matches the desired effect ? */
        if (dwEffect & *pdwEffect) {
            return TRUE;
        }
    }
    return FALSE;
}

static HRESULT WINAPI
ISFDropTarget_QueryInterface (IDropTarget * iface, REFIID riid, LPVOID * ppvObj)
{
    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);

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

    return IUnknown_QueryInterface (This->pUnkOuter, riid, ppvObj);
}

static ULONG WINAPI ISFDropTarget_AddRef (IDropTarget * iface)
{
    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);

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

    return IUnknown_AddRef (This->pUnkOuter);
}

static ULONG WINAPI ISFDropTarget_Release (IDropTarget * iface)
{
    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);

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

    return IUnknown_Release (This->pUnkOuter);
}

static HRESULT WINAPI
ISFDropTarget_DragEnter (IDropTarget * iface, IDataObject * pDataObject,
                         DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
{
    FORMATETC fmt;

    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);

    TRACE ("(%p)->(DataObject=%p)\n", This, pDataObject);

    InitFormatEtc (fmt, This->cfShellIDList, TYMED_HGLOBAL);

    This->fAcceptFmt = (S_OK == IDataObject_QueryGetData (pDataObject, &fmt)) ?
     TRUE : FALSE;

    ISFDropTarget_QueryDrop (iface, dwKeyState, pdwEffect);

    return S_OK;
}

static HRESULT WINAPI
ISFDropTarget_DragOver (IDropTarget * iface, DWORD dwKeyState, POINTL pt,
                        DWORD * pdwEffect)
{
    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);

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

    if (!pdwEffect)
        return E_INVALIDARG;

    ISFDropTarget_QueryDrop (iface, dwKeyState, pdwEffect);

    return S_OK;
}

static HRESULT WINAPI ISFDropTarget_DragLeave (IDropTarget * iface)
{
    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);

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

    This->fAcceptFmt = FALSE;

    return S_OK;
}

static HRESULT WINAPI
ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject,
                    DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
{
    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);

    FIXME ("(%p) object dropped\n", This);

    return E_NOTIMPL;
}

static struct IDropTargetVtbl dtvt = {
    ISFDropTarget_QueryInterface,
    ISFDropTarget_AddRef,
    ISFDropTarget_Release,
    ISFDropTarget_DragEnter,
    ISFDropTarget_DragOver,
    ISFDropTarget_DragLeave,
    ISFDropTarget_Drop
};
