patch shell32

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- cleaned up the implementation of shell folders and put them into seperate 
files
- fixed some memoryleaks
- some more fixes



the native mydocs.dll (w2k) is now working.

juergen
Index: wine/dlls/shell32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/shell32/Makefile.in,v
retrieving revision 1.50
diff -d -u -r1.50 Makefile.in
--- wine/dlls/shell32/Makefile.in	14 Jun 2002 23:48:27 -0000	1.50
+++ wine/dlls/shell32/Makefile.in	18 Jul 2002 19:33:30 -0000
@@ -37,6 +37,9 @@
 	shellreg.c \
 	shlexec.c \
 	shlfileop.c \
+	shfldr_desktop.c \
+	shfldr_fs.c \
+	shfldr_mycomp.c \
 	shlfolder.c \
 	shlview.c \
 	shpolicy.c \
@@ -64,3 +67,6 @@
 shell.spec.c: version16.res
 
 ### Dependencies:
+
+
+
Index: wine/dlls/shell32/brsfolder.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/brsfolder.c,v
retrieving revision 1.37
diff -d -u -r1.37 brsfolder.c
--- wine/dlls/shell32/brsfolder.c	31 May 2002 23:25:51 -0000	1.37
+++ wine/dlls/shell32/brsfolder.c	18 Jul 2002 19:33:31 -0000
@@ -14,6 +14,11 @@
  * 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
+ *
+ * FIXME:
+ *  - view with root unequal desktop
+ *  - many memory leaks
+ *  - show only filesystem objects
  */
 
 #include <stdlib.h>
@@ -52,7 +57,7 @@
 
 	/* so far, this method doesn't work (still missing the upper level), keep the old way */
 #if 0
-	if (root == NULL) {
+	if (_ILIsDesktop (root)) {
 	   hr = SHGetDesktopFolder(&lpsf);
 	} else {
 	   IShellFolder *	lpsfdesktop;
Index: wine/dlls/shell32/classes.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/classes.c,v
retrieving revision 1.22
diff -d -u -r1.22 classes.c
--- wine/dlls/shell32/classes.c	31 May 2002 23:25:52 -0000	1.22
+++ wine/dlls/shell32/classes.c	18 Jul 2002 19:33:32 -0000
@@ -30,6 +30,7 @@
 #include "shell32_main.h"
 #include "shlguid.h"
 #include "shresdef.h"
+#include "shlwapi.h"
 #include "wine/obj_queryassociations.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -62,36 +63,24 @@
 
 	RegCloseKey(hkey);
 
-	TRACE("-- %s\n", szFileType );
+	TRACE("--UE;
+} %s\n", szFileType );
 
 	return TRUE;
 }
 BOOL HCR_GetExecuteCommand ( LPCSTR szClass, LPCSTR szVerb, LPSTR szDest, DWORD len )
 {
-	HKEY	hkey;
 	char	sTemp[MAX_PATH];
-	DWORD	dwType;
-	BOOL	ret = FALSE;
 
 	TRACE("%s %s\n",szClass, szVerb );
 
-	sprintf(sTemp, "%s\\shell\\%s\\command",szClass, szVerb);
+	snprintf(sTemp, MAX_PATH, "%s\\shell\\%s\\command",szClass, szVerb);
 
-	if (!RegOpenKeyExA(HKEY_CLASSES_ROOT,sTemp,0,0x02000000,&hkey))
-	{
-	  if (!RegQueryValueExA(hkey, NULL, 0, &dwType, szDest, &len))
-	  {
-	    if (dwType == REG_EXPAND_SZ)
-	    {
-	      ExpandEnvironmentStringsA(szDest, sTemp, MAX_PATH);
-	      strcpy(szDest, sTemp);
-	    }
-	    ret = TRUE;
-	  }
-	  RegCloseKey(hkey);
+	if (ERROR_SUCCESS == SHGetValueA(HKEY_CLASSES_ROOT, sTemp, NULL, NULL, szDest, &len)) {
+	    TRACE("-- %s\n", debugstr_a(szDest) );
+	    return TRUE;
 	}
-	TRACE("-- %s\n", szDest );
-	return ret;
+	return FALSE;
 }
 /***************************************************************************************
 *	HCR_GetDefaultIcon	[internal]
@@ -243,7 +232,6 @@
 	ICOM_VTBL(ei) = &qavt;
 
 	TRACE("(%p)\n",ei);
-	shell32_ObjCount++;
 	return (IQueryAssociations *)ei;
 }
 /**************************************************************************
@@ -288,8 +276,6 @@
 
 	TRACE("(%p)->(count=%lu)\n",This, This->ref );
 
-	shell32_ObjCount++;
-
 	return ++(This->ref);
 }
 /**************************************************************************
@@ -301,8 +287,6 @@
 
 	TRACE("(%p)->()\n",This);
 
-	shell32_ObjCount--;
-
 	if (!--(This->ref))
 	{
 	  TRACE(" destroying IExtractIcon(%p)\n",This);
@@ -376,3 +360,5 @@
 	IQueryAssociations_fnGetData,
 	IQueryAssociations_fnGetEnum
 };
+
+
Index: wine/dlls/shell32/clipboard.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/clipboard.c,v
retrieving revision 1.11
diff -d -u -r1.11 clipboard.c
--- wine/dlls/shell32/clipboard.c	2 Jul 2002 02:05:17 -0000	1.11
+++ wine/dlls/shell32/clipboard.c	18 Jul 2002 19:33:32 -0000
@@ -257,3 +257,4 @@
 	}
 	return ret;
 }
+
Index: wine/dlls/shell32/dataobject.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/dataobject.c,v
retrieving revision 1.31
diff -d -u -r1.31 dataobject.c
--- wine/dlls/shell32/dataobject.c	31 May 2002 23:25:52 -0000	1.31
+++ wine/dlls/shell32/dataobject.c	18 Jul 2002 19:33:33 -0000
@@ -84,8 +84,6 @@
 	  {
 	    memcpy(ef->pFmt, afmt, size);
 	  }
-
-	  shell32_ObjCount++;
 	}
 
 	TRACE("(%p)->(%u,%p)\n",ef, cfmt, afmt);
@@ -123,7 +121,6 @@
 {
 	ICOM_THIS(IEnumFORMATETCImpl,iface);
 	TRACE("(%p)->(count=%lu)\n",This, This->ref);
-	shell32_ObjCount++;
 	return ++(This->ref);
 }
 
@@ -132,8 +129,6 @@
 	ICOM_THIS(IEnumFORMATETCImpl,iface);
 	TRACE("(%p)->()\n",This);
 
-	shell32_ObjCount--;
-
 	if (!--(This->ref))
 	{
 	  TRACE(" destroying IEnumFORMATETC(%p)\n",This);
@@ -246,8 +241,6 @@
 	  InitFormatEtc(dto->pFormatEtc[0], dto->cfShellIDList, TYMED_HGLOBAL);
 	  InitFormatEtc(dto->pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL);
 	  InitFormatEtc(dto->pFormatEtc[2], dto->cfFileName, TYMED_HGLOBAL);
-
-	  shell32_ObjCount++;
 	}
 
 	TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl);
@@ -289,10 +282,7 @@
 static ULONG WINAPI IDataObject_fnAddRef(LPDATAOBJECT iface)
 {
 	ICOM_THIS(IDataObjectImpl,iface);
-
 	TRACE("(%p)->(count=%lu)\n",This, This->ref);
-
-	shell32_ObjCount++;
 	return ++(This->ref);
 }
 
@@ -304,12 +294,11 @@
 	ICOM_THIS(IDataObjectImpl,iface);
 	TRACE("(%p)->()\n",This);
 
-	shell32_ObjCount--;
-
 	if (!--(This->ref))
 	{
 	  TRACE(" destroying IDataObject(%p)\n",This);
 	  _ILFreeaPidl(This->apidl, This->cidl);
+	  ILFree(This->pidl),
 	  HeapFree(GetProcessHeap(),0,This);
 	  return 0;
 	}
@@ -454,4 +443,5 @@
 	IDataObject_fnDUnadvise,
 	IDataObject_fnEnumDAdvise
 };
+
 
Index: wine/dlls/shell32/debughlp.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/debughlp.c,v
retrieving revision 1.3
diff -d -u -r1.3 debughlp.c
--- wine/dlls/shell32/debughlp.c	2 Jul 2002 02:05:17 -0000	1.3
+++ wine/dlls/shell32/debughlp.c	18 Jul 2002 19:33:33 -0000
@@ -127,10 +127,6 @@
 	    case PT_SPECIAL:
 	    case PT_MYCOMP:
 	      return (REFIID) &(pdata->u.mycomp.guid);
-
-	    default:
-		TRACE("Unknown pidl type 0x%04x\n", pdata->type);
-		break;
 	  }
 	}
 	return NULL;
@@ -169,10 +165,6 @@
                  riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
 	  dwReturn = strlen (szTemp);
 	}
-	else
-	{
-	  ERR("-- no text\n");
-	}
 	return dwReturn;
 }
 
@@ -209,7 +201,7 @@
 	      else if( PT_VALUE == type)
 	        dwAttrib = pData->u.file.uFileAttribs;
 
-	      MESSAGE ("-- pidl=%p size=%u type=%lx attr=0x%08lx name=%s (%s,%s)\n",
+	      MESSAGE ("[%p] size=%04u type=%lx attr=0x%08lx name=\"%s\" (%s,%s)\n",
 	               pidltemp, pidltemp->mkid.cb,type,dwAttrib,szName,debugstr_a(szLongName), debugstr_a(szShortName));
 
 	      pidltemp = _dbg_ILGetNext(pidltemp);
@@ -267,7 +259,7 @@
 		  szTemp[i+BYTES_PRINTED*3]  =  (c>=0x20 && c <=0x80) ? c : '.';
 		}
 		szTemp[BYTES_PRINTED*4] = 0x00;
-		ERR("unknown IDLIST type size=%u type=%lx\n%s\n",pidltemp->mkid.cb,type, szTemp);
+		ERR("unknown IDLIST %p [%p] size=%u type=%lx\n%s\n",pidl, pidltemp, pidltemp->mkid.cb,type, szTemp);
 		ret = FALSE;
 	      }
 	    }
@@ -277,14 +269,16 @@
 	return ret;
 }
 
-static char shdebugstr_buf[100];
-
+static char shdebugstr_buf1[100];
+static char shdebugstr_buf2[100];
+static char * shdebugstr_buf = shdebugstr_buf1;
 
 static struct {
 	REFIID	riid;
 	char 	*name;
 } InterfaceDesc[] = {
 	{&IID_IUnknown,			"IID_IUnknown"},
+	{&IID_IClassFactory,		"IID_IClassFactory"},
 	{&IID_IShellView,		"IID_IShellView"},
 	{&IID_IOleCommandTarget,	"IID_IOleCommandTarget"},
 	{&IID_IDropTarget,		"IID_IDropTarget"},
@@ -309,12 +303,14 @@
 	char* name = NULL;
 	char clsidbuf[100];
 
+	shdebugstr_buf = (shdebugstr_buf == shdebugstr_buf1) ? shdebugstr_buf2 : shdebugstr_buf1;
+
 	if (!id) {
 	  strcpy (shdebugstr_buf, "(null)");
 	} else {
 	    for (i=0;InterfaceDesc[i].riid && !name;i++) {
 	        if (IsEqualIID(InterfaceDesc[i].riid, id)) name = InterfaceDesc[i].name;
-	    }
+	    } 
 	    if (!name) {
 		if (HCR_GetClassName(id, clsidbuf, 100))
 		    name = clsidbuf;
@@ -327,3 +323,10 @@
 	}
 	return shdebugstr_buf;
 }
+
+
+
+
+
+
+
Index: wine/dlls/shell32/enumidlist.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/enumidlist.c,v
retrieving revision 1.25
diff -d -u -r1.25 enumidlist.c
--- wine/dlls/shell32/enumidlist.c	31 May 2002 23:25:52 -0000	1.25
+++ wine/dlls/shell32/enumidlist.c	18 Jul 2002 19:33:34 -0000
@@ -317,9 +317,9 @@
 	IEnumIDListImpl*	lpeidl;
 	BOOL			ret = FALSE;
 
-	lpeidl = (IEnumIDListImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumIDListImpl));
+	TRACE("()->(%s flags=0x%08lx kind=0x%08lx)\n",debugstr_a(lpszPath),dwFlags, dwKind);
 
-	TRACE("(%p)->(%s flags=0x%08lx kind=0x%08lx)\n",lpeidl,debugstr_a(lpszPath),dwFlags, dwKind);
+	lpeidl = (IEnumIDListImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IEnumIDListImpl));
 
 	if (lpeidl)
 	{
@@ -341,17 +341,10 @@
 	      break;
 	  }
 
-	  if(ret)
-	  {
-	    shell32_ObjCount++;
-	  }
-	  else
-	  {
-	    if (lpeidl)
-	    {
-	      HeapFree(GetProcessHeap(),0,lpeidl);
+	    if(!ret) {
+	        HeapFree(GetProcessHeap(),0,lpeidl);
+	        lpeidl = NULL;
 	    }
-	  }
 	}
 
 	TRACE("-- (%p)->()\n",lpeidl);
@@ -397,10 +390,7 @@
 	IEnumIDList * iface)
 {
 	ICOM_THIS(IEnumIDListImpl,iface);
-
 	TRACE("(%p)->(%lu)\n",This,This->ref);
-
-	shell32_ObjCount++;
 	return ++(This->ref);
 }
 /******************************************************************************
@@ -413,10 +403,8 @@
 
 	TRACE("(%p)->(%lu)\n",This,This->ref);
 
-	shell32_ObjCount--;
-
-	if (!--(This->ref))
-	{ TRACE(" destroying IEnumIDList(%p)\n",This);
+	if (!--(This->ref)) {
+	  TRACE(" destroying IEnumIDList(%p)\n",This);
 	  DeleteList((IEnumIDList*)This);
 	  HeapFree(GetProcessHeap(),0,This);
 	  return 0;
@@ -530,3 +518,4 @@
 	IEnumIDList_fnReset,
 	IEnumIDList_fnClone,
 };
+
Index: wine/dlls/shell32/folders.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/folders.c,v
retrieving revision 1.31
diff -d -u -r1.31 folders.c
--- wine/dlls/shell32/folders.c	31 May 2002 23:25:52 -0000	1.31
+++ wine/dlls/shell32/folders.c	18 Jul 2002 19:33:34 -0000
@@ -69,7 +69,6 @@
 	pdump(pidl);
 
 	TRACE("(%p)\n",ei);
-	shell32_ObjCount++;
 	return (IExtractIconA *)ei;
 }
 /**************************************************************************
@@ -111,8 +110,6 @@
 
 	TRACE("(%p)->(count=%lu)\n",This, This->ref );
 
-	shell32_ObjCount++;
-
 	return ++(This->ref);
 }
 /**************************************************************************
@@ -123,8 +120,6 @@
 	ICOM_THIS(IExtractIconAImpl,iface);
 
 	TRACE("(%p)->()\n",This);
-
-	shell32_ObjCount--;
 
 	if (!--(This->ref))
 	{ TRACE(" destroying IExtractIcon(%p)\n",This);
Index: wine/dlls/shell32/memorystream.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/memorystream.c,v
retrieving revision 1.7
diff -d -u -r1.7 memorystream.c
--- wine/dlls/shell32/memorystream.c	31 May 2002 23:25:52 -0000	1.7
+++ wine/dlls/shell32/memorystream.c	18 Jul 2002 19:33:35 -0000
@@ -96,8 +96,6 @@
 	fstr->ref = 1;
 	fstr->dwLength = GetFileSize (hFile, NULL);
 
-	shell32_ObjCount++;
-
 	if (!(fstr->hMapping = CreateFileMappingA(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL)))
 	{
 	  WARN("failed to create filemap.\n");
@@ -158,7 +156,6 @@
 
 	TRACE("(%p)->(count=%lu)\n",This, This->ref);
 
-	shell32_ObjCount++;
 	return ++(This->ref);
 }
 
@@ -170,8 +167,6 @@
 	ICOM_THIS(ISHFileStream, iface);
 
 	TRACE("(%p)->()\n",This);
-
-	shell32_ObjCount--;
 
 	if (!--(This->ref))
 	{ TRACE(" destroying SHFileStream (%p)\n",This);
Index: wine/dlls/shell32/pidl.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/pidl.c,v
retrieving revision 1.72
diff -d -u -r1.72 pidl.c
--- wine/dlls/shell32/pidl.c	2 Jul 2002 02:05:17 -0000	1.72
+++ wine/dlls/shell32/pidl.c	18 Jul 2002 19:33:37 -0000
@@ -563,12 +563,15 @@
 {
 	WORD len;
 
+	TRACE("%p\n", pidl);
+
 	if(pidl)
 	{
 	  len =  pidl->mkid.cb;
 	  if (len)
 	  {
 	    pidl = (LPITEMIDLIST) (((LPBYTE)pidl)+len);
+	    TRACE("-- %p\n", pidl);
 	    return pidl;
 	  }
 	}
@@ -907,40 +910,28 @@
  * FIXME
  *  fnGetDisplayNameOf can return different types of OLEString
  */
-BOOL WINAPI SHGetPathFromIDListA (LPCITEMIDLIST pidl,LPSTR pszPath)
-{	STRRET str;
+BOOL WINAPI SHGetPathFromIDListA (LPCITEMIDLIST pidl, LPSTR pszPath)
+{
+	HRESULT hr;
+	STRRET str;
 	LPSHELLFOLDER shellfolder;
 
 	TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
+	pdump(pidl);
 
 	if (!pidl) return FALSE;
 
-	pdump(pidl);
-
-	if(_ILIsDesktop(pidl))
-	{
-	   SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
-	}
-	else if (_ILIsSpecialFolder(ILFindLastID(pidl)))
-	{
-	  /* we are somewhere in a special folder */
-	  return FALSE;
-	}
-	else
-	{
-	  if (SHGetDesktopFolder(&shellfolder)==S_OK)
-	  {
-	    if(!SUCCEEDED(IShellFolder_GetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&str))) {
-	      IShellFolder_Release(shellfolder);
-	      return FALSE;
+	hr = SHGetDesktopFolder(&shellfolder);
+	if (SUCCEEDED (hr)) {
+	    hr = IShellFolder_GetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&str);
+	    if(SUCCEEDED(hr)) {
+	        StrRetToStrNA (pszPath, MAX_PATH, &str, pidl);
 	    }
-	    StrRetToStrNA (pszPath, MAX_PATH, &str, pidl);
 	    IShellFolder_Release(shellfolder);
-	  }
 	}
-	TRACE_(shell)("-- (%s)\n",pszPath);
 
-	return TRUE;
+	TRACE_(shell)("-- %s, 0x%08lx\n",pszPath, hr);
+	return SUCCEEDED(hr);
 }
 /*************************************************************************
  * SHGetPathFromIDListW 			[SHELL32.@]
@@ -1287,7 +1278,7 @@
  */
 BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
 {	TRACE("(%p)\n",pidl);
-	return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
+	return pidl && pidl->mkid.cb  ? 0 : 1;
 }
 
 BOOL _ILIsMyComputer(LPCITEMIDLIST pidl)
@@ -1562,12 +1553,18 @@
 {
 	FILETIME ft,lft;
 	SYSTEMTIME time;
+	BOOL ret;
 
-	if (! _ILGetFileDateTime( pidl, &ft )) return FALSE;
+	if (_ILGetFileDateTime( pidl, &ft )) {
+	    FileTimeToLocalFileTime(&ft, &lft);
+	    FileTimeToSystemTime (&lft, &time);
+	    ret = GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  pOut, uOutSize);
+	} else {
+	    pOut[0] = '\0';
+	    ret = FALSE;
+	}
+	return ret;
 
-	FileTimeToLocalFileTime(&ft, &lft);
-	FileTimeToSystemTime (&lft, &time);
-	return GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL,  pOut, uOutSize);
 }
 
 /*************************************************************************
@@ -1788,3 +1785,8 @@
 
 	return dst;
 }
+
+
+
+
+
Index: wine/dlls/shell32/shell32_main.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32_main.c,v
retrieving revision 1.95
diff -d -u -r1.95 shell32_main.c
--- wine/dlls/shell32/shell32_main.c	2 Jul 2002 02:05:17 -0000	1.95
+++ wine/dlls/shell32/shell32_main.c	18 Jul 2002 19:33:39 -0000
@@ -215,7 +215,7 @@
 	IExtractIconA * pei = NULL;
 	LPITEMIDLIST	pidlLast = NULL, pidl = NULL;
 	HRESULT hr = S_OK;
-    BOOL IconNotYetLoaded=TRUE;
+	BOOL IconNotYetLoaded=TRUE;
 
 	TRACE("(%s fattr=0x%lx sfi=%p(attr=0x%08lx) size=0x%x flags=0x%x)\n",
 	  (flags & SHGFI_PIDL)? "pidl" : path, dwFileAttributes, psfi, psfi->dwAttributes, sizeofpsfi, flags);
@@ -289,25 +289,20 @@
 
 	/* translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES in not specified
 	   the pidl functions fail on not existing file names */
-	if (flags & SHGFI_PIDL)
-	{
-	  pidl = (LPCITEMIDLIST) path;
-	  if (!pidl )
-	  {
-	    ERR("pidl is null!\n");
-	    return FALSE;
-	  }
-	}
-	else if (!(flags & SHGFI_USEFILEATTRIBUTES))
-	{
-	  hr = SHILCreateFromPathA ( path, &pidl, &dwAttributes);
-	  /* note: the attributes in ISF::ParseDisplayName are not implemented */
+
+	if (flags & SHGFI_PIDL) {
+	    pidl = ILClone((LPCITEMIDLIST)path);
+	} else if (!(flags & SHGFI_USEFILEATTRIBUTES)) {
+	    hr = SHILCreateFromPathA(path, &pidl, &dwAttributes);
 	}
 
 	/* get the parent shellfolder */
-	if (pidl)
-	{
-	  hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidlLast);
+	if (pidl) {
+	    hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidlLast);
+	    ILFree(pidl);
+	} else {
+	    ERR("pidl is null!\n");
+	    return FALSE;
 	}
 
 	/* get the attributes of the child */
@@ -928,7 +923,6 @@
 
 static HINSTANCE	hComctl32;
 
-LONG		shell32_ObjCount = 0;
 HINSTANCE	shell32_hInstance = 0;
 HIMAGELIST	ShellSmallIconList = 0;
 HIMAGELIST	ShellBigIconList = 0;
@@ -995,15 +989,8 @@
 
 	  case DLL_PROCESS_DETACH:
 	      shell32_hInstance = 0;
-
 	      SIC_Destroy();
 	      FreeChangeNotifications();
-
-	      /* this one is here to check if AddRef/Release is balanced */
-	      if (shell32_ObjCount)
-	      {
-	        WARN("leaving with %lu objects left (memory leak)\n", shell32_ObjCount);
-	      }
               break;
 	}
 	return TRUE;
