Enable the display of a true type bitmap for true type fonts.
[wine] / dlls / shell32 / shlfolder.c
index 155aa7b..1724e44 100644 (file)
@@ -1,44 +1,59 @@
+
 /*
  *     Shell Folder stuff
  *
- *     Copyright 1997  Marcus Meissner
- *     Copyright 1998, 1999    Juergen Schmied
- *     
+ *     Copyright 1997                  Marcus Meissner
+ *     Copyright 1998, 1999, 2002      Juergen Schmied
+ *
  *     IShellFolder2 and related interfaces
  *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "config.h"
+#include "wine/port.h"
+
 #include <stdlib.h>
 #include <string.h>
+#include <stdarg.h>
 #include <stdio.h>
 
-#include "debugtools.h"
 #include "winerror.h"
+#include "windef.h"
 #include "winbase.h"
+#include "winreg.h"
+#include "wingdi.h"
+#include "winuser.h"
 
-#include "oleidl.h"
+#include "ole2.h"
 #include "shlguid.h"
 
 #include "pidl.h"
-#include "wine/winestring.h"
-#include "wine/obj_base.h"
-#include "wine/obj_dragdrop.h"
-#include "wine/obj_shellfolder.h"
-#include "wine/undocshell.h"
+#include "undocshell.h"
 #include "shell32_main.h"
 #include "shresdef.h"
 #include "shlwapi.h"
-
-#define INITGUID
-#include "initguid.h"
 #include "shellfolder.h"
-#include "wine/obj_queryassociations.h"
-
-DEFAULT_DEBUG_CHANNEL(shell)
+#include "wine/debug.h"
+#include "debughlp.h"
+#include "shfldr.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL (shell);
 
 /***************************************************************************
- * debughelper: print out the return adress
+ * debughelper: print out the return address
  *  helps especially to track down unbalanced AddRef/Release
  */
 #define MEM_DEBUG 0
@@ -49,15 +64,6 @@ DEFAULT_DEBUG_CHANNEL(shell)
 #define _CALL_TRACE
 #endif
 
-typedef struct
-{
-       int     colnameid;
-       int     pcsFlags;
-       int     fmt;
-       int     cxChar;
-       
-} shvheader;
-
 /***************************************************************************
  *  GetNextElement (internal function)
  *
@@ -72,2723 +78,388 @@ typedef struct
  *    LPSTR pointer to first, not yet parsed char
  */
 
-static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
-{      LPCWSTR   pszTail = pszNext;
-       DWORD dwCopy;
-       TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
-
-       *pszOut=0x0000;
-       
-       if(!pszNext || !*pszNext)
-         return NULL;
-
-       while(*pszTail && (*pszTail != (WCHAR)'\\'))
-         pszTail++;
-
-       dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
-       lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
-
-       if(*pszTail)
-          pszTail++;
-       else
-          pszTail = NULL;
-
-       TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
-       return pszTail;
-}
-
-static HRESULT SHELL32_ParseNextElement(
-       HWND hwndOwner,
-       IShellFolder2 * psf,
-       LPITEMIDLIST * pidlInOut,
-       LPOLESTR szNext,
-       DWORD *pEaten,
-       DWORD *pdwAttributes)
+LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut)
 {
-       HRESULT         hr = E_OUTOFMEMORY;
-       LPITEMIDLIST    pidlOut, pidlTemp = NULL;
-       IShellFolder    *psfChild;
-       
-       TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
-
+    LPCWSTR pszTail = pszNext;
+    DWORD dwCopy;
 
-       /* get the shellfolder for the child pidl and let it analyse further */
-       hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
+    TRACE ("(%s %p 0x%08lx)\n", debugstr_w (pszNext), pszOut, dwOut);
 
-       if (psfChild)
-       {
-         hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
-         IShellFolder_Release(psfChild);
+    *pszOut = 0x0000;
 
-         pidlTemp = ILCombine(*pidlInOut, pidlOut);
+    if (!pszNext || !*pszNext)
+       return NULL;
 
-         if (pidlOut) 
-           ILFree(pidlOut);
-       }
+    while (*pszTail && (*pszTail != (WCHAR) '\\'))
+       pszTail++;
 
-       ILFree(*pidlInOut);
-       *pidlInOut = pidlTemp;
+    dwCopy = (WCHAR *) pszTail - (WCHAR *) pszNext + 1;
+    lstrcpynW (pszOut, pszNext, (dwOut < dwCopy) ? dwOut : dwCopy);
 
-       TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
-       return hr;      
-}
-
-/***********************************************************************
- *     SHELL32_CoCreateInitSF
- *
- *     creates a initialized shell folder
- */
-static HRESULT SHELL32_CoCreateInitSF (
-       LPITEMIDLIST pidlRoot,
-       LPITEMIDLIST pidlChild,
-       REFCLSID clsid,
-       REFIID iid,
-       LPVOID * ppvOut)
-{
-       HRESULT hr;
-       LPITEMIDLIST    absPidl;
-       IShellFolder2   *pShellFolder;
-       IPersistFolder  *pPersistFolder;
-
-       TRACE("%p %p\n", pidlRoot, pidlChild);
-
-       *ppvOut = NULL;
-       
-       /* we have to ask first for IPersistFolder, some special folders are expecting this */
-       hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
-       if (SUCCEEDED(hr))
-       {
-         hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
-         if (SUCCEEDED(hr))
-         {
-           absPidl = ILCombine (pidlRoot, pidlChild);
-           hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
-           IPersistFolder_Release(pPersistFolder);
-           SHFree(absPidl);
-           *ppvOut = pShellFolder;
-         }
-       }
+    if (*pszTail)
+       pszTail++;
+    else
+       pszTail = NULL;
 
-       TRACE("-- ret=0x%08lx\n", hr);
-       return hr;
+    TRACE ("--(%s %s 0x%08lx %p)\n", debugstr_w (pszNext), debugstr_w (pszOut), dwOut, pszTail);
+    return pszTail;
 }
 
