shell32 fixes

Jürgen Schmied juergenschmied at lycos.de
Sat Jun 29 04:07:27 CDT 2002


- changed STRRET definition
- small changes for seperation of shell32 from ole32
- debughelper for printing interface names (shell internal)
- changed shell memory allocation to use IMalloc of ole32 when this library is already 
loaded
- fallback IMalloc internally in shell
- unified constructor syntax for several objects  created by DllGetClassObject
- rewrote instance creation for com objects
- made the desktop folder parsing paths like ::{CLSID}
- Implemented IPersistFolder3 partially

---
juergen.schmied at debitel.net



-------------- next part --------------
Index: wine/dlls/commdlg/filedlg95.c
===================================================================
RCS file: /home/wine/wine/dlls/commdlg/filedlg95.c,v
retrieving revision 1.75
diff -d -u -r1.75 filedlg95.c
--- wine/dlls/commdlg/filedlg95.c	25 Jun 2002 02:55:53 -0000	1.75
+++ wine/dlls/commdlg/filedlg95.c	27 Jun 2002 09:50:38 -0000
@@ -2680,11 +2680,11 @@
 	    COMDLG32_SHFree(src->u.pOleStr);
 	    break;
 
-	  case STRRET_CSTRA:
+	  case STRRET_CSTR:
 	    lstrcpynA((LPSTR)dest, src->u.cStr, len);
 	    break;
 
-	  case STRRET_OFFSETA:
+	  case STRRET_OFFSET:
 	    lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
 	    break;
 
@@ -2946,9 +2946,9 @@
  * returns the pidl of the file name relative to folder
  * NULL if an error occurred
  */
-LPITEMIDLIST GetPidlFromName(IShellFolder *lpsf,LPCSTR lpcstrFileName)
+LPITEMIDLIST GetPidlFromName(IShellFolder *lpsf, LPCSTR lpcstrFileName)
 {
-  LPITEMIDLIST pidl;
+  LPITEMIDLIST pidl = NULL;
   ULONG ulEaten;
   WCHAR lpwstrDirName[MAX_PATH];
 
@@ -2957,16 +2957,16 @@
   if(!lpcstrFileName) return NULL;
   if(!*lpcstrFileName) return NULL;
 
-  MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpcstrFileName,-1,(LPWSTR)lpwstrDirName,MAX_PATH);
-
   if(!lpsf)
   {
-    SHGetDesktopFolder(&lpsf);
-    pidl = GetPidlFromName(lpsf, lpcstrFileName);
-    IShellFolder_Release(lpsf);
+    if (SUCCEEDED(SHGetDesktopFolder(&lpsf))) {
+        pidl = GetPidlFromName(lpsf, lpcstrFileName);
+        IShellFolder_Release(lpsf);
+    }
   }
   else
   {
+    MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpcstrFileName,-1,(LPWSTR)lpwstrDirName,MAX_PATH);
     IShellFolder_ParseDisplayName(lpsf, 0, NULL, (LPWSTR)lpwstrDirName, &ulEaten, &pidl, NULL);
   }
   return pidl;
@@ -3035,4 +3035,6 @@
         HeapFree(GetProcessHeap(),0,mem);
     }
 }
+
+
 
Index: wine/dlls/commdlg/filedlgbrowser.c
===================================================================
RCS file: /home/wine/wine/dlls/commdlg/filedlgbrowser.c,v
retrieving revision 1.33
diff -d -u -r1.33 filedlgbrowser.c
--- wine/dlls/commdlg/filedlgbrowser.c	31 May 2002 23:25:45 -0000	1.33
+++ wine/dlls/commdlg/filedlgbrowser.c	27 Jun 2002 09:50:40 -0000
@@ -110,12 +110,12 @@
 	    COMDLG32_SHFree(src->u.pOleStr);
 	    break;
 
-	  case STRRET_CSTRA:
+	  case STRRET_CSTR:
             if (len && !MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, (LPWSTR)dest, len ))
                 ((LPWSTR)dest)[len-1] = 0;
 	    break;
 
-	  case STRRET_OFFSETA:
+	  case STRRET_OFFSET:
 	    if (pidl)
 	    {
                 if (len && !MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset,
@@ -211,7 +211,7 @@
 {
     ICOM_THIS(IShellBrowserImpl, iface);
 
-    TRACE("(%p)\n", This);
+    TRACE("(%p,%lu)\n", This, This->ref);
 
     return ++(This->ref);
 }
@@ -223,11 +223,12 @@
 {
     ICOM_THIS(IShellBrowserImpl, iface);
 
-    TRACE("(%p)\n", This);
+    TRACE("(%p,%lu)\n", This, This->ref);
 
     if (!--(This->ref))
     {
       HeapFree(GetProcessHeap(),0, This);
+      TRACE("-- destroyed\n");
       return 0;
     }
     return This->ref;
@@ -905,9 +906,8 @@
 *  IShellBrowserImpl_IServiceProvider_Release
 *
 * NOTES
-*  the w2k shellview asks for
-*   guidService = SID_STopLevelBrowser
-*   riid = IShellBrowser
+*  the w2k shellview asks for (guidService = SID_STopLevelBrowser,
+*  riid = IShellBrowser) to call SendControlMsg ().
 *
 * FIXME
 *  this is a hack!
@@ -943,3 +943,7 @@
         /* IServiceProvider */
         IShellBrowserImpl_IServiceProvider_QueryService
 };
+
+
+
+

Index: wine/dlls/shell32/clipboard.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/clipboard.c,v
retrieving revision 1.10
diff -d -u -r1.10 clipboard.c
--- wine/dlls/shell32/clipboard.c	31 May 2002 23:25:52 -0000	1.10
+++ wine/dlls/shell32/clipboard.c	27 Jun 2002 09:51:12 -0000
@@ -47,40 +47,23 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
-static int refClipCount = 0;
-static HINSTANCE hShellOle32 = 0;
-
-/**************************************************************************
- * InitShellOle
- *
- *
- */
-void InitShellOle(void)
-{
-}
-
-/**************************************************************************
- * FreeShellOle
- *
- * unload OLE32.DLL
- */
-void FreeShellOle(void)
-{
-	if (!--refClipCount)
-	{
-	  pOleUninitialize();
-	  FreeLibrary(hShellOle32);
-	}
-}
+HRESULT (WINAPI *pOleInitialize)(LPVOID reserved);
+void    (WINAPI *pOleUninitialize)(void);
+HRESULT (WINAPI *pRegisterDragDrop)(HWND hwnd, IDropTarget* pDropTarget);
+HRESULT (WINAPI *pRevokeDragDrop)(HWND hwnd);
+HRESULT (WINAPI *pDoDragDrop)(LPDATAOBJECT,LPDROPSOURCE,DWORD,DWORD*);
+void 	(WINAPI *pReleaseStgMedium)(STGMEDIUM* pmedium);
+HRESULT (WINAPI *pOleSetClipboard)(IDataObject* pDataObj);
+HRESULT (WINAPI *pOleGetClipboard)(IDataObject** ppDataObj);
 
 /**************************************************************************
- * LoadShellOle
+ * GetShellOle
  *
  * make sure OLE32.DLL is loaded
  */
 BOOL GetShellOle(void)
 {
-	if(!refClipCount)
+	if(!hShellOle32)
 	{
 	  hShellOle32 = LoadLibraryA("ole32.dll");
 	  if(hShellOle32)
@@ -95,7 +78,6 @@
 	    pOleGetClipboard=(void*)GetProcAddress(hShellOle32,"OleGetClipboard");
 
 	    pOleInitialize(NULL);
-	    refClipCount++;
 	  }
 	}
 	return TRUE;
@@ -275,3 +257,4 @@
 	}
 	return ret;
 }
+
Index: wine/dlls/shell32/debughlp.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/debughlp.c,v
retrieving revision 1.2
diff -d -u -r1.2 debughlp.c
--- wine/dlls/shell32/debughlp.c	31 May 2002 23:25:52 -0000	1.2
+++ wine/dlls/shell32/debughlp.c	27 Jun 2002 09:51:13 -0000
@@ -26,6 +26,8 @@
 #include "shlguid.h"
 #include "wine/debug.h"
 #include "debughlp.h"
+#include "docobj.h"
+#include "shell32_main.h"
 
 
 WINE_DEFAULT_DEBUG_CHANNEL(pidl);
@@ -274,3 +276,57 @@
 	}
 	return ret;
 }
+
+static char shdebugstr_buf[100];
+
+
+static struct {
+	REFIID	riid;
+	char 	*name;
+} InterfaceDesc[] = {
+	{&IID_IUnknown,			"IID_IUnknown"},
+	{&IID_IShellView,		"IID_IShellView"},
+	{&IID_IOleCommandTarget,	"IID_IOleCommandTarget"},
+	{&IID_IDropTarget,		"IID_IDropTarget"},
+	{&IID_IDropSource,		"IID_IDropSource"},
+	{&IID_IViewObject,		"IID_IViewObject"},
+	{&IID_IContextMenu,		"IID_IContextMenu"},
+	{&IID_IShellExtInit,		"IID_IShellExtInit"},
+	{&IID_IShellFolder,		"IID_IShellFolder"},
+	{&IID_IShellFolder2,		"IID_IShellFolder2"},
+	{&IID_IPersist,			"IID_IPersist"},
+	{&IID_IPersistFolder,		"IID_IPersistFolder"},
+	{&IID_IPersistFolder2,		"IID_IPersistFolder2"},
+	{&IID_IPersistFolder3,		"IID_IPersistFolder3"},
+	{&IID_IExtractIconA,		"IID_IExtractIconA"},
+	{&IID_IDataObject,		"IID_IDataObject"},
+	{&IID_IDataObject,		"IID_IDataObject"},
+	{NULL,NULL}};
+
+const char * shdebugstr_guid( const struct _GUID *id )
+{
+	int i;
+	char* name = NULL;
+	char clsidbuf[100];
+
+	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;
+	    }
+
+	    sprintf( shdebugstr_buf, "\n\t{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x} (%s)",
+                 id->Data1, id->Data2, id->Data3,
+                 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
+                 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7], name ? name : "unknown" );
+	}
+	return shdebugstr_buf;
+}
+
+
+
Index: wine/dlls/shell32/pidl.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/pidl.c,v
retrieving revision 1.71
diff -d -u -r1.71 pidl.c
--- wine/dlls/shell32/pidl.c	31 May 2002 23:25:52 -0000	1.71
+++ wine/dlls/shell32/pidl.c	27 Jun 2002 09:51:15 -0000
@@ -1162,7 +1162,11 @@
 
     if (!MultiByteToWideChar( CP_ACP, 0, szGUID, -1, buffer, sizeof(buffer)/sizeof(WCHAR) ))
         return NULL;
-    CLSIDFromString( buffer, &iid );
+
+    if (! SUCCEEDED (CLSIDFromString( buffer, &iid ))) {
+	ERR("%s is not a GUID\n", szGUID);
+	return NULL;
+    }
     return _ILCreate(PT_MYCOMP, &iid, sizeof(IID));
 }
 
@@ -1219,7 +1223,7 @@
 	    pData =_ILGetDataPointer(pidlOut);
 	    pData->type = type;
 	    memcpy(&(pData->u.mycomp.guid), pIn, uInSize);