@@ -1034,3 +1021,7 @@
 
     return S_FALSE;
 }
+
+
+
+
Index: wine/dlls/shell32/shell32_main.h
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32_main.h,v
retrieving revision 1.48
diff -d -u -r1.48 shell32_main.h
--- wine/dlls/shell32/shell32_main.h	2 Jul 2002 02:05:17 -0000	1.48
+++ wine/dlls/shell32/shell32_main.h	18 Jul 2002 19:33:40 -0000
@@ -24,7 +24,7 @@
 
 #include "commctrl.h"
 #include "docobj.h"
-
+#include "undocshell.h"
 #include "wine/obj_shellfolder.h"
 #include "wine/obj_dataobject.h"
 #include "wine/obj_contextmenu.h"
@@ -38,7 +38,6 @@
 */
 extern HMODULE	huser32;
 extern HINSTANCE shell32_hInstance;
-extern LONG	  shell32_ObjCount;
 extern HIMAGELIST	ShellSmallIconList;
 extern HIMAGELIST	ShellBigIconList;
 extern HDPA		sic_hdpa;
@@ -98,6 +97,7 @@
 HRESULT WINAPI IFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI IShellLink_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI ISF_Desktop_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
+HRESULT WINAPI ISF_MyComputer_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 
 /* kind of enumidlist */
 #define EIDL_DESK	0
@@ -195,4 +195,27 @@
     return !(GetVersion() & 0x80000000);
 }
 
+#define __SHFreeAndNil(ptr) \
+	{\
+	  SHFree(*ptr); \
+	  *ptr = NULL; \
+	};
+inline static void __SHCloneStrA(char ** target,const char * source)
+{
+	*target = SHAlloc(strlen(source)+1); \
+	strcpy(*target, source); \
+}
+  
+inline static void __SHCloneStrWtoA(char ** target, const WCHAR * source) 
+{ 
+	int len = WideCharToMultiByte(CP_ACP, 0, source, -1, NULL, 0, NULL, NULL);
+	*target = SHAlloc(len);
+	WideCharToMultiByte(CP_ACP, 0, source, -1, *target, len, NULL, NULL);
+}
+
 #endif
+
+
+
+
+
Index: wine/dlls/shell32/shelllink.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shelllink.c,v
retrieving revision 1.41
diff -d -u -r1.41 shelllink.c
--- wine/dlls/shell32/shelllink.c	2 Jul 2002 02:05:17 -0000	1.41
+++ wine/dlls/shell32/shelllink.c	18 Jul 2002 19:33:44 -0000
@@ -991,7 +991,6 @@
 	    return E_NOINTERFACE;
 	}
 
-	shell32_ObjCount++;
 	return S_OK;
 }
 
@@ -1042,7 +1041,6 @@
 
 	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
-	shell32_ObjCount++;
 	return ++(This->ref);
 }
 /******************************************************************************
@@ -1054,7 +1052,6 @@
 
 	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
-	shell32_ObjCount--;
 	if (!--(This->ref))
 	{ TRACE("-- destroying IShellLink(%p)\n",This);
 
@@ -1560,3 +1557,4 @@
 	IShellLinkW_fnResolve,
 	IShellLinkW_fnSetPath
 };
+
Index: wine/dlls/shell32/shellole.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shellole.c,v
retrieving revision 1.48
diff -d -u -r1.48 shellole.c
--- wine/dlls/shell32/shellole.c	2 Jul 2002 02:05:17 -0000	1.48
+++ wine/dlls/shell32/shellole.c	18 Jul 2002 19:33:44 -0000
@@ -37,6 +37,7 @@
 #include "wine/debug.h"
 #include "shlwapi.h"
 #include "winuser.h"
+#include "debughlp.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -57,10 +58,11 @@
 struct {
 	REFIID			riid;
 	LPFNCREATEINSTANCE	lpfnCI;
-} InterfaceTable[4] = {
-	{&CLSID_ShellFSFolder, &IFSFolder_Constructor},
-	{&CLSID_ShellDesktop, &ISF_Desktop_Constructor},
-	{&CLSID_ShellLink, &IShellLink_Constructor},
+} InterfaceTable[5] = {
+	{&CLSID_ShellFSFolder,	&IFSFolder_Constructor},
+	{&CLSID_MyComputer,	&ISF_MyComputer_Constructor},
+	{&CLSID_ShellDesktop,	&ISF_Desktop_Constructor},
+	{&CLSID_ShellLink,	&IShellLink_Constructor},
 	{NULL,NULL}
 };
 
@@ -69,7 +71,7 @@
  *
  * NOTES
  *   wraper for late bound call to OLE32.DLL
- *
+ * 
  */
 HRESULT (WINAPI *pCoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv) = NULL;
 
@@ -77,7 +79,7 @@
 {
 	if (!*phModule) *phModule = GetModuleHandleW(szModuleName);
 	if (!*phModule) *phModule = LoadLibraryW(szModuleName);
-	if (*phModule) return GetProcAddress(*phModule, szProcName);
+	if (*phModule) return GetProcAddress(*phModule, szProcName); 
 	return NULL;
 }
 
@@ -90,7 +92,7 @@
 
 /*************************************************************************
  * SHCoCreateInstance [SHELL32.102]
- *
+ * 
  * NOTES
  *     exported by ordinal
  */
@@ -135,6 +137,9 @@
 	BOOLEAN bLoadWithoutCOM = FALSE;
 	IClassFactory * pcf = NULL;
 
+	if(!ppv) return E_POINTER;
+	*ppv=NULL;
+
 	/* if the clsid is a string, convert it */
 	if (!clsid)
 	{
@@ -143,17 +148,17 @@
 	  myclsid = &iid;
 	}
 
-	TRACE("(%p,\n\tCLSID:\t%s, unk:%p\n\tIID:\t%s,%p)\n",
-		aclsid,debugstr_guid(myclsid),pUnkOuter,debugstr_guid(refiid),ppv);
+	TRACE("(%p,%s,unk:%p,%s,%p)\n",
+		aclsid,shdebugstr_guid(myclsid),pUnkOuter,shdebugstr_guid(refiid),ppv);
 
 	/* we look up the dll path in the registry */
         __SHGUIDToStringW(myclsid, sClassID);
 	lstrcpyW(sKeyName, sCLSID);
 	lstrcatW(sKeyName, sClassID);
-	lstrcatW(sKeyName, sInProcServer32);
+	lstrcatW(sKeyName, sInProcServer32); 
 
 	if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_READ, &hKey)) {
-	    dwSize = sizeof(sDllPath);
+	    dwSize = sizeof(sDllPath); 
 	    SHQueryValueExW(hKey, NULL, 0,0, sDllPath, &dwSize );
 
 	    /* if a special registry key is set we loading a shell extension without help of OLE32 */
@@ -167,15 +172,13 @@
 	    /* since we can't find it in the registry we try internally */
 	    bLoadFromShell32 = TRUE;
 	}
-
+	
 	TRACE("WithoutCom=%u FromShell=%u\n", bLoadWithoutCOM, bLoadFromShell32);
 
 	/* now we create a instance */
-	*ppv=NULL;
-
 	if (bLoadFromShell32) {
 	    if (! SUCCEEDED(SHELL32_DllGetClassObject(myclsid, &IID_IClassFactory,(LPVOID*)&pcf))) {
-	        ERR("LoadFromShell failed for CLSID=%s\n", debugstr_guid(myclsid));
+	        ERR("LoadFromShell failed for CLSID=%s\n", shdebugstr_guid(myclsid));
 	    }
 	} else if (bLoadWithoutCOM) {
 
@@ -204,7 +207,7 @@
 	    hres = __CoCreateInstance(myclsid, pUnkOuter, CLSCTX_INPROC_SERVER, refiid, ppv);
 	    goto end;
 	}
-
+	
 	/* here we should have a ClassFactory */
 	if (!pcf) return E_ACCESSDENIED;
 
@@ -213,8 +216,8 @@
 end:
 	if(hres!=S_OK)
 	{
-	  ERR("failed (0x%08lx) to create \n\tCLSID:\t%s\n\tIID:\t%s\n",
-              hres, debugstr_guid(myclsid), debugstr_guid(refiid));
+	  ERR("failed (0x%08lx) to create CLSID:%s IID:%s\n",
+              hres, shdebugstr_guid(myclsid), shdebugstr_guid(refiid));
 	  ERR("class not found in registry\n");
 	}
 
@@ -231,21 +234,21 @@
 	IClassFactory * pcf = NULL;
 	int i;
 
-	TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
-
+	TRACE("CLSID:%s,IID:%s\n",shdebugstr_guid(rclsid),shdebugstr_guid(iid));
+	
 	if (!ppv) return E_INVALIDARG;
 	*ppv = NULL;
 
-	/* search our internal interface table */
+	/* search our internal interface table */	
 	for(i=0;InterfaceTable[i].riid;i++) {
 	    if(IsEqualIID(InterfaceTable[i].riid, rclsid)) {
 	        TRACE("index[%u]\n", i);
-	        pcf = IDefClF_fnConstructor(InterfaceTable[i].lpfnCI, &shell32_ObjCount, NULL);
+	        pcf = IDefClF_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL);
 	    }
 	}
 
         if (!pcf) {
-	    FIXME("failed for CLSID=%s\n", debugstr_guid(rclsid));
+	    FIXME("failed for CLSID=%s\n", shdebugstr_guid(rclsid));
 	    return CLASS_E_CLASSNOTAVAILABLE;
 	}
 
@@ -273,7 +276,7 @@
 DWORD WINAPI SHCLSIDFromStringW (LPWSTR clsid, CLSID *id)
 {
 	TRACE("(%p(%s) %p)\n", clsid, debugstr_w(clsid), id);
-	return CLSIDFromString(clsid, id);
+	return CLSIDFromString(clsid, id); 
 }
 DWORD WINAPI SHCLSIDFromStringAW (LPVOID clsid, CLSID *id)
 {
@@ -305,8 +308,7 @@
  */
 static HRESULT WINAPI IShellMalloc_fnQueryInterface(LPMALLOC iface, REFIID refiid, LPVOID *obj)
 {
-	TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
-
+	TRACE("(%s,%p)\n",shdebugstr_guid(refiid),obj);
 	if (IsEqualIID(refiid, &IID_IUnknown) || IsEqualIID(refiid, &IID_IMalloc)) {
 		*obj = (LPMALLOC) &Shell_Malloc;
 		return S_OK;
@@ -363,7 +365,7 @@
 /******************************************************************************
  *		IShellMalloc_Free [VTABLE]
  */
-static VOID WINAPI IShellMalloc_fnFree(LPMALLOC iface, LPVOID pv)
+static VOID WINAPI IShellMalloc_fnFree(LPMALLOC iface, LPVOID pv) 
 {
         TRACE("(%p)\n",pv);
 	LocalFree((HANDLE) pv);
@@ -372,7 +374,7 @@
 /******************************************************************************
  *		IShellMalloc_GetSize [VTABLE]
  */
-static DWORD WINAPI IShellMalloc_fnGetSize(LPMALLOC iface, LPVOID pv)
+static DWORD WINAPI IShellMalloc_fnGetSize(LPMALLOC iface, LPVOID pv) 
 {
         DWORD cb = (DWORD) LocalSize((HANDLE)pv);
         TRACE("(%p,%ld)\n", pv, cb);
@@ -382,7 +384,7 @@
 /******************************************************************************
  *		IShellMalloc_DidAlloc [VTABLE]
  */
-static INT WINAPI IShellMalloc_fnDidAlloc(LPMALLOC iface, LPVOID pv)
+static INT WINAPI IShellMalloc_fnDidAlloc(LPMALLOC iface, LPVOID pv) 
 {
         TRACE("(%p)\n",pv);
         return -1;
@@ -418,7 +420,7 @@
  *  uses OLE32.CoGetMalloc if OLE32.DLL is already loaded.
  *  if not it uses a internal implementations as fallback.
  */
-DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal)
+DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal) 
 {
 	HRESULT (WINAPI *pCoGetMalloc)(DWORD,LPMALLOC *);
 	HMODULE hOle32;
@@ -456,7 +458,6 @@
 	if (!ShellTaskAllocator) SHGetMalloc(&ppv);
 
 	ret = (LPVOID) IMalloc_Alloc(ShellTaskAllocator, len);
-	if(ret) ZeroMemory(ret, len); /*FIXME*/
 	TRACE("%lu bytes at %p\n",len, ret);
 	return (LPVOID)ret;
 }
@@ -482,7 +483,7 @@
 DWORD WINAPI SHGetDesktopFolder(IShellFolder **psf)
 {
 	HRESULT	hres = S_OK;
-	TRACE("%p->(%p)\n",psf,*psf);
+	TRACE("\n");
 
 	if(!psf) return E_INVALIDARG;
 	*psf = NULL;
@@ -491,7 +492,6 @@
 	TRACE("-- %p->(%p)\n",psf, *psf);
 	return hres;
 }
-
 /**************************************************************************
  * Default ClassFactory Implementation
  *
@@ -532,7 +532,7 @@
 	if (pcRefDll) InterlockedIncrement(pcRefDll);
 	lpclf->riidInst = riidInst;
 
-	TRACE("(%p)\n\tIID:\t%s\n",lpclf, debugstr_guid(riidInst));
+	TRACE("(%p)%s\n",lpclf, shdebugstr_guid(riidInst));
 	return (LPCLASSFACTORY)lpclf;
 }
 /**************************************************************************
@@ -543,19 +543,19 @@
 {
 	ICOM_THIS(IDefClFImpl,iface);
 
-	TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
+	TRACE("(%p)->(%s)\n",This,shdebugstr_guid(riid));
 
 	*ppvObj = NULL;
 
 	if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) {
-	  *ppvObj = This;
+	  *ppvObj = This; 
 	  InterlockedIncrement(&This->ref);
 	  return S_OK;
 	}
 
 	TRACE("-- E_NOINTERFACE\n");
 	return E_NOINTERFACE;
-}
+}  
 /******************************************************************************
  * IDefClF_fnAddRef
  */
@@ -574,8 +574,8 @@
 	ICOM_THIS(IDefClFImpl,iface);
 	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
-	if (!InterlockedDecrement(&This->ref))
-	{
+	if (!InterlockedDecrement(&This->ref)) 
+	{ 
 	  if (This->pcRefDll) InterlockedDecrement(This->pcRefDll);
 
 	  TRACE("-- destroying IClassFactory(%p)\n",This);
@@ -592,10 +592,10 @@
 {
 	ICOM_THIS(IDefClFImpl,iface);
 
-	TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnkOuter,debugstr_guid(riid),ppvObject);
+	TRACE("%p->(%p,%s,%p)\n",This,pUnkOuter,shdebugstr_guid(riid),ppvObject);
 
 	*ppvObject = NULL;
-
+		
 	if ( This->riidInst==NULL ||
 	     IsEqualCLSID(riid, This->riidInst) ||
 	     IsEqualCLSID(riid, &IID_IUnknown) )
@@ -603,7 +603,7 @@
 	  return This->lpfnCI(pUnkOuter, riid, ppvObject);
 	}
 
-	ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
+	ERR("unknown IID requested %s\n",shdebugstr_guid(riid));
 	return E_NOINTERFACE;
 }
 /******************************************************************************
@@ -616,7 +616,7 @@
 	return E_NOTIMPL;
 }
 
-static ICOM_VTABLE(IClassFactory) dclfvt =
+static ICOM_VTABLE(IClassFactory) dclfvt = 
 {
     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
     IDefClF_fnQueryInterface,
@@ -630,16 +630,16 @@
  * SHCreateDefClassObject			[SHELL32.70]
  */
 HRESULT WINAPI SHCreateDefClassObject(
-	REFIID	riid,
-	LPVOID*	ppv,
+	REFIID	riid,				
+	LPVOID*	ppv,	
 	LPFNCREATEINSTANCE lpfnCI,	/* [in] create instance callback entry */
 	LPDWORD	pcRefDll,		/* [in/out] ref count of the dll */
 	REFIID	riidInst)		/* [in] optional interface to the instance */
 {
 	IClassFactory * pcf;
 
-	TRACE("\n\tIID:\t%s %p %p %p \n\tIIDIns:\t%s\n",
-              debugstr_guid(riid), ppv, lpfnCI, pcRefDll, debugstr_guid(riidInst));
+	TRACE("%s %p %p %p %s\n",
+              shdebugstr_guid(riid), ppv, lpfnCI, pcRefDll, shdebugstr_guid(riidInst));
 
 	if (! IsEqualCLSID(riid, &IID_IClassFactory) ) return E_NOINTERFACE;
 	if (! (pcf = IDefClF_fnConstructor(lpfnCI, pcRefDll, riidInst))) return E_OUTOFMEMORY;
@@ -653,7 +653,7 @@
 void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
 {
 	LONG exstyle;
-
+  
 	if( !IsWindow(hWnd) ) return;
 	exstyle = GetWindowLongA(hWnd,GWL_EXSTYLE);
 	if (b)
@@ -686,7 +686,7 @@
 
         *p = lpDropFileStruct->pt;
 	bRet = lpDropFileStruct->fNC;
-
+  
 	GlobalUnlock(hDrop);
 	return bRet;
 }
@@ -807,3 +807,13 @@
 	GlobalUnlock(hDrop);
 	return i;
 }
+
+
+
+
+
+
+
+
+
+
Index: wine/dlls/shell32/shellord.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shellord.c,v
retrieving revision 1.99
diff -d -u -r1.99 shellord.c
--- wine/dlls/shell32/shellord.c	3 Jul 2002 21:07:36 -0000	1.99
+++ wine/dlls/shell32/shellord.c	18 Jul 2002 19:33:46 -0000
@@ -3,7 +3,7 @@
  * (NT uses Unicode strings, 95 uses ASCII strings)
  *
  * Copyright 1997 Marcus Meissner
- *           1998 Jürgen Schmied
+ *           1998 Jrgen Schmied
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1490,3 +1490,4 @@
     if (*ppdataObject) return S_OK;
     return E_OUTOFMEMORY;
 }
+
Index: wine/dlls/shell32/shellstring.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shellstring.c,v
retrieving revision 1.22
diff -d -u -r1.22 shellstring.c
--- wine/dlls/shell32/shellstring.c	2 Jul 2002 02:05:17 -0000	1.22
+++ wine/dlls/shell32/shellstring.c	18 Jul 2002 19:33:47 -0000
@@ -47,7 +47,12 @@
 
 HRESULT WINAPI StrRetToStrNA (LPVOID dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
 {
-	TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
+	TRACE("dest=0x%p len=0x%lx strret=%p(%s) pidl=%p\n",
+	    dest,len,src,
+	    (src->uType == STRRET_WSTR) ? "STRRET_WSTR" : 
+	    (src->uType == STRRET_CSTR) ? "STRRET_CSTR" : 
+	    (src->uType == STRRET_OFFSET) ? "STRRET_OFFSET" : "STRRET_???",
+	    pidl);
 
 	switch (src->uType)
 	{
@@ -66,21 +71,23 @@
 
 	  default:
 	    FIXME("unknown type!\n");
-	    if (len)
-	    {
-	      *(LPSTR)dest = '\0';
-	    }
+	    if (len) *(LPSTR)dest = '\0';
 	    return(FALSE);
 	}
+	TRACE("-- %s\n", debugstr_a(dest) );
 	return S_OK;
 }
 
 /************************************************************************/
 
-HRESULT WINAPI StrRetToStrNW (LPVOID dest1, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
+HRESULT WINAPI StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
 {
-    LPWSTR dest = (LPWSTR) dest1;
-	TRACE("dest=0x%p len=0x%lx strret=0x%p pidl=%p stub\n",dest,len,src,pidl);
+	TRACE("dest=0x%p len=0x%lx strret=%p(%s) pidl=%p\n",
+	    dest,len,src,
+	    (src->uType == STRRET_WSTR) ? "STRRET_WSTR" : 
+	    (src->uType == STRRET_CSTR) ? "STRRET_CSTR" : 
+	    (src->uType == STRRET_OFFSET) ? "STRRET_OFFSET" : "STRRET_???",
+	    pidl);
 
 	switch (src->uType)
 	{
@@ -90,24 +97,18 @@
 	    break;
 
 	  case STRRET_CSTR:
-              if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len)
-                  dest[len-1] = 0;
+            if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len)
+                  ((LPWSTR)dest)[len-1] = 0;
 	    break;
 
 	  case STRRET_OFFSET:
-	    if (pidl)
-	    {
-              if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1,
-                                        dest, len ) && len)
-                  dest[len-1] = 0;
-	    }
+            if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1, dest, len ) && len)
+                  ((LPWSTR)dest)[len-1] = 0;
 	    break;
 
 	  default:
 	    FIXME("unknown type!\n");
-	    if (len)
-	    { *(LPSTR)dest = '\0';
-	    }
+	    if (len) *(LPWSTR)dest = '\0';
 	    return(FALSE);
 	}
 	return S_OK;
@@ -251,3 +252,7 @@
    handle);
     return 0;
 }