-static HRESULT SHELL32_GetDisplayNameOfChild(
-       IShellFolder2 * psf,
-       LPCITEMIDLIST pidl,
-       DWORD dwFlags,
-       LPSTR szOut,
-       DWORD dwOutLen)
+HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
+                                 LPITEMIDLIST * pidlInOut, LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes)
 {
-       LPITEMIDLIST    pidlFirst, pidlNext;
-       IShellFolder2 * psfChild;
-       HRESULT         hr = E_OUTOFMEMORY;
-       STRRET strTemp;
-       
-       TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
-       pdump(pidl);
-       
-       if ((pidlFirst = ILCloneFirst(pidl)))
-       { 
-         hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
-         if (SUCCEEDED(hr))
-         {
-           pidlNext = ILGetNext(pidl);
-
-           hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
-           if (SUCCEEDED(hr))
-           {
-             hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
-           }
+    HRESULT hr = E_OUTOFMEMORY;
+    LPITEMIDLIST pidlOut = NULL,
+      pidlTemp = NULL;
+    IShellFolder *psfChild;
 
-           IShellFolder_Release(psfChild);
-         }
-         ILFree(pidlFirst);
-       }
+    TRACE ("(%p, %p, %p, %s)\n", psf, pbc, pidlInOut ? *pidlInOut : NULL, debugstr_w (szNext));
 
-       TRACE("-- ret=0x%08lx %s\n", hr, szOut);
+    /* get the shellfolder for the child pidl and let it analyse further */
+    hr = IShellFolder_BindToObject (psf, *pidlInOut, pbc, &IID_IShellFolder, (LPVOID *) & psfChild);
 
-       return hr;
-}
+    if (SUCCEEDED (hr)) {
+       hr = IShellFolder_ParseDisplayName (psfChild, hwndOwner, pbc, szNext, pEaten, &pidlOut, pdwAttributes);
+       IShellFolder_Release (psfChild);
 
-/***********************************************************************
- *  SHELL32_GetItemAttributes
- *
- * NOTES
- * observerd values:
- *  folder:    0xE0000177      FILESYSTEM | HASSUBFOLDER | FOLDER
- *  file:      0x40000177      FILESYSTEM
- *  drive:     0xf0000144      FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
- *  mycomputer:        0xb0000154      HASSUBFOLDER | FOLDER | FILESYSANCESTOR
- *  (seems to be default for shell extensions if no registry entry exists)
- *
- * This functions does not set flags!! It only resets flags when nessesary.
- */
-static HRESULT SHELL32_GetItemAttributes(
-       IShellFolder * psf,
-       LPITEMIDLIST pidl,
-       LPDWORD pdwAttributes)
-{
-        GUID const * clsid;
-       DWORD dwAttributes;
-       
-       TRACE("0x%08lx\n", *pdwAttributes);
-
-       if (*pdwAttributes & (0xcff3fe88))
-         WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
-       *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
-
-       if (_ILIsDrive(pidl))
-       {
-         *pdwAttributes &= 0xf0000144;
-       }
-       else if ((clsid=_ILGetGUIDPointer(pidl)))
-       {
-         if (HCR_GetFolderAttributes(clsid, &dwAttributes))
-         {
-           *pdwAttributes &= dwAttributes;
-         }
-         else
-         {
-           *pdwAttributes &= 0xb0000154;
-         }       
-       }
-       else if (_ILGetDataPointer(pidl))
-       {
-         dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
-         *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
+       pidlTemp = ILCombine (*pidlInOut, pidlOut);
 
-         if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
-             *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
+       if (pidlOut)
+           ILFree (pidlOut);
+    }
 
-         if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
-             *pdwAttributes &= ~SFGAO_HIDDEN;
+    ILFree (*pidlInOut);
+    *pidlInOut = pidlTemp;
 
-         if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
-             *pdwAttributes &= ~SFGAO_READONLY;
-       }
-       else
-       {
-         *pdwAttributes &= 0xb0000154;
-       }
-       TRACE("-- 0x%08lx\n", *pdwAttributes);
-       return S_OK;
+    TRACE ("-- pidl=%p ret=0x%08lx\n", pidlInOut ? *pidlInOut : NULL, hr);
+    return hr;
 }
 
 /***********************************************************************
-*   IShellFolder implementation
-*/
-
-typedef struct 
-{
-       ICOM_VFIELD(IUnknown);
-       DWORD                           ref;
-       ICOM_VTABLE(IShellFolder2)*     lpvtblShellFolder;
-       ICOM_VTABLE(IPersistFolder2)*   lpvtblPersistFolder2;
-       ICOM_VTABLE(IDropTarget)*       lpvtblDropTarget;
-       ICOM_VTABLE(ISFHelper)*         lpvtblSFHelper;
-
-       IUnknown                        *pUnkOuter;     /* used for aggregation */
-
-       CLSID*                          pclsid;
-
-       LPSTR                           sMyPath;
-       LPITEMIDLIST                    absPidl;        /* complete pidl */
-
-       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(IPersistFolder2) psfvt;
-static struct ICOM_VTABLE(IDropTarget) dtvt;
-static struct ICOM_VTABLE(ISFHelper) shvt;
-
-static IShellFolder * ISF_MyComputer_Constructor(void);
-
-#define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder))) 
-#define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset); 
-       
-#define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2))) 
-#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_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->lpvtblPersistFolder2)
-#define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
-#define _IPersistFolder2_(This)        (IPersistFolder2*)&(This->lpvtblPersistFolder2)
-#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 seperate IUnknown to handle aggregation
-*      (inner IUnknown)
-*/
-static HRESULT WINAPI IUnknown_fnQueryInterface(
-       IUnknown * iface,
-       REFIID riid,
-       LPVOID *ppvObj)
-{
-       ICOM_THIS(IGenericSFImpl, iface);
-
-       _CALL_TRACE
-       TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_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_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);
-
-       _CALL_TRACE
-       TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-       shell32_ObjCount++;
-       return ++(This->ref);
-}
-
-static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface) 
-{
-       ICOM_THIS(IGenericSFImpl, iface);
-
-       _CALL_TRACE
-       TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-       shell32_ObjCount--;
-       if (!--(This->ref)) 
-       {
-         TRACE("-- destroying IShellFolder(%p)\n",This);
-
-         if (pdesktopfolder == _IShellFolder_(This))
-         {
-           pdesktopfolder=NULL;
-           TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
-         }
-         if(This->absPidl) SHFree(This->absPidl);
-         if(This->sMyPath) SHFree(This->sMyPath);
-         HeapFree(GetProcessHeap(),0,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
-
-/**************************************************************************
-*      IShellFolder_Constructor
-*
-* NOTES
-*  creating undocumented ShellFS_Folder as part of an aggregation
-*  {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
-*
-* FIXME
-*      when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
-*/
-HRESULT IFSFolder_Constructor(
-       IUnknown * pUnkOuter,
-       REFIID riid,
-       LPVOID * ppv)
-{
-       IGenericSFImpl *        sf;
-       HRESULT hr = S_OK;
-
-       TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
-
-       if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
-       {
-         hr = CLASS_E_NOAGGREGATION;   /* forbidden by definition */
-       }
-       else
-       {
-         sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
-         if (sf)
-         {
-           sf->ref=1;
-           ICOM_VTBL(sf)=&unkvt;
-           sf->lpvtblShellFolder=&sfvt;
-           sf->lpvtblPersistFolder2=&psfvt;
-           sf->lpvtblDropTarget=&dtvt;
-           sf->lpvtblSFHelper=&shvt;
-           
-           sf->pclsid = (CLSID*)&CLSID_SFFile;
-           sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
-           *ppv = _IUnknown_(sf);
-           hr = S_OK;
-           shell32_ObjCount++;
-         }
-         else
-         {
-           hr = E_OUTOFMEMORY;
-         }
-       }
-       return hr;
-}
-/**************************************************************************
-*        IShellFolder_Constructor
-*
-* NOTES
-*      THIS points to the parent folder
-*/
-
-IShellFolder * IShellFolder_Constructor(
-       IShellFolder2 * iface,
-       LPITEMIDLIST pidl)
-{
-       IGenericSFImpl *        sf;
-       DWORD                   dwSize=0;
-
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-       sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
-       sf->ref=1;
-
-       ICOM_VTBL(sf)=&unkvt;
-       sf->lpvtblShellFolder=&sfvt;
-       sf->lpvtblPersistFolder2=&psfvt;
-       sf->lpvtblDropTarget=&dtvt;
-       sf->lpvtblSFHelper=&shvt;
-
-       sf->pclsid = (CLSID*)&CLSID_SFFile;
-       sf->pUnkOuter = _IUnknown_(sf);
-
-       TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
-       pdump(pidl);
-               
-       if(pidl && iface)                               /* do we have a pidl? */
-       {
-         int len;
-
-         sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
-
-         if (!_ILIsSpecialFolder(pidl))                                /* only file system paths */
-         {
-           if(This->sMyPath)                           /* get the size of the parents path */
-           {
-             dwSize += strlen(This->sMyPath) ;
-             TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
-           }   
-
-           dwSize += _ILSimpleGetText(pidl,NULL,0);            /* add the size of our name*/
-           sf->sMyPath = SHAlloc(dwSize + 2);                  /* '\0' and backslash */
-
-           if(!sf->sMyPath) return NULL;
-           *(sf->sMyPath)=0x00;
-
-           if(This->sMyPath)                           /* if the parent has a path, get it*/
-           {
-             strcpy(sf->sMyPath, This->sMyPath);
-             PathAddBackslashA (sf->sMyPath);
-           }
-
-           len = strlen(sf->sMyPath);
-           _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
-         }
-
-         TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
-
-         pdump (sf->absPidl);
-       }
-
-       shell32_ObjCount++;
-       return _IShellFolder_(sf);
-}
-
-/**************************************************************************
- *  IShellFolder_fnQueryInterface
+ *     SHELL32_CoCreateInitSF
  *
- * 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)
-
-       _CALL_TRACE
-       TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_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)
-
-       _CALL_TRACE
-       TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-       return IUnknown_AddRef(This->pUnkOuter);
-}
-
-/**************************************************************************
- *  IShellFolder_fnRelease
+ * Creates a shell folder and initializes it with a pidl via IPersistFolder.
+ * This function is meant for virtual folders not backed by a file system
+ * folder.
  */
-static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface) 
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-       _CALL_TRACE
-       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 */
-         lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
-         strcpy(szPath, This->sMyPath);
-         PathAddBackslashA(szPath);
-         strcat(szPath, szTempA);
-
-         /* get the pidl */
-         pidlTemp = SHSimpleIDListFromPathA(szPath);
-
-         if (pidlTemp)
-         {
-           /* try to analyse the next element */
-           if (szNext && *szNext)
-           {
-             hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
-           }
-           else
-           {
-              if (pdwAttributes && *pdwAttributes)
-              {
-                SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
-/*              WIN32_FIND_DATAA fd;
-                SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
-                if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
-                  *pdwAttributes &= ~SFGAO_FOLDER;
-                if (FILE_ATTRIBUTE_READONLY  & fd.dwFileAttributes)
-                  *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
-*/
-              }
-              hr = S_OK;
-           }
-         }
-       }
-
-       *ppidl = pidlTemp;
-
-       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 = NULL;
-       *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
-
-       TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
-
-       if(!*ppEnumIDList) return E_OUTOFMEMORY;
-
-       return S_OK;            
-}
-
-/**************************************************************************
-*              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)
-       GUID            const * iid;
-       IShellFolder    *pShellFolder, *pSubFolder;
-       IPersistFolder  *pPersistFolder;
-       LPITEMIDLIST    absPidl;
-       
-       TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
-
-       if(!pidl || !ppvOut) return E_INVALIDARG;
-
-       *ppvOut = NULL;
-
-       if ((iid=_ILGetGUIDPointer(pidl)))
-       {
-         /* we have to create a alien folder */
-         if (  SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
-            && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
-           {
-             absPidl = ILCombine (This->absPidl, pidl);
-             IPersistFolder_Initialize(pPersistFolder, absPidl);
-             IPersistFolder_Release(pPersistFolder);
-             SHFree(absPidl);
-           }
-           else
-           {
-             return E_FAIL;
-           }
-       }
-       else if(_ILIsFolder(pidl))
-       {
-         LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
-         pShellFolder = IShellFolder_Constructor(iface, pidltemp);
-         ILFree(pidltemp);
-       }
-       else
-       {
-         ERR("can't bind to a file\n");
-         return E_FAIL;
-       }
-       
-       if (_ILIsPidlSimple(pidl))
-       {
-         *ppvOut = pShellFolder;
-       }
-       else
-       {
-         IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
-         IShellFolder_Release(pShellFolder);
-         *ppvOut = pSubFolder;
-       }
-
-       TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
-
-       return S_OK;
-}
-
-/**************************************************************************
-*  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,\n\tIID:%s,%p) stub\n",
-              This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
-
-       *ppvOut = NULL;
-       return E_NOTIMPL;
-}
-
-/**************************************************************************
-*  IShellFolder_fnCompareIDs
-*
-* PARMETERS
-*  LPARAM        lParam, //[in ] Column?
-*  LPCITEMIDLIST pidl1,  //[in ] simple pidl
-*  LPCITEMIDLIST pidl2)  //[in ] simple pidl
-*
-* NOTES
-*   Special case - If one of the items is a Path and the other is a File,
-*   always make the Path come before the File.
-*
-* NOTES 
-*  use SCODE_CODE() on the return value to get the result
-*/
-
-static HRESULT WINAPI  IShellFolder_fnCompareIDs(
-       IShellFolder2 * iface,
-       LPARAM lParam,
-       LPCITEMIDLIST pidl1,
-       LPCITEMIDLIST pidl2)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-       CHAR szTemp1[MAX_PATH];
-       CHAR szTemp2[MAX_PATH];
-       int   nReturn;
-       IShellFolder * psf;
-       HRESULT hr = E_OUTOFMEMORY;
-       LPCITEMIDLIST  pidlTemp;
-       PIDLTYPE pt1, pt2;
-
-       TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
-       pdump (pidl1);
-       pdump (pidl2);
-       
-       if (!pidl1 && !pidl2)
-       {
-         hr = ResultFromShort(0);
-       }
-       else if (!pidl1)
-       {
-         hr = ResultFromShort(-1);
-       }
-       else if (!pidl2)
-       {
-         hr = ResultFromShort(1);
-       }
-       else
-       {
-         LPPIDLDATA pd1, pd2;
-         pd1 = _ILGetDataPointer(pidl1);
-         pd2 = _ILGetDataPointer(pidl2);
-       
-         /* compate the types. sort order is the PT_* constant */
-         pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
-         pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
-
-         if (pt1 != pt2)
-         {
-           hr = ResultFromShort(pt1-pt2);
-         }
-         else                                          /* same type of pidl */
-         {
-           _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
-           _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
-           nReturn = strcasecmp(szTemp1, szTemp2);
-       
-           if (nReturn == 0)                           /* first pidl different ? */
-           {
-             pidl1 = ILGetNext(pidl1);
-
-             if (pidl1 && pidl1->mkid.cb)              /* go deeper? */        
-             {
-               pidlTemp = ILCloneFirst(pidl1);
-               pidl2 = ILGetNext(pidl2);
-       
-               hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
-               if (SUCCEEDED(hr))
-               { 
-                 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
-                 IShellFolder_Release(psf);
-                 hr = ResultFromShort(nReturn);
-               }
-               ILFree(pidlTemp);
-             }
-             else
-             {
-               hr = ResultFromShort(nReturn);          /* two equal simple pidls */
-             }
-           }
-           else
-           {
-             hr = ResultFromShort(nReturn);            /* two different simple pidls */
-           }
-         }
-       }
-       
-       TRACE("-- res=0x%08lx\n", hr);
-       return hr;
-}
-
-/**************************************************************************
-*      IShellFolder_fnCreateViewObject
-*/
-static HRESULT WINAPI IShellFolder_fnCreateViewObject(
-       IShellFolder2 * iface,
-       HWND hwndOwner,
-       REFIID riid,
-       LPVOID *ppvOut)
+HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot,
+                               LPCITEMIDLIST pidlChild, REFCLSID clsid, REFIID iid, LPVOID * ppvOut)
 {
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-       LPSHELLVIEW     pShellView;
-       HRESULT         hr = E_INVALIDARG;
-
-       TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_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;
 
-       HRESULT hr = S_OK;
+    TRACE ("%p %p\n", pidlRoot, pidlChild);
 
-       TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
+    if (SUCCEEDED ((hr = SHCoCreateInstance (NULL, clsid, NULL, iid, ppvOut)))) {
 
-       if ( (!cidl) || (!apidl) || (!rgfInOut))
-         return E_INVALIDARG;
+       IPersistFolder *pPF;
 
-       while (cidl > 0 && *apidl)
-       {
-         pdump (*apidl);
-         SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
-         apidl++;
-         cidl--;
-       } 
+       if (SUCCEEDED ((hr = IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder, (LPVOID *) & pPF)))) {
 
-       TRACE("-- result=0x%08lx\n",*rgfInOut);
+           LPITEMIDLIST pidlAbsolute;
 
-       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,\n\tIID:%s,%p,%p)\n",
-         This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
-
-       if (ppvOut)
-       {
-         *ppvOut = NULL;
-
-         if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
-         {
-           pObj  = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
-           hr = S_OK;
-         }
-         else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
-         {
-           pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
-           hr = S_OK;
-         }
-         else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
-         {
-           pidl = ILCombine(This->absPidl,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;
+           pidlAbsolute = ILCombine (pidlRoot, pidlChild);
+           IPersistFolder_Initialize (pPF, pidlAbsolute);
+           IPersistFolder_Release (pPF);
+           SHFree (pidlAbsolute);
        }
-       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
-*/
-#define GET_SHGDN_FOR(dwFlags)         ((DWORD)dwFlags & (DWORD)0x0000FF00)
-#define GET_SHGDN_RELATION(dwFlags)    ((DWORD)dwFlags & (DWORD)0x000000FF)
-
-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
-       {
-         if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
-         {
-           strcpy (szPath, This->sMyPath);                     /* get path to root*/
-           PathAddBackslashA(szPath);
-           len = strlen(szPath);
-         }
-         _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
-       }
-       
-       if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl)      /* go deeper if needed */
-       {
-         PathAddBackslashA(szPath);
-         len = strlen(szPath);
-
-         if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
-           return E_OUTOFMEMORY;
-       }
-       strRet->uType = STRRET_CSTRA;
-       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->sMyPath);
-         PathAddBackslashA(szSrc);
-         len = strlen (szSrc);
-         _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
-       }
-       else 
-       {
-         SHGetPathFromIDListA(pidl, szSrc);
-       }
-
-       /* build destination path */
-       strcpy(szDest, This->sMyPath);
-       PathAddBackslashA(szDest);
-       len = strlen (szDest);
-       lstrcpynWtoA(szDest+len, lpName, MAX_PATH-len);
-       
-       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;
+    TRACE ("-- (%p) ret=0x%08lx\n", *ppvOut, hr);
+    return hr;
 }
 