-	    TRACE("- create GUID-pidl\n");
+	    TRACE("-- create GUID-pidl %s\n", debugstr_guid(&(pData->u.mycomp.guid)));
 	    break;
 
 	  case PT_DRIVE:
@@ -1227,7 +1231,7 @@
 	    pData->type = type;
 	    pszDest = _ILGetTextPointer(pidlOut);
 	    memcpy(pszDest, pIn, uInSize);
-	    TRACE("- create Drive: %s\n",debugstr_a(pszDest));
+	    TRACE("-- create Drive: %s\n",debugstr_a(pszDest));
 	    break;
 
 	  case PT_FOLDER:
@@ -1236,7 +1240,7 @@
 	    pData->type = type;
 	    pszDest =  _ILGetTextPointer(pidlOut);
 	    memcpy(pszDest, pIn, uInSize);
-	    TRACE("- create Value: %s\n",debugstr_a(pszDest));
+	    TRACE("-- create Value: %s\n",debugstr_a(pszDest));
 	    break;
 	}
 
@@ -1784,3 +1788,5 @@
 
 	return dst;
 }
+
+
Index: wine/dlls/shell32/shell32_main.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32_main.c,v
retrieving revision 1.94
diff -d -u -r1.94 shell32_main.c
--- wine/dlls/shell32/shell32_main.c	31 May 2002 23:25:52 -0000	1.94
+++ wine/dlls/shell32/shell32_main.c	27 Jun 2002 09:51:17 -0000
@@ -996,12 +996,6 @@
 	  case DLL_PROCESS_DETACH:
 	      shell32_hInstance = 0;
 
-	      if (pdesktopfolder)
-	      {
-	        IShellFolder_Release(pdesktopfolder);
-	        pdesktopfolder = NULL;
-	      }
-
 	      SIC_Destroy();
 	      FreeChangeNotifications();
 
@@ -1040,3 +1034,4 @@
 
     return S_FALSE;
 }
+
Index: wine/dlls/shell32/shell32_main.h
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32_main.h,v
retrieving revision 1.47
diff -d -u -r1.47 shell32_main.h
--- wine/dlls/shell32/shell32_main.h	31 May 2002 23:25:52 -0000	1.47
+++ wine/dlls/shell32/shell32_main.h	27 Jun 2002 09:51:17 -0000
@@ -65,14 +65,7 @@
 extern INT      (WINAPI *pEnumMRUListA) (HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize);
 #define pDPA_GetPtrCount(hdpa)  (*(INT*)(hdpa))
 
-/* ole2 */
-/*
-extern HRESULT (WINAPI *pOleInitialize)(LPVOID reserved);
-extern void (WINAPI *pOleUninitialize)(void);
-extern HRESULT (WINAPI *pDoDragDrop)(IDataObject* pDataObject, IDropSource * pDropSource, DWORD dwOKEffect, DWORD * pdwEffect);
-extern HRESULT (WINAPI *pRegisterDragDrop)(HWND hwnd, IDropTarget* pDropTarget);
-extern HRESULT (WINAPI *pRevokeDragDrop)(HWND hwnd);
-*/
+
 BOOL WINAPI Shell_GetImageList(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList);
 
 /* Iconcache */
@@ -101,9 +94,10 @@
 IContextMenu *	ISvItemCm_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, LPCITEMIDLIST *aPidls, UINT uItemCount);
 IContextMenu *	ISvBgCm_Constructor(LPSHELLFOLDER pSFParent);
 LPSHELLVIEW	IShellView_Constructor(LPSHELLFOLDER);
-LPSHELLLINK	IShellLink_Constructor(BOOL);
 
-IShellFolder * ISF_Desktop_Constructor(void);
+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);
 
 /* kind of enumidlist */
 #define EIDL_DESK	0
@@ -145,19 +139,20 @@
 /* Systray */
 BOOL SYSTRAY_Init(void);
 
-/* Clipboard */
-void InitShellOle(void);
-void FreeShellOle(void);
-BOOL GetShellOle(void);
+/* OLE32 */
+extern HINSTANCE hShellOle32;
 
-HRESULT (WINAPI *pOleInitialize)(LPVOID reserved);
-void    (WINAPI *pOleUninitialize)(void);
-HRESULT (WINAPI *pRegisterDragDrop)(HWND hwnd, IDropTarget* pDropTarget);
-HRESULT (WINAPI *pRevokeDragDrop)(HWND hwnd);
-HRESULT (WINAPI *pDoDragDrop)(LPDATAOBJECT,LPDROPSOURCE,DWORD,DWORD*);
-void 	(WINAPI *pReleaseStgMedium)(STGMEDIUM* pmedium);
-HRESULT (WINAPI *pOleSetClipboard)(IDataObject* pDataObj);
-HRESULT (WINAPI *pOleGetClipboard)(IDataObject** ppDataObj);
+extern HRESULT (WINAPI *pOleInitialize)(LPVOID reserved);
+extern void    (WINAPI *pOleUninitialize)(void);
+extern HRESULT (WINAPI *pRegisterDragDrop)(HWND hwnd, IDropTarget* pDropTarget);
+extern HRESULT (WINAPI *pRevokeDragDrop)(HWND hwnd);
+extern HRESULT (WINAPI *pDoDragDrop)(LPDATAOBJECT,LPDROPSOURCE,DWORD,DWORD*);
+extern void    (WINAPI *pReleaseStgMedium)(STGMEDIUM* pmedium);
+extern HRESULT (WINAPI *pOleSetClipboard)(IDataObject* pDataObj);
+extern HRESULT (WINAPI *pOleGetClipboard)(IDataObject** ppDataObj);
+extern HRESULT (WINAPI *pCoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv);
+
+BOOL GetShellOle(void);
 
 HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl);
 HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl);
@@ -201,3 +196,5 @@
 }
 
 #endif
+
+
Index: wine/dlls/shell32/shelllink.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shelllink.c,v
retrieving revision 1.40
diff -d -u -r1.40 shelllink.c
--- wine/dlls/shell32/shelllink.c	31 May 2002 23:25:52 -0000	1.40
+++ wine/dlls/shell32/shelllink.c	27 Jun 2002 09:51:20 -0000
@@ -958,10 +958,21 @@
 /**************************************************************************
  *	  IShellLink_Constructor
  */
-IShellLinkA * IShellLink_Constructor(BOOL bUnicode)
-{	IShellLinkImpl * sl;
+HRESULT WINAPI IShellLink_Constructor (
+	IUnknown * pUnkOuter,
+	REFIID riid,
+	LPVOID * ppv)
+{
+	IShellLinkImpl * sl;
+
+	TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
+
+	*ppv = NULL;
+
+	if(pUnkOuter) return CLASS_E_NOAGGREGATION;
+	sl = (IShellLinkImpl *) LocalAlloc(GMEM_ZEROINIT,sizeof(IShellLinkImpl));
+	if (!sl) return E_OUTOFMEMORY;
 
-	sl = (IShellLinkImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellLinkImpl));
 	sl->ref = 1;
 	ICOM_VTBL(sl) = &slvt;
 	sl->lpvtblw = &slvtw;
@@ -969,8 +980,19 @@
 	sl->lpvtblPersistStream = &psvt;
 
 	TRACE("(%p)->()\n",sl);
+
+	if (IsEqualIID(riid, &IID_IShellLinkA))
+	    *ppv = sl;
+	else if (IsEqualIID(riid, &IID_IShellLinkW))
+	    *ppv = &(sl->lpvtblw);
+	else {
+	    LocalFree((HLOCAL)sl);
+	    ERR("E_NOINTERFACE\n");
+	    return E_NOINTERFACE;
+	}
+
 	shell32_ObjCount++;
-	return bUnicode ? (IShellLinkA *) &(sl->lpvtblw) : (IShellLinkA *)sl;
+	return S_OK;
 }
 
 /**************************************************************************
@@ -1059,7 +1081,7 @@
 
 	  This->iIcoNdx = 0;
 
-	  HeapFree(GetProcessHeap(),0,This);
+	  LocalFree((HANDLE)This);
 	  return 0;
 	}
 	return This->ref;
@@ -1538,4 +1560,5 @@
 	IShellLinkW_fnResolve,
 	IShellLinkW_fnSetPath
 };
+
 
Index: wine/dlls/shell32/shellole.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shellole.c,v
retrieving revision 1.47
diff -d -u -r1.47 shellole.c
--- wine/dlls/shell32/shellole.c	10 Jun 2002 02:29:09 -0000	1.47
+++ wine/dlls/shell32/shellole.c	27 Jun 2002 09:51:21 -0000
@@ -35,35 +35,107 @@
 #include "shell32_main.h"
 
 #include "wine/debug.h"
+#include "shlwapi.h"
+#include "winuser.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
 DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id);
-extern IShellFolder * IShellFolder_Constructor(
-	IShellFolder * psf,
-	LPITEMIDLIST pidl);
-extern HRESULT IFSFolder_Constructor(
-	IUnknown * pUnkOuter,
-	REFIID riid,
-	LPVOID * ppv);
+extern HRESULT WINAPI IFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
+
+const WCHAR sShell32[12] = {'S','H','E','L','L','3','2','.','D','L','L','\0'};
+const WCHAR sOLE32[10] = {'O','L','E','3','2','.','D','L','L','\0'};
+
+HINSTANCE hShellOle32 = 0;
+/**************************************************************************
+ * Default ClassFactory types
+ */
+typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
+IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst);
+
+/* this table contains all CLSID's of shell32 objects */
+struct {
+	REFIID			riid;
+	LPFNCREATEINSTANCE	lpfnCI;
+} InterfaceTable[4] = {
+	{&CLSID_ShellFSFolder, &IFSFolder_Constructor},
+	{&CLSID_ShellDesktop, &ISF_Desktop_Constructor},
+	{&CLSID_ShellLink, &IShellLink_Constructor},
+	{NULL,NULL}
+};
 
 /*************************************************************************
- * SHCoCreateInstance [SHELL32.102]
+ * __CoCreateInstance [internal]
  *
  * NOTES
+ *   wraper for late bound call to OLE32.DLL
+ * 
+ */
+HRESULT (WINAPI *pCoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv) = NULL;
+
+void * __GetExternalFunc(HMODULE * phModule, LPCWSTR szModuleName, LPCSTR szProcName)
+{
+	if (!*phModule) *phModule = GetModuleHandleW(szModuleName);
+	if (!*phModule) *phModule = LoadLibraryW(szModuleName);
+	if (*phModule) return GetProcAddress(*phModule, szProcName); 
+	return NULL;
+}
+
+HRESULT  __CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
+{
+	if(!pCoCreateInstance) pCoCreateInstance = __GetExternalFunc(&hShellOle32, sOLE32, "CoCreateInstance");
+	if(!pCoCreateInstance) return E_FAIL;
+	return pCoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
+}
+
+/*************************************************************************
+ * SHCoCreateInstance [SHELL32.102]
+ * 
+ * NOTES
  *     exported by ordinal
  */