+
+
+
+
Index: wine/dlls/shell32/shlfolder.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shlfolder.c,v
retrieving revision 1.73
diff -d -u -r1.73 shlfolder.c
--- wine/dlls/shell32/shlfolder.c	16 Jul 2002 01:11:52 -0000	1.73
+++ wine/dlls/shell32/shlfolder.c	18 Jul 2002 19:33:48 -0000
@@ -1,8 +1,9 @@
+
 /*
  *	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
  *
@@ -46,9 +47,9 @@
 #include "shellfolder.h"
 #include "wine/debug.h"
 #include "debughlp.h"
+#include "shfldr.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(shell);
-
+WINE_DEFAULT_DEBUG_CHANNEL (shell);
 
 /***************************************************************************
  * debughelper: print out the return adress
@@ -62,15 +63,6 @@
 #define _CALL_TRACE
 #endif
 
-typedef struct
-{
-	int 	colnameid;
-	int	pcsFlags;
-	int	fmt;
-	int	cxChar;
-
-} shvheader;
-
 /***************************************************************************
  *  GetNextElement (internal function)
  *
@@ -85,2820 +77,355 @@
  *    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);
+LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut)
+{
+    LPCWSTR pszTail = pszNext;
+    DWORD dwCopy;
 
-	*pszOut=0x0000;
+    TRACE ("(%s %p 0x%08lx)\n", debugstr_w (pszNext), pszOut, dwOut);
 
-	if(!pszNext || !*pszNext)
-	  return NULL;
+    *pszOut = 0x0000;
 
-	while(*pszTail && (*pszTail != (WCHAR)'\\'))
-	  pszTail++;
+    if (!pszNext || !*pszNext)
+	return NULL;
 
-	dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
-	lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
+    while (*pszTail && (*pszTail != (WCHAR) '\\'))
+	pszTail++;
 
-	if(*pszTail)
-	   pszTail++;
-	else
-	   pszTail = NULL;
+    dwCopy = (WCHAR *) pszTail - (WCHAR *) pszNext + 1;
+    lstrcpynW (pszOut, pszNext, (dwOut < dwCopy) ? dwOut : dwCopy);
 
-	TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
-	return pszTail;
+    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)
+HRESULT SHELL32_ParseNextElement (HWND hwndOwner,
+				  IShellFolder2 * psf,
+				  LPITEMIDLIST * pidlInOut, LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes)
 {
-	HRESULT		hr = E_OUTOFMEMORY;
-	LPITEMIDLIST	pidlOut = NULL, pidlTemp = NULL;
-	IShellFolder	*psfChild;
-
-	TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
+    HRESULT hr = E_OUTOFMEMORY;
+    LPITEMIDLIST pidlOut = NULL,
+      pidlTemp = NULL;
+    IShellFolder *psfChild;
 
+    TRACE ("(%p, %p, %s)\n", psf, pidlInOut ? *pidlInOut : NULL, debugstr_w (szNext));
 
-	/* get the shellfolder for the child pidl and let it analyse further */
-	hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
+    /* get the shellfolder for the child pidl and let it analyse further */
+    hr = IShellFolder_BindToObject (psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID *) & psfChild);
 
-	if (psfChild)
-	{
-	  hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
-	  IShellFolder_Release(psfChild);
+    if (SUCCEEDED (hr)) {
+	hr = IShellFolder_ParseDisplayName (psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
+	IShellFolder_Release (psfChild);
 
-	  pidlTemp = ILCombine(*pidlInOut, pidlOut);
+	pidlTemp = ILCombine (*pidlInOut, pidlOut);
 
-	  if (pidlOut)
-	    ILFree(pidlOut);
-	}
+	if (pidlOut)
+	    ILFree (pidlOut);
+    }
 
-	ILFree(*pidlInOut);
-	*pidlInOut = pidlTemp;
+    ILFree (*pidlInOut);
+    *pidlInOut = pidlTemp;
 
-	TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
-	return hr;
+    TRACE ("-- pidl=%p ret=0x%08lx\n", pidlInOut ? *pidlInOut : NULL, hr);
+    return hr;
 }
 
 /***********************************************************************
  *	SHELL32_CoCreateInitSF
  *
- *	creates a initialized shell folder
+ * Creates a shell folder and initializes it with a pidl via IPersistFolder.
+ * This function is meant for virtual forders not backed by a file system 
+ * folder.
  */
-static HRESULT SHELL32_CoCreateInitSF (
-	LPITEMIDLIST pidlRoot,
-	LPITEMIDLIST pidlChild,
-	REFCLSID clsid,
-	REFIID iid,
-	LPVOID * ppvOut)
+HRESULT SHELL32_CoCreateInitSF (LPITEMIDLIST pidlRoot,
+				LPITEMIDLIST pidlChild, REFCLSID clsid, REFIID iid, LPVOID * ppvOut)
 {
-	HRESULT hr;
-	LPITEMIDLIST	pidlAbsolute;
-	IPersistFolder	*pPF;
-
-	TRACE("%p %p\n", pidlRoot, pidlChild);
-
-	*ppvOut = NULL;
-
-	if (SUCCEEDED((hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPF)))) {
-	  if(SUCCEEDED((hr = IPersistFolder_QueryInterface(pPF, iid, ppvOut)))) {
-	    pidlAbsolute = ILCombine (pidlRoot, pidlChild);
-	    hr = IPersistFolder_Initialize(pPF, pidlAbsolute);
-	    IPersistFolder_Release(pPF);
-	    SHFree(pidlAbsolute);
-	  }
-	}
+    HRESULT hr;
 
-	TRACE("-- ret=0x%08lx\n", hr);
-	return hr;
-}
+    TRACE ("%p %p\n", pidlRoot, pidlChild);
 
-static HRESULT SHELL32_GetDisplayNameOfChild(
-	IShellFolder2 * psf,
-	LPCITEMIDLIST pidl,
-	DWORD dwFlags,
-	LPSTR szOut,
-	DWORD dwOutLen)
-{
-	LPITEMIDLIST	pidlFirst, pidlNext;
-	IShellFolder2 *	psfChild;
-	HRESULT		hr = E_OUTOFMEMORY;
-	STRRET strTemp;
+    if (SUCCEEDED ((hr = SHCoCreateInstance (NULL, clsid, NULL, iid, ppvOut)))) {
 
-	TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
-	pdump(pidl);
+	IPersistFolder *pPF;
 
-	if ((pidlFirst = ILCloneFirst(pidl)))
-	{
-	  hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
-	  if (SUCCEEDED(hr))
-	  {
-	    pidlNext = ILGetNext(pidl);
+	if (SUCCEEDED ((hr = IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder, (LPVOID *) & pPF)))) {
 
-	    hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
-	    if (SUCCEEDED(hr))
-	    {
-	      hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
-	    }
+	    LPITEMIDLIST pidlAbsolute;
 
-	    IShellFolder_Release(psfChild);
-	  }
-	  ILFree(pidlFirst);
+	    pidlAbsolute = ILCombine (pidlRoot, pidlChild);
+	    IPersistFolder_Initialize (pPF, pidlAbsolute);
+	    IPersistFolder_Release (pPF);
+	    SHFree (pidlAbsolute);
 	}
+    }
 
-	TRACE("-- ret=0x%08lx %s\n", hr, szOut);
-
-	return hr;
+    TRACE ("-- (%p) ret=0x%08lx\n", *ppvOut, hr);
+    return hr;
 }
 
 /***********************************************************************
- *  SHELL32_GetItemAttributes
+ *	SHELL32_CoCreateInitSFEx
  *
- * 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)
+ * Creates a shell folder and initializes it with a pidl and a root folder
+ * via IPersistFolder3.
+ * This function is meant for virtual forders backed by a file system
+ * folder.
  *
- * This functions does not set flags!! It only resets flags when nessesary.
+ * NOTES
+ *   pathRoot can be NULL for Folders beeing a drive.
+ *   In this case the absolute path is build from pidlChild (eg. C:)
  */
-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;
-
-	  if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
-	      *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
-
-	  if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
-	      *pdwAttributes &= ~SFGAO_HIDDEN;
-
-	  if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
-	      *pdwAttributes &= ~SFGAO_READONLY;
-	}
-	else
-	{
-	  *pdwAttributes &= 0xb0000154;
-	}
-	TRACE("-- 0x%08lx\n", *pdwAttributes);
-	return S_OK;
-}
-
-/***********************************************************************
-*   IShellFolder implementation
-*/
-
-typedef struct
-{
-	ICOM_VFIELD(IUnknown);
-	DWORD				ref;
-	ICOM_VTABLE(IShellFolder2)*	lpvtblShellFolder;
-	ICOM_VTABLE(IPersistFolder3)*	lpvtblPersistFolder3;
-	ICOM_VTABLE(IDropTarget)*	lpvtblDropTarget;
-	ICOM_VTABLE(ISFHelper)*		lpvtblSFHelper;
-
-	IUnknown			*pUnkOuter;	/* used for aggregation */
-
-	CLSID*				pclsid;
-
-	/* both paths are parsible from the desktop */
-	LPSTR		sPathRoot;	/* complete path used as return value */
-	LPSTR		sPathTarget;	/* complete path to target used for enumeration and ChangeNotify */
-
-	LPITEMIDLIST	pidlRoot;	/* absolute pidl */
-	LPITEMIDLIST	pidlTarget;	/* absolute pidl */
-
-	int		dwAttributes;	/* attributes returned by GetAttributesOf FIXME: use it */
-
-	UINT		cfShellIDList;	/* clipboardformat for IDropTarget */
-	BOOL		fAcceptFmt;	/* flag for pending Drop */
-} IGenericSFImpl;
-
-static struct ICOM_VTABLE(IUnknown) unkvt;
-static struct ICOM_VTABLE(IShellFolder2) sfvt;
-static struct ICOM_VTABLE(IPersistFolder3) 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)->lpvtblPersistFolder3)))
-#define _ICOM_THIS_From_IPersistFolder3(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->lpvtblPersistFolder3)
-#define _IPersistFolder_(This)	(IPersistFolder*)&(This->lpvtblPersistFolder3)
-#define _IPersistFolder2_(This)	(IPersistFolder2*)&(This->lpvtblPersistFolder3)
-#define _IPersistFolder3_(This)	(IPersistFolder3*)&(This->lpvtblPersistFolder3)
-#define _IDropTarget_(This)	(IDropTarget*)&(This->lpvtblDropTarget)
-#define _ISFHelper_(This)	(ISFHelper*)&(This->lpvtblSFHelper)
-/**************************************************************************
-*	registers clipboardformat once
-*/
-static void SF_RegisterClipFmt (IGenericSFImpl * This)
-{
-	TRACE("(%p)\n", This);
-
-	if (!This->cfShellIDList)
-	{
-	  This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
-	}
-}
-
-/**************************************************************************
-*	we need a separate IUnknown to handle aggregation
-*	(inner IUnknown)
-*/
-static HRESULT WINAPI IUnknown_fnQueryInterface(
-	IUnknown * iface,
-	REFIID riid,
-	LPVOID *ppvObj)
-{
-	ICOM_THIS(IGenericSFImpl, iface);
-
-	_CALL_TRACE
-	TRACE("(%p)->(%s,%p)\n",This,shdebugstr_guid(riid),ppvObj);
-
-	*ppvObj = NULL;
-
-	if(IsEqualIID(riid, &IID_IUnknown))		*ppvObj = _IUnknown_(This);
-	else if(IsEqualIID(riid, &IID_IShellFolder))	*ppvObj = _IShellFolder_(This);
-	else if(IsEqualIID(riid, &IID_IShellFolder2))	*ppvObj = _IShellFolder_(This);
-	else if(IsEqualIID(riid, &IID_IPersist))	*ppvObj = _IPersist_(This);
-	else if(IsEqualIID(riid, &IID_IPersistFolder))	*ppvObj = _IPersistFolder_(This);
-	else if(IsEqualIID(riid, &IID_IPersistFolder2))	*ppvObj = _IPersistFolder2_(This);
-	else if(IsEqualIID(riid, &IID_IPersistFolder3))	*ppvObj = _IPersistFolder3_(This);
-	else if(IsEqualIID(riid, &IID_ISFHelper))	*ppvObj = _ISFHelper_(This);
-	else if(IsEqualIID(riid, &IID_IDropTarget))
-	{
-	  *ppvObj = _IDropTarget_(This);
-	  SF_RegisterClipFmt(This);
-	}
-
-	if(*ppvObj)
-	{
-	  IUnknown_AddRef((IUnknown*)(*ppvObj));
-	  TRACE("-- Interface = %p\n", *ppvObj);
-	  return S_OK;
-	}
-	TRACE("-- Interface: E_NOINTERFACE\n");
-	return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
-{
-	ICOM_THIS(IGenericSFImpl, iface);
-
-	_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(This->pidlRoot) SHFree(This->pidlRoot);
-	  if(This->sPathRoot) SHFree(This->sPathRoot);
-	  LocalFree((HLOCAL)This);
-	  return 0;
-	}
-	return This->ref;
-}
-
-static ICOM_VTABLE(IUnknown) unkvt =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IUnknown_fnQueryInterface,
-	IUnknown_fnAddRef,
-	IUnknown_fnRelease,
-};
-
-static shvheader GenericSFHeader [] =
-{
- { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
- { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
- { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
-};
-#define GENERICSHELLVIEWCOLUMNS 5
-
-/**************************************************************************
-*	IFSFolder_Constructor
-*
-* NOTES
-*  creating undocumented ShellFS_Folder as part of an aggregation
-*  {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
-*
-*/
-HRESULT WINAPI IFSFolder_Constructor(
-	IUnknown * pUnkOuter,
-	REFIID riid,
-	LPVOID * ppv)
+HRESULT SHELL32_CoCreateInitSFEx (LPITEMIDLIST pidlRoot,
+				  LPCSTR pathRoot, LPITEMIDLIST pidlChild, REFCLSID clsid, REFIID riid, LPVOID * ppvOut)
 {
-	IGenericSFImpl * sf;
-
-	TRACE("unkOut=%p %s\n",pUnkOuter, shdebugstr_guid(riid));
-
-	if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown)) return CLASS_E_NOAGGREGATION;
-	sf=(IGenericSFImpl*) LocalAlloc(GMEM_ZEROINIT,sizeof(IGenericSFImpl));
-	if (!sf) return E_OUTOFMEMORY;
-
-	sf->ref=1;
-	ICOM_VTBL(sf)=&unkvt;
-	sf->lpvtblShellFolder=&sfvt;
-	sf->lpvtblPersistFolder3=&psfvt;
-	sf->lpvtblDropTarget=&dtvt;
-	sf->lpvtblSFHelper=&shvt;
-	sf->pclsid = (CLSID*)&CLSID_ShellFSFolder;
-	sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
+    HRESULT hr;
+    IPersistFolder3 *ppf;
 
-	/* we have to return the inner IUnknown */
-	*ppv = _IUnknown_(sf);
+    TRACE ("%p %s %p\n", pidlRoot, pathRoot, pidlChild);
 
-	shell32_ObjCount++;
-	TRACE("--%p\n", *ppv);
-	return S_OK;
-}
+    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];
 