-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_CSTRA;
-         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_CSTRA;
-       }
-
-       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)\n", This);
-
-       return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
-}
-
-static ULONG WINAPI ISFHelper_fnAddRef(
-       ISFHelper *iface)
-{
-       _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
-       TRACE("(%p)\n", This);
-
-       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
+/***********************************************************************
+ *     SHELL32_CoCreateInitSFEx
  *
- * 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
+ * Creates a shell folder and initializes it with a pidl and a root folder
+ * via IPersistFolder3.
+ * This function is meant for virtual folders backed by a file system
+ * folder.
  *
- * adds a new folder.
+ * NOTES
+ *   pathRoot can be NULL for Folders beeing a drive.
+ *   In this case the absolute path is build from pidlChild (eg. C:)
  */
-
-static HRESULT WINAPI ISFHelper_fnAddFolder(
-       ISFHelper *iface,
-       HWND hwnd,
-       LPCSTR lpName,
-       LPITEMIDLIST* ppidlOut)
+HRESULT SHELL32_CoCreateInitSFEx (LPCITEMIDLIST pidlRoot,
+                                 LPCSTR pathRoot, LPCITEMIDLIST pidlChild, REFCLSID clsid, REFIID riid, LPVOID * ppvOut)
 {
-       _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
-       char lpstrNewDir[MAX_PATH];
-       DWORD bRes;
-       HRESULT hres = E_FAIL;
-       
-       TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
+    HRESULT hr;
+    IPersistFolder3 *ppf;
 
-       strcpy(lpstrNewDir, This->sMyPath);
-       PathAddBackslashA(lpstrNewDir);
-       strcat(lpstrNewDir, lpName);
+    TRACE ("%p %s %p\n", pidlRoot, pathRoot, pidlChild);
 
-       bRes = CreateDirectoryA(lpstrNewDir, NULL);
+    if (SUCCEEDED ((hr = SHCoCreateInstance (NULL, &CLSID_ShellFSFolder, NULL, riid, ppvOut)))) {
+       if (SUCCEEDED (IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder3, (LPVOID *) & ppf))) {
+           PERSIST_FOLDER_TARGET_INFO ppfti;
+           LPITEMIDLIST pidlAbsolute;
+           char szDestPath[MAX_PATH];
 
-       if (bRes)
-       {
-         LPITEMIDLIST pidl, pidlitem;
+           ZeroMemory (&ppfti, sizeof (ppfti));
 
-         pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
-
-         pidl = ILCombine(This->absPidl, 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);
-       }
+           /* combine pidls */
+           pidlAbsolute = ILCombine (pidlRoot, pidlChild);
 
-       return hres;
-}
+           /* build path */
+           if (pathRoot) {
+               lstrcpyA (szDestPath, pathRoot);
+               PathAddBackslashA(szDestPath);          /* FIXME: why have drives a backslash here ? */
+           } else {
+               szDestPath[0] = '\0';
+           }
 
-/****************************************************************************
- * 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];
-
-       TRACE("(%p)(%u %p)\n", This, cidl, apidl);
-       
-       for(i=0; i< cidl; i++)
-       {
-         strcpy(szPath, This->sMyPath);
-         PathAddBackslashA(szPath);
-         _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
-
-         if (_ILIsFolder(apidl[i]))
-         {
-           LPITEMIDLIST pidl;
-
-           MESSAGE("delete %s\n", szPath);
-           if (! SHELL_DeleteDirectoryA(szPath, TRUE)) return E_FAIL;
-           pidl = ILCombine(This->absPidl, apidl[i]);
-           SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
-           SHFree(pidl); 
-         }
-         else if (_ILIsValue(apidl[i]))
-         {
-           LPITEMIDLIST pidl;
-
-           MESSAGE("delete %s\n", szPath);
-           if (! DeleteFileA(szPath)) return E_FAIL;
-           pidl = ILCombine(This->absPidl, apidl[i]);
-           SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
-           SHFree(pidl); 
-         }
+           if (pidlChild)
+               lstrcatA (szDestPath, _ILGetTextPointer (pidlChild));
 
-       }
-       return S_OK;
-}
+           /* fill the PERSIST_FOLDER_TARGET_INFO */
+           ppfti.dwAttributes = -1;
+           ppfti.csidl = -1;
+           MultiByteToWideChar (CP_ACP, 0, szDestPath, -1, ppfti.szTargetParsingName, MAX_PATH);
 
-/****************************************************************************
- * ISFHelper_fnCopyItems
- *
- * copys 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->sMyPath);
-             PathAddBackslashA(szDstPath);
-             _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
-             MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
-           }
-           SHFree(pidl);
-         }
-         IPersistFolder2_Release(ppf2);
+           IPersistFolder3_InitializeEx (ppf, NULL, pidlAbsolute, &ppfti);
+           IPersistFolder3_Release (ppf);
+           ILFree (pidlAbsolute);
        }
-       return S_OK;
+    }
+    TRACE ("-- (%p) ret=0x%08lx\n", *ppvOut, hr);
+    return hr;
 }
 
-static ICOM_VTABLE(ISFHelper) shvt = 
-{
-       ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-       ISFHelper_fnQueryInterface,
-       ISFHelper_fnAddRef,
-       ISFHelper_fnRelease,
-       ISFHelper_fnGetUniqueName,
-       ISFHelper_fnAddFolder,
-       ISFHelper_fnDeleteItems,
-       ISFHelper_fnCopyItems,
-};
-
 /***********************************************************************
-*      [Desktopfolder] IShellFolder implementation
-*/
-static struct ICOM_VTABLE(IShellFolder2) sfdvt;
-
-static shvheader DesktopSFHeader [] =
-{
- { 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 DESKTOPSHELLVIEWCOLUMNS 5
-
-/**************************************************************************
-*      ISF_Desktop_Constructor
-*
-*/
-IShellFolder * ISF_Desktop_Constructor()
-{
-       IGenericSFImpl *        sf;
-
-       sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
-       sf->ref=1;
-       ICOM_VTBL(sf)=&unkvt;
-       sf->lpvtblShellFolder=&sfdvt;
-       sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
-       sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
-
-       TRACE("(%p)\n",sf);
-
-       shell32_ObjCount++;
-       return _IShellFolder_(sf);
-}
-
-/**************************************************************************
- *     ISF_Desktop_fnQueryInterface
+ *     SHELL32_BindToChild
  *
- * NOTES supports not IPersist/IPersistFolder
+ * Common code for IShellFolder_BindToObject.
+ * Creates a shell folder by binding to a root pidl.
  */
-static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
-       IShellFolder2 * iface,
-       REFIID riid,
-       LPVOID *ppvObj)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-       TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
-
-       *ppvObj = NULL;
-
-       if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
-       {
-         *ppvObj = _IUnknown_(This); 
-       }
-       else if(IsEqualIID(riid, &IID_IShellFolder))  /*IShellFolder*/
-       {
-         *ppvObj = _IShellFolder_(This);
-       }   
-       else if(IsEqualIID(riid, &IID_IShellFolder2))  /*IShellFolder2*/
-       {
-         *ppvObj = _IShellFolder_(This);
-       }   
-
-       if(*ppvObj)
-       {
-         IUnknown_AddRef((IUnknown*)(*ppvObj));
-         TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-         return S_OK;
-       }
-       TRACE("-- Interface: E_NOINTERFACE\n");
-       return E_NOINTERFACE;
-}
-
-/**************************************************************************
-*      ISF_Desktop_fnParseDisplayName
-*
-* NOTES
-*      "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
-*      to MyComputer
-*/
-static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
-       IShellFolder2 * iface,
-       HWND hwndOwner,
-       LPBC pbcReserved,
-       LPOLESTR lpszDisplayName,
-       DWORD *pchEaten,
-       LPITEMIDLIST *ppidl,
-       DWORD *pdwAttributes)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-       LPCWSTR         szNext=NULL;
-       LPITEMIDLIST    pidlTemp=NULL;
-       HRESULT         hr=E_OUTOFMEMORY;
-       
-       TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
-       This,hwndOwner,pbcReserved,lpszDisplayName,
-       debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
-
-       *ppidl = 0;
-       if (pchEaten) *pchEaten = 0;    /* strange but like the original */
-       
-       /* fixme no real parsing implemented */
-       pidlTemp = _ILCreateMyComputer();
-       szNext = lpszDisplayName;
-
-       if (szNext && *szNext)
-       {
-         hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
-       }
-       else
-       {
-         hr = S_OK;
-
-         if (pdwAttributes && *pdwAttributes)
-         {
-           SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
-         }
-       }
-
-       *ppidl = pidlTemp;
-
-       TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
-
-       return hr;      
-}
-
-/**************************************************************************
-*              ISF_Desktop_fnEnumObjects
-*/
-static HRESULT WINAPI ISF_Desktop_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 = NULL;
-       *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
-
-       TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
-
-       if(!*ppEnumIDList) return E_OUTOFMEMORY;
-
-       return S_OK;            
-}
-
-/**************************************************************************
-*              ISF_Desktop_fnBindToObject
-*/
-static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
-                       LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
+                            LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
 {
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       GUID            const * clsid;
-       IShellFolder    *pShellFolder, *pSubFolder;
-       
-       TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
-              This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
-
-       *ppvOut = NULL;
-
-       if ((clsid=_ILGetGUIDPointer(pidl)))
-       {
-         if ( IsEqualIID(clsid, &CLSID_MyComputer))
-         {
-           pShellFolder = ISF_MyComputer_Constructor();
-         }
-         else 
-         {
-            /* shell extension */
-            if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
-            {
-              return E_INVALIDARG;
-            }
-         }
-       } 
-       else
-       {
-         /* file system folder on the desktop */
-         LPITEMIDLIST deskpidl, firstpidl, completepidl;
-         IPersistFolder * ppf;
-
-         /* combine pidls */
-         SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
-         firstpidl = ILCloneFirst(pidl);
-         completepidl = ILCombine(deskpidl, firstpidl);
-
-         pShellFolder = IShellFolder_Constructor(NULL, NULL);
-         if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
-         {
-           IPersistFolder_Initialize(ppf, completepidl);
-           IPersistFolder_Release(ppf);
-         }
-         ILFree(completepidl);
-         ILFree(deskpidl);
-         ILFree(firstpidl);
-       }
-       
-       if (_ILIsPidlSimple(pidl))      /* no sub folders */
-       {
-         *ppvOut = pShellFolder;
-       }
-       else                            /* go deeper */
-       {
-         IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
-         IShellFolder_Release(pShellFolder);
-         *ppvOut = pSubFolder;
-       }
+    GUID const *clsid;
+    IShellFolder *pSF;
+    HRESULT hr;
+    LPITEMIDLIST pidlChild;
 
-       TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
-
-       return S_OK;
-}
-
-/**************************************************************************
-*      ISF_Desktop_fnCreateViewObject
-*/
-static HRESULT WINAPI ISF_Desktop_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,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
-       
-       if(ppvOut)
-       {
-         *ppvOut = NULL;
-
-         if(IsEqualIID(riid, &IID_IDropTarget))
-         {
-           WARN("IDropTarget not implemented\n");
-           hr = E_NOTIMPL;
-         }
-         else if(IsEqualIID(riid, &IID_IContextMenu))
-         {
-           WARN("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; 
-}
-
-/**************************************************************************
-*  ISF_Desktop_fnGetAttributesOf
-*/
-static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
-       IShellFolder2 * iface,
-       UINT cidl,
-       LPCITEMIDLIST *apidl,
-       DWORD *rgfInOut)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
+    if (!pidlRoot || !ppvOut)
+       return E_INVALIDARG;
 
-       HRESULT         hr = S_OK;
+    *ppvOut = NULL;
 
-       TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
+    pidlChild = ILCloneFirst (pidlComplete);
 
-       if ( (!cidl) || (!apidl) || (!rgfInOut))
-         return E_INVALIDARG;
+    if ((clsid = _ILGetGUIDPointer (pidlChild))) {
+       /* virtual folder */
+       hr = SHELL32_CoCreateInitSF (pidlRoot, pidlChild, clsid, &IID_IShellFolder, (LPVOID *) & pSF);
+    } else {
+       /* file system folder */
+       hr = SHELL32_CoCreateInitSFEx (pidlRoot, pathRoot, pidlChild, &CLSID_ShellFSFolder, &IID_IShellFolder,
+                                      (LPVOID *) & pSF);
+    }
+    ILFree (pidlChild);
 
-       while (cidl > 0 && *apidl)
-       {
-         pdump (*apidl);
-         SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
-         apidl++;
-         cidl--;
+    if (SUCCEEDED (hr)) {
+       if (_ILIsPidlSimple (pidlComplete)) {
+           /* no sub folders */
+           hr = IShellFolder_QueryInterface (pSF, riid, ppvOut);
+       } else {
+           /* go deeper */
+           hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut);
        }
+       IShellFolder_Release (pSF);
+    }
 
-       TRACE("-- result=0x%08lx\n",*rgfInOut);
+    TRACE ("-- returning (%p) %08lx\n", *ppvOut, hr);
 
-       return hr;
+    return hr;
 }
 