+
+/* FIXME: this should be SHLWAPI.24 since we can't yet import by ordinal */
+
+DWORD WINAPI __SHGUIDToStringW (REFGUID guid, LPWSTR str)
+{
+    WCHAR sFormat[52] = {'{','%','0','8','l','x','-','%','0','4',
+		         'x','-','%','0','4','x','-','%','0','2',
+                         'x','%','0','2','x','-','%','0','2','x',
+			 '%','0','2','x','%','0','2','x','%','0',
+			 '2','x','%','0','2','x','%','0','2','x',
+			 '}','\0'};
+
+    return wsprintfW ( 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] );
+
+}
+
 LRESULT WINAPI SHCoCreateInstance(
 	LPCSTR aclsid,
 	REFCLSID clsid,
-	LPUNKNOWN unknownouter,
+	LPUNKNOWN pUnkOuter,
 	REFIID refiid,
 	LPVOID *ppv)
 {
 	DWORD	hres;
 	IID	iid;
 	CLSID * myclsid = (CLSID*)clsid;
+	WCHAR	sKeyName[MAX_PATH];
+	const	WCHAR sCLSID[7] = {'C','L','S','I','D','\\','\0'};
+	WCHAR	sClassID[60];
+	const WCHAR sInProcServer32[16] ={'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2','\0'};
+	const WCHAR sLoadWithoutCOM[15] ={'L','o','a','d','W','i','t','h','o','u','t','C','O','M','\0'};
+	WCHAR	sDllPath[MAX_PATH];
+	HKEY	hKey;
+	DWORD	dwSize;
+	BOOLEAN bLoadFromShell32 = FALSE;
+	BOOLEAN bLoadWithoutCOM = FALSE;
+	IClassFactory * pcf = NULL;
 
+	/* if the clsid is a string, convert it */
 	if (!clsid)
 	{
 	  if (!aclsid) return REGDB_E_CLASSNOTREG;
@@ -72,18 +144,73 @@
 	}
 
 	TRACE("(%p,\n\tCLSID:\t%s, unk:%p\n\tIID:\t%s,%p)\n",
-		aclsid,debugstr_guid(myclsid),unknownouter,debugstr_guid(refiid),ppv);
+		aclsid,debugstr_guid(myclsid),pUnkOuter,debugstr_guid(refiid),ppv);
 
-	if IsEqualCLSID(myclsid, &CLSID_ShellFSFolder)
-	{
-	  hres = IFSFolder_Constructor(unknownouter, refiid, ppv);
+	/* we look up the dll path in the registry */
+        __SHGUIDToStringW(myclsid, sClassID);
+	lstrcpyW(sKeyName, sCLSID);
+	lstrcatW(sKeyName, sClassID);
+	lstrcatW(sKeyName, sInProcServer32); 
+
+	if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_READ, &hKey)) {
+	    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 */
+	    bLoadWithoutCOM = (ERROR_SUCCESS == SHQueryValueExW(hKey, sLoadWithoutCOM, 0, 0, 0, 0)); 
+
+	    /* if the com object is inside shell32 omit use of ole32 */
+	    bLoadFromShell32 = (0==lstrcmpiW( PathFindFileNameW(sDllPath), sShell32));
+
+	    RegCloseKey (hKey);
+	} else {
+	    /* since we can't find it in the registry we try internally */
+	    bLoadFromShell32 = TRUE;
 	}
-	else
-	{
-	  CoInitialize(NULL);
-	  hres = CoCreateInstance(myclsid, unknownouter, CLSCTX_INPROC_SERVER, refiid, ppv);
+	
+	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));
+	    }
+	} else if (bLoadWithoutCOM) {
+
+	    /* load a external dll without ole32 */
+	    HANDLE hLibrary;
+	    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
+	    DllGetClassObjectFunc DllGetClassObject;
+
+	    if ((hLibrary = LoadLibraryExW(sDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
+	        ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(sDllPath));
+		hres = E_ACCESSDENIED;
+	        goto end;
+	    } else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) {
+	        ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(sDllPath));
+	        FreeLibrary( hLibrary );
+		hres = E_ACCESSDENIED;
+	        goto end;
+	    } else if (! SUCCEEDED(hres = DllGetClassObject(myclsid, &IID_IClassFactory, (LPVOID*)&pcf))) {
+		    TRACE("GetClassObject failed 0x%08lx\n", hres);
+		    goto end;
+	    }
+
+	} else {
+
+	    /* load a external dll in the usual way */
+	    hres = __CoCreateInstance(myclsid, pUnkOuter, CLSCTX_INPROC_SERVER, refiid, ppv);
+	    goto end;
 	}
+	
+	/* here we should have a ClassFactory */
+	if (!pcf) return E_ACCESSDENIED;
 