-/**************************************************************************
-*	InitializeGenericSF
-*/
-static HRESULT InitializeGenericSF(IGenericSFImpl * sf, LPITEMIDLIST pidlRoot, LPITEMIDLIST pidlFolder, LPCSTR sPathRoot)
-{
-	TRACE("(%p)->(pidl=%p, path=%s)\n",sf,pidlRoot, sPathRoot);
-	pdump(pidlRoot);
-	pdump(pidlFolder);
+	    ZeroMemory (&ppfti, sizeof (ppfti));
 
-	sf->pidlRoot = ILCombine(pidlRoot, pidlFolder);
-	if (!_ILIsSpecialFolder(pidlFolder)) {				/* only file system paths */
-	    char sNewPath[MAX_PATH];
-	    char * sPos;
+	    /* combine pidls */
+	    pidlAbsolute = ILCombine (pidlRoot, pidlChild);
 
-	    if (sPathRoot) {
-	        strcpy(sNewPath, sPathRoot);
-	        if (!((sPos = PathAddBackslashA (sNewPath)))) return E_UNEXPECTED;
+	    /* build path */
+	    if (pathRoot) {
+		lstrcpyA (szDestPath, pathRoot);
+		PathAddBackslashA(szDestPath);          /* FIXME: why have drives a backslash here ? */
 	    } else {
-	        sPos = sNewPath;
-	    }
-	    _ILSimpleGetText(pidlFolder, sPos, MAX_PATH - (sPos - sNewPath));
-	    if(!((sf->sPathRoot = SHAlloc(strlen(sNewPath)+1)))) return E_OUTOFMEMORY;
-	    strcpy(sf->sPathRoot, sNewPath);
-	    TRACE("-- %s\n", sNewPath);
-	}
-	return S_OK;
-}
-
-/**************************************************************************
-*	  IShellFolder_Constructor
-*/
-IGenericSFImpl * IShellFolder_Constructor()
-{
-	IGenericSFImpl * sf=(IGenericSFImpl*) LocalAlloc(GMEM_ZEROINIT,sizeof(IGenericSFImpl));
-	sf->ref=1;
-
-	ICOM_VTBL(sf)=&unkvt;
-	sf->lpvtblShellFolder=&sfvt;
-	sf->lpvtblPersistFolder3=&psfvt;
-	sf->lpvtblDropTarget=&dtvt;
-	sf->lpvtblSFHelper=&shvt;
-
-	sf->pclsid = (CLSID*)&CLSID_ShellFSFolder;
-	sf->pUnkOuter = _IUnknown_(sf);
-
-	TRACE("(%p)->()\n",sf);
-
-	shell32_ObjCount++;
-	return sf;
-}
-
-/**************************************************************************
- *  IShellFolder_fnQueryInterface
- *
- * PARAMETERS
- *  REFIID riid		[in ] Requested InterfaceID
- *  LPVOID* ppvObject	[out] Interface* to hold the result
- */
-static HRESULT WINAPI IShellFolder_fnQueryInterface(
-	IShellFolder2 * iface,
-	REFIID riid,
-	LPVOID *ppvObj)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	_CALL_TRACE
-	TRACE("(%p)->(%s,%p)\n",This,shdebugstr_guid(riid),ppvObj);
-
-	return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
-}
-
-/**************************************************************************
-*  IShellFolder_AddRef
-*/
-
-static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	_CALL_TRACE
-	TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-	return IUnknown_AddRef(This->pUnkOuter);
-}
-
-/**************************************************************************
- *  IShellFolder_fnRelease
- */
-static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	_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 */
-          WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
-	  strcpy(szPath, This->sPathRoot);
-	  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;
-	    }
-	  }
-	}
-
-        if (!hr)
-	  *ppidl = pidlTemp;
-	else
-	  *ppidl = NULL;
-
-	TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
-
-	return hr;
-}
-
-/**************************************************************************
-*		IShellFolder_fnEnumObjects
-* PARAMETERS
-*  HWND          hwndOwner,    //[in ] Parent Window
-*  DWORD         grfFlags,     //[in ] SHCONTF enumeration mask
-*  LPENUMIDLIST* ppenumIDList  //[out] IEnumIDList interface
-*/
-static HRESULT WINAPI IShellFolder_fnEnumObjects(
-	IShellFolder2 * iface,
-	HWND hwndOwner,
-	DWORD dwFlags,
-	LPENUMIDLIST* ppEnumIDList)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
-
-	*ppEnumIDList = NULL;
-	*ppEnumIDList = IEnumIDList_Constructor (This->sPathRoot, 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;
-        IGenericSFImpl  *pSFImpl;
-	IPersistFolder 	*pPersistFolder;
-	LPITEMIDLIST	pidlRoot;
-	HRESULT         hr;
-
-	TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",This,pidl,pbcReserved,shdebugstr_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)))
-	    {
-	      pidlRoot = ILCombine (This->pidlRoot, pidl);
-	      IPersistFolder_Initialize(pPersistFolder, pidlRoot);
-	      IPersistFolder_Release(pPersistFolder);
-	      SHFree(pidlRoot);
-	    }
-	    else
-	    {
-	      return E_FAIL;
-	    }
-	}
-	else
-	{
-	  if ((pSFImpl = IShellFolder_Constructor())) {
-	    LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
-	    hr = InitializeGenericSF(pSFImpl, This->pidlRoot, pidltemp, This->sPathRoot);
-	    ILFree(pidltemp);
-	    pShellFolder = _IShellFolder_(pSFImpl);
-	  }
-	}
-
-	if (_ILIsPidlSimple(pidl))
-	{
-	  if(IsEqualIID(riid, &IID_IShellFolder))
-	  {
-	    *ppvOut = pShellFolder;
-	    hr = S_OK;
-	  }
-	  else
-	  {
-	    hr = IShellFolder_QueryInterface(pShellFolder, riid, ppvOut);
-	    IShellFolder_Release(pShellFolder);
-	  }
-	}
-	else
-	{
-	  hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
-	  IShellFolder_Release(pShellFolder);
-	  *ppvOut = pSubFolder;
-	}
-
-	TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
-
-	return hr;
-}
-
-/**************************************************************************
-*  IShellFolder_fnBindToStorage
-* PARAMETERS
-*  LPCITEMIDLIST pidl,       //[in ] complex pidl to store
-*  LPBC          pbc,        //[in ] reserved
-*  REFIID        riid,       //[in ] Initial storage interface
-*  LPVOID*       ppvObject   //[out] Interface* returned
-*/
-static HRESULT WINAPI IShellFolder_fnBindToStorage(
-	IShellFolder2 * iface,
-	LPCITEMIDLIST pidl,
-	LPBC pbcReserved,
-	REFIID riid,
-	LPVOID *ppvOut)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n",
-              This,pidl,pbcReserved,shdebugstr_guid(riid),ppvOut);
-
-	*ppvOut = NULL;
-	return E_NOTIMPL;
-}
-
-/**************************************************************************
-*  IShellFolder_fnCompareIDs
-*
-* 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;
-
-	if (TRACE_ON(shell)) {
-	    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                                      /* no deeper on #1  */
-	      {
-	        pidl2 = ILGetNext(pidl2);
-		if (pidl2 && pidl2->mkid.cb)		/* go deeper on #2 ? */
-		    hr = ResultFromShort(-1);           /* two different */
-		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)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	LPSHELLVIEW	pShellView;
-	HRESULT		hr = E_INVALIDARG;
-
-	TRACE("(%p)->(hwnd=0x%x,%s,%p)\n",This,hwndOwner,shdebugstr_guid(riid),ppvOut);
-
-	if(ppvOut)
-	{
-	  *ppvOut = NULL;
-
-	  if(IsEqualIID(riid, &IID_IDropTarget))
-	  {
-	    hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
-	  }
-	  else if(IsEqualIID(riid, &IID_IContextMenu))
-	  {
-	    FIXME("IContextMenu not implemented\n");
-	    hr = E_NOTIMPL;
-	  }
-	  else if(IsEqualIID(riid, &IID_IShellView))
-	  {
-	    pShellView = IShellView_Constructor((IShellFolder*)iface);
-	    if(pShellView)
-	    {
-	      hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
-	      IShellView_Release(pShellView);
-	    }
-	  }
-	}
-	TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
-	return hr;
-}
-
-/**************************************************************************
-*  IShellFolder_fnGetAttributesOf
-*
-* PARAMETERS
-*  UINT            cidl,     //[in ] num elements in pidl array
-*  LPCITEMIDLIST*  apidl,    //[in ] simple pidl array
-*  ULONG*          rgfInOut) //[out] result array
-*
-*/
-static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
-	IShellFolder2 * iface,
-	UINT cidl,
-	LPCITEMIDLIST *apidl,
-	DWORD *rgfInOut)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	HRESULT hr = S_OK;
-
-	TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
-
-	if ( (!cidl) || (!apidl) || (!rgfInOut))
-	  return E_INVALIDARG;
-
-	while (cidl > 0 && *apidl)
-	{
-	  pdump (*apidl);
-	  SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
-	  apidl++;
-	  cidl--;
-	}
-
-	TRACE("-- result=0x%08lx\n",*rgfInOut);
-
-	return hr;
-}
-/**************************************************************************
-*  IShellFolder_fnGetUIObjectOf
-*
-* PARAMETERS
-*  HWND           hwndOwner, //[in ] Parent window for any output
-*  UINT           cidl,      //[in ] array size
-*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
-*  REFIID         riid,      //[in ] Requested Interface
-*  UINT*          prgfInOut, //[   ] reserved
-*  LPVOID*        ppvObject) //[out] Resulting Interface
-*
-* NOTES
-*  This function gets asked to return "view objects" for one or more (multiple select)
-*  items:
-*  The viewobject typically is an COM object with one of the following interfaces:
-*  IExtractIcon,IDataObject,IContextMenu
-*  In order to support icon positions in the default Listview your DataObject
-*  must implement the SetData method (in addition to GetData :) - the shell passes
-*  a barely documented "Icon positions" structure to SetData when the drag starts,
-*  and GetData's it if the drop is in another explorer window that needs the positions.
-*/
-static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
-	IShellFolder2 *	iface,
-	HWND		hwndOwner,
-	UINT		cidl,
-	LPCITEMIDLIST *	apidl,
-	REFIID		riid,
-	UINT *		prgfInOut,
-	LPVOID *	ppvOut)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	LPITEMIDLIST	pidl;
-	IUnknown*	pObj = NULL;
-	HRESULT		hr = E_INVALIDARG;
-
-	TRACE("(%p)->(0x%04x,%u,apidl=%p,%s,%p,%p)\n",
-	  This,hwndOwner,cidl,apidl,shdebugstr_guid(riid),prgfInOut,ppvOut);
-
-	if (ppvOut)
-	{
-	  *ppvOut = NULL;
-
-	  if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
-	  {
-	    pObj  = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->pidlRoot, apidl, cidl);
-	    hr = S_OK;
-	  }
-	  else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
-	  {
-	    pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
-	    hr = S_OK;
-	  }
-	  else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
-	  {
-	    pidl = ILCombine(This->pidlRoot,apidl[0]);
-	    pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
-	    SHFree(pidl);
-	    hr = S_OK;
-	  }
-	  else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
-	  {
-	    hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
-	  }
-	  else
-	  {
-	    hr = E_NOINTERFACE;
-	  }
-
-	  if(!pObj)
-	    hr = E_OUTOFMEMORY;
-
-	  *ppvOut = pObj;
-	}
-	TRACE("(%p)->hr=0x%08lx\n",This, hr);
-	return hr;
-}
-
-/**************************************************************************
-*  IShellFolder_fnGetDisplayNameOf
-*  Retrieves the display name for the specified file object or subfolder
-*
-* PARAMETERS
-*  LPCITEMIDLIST pidl,    //[in ] complex pidl to item
-*  DWORD         dwFlags, //[in ] SHGNO formatting flags
-*  LPSTRRET      lpName)  //[out] Returned display name
-*
-* FIXME
-*  if the name is in the pidl the ret value should be a STRRET_OFFSET
-*/
-#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->sPathRoot)
-	  {
-	    strcpy (szPath, This->sPathRoot);			/* get path to root*/
-	    PathAddBackslashA(szPath);
-	    len = strlen(szPath);
-	  }
-	  _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len);	/* append my own path */
-
-          /* MSDN also mentions SHGDN_FOREDITING, which isn't defined in wine */
-          if(!_ILIsFolder(pidl) && !(dwFlags & SHGDN_FORPARSING) &&
-             ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL)))
-          {
-              HKEY hKey;
-              DWORD dwData;
-              DWORD dwDataSize = sizeof(DWORD);
-              BOOL  doHide = 0; /* The default value is FALSE (win98 at least) */
-
-              /* XXX should it do this only for known file types? -- that would make it even slower! */
-			  /* XXX That's what the prompt says!! */
-              if(!RegCreateKeyExA(HKEY_CURRENT_USER,
-                                  "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
-                                  0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0))
-              {
-                  if(!RegQueryValueExA(hKey, "HideFileExt", 0, 0, (LPBYTE)&dwData, &dwDataSize))
-                      doHide = dwData;
-                  RegCloseKey(hKey);
-              }
-              if(doHide && szPath[0]!='.') PathRemoveExtensionA(szPath);
-          }
-	}
-
-	if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl)	/* go deeper if needed */
-	{
-	  PathAddBackslashA(szPath);
-	  len = strlen(szPath);
-
-	  if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
-	    return E_OUTOFMEMORY;
-	}
-	strRet->uType = STRRET_CSTR;
-	lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
-
-	TRACE("-- (%p)->(%s)\n", This, szPath);
-	return S_OK;
-}
-
-/**************************************************************************
-*  IShellFolder_fnSetNameOf
-*  Changes the name of a file object or subfolder, possibly changing its item
-*  identifier in the process.
-*
-* PARAMETERS
-*  HWND          hwndOwner,  //[in ] Owner window for output
-*  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
-*  LPCOLESTR     lpszName,   //[in ] the items new display name
-*  DWORD         dwFlags,    //[in ] SHGNO formatting flags
-*  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
-*/
-static HRESULT WINAPI IShellFolder_fnSetNameOf(
-	IShellFolder2 * iface,
-	HWND hwndOwner,
-	LPCITEMIDLIST pidl, /*simple pidl*/
-	LPCOLESTR lpName,
-	DWORD dwFlags,
-	LPITEMIDLIST *pPidlOut)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-	char szSrc[MAX_PATH], szDest[MAX_PATH];
-	int len;
-	BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
-
-	TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
-	  This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
-
-	/* build source path */
-	if (dwFlags & SHGDN_INFOLDER)
-	{
-	  strcpy(szSrc, This->sPathRoot);
-	  PathAddBackslashA(szSrc);
-	  len = strlen (szSrc);
-	  _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
-	}
-	else
-	{
-	  SHGetPathFromIDListA(pidl, szSrc);
-	}
-
-	/* build destination path */
-	strcpy(szDest, This->sPathRoot);
-	PathAddBackslashA(szDest);
-	len = strlen (szDest);
-        WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
-        szDest[MAX_PATH-1] = 0;
-	TRACE("src=%s dest=%s\n", szSrc, szDest);
-	if ( MoveFileA(szSrc, szDest) )
-	{
-	  if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
-	  SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
-	  return S_OK;
-	}
-	return E_FAIL;
-}
-
-static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
-	IShellFolder2 * iface,
-	GUID *pguid)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-	FIXME("(%p)\n",This);
-	return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellFolder_fnEnumSearches(
-	IShellFolder2 * iface,
-	IEnumExtraSearch **ppenum)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-	FIXME("(%p)\n",This);
-	return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
-	IShellFolder2 * iface,
-	DWORD dwRes,
-	ULONG *pSort,
-	ULONG *pDisplay)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	TRACE("(%p)\n",This);
-
-	if (pSort) *pSort = 0;
-	if (pDisplay) *pDisplay = 0;
-
-	return S_OK;
-}
-static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
-	IShellFolder2 * iface,
-	UINT iColumn,
-	DWORD *pcsFlags)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	TRACE("(%p)\n",This);
-
-	if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
-	*pcsFlags = GenericSFHeader[iColumn].pcsFlags;
-
-	return S_OK;
-}
-static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
-	IShellFolder2 * iface,
-	LPCITEMIDLIST pidl,
-	const SHCOLUMNID *pscid,
-	VARIANT *pv)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-	FIXME("(%p)\n",This);
-
-	return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
-	IShellFolder2 * iface,
-	LPCITEMIDLIST pidl,
-	UINT iColumn,
-	SHELLDETAILS *psd)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-	HRESULT hr = E_FAIL;
-
-	TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
-
-	if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
-	if (!pidl)
-	{
-	  /* the header titles */
-	  psd->fmt = GenericSFHeader[iColumn].fmt;
-	  psd->cxChar = GenericSFHeader[iColumn].cxChar;
-	  psd->str.uType = STRRET_CSTR;
-	  LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
-	  return S_OK;
-	}
-	else
-	{
-	  /* the data from the pidl */
-	  switch(iColumn)
-	  {
-	    case 0:	/* name */
-	      hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
-	      break;
-	    case 1:	/* size */
-	      _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
-	      break;
-	    case 2:	/* type */
-	      _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
-	      break;
-	    case 3:	/* date */
-	      _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
-	      break;
-	    case 4:	/* attributes */
-	      _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
-	      break;
-	  }
-	  hr = S_OK;
-	  psd->str.uType = STRRET_CSTR;
-	}
-
-	return hr;
-}
-static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
-	IShellFolder2 * iface,
-	LPCWSTR pwszName,
-	SHCOLUMNID *pscid)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-	FIXME("(%p)\n",This);
-	return E_NOTIMPL;
-}
-
-static ICOM_VTABLE(IShellFolder2) sfvt =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IShellFolder_fnQueryInterface,
-	IShellFolder_fnAddRef,
-	IShellFolder_fnRelease,
-	IShellFolder_fnParseDisplayName,
-	IShellFolder_fnEnumObjects,
-	IShellFolder_fnBindToObject,
-	IShellFolder_fnBindToStorage,
-	IShellFolder_fnCompareIDs,
-	IShellFolder_fnCreateViewObject,
-	IShellFolder_fnGetAttributesOf,
-	IShellFolder_fnGetUIObjectOf,
-	IShellFolder_fnGetDisplayNameOf,
-	IShellFolder_fnSetNameOf,
-
-	/* ShellFolder2 */
-	IShellFolder_fnGetDefaultSearchGUID,
-	IShellFolder_fnEnumSearches,
-	IShellFolder_fnGetDefaultColumn,
-	IShellFolder_fnGetDefaultColumnState,
-	IShellFolder_fnGetDetailsEx,
-	IShellFolder_fnGetDetailsOf,
-	IShellFolder_fnMapNameToSCID
-};
-
-/****************************************************************************
- * ISFHelper for IShellFolder implementation
- */
-
-static HRESULT WINAPI ISFHelper_fnQueryInterface(
-	ISFHelper *iface,
-	REFIID riid,
-	LPVOID *ppvObj)
-{
-	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
-	TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-	return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
-}
-
-static ULONG WINAPI ISFHelper_fnAddRef(
-	ISFHelper *iface)
-{
-	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
-	TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-	return IUnknown_AddRef(This->pUnkOuter);
-}
-
-static ULONG WINAPI ISFHelper_fnRelease(
-	ISFHelper *iface)
-{
-	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
-	TRACE("(%p)\n", This);
-
-	return IUnknown_Release(This->pUnkOuter);
-}
-
-
-/****************************************************************************
- * ISFHelper_fnAddFolder
- *
- * creates a unique folder name
- */
-
-static HRESULT WINAPI ISFHelper_fnGetUniqueName(
-	ISFHelper *iface,
-	LPSTR lpName,
-	UINT uLen)
-{
-	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
-	IEnumIDList * penum;
-	HRESULT hr;
-	char szText[MAX_PATH];
-	char * szNewFolder = "New Folder";
-
-	TRACE("(%p)(%s %u)\n", This, lpName, uLen);
-
-	if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
-
-	strcpy(lpName, szNewFolder);
-
-	hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
-	if (penum)
-	{
-	  LPITEMIDLIST pidl;
-	  DWORD dwFetched;
-	  int i=1;
-
-next:     IEnumIDList_Reset(penum);
-	  while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
-	  {
-	    _ILSimpleGetText(pidl, szText, MAX_PATH);
-	    if (0 == strcasecmp(szText, lpName))
-	    {
-	      sprintf(lpName, "%s %d", szNewFolder, i++);
-	      if (i > 99)
-	      {
-	        hr = E_FAIL;
-	        break;
-	      }
-	      goto next;
-	    }
-	  }
-
-	  IEnumIDList_Release(penum);
-	}
-	return hr;
-}
-
-/****************************************************************************
- * ISFHelper_fnAddFolder
- *
- * adds a new folder.
- */
-
-static HRESULT WINAPI ISFHelper_fnAddFolder(
-	ISFHelper *iface,
-	HWND hwnd,
-	LPCSTR lpName,
-	LPITEMIDLIST* ppidlOut)
-{
-	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
-	char lpstrNewDir[MAX_PATH];
-	DWORD bRes;
-	HRESULT hres = E_FAIL;
-
-	TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
-
-	strcpy(lpstrNewDir, This->sPathRoot);
-	PathAddBackslashA(lpstrNewDir);
-	strcat(lpstrNewDir, lpName);
-
-	bRes = CreateDirectoryA(lpstrNewDir, NULL);
-
-	if (bRes)
-	{
-	  LPITEMIDLIST pidl, pidlitem;
-
-	  pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
-
-	  pidl = ILCombine(This->pidlRoot, pidlitem);
-	  SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
-	  SHFree(pidl);
-
-	  if (ppidlOut) *ppidlOut = pidlitem;
-	  hres = S_OK;
-	}
-	else
-	{
-	  char lpstrText[128+MAX_PATH];
-	  char lpstrTempText[128];
-	  char lpstrCaption[256];
-
-	  /* Cannot Create folder because of permissions */
-	  LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
-	  LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
-	  sprintf(lpstrText,lpstrTempText, lpstrNewDir);
-	  MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
-	}
-
-	return hres;
-}
-
-/****************************************************************************
- * ISFHelper_fnDeleteItems
- *
- * deletes items in folder
- */
-static HRESULT WINAPI ISFHelper_fnDeleteItems(
-	ISFHelper *iface,
-	UINT cidl,
-	LPCITEMIDLIST* apidl)
-{
-	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
-	int i;
-	char szPath[MAX_PATH];
-        BOOL bConfirm = TRUE;
-
-	TRACE("(%p)(%u %p)\n", This, cidl, apidl);
-
-	/* deleting multiple items so give a slightly different warning */
-	if(cidl != 1)
-	{
-          char tmp[8];
-          snprintf(tmp, sizeof(tmp), "%d", cidl);
-	  if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
-            return E_FAIL;
-          bConfirm = FALSE;
-	}
-
-	for(i=0; i< cidl; i++)
-	{
-	  strcpy(szPath, This->sPathRoot);
-	  PathAddBackslashA(szPath);
-	  _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
-
-	  if (_ILIsFolder(apidl[i]))
-	  {
-	    LPITEMIDLIST pidl;
-	    TRACE("delete %s\n", szPath);
-	    if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
-	    {
-              TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
-	      return E_FAIL;
-	    }
-	    pidl = ILCombine(This->pidlRoot, apidl[i]);
-	    SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
-	    SHFree(pidl);
-	  }
-	  else if (_ILIsValue(apidl[i]))
-	  {
-	    LPITEMIDLIST pidl;
-
-	    TRACE("delete %s\n", szPath);
-	    if (! SHELL_DeleteFileA(szPath, bConfirm))
-	    {
-              TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
-	      return E_FAIL;
+		szDestPath[0] = '\0';
 	    }
-	    pidl = ILCombine(This->pidlRoot, apidl[i]);
-	    SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
-	    SHFree(pidl);
-	  }
-
-	}
-	return S_OK;
-}
-
-/****************************************************************************
- * ISFHelper_fnCopyItems
- *
- * copies items to this folder
- */
-static HRESULT WINAPI ISFHelper_fnCopyItems(
-	ISFHelper *iface,
-	IShellFolder* pSFFrom,
-	UINT cidl,
-	LPCITEMIDLIST *apidl)
-{
-	int i;
-	IPersistFolder2 * ppf2=NULL;
-	char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
-	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
-	TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
+	    lstrcatA (szDestPath, _ILGetTextPointer (pidlChild));
 
-	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);
+	    /* fill the PERSIST_FOLDER_TARGET_INFO */
+	    ppfti.dwAttributes = -1;
+	    ppfti.csidl = -1;
+	    MultiByteToWideChar (CP_ACP, 0, szDestPath, -1, ppfti.szTargetParsingName, MAX_PATH);
 
-	      strcpy(szDstPath, This->sPathRoot);
-	      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
-*
-*/
-HRESULT WINAPI ISF_Desktop_Constructor (
-	IUnknown * pUnkOuter,
-	REFIID riid,
-	LPVOID * ppv)
-{
-	IGenericSFImpl *	sf;
-
-	TRACE("unkOut=%p %s\n",pUnkOuter, shdebugstr_guid(riid));
-
-	if(!ppv) return E_POINTER;
-
-	if(pUnkOuter ) {
-	    FIXME("CLASS_E_NOAGGREGATION\n");
-	    return CLASS_E_NOAGGREGATION;
-	}
-
-	sf=(IGenericSFImpl*) LocalAlloc(GMEM_ZEROINIT,sizeof(IGenericSFImpl));
-	sf->ref=1;
-	ICOM_VTBL(sf)=&unkvt;
-	sf->lpvtblShellFolder=&sfdvt;
-	sf->pidlRoot=_ILCreateDesktop();	/* my qualified pidl */
-	sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
-
-	*ppv = _IShellFolder_(sf);
-	shell32_ObjCount++;
-
-	TRACE("--(%p)\n",sf);
-	return S_OK;
-}
-
-/**************************************************************************
- *	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)
+HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
+			     LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
 {
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
-	TRACE("(%p)->(%s,%p)\n",This,shdebugstr_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;
-}
+    GUID const *clsid;
+    IShellFolder *pSF;
+    HRESULT hr;
+    LPITEMIDLIST pidlChild;
 
-/**************************************************************************
-*	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)
+    if (!pidlRoot || !ppvOut)
+	return E_INVALIDARG;
 
-        WCHAR           szElement[MAX_PATH];
-	LPCWSTR		szNext=NULL;
-	LPITEMIDLIST	pidlTemp=NULL;
-	HRESULT		hr=E_OUTOFMEMORY;
-	CLSID		clsid;
+    *ppvOut = NULL;
 
-	TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
-	This,hwndOwner,pbcReserved,lpszDisplayName,
-	debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
+    pidlChild = ILCloneFirst (pidlComplete);
 
-	*ppidl = 0;
-	if (pchEaten) *pchEaten = 0;	/* strange but like the original */
+    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);
 
-	if(lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') {
-	    szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
-	    TRACE("-- element: %s\n", debugstr_w(szElement));
-	    CLSIDFromString(szElement+2, &clsid);
-	    TRACE("-- %s\n", shdebugstr_guid(&clsid));
-	    pidlTemp = _ILCreate(PT_MYCOMP, &clsid, sizeof(clsid));
+    if (SUCCEEDED (hr)) {
+	if (_ILIsPidlSimple (pidlComplete)) {
+	    /* no sub folders */
+	    hr = IShellFolder_QueryInterface (pSF, riid, ppvOut);
 	} else {
-	    pidlTemp = _ILCreateMyComputer();
-	    /* it's a filesystem path, so we cant cut anything away */
-	    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)
-{
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-	GUID		const * clsid;
-	IShellFolder	*pShellFolder, *pSubFolder;
-        IGenericSFImpl  *pSFImpl;
-	HRESULT         hr;
-
-	TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",
-              This,pidl,pbcReserved,shdebugstr_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->pidlRoot, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
-	     {
-	       return E_INVALIDARG;
-	     }
-	  }
-	}
-	else
-	{
-	  /* file system folder on the desktop */
-	  LPITEMIDLIST deskpidl, firstpidl, completepidl;
-	  IPersistFolder * ppf;
-
-	  /* combine pidls */
-	  if ((pSFImpl = IShellFolder_Constructor())) {
-	    pShellFolder = _IShellFolder_(pSFImpl);
-	    if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf))) {
-	      SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
-	      firstpidl = ILCloneFirst(pidl);
-	      completepidl = ILCombine(deskpidl, firstpidl);
-	      IPersistFolder_Initialize(ppf, completepidl);
-	      IPersistFolder_Release(ppf);
-	      ILFree(completepidl);
-	      ILFree(deskpidl);
-	      ILFree(firstpidl);
-	    }
-	  }
-	}
-
-	if (_ILIsPidlSimple(pidl))	/* no sub folders */
-	{
-	  *ppvOut = pShellFolder;
-	  hr = S_OK;
-	}
-	else				/* go deeper */
-	{
-	  hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
-	  IShellFolder_Release(pShellFolder);
-	  *ppvOut = pSubFolder;
-	}
-
-	TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
-
-	return hr;
-}
-
-/**************************************************************************
-*	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,%s,%p)\n",This,hwndOwner,shdebugstr_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)
-
-	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_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;
+	    /* go deeper */
+	    hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut);
 	}