-/**************************************************************************
-*      ISF_Desktop_fnGetDisplayNameOf
-*
-* NOTES
-*      special case: pidl = null gives desktop-name back
-*/
-static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
-       IShellFolder2 * iface,
-       LPCITEMIDLIST pidl,
-       DWORD dwFlags,
-       LPSTRRET strRet)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-       CHAR            szPath[MAX_PATH]= "";
-               
-       TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
-       pdump(pidl);
-       
-       if(!strRet) return E_INVALIDARG;
-       
-       if(!pidl)
-       {
-         HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
-       }
-       else if ( _ILIsPidlSimple(pidl) )
-       {
-         _ILSimpleGetText(pidl, szPath, MAX_PATH);
-       }
-       else
-       { 
-         if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
-           return E_OUTOFMEMORY;
-       }
-       strRet->uType = STRRET_CSTRA;
-       lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
-
-
-       TRACE("-- (%p)->(%s)\n", This, szPath);
-       return S_OK;
-}
-
-static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
-       IShellFolder2 * iface,
-       GUID *pguid)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       FIXME("(%p)\n",This);
-       return E_NOTIMPL;
-}      
-static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
-       IShellFolder2 * iface,
-       IEnumExtraSearch **ppenum)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       FIXME("(%p)\n",This);
-       return E_NOTIMPL;
-}      
-static HRESULT WINAPI ISF_Desktop_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 ISF_Desktop_fnGetDefaultColumnState(
-       IShellFolder2 * iface,
-       UINT iColumn,
-       DWORD *pcsFlags)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       
-       TRACE("(%p)\n",This);
-
-       if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
-       *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
-
-       return S_OK;
-}      
-static HRESULT WINAPI ISF_Desktop_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 ISF_Desktop_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 >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-       
-       if (!pidl)
-       {
-         psd->fmt = DesktopSFHeader[iColumn].fmt;
-         psd->cxChar = DesktopSFHeader[iColumn].cxChar;
-         psd->str.uType = STRRET_CSTRA;
-         LoadStringA(shell32_hInstance, DesktopSFHeader[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_CSTRA;
-       }
-
-       return hr;
-}      
-static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
-       IShellFolder2 * iface,
-       LPCWSTR pwszName,
-       SHCOLUMNID *pscid)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       FIXME("(%p)\n",This);
-       return E_NOTIMPL;
-}      
-
-static ICOM_VTABLE(IShellFolder2) sfdvt = 
-{      
-       ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-       ISF_Desktop_fnQueryInterface,
-       IShellFolder_fnAddRef,
-       IShellFolder_fnRelease,
-       ISF_Desktop_fnParseDisplayName,
-       ISF_Desktop_fnEnumObjects,
-       ISF_Desktop_fnBindToObject,
-       IShellFolder_fnBindToStorage,
-       IShellFolder_fnCompareIDs,
-       ISF_Desktop_fnCreateViewObject,
-       ISF_Desktop_fnGetAttributesOf,
-       IShellFolder_fnGetUIObjectOf,
-       ISF_Desktop_fnGetDisplayNameOf,
-       IShellFolder_fnSetNameOf,
-
-       /* ShellFolder2 */
-       ISF_Desktop_fnGetDefaultSearchGUID,
-       ISF_Desktop_fnEnumSearches,
-       ISF_Desktop_fnGetDefaultColumn,
-       ISF_Desktop_fnGetDefaultColumnState,
-       ISF_Desktop_fnGetDetailsEx,
-       ISF_Desktop_fnGetDetailsOf,
-       ISF_Desktop_fnMapNameToSCID
-};
-
-
 /***********************************************************************
-*   IShellFolder [MyComputer] implementation
-*/
-
-static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
-
-static shvheader MyComputerSFHeader [] =
-{
- { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
- { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
-};
-#define MYCOMPUTERSHELLVIEWCOLUMNS 4
-
-/**************************************************************************
-*      ISF_MyComputer_Constructor
-*/
-static IShellFolder * ISF_MyComputer_Constructor(void)
-{
-       IGenericSFImpl *        sf;
-
-       sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
-       sf->ref=1;
-
-       ICOM_VTBL(sf)=&unkvt;
-       sf->lpvtblShellFolder=&sfmcvt;
-       sf->lpvtblPersistFolder2 = &psfvt;
-       sf->pclsid = (CLSID*)&CLSID_SFMyComp;
-       sf->absPidl=_ILCreateMyComputer();      /* my qualified pidl */
-       sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
-
-       TRACE("(%p)\n",sf);
-
-       shell32_ObjCount++;
-       return _IShellFolder_(sf);
-}
-
-/**************************************************************************
-*      ISF_MyComputer_fnParseDisplayName
-*/
-static HRESULT WINAPI ISF_MyComputer_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];
-       LPITEMIDLIST    pidlTemp;
-       
-       TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
-       This,hwndOwner,pbcReserved,lpszDisplayName,
-       debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
-
-       *ppidl = 0;
-       if (pchEaten) *pchEaten = 0;    /* strange but like the original */
-
-       /* do we have an absolute path name ? */
-       if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
-           lpszDisplayName[2] == (WCHAR)'\\')
-       {
-         szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
-         lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
-         pidlTemp = _ILCreateDrive(szTempA);
-
-         if (szNext && *szNext)
-         {
-           hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
-         }
-         else
-         {
-           if (pdwAttributes && *pdwAttributes)
-           {
-             SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
-           }
-           hr = S_OK;
-         }
-         *ppidl = pidlTemp;
-       }
-
-       TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
-
-       return hr;      
-}
-
-/**************************************************************************
-*              ISF_MyComputer_fnEnumObjects
-*/
-static HRESULT WINAPI ISF_MyComputer_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 = NULL;
-       *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
-
-       TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
-
-       if(!*ppEnumIDList) return E_OUTOFMEMORY;
-
-       return S_OK;            
-}
-
-/**************************************************************************
-*              ISF_MyComputer_fnBindToObject
-*/
-static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
-                       LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       GUID            const * clsid;
-       IShellFolder    *pShellFolder, *pSubFolder;
-       LPITEMIDLIST    pidltemp;
-       
-       TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
-              This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
-
-       if(!pidl || !ppvOut) return E_INVALIDARG;
-
-       *ppvOut = NULL;
-
-       if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
-       {
-          if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
-          {
-            return E_FAIL;
-          }
-       }
-       else
-       {
-         if (!_ILIsDrive(pidl)) return E_INVALIDARG;
-
-         pidltemp = ILCloneFirst(pidl);
-         pShellFolder = IShellFolder_Constructor(iface, pidltemp);
-         ILFree(pidltemp);
-       }
-
-       if (_ILIsPidlSimple(pidl))      /* no sub folders */
-       {
-         *ppvOut = pShellFolder;
-       }
-       else                            /* go deeper */
-       {
-         IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
-         IShellFolder_Release(pShellFolder);
-         *ppvOut = pSubFolder;
-       }
-
-       TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
-
-       return S_OK;
-}
-
-/**************************************************************************
-*      ISF_MyComputer_fnCreateViewObject
-*/
-static HRESULT WINAPI ISF_MyComputer_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,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
-       
-       if(ppvOut)
-       {
-         *ppvOut = NULL;
-
-         if(IsEqualIID(riid, &IID_IDropTarget))
-         {
-           WARN("IDropTarget not implemented\n");
-           hr = E_NOTIMPL;
-         }
-         else if(IsEqualIID(riid, &IID_IContextMenu))
-         {
-           WARN("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; 
-}
-
-/**************************************************************************
-*  ISF_MyComputer_fnGetAttributesOf
-*/
-static HRESULT WINAPI ISF_MyComputer_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;
-}
-
-/**************************************************************************
-*      ISF_MyComputer_fnGetDisplayNameOf
-*
-* NOTES
-*      The desktopfolder creates only complete paths (SHGDN_FORPARSING).
-*      SHGDN_INFOLDER makes no sense.
-*/
-static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
-       IShellFolder2 * iface,
-       LPCITEMIDLIST pidl,
-       DWORD dwFlags,
-       LPSTRRET strRet)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-       char            szPath[MAX_PATH], szDrive[18];
-       int             len = 0;
-       BOOL            bSimplePidl;
-               
-       TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
-       pdump(pidl);
-       
-       if(!strRet) return E_INVALIDARG;
-       
-       szPath[0]=0x00; szDrive[0]=0x00;
-       
-       
-       bSimplePidl = _ILIsPidlSimple(pidl);
-       
-       if (_ILIsSpecialFolder(pidl))
-       {
-         /* take names of special folders only if its only this folder */
-         if ( bSimplePidl )
-         {
-           _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
-         }
-       }
-       else
-       {
-         if (!_ILIsDrive(pidl))
-         {
-           ERR("Wrong pidl type\n");
-           return E_INVALIDARG;
-         }
-
-         _ILSimpleGetText(pidl, szPath, MAX_PATH);     /* append my own path */
-
-         /* long view "lw_name (C:)" */
-         if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
-         {
-           DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
-
-           GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
-           strcat (szDrive," (");
-           strncat (szDrive, szPath, 2);
-           strcat (szDrive,")");
-           strcpy (szPath, szDrive);
-         }
-       }
-       
-       if (!bSimplePidl)       /* go deeper if needed */
-       { 
-         PathAddBackslashA(szPath);
-         len = strlen(szPath);
-
-         if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
-           return E_OUTOFMEMORY;
-       }
-       strRet->uType = STRRET_CSTRA;
-       lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
-
-
-       TRACE("-- (%p)->(%s)\n", This, szPath);
-       return S_OK;
-}
-
-static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
-       IShellFolder2 * iface,
-       GUID *pguid)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       FIXME("(%p)\n",This);
-       return E_NOTIMPL;
-}      
-static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
-       IShellFolder2 * iface,
-       IEnumExtraSearch **ppenum)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       FIXME("(%p)\n",This);
-       return E_NOTIMPL;
-}      
-static HRESULT WINAPI ISF_MyComputer_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 ISF_MyComputer_fnGetDefaultColumnState(
-       IShellFolder2 * iface,
-       UINT iColumn,
-       DWORD *pcsFlags)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       
-       TRACE("(%p)\n",This);
-
-       if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
-       *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
-
-       return S_OK;
-}      
-static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
-       IShellFolder2 * iface,
-       LPCITEMIDLIST pidl,
-       const SHCOLUMNID *pscid,
-       VARIANT *pv)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       FIXME("(%p)\n",This);
-
-       return E_NOTIMPL;
-}      
-
-/* fixme: drive size >4GB is rolling over */
-static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
-       IShellFolder2 * iface,
-       LPCITEMIDLIST pidl,
-       UINT iColumn,
-       SHELLDETAILS *psd)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       HRESULT hr;
-
-       TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
-
-       if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-       
-       if (!pidl)
-       {
-         psd->fmt = MyComputerSFHeader[iColumn].fmt;
-         psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
-         psd->str.uType = STRRET_CSTRA;
-         LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
-         return S_OK;
-       }
-       else
-       {
-         char szPath[MAX_PATH];
-         ULARGE_INTEGER ulBytes;
-
-         psd->str.u.cStr[0] = 0x00;
-         psd->str.uType = STRRET_CSTRA;
-         switch(iColumn)
-         {
-           case 0:     /* name */
-             hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
-             break;
-           case 1:     /* type */
-             _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
-             break;
-           case 2:     /* total size */
-             if (_ILIsDrive(pidl))
-             {
-               _ILSimpleGetText(pidl, szPath, MAX_PATH);
-               GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
-               StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
-             }
-             break;
-           case 3:     /* free size */
-             if (_ILIsDrive(pidl))
-             {
-               _ILSimpleGetText(pidl, szPath, MAX_PATH);
-               GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
-               StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
-             }
-             break;
-         }
-         hr = S_OK;
-       }
-
-       return hr;
-}      
-static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
-       IShellFolder2 * iface,
-       LPCWSTR pwszName,
-       SHCOLUMNID *pscid)
-{
-       _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-       FIXME("(%p)\n",This);
-       return E_NOTIMPL;
-}      
-
-static ICOM_VTABLE(IShellFolder2) sfmcvt = 
-{      
-       ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-       IShellFolder_fnQueryInterface,
-       IShellFolder_fnAddRef,
-       IShellFolder_fnRelease,
-       ISF_MyComputer_fnParseDisplayName,
-       ISF_MyComputer_fnEnumObjects,
-       ISF_MyComputer_fnBindToObject,
-       IShellFolder_fnBindToStorage,
-       IShellFolder_fnCompareIDs,
-       ISF_MyComputer_fnCreateViewObject,
-       ISF_MyComputer_fnGetAttributesOf,
-       IShellFolder_fnGetUIObjectOf,
-       ISF_MyComputer_fnGetDisplayNameOf,
-       IShellFolder_fnSetNameOf,
-
-       /* ShellFolder2 */
-       ISF_MyComputer_fnGetDefaultSearchGUID,
-       ISF_MyComputer_fnEnumSearches,
-       ISF_MyComputer_fnGetDefaultColumn,
-       ISF_MyComputer_fnGetDefaultColumnState,
-       ISF_MyComputer_fnGetDetailsEx,
-       ISF_MyComputer_fnGetDetailsOf,
-       ISF_MyComputer_fnMapNameToSCID
-};
-
-
-/************************************************************************
- * ISFPersistFolder_QueryInterface (IUnknown)
+ *     SHELL32_GetDisplayNameOfChild
  *
- */
-static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
-       IPersistFolder2 *       iface,
-       REFIID                  iid,
-       LPVOID*                 ppvObj)
-{
-       _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
-
-       TRACE("(%p)\n", This);
-
-       return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
-}
-
-/************************************************************************
- * ISFPersistFolder_AddRef (IUnknown)
+ * Retrives the display name of a child object of a shellfolder.
  *
- */
-static ULONG WINAPI ISFPersistFolder2_AddRef(
-       IPersistFolder2 *       iface)
-{
-       _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
-
-       TRACE("(%p)\n", This);
-
-       return IUnknown_AddRef(This->pUnkOuter);
-}
-
-/************************************************************************
- * ISFPersistFolder_Release (IUnknown)
+ * For a pidl eg. [subpidl1][subpidl2][subpidl3]:
+ * - it binds to the child shellfolder [subpidl1]
+ * - asks it for the displayname of [subpidl2][subpidl3]
  *
+ * Is possible the pidl is a simple pidl. In this case it asks the
+ * subfolder for the displayname of a empty pidl. The subfolder
+ * returns the own displayname eg. "::{guid}". This is used for
+ * virtual folders with the registry key WantsFORPARSING set.
  */
