
/*
 *	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 <stdio.h>

#include "winerror.h"
#include "winbase.h"
#include "winreg.h"

#include "oleidl.h"
#include "shlguid.h"

#include "pidl.h"
#include "wine/obj_base.h"
#include "wine/obj_dragdrop.h"
#include "wine/obj_shellfolder.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 {
    ICOM_VFIELD (IUnknown);
    DWORD ref;
    ICOM_VTABLE (IShellFolder2) * lpvtblShellFolder;
    ICOM_VTABLE (IPersistFolder3) * lpvtblPersistFolder3;
    ICOM_VTABLE (IDropTarget) * lpvtblDropTarget;
    ICOM_VTABLE (ISFHelper) * 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 ICOM_VTABLE (IUnknown) unkvt;
static struct ICOM_VTABLE (IShellFolder2) sfvt;
static struct ICOM_VTABLE (IPersistFolder3) vt_FSFldr_PersistFolder3;	/* IPersistFolder3 for a FS_Folder */
static struct ICOM_VTABLE (IDropTarget) dtvt;
static struct ICOM_VTABLE (ISFHelper) 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 a 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)
{
    ICOM_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)
{
    ICOM_THIS (IGenericSFImpl, iface);

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

    return ++(This->ref);
}

static ULONG WINAPI IUnknown_fnRelease (IUnknown * iface)
{
    ICOM_THIS (IGenericSFImpl, iface);

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

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

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

static ICOM_VTABLE (IUnknown) unkvt =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE 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 (GMEM_ZEROINIT, sizeof (IGenericSFImpl));
    if (!sf)
	return E_OUTOFMEMORY;

    sf->ref = 0;
    ICOM_VTBL (sf) = &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);
}

/**************************************************************************
*		IShellFolder_fnParseDisplayName
* PARAMETERS
*  HWND          hwndOwner,      //[in ] Parent window for any message's
*  LPBC          pbc,            //[in ] reserved
*  LPOLESTR      lpszDisplayName,//[in ] "Unicode" displayname.
*  ULONG*        pchEaten,       //[out] (unicode) characters processed
*  LPITEMIDLIST* ppidl,          //[out] complex pidl to item
*  ULONG*        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 -> chrash
*			lpszDisplayName="" -> returns mycoputer-pidl
*
* FIXME:
*    pdwAttributes: not set
*    pchEaten: not set like in windows
*/
static HRESULT WINAPI
IShellFolder_fnParseDisplayName (IShellFolder2 * iface,
				 HWND hwndOwner,
				 LPBC pbcReserved,
				 LPOLESTR lpszDisplayName,
				 DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    HRESULT hr = E_OUTOFMEMORY;
    LPCWSTR szNext = NULL;
    WCHAR szElement[MAX_PATH];
    CHAR szTempA[MAX_PATH],
      szPath[MAX_PATH];
    LPITEMIDLIST pidlTemp = NULL;

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

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

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

    if (*lpszDisplayName) {
	/* get the next element */
	szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);

	/* build the full pathname to the element */
	WideCharToMultiByte (CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL);
	lstrcpyA (szPath, This->sPathTarget);
	PathAddBackslashA (szPath);
	lstrcatA (szPath, szTempA);

	/* get the pidl */
	pidlTemp = SHSimpleIDListFromPathA (szPath);

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

    if (!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=0x%08x flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList);

    *ppEnumIDList = IEnumIDList_Constructor (This->sPathTarget, dwFlags, EIDL_FILE);

    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 ] reserved
*  REFIID        riid,       //[in ] Initial Interface
*  LPVOID*       ppvObject   //[out] Interface*
*/
static HRESULT WINAPI
IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)

    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbcReserved, 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=0x%x,%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;

    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)->(0x%04x,%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_IDropTarget) && (cidl >= 1)) {
	    hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, (LPVOID *) & pObj);
	} else {
	    hr = E_NOINTERFACE;
	}

	if (!pObj)
	    hr = E_OUTOFMEMORY;

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

/**************************************************************************
*  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;

    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) {
	    lstrcpyA (szPath, This->sPathTarget);	/* get path to root */
	    PathAddBackslashA (szPath);
	    len = lstrlenA (szPath);
	}
	_ILSimpleGetText (pidl, szPath + len, MAX_PATH - len);	/* append my own path */

	/* MSDN also mentions SHGDN_FOREDITING, which isn't defined in wine */
	if (!_ILIsFolder (pidl) && !(dwFlags & SHGDN_FORPARSING) &&
	    ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) {
	    HKEY hKey;
	    DWORD dwData;
	    DWORD dwDataSize = sizeof (DWORD);
	    BOOL doHide = 0;	/* The default value is FALSE (win98 at least) */

	    /* XXX should it do this only for known file types? -- that would make it even slower! */
	    /* XXX That's what the prompt says!! */
	    if (!RegCreateKeyExA (HKEY_CURRENT_USER,
				  "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
				  0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0)) {
		if (!RegQueryValueExA (hKey, "HideFileExt", 0, 0, (LPBYTE) & dwData, &dwDataSize))
		    doHide = dwData;
		RegCloseKey (hKey);
	    }
	    if (doHide && szPath[0] != '.')
		PathRemoveExtensionA (szPath);
	}
    }

    if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) {	/* go deeper if needed */
	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,	/*simple pidl */
						LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
    char szSrc[MAX_PATH],
      szDest[MAX_PATH];
    int len;
    BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl));

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

    /* build source path */
    if (dwFlags & SHGDN_INFOLDER) {
	strcpy (szSrc, This->sPathTarget);
	PathAddBackslashA (szSrc);
	len = strlen (szSrc);
	_ILSimpleGetText (pidl, szSrc + len, MAX_PATH - len);
    } else {
	SHGetPathFromIDListA (pidl, szSrc);
    }

    /* build destination path */
    strcpy (szDest, This->sPathTarget);
    PathAddBackslashA (szDest);
    len = strlen (szDest);
    WideCharToMultiByte (CP_ACP, 0, lpName, -1, szDest + len, MAX_PATH - len, NULL, NULL);
    szDest[MAX_PATH - 1] = 0;
    TRACE ("src=%s dest=%s\n", szSrc, szDest);
    if (MoveFileA (szSrc, szDest)) {
	if (pPidlOut)
	    *pPidlOut = SHSimpleIDListFromPathA (szDest);
	SHChangeNotifyA (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
	return S_OK;
    }
    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_fnMapNameToSCID (IShellFolder2 * iface, LPCWSTR pwszName, SHCOLUMNID * pscid)
{
    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
    FIXME ("(%p)\n", This);
    return E_NOTIMPL;
}

static ICOM_VTABLE (IShellFolder2) sfvt =
{
        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	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_fnMapNameToSCID
};

/****************************************************************************
 * 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);
    PathAddBackslashA (lpstrNewDir);
    strcat (lpstrNewDir, lpName);

    bRes = CreateDirectoryA (lpstrNewDir, NULL);

    if (bRes) {
	LPITEMIDLIST pidl,
	  pidlitem;

	pidlitem = SHSimpleIDListFromPathA (lpstrNewDir);

	pidl = ILCombine (This->pidlRoot, pidlitem);
	SHChangeNotifyA (SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
	SHFree (pidl);

	if (ppidlOut)
	    *ppidlOut = pidlitem;
	hres = S_OK;
    } 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)
    int 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_WarnItemDelete (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]);
	    SHChangeNotifyA (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]);
	    SHChangeNotifyA (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)
{
    int 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 ICOM_VTABLE (ISFHelper) shvt =
{
        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	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: errorhandling
 */
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 ICOM_VTABLE (IPersistFolder3) vt_FSFldr_PersistFolder3 =
{
        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	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 ICOM_VTABLE (IDropTarget) dtvt = {
        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	ISFDropTarget_QueryInterface,
	ISFDropTarget_AddRef,
	ISFDropTarget_Release,
	ISFDropTarget_DragEnter,
	ISFDropTarget_DragOver,
	ISFDropTarget_DragLeave,
	ISFDropTarget_Drop
};