-	strRet->uType = STRRET_CSTR;
-	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;
+	IShellFolder_Release (pSF);
+    }
 
-	if (!pidl)
-	{
-	  psd->fmt = DesktopSFHeader[iColumn].fmt;
-	  psd->cxChar = DesktopSFHeader[iColumn].cxChar;
-	  psd->str.uType = STRRET_CSTR;
-	  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_CSTR;
-	}
+    TRACE ("-- returning (%p) %08lx\n", *ppvOut, hr);
 
-	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;
+    return hr;
 }
 
-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->lpvtblPersistFolder3 = &psfvt;
-	sf->pclsid = (CLSID*)&CLSID_MyComputer;
-	sf->pidlRoot=_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);
-          WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
-	  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;
-        IGenericSFImpl  *pSFImpl;
-	LPITEMIDLIST	pidltemp;
-	HRESULT         hr;
-
-	TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",
-              This,pidl,pbcReserved,shdebugstr_guid(riid),ppvOut);
-
-	if(!pidl || !ppvOut) return E_INVALIDARG;
-
-	*ppvOut = NULL;
-
-	if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
-	{
-	   if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->pidlRoot, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
-	   {
-	     return E_FAIL;
-	   }
-	}
-	else
-	{
-	  if (!_ILIsDrive(pidl)) return E_INVALIDARG;
-
-	  if ((pSFImpl = IShellFolder_Constructor())) {
-	    pidltemp = ILCloneFirst(pidl);
-	    InitializeGenericSF(pSFImpl, This->pidlRoot, pidltemp, This->sPathRoot);
-	    ILFree(pidltemp);
-	    pShellFolder = _IShellFolder_(pSFImpl);
-	  }
-	}
-
-	if (_ILIsPidlSimple(pidl))	/* no sub folders */
-	{
-	  *ppvOut = pShellFolder;
-	  hr = S_OK;
-	}
-	else				/* go deeper */
-	{
-	  hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
-					 riid, (LPVOID)&pSubFolder);
-	  IShellFolder_Release(pShellFolder);
-	  *ppvOut = pSubFolder;
-	}
-
-	TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
-
-	return hr;
-}
-
-/**************************************************************************
-*	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,%s,%p)\n",This,hwndOwner,shdebugstr_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,sizeof(szDrive)-6,&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_CSTR;
-	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_CSTR;
-	  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_CSTR;
-	  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 ISFPersistFolder3_QueryInterface(
-	IPersistFolder3 *	iface,
-	REFIID			iid,
-	LPVOID*			ppvObj)
-{
-	_ICOM_THIS_From_IPersistFolder3(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 ISFPersistFolder3_AddRef(
-	IPersistFolder3 *	iface)
-{
-	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
-
-	TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-	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 ISFPersistFolder3_Release(
-	IPersistFolder3 *	iface)
+HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf,
+				       LPCITEMIDLIST pidl, DWORD dwFlags, LPSTR szOut, DWORD dwOutLen)
 {
-	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
+    LPITEMIDLIST pidlFirst;
+    HRESULT hr = E_OUTOFMEMORY;
 
-	TRACE("(%p)->(count=%lu)\n",This,This->ref);
+    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 ISFPersistFolder3_GetClassID(
-	IPersistFolder3 *	iface,
-	CLSID *			lpClassId)
-{
-	_ICOM_THIS_From_IPersistFolder3(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
- *  sPathRoot 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)
+ *
+ * This functions does not set flags!! It only resets flags when nessesary.
  */