+	hres = IClassFactory_CreateInstance(pcf, pUnkOuter, refiid, ppv);
+	IClassFactory_Release(pcf);
+end:
 	if(hres!=S_OK)
 	{
 	  ERR("failed (0x%08lx) to create \n\tCLSID:\t%s\n\tIID:\t%s\n",
@@ -98,30 +225,33 @@
 /*************************************************************************
  * DllGetClassObject   [SHELL32.128]
  */
-HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
-{	HRESULT	hres = E_OUTOFMEMORY;
-	LPCLASSFACTORY lpclf;
+HRESULT WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+{
+	HRESULT	hres = E_OUTOFMEMORY;
+	IClassFactory * pcf = NULL;
+	int i;
 
 	TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
-
+	
+	if (!ppv) return E_INVALIDARG;
 	*ppv = NULL;
 
-	if(IsEqualCLSID(rclsid, &CLSID_ShellDesktop)||
-	   IsEqualCLSID(rclsid, &CLSID_ShellLink))
-	{
-	  lpclf = IClassFactory_Constructor( rclsid );
-
-	  if(lpclf)
-	  {
-	    hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
-	    IClassFactory_Release(lpclf);
-	  }
+	/* 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);
+	    }
 	}
-	else
-	{
-	  WARN("-- CLSID not found\n");
-	  hres = CLASS_E_CLASSNOTAVAILABLE;
+
+        if (!pcf) {
+	    FIXME("failed for CLSID=%s\n", debugstr_guid(rclsid));
+	    return CLASS_E_CLASSNOTAVAILABLE;
 	}
+
+	hres = IClassFactory_QueryInterface(pcf, iid, ppv);
+	IClassFactory_Release(pcf);
+
 	TRACE("-- pointer to class factory: %p\n",*ppv);
 	return hres;
 }
@@ -143,7 +273,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)
 {
@@ -153,205 +283,214 @@
 }
 
 /*************************************************************************
- *			 SHGetMalloc			[SHELL32.@]
- * returns the interface to shell malloc.
- *
- * [SDK header win95/shlobj.h:
- * equivalent to:  #define SHGetMalloc(ppmem)   CoGetMalloc(MEMCTX_TASK, ppmem)
- * ]
- * What we are currently doing is not very wrong, since we always use the same
- * heap (ProcessHeap).
+ *	Shell Memory Allocator
  */
-DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal)
-{
-	TRACE("(%p)\n", lpmal);
-	return CoGetMalloc(MEMCTX_TASK, lpmal);
-}
 
-/*************************************************************************
- * SHGetDesktopFolder			[SHELL32.@]
- */
-LPSHELLFOLDER pdesktopfolder=NULL;
+/* set the vtable later */
+extern ICOM_VTABLE(IMalloc) VT_Shell_IMalloc32;
 
-DWORD WINAPI SHGetDesktopFolder(IShellFolder **psf)
-{
-	HRESULT	hres = S_OK;
-	LPCLASSFACTORY lpclf;
-	TRACE("%p->(%p)\n",psf,*psf);
+/* this is the static object instance */
+typedef struct {
+	ICOM_VFIELD(IMalloc);
+	DWORD dummy;
+} _ShellMalloc;
 
-	*psf=NULL;
+_ShellMalloc Shell_Malloc = { &VT_Shell_IMalloc32,1};
 
-	if (!pdesktopfolder)
-	{
-	  lpclf = IClassFactory_Constructor(&CLSID_ShellDesktop);
-	  if(lpclf)
-	  {
-	    hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
-	    IClassFactory_Release(lpclf);
-	  }
-	}
+/* this is the global allocator of shell32 */
+IMalloc * ShellTaskAllocator = NULL;
 
-	if (pdesktopfolder)
-	{
-	  /* even if we create the folder, add a ref so the application cant destroy the folder*/
-	  IShellFolder_AddRef(pdesktopfolder);
-	  *psf = pdesktopfolder;
-	}
+/******************************************************************************
+ *              IShellMalloc_QueryInterface        [VTABLE]
+ */
+static HRESULT WINAPI IShellMalloc_fnQueryInterface(LPMALLOC iface, REFIID refiid, LPVOID *obj)
+{
+	TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
 
-	TRACE("-- %p->(%p)\n",psf, *psf);
-	return hres;
+	if (IsEqualIID(refiid, &IID_IUnknown) || IsEqualIID(refiid, &IID_IMalloc)) {
+		*obj = (LPMALLOC) &Shell_Malloc;
+		return S_OK;
+	}
+	return E_NOINTERFACE;
 }
 
-/**************************************************************************
-*  IClassFactory Implementation
-*/
-
-typedef struct
+/******************************************************************************
+ *              IShellMalloc_AddRefRelease        [VTABLE]
+ */
+static ULONG WINAPI IShellMalloc_fnAddRefRelease(LPMALLOC iface)
 {
-    /* IUnknown fields */
-    ICOM_VFIELD(IClassFactory);
-    DWORD                       ref;
-    CLSID			*rclsid;
-} IClassFactoryImpl;
-
-static ICOM_VTABLE(IClassFactory) clfvt;
+        return 1;
+}
 
-/**************************************************************************
- *  IClassFactory_Constructor
+/******************************************************************************
+ *		IShellMalloc_Alloc [VTABLE]
  */
-
-LPCLASSFACTORY IClassFactory_Constructor(REFCLSID rclsid)
+static LPVOID WINAPI IShellMalloc_fnAlloc(LPMALLOC iface, DWORD cb)
 {
-	IClassFactoryImpl* lpclf;
-
-	lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
-	lpclf->ref = 1;
-	ICOM_VTBL(lpclf) = &clfvt;
-	lpclf->rclsid = (CLSID*)rclsid;
+        LPVOID addr;
 
-	TRACE("(%p)->()\n",lpclf);
-	InterlockedIncrement(&shell32_ObjCount);
-	return (LPCLASSFACTORY)lpclf;
+	addr = (LPVOID) LocalAlloc(GMEM_ZEROINIT, cb);
+        TRACE("(%p,%ld);\n",addr,cb);
+        return addr;
 }
-/**************************************************************************
- *  IClassFactory_QueryInterface
+
+/******************************************************************************
+ *		IShellMalloc_Realloc [VTABLE]
  */
-static HRESULT WINAPI IClassFactory_fnQueryInterface(
-  LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
+static LPVOID WINAPI IShellMalloc_fnRealloc(LPMALLOC iface, LPVOID pv, DWORD cb)
 {
-	ICOM_THIS(IClassFactoryImpl,iface);
-	TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
-
-	*ppvObj = NULL;
+        LPVOID addr;
 
-	if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
-	{ *ppvObj = This;
-	}
-	else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
-	{ *ppvObj = (IClassFactory*)This;
+	if (pv) {
+		if (cb) {
+			addr = (LPVOID) LocalReAlloc((HANDLE) pv, cb, GMEM_ZEROINIT | GMEM_MOVEABLE);
+		} else {
+			LocalFree((HANDLE) pv);
+			addr = NULL;
+		}
+	} else {
+		if (cb) {
+			addr = (LPVOID) LocalAlloc(GMEM_ZEROINIT, cb);
+		} else {
+			addr = NULL;
+		}
 	}
 
-	if(*ppvObj)
-	{ IUnknown_AddRef((LPUNKNOWN)*ppvObj);
-	  TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
-	  return S_OK;
-	}
-	TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
-	return E_NOINTERFACE;
+        TRACE("(%p->%p,%ld)\n",pv,addr,cb);
+        return addr;
 }
+
 /******************************************************************************
- * IClassFactory_AddRef
+ *		IShellMalloc_Free [VTABLE]
  */
-static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface)
+static VOID WINAPI IShellMalloc_fnFree(LPMALLOC iface, LPVOID pv) 
 {
-	ICOM_THIS(IClassFactoryImpl,iface);
-	TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-	InterlockedIncrement(&shell32_ObjCount);
-	return InterlockedIncrement(&This->ref);
+        TRACE("(%p)\n",pv);
+	LocalFree((HANDLE) pv);
 }
+
 /******************************************************************************
- * IClassFactory_Release
+ *		IShellMalloc_GetSize [VTABLE]
  */
-static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface)
+static DWORD WINAPI IShellMalloc_fnGetSize(LPMALLOC iface, LPVOID pv) 
 {
-	ICOM_THIS(IClassFactoryImpl,iface);
-	TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
-	InterlockedDecrement(&shell32_ObjCount);
-	if (!InterlockedDecrement(&This->ref))
-	{
-	  TRACE("-- destroying IClassFactory(%p)\n",This);
-	  HeapFree(GetProcessHeap(),0,This);
-	  return 0;
-	}
-	return This->ref;
+        DWORD cb = (DWORD) LocalSize((HANDLE)pv);
+        TRACE("(%p,%ld)\n", pv, cb);
+	return cb;
 }
+
 /******************************************************************************
- * IClassFactory_CreateInstance
+ *		IShellMalloc_DidAlloc [VTABLE]
  */
-static HRESULT WINAPI IClassFactory_fnCreateInstance(
-  LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
+static INT WINAPI IShellMalloc_fnDidAlloc(LPMALLOC iface, LPVOID pv) 
 {
-	ICOM_THIS(IClassFactoryImpl,iface);
-	IUnknown *pObj = NULL;
-	HRESULT hres;
+        TRACE("(%p)\n",pv);
+        return -1;
+}
 
-	TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,debugstr_guid(riid),ppObject);
+/******************************************************************************
+ * 		IShellMalloc_HeapMinimize [VTABLE]
+ */
+static VOID WINAPI IShellMalloc_fnHeapMinimize(LPMALLOC iface)
+{
+	TRACE("()\n");
+}
 
-	*ppObject = NULL;
+static ICOM_VTABLE(IMalloc) VT_Shell_IMalloc32 =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IShellMalloc_fnQueryInterface,
+	IShellMalloc_fnAddRefRelease,
+	IShellMalloc_fnAddRefRelease,
+	IShellMalloc_fnAlloc,
+	IShellMalloc_fnRealloc,
+	IShellMalloc_fnFree,
+	IShellMalloc_fnGetSize,
+	IShellMalloc_fnDidAlloc,
+	IShellMalloc_fnHeapMinimize
+};
 
-	if(pUnknown)
-	{
-	  return(CLASS_E_NOAGGREGATION);
-	}
+/*************************************************************************
+ *			 SHGetMalloc			[SHELL32.@]
+ * returns the interface to shell malloc.
+ *
+ * NOTES
+ *  uses OLE32.CoGetMalloc if OLE32.DLL is already loaded.
+ *  if not it uses a internal implementations as fallback.
+ */
+DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal) 
+{
+	HRESULT (WINAPI *pCoGetMalloc)(DWORD,LPMALLOC *);
+	HMODULE hOle32;
 
-	if (IsEqualCLSID(This->rclsid, &CLSID_ShellDesktop))
-	{
-	  pObj = (IUnknown *)ISF_Desktop_Constructor();
-	}
-	else if (IsEqualCLSID(This->rclsid, &CLSID_ShellLink))
-	{
-	  pObj = (IUnknown *)IShellLink_Constructor(FALSE);
-	}
-	else
-	{
-	  ERR("unknown IID requested\n\tIID:\t%s\n",debugstr_guid(riid));
-	  return(E_NOINTERFACE);
-	}
+	TRACE("(%p)\n", lpmal);
 
-	if (!pObj)
+	if (!ShellTaskAllocator)
 	{
-	  return(E_OUTOFMEMORY);
+		hOle32 = GetModuleHandleA("OLE32.DLL");
+		if(hOle32) {
+			pCoGetMalloc = (void*) GetProcAddress(hOle32, "CoGetMalloc");
+			if (pCoGetMalloc) pCoGetMalloc(MEMCTX_TASK, &ShellTaskAllocator);
+			TRACE("got ole32 IMalloc\n");
+		}
+		if(!ShellTaskAllocator) {
+			ShellTaskAllocator = (IMalloc* ) &Shell_Malloc;
+			TRACE("use fallback allocator\n");
+		}
 	}
+	*lpmal = ShellTaskAllocator;
+	return  S_OK;
+}
 
-	hres = IUnknown_QueryInterface(pObj,riid, ppObject);
-	IUnknown_Release(pObj);
+/*************************************************************************
+ * SHAlloc					[SHELL32.196]
+ *
+ * NOTES
+ *     exported by ordinal
+ */
+LPVOID WINAPI SHAlloc(DWORD len) 
+{
+	IMalloc * ppv;
+	LPBYTE ret;
 
-	TRACE("-- Object created: (%p)->%p\n",This,*ppObject);
+	if (!ShellTaskAllocator) SHGetMalloc(&ppv);
 
-	return hres;
+	ret = (LPVOID) IMalloc_Alloc(ShellTaskAllocator, len);
+	if(ret) ZeroMemory(ret, len); /*FIXME*/
+	TRACE("%lu bytes at %p\n",len, ret);
+	return (LPVOID)ret;
 }
-/******************************************************************************
- * IClassFactory_LockServer
+
+/*************************************************************************
+ * SHFree					[SHELL32.195]
+ *
+ * NOTES
+ *     exported by ordinal
  */
-static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
+void WINAPI SHFree(LPVOID pv) 
 {
-	ICOM_THIS(IClassFactoryImpl,iface);
-	TRACE("%p->(0x%x), not implemented\n",This, fLock);
-	return E_NOTIMPL;
+	IMalloc * ppv;
+
+	TRACE("%p\n",pv);
+	if (!ShellTaskAllocator) SHGetMalloc(&ppv);
+	IMalloc_Free(ShellTaskAllocator, pv);
 }
 
-static ICOM_VTABLE(IClassFactory) clfvt =
+/*************************************************************************
+ * SHGetDesktopFolder			[SHELL32.@]
+ */
+DWORD WINAPI SHGetDesktopFolder(IShellFolder **psf)
 {
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    IClassFactory_fnQueryInterface,
-    IClassFactory_fnAddRef,
-  IClassFactory_fnRelease,
-  IClassFactory_fnCreateInstance,
-  IClassFactory_fnLockServer
-};
+	HRESULT	hres = S_OK;
+	TRACE("%p->(%p)\n",psf,*psf);
+
+	if(!psf) return E_INVALIDARG;
+	*psf = NULL;
+	hres = ISF_Desktop_Constructor(NULL, &IID_IShellFolder,(LPVOID*)psf);
 
+	TRACE("-- %p->(%p)\n",psf, *psf);
+	return hres;
+}
 /**************************************************************************
  * Default ClassFactory Implementation
  *
@@ -362,7 +501,6 @@
  *  a generic classfactory is returned
  *  when the CreateInstance of the cf is called the callback is executed
  */
-typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
 
 typedef struct
 {
@@ -394,7 +532,6 @@
 	lpclf->riidInst = riidInst;
 
 	TRACE("(%p)\n\tIID:\t%s\n",lpclf, debugstr_guid(riidInst));
-	InterlockedIncrement(&shell32_ObjCount);
 	return (LPCLASSFACTORY)lpclf;
 }
 /**************************************************************************
@@ -409,21 +546,15 @@
 
 	*ppvObj = NULL;
 
-	if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
-	{ *ppvObj = This;
-	}
-	else if(IsEqualIID(riid, &IID_IClassFactory))  /*IClassFactory*/
-	{ *ppvObj = (IClassFactory*)This;
-	}
-
-	if(*ppvObj)
-	{ IUnknown_AddRef((LPUNKNOWN)*ppvObj);
-	  TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+	if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) {
+	  *ppvObj = This; 
+	  InterlockedIncrement(&This->ref);
 	  return S_OK;
 	}
-	TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
+
+	TRACE("-- E_NOINTERFACE\n");
 	return E_NOINTERFACE;
-}
+}  
 /******************************************************************************
  * IDefClF_fnAddRef
  */
@@ -432,7 +563,6 @@
 	ICOM_THIS(IDefClFImpl,iface);
 	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
-	InterlockedIncrement(&shell32_ObjCount);
 	return InterlockedIncrement(&This->ref);
 }
 /******************************************************************************
@@ -443,10 +573,8 @@
 	ICOM_THIS(IDefClFImpl,iface);
 	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
-	InterlockedDecrement(&shell32_ObjCount);
-
-	if (!InterlockedDecrement(&This->ref))
-	{
+	if (!InterlockedDecrement(&This->ref)) 
+	{ 
 	  if (This->pcRefDll) InterlockedDecrement(This->pcRefDll);
 
 	  TRACE("-- destroying IClassFactory(%p)\n",This);
@@ -466,10 +594,7 @@
 	TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnkOuter,debugstr_guid(riid),ppvObject);
 
 	*ppvObject = NULL;
-
-	if(pUnkOuter)
-	  return(CLASS_E_NOAGGREGATION);
-
+		
 	if ( This->riidInst==NULL ||
 	     IsEqualCLSID(riid, This->riidInst) ||
 	     IsEqualCLSID(riid, &IID_IUnknown) )
@@ -490,7 +615,7 @@
 	return E_NOTIMPL;
 }
 
-static ICOM_VTABLE(IClassFactory) dclfvt =
+static ICOM_VTABLE(IClassFactory) dclfvt = 
 {
     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
     IDefClF_fnQueryInterface,
@@ -504,26 +629,21 @@
  * 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));
 
-	if ( IsEqualCLSID(riid, &IID_IClassFactory) )
-	{
-	  IClassFactory * pcf = IDefClF_fnConstructor(lpfnCI, pcRefDll, riidInst);
-	  if (pcf)
-	  {
-	    *ppv = pcf;
-	    return NOERROR;
-	  }
-	  return E_OUTOFMEMORY;
-	}
-	return E_NOINTERFACE;
+	if (! IsEqualCLSID(riid, &IID_IClassFactory) ) return E_NOINTERFACE;
+	if (! (pcf = IDefClF_fnConstructor(lpfnCI, pcRefDll, riidInst))) return E_OUTOFMEMORY;
+	*ppv = pcf;
+	return NOERROR;
 }
 
 /*************************************************************************
@@ -532,7 +652,7 @@
 void WINAPI DragAcceptFiles(HWND hWnd, BOOL b)
 {
 	LONG exstyle;
-
+  
 	if( !IsWindow(hWnd) ) return;
 	exstyle = GetWindowLongA(hWnd,GWL_EXSTYLE);
 	if (b)
@@ -565,7 +685,7 @@
 
         *p = lpDropFileStruct->pt;
 	bRet = lpDropFileStruct->fNC;
-
+  
 	GlobalUnlock(hDrop);
 	return bRet;
 }
@@ -686,3 +806,7 @@
 	GlobalUnlock(hDrop);
 	return i;
 }
+
+
+
+
Index: wine/dlls/shell32/shellord.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shellord.c,v
retrieving revision 1.97
diff -d -u -r1.97 shellord.c
--- wine/dlls/shell32/shellord.c	31 May 2002 23:25:52 -0000	1.97
+++ wine/dlls/shell32/shellord.c	27 Jun 2002 09:51:24 -0000
@@ -3,7 +3,7 @@
  * (NT uses Unicode strings, 95 uses ASCII strings)
  *
  * Copyright 1997 Marcus Meissner
- *           1998 Jrgen 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
@@ -345,64 +345,6 @@
 }
 
 /*************************************************************************
- * SHFree					[SHELL32.195]
- *
- * NOTES
- *     free_ptr() - frees memory using IMalloc
- *     exported by ordinal
- */
-#define MEM_DEBUG 0
-void WINAPI SHFree(LPVOID x)
-{
-#if MEM_DEBUG
-	WORD len = *(LPWORD)((LPBYTE)x-2);
-
-	if ( *(LPWORD)((LPBYTE)x+len) != 0x7384)
-	  ERR("MAGIC2!\n");
-
-	if ( (*(LPWORD)((LPBYTE)x-4)) != 0x8271)
-	  ERR("MAGIC1!\n");
-	else
-	  memset((LPBYTE)x-4, 0xde, len+6);
-
-	TRACE("%p len=%u\n",x, len);
-
-	x = (LPBYTE) x - 4;
-#else
-	TRACE("%p\n",x);
-#endif
-	HeapFree(GetProcessHeap(), 0, x);
-}
-
-/*************************************************************************
- * SHAlloc					[SHELL32.196]
- *
- * NOTES
- *     void *task_alloc(DWORD len), uses SHMalloc allocator
- *     exported by ordinal
- */
-LPVOID WINAPI SHAlloc(DWORD len)
-{
-	LPBYTE ret;
-
-#if MEM_DEBUG
-	ret = (LPVOID) HeapAlloc(GetProcessHeap(),0,len+6);
-#else
-	ret = (LPVOID) HeapAlloc(GetProcessHeap(),0,len);
-#endif
-
-#if MEM_DEBUG
-	*(LPWORD)(ret) = 0x8271;
-	*(LPWORD)(ret+2) = (WORD)len;
-	*(LPWORD)(ret+4+len) = 0x7384;
-	ret += 4;
-	memset(ret, 0xdf, len);
-#endif
-	TRACE("%lu bytes at %p\n",len, ret);
-	return (LPVOID)ret;
-}
-
-/*************************************************************************
  * SHRegisterDragDrop				[SHELL32.86]
  *
  * NOTES
@@ -1548,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.21
diff -d -u -r1.21 shellstring.c
--- wine/dlls/shell32/shellstring.c	31 May 2002 23:25:52 -0000	1.21
+++ wine/dlls/shell32/shellstring.c	27 Jun 2002 09:51:24 -0000
@@ -53,14 +53,14 @@
 	{
 	  case STRRET_WSTR:
 	    WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
-/*	    SHFree(src->u.pOleStr);  FIXME: is this right? */
+	    CoTaskMemFree(src->u.pOleStr);
 	    break;
 
-	  case STRRET_CSTRA:
+	  case STRRET_CSTR:
 	    lstrcpynA((LPSTR)dest, src->u.cStr, len);
 	    break;
 
-	  case STRRET_OFFSETA:
+	  case STRRET_OFFSET:
 	    lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
 	    break;
 
@@ -86,15 +86,15 @@
 	{
 	  case STRRET_WSTR:
 	    lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
-/*	    SHFree(src->u.pOleStr);  FIXME: is this right? */
+	    CoTaskMemFree(src->u.pOleStr);
 	    break;
 
-	  case STRRET_CSTRA:
+	  case STRRET_CSTR:
               if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len)
                   dest[len-1] = 0;
 	    break;
 
-	  case STRRET_OFFSETA:
+	  case STRRET_OFFSET:
 	    if (pidl)
 	    {
               if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1,
@@ -251,3 +251,4 @@
    handle);
     return 0;
 }
+
Index: wine/dlls/shell32/shlfolder.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shlfolder.c,v
retrieving revision 1.70
diff -d -u -r1.70 shlfolder.c
--- wine/dlls/shell32/shlfolder.c	31 May 2002 23:25:52 -0000	1.70
+++ wine/dlls/shell32/shlfolder.c	27 Jun 2002 09:51:29 -0000
@@ -45,6 +45,7 @@
 #include "shlwapi.h"
 #include "shellfolder.h"
 #include "wine/debug.h"
+#include "debughlp.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -158,26 +159,19 @@
 	LPVOID * ppvOut)
 {
 	HRESULT hr;
-	LPITEMIDLIST	absPidl;
-	IShellFolder2 	*pShellFolder;
-	IPersistFolder	*pPersistFolder;
+	LPITEMIDLIST	pidlAbsolute;
+	IPersistFolder	*pPF;
 
 	TRACE("%p %p\n", pidlRoot, pidlChild);
 
 	*ppvOut = NULL;
 
-	/* we have to ask first for IPersistFolder, some special folders are expecting this */
-	hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
-	if (SUCCEEDED(hr))
-	{
-	  hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
-	  if (SUCCEEDED(hr))
-	  {
-	    absPidl = ILCombine (pidlRoot, pidlChild);
-	    hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
-	    IPersistFolder_Release(pPersistFolder);
-	    SHFree(absPidl);
-	    *ppvOut = pShellFolder;
+	if (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);
 	  }
 	}
 
@@ -296,7 +290,7 @@
 	ICOM_VFIELD(IUnknown);
 	DWORD				ref;
 	ICOM_VTABLE(IShellFolder2)*	lpvtblShellFolder;
-	ICOM_VTABLE(IPersistFolder2)*	lpvtblPersistFolder2;
+	ICOM_VTABLE(IPersistFolder3)*	lpvtblPersistFolder3;
 	ICOM_VTABLE(IDropTarget)*	lpvtblDropTarget;
 	ICOM_VTABLE(ISFHelper)*		lpvtblSFHelper;
 
@@ -304,16 +298,22 @@
 
 	CLSID*				pclsid;
 
-	LPSTR				sMyPath;
-	LPITEMIDLIST			absPidl;	/* complete pidl */
+	/* 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 */
 
-	UINT		cfShellIDList;			/* clipboardformat for IDropTarget */
-	BOOL		fAcceptFmt;			/* flag for pending Drop */
+	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(IPersistFolder2) psfvt;
+static struct ICOM_VTABLE(IPersistFolder3) psfvt;
 static struct ICOM_VTABLE(IDropTarget) dtvt;
 static struct ICOM_VTABLE(ISFHelper) shvt;
 
@@ -322,8 +322,8 @@
 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
 
-#define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
-#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
+#define _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);
@@ -336,9 +336,10 @@
 #define _IUnknown_(This)	(IUnknown*)&(This->lpVtbl)
 #define _IShellFolder_(This)	(IShellFolder*)&(This->lpvtblShellFolder)
 #define _IShellFolder2_(This)	(IShellFolder2*)&(This->lpvtblShellFolder)
-#define _IPersist_(This)	(IPersist*)&(This->lpvtblPersistFolder2)
-#define _IPersistFolder_(This)	(IPersistFolder*)&(This->lpvtblPersistFolder2)
-#define _IPersistFolder2_(This)	(IPersistFolder2*)&(This->lpvtblPersistFolder2)
+#define _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)
 /**************************************************************************
@@ -366,7 +367,7 @@
 	ICOM_THIS(IGenericSFImpl, iface);
 
 	_CALL_TRACE
-	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
+	TRACE("(%p)->(%s,%p)\n",This,shdebugstr_guid(riid),ppvObj);
 
 	*ppvObj = NULL;
 
@@ -376,6 +377,7 @@
 	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))
 	{
@@ -416,14 +418,9 @@
 	{
 	  TRACE("-- destroying IShellFolder(%p)\n",This);
 
-	  if (pdesktopfolder == _IShellFolder_(This))
-	  {
-	    pdesktopfolder=NULL;
-	    TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
-	  }
-	  if(This->absPidl) SHFree(This->absPidl);
-	  if(This->sMyPath) SHFree(This->sMyPath);
-	  HeapFree(GetProcessHeap(),0,This);
+	  if(This->pidlRoot) SHFree(This->pidlRoot);
+	  if(This->sPathRoot) SHFree(This->sPathRoot);
+	  LocalFree((HLOCAL)This);
 	  return 0;
 	}
 	return This->ref;
@@ -448,122 +445,92 @@
 #define GENERICSHELLVIEWCOLUMNS 5
 
 /**************************************************************************
-*	IShellFolder_Constructor
+*	IFSFolder_Constructor
 *
 * NOTES
 *  creating undocumented ShellFS_Folder as part of an aggregation
 *  {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
 *
-* FIXME
-*	when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
 */
-HRESULT IFSFolder_Constructor(
+HRESULT WINAPI IFSFolder_Constructor(
 	IUnknown * pUnkOuter,
 	REFIID riid,
 	LPVOID * ppv)
 {
-	IGenericSFImpl *	sf;
-	HRESULT hr = S_OK;
-
-	TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
-
-	if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
-	{
-	  hr = CLASS_E_NOAGGREGATION;	/* forbidden by definition */
-	}
-	else
-	{
-	  sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
-	  if (sf)
-	  {
-	    sf->ref=1;
-	    ICOM_VTBL(sf)=&unkvt;
-	    sf->lpvtblShellFolder=&sfvt;
-	    sf->lpvtblPersistFolder2=&psfvt;
-	    sf->lpvtblDropTarget=&dtvt;
-	    sf->lpvtblSFHelper=&shvt;
-
-	    sf->pclsid = (CLSID*)&CLSID_SFFile;
-	    sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
-	    *ppv = _IUnknown_(sf);
-	    hr = S_OK;
-	    shell32_ObjCount++;
-	  }
-	  else
-	  {
-	    hr = E_OUTOFMEMORY;
-	  }
-	}
-	return hr;
-}
-/**************************************************************************
-*	  IShellFolder_Constructor
-*
-* NOTES
-*	THIS points to the parent folder
-*/
+	IGenericSFImpl * sf;
 
-IShellFolder * IShellFolder_Constructor(
-	IShellFolder2 * iface,
-	LPITEMIDLIST pidl)
-{
-	IGenericSFImpl *	sf;
-	DWORD			dwSize=0;
+	TRACE("unkOut=%p %s\n",pUnkOuter, shdebugstr_guid(riid));
 
-	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
+	if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown)) return CLASS_E_NOAGGREGATION;
+	sf=(IGenericSFImpl*) LocalAlloc(GMEM_ZEROINIT,sizeof(IGenericSFImpl));
+	if (!sf) return E_OUTOFMEMORY;
 
-	sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
 	sf->ref=1;
-
 	ICOM_VTBL(sf)=&unkvt;
 	sf->lpvtblShellFolder=&sfvt;
-	sf->lpvtblPersistFolder2=&psfvt;
+	sf->lpvtblPersistFolder3=&psfvt;
 	sf->lpvtblDropTarget=&dtvt;
 	sf->lpvtblSFHelper=&shvt;
+	sf->pclsid = (CLSID*)&CLSID_ShellFSFolder;
+	sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
 
-	sf->pclsid = (CLSID*)&CLSID_SFFile;
-	sf->pUnkOuter = _IUnknown_(sf);
+	/* we have to return the inner IUnknown */
+	*ppv = _IUnknown_(sf);
 
-	TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
-	pdump(pidl);
+	shell32_ObjCount++;
+	TRACE("--%p\n", *ppv);
+	return S_OK;
+}
 
-	if(pidl && iface)				/* do we have a pidl? */
-	{
-	  int len;
+/**************************************************************************
+*	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);
 
-	  sf->absPidl = ILCombine(This->absPidl, pidl);	/* build a absolute pidl */
+	sf->pidlRoot = ILCombine(pidlRoot, pidlFolder);
+	if (!_ILIsSpecialFolder(pidlFolder)) {				/* only file system paths */
+	    char sNewPath[MAX_PATH];
+	    char * sPos;
 
-	  if (!_ILIsSpecialFolder(pidl))				/* only file system paths */
-	  {
-	    if(This->sMyPath)				/* get the size of the parents path */
-	    {
-	      dwSize += strlen(This->sMyPath) ;
-	      TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
+	    if (sPathRoot) {
+	        strcpy(sNewPath, sPathRoot);
+	        if (!((sPos = PathAddBackslashA (sNewPath)))) return E_UNEXPECTED;
+	    } 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;
+}
 
-	    dwSize += _ILSimpleGetText(pidl,NULL,0);		/* add the size of our name*/
-	    sf->sMyPath = SHAlloc(dwSize + 2);			/* '\0' and backslash */
-
-	    if(!sf->sMyPath) return NULL;
-	    *(sf->sMyPath)=0x00;
-
-	    if(This->sMyPath)				/* if the parent has a path, get it*/
-	    {
-	      strcpy(sf->sMyPath, This->sMyPath);
-	      PathAddBackslashA (sf->sMyPath);
-	    }
+/**************************************************************************
+*	  IShellFolder_Constructor
+*/
+IGenericSFImpl * IShellFolder_Constructor()
+{
+	IGenericSFImpl * sf=(IGenericSFImpl*) LocalAlloc(GMEM_ZEROINIT,sizeof(IGenericSFImpl));
+	sf->ref=1;
 
-	    len = strlen(sf->sMyPath);
-	    _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
-	  }
+	ICOM_VTBL(sf)=&unkvt;
+	sf->lpvtblShellFolder=&sfvt;
+	sf->lpvtblPersistFolder3=&psfvt;
+	sf->lpvtblDropTarget=&dtvt;
+	sf->lpvtblSFHelper=&shvt;
 
-	  TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
+	sf->pclsid = (CLSID*)&CLSID_ShellFSFolder;
+	sf->pUnkOuter = _IUnknown_(sf);
 
-	  pdump (sf->absPidl);
-	}
+	TRACE("(%p)->()\n",sf);
 
 	shell32_ObjCount++;
-	return _IShellFolder_(sf);
+	return sf;
 }
 
 /**************************************************************************
@@ -581,7 +548,7 @@
 	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
 
 	_CALL_TRACE
-	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
+	TRACE("(%p)->(%s,%p)\n",This,shdebugstr_guid(riid),ppvObj);
 
 	return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
 }
@@ -667,7 +634,7 @@
 
 	  /* build the full pathname to the element */
           WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
-	  strcpy(szPath, This->sMyPath);
+	  strcpy(szPath, This->sPathRoot);
 	  PathAddBackslashA(szPath);
 	  strcat(szPath, szTempA);
 
@@ -727,7 +694,7 @@
 	TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
 
 	*ppEnumIDList = NULL;
-	*ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
+	*ppEnumIDList = IEnumIDList_Constructor (This->sPathRoot, dwFlags, EIDL_FILE);
 
 	TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
 
@@ -750,11 +717,12 @@
 	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
 	GUID		const * iid;
 	IShellFolder	*pShellFolder, *pSubFolder;
+        IGenericSFImpl  *pSFImpl;
 	IPersistFolder 	*pPersistFolder;
-	LPITEMIDLIST	absPidl;
+	LPITEMIDLIST	pidlRoot;
 	HRESULT         hr;
 
-	TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
+	TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",This,pidl,pbcReserved,shdebugstr_guid(riid),ppvOut);
 
 	if(!pidl || !ppvOut) return E_INVALIDARG;
 
@@ -766,10 +734,10 @@
 	  if (  SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
 	     && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
 	    {
-	      absPidl = ILCombine (This->absPidl, pidl);
-	      IPersistFolder_Initialize(pPersistFolder, absPidl);
+	      pidlRoot = ILCombine (This->pidlRoot, pidl);
+	      IPersistFolder_Initialize(pPersistFolder, pidlRoot);
 	      IPersistFolder_Release(pPersistFolder);
-	      SHFree(absPidl);
+	      SHFree(pidlRoot);
 	    }
 	    else
 	    {
@@ -778,9 +746,12 @@
 	}
 	else
 	{
-	  LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
-	  pShellFolder = IShellFolder_Constructor(iface, pidltemp);
-	  ILFree(pidltemp);
+	  if ((pSFImpl = IShellFolder_Constructor())) {
+	    LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
+	    hr = InitializeGenericSF(pSFImpl, This->pidlRoot, pidltemp, This->sPathRoot);
+	    ILFree(pidltemp);
+	    pShellFolder = _IShellFolder_(pSFImpl);
+	  }
 	}
 
 	if (_ILIsPidlSimple(pidl))
@@ -798,8 +769,7 @@
 	}
 	else
 	{
-	  hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
-					 riid, (LPVOID)&pSubFolder);
+	  hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
 	  IShellFolder_Release(pShellFolder);
 	  *ppvOut = pSubFolder;
 	}
@@ -826,8 +796,8 @@
 {
 	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
 
-	FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
-              This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
+	FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n",
+              This,pidl,pbcReserved,shdebugstr_guid(riid),ppvOut);
 
 	*ppvOut = NULL;
 	return E_NOTIMPL;
@@ -955,7 +925,7 @@
 	LPSHELLVIEW	pShellView;
 	HRESULT		hr = E_INVALIDARG;
 
-	TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
+	TRACE("(%p)->(hwnd=0x%x,%s,%p)\n",This,hwndOwner,shdebugstr_guid(riid),ppvOut);
 
 	if(ppvOut)
 	{
@@ -1056,8 +1026,8 @@
 	IUnknown*	pObj = NULL;
 	HRESULT		hr = E_INVALIDARG;
 
-	TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
-	  This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
+	TRACE("(%p)->(0x%04x,%u,apidl=%p,%s,%p,%p)\n",
+	  This,hwndOwner,cidl,apidl,shdebugstr_guid(riid),prgfInOut,ppvOut);
 
 	if (ppvOut)
 	{
@@ -1065,17 +1035,17 @@
 
 	  if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
 	  {
-	    pObj  = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
+	    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->absPidl, apidl, cidl);
+	    pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->pidlRoot, apidl, cidl);
 	    hr = S_OK;
 	  }
 	  else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
 	  {
-	    pidl = ILCombine(This->absPidl,apidl[0]);
+	    pidl = ILCombine(This->pidlRoot,apidl[0]);
 	    pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
 	    SHFree(pidl);
 	    hr = S_OK;
@@ -1142,9 +1112,9 @@
 	}
 	else
 	{
-	  if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
+	  if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sPathRoot)
 	  {
-	    strcpy (szPath, This->sMyPath);			/* get path to root*/
+	    strcpy (szPath, This->sPathRoot);			/* get path to root*/
 	    PathAddBackslashA(szPath);
 	    len = strlen(szPath);
 	  }
@@ -1181,7 +1151,7 @@
 	  if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
 	    return E_OUTOFMEMORY;
 	}
-	strRet->uType = STRRET_CSTRA;
+	strRet->uType = STRRET_CSTR;
 	lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
 
 	TRACE("-- (%p)->(%s)\n", This, szPath);
@@ -1219,7 +1189,7 @@
 	/* build source path */
 	if (dwFlags & SHGDN_INFOLDER)
 	{
-	  strcpy(szSrc, This->sMyPath);
+	  strcpy(szSrc, This->sPathRoot);
 	  PathAddBackslashA(szSrc);
 	  len = strlen (szSrc);
 	  _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
@@ -1230,7 +1200,7 @@
 	}
 
 	/* build destination path */
-	strcpy(szDest, This->sMyPath);
+	strcpy(szDest, This->sPathRoot);
 	PathAddBackslashA(szDest);
 	len = strlen (szDest);
         WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
@@ -1320,7 +1290,7 @@
 	  /* the header titles */
 	  psd->fmt = GenericSFHeader[iColumn].fmt;
 	  psd->cxChar = GenericSFHeader[iColumn].cxChar;
-	  psd->str.uType = STRRET_CSTRA;
+	  psd->str.uType = STRRET_CSTR;
 	  LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
 	  return S_OK;
 	}
@@ -1346,7 +1316,7 @@
 	      break;
 	  }
 	  hr = S_OK;
-	  psd->str.uType = STRRET_CSTRA;
+	  psd->str.uType = STRRET_CSTR;
 	}
 
 	return hr;
@@ -1399,7 +1369,7 @@
 {
 	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
 
-	TRACE("(%p)\n", This);
+	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
 	return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
 }
@@ -1409,7 +1379,7 @@
 {
 	_ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
 
-	TRACE("(%p)\n", This);
+	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
 	return IUnknown_AddRef(This->pUnkOuter);
 }
@@ -1495,7 +1465,7 @@
 
 	TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
 
-	strcpy(lpstrNewDir, This->sMyPath);
+	strcpy(lpstrNewDir, This->sPathRoot);
 	PathAddBackslashA(lpstrNewDir);
 	strcat(lpstrNewDir, lpName);
 
@@ -1507,7 +1477,7 @@
 
 	  pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
 
-	  pidl = ILCombine(This->absPidl, pidlitem);
+	  pidl = ILCombine(This->pidlRoot, pidlitem);
 	  SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
 	  SHFree(pidl);
 
@@ -1559,7 +1529,7 @@
 
 	for(i=0; i< cidl; i++)
 	{
-	  strcpy(szPath, This->sMyPath);
+	  strcpy(szPath, This->sPathRoot);
 	  PathAddBackslashA(szPath);
 	  _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
 
@@ -1572,7 +1542,7 @@
               TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
 	      return E_FAIL;
 	    }
-	    pidl = ILCombine(This->absPidl, apidl[i]);
+	    pidl = ILCombine(This->pidlRoot, apidl[i]);
 	    SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
 	    SHFree(pidl);
 	  }
@@ -1586,7 +1556,7 @@
               TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
 	      return E_FAIL;
 	    }
-	    pidl = ILCombine(This->absPidl, apidl[i]);
+	    pidl = ILCombine(This->pidlRoot, apidl[i]);
 	    SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
 	    SHFree(pidl);
 	  }
@@ -1625,7 +1595,7 @@
 	      PathAddBackslashA(szSrcPath);
 	      _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
 
-	      strcpy(szDstPath, This->sMyPath);
+	      strcpy(szDstPath, This->sPathRoot);
 	      PathAddBackslashA(szDstPath);
 	      _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
 	      MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
@@ -1668,21 +1638,34 @@
 *	ISF_Desktop_Constructor
 *
 */
-IShellFolder * ISF_Desktop_Constructor()
+HRESULT WINAPI ISF_Desktop_Constructor (
+	IUnknown * pUnkOuter,
+	REFIID riid,
+	LPVOID * ppv)
 {
 	IGenericSFImpl *	sf;
 
-	sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
+	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->absPidl=_ILCreateDesktop();	/* my qualified pidl */
+	sf->pidlRoot=_ILCreateDesktop();	/* my qualified pidl */
 	sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
 
-	TRACE("(%p)\n",sf);
-
+	*ppv = _IShellFolder_(sf);
 	shell32_ObjCount++;
-	return _IShellFolder_(sf);
+
+	TRACE("--(%p)\n",sf);
+	return S_OK;
 }
 
 /**************************************************************************
@@ -1697,7 +1680,7 @@
 {
 	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
 
-	TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
+	TRACE("(%p)->(%s,%p)\n",This,shdebugstr_guid(riid),ppvObj);
 
 	*ppvObj = NULL;
 
@@ -1742,9 +1725,11 @@
 {
 	_ICOM_THIS_From_IShellFolder2(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,
@@ -1753,9 +1738,18 @@
 	*ppidl = 0;
 	if (pchEaten) *pchEaten = 0;	/* strange but like the original */
 
-	/* FIXME no real parsing implemented */
-	pidlTemp = _ILCreateMyComputer();
-	szNext = lpszDisplayName;
+	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));
+	} else {
+	    pidlTemp = _ILCreateMyComputer();
+	    /* it's a filesystem path, so we cant cut anything away */
+	    szNext = lpszDisplayName;
+	}
+
 
 	if (szNext && *szNext)
 	{
@@ -1810,10 +1804,11 @@
 	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
 	GUID		const * clsid;
 	IShellFolder	*pShellFolder, *pSubFolder;
+        IGenericSFImpl  *pSFImpl;
 	HRESULT         hr;
 
-	TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
-              This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
+	TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",
+              This,pidl,pbcReserved,shdebugstr_guid(riid),ppvOut);
 
 	*ppvOut = NULL;
 
@@ -1826,7 +1821,7 @@
 	  else
 	  {
 	     /* shell extension */
-	     if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
+	     if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->pidlRoot, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
 	     {
 	       return E_INVALIDARG;
 	     }
@@ -1839,19 +1834,19 @@
 	  IPersistFolder * ppf;
 
 	  /* combine pidls */
-	  SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
-	  firstpidl = ILCloneFirst(pidl);
-	  completepidl = ILCombine(deskpidl, firstpidl);
-
-	  pShellFolder = IShellFolder_Constructor(NULL, NULL);
-	  if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
-	  {
-	    IPersistFolder_Initialize(ppf, completepidl);
-	    IPersistFolder_Release(ppf);
+	  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);
+	    }
 	  }
-	  ILFree(completepidl);
-	  ILFree(deskpidl);
-	  ILFree(firstpidl);
 	}
 
 	if (_ILIsPidlSimple(pidl))	/* no sub folders */
@@ -1882,7 +1877,7 @@
 	LPSHELLVIEW	pShellView;
 	HRESULT		hr = E_INVALIDARG;
 
-	TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
+	TRACE("(%p)->(hwnd=0x%x,%s,%p)\n",This,hwndOwner,shdebugstr_guid(riid),ppvOut);
 
 	if(ppvOut)
 	{
@@ -1977,7 +1972,7 @@
 	  if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
 	    return E_OUTOFMEMORY;
 	}
-	strRet->uType = STRRET_CSTRA;
+	strRet->uType = STRRET_CSTR;
 	lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
 
 
@@ -2059,7 +2054,7 @@
 	{
 	  psd->fmt = DesktopSFHeader[iColumn].fmt;
 	  psd->cxChar = DesktopSFHeader[iColumn].cxChar;
-	  psd->str.uType = STRRET_CSTRA;
+	  psd->str.uType = STRRET_CSTR;
 	  LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
 	  return S_OK;
 	}
@@ -2085,7 +2080,7 @@
 	      break;
 	  }
 	  hr = S_OK;
-	  psd->str.uType = STRRET_CSTRA;
+	  psd->str.uType = STRRET_CSTR;
 	}
 
 	return hr;
@@ -2155,9 +2150,9 @@
 
 	ICOM_VTBL(sf)=&unkvt;
 	sf->lpvtblShellFolder=&sfmcvt;
-	sf->lpvtblPersistFolder2 = &psfvt;
-	sf->pclsid = (CLSID*)&CLSID_SFMyComp;
-	sf->absPidl=_ILCreateMyComputer();	/* my qualified pidl */
+	sf->lpvtblPersistFolder3 = &psfvt;
+	sf->pclsid = (CLSID*)&CLSID_MyComputer;
+	sf->pidlRoot=_ILCreateMyComputer();	/* my qualified pidl */
 	sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
 
 	TRACE("(%p)\n",sf);
@@ -2253,11 +2248,12 @@
 	_ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
 	GUID		const * clsid;
 	IShellFolder	*pShellFolder, *pSubFolder;
+        IGenericSFImpl  *pSFImpl;
 	LPITEMIDLIST	pidltemp;
 	HRESULT         hr;
 
-	TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
-              This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
+	TRACE("(%p)->(pidl=%p,%p,%s,%p)\n",
+              This,pidl,pbcReserved,shdebugstr_guid(riid),ppvOut);
 
 	if(!pidl || !ppvOut) return E_INVALIDARG;
 
@@ -2265,7 +2261,7 @@
 
 	if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
 	{
-	   if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
+	   if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->pidlRoot, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
 	   {
 	     return E_FAIL;
 	   }
@@ -2274,9 +2270,12 @@
 	{
 	  if (!_ILIsDrive(pidl)) return E_INVALIDARG;
 
-	  pidltemp = ILCloneFirst(pidl);
-	  pShellFolder = IShellFolder_Constructor(iface, pidltemp);
-	  ILFree(pidltemp);
+	  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 */
@@ -2308,7 +2307,7 @@
 	LPSHELLVIEW	pShellView;
 	HRESULT		hr = E_INVALIDARG;
 
-	TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
+	TRACE("(%p)->(hwnd=0x%x,%s,%p)\n",This,hwndOwner,shdebugstr_guid(riid),ppvOut);
 
 	if(ppvOut)
 	{
@@ -2436,7 +2435,7 @@
 	  if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
 	    return E_OUTOFMEMORY;
 	}
-	strRet->uType = STRRET_CSTRA;
+	strRet->uType = STRRET_CSTR;
 	lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
 
 
@@ -2520,7 +2519,7 @@
 	{
 	  psd->fmt = MyComputerSFHeader[iColumn].fmt;
 	  psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
-	  psd->str.uType = STRRET_CSTRA;
+	  psd->str.uType = STRRET_CSTR;
 	  LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
 	  return S_OK;
 	}
@@ -2530,7 +2529,7 @@
 	  ULARGE_INTEGER ulBytes;
 
 	  psd->str.u.cStr[0] = 0x00;
-	  psd->str.uType = STRRET_CSTRA;
+	  psd->str.uType = STRRET_CSTR;
 	  switch(iColumn)
 	  {
 	    case 0:	/* name */
@@ -2603,12 +2602,12 @@
  * ISFPersistFolder_QueryInterface (IUnknown)
  *
  */
-static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
-	IPersistFolder2 *	iface,
+static HRESULT WINAPI ISFPersistFolder3_QueryInterface(
+	IPersistFolder3 *	iface,
 	REFIID			iid,
 	LPVOID*			ppvObj)
 {
-	_ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
 
 	TRACE("(%p)\n", This);
 
@@ -2619,12 +2618,12 @@
  * ISFPersistFolder_AddRef (IUnknown)
  *
  */
-static ULONG WINAPI ISFPersistFolder2_AddRef(
-	IPersistFolder2 *	iface)
+static ULONG WINAPI ISFPersistFolder3_AddRef(
+	IPersistFolder3 *	iface)
 {
-	_ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
 
-	TRACE("(%p)\n", This);
+	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
 	return IUnknown_AddRef(This->pUnkOuter);
 }
@@ -2633,12 +2632,12 @@
  * ISFPersistFolder_Release (IUnknown)
  *
  */
-static ULONG WINAPI ISFPersistFolder2_Release(
-	IPersistFolder2 *	iface)
+static ULONG WINAPI ISFPersistFolder3_Release(
+	IPersistFolder3 *	iface)
 {
-	_ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
 
-	TRACE("(%p)\n", This);
+	TRACE("(%p)->(count=%lu)\n",This,This->ref);
 
 	return IUnknown_Release(This->pUnkOuter);
 }
@@ -2646,11 +2645,11 @@
 /************************************************************************
  * ISFPersistFolder_GetClassID (IPersist)
  */
-static HRESULT WINAPI ISFPersistFolder2_GetClassID(
-	IPersistFolder2 *	iface,
+static HRESULT WINAPI ISFPersistFolder3_GetClassID(
+	IPersistFolder3 *	iface,
 	CLSID *			lpClassId)
 {
-	_ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
 
 	TRACE("(%p)\n", This);
 
@@ -2664,71 +2663,110 @@
  * ISFPersistFolder_Initialize (IPersistFolder)
  *
  * NOTES
- *  sMyPath is not set. Don't know how to handle in a non rooted environment.
+ *  sPathRoot is not set. Don't know how to handle in a non rooted environment.
  */
-static HRESULT WINAPI ISFPersistFolder2_Initialize(
-	IPersistFolder2 *	iface,
+static HRESULT WINAPI ISFPersistFolder3_Initialize(
+	IPersistFolder3 *	iface,
 	LPCITEMIDLIST		pidl)
 {
 	char sTemp[MAX_PATH];
-	_ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
 
 	TRACE("(%p)->(%p)\n", This, pidl);
 
-	/* free the old stuff */
-	if(This->absPidl)
-	{
-	  SHFree(This->absPidl);
-	  This->absPidl = NULL;
-	}
-	if(This->sMyPath)
-	{
-	  SHFree(This->sMyPath);
-	  This->sMyPath = NULL;
-	}
+	if(This->pidlRoot) SHFree(This->pidlRoot);	/* free the old pidl */
+	This->pidlRoot = ILClone(pidl);			/* set my pidl */
 
-	/* set my pidl */
-	This->absPidl = ILClone(pidl);
+	if(This->sPathRoot) SHFree(This->sPathRoot);
 
 	/* set my path */
 	if (SHGetPathFromIDListA(pidl, sTemp))
 	{
-	  This->sMyPath = SHAlloc(strlen(sTemp)+1);
-	  strcpy(This->sMyPath, sTemp);
+	  This->sPathRoot = SHAlloc(strlen(sTemp)+1);
+	  strcpy(This->sPathRoot, sTemp);
 	}
 
-	TRACE("--(%p)->(%s)\n", This, This->sMyPath);
-
+	TRACE("--(%p)->(%s)\n", This, This->sPathRoot);
 	return S_OK;
 }
 
 /**************************************************************************
 *  IPersistFolder2_fnGetCurFolder
 */
-static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
-	IPersistFolder2 *	iface,
+static HRESULT WINAPI ISFPersistFolder3_fnGetCurFolder(
+	IPersistFolder3 *	iface,
 	LPITEMIDLIST * pidl)
 {
-	_ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+	_ICOM_THIS_From_IPersistFolder3(IGenericSFImpl, iface);
 
 	TRACE("(%p)->(%p)\n",This, pidl);
 
 	if (!pidl) return E_POINTER;
 
-	*pidl = ILClone(This->absPidl);
+	*pidl = ILClone(This->pidlRoot);
 
 	return S_OK;
 }
 
-static ICOM_VTABLE(IPersistFolder2) psfvt =
+static HRESULT WINAPI ISFPersistFolder3_InitializeEx(
+	IPersistFolder3 *	iface,
+	IBindCtx *		pbc,
+	LPCITEMIDLIST		pidlRoot,
+	const PERSIST_FOLDER_TARGET_INFO *ppfti)
+{
+	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);
+
+	pdump(pidlRoot);
+	if(ppfti->pidlTargetFolder) pdump(ppfti->pidlTargetFolder);
+
+	if(This->pidlRoot) SHFree(This->pidlRoot);	/* free the old pidl */
+
+	if(ppfti->csidl == -1) {			/* set my pidl */
+	    This->pidlRoot = ILClone(ppfti->pidlTargetFolder);
+	} else {
+	    SHGetSpecialFolderLocation(0, ppfti->csidl, &This->pidlRoot);
+	}
+
+	if(This->sPathRoot) SHFree(This->sPathRoot);
+
+	/* set my path */
+	if (SHGetPathFromIDListA(This->pidlRoot, sTemp))
+	{
+	  This->sPathRoot = SHAlloc(strlen(sTemp)+1);
+	  strcpy(This->sPathRoot, sTemp);
+	}
+
+	TRACE("--(%p)->(%s)\n", This, This->sPathRoot);
+	return S_OK;
+}
+
+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;
+}
+
+static ICOM_VTABLE(IPersistFolder3) psfvt =
 {
 	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	ISFPersistFolder2_QueryInterface,
-	ISFPersistFolder2_AddRef,
-	ISFPersistFolder2_Release,
-	ISFPersistFolder2_GetClassID,
-	ISFPersistFolder2_Initialize,
-	ISFPersistFolder2_fnGetCurFolder
+	ISFPersistFolder3_QueryInterface,
+	ISFPersistFolder3_AddRef,
+	ISFPersistFolder3_Release,
+	ISFPersistFolder3_GetClassID,
+	ISFPersistFolder3_Initialize,
+	ISFPersistFolder3_fnGetCurFolder,
+	ISFPersistFolder3_InitializeEx,
+	ISFPersistFolder3_GetFolderTargetInfo
 };
 
 /****************************************************************************
@@ -2864,3 +2902,16 @@
 	ISFDropTarget_DragLeave,
  	ISFDropTarget_Drop
 };
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: wine/dlls/shell32/undocshell.h
===================================================================
RCS file: /home/wine/wine/dlls/shell32/undocshell.h,v
retrieving revision 1.6
diff -d -u -r1.6 undocshell.h
--- wine/dlls/shell32/undocshell.h	31 May 2002 23:25:52 -0000	1.6
+++ wine/dlls/shell32/undocshell.h	27 Jun 2002 09:51:30 -0000
@@ -858,6 +858,9 @@
 	LPDWORD lpdwUsage,
 	REFIID riidObject);
 
+DWORD WINAPI SHCLSIDFromStringA (LPCSTR clsid, CLSID *id);
+DWORD WINAPI SHCLSIDFromStringW (LPWSTR clsid, CLSID *id);
+
 HRESULT WINAPI SHCoCreateInstance(
 	LPCSTR lpszClsid,
 	REFCLSID rClsid,
@@ -906,3 +909,4 @@
 #endif /* defined(__cplusplus) */
 
 #endif /* __WINE_UNDOCSHELL_H */
+
Index: wine/include/wine/obj_shellfolder.h
===================================================================
RCS file: /home/wine/wine/include/wine/obj_shellfolder.h,v
retrieving revision 1.12
diff -d -u -r1.12 obj_shellfolder.h
--- wine/include/wine/obj_shellfolder.h	31 May 2002 23:06:51 -0000	1.12
+++ wine/include/wine/obj_shellfolder.h	27 Jun 2002 09:52:04 -0000
@@ -31,24 +31,15 @@
 *  STRRET
 */
 #define	STRRET_WSTR	0x0000
-#define STRRET_ASTR	0x0003
-
-#define	STRRET_OFFSETA	0x0001
-#define STRRET_OFFSETW	0x0004
-#define STRRET_OFFSET WINELIB_NAME_AW(STRRET_OFFSET)
-
-#define	STRRET_CSTRA	0x0002
-#define STRRET_CSTRW	0x0005
-#define STRRET_CSTR WINELIB_NAME_AW(STRRET_CSTR)
+#define	STRRET_OFFSET	0x0001
+#define	STRRET_CSTR	0x0002
 
-typedef struct _STRRET
-{ UINT uType;		/* STRRET_xxx */
-  union
-  { LPWSTR	pOleStr;	/* OLESTR that will be freed */
-    LPSTR	pStr;
-    UINT	uOffset;	/* OffsetINT32o SHITEMID (ANSI) */
-    char	cStr[MAX_PATH];	/* Buffer to fill in */
-    WCHAR	cStrW[MAX_PATH];
+typedef struct _STRRET {
+  UINT uType;			/* STRRET_xxx */
+  union {
+    LPWSTR	pOleStr;	/* OLESTR that will be freed */
+    UINT	uOffset;	/* Offset into SHITEMID (ANSI) */
+    char	cStr[MAX_PATH];	/* ANSI Buffer */
   } DUMMYUNIONNAME;
 } STRRET,*LPSTRRET;
 
@@ -62,6 +53,9 @@
 DEFINE_GUID(IID_IPersistFolder2, 0x1ac3d9f0L, 0x175C, 0x11D1, 0x95, 0xBE, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x4F);
 typedef struct IPersistFolder2 IPersistFolder2, *LPPERSISTFOLDER2;
 
+DEFINE_GUID(IID_IPersistFolder3, 0xcef04fdf, 0xfe72, 0x11d2, 0x87, 0xa5, 0x0, 0xc0, 0x4f, 0x68, 0x37, 0xcf);
+typedef struct IPersistFolder3 IPersistFolder3, *LPPERSISTFOLDER3;
+
 DEFINE_GUID(IID_IShellFolder2,  0xB82C5AA8, 0xA41B, 0x11D2, 0xBE, 0x32, 0x0, 0xc0, 0x4F, 0xB9, 0x36, 0x61);
 typedef struct IShellFolder2 IShellFolder2, *LPSHELLFOLDER2;
 
@@ -317,11 +311,6 @@
  * IPersistFolder interface
  */
 
-/* ClassID's */
-DEFINE_GUID (CLSID_SFMyComp,0x20D04FE0,0x3AEA,0x1069,0xA2,0xD8,0x08,0x00,0x2B,0x30,0x30,0x9D);
-DEFINE_GUID (CLSID_SFINet,  0x871C5380,0x42A0,0x1069,0xA2,0xEA,0x08,0x00,0x2B,0x30,0x30,0x9D);
-DEFINE_GUID (CLSID_SFFile,  0xF3364BA0,0x65B9,0x11CE,0xA9,0xBA,0x00,0xAA,0x00,0x4A,0xE8,0x37);
-
 #define ICOM_INTERFACE IPersistFolder
 #define IPersistFolder_METHODS \
     ICOM_METHOD1( HRESULT, Initialize, LPCITEMIDLIST, pidl)
@@ -365,8 +354,53 @@
 /*** IPersistFolder2 methods ***/
 #define IPersistFolder2_GetCurFolder(p,a)	ICOM_CALL1(GetCurFolder,p,a)
 
+
+/*****************************************************************************
+ * IPersistFolder3 interface
+ */
+
+typedef struct {
+	LPITEMIDLIST	pidlTargetFolder;
+	WCHAR		szTargetParsingName[MAX_PATH];
+	WCHAR		szNetworkProvider[MAX_PATH];
+	DWORD		dwAttributes;
+	int		csidl;
+} PERSIST_FOLDER_TARGET_INFO;
+
+#define ICOM_INTERFACE IPersistFolder3
+#define IPersistFolder3_METHODS \
+    ICOM_METHOD3( HRESULT, InitializeEx, IBindCtx*, pbc, LPCITEMIDLIST, pidlRoot, const PERSIST_FOLDER_TARGET_INFO*, ppfti)\
+    ICOM_METHOD1( HRESULT, GetFolderTargetInfo, PERSIST_FOLDER_TARGET_INFO*, ppfti)
+#define IPersistFolder3_IMETHODS \
+    IPersist_IMETHODS \
+    IPersistFolder_METHODS \
+    IPersistFolder2_METHODS \
+    IPersistFolder3_METHODS
+ICOM_DEFINE(IPersistFolder3, IPersistFolder2)
+#undef ICOM_INTERFACE
+
+/*** IUnknown methods ***/
+#define IPersistFolder3_QueryInterface(p,a,b)	ICOM_CALL2(QueryInterface,p,a,b)
+#define IPersistFolder3_AddRef(p)		ICOM_CALL (AddRef,p)
+#define IPersistFolder3_Release(p)		ICOM_CALL (Release,p)
+/*** IPersist methods ***/
+#define IPersistFolder3_GetClassID(p,a)		ICOM_CALL1(GetClassID,p,a)
+/*** IPersistFolder methods ***/
+#define IPersistFolder3_Initialize(p,a)		ICOM_CALL1(Initialize,p,a)
+/*** IPersistFolder2 methods ***/
+#define IPersistFolder3_GetCurFolder(p,a)	ICOM_CALL1(GetCurFolder,p,a)
+/*** IPersistFolder3 methods ***/
+#define IPersistFolder3_InitializeEx(p,a,b,c)	ICOM_CALL3(InitializeEx,p,a,b,c)
+#define IPersistFolder3_GetFolderTargetInfo(p,a) ICOM_CALL1(InitializeEx,p,a)
+
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
 
 #endif /* __WINE_WINE_OBJ_SHELLFOLDER_H */
+
+
+
+
+



More information about the wine-patches mailing list