-static ULONG WINAPI ISFPersistFolder2_Release(
-       IPersistFolder2 *       iface)
+HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf,
+                                      LPCITEMIDLIST pidl, DWORD dwFlags, LPSTR szOut, DWORD dwOutLen)
 {
-       _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+    LPITEMIDLIST pidlFirst;
+    HRESULT hr = E_OUTOFMEMORY;
 
-       TRACE("(%p)\n", This);
+    TRACE ("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n", psf, pidl, dwFlags, szOut, dwOutLen);
+    pdump (pidl);
 
-       return IUnknown_Release(This->pUnkOuter);
-}
+    pidlFirst = ILCloneFirst (pidl);
+    if (pidlFirst) {
+       IShellFolder2 *psfChild;
 
-/************************************************************************
- * ISFPersistFolder_GetClassID (IPersist)
- */
-static HRESULT WINAPI ISFPersistFolder2_GetClassID(
-       IPersistFolder2 *       iface,
-       CLSID *                 lpClassId)
-{
-       _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+       hr = IShellFolder_BindToObject (psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID *) & psfChild);
+       if (SUCCEEDED (hr)) {
+           STRRET strTemp;
+           LPITEMIDLIST pidlNext = ILGetNext (pidl);
 
-       TRACE("(%p)\n", This);
+           hr = IShellFolder_GetDisplayNameOf (psfChild, pidlNext, dwFlags, &strTemp);
+           if (SUCCEEDED (hr)) {
+               hr = StrRetToStrNA (szOut, dwOutLen, &strTemp, pidlNext);
+           }
+           IShellFolder_Release (psfChild);
+       }
+       ILFree (pidlFirst);
+    }
 
-       if (!lpClassId) return E_POINTER;
-       *lpClassId = *This->pclsid;
+    TRACE ("-- ret=0x%08lx %s\n", hr, szOut);
 
-       return S_OK;
+    return hr;
 }
 
-/************************************************************************
- * ISFPersistFolder_Initialize (IPersistFolder)
+/***********************************************************************
+ *  SHELL32_GetItemAttributes
  *
  * NOTES
- *  sMyPath is not set. Don't know how to handle in a non rooted environment.
+ * observerd values:
+ *  folder:    0xE0000177      FILESYSTEM | HASSUBFOLDER | FOLDER
+ *  file:      0x40000177      FILESYSTEM
+ *  drive:     0xf0000144      FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
+ *  mycomputer:        0xb0000154      HASSUBFOLDER | FOLDER | FILESYSANCESTOR
+ *  (seems to be default for shell extensions if no registry entry exists)
+ *
+ * win2k:
+ *  folder:    0xF0400177      FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER
+ *  file:      0x40400177      FILESYSTEM | CANMONIKER
+ *  drive      0xF0400154      FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER | CANRENAME (LABEL)
+ *
+ * This functions does not set flags!! It only resets flags when nessesary.
  */
-static HRESULT WINAPI ISFPersistFolder2_Initialize(
-       IPersistFolder2 *       iface,
-       LPCITEMIDLIST           pidl)
-{
-       char sTemp[MAX_PATH];
-       _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
-
-       TRACE("(%p)->(%p)\n", This, pidl);
-
-       /* free the old stuff */
-       if(This->absPidl)
-       {
-         SHFree(This->absPidl);
-         This->absPidl = NULL;
-       }
-       if(This->sMyPath)
-       {
-         SHFree(This->sMyPath);
-         This->sMyPath = NULL;
+HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes)
+{
+    GUID const *clsid;
+    DWORD dwAttributes;
+    DWORD dwSupportedAttr=SFGAO_CANCOPY |           /*0x00000001 */
+                          SFGAO_CANMOVE |           /*0x00000002 */
+                          SFGAO_CANLINK |           /*0x00000004 */
+                          SFGAO_CANRENAME |         /*0x00000010 */
+                          SFGAO_CANDELETE |         /*0x00000020 */
+                          SFGAO_HASPROPSHEET |      /*0x00000040 */
+                          SFGAO_DROPTARGET |        /*0x00000100 */
+                          SFGAO_READONLY |          /*0x00040000 */
+                          SFGAO_HIDDEN |            /*0x00080000 */
+                          SFGAO_FILESYSANCESTOR |   /*0x10000000 */
+                          SFGAO_FOLDER |            /*0x20000000 */
+                          SFGAO_FILESYSTEM |        /*0x40000000 */
+                          SFGAO_HASSUBFOLDER;       /*0x80000000 */
+    
+    TRACE ("0x%08lx\n", *pdwAttributes);
+
+    if (*pdwAttributes & ~dwSupportedAttr)
+    {
+        WARN ("attributes 0x%08lx not implemented\n", (*pdwAttributes & ~dwSupportedAttr));
+        *pdwAttributes &= dwSupportedAttr;
+    }
+
+    if (_ILIsDrive (pidl)) {
+        *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK;
+    } else if ((clsid = _ILGetGUIDPointer (pidl))) {
+       if (HCR_GetFolderAttributes (clsid, &dwAttributes)) {
+           *pdwAttributes &= dwAttributes;
+       } else {
+           *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK;
        }
+    } else if (_ILGetDataPointer (pidl)) {
+       dwAttributes = _ILGetFileAttributes (pidl, NULL, 0);
+       *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
 
-       /* set my pidl */
-       This->absPidl = ILClone(pidl);
-
-       /* set my path */
-       if (SHGetPathFromIDListA(pidl, sTemp))
-       {
-         This->sMyPath = SHAlloc(strlen(sTemp)+1);
-         strcpy(This->sMyPath, sTemp);
-       }
+       if ((SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
+           *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
 
-       TRACE("--(%p)->(%s)\n", This, This->sMyPath);
+       if ((SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
+           *pdwAttributes &= ~SFGAO_HIDDEN;
 
-       return S_OK;
+       if ((SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
+           *pdwAttributes &= ~SFGAO_READONLY;
+    } else {
+       *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK;
+    }
+    TRACE ("-- 0x%08lx\n", *pdwAttributes);
+    return S_OK;
 }
 
-/**************************************************************************
-*  IPersistFolder2_fnGetCurFolder
-*/
-static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
-       IPersistFolder2 *       iface,
-       LPITEMIDLIST * pidl)
-{
-       _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
-       
-       TRACE("(%p)->(%p)\n",This, pidl);
-
-       if (!pidl) return E_POINTER;
-
-       *pidl = ILClone(This->absPidl);
-
-       return S_OK;
-}
-
-static ICOM_VTABLE(IPersistFolder2) psfvt = 
-{
-       ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-       ISFPersistFolder2_QueryInterface,
-       ISFPersistFolder2_AddRef,
-       ISFPersistFolder2_Release,
-       ISFPersistFolder2_GetClassID,
-       ISFPersistFolder2_Initialize,
-       ISFPersistFolder2_fnGetCurFolder
-};
-
-/****************************************************************************
- * ISFDropTarget implementation
+/***********************************************************************
+ *  SHELL32_CompareIDs
  */
-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);
+HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+{
+    int type1,
+      type2;
+    char szTemp1[MAX_PATH];
+    char szTemp2[MAX_PATH];
+    int nReturn = 0;
+    LPITEMIDLIST firstpidl,
+      nextpidl1,
+      nextpidl2;
+    IShellFolder *psf;
+
+    /* test for empty pidls */
+    BOOL isEmpty1 = _ILIsDesktop (pidl1);
+    BOOL isEmpty2 = _ILIsDesktop (pidl2);
+
+    if (isEmpty1 && isEmpty2)
+       return 0;
+    if (isEmpty1)
+       return -1;
+    if (isEmpty2)
+       return 1;
+
+    /* test for different types. Sort order is the PT_* constant */
+    type1 = _ILGetDataPointer (pidl1)->type;
+    type2 = _ILGetDataPointer (pidl2)->type;
+    if (type1 != type2)
+       return (type1 - type2);
+
+    /* test for name of pidl */
+    _ILSimpleGetText (pidl1, szTemp1, MAX_PATH);
+    _ILSimpleGetText (pidl2, szTemp2, MAX_PATH);
+    nReturn = strcasecmp (szTemp1, szTemp2);
+    if (nReturn != 0)
+       return nReturn;
+
+    /* test of complex pidls */
+    firstpidl = ILCloneFirst (pidl1);
+    nextpidl1 = ILGetNext (pidl1);
+    nextpidl2 = ILGetNext (pidl2);
+
+    /* optimizing: test special cases and bind not deeper */
+    /* the deeper shellfolder would do the same */
+    isEmpty1 = _ILIsDesktop (nextpidl1);
+    isEmpty2 = _ILIsDesktop (nextpidl2);
+
+    if (isEmpty1 && isEmpty2) {
+       nReturn = 0;
+    } else if (isEmpty1) {
+       nReturn = -1;
+    } else if (isEmpty2) {
+       nReturn = 1;
+    /* optimizing end */
+    } else if (SUCCEEDED (IShellFolder_BindToObject (iface, firstpidl, NULL, &IID_IShellFolder, (LPVOID *) & psf))) {
+       nReturn = IShellFolder_CompareIDs (psf, lParam, nextpidl1, nextpidl2);
+       IShellFolder_Release (psf);
+    }
+    ILFree (firstpidl);
+    return nReturn;
 }
 
-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)
+/***********************************************************************
+ *  SHCreateLinks
+ *
+ *   Undocumented.
+ */
+HRESULT WINAPI SHCreateLinks( HWND hWnd, LPCSTR lpszDir, LPDATAOBJECT lpDataObject,
+                              UINT uFlags, LPITEMIDLIST *lppidlLinks)
 {
-       _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
-       FIXME("(%p) object dropped\n",This);
-
-       return E_NOTIMPL;
+    FIXME("%p %s %p %08x %p\n",hWnd,lpszDir,lpDataObject,uFlags,lppidlLinks);
+    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
-};