-static HRESULT WINAPI ISFPersistFolder3_Initialize(
-	IPersistFolder3 *	iface,
-	LPCITEMIDLIST		pidl)
-{
-	char sTemp[MAX_PATH];
-	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
-
-	TRACE("(%p)->(%p)\n", This, pidl);
-
-	if(This->pidlRoot) SHFree(This->pidlRoot);	/* free the old pidl */
-	This->pidlRoot = ILClone(pidl);			/* set my pidl */
-
-	if(This->sPathRoot) SHFree(This->sPathRoot);
-
-	/* set my path */
-	if (SHGetPathFromIDListA(pidl, sTemp))
-	{
-	  This->sPathRoot = SHAlloc(strlen(sTemp)+1);
-	  strcpy(This->sPathRoot, sTemp);
-	}
-
-	TRACE("--(%p)->(%s)\n", This, This->sPathRoot);
-	return S_OK;
-}
-
-/**************************************************************************
-*  IPersistFolder2_fnGetCurFolder
-*/
-static HRESULT WINAPI ISFPersistFolder3_fnGetCurFolder(
-	IPersistFolder3 *	iface,
-	LPITEMIDLIST * pidl)
-{
-	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
-
-	TRACE("(%p)->(%p)\n",This, pidl);
-
-	if (!pidl) return E_POINTER;
-
-	*pidl = ILClone(This->pidlRoot);
-
-	return S_OK;
-}
-
-static HRESULT WINAPI ISFPersistFolder3_InitializeEx(
-	IPersistFolder3 *	iface,
-	IBindCtx *		pbc,
-	LPCITEMIDLIST		pidlRoot,
-	const PERSIST_FOLDER_TARGET_INFO *ppfti)
+HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPITEMIDLIST pidl, LPDWORD pdwAttributes)
 {
-	char sTemp[MAX_PATH];
-	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
-
-	FIXME("(%p)->(%p,%p,%p)\n",This,pbc,pidlRoot,ppfti);
-	TRACE("--%p %s %s 0x%08lx 0x%08x\n",
-	  ppfti->pidlTargetFolder, debugstr_w(ppfti->szTargetParsingName),
-	  debugstr_w(ppfti->szNetworkProvider), ppfti->dwAttributes, ppfti->csidl);
+    GUID const *clsid;
+    DWORD dwAttributes;
 
-	pdump(pidlRoot);
-	if(ppfti->pidlTargetFolder) pdump(ppfti->pidlTargetFolder);
+    TRACE ("0x%08lx\n", *pdwAttributes);
 
-	if(This->pidlRoot) SHFree(This->pidlRoot);	/* free the old pidl */
+    if (*pdwAttributes & (0xcff3fe88))
+	WARN ("attribute 0x%08lx not implemented\n", *pdwAttributes);
+    *pdwAttributes &= ~SFGAO_LINK;	/* FIXME: for native filedialogs */
 
-	if(ppfti->csidl == -1) {			/* set my pidl */
-	    This->pidlRoot = ILClone(ppfti->pidlTargetFolder);
+    if (_ILIsDrive (pidl)) {
+	*pdwAttributes &= 0xf0000144;
+    } else if ((clsid = _ILGetGUIDPointer (pidl))) {
+	if (HCR_GetFolderAttributes (clsid, &dwAttributes)) {
+	    *pdwAttributes &= dwAttributes;
 	} else {
-	    SHGetSpecialFolderLocation(0, ppfti->csidl, &This->pidlRoot);
+	    *pdwAttributes &= 0xb0000154;
 	}
+    } else if (_ILGetDataPointer (pidl)) {
+	dwAttributes = _ILGetFileAttributes (pidl, NULL, 0);
+	*pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
 
-	if(This->sPathRoot) SHFree(This->sPathRoot);
-
-	/* set my path */
-	if (SHGetPathFromIDListA(This->pidlRoot, sTemp))
-	{
-	  This->sPathRoot = SHAlloc(strlen(sTemp)+1);
-	  strcpy(This->sPathRoot, sTemp);
-	}
+	if ((SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
+	    *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
 
-	TRACE("--(%p)->(%s)\n", This, This->sPathRoot);
-	return S_OK;
-}
+	if ((SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
+	    *pdwAttributes &= ~SFGAO_HIDDEN;
 
-static HRESULT WINAPI ISFPersistFolder3_GetFolderTargetInfo(
-	IPersistFolder3 *iface,
-	PERSIST_FOLDER_TARGET_INFO *ppfti)
-{
-	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
-	FIXME("(%p)->(%p)\n",This,ppfti);
-	ZeroMemory(ppfti, sizeof(ppfti));
-	return E_NOTIMPL;
+	if ((SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
+	    *pdwAttributes &= ~SFGAO_READONLY;
+    } else {
+	*pdwAttributes &= 0xb0000154;
+    }
+    TRACE ("-- 0x%08lx\n", *pdwAttributes);
+    return S_OK;
 }
 
-static ICOM_VTABLE(IPersistFolder3) psfvt =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	ISFPersistFolder3_QueryInterface,
-	ISFPersistFolder3_AddRef,
-	ISFPersistFolder3_Release,
-	ISFPersistFolder3_GetClassID,
-	ISFPersistFolder3_Initialize,
-	ISFPersistFolder3_fnGetCurFolder,
-	ISFPersistFolder3_InitializeEx,
-	ISFPersistFolder3_GetFolderTargetInfo
-};
-
-/****************************************************************************
- * ISFDropTarget implementation
+/***********************************************************************
+ *  SHELL32_GetItemAttributes
  */
-static BOOL ISFDropTarget_QueryDrop(
-	IDropTarget *iface,
-	DWORD dwKeyState,
-	LPDWORD pdwEffect)
-{
-	DWORD dwEffect = *pdwEffect;
-
-	_ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
-	*pdwEffect = DROPEFFECT_NONE;
-
-	if (This->fAcceptFmt)
-	{ /* Does our interpretation of the keystate ... */
-	  *pdwEffect = KeyStateToDropEffect(dwKeyState);
-
-	  /* ... matches the desired effect ? */
-	  if (dwEffect & *pdwEffect)
-	  {
-	    return TRUE;
-	  }
-	}
-	return FALSE;
-}
-
-static HRESULT WINAPI ISFDropTarget_QueryInterface(
-	IDropTarget *iface,
-	REFIID riid,
-	LPVOID *ppvObj)
-{
-	_ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
-	TRACE("(%p)\n", This);
-
-	return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
-}
-
-static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
-{
-	_ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
-	TRACE("(%p)\n", This);
-
-	return IUnknown_AddRef(This->pUnkOuter);
-}
-
-static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
-{
-	_ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
-	TRACE("(%p)\n", This);
-
-	return IUnknown_Release(This->pUnkOuter);
-}
-
-static HRESULT WINAPI ISFDropTarget_DragEnter(
-	IDropTarget 	*iface,
-	IDataObject	*pDataObject,
-	DWORD		dwKeyState,
-	POINTL		pt,
-	DWORD		*pdwEffect)
-{
-	FORMATETC	fmt;
-
-	_ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
-	TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
-
-	InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
-
-	This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
-
-	ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
-
-	return S_OK;
-}
-
-static HRESULT WINAPI ISFDropTarget_DragOver(
-	IDropTarget	*iface,
-	DWORD		dwKeyState,
-	POINTL		pt,
-	DWORD		*pdwEffect)
+HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 {
-	_ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
-	TRACE("(%p)\n",This);
-
-	if(!pdwEffect) return E_INVALIDARG;
-
-	ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
-
-	return S_OK;
-}
+    int type1,
+      type2;
+    char szTemp1[MAX_PATH];
+    char szTemp2[MAX_PATH];
+    int nReturn = 0;
+    LPITEMIDLIST firstpidl,
+      nextpidl1,
+      nextpidl2;
+    IShellFolder *psf;
 
-static HRESULT WINAPI ISFDropTarget_DragLeave(
-	IDropTarget	*iface)
-{
-	_ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
+    // test for empty pidls
+    BOOL isEmpty1 = _ILIsDesktop (pidl1);
+    BOOL isEmpty2 = _ILIsDesktop (pidl2);
 
-	TRACE("(%p)\n",This);
+    if (isEmpty1 && isEmpty2)
+	return 0;
+    if (isEmpty1)
+	return -1;
+    if (isEmpty2)
+	return 1;
 
-	This->fAcceptFmt = FALSE;
+    // test for different types. Sort order is the PT_* constant */
+    type1 = _ILGetDataPointer (pidl1)->type;
+    type2 = _ILGetDataPointer (pidl2)->type;
+    if (type1 != type2)
+	return (type1 - type2);
 
-	return S_OK;
-}
+    // test for name of pidl
+    _ILSimpleGetText (pidl1, szTemp1, MAX_PATH);
+    _ILSimpleGetText (pidl2, szTemp2, MAX_PATH);
+    nReturn = strcasecmp (szTemp1, szTemp2);
+    if (nReturn != 0)
+	return nReturn;
 
-static HRESULT WINAPI ISFDropTarget_Drop(
-	IDropTarget	*iface,
-	IDataObject*	pDataObject,
-	DWORD		dwKeyState,
-	POINTL		pt,
-	DWORD		*pdwEffect)
-{
-	_ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
+    // test of complex pidls
+    firstpidl = ILCloneFirst (pidl1);
+    nextpidl1 = ILGetNext (pidl1);
+    nextpidl2 = ILGetNext (pidl2);
 
-	FIXME("(%p) object dropped\n",This);
+    // optimizing: test special cases and bind not deeper
+    // the deeper shellfolder would do the same
+    isEmpty1 = _ILIsDesktop (nextpidl1);
+    isEmpty2 = _ILIsDesktop (nextpidl2);
 
-	return E_NOTIMPL;
+    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 struct ICOM_VTABLE(IDropTarget) dtvt =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	ISFDropTarget_QueryInterface,
-	ISFDropTarget_AddRef,
-	ISFDropTarget_Release,
-	ISFDropTarget_DragEnter,
-	ISFDropTarget_DragOver,
-	ISFDropTarget_DragLeave,
- 	ISFDropTarget_Drop
-};
Index: wine/dlls/shell32/shlview.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shlview.c,v
retrieving revision 1.67
diff -d -u -r1.67 shlview.c
--- wine/dlls/shell32/shlview.c	31 May 2002 23:25:52 -0000	1.67
+++ wine/dlls/shell32/shlview.c	18 Jul 2002 19:33:51 -0000
@@ -169,7 +169,6 @@
 	IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
 
 	TRACE("(%p)->(%p)\n",sv, pFolder);
-	shell32_ObjCount++;
 	return (IShellView *) sv;
 }
 
@@ -1502,7 +1501,6 @@
 
 	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
-	shell32_ObjCount++;
 	return ++(This->ref);
 }
 /**********************************************************
@@ -1514,8 +1512,6 @@
 
 	TRACE("(%p)->()\n",This);
 
-	shell32_ObjCount--;
-
 	if (!--(This->ref))
 	{
 	  TRACE(" destroying IShellView(%p)\n",This);
@@ -1529,9 +1525,6 @@
 	  if (This->apidl)
 	    SHFree(This->apidl);
 
-	  if (This->pCommDlgBrowser)
-	    ICommDlgBrowser_Release(This->pCommDlgBrowser);
-
 	  HeapFree(GetProcessHeap(),0,This);
 	  return 0;
 	}
@@ -1733,7 +1726,9 @@
 	}
 
 	DestroyWindow(This->hWnd);
-	IShellBrowser_Release(This->pShellBrowser);
+	if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
+	if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
+
 
 	return S_OK;
 }
@@ -2272,4 +2267,5 @@
 	ISVViewObject_SetAdvise,
 	ISVViewObject_GetAdvise
 };
+
 
Index: wine/dlls/shell32/shv_bg_cmenu.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shv_bg_cmenu.c,v
retrieving revision 1.17
diff -d -u -r1.17 shv_bg_cmenu.c
--- wine/dlls/shell32/shv_bg_cmenu.c	31 May 2002 23:25:52 -0000	1.17
+++ wine/dlls/shell32/shv_bg_cmenu.c	18 Jul 2002 19:33:52 -0000
@@ -61,7 +61,6 @@
 	if(pSFParent) IShellFolder_AddRef(pSFParent);
 
 	TRACE("(%p)->()\n",cm);
-	shell32_ObjCount++;
 	return (IContextMenu*)cm;
 }
 
@@ -108,7 +107,6 @@
 
 	TRACE("(%p)->(count=%lu)\n",This, This->ref);
 
-	shell32_ObjCount++;
 	return ++(This->ref);
 }
 
@@ -131,8 +129,6 @@
 	  HeapFree(GetProcessHeap(),0,This);
 	  return 0;
 	}
-
-	shell32_ObjCount--;
 
 	return This->ref;
 }
Index: wine/dlls/shell32/shv_item_cmenu.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shv_item_cmenu.c,v
retrieving revision 1.9
diff -d -u -r1.9 shv_item_cmenu.c
--- wine/dlls/shell32/shv_item_cmenu.c	31 May 2002 23:25:52 -0000	1.9
+++ wine/dlls/shell32/shv_item_cmenu.c	18 Jul 2002 19:33:53 -0000
@@ -98,7 +98,6 @@
 
 	TRACE("(%p)->()\n",cm);
 
-	shell32_ObjCount++;
 	return (IContextMenu*)cm;
 }
 
@@ -145,7 +144,6 @@
 
 	TRACE("(%p)->(count=%lu)\n",This, This->ref);
 
-	shell32_ObjCount++;
 	return ++(This->ref);
 }
 
@@ -157,8 +155,6 @@
 	ICOM_THIS(ItemCmImpl, iface);
 
 	TRACE("(%p)->()\n",This);
-
-	shell32_ObjCount--;
 
 	if (!--(This->ref))
 	{
Index: wine/dlls/shell32/undocshell.h
===================================================================
RCS file: /home/wine/wine/dlls/shell32/undocshell.h,v
retrieving revision 1.7
diff -d -u -r1.7 undocshell.h
--- wine/dlls/shell32/undocshell.h	2 Jul 2002 02:05:17 -0000	1.7
+++ wine/dlls/shell32/undocshell.h	18 Jul 2002 19:33:54 -0000
@@ -909,3 +909,4 @@
 #endif /* defined(__cplusplus) */
 
 #endif /* __WINE_UNDOCSHELL_H */
+
--- /dev/null	Sun Jul 14 16:54:37 2002
+++ wine/dlls/shell32/shfldr.h	Wed Jul 17 23:03:19 2002
@@ -0,0 +1,48 @@
+
+/*
+ *	Virtual Folder
+ *	common definitions
+ *
+ *	Copyright 1997			Marcus Meissner
+ *	Copyright 1998, 1999, 2002	Juergen Schmied
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+typedef struct {
+    int colnameid;
+    int pcsFlags;
+    int fmt;
+    int cxChar;
+} shvheader;
+
+#define GET_SHGDN_FOR(dwFlags)         ((DWORD)dwFlags & (DWORD)0x0000FF00)
+#define GET_SHGDN_RELATION(dwFlags)    ((DWORD)dwFlags & (DWORD)0x000000FF)
+
+LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut);
+HRESULT SHELL32_ParseNextElement (HWND hwndOwner, IShellFolder2 * psf, LPITEMIDLIST * pidlInOut, LPOLESTR szNext,
+				  DWORD * pEaten, DWORD * pdwAttributes);
+HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPITEMIDLIST pidl, LPDWORD pdwAttributes);
+HRESULT SHELL32_CoCreateInitSF (LPITEMIDLIST pidlRoot, LPITEMIDLIST pidlChild, REFCLSID clsid, REFIID iid,
+				LPVOID * ppvOut);
+HRESULT SHELL32_CoCreateInitSFEx (LPITEMIDLIST pidlRoot, LPCSTR pathRoot, LPITEMIDLIST pidlChild, REFCLSID clsid,
+				  REFIID iid, LPVOID * ppvOut);
+HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTR szOut,
+				       DWORD dwOutLen);
+
+HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
+			     LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
+
+HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
--- /dev/null	Sun Jul 14 16:54:37 2002
+++ wine/dlls/shell32/shfldr_desktop.c	Thu Jul 18 17:29:07 2002
@@ -0,0 +1,664 @@
+
+/*
+ *	Virtual Desktop Folder
+ *
+ *	Copyright 1997			Marcus Meissner
+ *	Copyright 1998, 1999, 2002	Juergen Schmied
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "winbase.h"
+#include "winreg.h"
+
+#include "oleidl.h"
+#include "shlguid.h"
+
+#include "pidl.h"
+#include "wine/obj_base.h"
+#include "wine/obj_dragdrop.h"
+#include "wine/obj_shellfolder.h"
+#include "undocshell.h"
+#include "shell32_main.h"
+#include "shresdef.h"
+#include "shlwapi.h"
+#include "shellfolder.h"
+#include "wine/debug.h"
+#include "debughlp.h"
+#include "shfldr.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL (shell);
+
+/***********************************************************************
+* 	Desktopfolder implementation
+*/
+
+typedef struct {
+    ICOM_VFIELD (IShellFolder2);
+    DWORD ref;
+
+    CLSID *pclsid;
+
+    /* both paths are parsible from the desktop */
+    LPSTR sPathTarget;		/* complete path to target used for enumeration and ChangeNotify */
+    LPITEMIDLIST pidlRoot;	/* absolute pidl */
+
+    int dwAttributes;		/* attributes returned by GetAttributesOf FIXME: use it */
+
+    UINT cfShellIDList;		/* clipboardformat for IDropTarget */
+    BOOL fAcceptFmt;		/* flag for pending Drop */
+} IGenericSFImpl;
+
+#define _IUnknown_(This)	(IShellFolder*)&(This->lpVtbl)
+#define _IShellFolder_(This)	(IShellFolder*)&(This->lpVtbl)
+
+HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
+
+static struct ICOM_VTABLE (IShellFolder2) vt_MCFldr_ShellFolder2;
+
+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
+*/
+HRESULT WINAPI ISF_Desktop_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
+{
+    IGenericSFImpl *sf;
+    char szMyPath[MAX_PATH];
+
+    TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
+
+    if (!ppv)
+	return E_POINTER;
+    if (pUnkOuter)
+	return CLASS_E_NOAGGREGATION;
+
+    if (!SHGetSpecialFolderPathA (0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE))
+	return E_UNEXPECTED;
+
+    sf = (IGenericSFImpl *) LocalAlloc (GMEM_ZEROINIT, sizeof (IGenericSFImpl));
+    if (!sf)
+	return E_OUTOFMEMORY;
+
+    sf->ref = 0;
+    ICOM_VTBL (sf) = &vt_MCFldr_ShellFolder2;
+    sf->pidlRoot = _ILCreateDesktop ();	/* my qualified pidl */
+    sf->sPathTarget = SHAlloc (strlen (szMyPath) + 1);
+    lstrcpyA (sf->sPathTarget, szMyPath);
+
+    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv))) {
+	IUnknown_Release (_IUnknown_ (sf));
+	return E_NOINTERFACE;
+    }
+
+    TRACE ("--(%p)\n", sf);
+    return S_OK;
+}
+
+/**************************************************************************
+ *	ISF_Desktop_fnQueryInterface
+ *
+ * NOTES supports not IPersist/IPersistFolder
+ */
+static HRESULT WINAPI ISF_Desktop_fnQueryInterface (IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
+
+    *ppvObj = NULL;
+
+    if (IsEqualIID (riid, &IID_IUnknown) || IsEqualIID (riid, &IID_IShellFolder)
+	|| IsEqualIID (riid, &IID_IShellFolder2)) {
+	*ppvObj = 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;
+}
+
+static ULONG WINAPI ISF_Desktop_fnAddRef (IShellFolder2 * iface)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return ++(This->ref);
+}
+
+static ULONG WINAPI ISF_Desktop_fnRelease (IShellFolder2 * iface)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    if (!--(This->ref)) {
+	TRACE ("-- destroying IShellFolder(%p)\n", This);
+	if (This->pidlRoot)
+	    SHFree (This->pidlRoot);
+	if (This->sPathTarget)
+	    SHFree (This->sPathTarget);
+	LocalFree ((HLOCAL) This);
+    }
+    return This->ref;
+}
+
+/**************************************************************************
+*	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 (IGenericSFImpl, iface);
+
+    WCHAR szElement[MAX_PATH];
+    LPCWSTR szNext = NULL;
+    LPITEMIDLIST pidlTemp = NULL;
+    HRESULT hr = E_OUTOFMEMORY;
+    CLSID clsid;
+
+    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 */
+
+    if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') {
+	szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
+	TRACE ("-- element: %s\n", debugstr_w (szElement));
+	CLSIDFromString (szElement + 2, &clsid);
+	pidlTemp = _ILCreate (PT_MYCOMP, &clsid, sizeof (clsid));
+    } else if (PathGetDriveNumberW (lpszDisplayName) >= 0) {
+	/* it's a filesystem path with a drive. Let MyComputer parse it */
+	pidlTemp = _ILCreateMyComputer ();
+	szNext = lpszDisplayName;
+    } else {
+	/* it's a filesystem path on the desktop. Let a FSFolder parse it */
+	WCHAR szCompletePath[MAX_PATH];
+
+	/* build a complete path to create a simpel pidl */
+	MultiByteToWideChar (CP_ACP, 0, This->sPathTarget, -1, szCompletePath, MAX_PATH);
+	PathAddBackslashW (szCompletePath);
+	lstrcatW (szCompletePath, lpszDisplayName);
+	pidlTemp = SHSimpleIDListFromPathW (lpszDisplayName);
+	szNext = lpszDisplayName;
+    }
+
+    if (pidlTemp) {
+	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 (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)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+
+    return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid, ppvOut);
+}
+
+/**************************************************************************
+*	ISF_Desktop_fnBindToStorage
+*/
+static HRESULT WINAPI ISF_Desktop_fnBindToStorage (IShellFolder2 * iface,
+						   LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+
+    *ppvOut = NULL;
+    return E_NOTIMPL;
+}
+
+/**************************************************************************
+* 	ISF_Desktop_fnCompareIDs
+*/
+
+static HRESULT WINAPI ISF_Desktop_fnCompareIDs (IShellFolder2 * iface,
+						LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    int nReturn;
+
+    TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
+    nReturn = SHELL32_CompareIDs (_IShellFolder_ (This), lParam, pidl1, pidl2);
+    TRACE ("-- %i\n", nReturn);
+    return nReturn;
+}
+
+/**************************************************************************
+*	ISF_Desktop_fnCreateViewObject
+*/
+static HRESULT WINAPI ISF_Desktop_fnCreateViewObject (IShellFolder2 * iface,
+						      HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    LPSHELLVIEW pShellView;
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE ("(%p)->(hwnd=0x%x,%s,%p)\n", This, hwndOwner, shdebugstr_guid (riid), ppvOut);
+
+    if (ppvOut) {
+	*ppvOut = NULL;
+
+	if (IsEqualIID (riid, &IID_IDropTarget)) {
+	    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 (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_Desktop_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
+*
+*/
+static HRESULT WINAPI ISF_Desktop_fnGetUIObjectOf (IShellFolder2 * iface,
+						   HWND hwndOwner,
+						   UINT cidl,
+						   LPCITEMIDLIST * apidl,
+						   REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    LPITEMIDLIST pidl;
+    IUnknown *pObj = NULL;
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE ("(%p)->(0x%04x,%u,apidl=%p,%s,%p,%p)\n",
+	   This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
+
+    if (ppvOut) {
+	*ppvOut = NULL;
+
+	if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
+	    pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
+	    pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
+	    pidl = ILCombine (This->pidlRoot, apidl[0]);
+	    pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
+	    SHFree (pidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1)) {
+	    hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, (LPVOID *) & pObj);
+	} else {
+	    hr = E_NOINTERFACE;
+	}
+
+	if (!pObj)
+	    hr = E_OUTOFMEMORY;
+
+	*ppvOut = pObj;
+    }
+    TRACE ("(%p)->hr=0x%08lx\n", This, hr);
+    return hr;
+}
+
+/**************************************************************************
+*	ISF_Desktop_fnGetDisplayNameOf
+*
+* NOTES
+*	special case: pidl = null gives desktop-name back
+*/
+DWORD WINAPI __SHGUIDToStringA (REFGUID guid, LPSTR str)
+{
+    CHAR sFormat[52] = "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}";
+
+    return wsprintfA (str, sFormat,
+		      guid->Data1, guid->Data2, guid->Data3,
+		      guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
+		      guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
+
+}
+
+static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf (IShellFolder2 * iface,
+						      LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    CHAR szPath[MAX_PATH] = "";
+    GUID const *clsid;
+    HRESULT hr = S_OK;
+
+    TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
+    pdump (pidl);
+
+    if (!strRet)
+	return E_INVALIDARG;
+
+    if (_ILIsDesktop (pidl)) {
+	if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING)) {
+	    lstrcpyA (szPath, This->sPathTarget);
+	} else {
+	    HCR_GetClassName (&CLSID_ShellDesktop, szPath, MAX_PATH);
+	}
+    } else if (_ILIsPidlSimple (pidl)) {
+	if ((clsid = _ILGetGUIDPointer (pidl))) {
+	    if (GET_SHGDN_FOR (dwFlags) == SHGDN_FORPARSING) {
+		int bWantsForParsing;
+
+		/*
+		 * we can only get a filesystem path from a shellfolder if the value WantsFORPARSING in
+		 * CLSID\\{...}\\shellfolder exists
+		 * exception: the MyComputer folder has this keys not but like any filesystem backed 
+		 *            folder it needs these behaviour
+		 */
+		if (IsEqualIID (clsid, &CLSID_MyComputer)) {
+		    bWantsForParsing = 1;
+		} else {
+		    /* get the "WantsFORPARSING" flag from the registry */
+		    char szRegPath[100];
+
+		    lstrcpyA (szRegPath, "CLSID\\");
+		    __SHGUIDToStringA (clsid, &szRegPath[6]);
+		    lstrcatA (szRegPath, "\\shellfolder");
+		    bWantsForParsing =
+			(ERROR_SUCCESS ==
+			 SHGetValueA (HKEY_CLASSES_ROOT, szRegPath, "WantsFORPARSING", NULL, NULL, NULL));
+		}
+
+		if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) && bWantsForParsing) {
+		    /* we need the filesystem path to the destination folder. Only the folder itself can know it */
+		    hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, szPath, MAX_PATH);
+		} else {
+		    /* parsing name like ::{...} */
+		    lstrcpyA (szPath, "::");
+		    __SHGUIDToStringA (clsid, &szPath[2]);
+		}
+	    } else {
+		/* user friendly name */
+		HCR_GetClassName (clsid, szPath, MAX_PATH);
+	    }
+	} else {
+	    /* file system folder */
+	    _ILSimpleGetText (pidl, szPath, MAX_PATH);
+	}
+    } else {
+	/* a complex pidl, let the subfolder do the work */
+	hr = SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags, szPath, MAX_PATH);
+    }
+
+    if (SUCCEEDED (hr)) {
+	strRet->uType = STRRET_CSTR;
+	lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
+    }
+
+    TRACE ("-- (%p)->(%s,0x%08lx)\n", This, szPath, hr);
+    return hr;
+}
+
+/**************************************************************************
+*  ISF_Desktop_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 ISF_Desktop_fnSetNameOf (IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,	/*simple pidl */
+					       LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    FIXME ("(%p)->(%u,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
+
+    return E_FAIL;
+}
+
+static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID (IShellFolder2 * iface, GUID * pguid)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+static HRESULT WINAPI ISF_Desktop_fnEnumSearches (IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
+{
+    ICOM_THIS (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 (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 (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 (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 (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_CSTR;
+	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_CSTR;
+    }
+
+    return hr;
+}
+static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID (IShellFolder2 * iface, LPCWSTR pwszName, SHCOLUMNID * pscid)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+    FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+
+static ICOM_VTABLE (IShellFolder2) vt_MCFldr_ShellFolder2 =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	ISF_Desktop_fnQueryInterface,
+	ISF_Desktop_fnAddRef,
+	ISF_Desktop_fnRelease,
+	ISF_Desktop_fnParseDisplayName,
+	ISF_Desktop_fnEnumObjects,
+	ISF_Desktop_fnBindToObject,
+	ISF_Desktop_fnBindToStorage,
+	ISF_Desktop_fnCompareIDs,
+	ISF_Desktop_fnCreateViewObject,
+	ISF_Desktop_fnGetAttributesOf,
+	ISF_Desktop_fnGetUIObjectOf,
+	ISF_Desktop_fnGetDisplayNameOf,
+	ISF_Desktop_fnSetNameOf,
+	/* ShellFolder2 */
+        ISF_Desktop_fnGetDefaultSearchGUID,
+	ISF_Desktop_fnEnumSearches,
+	ISF_Desktop_fnGetDefaultColumn,
+	ISF_Desktop_fnGetDefaultColumnState,
+	ISF_Desktop_fnGetDetailsEx,
+	ISF_Desktop_fnGetDetailsOf,
+	ISF_Desktop_fnMapNameToSCID};
--- /dev/null	Sun Jul 14 16:54:37 2002
+++ wine/dlls/shell32/shfldr_fs.c	Thu Jul 18 17:36:24 2002
@@ -0,0 +1,1356 @@
+
+/*
+ *	file system folder
+ *
+ *	Copyright 1997			Marcus Meissner
+ *	Copyright 1998, 1999, 2002	Juergen Schmied
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "winbase.h"
+#include "winreg.h"
+
+#include "oleidl.h"
+#include "shlguid.h"
+
+#include "pidl.h"
+#include "wine/obj_base.h"
+#include "wine/obj_dragdrop.h"
+#include "wine/obj_shellfolder.h"
+#include "undocshell.h"
+#include "shell32_main.h"
+#include "shresdef.h"
+#include "shlwapi.h"
+#include "shellfolder.h"
+#include "wine/debug.h"
+#include "debughlp.h"
+#include "shfldr.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL (shell);
+
+/***********************************************************************
+*   IShellFolder implementation
+*/
+
+typedef struct {
+    ICOM_VFIELD (IUnknown);
+    DWORD ref;
+    ICOM_VTABLE (IShellFolder2) * lpvtblShellFolder;
+    ICOM_VTABLE (IPersistFolder3) * lpvtblPersistFolder3;
+    ICOM_VTABLE (IDropTarget) * lpvtblDropTarget;
+    ICOM_VTABLE (ISFHelper) * lpvtblSFHelper;
+
+    IUnknown *pUnkOuter;	/* used for aggregation */
+
+    CLSID *pclsid;
+
+    /* both paths are parsible from the desktop */
+    LPSTR sPathTarget;		/* complete path to target used for enumeration and ChangeNotify */
+
+    LPITEMIDLIST pidlRoot;	/* absolute pidl */
+
+    int dwAttributes;		/* attributes returned by GetAttributesOf FIXME: use it */
+
+    UINT cfShellIDList;		/* clipboardformat for IDropTarget */
+    BOOL fAcceptFmt;		/* flag for pending Drop */
+} IGenericSFImpl;
+
+static struct ICOM_VTABLE (IUnknown) unkvt;
+static struct ICOM_VTABLE (IShellFolder2) sfvt;
+static struct ICOM_VTABLE (IPersistFolder3) vt_FSFldr_PersistFolder3;	/* IPersistFolder3 for a FS_Folder */
+static struct ICOM_VTABLE (IDropTarget) dtvt;
+static struct ICOM_VTABLE (ISFHelper) shvt;
+
+#define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
+#define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
+
+#define _IPersistFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder3)))
+#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset);
+
+#define _IPersistFolder3_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder3)))
+#define _ICOM_THIS_From_IPersistFolder3(class, name) class* This = (class*)(((char*)name)-_IPersistFolder3_Offset);
+
+#define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
+#define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
+
+#define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
+#define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
+
+/*
+  converts This to a interface pointer
+*/
+#define _IUnknown_(This)	(IUnknown*)&(This->lpVtbl)
+#define _IShellFolder_(This)	(IShellFolder*)&(This->lpvtblShellFolder)
+#define _IShellFolder2_(This)	(IShellFolder2*)&(This->lpvtblShellFolder)
+#define _IPersist_(This)	(IPersist*)&(This->lpvtblPersistFolder3)
+#define _IPersistFolder_(This)	(IPersistFolder*)&(This->lpvtblPersistFolder3)
+#define _IPersistFolder2_(This)	(IPersistFolder2*)&(This->lpvtblPersistFolder3)
+#define _IPersistFolder3_(This)	(IPersistFolder3*)&(This->lpvtblPersistFolder3)
+#define _IDropTarget_(This)	(IDropTarget*)&(This->lpvtblDropTarget)
+#define _ISFHelper_(This)	(ISFHelper*)&(This->lpvtblSFHelper)
+
+/**************************************************************************
+*	registers clipboardformat once
+*/
+static void SF_RegisterClipFmt (IGenericSFImpl * This)
+{
+    TRACE ("(%p)\n", This);
+
+    if (!This->cfShellIDList) {
+	This->cfShellIDList = RegisterClipboardFormatA (CFSTR_SHELLIDLIST);
+    }
+}
+
+/**************************************************************************
+*	we need a separate IUnknown to handle aggregation
+*	(inner IUnknown)
+*/
+static HRESULT WINAPI IUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppvObj)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
+
+    *ppvObj = NULL;
+
+    if (IsEqualIID (riid, &IID_IUnknown))
+	*ppvObj = _IUnknown_ (This);
+    else if (IsEqualIID (riid, &IID_IShellFolder))
+	*ppvObj = _IShellFolder_ (This);
+    else if (IsEqualIID (riid, &IID_IShellFolder2))
+	*ppvObj = _IShellFolder_ (This);
+    else if (IsEqualIID (riid, &IID_IPersist))
+	*ppvObj = _IPersist_ (This);
+    else if (IsEqualIID (riid, &IID_IPersistFolder))
+	*ppvObj = _IPersistFolder_ (This);
+    else if (IsEqualIID (riid, &IID_IPersistFolder2))
+	*ppvObj = _IPersistFolder2_ (This);
+    else if (IsEqualIID (riid, &IID_IPersistFolder3))
+	*ppvObj = _IPersistFolder3_ (This);
+    else if (IsEqualIID (riid, &IID_ISFHelper))
+	*ppvObj = _ISFHelper_ (This);
+    else if (IsEqualIID (riid, &IID_IDropTarget)) {
+	*ppvObj = _IDropTarget_ (This);
+	SF_RegisterClipFmt (This);
+    }
+
+    if (*ppvObj) {
+	IUnknown_AddRef ((IUnknown *) (*ppvObj));
+	TRACE ("-- Interface = %p\n", *ppvObj);
+	return S_OK;
+    }
+    TRACE ("-- Interface: E_NOINTERFACE\n");
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IUnknown_fnAddRef (IUnknown * iface)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return ++(This->ref);
+}
+
+static ULONG WINAPI IUnknown_fnRelease (IUnknown * iface)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    if (!--(This->ref)) {
+	TRACE ("-- destroying IShellFolder(%p)\n", This);
+
+	if (This->pidlRoot)
+	    SHFree (This->pidlRoot);
+	if (This->sPathTarget)
+	    SHFree (This->sPathTarget);
+	LocalFree ((HLOCAL) This);
+	return 0;
+    }
+    return This->ref;
+}
+
+static ICOM_VTABLE (IUnknown) unkvt =
+{
+    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE IUnknown_fnQueryInterface,
+      IUnknown_fnAddRef,
+      IUnknown_fnRelease,
+};
+
+static shvheader GenericSFHeader[] = {
+    {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
+    {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
+    {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
+    {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
+    {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
+};
+
+#define GENERICSHELLVIEWCOLUMNS 5
+
+/**************************************************************************
+*	IFSFolder_Constructor
+*
+* NOTES
+*  creating undocumented ShellFS_Folder as part of an aggregation
+*  {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
+*
+*/
+HRESULT WINAPI IFSFolder_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
+{
+    IGenericSFImpl *sf;
+
+    TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
+
+    if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown))
+	return CLASS_E_NOAGGREGATION;
+    sf = (IGenericSFImpl *) LocalAlloc (GMEM_ZEROINIT, sizeof (IGenericSFImpl));
+    if (!sf)
+	return E_OUTOFMEMORY;
+
+    sf->ref = 0;
+    ICOM_VTBL (sf) = &unkvt;
+    sf->lpvtblShellFolder = &sfvt;
+    sf->lpvtblPersistFolder3 = &vt_FSFldr_PersistFolder3;
+    sf->lpvtblDropTarget = &dtvt;
+    sf->lpvtblSFHelper = &shvt;
+    sf->pclsid = (CLSID *) & CLSID_ShellFSFolder;
+    sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_ (sf);
+
+    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv))) {
+	IUnknown_Release (_IUnknown_ (sf));
+	return E_NOINTERFACE;
+    }
+
+    TRACE ("--%p\n", *ppv);
+    return S_OK;
+}
+
+/**************************************************************************
+ *  IShellFolder_fnQueryInterface
+ *
+ * PARAMETERS
+ *  REFIID riid		[in ] Requested InterfaceID
+ *  LPVOID* ppvObject	[out] Interface* to hold the result
+ */
+static HRESULT WINAPI IShellFolder_fnQueryInterface (IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+	TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
+
+    return IUnknown_QueryInterface (This->pUnkOuter, riid, ppvObj);
+}
+
+/**************************************************************************
+*  IShellFolder_AddRef
+*/
+
+static ULONG WINAPI IShellFolder_fnAddRef (IShellFolder2 * iface)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return IUnknown_AddRef (This->pUnkOuter);
+}
+
+/**************************************************************************
+ *  IShellFolder_fnRelease
+ */
+static ULONG WINAPI IShellFolder_fnRelease (IShellFolder2 * iface)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return IUnknown_Release (This->pUnkOuter);
+}
+
+/**************************************************************************
+*		IShellFolder_fnParseDisplayName
+* PARAMETERS
+*  HWND          hwndOwner,      //[in ] Parent window for any message's
+*  LPBC          pbc,            //[in ] reserved
+*  LPOLESTR      lpszDisplayName,//[in ] "Unicode" displayname.
+*  ULONG*        pchEaten,       //[out] (unicode) characters processed
+*  LPITEMIDLIST* ppidl,          //[out] complex pidl to item
+*  ULONG*        pdwAttributes   //[out] items attributes
+*
+* NOTES
+*  every folder tries to parse only its own (the leftmost) pidl and creates a
+*  subfolder to evaluate the remaining parts
+*  now we can parse into namespaces implemented by shell extensions
+*
+*  behaviour on win98:	lpszDisplayName=NULL -> chrash
+*			lpszDisplayName="" -> returns mycoputer-pidl
+*
+* FIXME:
+*    pdwAttributes: not set
+*    pchEaten: not set like in windows
+*/
+static HRESULT WINAPI
+IShellFolder_fnParseDisplayName (IShellFolder2 * iface,
+				 HWND hwndOwner,
+				 LPBC pbcReserved,
+				 LPOLESTR lpszDisplayName,
+				 DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    HRESULT hr = E_OUTOFMEMORY;
+    LPCWSTR szNext = NULL;
+    WCHAR szElement[MAX_PATH];
+    CHAR szTempA[MAX_PATH],
+      szPath[MAX_PATH];
+    LPITEMIDLIST pidlTemp = NULL;
+
+    TRACE ("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
+	   This, hwndOwner, pbcReserved, lpszDisplayName, debugstr_w (lpszDisplayName), pchEaten, ppidl, pdwAttributes);
+
+    if (!lpszDisplayName || !ppidl)
+	return E_INVALIDARG;
+
+    if (pchEaten)
+	*pchEaten = 0;		/* strange but like the original */
+
+    if (*lpszDisplayName) {
+	/* get the next element */
+	szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
+
+	/* build the full pathname to the element */
+	WideCharToMultiByte (CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL);
+	lstrcpyA (szPath, This->sPathTarget);
+	PathAddBackslashA (szPath);
+	lstrcatA (szPath, szTempA);
+
+	/* get the pidl */
+	pidlTemp = SHSimpleIDListFromPathA (szPath);
+
+	if (pidlTemp) {
+	    if (szNext && *szNext) {
+		/* try to analyse the next element */
+		hr = SHELL32_ParseNextElement (hwndOwner, iface, &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
+	    } else {
+		/* it's the last element */
+		if (pdwAttributes && *pdwAttributes) {
+		    SHELL32_GetItemAttributes (_IShellFolder_ (This), pidlTemp, pdwAttributes);
+		}
+		hr = S_OK;
+	    }
+	}
+    }
+
+    if (!hr)
+	*ppidl = pidlTemp;
+    else
+	*ppidl = NULL;
+
+    TRACE ("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl ? *ppidl : 0, hr);
+
+    return hr;
+}
+
+/**************************************************************************
+*		IShellFolder_fnEnumObjects
+* PARAMETERS
+*  HWND          hwndOwner,    //[in ] Parent Window
+*  DWORD         grfFlags,     //[in ] SHCONTF enumeration mask
+*  LPENUMIDLIST* ppenumIDList  //[out] IEnumIDList interface
+*/
+static HRESULT WINAPI
+IShellFolder_fnEnumObjects (IShellFolder2 * iface, HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    TRACE ("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList);
+
+    *ppEnumIDList = IEnumIDList_Constructor (This->sPathTarget, dwFlags, EIDL_FILE);
+
+    TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
+
+    return *ppEnumIDList ? S_OK : E_OUTOFMEMORY;
+}
+
+/**************************************************************************
+*		IShellFolder_fnBindToObject
+* PARAMETERS
+*  LPCITEMIDLIST pidl,       //[in ] relative pidl to open
+*  LPBC          pbc,        //[in ] reserved
+*  REFIID        riid,       //[in ] Initial Interface
+*  LPVOID*       ppvObject   //[out] Interface*
+*/
+static HRESULT WINAPI
+IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+
+    return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid, ppvOut);
+}
+
+/**************************************************************************
+*  IShellFolder_fnBindToStorage
+* PARAMETERS
+*  LPCITEMIDLIST pidl,       //[in ] complex pidl to store
+*  LPBC          pbc,        //[in ] reserved
+*  REFIID        riid,       //[in ] Initial storage interface
+*  LPVOID*       ppvObject   //[out] Interface* returned
+*/
+static HRESULT WINAPI
+IShellFolder_fnBindToStorage (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+
+    *ppvOut = NULL;
+    return E_NOTIMPL;
+}
+
+/**************************************************************************
+*  IShellFolder_fnCompareIDs
+*/
+
+static HRESULT WINAPI
+IShellFolder_fnCompareIDs (IShellFolder2 * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    int nReturn;
+
+    TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
+    nReturn = SHELL32_CompareIDs (_IShellFolder_ (This), lParam, pidl1, pidl2);
+    TRACE ("-- %i\n", nReturn);
+    return nReturn;
+}
+
+/**************************************************************************
+*	IShellFolder_fnCreateViewObject
+*/
+static HRESULT WINAPI
+IShellFolder_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    LPSHELLVIEW pShellView;
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE ("(%p)->(hwnd=0x%x,%s,%p)\n", This, hwndOwner, shdebugstr_guid (riid), ppvOut);
+
+    if (ppvOut) {
+	*ppvOut = NULL;
+
+	if (IsEqualIID (riid, &IID_IDropTarget)) {
+	    hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, ppvOut);
+	} else if (IsEqualIID (riid, &IID_IContextMenu)) {
+	    FIXME ("IContextMenu not implemented\n");
+	    hr = E_NOTIMPL;
+	} else if (IsEqualIID (riid, &IID_IShellView)) {
+	    pShellView = IShellView_Constructor ((IShellFolder *) iface);
+	    if (pShellView) {
+		hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
+		IShellView_Release (pShellView);
+	    }
+	}
+    }
+    TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
+    return hr;
+}
+
+/**************************************************************************
+*  IShellFolder_fnGetAttributesOf
+*
+* PARAMETERS
+*  UINT            cidl,     //[in ] num elements in pidl array
+*  LPCITEMIDLIST*  apidl,    //[in ] simple pidl array
+*  ULONG*          rgfInOut) //[out] result array
+*
+*/
+static HRESULT WINAPI
+IShellFolder_fnGetAttributesOf (IShellFolder2 * iface, UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    HRESULT hr = S_OK;
+
+    TRACE ("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl, *rgfInOut);
+
+    if ((!cidl) || (!apidl) || (!rgfInOut))
+	return E_INVALIDARG;
+
+    while (cidl > 0 && *apidl) {
+	pdump (*apidl);
+	SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
+	apidl++;
+	cidl--;
+    }
+
+    TRACE ("-- result=0x%08lx\n", *rgfInOut);
+
+    return hr;
+}
+
+/**************************************************************************
+*  IShellFolder_fnGetUIObjectOf
+*
+* PARAMETERS
+*  HWND           hwndOwner, //[in ] Parent window for any output
+*  UINT           cidl,      //[in ] array size
+*  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
+*  REFIID         riid,      //[in ] Requested Interface
+*  UINT*          prgfInOut, //[   ] reserved
+*  LPVOID*        ppvObject) //[out] Resulting Interface
+*
+* NOTES
+*  This function gets asked to return "view objects" for one or more (multiple select)
+*  items:
+*  The viewobject typically is an COM object with one of the following interfaces:
+*  IExtractIcon,IDataObject,IContextMenu
+*  In order to support icon positions in the default Listview your DataObject
+*  must implement the SetData method (in addition to GetData :) - the shell passes
+*  a barely documented "Icon positions" structure to SetData when the drag starts,
+*  and GetData's it if the drop is in another explorer window that needs the positions.
+*/
+static HRESULT WINAPI
+IShellFolder_fnGetUIObjectOf (IShellFolder2 * iface,
+			      HWND hwndOwner,
+			      UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    LPITEMIDLIST pidl;
+    IUnknown *pObj = NULL;
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE ("(%p)->(0x%04x,%u,apidl=%p,%s,%p,%p)\n",
+	   This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
+
+    if (ppvOut) {
+	*ppvOut = NULL;
+
+	if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
+	    pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
+	    pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
+	    pidl = ILCombine (This->pidlRoot, apidl[0]);
+	    pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
+	    SHFree (pidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1)) {
+	    hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, (LPVOID *) & pObj);
+	} else {
+	    hr = E_NOINTERFACE;
+	}
+
+	if (!pObj)
+	    hr = E_OUTOFMEMORY;
+
+	*ppvOut = pObj;
+    }
+    TRACE ("(%p)->hr=0x%08lx\n", This, hr);
+    return hr;
+}
+
+/**************************************************************************
+*  IShellFolder_fnGetDisplayNameOf
+*  Retrieves the display name for the specified file object or subfolder
+*
+* PARAMETERS
+*  LPCITEMIDLIST pidl,    //[in ] complex pidl to item
+*  DWORD         dwFlags, //[in ] SHGNO formatting flags
+*  LPSTRRET      lpName)  //[out] Returned display name
+*
+* FIXME
+*  if the name is in the pidl the ret value should be a STRRET_OFFSET
+*/
+
+static HRESULT WINAPI
+IShellFolder_fnGetDisplayNameOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+    CHAR szPath[MAX_PATH] = "";
+    int len = 0;
+    BOOL bSimplePidl;
+
+    TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
+    pdump (pidl);
+
+    if (!pidl || !strRet)
+	return E_INVALIDARG;
+
+    bSimplePidl = _ILIsPidlSimple (pidl);
+
+    /* take names of special folders only if its only this folder */
+    if (_ILIsSpecialFolder (pidl)) {
+	if (bSimplePidl) {
+	    _ILSimpleGetText (pidl, szPath, MAX_PATH);	/* append my own path */
+	} else {
+	    FIXME ("special pidl\n");
+	}
+    } else {
+	if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sPathTarget) {
+	    lstrcpyA (szPath, This->sPathTarget);	/* get path to root */
+	    PathAddBackslashA (szPath);
+	    len = lstrlenA (szPath);
+	}
+	_ILSimpleGetText (pidl, szPath + len, MAX_PATH - len);	/* append my own path */
+
+	/* MSDN also mentions SHGDN_FOREDITING, which isn't defined in wine */
+	if (!_ILIsFolder (pidl) && !(dwFlags & SHGDN_FORPARSING) &&
+	    ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) {
+	    HKEY hKey;
+	    DWORD dwData;
+	    DWORD dwDataSize = sizeof (DWORD);
+	    BOOL doHide = 0;	/* The default value is FALSE (win98 at least) */
+
+	    /* XXX should it do this only for known file types? -- that would make it even slower! */
+	    /* XXX That's what the prompt says!! */
+	    if (!RegCreateKeyExA (HKEY_CURRENT_USER,
+				  "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
+				  0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0)) {
+		if (!RegQueryValueExA (hKey, "HideFileExt", 0, 0, (LPBYTE) & dwData, &dwDataSize))
+		    doHide = dwData;
+		RegCloseKey (hKey);
+	    }
+	    if (doHide && szPath[0] != '.')
+		PathRemoveExtensionA (szPath);
+	}
+    }
+
+    if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) {	/* go deeper if needed */
+	PathAddBackslashA (szPath);
+	len = lstrlenA (szPath);
+
+	if (!SUCCEEDED
+	    (SHELL32_GetDisplayNameOfChild (iface, pidl, dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len)))
+	    return E_OUTOFMEMORY;
+    }
+    strRet->uType = STRRET_CSTR;
+    lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
+
+    TRACE ("-- (%p)->(%s)\n", This, szPath);
+    return S_OK;
+}
+
+/**************************************************************************
+*  IShellFolder_fnSetNameOf
+*  Changes the name of a file object or subfolder, possibly changing its item
+*  identifier in the process.
+*
+* PARAMETERS
+*  HWND          hwndOwner,  //[in ] Owner window for output
+*  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
+*  LPCOLESTR     lpszName,   //[in ] the items new display name
+*  DWORD         dwFlags,    //[in ] SHGNO formatting flags
+*  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
+*/
+static HRESULT WINAPI IShellFolder_fnSetNameOf (IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,	/*simple pidl */
+						LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+    char szSrc[MAX_PATH],
+      szDest[MAX_PATH];
+    int len;
+    BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl));
+
+    TRACE ("(%p)->(%u,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
+
+    /* build source path */
+    if (dwFlags & SHGDN_INFOLDER) {
+	strcpy (szSrc, This->sPathTarget);
+	PathAddBackslashA (szSrc);
+	len = strlen (szSrc);
+	_ILSimpleGetText (pidl, szSrc + len, MAX_PATH - len);
+    } else {
+	SHGetPathFromIDListA (pidl, szSrc);
+    }
+
+    /* build destination path */
+    strcpy (szDest, This->sPathTarget);
+    PathAddBackslashA (szDest);
+    len = strlen (szDest);
+    WideCharToMultiByte (CP_ACP, 0, lpName, -1, szDest + len, MAX_PATH - len, NULL, NULL);
+    szDest[MAX_PATH - 1] = 0;
+    TRACE ("src=%s dest=%s\n", szSrc, szDest);
+    if (MoveFileA (szSrc, szDest)) {
+	if (pPidlOut)
+	    *pPidlOut = SHSimpleIDListFromPathA (szDest);
+	SHChangeNotifyA (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
+	return S_OK;
+    }
+    return E_FAIL;
+}
+
+static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID (IShellFolder2 * iface, GUID * pguid)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+	FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+static HRESULT WINAPI IShellFolder_fnEnumSearches (IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+	FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+static HRESULT WINAPI
+IShellFolder_fnGetDefaultColumn (IShellFolder2 * iface, DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+	TRACE ("(%p)\n", This);
+
+    if (pSort)
+	*pSort = 0;
+    if (pDisplay)
+	*pDisplay = 0;
+
+    return S_OK;
+}
+static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState (IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+
+	TRACE ("(%p)\n", This);
+
+    if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS)
+	return E_INVALIDARG;
+
+    *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
+
+    return S_OK;
+}
+static HRESULT WINAPI
+IShellFolder_fnGetDetailsEx (IShellFolder2 * iface, LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+	FIXME ("(%p)\n", This);
+
+    return E_NOTIMPL;
+}
+static HRESULT WINAPI
+IShellFolder_fnGetDetailsOf (IShellFolder2 * iface, LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+    HRESULT hr = E_FAIL;
+
+    TRACE ("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd);
+
+    if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS)
+	return E_INVALIDARG;
+
+    if (!pidl) {
+	/* the header titles */
+	psd->fmt = GenericSFHeader[iColumn].fmt;
+	psd->cxChar = GenericSFHeader[iColumn].cxChar;
+	psd->str.uType = STRRET_CSTR;
+	LoadStringA (shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
+	return S_OK;
+    } else {
+	/* the data from the pidl */
+	switch (iColumn) {
+	case 0:		/* name */
+	    hr = IShellFolder_GetDisplayNameOf (iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
+	    break;
+	case 1:		/* size */
+	    _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
+	    break;
+	case 2:		/* type */
+	    _ILGetFileType (pidl, psd->str.u.cStr, MAX_PATH);
+	    break;
+	case 3:		/* date */
+	    _ILGetFileDate (pidl, psd->str.u.cStr, MAX_PATH);
+	    break;
+	case 4:		/* attributes */
+	    _ILGetFileAttributes (pidl, psd->str.u.cStr, MAX_PATH);
+	    break;
+	}
+	hr = S_OK;
+	psd->str.uType = STRRET_CSTR;
+    }
+
+    return hr;
+}
+static HRESULT WINAPI IShellFolder_fnMapNameToSCID (IShellFolder2 * iface, LPCWSTR pwszName, SHCOLUMNID * pscid)
+{
+    _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
+    FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+
+static ICOM_VTABLE (IShellFolder2) sfvt =
+{
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IShellFolder_fnQueryInterface,
+	IShellFolder_fnAddRef,
+	IShellFolder_fnRelease,
+	IShellFolder_fnParseDisplayName,
+	IShellFolder_fnEnumObjects,
+	IShellFolder_fnBindToObject,
+	IShellFolder_fnBindToStorage,
+	IShellFolder_fnCompareIDs,
+	IShellFolder_fnCreateViewObject,
+	IShellFolder_fnGetAttributesOf,
+	IShellFolder_fnGetUIObjectOf,
+	IShellFolder_fnGetDisplayNameOf,
+	IShellFolder_fnSetNameOf,
+	/* ShellFolder2 */
+        IShellFolder_fnGetDefaultSearchGUID,
+	IShellFolder_fnEnumSearches,
+	IShellFolder_fnGetDefaultColumn,
+	IShellFolder_fnGetDefaultColumnState,
+	IShellFolder_fnGetDetailsEx,
+	IShellFolder_fnGetDetailsOf,
+	IShellFolder_fnMapNameToSCID
+};
+
+/****************************************************************************
+ * ISFHelper for IShellFolder implementation
+ */
+
+static HRESULT WINAPI ISFHelper_fnQueryInterface (ISFHelper * iface, REFIID riid, LPVOID * ppvObj)
+{
+    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return IUnknown_QueryInterface (This->pUnkOuter, riid, ppvObj);
+}
+
+static ULONG WINAPI ISFHelper_fnAddRef (ISFHelper * iface)
+{
+    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return IUnknown_AddRef (This->pUnkOuter);
+}
+
+static ULONG WINAPI ISFHelper_fnRelease (ISFHelper * iface)
+{
+    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    return IUnknown_Release (This->pUnkOuter);
+}
+
+/****************************************************************************
+ * ISFHelper_fnAddFolder
+ *
+ * creates a unique folder name
+ */
+
+static HRESULT WINAPI ISFHelper_fnGetUniqueName (ISFHelper * iface, LPSTR lpName, UINT uLen)
+{
+    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
+    IEnumIDList *penum;
+    HRESULT hr;
+    char szText[MAX_PATH];
+    char *szNewFolder = "New Folder";
+
+    TRACE ("(%p)(%s %u)\n", This, lpName, uLen);
+
+    if (uLen < strlen (szNewFolder) + 4)
+	return E_POINTER;
+
+    strcpy (lpName, szNewFolder);
+
+    hr = IShellFolder_fnEnumObjects (_IShellFolder2_ (This), 0,
+				     SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
+    if (penum) {
+	LPITEMIDLIST pidl;
+	DWORD dwFetched;
+	int i = 1;
+
+      next:IEnumIDList_Reset (penum);
+	while (S_OK == IEnumIDList_Next (penum, 1, &pidl, &dwFetched) && dwFetched) {
+	    _ILSimpleGetText (pidl, szText, MAX_PATH);
+	    if (0 == strcasecmp (szText, lpName)) {
+		sprintf (lpName, "%s %d", szNewFolder, i++);
+		if (i > 99) {
+		    hr = E_FAIL;
+		    break;
+		}
+		goto next;
+	    }
+	}
+
+	IEnumIDList_Release (penum);
+    }
+    return hr;
+}
+
+/****************************************************************************
+ * ISFHelper_fnAddFolder
+ *
+ * adds a new folder.
+ */
+
+static HRESULT WINAPI ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCSTR lpName, LPITEMIDLIST * ppidlOut)
+{
+    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
+    char lpstrNewDir[MAX_PATH];
+    DWORD bRes;
+    HRESULT hres = E_FAIL;
+
+    TRACE ("(%p)(%s %p)\n", This, lpName, ppidlOut);
+
+    strcpy (lpstrNewDir, This->sPathTarget);
+    PathAddBackslashA (lpstrNewDir);
+    strcat (lpstrNewDir, lpName);
+
+    bRes = CreateDirectoryA (lpstrNewDir, NULL);
+
+    if (bRes) {
+	LPITEMIDLIST pidl,
+	  pidlitem;
+
+	pidlitem = SHSimpleIDListFromPathA (lpstrNewDir);
+
+	pidl = ILCombine (This->pidlRoot, pidlitem);
+	SHChangeNotifyA (SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
+	SHFree (pidl);
+
+	if (ppidlOut)
+	    *ppidlOut = pidlitem;
+	hres = S_OK;
+    } else {
+	char lpstrText[128 + MAX_PATH];
+	char lpstrTempText[128];
+	char lpstrCaption[256];
+
+	/* Cannot Create folder because of permissions */
+	LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof (lpstrTempText));
+	LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof (lpstrCaption));
+	sprintf (lpstrText, lpstrTempText, lpstrNewDir);
+	MessageBoxA (hwnd, lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
+    }
+
+    return hres;
+}
+
+/****************************************************************************
+ * ISFHelper_fnDeleteItems
+ *
+ * deletes items in folder
+ */
+static HRESULT WINAPI ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
+{
+    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface)
+    int i;
+    char szPath[MAX_PATH];
+    BOOL bConfirm = TRUE;
+
+    TRACE ("(%p)(%u %p)\n", This, cidl, apidl);
+
+    /* deleting multiple items so give a slightly different warning */
+    if (cidl != 1) {
+	char tmp[8];
+
+	snprintf (tmp, sizeof (tmp), "%d", cidl);
+	if (!SHELL_WarnItemDelete (ASK_DELETE_MULTIPLE_ITEM, tmp))
+	    return E_FAIL;
+	bConfirm = FALSE;
+    }
+
+    for (i = 0; i < cidl; i++) {
+	strcpy (szPath, This->sPathTarget);
+	PathAddBackslashA (szPath);
+	_ILSimpleGetText (apidl[i], szPath + strlen (szPath), MAX_PATH);
+
+	if (_ILIsFolder (apidl[i])) {
+	    LPITEMIDLIST pidl;
+
+	    TRACE ("delete %s\n", szPath);
+	    if (!SHELL_DeleteDirectoryA (szPath, bConfirm)) {
+		TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
+		return E_FAIL;
+	    }
+	    pidl = ILCombine (This->pidlRoot, apidl[i]);
+	    SHChangeNotifyA (SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
+	    SHFree (pidl);
+	} else if (_ILIsValue (apidl[i])) {
+	    LPITEMIDLIST pidl;
+
+	    TRACE ("delete %s\n", szPath);
+	    if (!SHELL_DeleteFileA (szPath, bConfirm)) {
+		TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
+		return E_FAIL;
+	    }
+	    pidl = ILCombine (This->pidlRoot, apidl[i]);
+	    SHChangeNotifyA (SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
+	    SHFree (pidl);
+	}
+
+    }
+    return S_OK;
+}
+
+/****************************************************************************
+ * ISFHelper_fnCopyItems
+ *
+ * copies items to this folder
+ */
+static HRESULT WINAPI
+ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl)
+{
+    int i;
+    IPersistFolder2 *ppf2 = NULL;
+    char szSrcPath[MAX_PATH],
+      szDstPath[MAX_PATH];
+
+    _ICOM_THIS_From_ISFHelper (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
+
+    IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2, (LPVOID *) & ppf2);
+    if (ppf2) {
+	LPITEMIDLIST pidl;
+
+	if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
+	    for (i = 0; i < cidl; i++) {
+		SHGetPathFromIDListA (pidl, szSrcPath);
+		PathAddBackslashA (szSrcPath);
+		_ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath), MAX_PATH);
+
+		strcpy (szDstPath, This->sPathTarget);
+		PathAddBackslashA (szDstPath);
+		_ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath), MAX_PATH);
+		MESSAGE ("would copy %s to %s\n", szSrcPath, szDstPath);
+	    }
+	    SHFree (pidl);
+	}
+	IPersistFolder2_Release (ppf2);
+    }
+    return S_OK;
+}
+
+static ICOM_VTABLE (ISFHelper) shvt =
+{
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	ISFHelper_fnQueryInterface,
+	ISFHelper_fnAddRef,
+	ISFHelper_fnRelease,
+	ISFHelper_fnGetUniqueName,
+	ISFHelper_fnAddFolder,
+	ISFHelper_fnDeleteItems,
+        ISFHelper_fnCopyItems
+};
+
+/************************************************************************
+ *	IFSFldr_PersistFolder3_QueryInterface
+ *
+ */
+static HRESULT WINAPI IFSFldr_PersistFolder3_QueryInterface (IPersistFolder3 * iface, REFIID iid, LPVOID * ppvObj)
+{
+    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    return IUnknown_QueryInterface (This->pUnkOuter, iid, ppvObj);
+}
+
+/************************************************************************
+ *	IFSFldr_PersistFolder3_AddRef
+ *
+ */
+static ULONG WINAPI IFSFldr_PersistFolder3_AddRef (IPersistFolder3 * iface)
+{
+    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return IUnknown_AddRef (This->pUnkOuter);
+}
+
+/************************************************************************
+ *	IFSFldr_PersistFolder3_Release
+ *
+ */
+static ULONG WINAPI IFSFldr_PersistFolder3_Release (IPersistFolder3 * iface)
+{
+    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return IUnknown_Release (This->pUnkOuter);
+}
+
+/************************************************************************
+ *	IFSFldr_PersistFolder3_GetClassID
+ */
+static HRESULT WINAPI IFSFldr_PersistFolder3_GetClassID (IPersistFolder3 * iface, CLSID * lpClassId)
+{
+    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    if (!lpClassId)
+	return E_POINTER;
+    *lpClassId = *This->pclsid;
+
+    return S_OK;
+}
+
+/************************************************************************
+ *	IFSFldr_PersistFolder3_Initialize
+ *
+ * NOTES
+ *  sPathTarget is not set. Don't know how to handle in a non rooted environment.
+ */
+static HRESULT WINAPI IFSFldr_PersistFolder3_Initialize (IPersistFolder3 * iface, LPCITEMIDLIST pidl)
+{
+    char sTemp[MAX_PATH];
+
+    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(%p)\n", This, pidl);
+
+    if (This->pidlRoot)
+	SHFree (This->pidlRoot);	/* free the old pidl */
+    This->pidlRoot = ILClone (pidl);	/* set my pidl */
+
+    if (This->sPathTarget)
+	SHFree (This->sPathTarget);
+
+    /* set my path */
+    if (SHGetPathFromIDListA (pidl, sTemp)) {
+	This->sPathTarget = SHAlloc (strlen (sTemp) + 1);
+	strcpy (This->sPathTarget, sTemp);
+    }
+
+    TRACE ("--(%p)->(%s)\n", This, This->sPathTarget);
+    return S_OK;
+}
+
+/**************************************************************************
+ *	IFSFldr_PersistFolder3_GetCurFolder
+ */
+static HRESULT WINAPI IFSFldr_PersistFolder3_fnGetCurFolder (IPersistFolder3 * iface, LPITEMIDLIST * pidl)
+{
+    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(%p)\n", This, pidl);
+
+    if (!pidl) return E_POINTER;
+    *pidl = ILClone (This->pidlRoot);
+    return S_OK;
+}
+
+/**************************************************************************
+ *	IFSFldr_PersistFolder3_InitializeEx
+ *
+ * FIXME: errorhandling
+ */
+static HRESULT WINAPI
+IFSFldr_PersistFolder3_InitializeEx (IPersistFolder3 * iface,
+				     IBindCtx * pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO * ppfti)
+{
+    char sTemp[MAX_PATH];
+
+    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(%p,%p,%p)\n", This, pbc, pidlRoot, ppfti);
+    if (ppfti)
+	TRACE ("--%p %s %s 0x%08lx 0x%08x\n",
+	       ppfti->pidlTargetFolder, debugstr_w (ppfti->szTargetParsingName),
+	       debugstr_w (ppfti->szNetworkProvider), ppfti->dwAttributes, ppfti->csidl);
+
+    pdump (pidlRoot);
+    if (ppfti && ppfti->pidlTargetFolder)
+	pdump (ppfti->pidlTargetFolder);
+
+    if (This->pidlRoot)
+	__SHFreeAndNil (&This->pidlRoot);	/* free the old */
+    if (This->sPathTarget)
+	__SHFreeAndNil (&This->sPathTarget);
+
+    /*
+     * Root path and pidl
+     */
+    This->pidlRoot = ILClone (pidlRoot);
+
+    /*
+     *  the target folder is spezified in csidl OR pidlTargetFolder OR szTargetParsingName
+     */
+    if (ppfti) {
+	if (ppfti->csidl != -1) {
+	    if (SHGetSpecialFolderPathA (0, sTemp, ppfti->csidl, ppfti->csidl & CSIDL_FLAG_CREATE)) {
+		__SHCloneStrA (&This->sPathTarget, sTemp);
+	    }
+	} else if (ppfti->szTargetParsingName[0]) {
+	    __SHCloneStrWtoA (&This->sPathTarget, ppfti->szTargetParsingName);
+	} else if (ppfti->pidlTargetFolder) {
+	    if (SHGetPathFromIDListA (ppfti->pidlTargetFolder, sTemp)) {
+		__SHCloneStrA (&This->sPathTarget, sTemp);
+	    }
+	}
+    }
+
+    TRACE ("--(%p)->(target=%s)\n", This, debugstr_a (This->sPathTarget));
+    pdump (This->pidlRoot);
+    return (This->sPathTarget) ? S_OK : E_FAIL;
+}
+
+static HRESULT WINAPI
+IFSFldr_PersistFolder3_GetFolderTargetInfo (IPersistFolder3 * iface, PERSIST_FOLDER_TARGET_INFO * ppfti)
+{
+    _ICOM_THIS_From_IPersistFolder3 (IGenericSFImpl, iface);
+    FIXME ("(%p)->(%p)\n", This, ppfti);
+    ZeroMemory (ppfti, sizeof (ppfti));
+    return E_NOTIMPL;
+}
+
+static ICOM_VTABLE (IPersistFolder3) vt_FSFldr_PersistFolder3 =
+{
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IFSFldr_PersistFolder3_QueryInterface,
+	IFSFldr_PersistFolder3_AddRef,
+	IFSFldr_PersistFolder3_Release,
+	IFSFldr_PersistFolder3_GetClassID,
+	IFSFldr_PersistFolder3_Initialize,
+	IFSFldr_PersistFolder3_fnGetCurFolder,
+	IFSFldr_PersistFolder3_InitializeEx,
+	IFSFldr_PersistFolder3_GetFolderTargetInfo
+};
+
+/****************************************************************************
+ * ISFDropTarget implementation
+ */
+static BOOL ISFDropTarget_QueryDrop (IDropTarget * iface, DWORD dwKeyState, LPDWORD pdwEffect)
+{
+    DWORD dwEffect = *pdwEffect;
+
+    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
+
+    *pdwEffect = DROPEFFECT_NONE;
+
+    if (This->fAcceptFmt) {	/* Does our interpretation of the keystate ... */
+	*pdwEffect = KeyStateToDropEffect (dwKeyState);
+
+	/* ... matches the desired effect ? */
+	if (dwEffect & *pdwEffect) {
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+static HRESULT WINAPI ISFDropTarget_QueryInterface (IDropTarget * iface, REFIID riid, LPVOID * ppvObj)
+{
+    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    return IUnknown_QueryInterface (This->pUnkOuter, riid, ppvObj);
+}
+
+static ULONG WINAPI ISFDropTarget_AddRef (IDropTarget * iface)
+{
+    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    return IUnknown_AddRef (This->pUnkOuter);
+}
+
+static ULONG WINAPI ISFDropTarget_Release (IDropTarget * iface)
+{
+    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    return IUnknown_Release (This->pUnkOuter);
+}
+
+static HRESULT WINAPI
+ISFDropTarget_DragEnter (IDropTarget * iface, IDataObject * pDataObject, DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
+{
+    FORMATETC fmt;
+
+    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(DataObject=%p)\n", This, pDataObject);
+
+    InitFormatEtc (fmt, This->cfShellIDList, TYMED_HGLOBAL);
+
+    This->fAcceptFmt = (S_OK == IDataObject_QueryGetData (pDataObject, &fmt)) ? TRUE : FALSE;
+
+    ISFDropTarget_QueryDrop (iface, dwKeyState, pdwEffect);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI ISFDropTarget_DragOver (IDropTarget * iface, DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
+{
+    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    if (!pdwEffect)
+	return E_INVALIDARG;
+
+    ISFDropTarget_QueryDrop (iface, dwKeyState, pdwEffect);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI ISFDropTarget_DragLeave (IDropTarget * iface)
+{
+    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    This->fAcceptFmt = FALSE;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI
+ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject, DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
+{
+    _ICOM_THIS_From_IDropTarget (IGenericSFImpl, iface);
+
+    FIXME ("(%p) object dropped\n", This);
+
+    return E_NOTIMPL;
+}
+
+static struct ICOM_VTABLE (IDropTarget) dtvt = {
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	ISFDropTarget_QueryInterface,
+	ISFDropTarget_AddRef,
+	ISFDropTarget_Release,
+	ISFDropTarget_DragEnter,
+	ISFDropTarget_DragOver,
+	ISFDropTarget_DragLeave,
+	ISFDropTarget_Drop
+};
--- /dev/null	Sun Jul 14 16:54:37 2002
+++ wine/dlls/shell32/shfldr_mycomp.c	Thu Jul 18 17:59:49 2002
@@ -0,0 +1,711 @@
+
+/*
+ *	Virtual Workplace folder
+ *
+ *	Copyright 1997			Marcus Meissner
+ *	Copyright 1998, 1999, 2002	Juergen Schmied
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "winerror.h"
+#include "winbase.h"
+#include "winreg.h"
+
+#include "oleidl.h"
+#include "shlguid.h"
+
+#include "pidl.h"
+#include "wine/obj_base.h"
+#include "wine/obj_dragdrop.h"
+#include "wine/obj_shellfolder.h"
+#include "undocshell.h"
+#include "shell32_main.h"
+#include "shresdef.h"
+#include "shlwapi.h"
+#include "shellfolder.h"
+#include "wine/debug.h"
+#include "debughlp.h"
+#include "shfldr.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL (shell);
+
+/***********************************************************************
+*   IShellFolder implementation
+*/
+
+typedef struct {
+    ICOM_VFIELD (IShellFolder2);
+    DWORD ref;
+      ICOM_VTABLE (IPersistFolder2) * lpVtblPersistFolder2;
+
+    /* both paths are parsible from the desktop */
+    LPITEMIDLIST pidlRoot;	/* absolute pidl */
+    int dwAttributes;		/* attributes returned by GetAttributesOf FIXME: use it */
+} IGenericSFImpl;
+
+static struct ICOM_VTABLE (IShellFolder2) vt_ShellFolder2;
+static struct ICOM_VTABLE (IPersistFolder2) vt_PersistFolder2;
+
+HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
+
+#define _IPersistFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpVtblPersistFolder2)))
+#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset);
+
+/*
+  converts This to a interface pointer
+*/
+#define _IUnknown_(This)	(IUnknown*)&(This->lpVtbl)
+#define _IShellFolder_(This)	(IShellFolder*)&(This->lpVtbl)
+#define _IShellFolder2_(This)	(IShellFolder2*)&(This->lpVtbl)
+
+#define _IPersist_(This)	(IPersist*)&(This->lpVtblPersistFolder2)
+#define _IPersistFolder_(This)	(IPersistFolder*)&(This->lpVtblPersistFolder2)
+#define _IPersistFolder2_(This)	(IPersistFolder2*)&(This->lpVtblPersistFolder2)
+
+/***********************************************************************
+*   IShellFolder [MyComputer] implementation
+*/
+
+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
+*/
+HRESULT WINAPI ISF_MyComputer_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
+{
+    IGenericSFImpl *sf;
+
+    TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
+
+    if (!ppv)
+	return E_POINTER;
+    if (pUnkOuter)
+	return CLASS_E_NOAGGREGATION;
+
+    sf = (IGenericSFImpl *) LocalAlloc (GMEM_ZEROINIT, sizeof (IGenericSFImpl));
+    if (!sf)
+	return E_OUTOFMEMORY;
+
+    sf->ref = 0;
+    ICOM_VTBL (sf) = &vt_ShellFolder2;
+    sf->lpVtblPersistFolder2 = &vt_PersistFolder2;
+    sf->pidlRoot = _ILCreateMyComputer ();	/* my qualified pidl */
+
+    if (!SUCCEEDED (IUnknown_QueryInterface (_IUnknown_ (sf), riid, ppv))) {
+	IUnknown_Release (_IUnknown_ (sf));
+	return E_NOINTERFACE;
+    }
+
+    TRACE ("--(%p)\n", sf);
+    return S_OK;
+}
+
+/**************************************************************************
+ *	ISF_MyComputer_fnQueryInterface
+ *
+ * NOTES supports not IPersist/IPersistFolder
+ */
+static HRESULT WINAPI ISF_MyComputer_fnQueryInterface (IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
+
+    *ppvObj = NULL;
+
+    if (IsEqualIID (riid, &IID_IUnknown) ||
+	IsEqualIID (riid, &IID_IShellFolder) || IsEqualIID (riid, &IID_IShellFolder2)) {
+	*ppvObj = This;
+    } else if (IsEqualIID (riid, &IID_IPersist) ||
+	       IsEqualIID (riid, &IID_IPersistFolder) || IsEqualIID (riid, &IID_IPersistFolder2)) {
+	*ppvObj = _IPersistFolder2_ (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;
+}
+
+static ULONG WINAPI ISF_MyComputer_fnAddRef (IShellFolder2 * iface)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return ++(This->ref);
+}
+
+static ULONG WINAPI ISF_MyComputer_fnRelease (IShellFolder2 * iface)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    if (!--(This->ref)) {
+	TRACE ("-- destroying IShellFolder(%p)\n", This);
+	if (This->pidlRoot)
+	    SHFree (This->pidlRoot);
+	LocalFree ((HLOCAL) This);
+    }
+    return This->ref;
+}
+
+/**************************************************************************
+*	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 (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);
+	WideCharToMultiByte (CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL);
+	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 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList);
+
+    *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
+
+    TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
+
+    return (*ppEnumIDList) ? S_OK : E_OUTOFMEMORY;
+}
+
+/**************************************************************************
+*		ISF_MyComputer_fnBindToObject
+*/
+static HRESULT WINAPI
+ISF_MyComputer_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl,
+			       LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+
+    return SHELL32_BindToChild (This->pidlRoot, NULL, pidl, riid, ppvOut);
+}
+
+/**************************************************************************
+*	ISF_MyComputer_fnBindToStorage
+*/
+static HRESULT WINAPI
+ISF_MyComputer_fnBindToStorage (IShellFolder2 * iface,
+				LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+
+    *ppvOut = NULL;
+    return E_NOTIMPL;
+}
+
+/**************************************************************************
+* 	ISF_MyComputer_fnCompareIDs
+*/
+
+static HRESULT WINAPI
+ISF_MyComputer_fnCompareIDs (IShellFolder2 * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    int nReturn;
+
+    TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
+    nReturn = SHELL32_CompareIDs (_IShellFolder_ (This), lParam, pidl1, pidl2);
+    TRACE ("-- %i\n", nReturn);
+    return nReturn;
+}
+
+/**************************************************************************
+*	ISF_MyComputer_fnCreateViewObject
+*/
+static HRESULT WINAPI
+ISF_MyComputer_fnCreateViewObject (IShellFolder2 * iface, HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    LPSHELLVIEW pShellView;
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE ("(%p)->(hwnd=0x%x,%s,%p)\n", This, hwndOwner, shdebugstr_guid (riid), ppvOut);
+
+    if (ppvOut) {
+	*ppvOut = NULL;
+
+	if (IsEqualIID (riid, &IID_IDropTarget)) {
+	    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 (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_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
+*
+*/
+static HRESULT WINAPI
+ISF_MyComputer_fnGetUIObjectOf (IShellFolder2 * iface,
+				HWND hwndOwner,
+				UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+
+    LPITEMIDLIST pidl;
+    IUnknown *pObj = NULL;
+    HRESULT hr = E_INVALIDARG;
+
+    TRACE ("(%p)->(0x%04x,%u,apidl=%p,%s,%p,%p)\n",
+	   This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
+
+    if (ppvOut) {
+	*ppvOut = NULL;
+
+	if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
+	    pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface, This->pidlRoot, apidl, cidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
+	    pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
+	    pidl = ILCombine (This->pidlRoot, apidl[0]);
+	    pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
+	    SHFree (pidl);
+	    hr = S_OK;
+	} else if (IsEqualIID (riid, &IID_IDropTarget) && (cidl >= 1)) {
+	    hr = IShellFolder_QueryInterface (iface, &IID_IDropTarget, (LPVOID *) & pObj);
+	} else {
+	    hr = E_NOINTERFACE;
+	}
+
+	if (!pObj)
+	    hr = E_OUTOFMEMORY;
+
+	*ppvOut = pObj;
+    }
+    TRACE ("(%p)->hr=0x%08lx\n", This, hr);
+    return hr;
+}
+
+/**************************************************************************
+*	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 (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 {
+	    FIXME ("special folder\n");
+	}
+    } 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, sizeof (szDrive) - 6, &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_INFOLDER, szPath + len, MAX_PATH - len)))
+	    return E_OUTOFMEMORY;
+    }
+    strRet->uType = STRRET_CSTR;
+    lstrcpynA (strRet->u.cStr, szPath, MAX_PATH);
+
+    TRACE ("-- (%p)->(%s)\n", This, szPath);
+    return S_OK;
+}
+
+/**************************************************************************
+*  ISF_MyComputer_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 ISF_MyComputer_fnSetNameOf (IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl,	/*simple pidl */
+						  LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+    FIXME ("(%p)->(%u,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
+    return E_FAIL;
+}
+
+static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID (IShellFolder2 * iface, GUID * pguid)
+{
+    ICOM_THIS (IGenericSFImpl, iface);
+    FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+static HRESULT WINAPI ISF_MyComputer_fnEnumSearches (IShellFolder2 * iface, IEnumExtraSearch ** ppenum)
+{
+    ICOM_THIS (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 (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 (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 (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 (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_CSTR;
+	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_CSTR;
+	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 (IGenericSFImpl, iface);
+    FIXME ("(%p)\n", This);
+    return E_NOTIMPL;
+}
+
+static ICOM_VTABLE (IShellFolder2) vt_ShellFolder2 =
+{
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	ISF_MyComputer_fnQueryInterface,
+	ISF_MyComputer_fnAddRef,
+	ISF_MyComputer_fnRelease,
+	ISF_MyComputer_fnParseDisplayName,
+	ISF_MyComputer_fnEnumObjects,
+	ISF_MyComputer_fnBindToObject,
+	ISF_MyComputer_fnBindToStorage,
+	ISF_MyComputer_fnCompareIDs,
+	ISF_MyComputer_fnCreateViewObject,
+	ISF_MyComputer_fnGetAttributesOf,
+	ISF_MyComputer_fnGetUIObjectOf,
+	ISF_MyComputer_fnGetDisplayNameOf,
+	ISF_MyComputer_fnSetNameOf,
+	/* ShellFolder2 */
+        ISF_MyComputer_fnGetDefaultSearchGUID,
+	ISF_MyComputer_fnEnumSearches,
+	ISF_MyComputer_fnGetDefaultColumn,
+	ISF_MyComputer_fnGetDefaultColumnState,
+	ISF_MyComputer_fnGetDetailsEx,
+	ISF_MyComputer_fnGetDetailsOf,
+	ISF_MyComputer_fnMapNameToSCID
+};
+
+/************************************************************************
+ *	IMCFldr_PersistFolder2_QueryInterface
+ */
+static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface (IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj)
+{
+    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    return IUnknown_QueryInterface (_IUnknown_ (This), iid, ppvObj);
+}
+
+/************************************************************************
+ *	IMCFldr_PersistFolder2_AddRef
+ */
+static ULONG WINAPI IMCFldr_PersistFolder2_AddRef (IPersistFolder2 * iface)
+{
+    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return IUnknown_AddRef (_IUnknown_ (This));
+}
+
+/************************************************************************
+ *	ISFPersistFolder_Release
+ */
+static ULONG WINAPI IMCFldr_PersistFolder2_Release (IPersistFolder2 * iface)
+{
+    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return IUnknown_Release (_IUnknown_ (This));
+}
+
+/************************************************************************
+ *	IMCFldr_PersistFolder2_GetClassID
+ */
+static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID (IPersistFolder2 * iface, CLSID * lpClassId)
+{
+    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)\n", This);
+
+    if (!lpClassId)
+	return E_POINTER;
+    *lpClassId = CLSID_MyComputer;
+
+    return S_OK;
+}
+
+/************************************************************************
+ *	IMCFldr_PersistFolder2_Initialize
+ *
+ * NOTES: it makes no sense to change the pidl
+ */
+static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize (IPersistFolder2 * iface, LPCITEMIDLIST pidl)
+{
+    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+    TRACE ("(%p)->(%p)\n", This, pidl);
+    return E_NOTIMPL;
+}
+
+/**************************************************************************
+ *	IPersistFolder2_fnGetCurFolder
+ */
+static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder (IPersistFolder2 * iface, LPITEMIDLIST * pidl)
+{
+    _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
+
+    TRACE ("(%p)->(%p)\n", This, pidl);
+
+    if (!pidl)
+	return E_POINTER;
+    *pidl = ILClone (This->pidlRoot);
+    return S_OK;
+}
+
+static ICOM_VTABLE (IPersistFolder2) vt_PersistFolder2 =
+{
+ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IMCFldr_PersistFolder2_QueryInterface,
+	IMCFldr_PersistFolder2_AddRef,
+	IMCFldr_PersistFolder2_Release,
+	IMCFldr_PersistFolder2_GetClassID,
+	IMCFldr_PersistFolder2_Initialize,
+	IMCFldr_PersistFolder2_GetCurFolder
+};
--- /dev/null	Sun Jul 14 16:54:37 2002
+++ wine/dlls/shell32/debughlp.h	Tue Jun 25 18:02:03 2002
@@ -0,0 +1,6 @@
+#include "winbase.h"
+#include "shlobj.h"
+
+void pdump (LPCITEMIDLIST pidl);
+BOOL pcheck (LPCITEMIDLIST pidl);
+const char * shdebugstr_guid( const struct _GUID *id );

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux