
/*
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 "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 {
    IUnknown IUnknown_inner;
    LONG ref;
    IShellFolder2 IShellFolder2_iface;
    IPersistFolder3 IPersistFolder3_iface;
    IDropTarget IDropTarget_iface;
    ISFHelper ISFHelper_iface;
    IUnknown *outer_unk;

    CLSID *pclsid;

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

    LPITEMIDLIST pidlRoot; /* absolute pidl */

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

static inline IGenericSFImpl *impl_from_IUnknown(IUnknown *iface)
{
    return CONTAINING_RECORD(iface, IGenericSFImpl, IUnknown_inner);
}

static inline IGenericSFImpl *impl_from_IShellFolder2(IShellFolder2 *iface)
{
    return CONTAINING_RECORD(iface, IGenericSFImpl, IShellFolder2_iface);
}

static inline IGenericSFImpl *impl_from_IPersistFolder3(IPersistFolder3 *iface)
{
    return CONTAINING_RECORD(iface, IGenericSFImpl, IPersistFolder3_iface);
}

static inline IGenericSFImpl *impl_from_IDropTarget(IDropTarget *iface)
{
    return CONTAINING_RECORD(iface, IGenericSFImpl, IDropTarget_iface);
}

static inline IGenericSFImpl *impl_from_ISFHelper(ISFHelper *iface)
{
    return CONTAINING_RECORD(iface, IGenericSFImpl, ISFHelper_iface);
}

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

    if (!This->cfShellIDList) {
        This->cfShellIDList = RegisterClipboardFormatW (CFSTR_SHELLIDLISTW);
    }
}

/**************************************************************************
* inner IUnknown
*/
static HRESULT WINAPI IUnknown_fnQueryInterface(IUnknown *iface, REFIID riid, void **ppvObj)
{
    IGenericSFImpl *This = impl_from_IUnknown(iface);

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

    *ppvObj = NULL;

    if (IsEqualIID (riid, &IID_IUnknown))
        *ppvObj = &This->IUnknown_inner;
    else if (IsEqualIID(riid, &IID_IShellFolder) || IsEqualIID(riid, &IID_IShellFolder2))
        *ppvObj = &This->IShellFolder2_iface;
    else if (IsEqualIID(riid, &IID_IPersist) || IsEqualIID(riid, &IID_IPersistFolder) ||
            IsEqualIID(riid, &IID_IPersistFolder2) || IsEqualIID(riid, &IID_IPersistFolder3))
        *ppvObj = &This->IPersistFolder3_iface;
    else if (IsEqualIID (riid, &IID_ISFHelper))
        *ppvObj = &This->ISFHelper_iface;
    else if (IsEqualIID (riid, &IID_IDropTarget)) {
        *ppvObj = &This->IDropTarget_iface;
        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 = impl_from_IUnknown(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

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

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

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

        SHFree(This->pidlRoot);
        SHFree(This->sPathTarget);
        LocalFree(This);
    }
    return ref;
}

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

static const 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

/**************************************************************************
 *  IShellFolder_fnQueryInterface
 */
static HRESULT WINAPI IShellFolder_fnQueryInterface(IShellFolder2 *iface, REFIID riid,
        void **ppvObj)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);

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

/**************************************************************************
*  IShellFolder_AddRef
*/
static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 *iface)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);

    return IUnknown_AddRef(This->outer_unk);
}

/**************************************************************************
 *  IShellFolder_fnRelease
 */
static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 *iface)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);

    return IUnknown_Release(This->outer_unk);
}

/**************************************************************************
 *  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 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 *unk = NULL;
    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, szfsbc, &unk );
    if (FAILED(r))
        return NULL;

    r = IUnknown_QueryInterface( unk, &IID_IFileSystemBindData, (void**)&fsbd );
    if (SUCCEEDED(r))
    {
        WIN32_FIND_DATAW wfd;

        r = IFileSystemBindData_GetFindData( fsbd, &wfd );
        if (SUCCEEDED(r))
        {
            lstrcpynW( &wfd.cFileName[0], path, MAX_PATH );
            pidl = _ILCreateFromFindDataW( &wfd );
        }
        IFileSystemBindData_Release( fsbd );
    }
    IUnknown_Release( unk );
    
    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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(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 */
        lstrcpynW(szPath, This->sPathTarget, MAX_PATH - 1);
        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->IShellFolder2_iface,
                            pidlTemp, pdwAttributes);
                }
            }
        }
    }

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

    TRACE ("(%p)->(-- pidl=%p ret=0x%08x)\n", This, *ppidl, 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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);
    IEnumIDListImpl *list;

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

    if (!(list = IEnumIDList_Constructor()))
        return E_OUTOFMEMORY;
    CreateFolderEnumList(list, This->sPathTarget, dwFlags);
    *ppEnumIDList = &list->IEnumIDList_iface;

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

    return S_OK;
}

/**************************************************************************
* 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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);

    int nReturn;

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

/**************************************************************************
* IShellFolder_fnCreateViewObject
*/
static HRESULT WINAPI
IShellFolder_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner,
                                 REFIID riid, LPVOID * ppvOut)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(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 = IShellFolder2_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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);

    HRESULT hr = S_OK;

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

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

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

    if(cidl == 0){
        IShellFolder *psfParent = NULL;
        LPCITEMIDLIST rpidl = NULL;

        hr = SHBindToParent(This->pidlRoot, &IID_IShellFolder, (LPVOID*)&psfParent, &rpidl);
        if(SUCCEEDED(hr)) {
            SHELL32_GetItemAttributes (psfParent, rpidl, rgfInOut);
            IShellFolder_Release(psfParent);
        }
    }
    else {
        while (cidl > 0 && *apidl) {
            pdump (*apidl);
            SHELL32_GetItemAttributes((IShellFolder *)&This->IShellFolder2_iface, *apidl, rgfInOut);
            apidl++;
            cidl--;
        }
    }
    /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
    *rgfInOut &= ~SFGAO_VALIDATE;

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

    return hr;
}

/**************************************************************************
 * SHELL32_CreateExtensionUIObject (internal)
 */
HRESULT SHELL32_CreateExtensionUIObject(IShellFolder2 *iface,
        LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppvOut)
{
    static const WCHAR reg_blockedW[] = {'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','\\',
        'S','h','e','l','l',' ','E','x','t','e','n','s','i','o','n','s','\\',
        'B','l','o','c','k','e','d',0};
    static const WCHAR formatW[] = {'.','%','s','\\','S','h','e','l','l','E','x','\\',
        '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
        '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x',
        '%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x','}',0};

    IPersistFile *persist_file;
    char extensionA[20];
    WCHAR extensionW[20], buf[MAX_PATH];
    DWORD size = MAX_PATH;
    STRRET path;
    WCHAR *file;
    GUID guid;
    HKEY key;
    HRESULT hr;


    if(!_ILGetExtension(pidl, extensionA, 20))
        return S_FALSE;

    MultiByteToWideChar(CP_ACP, 0, extensionA, -1, extensionW, 20);

    sprintfW(buf, formatW, extensionW, riid->Data1, riid->Data2, riid->Data3,
            riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
            riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);

    if(RegGetValueW(HKEY_CLASSES_ROOT, buf, NULL, RRF_RT_REG_SZ,
                NULL, buf, &size) != ERROR_SUCCESS)
        return S_FALSE;

    if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, reg_blockedW, 0, 0, 0,
                KEY_READ, NULL, &key, NULL) != ERROR_SUCCESS)
        return E_FAIL;
    if(RegQueryValueExW(key, buf, 0, NULL, NULL, NULL)
            != ERROR_FILE_NOT_FOUND)
        return E_ACCESSDENIED;
    RegCloseKey(key);

    if(RegCreateKeyExW(HKEY_CURRENT_USER, reg_blockedW, 0, 0, 0,
                KEY_READ, NULL, &key, NULL) != ERROR_SUCCESS)
        return E_FAIL;
    if(RegQueryValueExW(key, buf, 0, NULL, NULL, NULL)
            != ERROR_FILE_NOT_FOUND)
        return E_ACCESSDENIED;
    RegCloseKey(key);

    if(!GUIDFromStringW(buf, &guid))
        return E_FAIL;

    hr = CoCreateInstance(&guid, NULL, CLSCTX_INPROC_SERVER,
            &IID_IPersistFile, (void**)&persist_file);
    if(FAILED(hr))
        return hr;

    hr = IShellFolder2_GetDisplayNameOf(iface, pidl, SHGDN_FORPARSING, &path);
    if(SUCCEEDED(hr))
        hr = StrRetToStrW(&path, NULL, &file);
    if(FAILED(hr)) {
        IPersistFile_Release(persist_file);
        return hr;
    }

    hr = IPersistFile_Load(persist_file, file, STGM_READ);
    CoTaskMemFree(file);
    if(FAILED(hr)) {
        IPersistFile_Release(persist_file);
        return hr;
    }

    hr = IPersistFile_QueryInterface(persist_file, riid, ppvOut);
    IPersistFile_Release(persist_file);
    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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(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(cidl == 1) {
            hr = SHELL32_CreateExtensionUIObject(iface, *apidl, riid, ppvOut);
            if(hr != S_FALSE)
                return hr;
        }

        if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
            return ItemMenu_Constructor((IShellFolder*)iface, This->pidlRoot, apidl, cidl, riid, ppvOut);
        } 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 = IShellFolder2_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, &pObj);
            SHFree (pidl);
        } else {
            hr = E_NOINTERFACE;
        }

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

        *ppvOut = pObj;
    }
    TRACE ("(%p)->hr=0x%08x\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 };

/******************************************************************************
 * SHELL_FS_HideExtension [Internal]
 *
 * Query the registry if the filename extension of a given path should be 
 * hidden.
 *
 * PARAMS
 *  szPath [I] Relative or absolute path of a file
 *  
 * RETURNS
 *  TRUE, if the filename's extension should be hidden
 *  FALSE, otherwise.
 */
BOOL SHELL_FS_HideExtension(LPCWSTR szPath)
{
    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) {
        LPWSTR ext = PathFindExtensionW(szPath);

        if (*ext != '\0') {
            WCHAR classname[MAX_PATH];
            LONG classlen = sizeof(classname);

            if (!RegQueryValueW(HKEY_CLASSES_ROOT, ext, classname, &classlen))
                if (!RegOpenKeyW(HKEY_CLASSES_ROOT, classname, &hKey)) {
                    if (!RegQueryValueExW(hKey, NeverShowExtW, 0, NULL, NULL, NULL))
                        doHide = TRUE;
                    RegCloseKey(hKey);
                }
        }
    }
    return doHide;
}
    
void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags)
{
    /*FIXME: MSDN also mentions SHGDN_FOREDITING which is not yet handled. */
    if (!(dwFlags & SHGDN_FORPARSING) &&
        ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) {
        if (SHELL_FS_HideExtension(szPath) && szPath[0] != '.')
            PathRemoveExtensionW(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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);
    LPWSTR pszPath;

    HRESULT hr = S_OK;
    int len = 0;

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

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

    pszPath = CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR));
    if (!pszPath)
        return E_OUTOFMEMORY;

    if (_ILIsDesktop(pidl)) { /* empty pidl */
        if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
            (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER)) 
        {
            if (This->sPathTarget)
                lstrcpynW(pszPath, This->sPathTarget, MAX_PATH);
        } else {
            /* pidl has to contain exactly one non null SHITEMID */
            hr = E_INVALIDARG;
        }
    } else if (_ILIsPidlSimple(pidl)) {
        if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
            (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) && 
            This->sPathTarget) 
        {
            lstrcpynW(pszPath, This->sPathTarget, MAX_PATH);
            PathAddBackslashW(pszPath);
            len = lstrlenW(pszPath);
        }
        _ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len);
        if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
    } else {
        hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, pszPath, MAX_PATH);
    }

    if (SUCCEEDED(hr)) {
        /* Win9x always returns ANSI strings, NT always returns Unicode strings */
        if (GetVersion() & 0x80000000) {
            strRet->uType = STRRET_CSTR;
            if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->u.cStr, MAX_PATH,
                 NULL, NULL))
                strRet->u.cStr[0] = '\0';
            CoTaskMemFree(pszPath);
        } else {
            strRet->uType = STRRET_WSTR;
            strRet->u.pOleStr = pszPath;
        }
    } else
        CoTaskMemFree(pszPath);

    TRACE ("-- (%p)->(%s)\n", This, strRet->uType == STRRET_CSTR ? strRet->u.cStr : debugstr_w(strRet->u.pOleStr));
    return hr;
}

/**************************************************************************
*  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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);
    WCHAR szSrc[MAX_PATH + 1], szDest[MAX_PATH + 1];
    LPWSTR ptr;
    BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl));

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

    /* build source path */
    lstrcpynW(szSrc, This->sPathTarget, MAX_PATH);
    ptr = PathAddBackslashW (szSrc);
    if (ptr)
        _ILSimpleGetTextW (pidl, ptr, MAX_PATH + 1 - (ptr - szSrc));

    /* build destination path */
    if (dwFlags == SHGDN_NORMAL || dwFlags & SHGDN_INFOLDER) {
        lstrcpynW(szDest, This->sPathTarget, MAX_PATH);
        ptr = PathAddBackslashW (szDest);
        if (ptr)
            lstrcpynW(ptr, lpName, MAX_PATH + 1 - (ptr - szDest));
    } else
        lstrcpynW(szDest, lpName, MAX_PATH);

    if(!(dwFlags & SHGDN_FORPARSING) && SHELL_FS_HideExtension(szSrc)) {
        WCHAR *ext = PathFindExtensionW(szSrc);
        if(*ext != '\0') {
            INT len = strlenW(szDest);
            lstrcpynW(szDest + len, ext, MAX_PATH - len);
        }
    }
    
    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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);
    FIXME ("(%p)\n", This);
    return E_NOTIMPL;
}
static HRESULT WINAPI IShellFolder_fnEnumSearches (IShellFolder2 * iface,
                                                   IEnumExtraSearch ** ppenum)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);
    FIXME ("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI
IShellFolder_fnGetDefaultColumn (IShellFolder2 * iface, DWORD dwRes,
                                 ULONG * pSort, ULONG * pDisplay)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(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)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(iface);
    FIXME ("(%p)\n", This);

    return E_NOTIMPL;
}

static HRESULT WINAPI
IShellFolder_fnGetDetailsOf (IShellFolder2 * iface, LPCITEMIDLIST pidl,
                             UINT iColumn, SHELLDETAILS * psd)
{
    IGenericSFImpl *This = impl_from_IShellFolder2(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 {
        hr = S_OK;
        psd->str.uType = STRRET_CSTR;
        /* the data from the pidl */
        switch (iColumn) {
        case 0:                /* name */
            hr = IShellFolder2_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;
        }
    }

    return hr;
}

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

static const 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, void **ppvObj)
{
    IGenericSFImpl *This = impl_from_ISFHelper(iface);

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

static ULONG WINAPI ISFHelper_fnAddRef(ISFHelper *iface)
{
    IGenericSFImpl *This = impl_from_ISFHelper(iface);

    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI ISFHelper_fnRelease(ISFHelper *iface)
{
    IGenericSFImpl *This = impl_from_ISFHelper(iface);

    return IUnknown_Release(This->outer_unk);
}

/****************************************************************************
 * ISFHelper_fnGetUniqueName
 *
 * creates a unique folder name
 */

static HRESULT WINAPI
ISFHelper_fnGetUniqueName (ISFHelper * iface, LPWSTR pwszName, UINT uLen)
{
    IGenericSFImpl *This = impl_from_ISFHelper(iface);
    IEnumIDList *penum;
    HRESULT hr;
    WCHAR wszText[MAX_PATH];
    WCHAR wszNewFolder[25];
    const WCHAR wszFormat[] = {'%','s',' ','%','d',0 };

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

    LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder,  sizeof(wszNewFolder)/sizeof(WCHAR));
    if (uLen < sizeof(wszNewFolder)/sizeof(WCHAR) + 3)
        return E_POINTER;

    lstrcpynW (pwszName, wszNewFolder, uLen);

    hr = IShellFolder2_EnumObjects(&This->IShellFolder2_iface, 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) {
            _ILSimpleGetTextW (pidl, wszText, MAX_PATH);
            if (0 == lstrcmpiW (wszText, pwszName)) {
                snprintfW (pwszName, uLen, wszFormat, wszNewFolder, 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, LPCWSTR pwszName,
                       LPITEMIDLIST * ppidlOut)
{
    IGenericSFImpl *This = impl_from_ISFHelper(iface);
    WCHAR wszNewDir[MAX_PATH];
    DWORD bRes;
    HRESULT hres = E_FAIL;

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

    wszNewDir[0] = 0;
    if (This->sPathTarget)
        lstrcpynW(wszNewDir, This->sPathTarget, MAX_PATH);
    PathAppendW(wszNewDir, pwszName);

    bRes = CreateDirectoryW (wszNewDir, NULL);
    if (bRes) {
        LPITEMIDLIST relPidl;

        lstrcpyW(wszNewDir, pwszName);

        hres = IShellFolder2_ParseDisplayName(&This->IShellFolder2_iface, hwnd, NULL, wszNewDir,
                NULL, &relPidl, NULL);

        if (SUCCEEDED(hres)) {
            LPITEMIDLIST fullPidl;

            fullPidl = ILCombine(This->pidlRoot, relPidl);

            if (fullPidl) {
                SHChangeNotify(SHCNE_MKDIR, SHCNF_IDLIST, fullPidl, NULL);
                ILFree(fullPidl);

                if (ppidlOut)
                    *ppidlOut = relPidl;
                else
                    ILFree(relPidl);
            } else {
                WARN("failed to combine %s into a full PIDL\n", wine_dbgstr_w(pwszName));
                ILFree(relPidl);
            }

        } else
            WARN("failed to parse %s into a PIDL\n", wine_dbgstr_w(pwszName));

    } else {
        WCHAR wszText[128 + MAX_PATH];
        WCHAR wszTempText[128];
        WCHAR wszCaption[256];

        /* Cannot Create folder because of permissions */
        LoadStringW (shell32_hInstance, IDS_CREATEFOLDER_DENIED, wszTempText,
         sizeof (wszTempText)/sizeof (wszTempText[0]));
        LoadStringW (shell32_hInstance, IDS_CREATEFOLDER_CAPTION, wszCaption,
         sizeof (wszCaption)/sizeof (wszCaption[0]));
        sprintfW (wszText, wszTempText, wszNewDir);
        MessageBoxW (hwnd, wszText, wszCaption, MB_OK | MB_ICONEXCLAMATION);
    }

    return hres;
}

/****************************************************************************
 * build_paths_list
 *
 * Builds a list of paths like the one used in SHFileOperation from a table of
 * PIDLs relative to the given base folder
 */
static WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, const LPCITEMIDLIST *pidls)
{
    WCHAR *wszPathsList;
    WCHAR *wszListPos;
    int iPathLen;
    int i;
    
    iPathLen = lstrlenW(wszBasePath);
    wszPathsList = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR)*cidl+1);
    wszListPos = wszPathsList;
    
    for (i = 0; i < cidl; i++) {
        if (!_ILIsFolder(pidls[i]) && !_ILIsValue(pidls[i]))
            continue;

        lstrcpynW(wszListPos, wszBasePath, MAX_PATH);
        /* FIXME: abort if path too long */
        _ILSimpleGetTextW(pidls[i], wszListPos+iPathLen, MAX_PATH-iPathLen);
        wszListPos += lstrlenW(wszListPos)+1;
    }
    *wszListPos=0;
    return wszPathsList;
}

/****************************************************************************
 * ISFHelper_fnDeleteItems
 *
 * deletes items in folder
 */
static HRESULT WINAPI
ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
{
    IGenericSFImpl *This = impl_from_ISFHelper(iface);
    UINT i;
    SHFILEOPSTRUCTW op;
    WCHAR wszPath[MAX_PATH];
    WCHAR *wszPathsList;
    HRESULT ret;
    WCHAR *wszCurrentPath;

    TRACE ("(%p)(%u %p)\n", This, cidl, apidl);
    if (cidl==0) return S_OK;

    if (This->sPathTarget)
        lstrcpynW(wszPath, This->sPathTarget, MAX_PATH);
    else
        wszPath[0] = '\0';
    PathAddBackslashW(wszPath);
    wszPathsList = build_paths_list(wszPath, cidl, apidl);

    ZeroMemory(&op, sizeof(op));
    op.hwnd = GetActiveWindow();
    op.wFunc = FO_DELETE;
    op.pFrom = wszPathsList;
    op.fFlags = FOF_ALLOWUNDO;
    if (SHFileOperationW(&op))
    {
        WARN("SHFileOperation failed\n");
        ret = E_FAIL;
    }
    else
        ret = S_OK;

    /* we currently need to manually send the notifies */
    wszCurrentPath = wszPathsList;
    for (i = 0; i < cidl; i++)
    {
        LONG wEventId;

        if (_ILIsFolder(apidl[i]))
            wEventId = SHCNE_RMDIR;
        else if (_ILIsValue(apidl[i]))
            wEventId = SHCNE_DELETE;
        else
            continue;

        /* check if file exists */
        if (GetFileAttributesW(wszCurrentPath) == INVALID_FILE_ATTRIBUTES)
        {
            LPITEMIDLIST pidl = ILCombine(This->pidlRoot, apidl[i]);
            SHChangeNotify(wEventId, SHCNF_IDLIST, pidl, NULL);
            SHFree(pidl);
        }

        wszCurrentPath += lstrlenW(wszCurrentPath)+1;
    }
    HeapFree(GetProcessHeap(), 0, wszPathsList);
    return ret;
}

/****************************************************************************
 * ISFHelper_fnCopyItems
 *
 * copies items to this folder
 */
static HRESULT WINAPI
ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl,
                       LPCITEMIDLIST * apidl)
{
    HRESULT ret=E_FAIL;
    IPersistFolder2 *ppf2 = NULL;
    WCHAR wszSrcPathRoot[MAX_PATH],
      wszDstPath[MAX_PATH+1];
    WCHAR *wszSrcPathsList;
    IGenericSFImpl *This = impl_from_ISFHelper(iface);

    SHFILEOPSTRUCTW fop;

    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))) {
            SHGetPathFromIDListW (pidl, wszSrcPathRoot);
            ZeroMemory(wszDstPath, MAX_PATH+1);
            if (This->sPathTarget)
                lstrcpynW(wszDstPath, This->sPathTarget, MAX_PATH);
            PathAddBackslashW(wszSrcPathRoot);
            PathAddBackslashW(wszDstPath);
            wszSrcPathsList = build_paths_list(wszSrcPathRoot, cidl, apidl);
            ZeroMemory(&fop, sizeof(fop));
            fop.hwnd = GetActiveWindow();
            fop.wFunc = FO_COPY;
            fop.pFrom = wszSrcPathsList;
            fop.pTo = wszDstPath;
            fop.fFlags = FOF_ALLOWUNDO;
            ret = S_OK;
            if(SHFileOperationW(&fop))
            {
                WARN("Copy failed\n");
                ret = E_FAIL;
            }
            HeapFree(GetProcessHeap(), 0, wszSrcPathsList);

        }
        SHFree(pidl);
        IPersistFolder2_Release(ppf2);
    }
    return ret;
}

static const 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,
        void **ppv)
{
    IGenericSFImpl *This = impl_from_IPersistFolder3(iface);

    return IUnknown_QueryInterface(This->outer_unk, iid, ppv);
}

/************************************************************************
 * IFSFldr_PersistFolder3_AddRef
 *
 */
static ULONG WINAPI IFSFldr_PersistFolder3_AddRef(IPersistFolder3 *iface)
{
    IGenericSFImpl *This = impl_from_IPersistFolder3(iface);

    return IUnknown_AddRef(This->outer_unk);
}

/************************************************************************
 * IFSFldr_PersistFolder3_Release
 *
 */
static ULONG WINAPI IFSFldr_PersistFolder3_Release(IPersistFolder3 *iface)
{
    IGenericSFImpl *This = impl_from_IPersistFolder3(iface);

    return IUnknown_Release(This->outer_unk);
}

/************************************************************************
 * IFSFldr_PersistFolder3_GetClassID
 */
static HRESULT WINAPI
IFSFldr_PersistFolder3_GetClassID (IPersistFolder3 * iface, CLSID * lpClassId)
{
    IGenericSFImpl *This = impl_from_IPersistFolder3(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)
{
    WCHAR wszTemp[MAX_PATH];

    IGenericSFImpl *This = impl_from_IPersistFolder3(iface);

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

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

    SHFree (This->sPathTarget);
    This->sPathTarget = NULL;

    /* set my path */
    if (SHGetPathFromIDListW (pidl, wszTemp)) {
        int len = strlenW(wszTemp);
        This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
        if (!This->sPathTarget)
            return E_OUTOFMEMORY;
        memcpy(This->sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR));
    }

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

/**************************************************************************
 * IFSFldr_PersistFolder3_GetCurFolder
 */
static HRESULT WINAPI
IFSFldr_PersistFolder3_fnGetCurFolder (IPersistFolder3 * iface,
                                       LPITEMIDLIST * pidl)
{
    IGenericSFImpl *This = impl_from_IPersistFolder3(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)
{
    WCHAR wszTemp[MAX_PATH];

    IGenericSFImpl *This = impl_from_IPersistFolder3(iface);

    TRACE ("(%p)->(%p,%p,%p)\n", This, pbc, pidlRoot, ppfti);
    if (ppfti)
        TRACE ("--%p %s %s 0x%08x 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 specified in csidl OR pidlTargetFolder OR
     *  szTargetParsingName
     */
    if (ppfti) {
        if (ppfti->csidl != -1) {
            if (SHGetSpecialFolderPathW (0, wszTemp, ppfti->csidl,
             ppfti->csidl & CSIDL_FLAG_CREATE)) {
                int len = strlenW(wszTemp);
                This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
                if (!This->sPathTarget)
                    return E_OUTOFMEMORY;
                memcpy(This->sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR));
            }
        } else if (ppfti->szTargetParsingName[0]) {
            int len = strlenW(ppfti->szTargetParsingName);
            This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
            if (!This->sPathTarget)
                return E_OUTOFMEMORY;
            memcpy(This->sPathTarget, ppfti->szTargetParsingName,
                   (len + 1) * sizeof(WCHAR));
        } else if (ppfti->pidlTargetFolder) {
            if (SHGetPathFromIDListW(ppfti->pidlTargetFolder, wszTemp)) {
                int len = strlenW(wszTemp);
                This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
                if (!This->sPathTarget)
                    return E_OUTOFMEMORY;
                memcpy(This->sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR));
            }
        }
    }

    TRACE ("--(%p)->(target=%s)\n", This, debugstr_w(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)
{
    IGenericSFImpl *This = impl_from_IPersistFolder3(iface);
    FIXME ("(%p)->(%p)\n", This, ppfti);
    ZeroMemory (ppfti, sizeof (*ppfti));
    return E_NOTIMPL;
}

static const IPersistFolder3Vtbl pfvt =
{
    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 HRESULT WINAPI ISFDropTarget_QueryInterface(IDropTarget *iface, REFIID riid, void **ppv)
{
    IGenericSFImpl *This = impl_from_IDropTarget(iface);

    return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}

static ULONG WINAPI ISFDropTarget_AddRef(IDropTarget *iface)
{
    IGenericSFImpl *This = impl_from_IDropTarget(iface);

    return IUnknown_AddRef(This->outer_unk);
}

static ULONG WINAPI ISFDropTarget_Release(IDropTarget *iface)
{
    IGenericSFImpl *This = impl_from_IDropTarget(iface);

    return IUnknown_Release(This->outer_unk);
}

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

    IGenericSFImpl *This = impl_from_IDropTarget(iface);

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

    InitFormatEtc (fmt, This->cfShellIDList, TYMED_HGLOBAL);
    This->fAcceptFmt = IDataObject_QueryGetData (pDataObject, &fmt) == S_OK;
    if (This->fAcceptFmt)
        *pdwEffect = KeyStateToDropEffect(dwKeyState);
    else
        *pdwEffect = DROPEFFECT_NONE;

    return S_OK;
}

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

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

    if (!pdwEffect)
        return E_INVALIDARG;

    if (This->fAcceptFmt)
        *pdwEffect = KeyStateToDropEffect(dwKeyState);
    else
        *pdwEffect = DROPEFFECT_NONE;

    return S_OK;
}

static HRESULT WINAPI ISFDropTarget_DragLeave (IDropTarget * iface)
{
    IGenericSFImpl *This = impl_from_IDropTarget(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)
{
    IGenericSFImpl *This = impl_from_IDropTarget(iface);

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

    return E_NOTIMPL;
}

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

HRESULT WINAPI IFSFolder_Constructor(IUnknown *outer_unk, REFIID riid, void **ppv)
{
    IGenericSFImpl *sf;
    HRESULT hr;

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

    if (outer_unk && !IsEqualIID(riid, &IID_IUnknown))
        return CLASS_E_NOAGGREGATION;

    sf = LocalAlloc(LMEM_ZEROINIT, sizeof(*sf));
    if (!sf)
        return E_OUTOFMEMORY;

    sf->ref = 1;
    sf->IUnknown_inner.lpVtbl = &unkvt;
    sf->IShellFolder2_iface.lpVtbl = &sfvt;
    sf->IPersistFolder3_iface.lpVtbl = &pfvt;
    sf->IDropTarget_iface.lpVtbl = &dtvt;
    sf->ISFHelper_iface.lpVtbl = &shvt;
    sf->pclsid = (CLSID *) & CLSID_ShellFSFolder;
    sf->outer_unk = outer_unk ? outer_unk : &sf->IUnknown_inner;

    hr = IUnknown_QueryInterface(&sf->IUnknown_inner, riid, ppv);
    IUnknown_Release(&sf->IUnknown_inner);

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