- 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
diff --git a/dlls/commdlg/filedlg95.c b/dlls/commdlg/filedlg95.c
index 591aebc..566d981 100644
--- a/dlls/commdlg/filedlg95.c
+++ b/dlls/commdlg/filedlg95.c
@@ -1046,18 +1046,18 @@
/* Initialise the file name edit control */
handledPath = FALSE;
TRACE("Before manipilation, file = '%s', dir = '%s'\n", fodInfos->ofnInfos->lpstrFile, fodInfos->ofnInfos->lpstrInitialDir);
-
+
if(fodInfos->ofnInfos->lpstrFile)
{
/* 1. If win2000 or higher and filename contains a path, use it
in preference over the lpstrInitialDir */
- if (win2000plus && *fodInfos->ofnInfos->lpstrFile &&
+ if (win2000plus && *fodInfos->ofnInfos->lpstrFile &&
strstr(fodInfos->ofnInfos->lpstrFile, "\\")) {
char tmpBuf[MAX_PATH];
char *nameBit;
DWORD result;
- result = GetFullPathNameA(fodInfos->ofnInfos->lpstrFile, MAX_PATH,
+ result = GetFullPathNameA(fodInfos->ofnInfos->lpstrFile, MAX_PATH,
tmpBuf, &nameBit);
if (result) {
strcpy(fodInfos->ofnInfos->lpstrFile, (LPSTR)nameBit);
@@ -1071,7 +1071,7 @@
strcpy((LPSTR)fodInfos->ofnInfos->lpstrInitialDir, tmpBuf);
}
handledPath = TRUE;
- TRACE("Value in lpstrFile includes path, overriding lpstrInitialDir: %s, %s\n",
+ TRACE("Value in lpstrFile includes path, overriding lpstrInitialDir: %s, %s\n",
fodInfos->ofnInfos->lpstrFile, fodInfos->ofnInfos->lpstrInitialDir);
}
SetDlgItemTextA(hwnd, IDC_FILENAME, fodInfos->ofnInfos->lpstrFile);
@@ -1113,13 +1113,13 @@
{
/* 3. All except w2k+: if filename contains a path use it */
if (!win2000plus && fodInfos->ofnInfos->lpstrFile &&
- *fodInfos->ofnInfos->lpstrFile &&
+ *fodInfos->ofnInfos->lpstrFile &&
strstr(fodInfos->ofnInfos->lpstrFile, "\\")) {
char tmpBuf[MAX_PATH];
char *nameBit;
DWORD result;
- result = GetFullPathNameA(fodInfos->ofnInfos->lpstrFile, MAX_PATH,
+ result = GetFullPathNameA(fodInfos->ofnInfos->lpstrFile, MAX_PATH,
tmpBuf, &nameBit);
if (result) {
strcpy(fodInfos->ofnInfos->lpstrFile, nameBit);
@@ -1133,7 +1133,7 @@
strcpy((LPSTR)fodInfos->ofnInfos->lpstrInitialDir, tmpBuf);
}
handledPath = TRUE;
- TRACE("Value in lpstrFile includes path, overriding lpstrInitialDir: %s, %s\n",
+ TRACE("Value in lpstrFile includes path, overriding lpstrInitialDir: %s, %s\n",
fodInfos->ofnInfos->lpstrFile, fodInfos->ofnInfos->lpstrInitialDir);
}
SetDlgItemTextA(hwnd, IDC_FILENAME, fodInfos->ofnInfos->lpstrFile);
@@ -1141,8 +1141,8 @@
/* 4. win98+ and win2000+ if any files of specified filter types in
current directory, use it */
- if ( win98plus && handledPath == FALSE &&
- fodInfos->ofnInfos->lpstrFilter &&
+ if ( win98plus && handledPath == FALSE &&
+ fodInfos->ofnInfos->lpstrFilter &&
*fodInfos->ofnInfos->lpstrFilter) {
BOOL searchMore = TRUE;
@@ -1150,7 +1150,7 @@
WIN32_FIND_DATAA FindFileData;
HANDLE hFind;
- while (searchMore)
+ while (searchMore)
{
/* filter is a list... title\0ext\0......\0\0 */
@@ -1169,7 +1169,7 @@
} else {
searchMore = FALSE;
-
+
initDir = MemAlloc(MAX_PATH);
GetCurrentDirectoryA(MAX_PATH, initDir);
fodInfos->ofnInfos->lpstrInitialDir = initDir;
@@ -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,3 @@
HeapFree(GetProcessHeap(),0,mem);
}
}
-
diff --git a/dlls/commdlg/filedlgbrowser.c b/dlls/commdlg/filedlgbrowser.c
index f48965f..8399c0f 100644
--- a/dlls/commdlg/filedlgbrowser.c
+++ b/dlls/commdlg/filedlgbrowser.c
@@ -111,12 +111,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,
@@ -212,7 +212,7 @@
{
ICOM_THIS(IShellBrowserImpl, iface);
- TRACE("(%p)\n", This);
+ TRACE("(%p,%lu)\n", This, This->ref);
return ++(This->ref);
}
@@ -224,11 +224,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;
@@ -906,9 +907,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!
diff --git a/dlls/shell32/clipboard.c b/dlls/shell32/clipboard.c
index ad74178..f039a17 100644
--- a/dlls/shell32/clipboard.c
+++ b/dlls/shell32/clipboard.c
@@ -47,40 +47,23 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-static int refClipCount = 0;
-static HINSTANCE hShellOle32 = 0;
+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);
/**************************************************************************
- * InitShellOle
- *
- *
- */
-void InitShellOle(void)
-{
-}
-
-/**************************************************************************
- * FreeShellOle
- *
- * unload OLE32.DLL
- */
-void FreeShellOle(void)
-{
- if (!--refClipCount)
- {
- pOleUninitialize();
- FreeLibrary(hShellOle32);
- }
-}
-
-/**************************************************************************
- * 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;
diff --git a/dlls/shell32/debughlp.c b/dlls/shell32/debughlp.c
index bdb33ed..350b928 100644
--- a/dlls/shell32/debughlp.c
+++ b/dlls/shell32/debughlp.c
@@ -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,54 @@
}
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;
+}
diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c
index 8ff062b..61279aa 100644
--- a/dlls/shell32/pidl.c
+++ b/dlls/shell32/pidl.c
@@ -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;
}
diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c
index 75adf2e..7a7f9ec 100644
--- a/dlls/shell32/shell32_main.c
+++ b/dlls/shell32/shell32_main.c
@@ -996,12 +996,6 @@
case DLL_PROCESS_DETACH:
shell32_hInstance = 0;
- if (pdesktopfolder)
- {
- IShellFolder_Release(pdesktopfolder);
- pdesktopfolder = NULL;
- }
-
SIC_Destroy();
FreeChangeNotifications();
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index 0e03fc8..ada04a3 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -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);
diff --git a/dlls/shell32/shelllink.c b/dlls/shell32/shelllink.c
index 1689e49..263b238 100644
--- a/dlls/shell32/shelllink.c
+++ b/dlls/shell32/shelllink.c
@@ -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;
- sl = (IShellLinkImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellLinkImpl));
+ 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->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,3 @@
IShellLinkW_fnResolve,
IShellLinkW_fnSetPath
};
-
diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c
index eec9f06..960f48a 100644
--- a/dlls/shell32/shellole.c
+++ b/dlls/shell32/shellole.c
@@ -35,17 +35,58 @@
#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}
+};
+
+/*************************************************************************
+ * __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]
@@ -53,17 +94,48 @@
* 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);
- }
- else
- {
- CoInitialize(NULL);
- hres = CoCreateInstance(myclsid, unknownouter, CLSCTX_INPROC_SERVER, 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;
}
+ 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 );
+ /* 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);
+ }
+ }
- if(lpclf)
- {
- hres = IClassFactory_QueryInterface(lpclf,iid, ppv);
- IClassFactory_Release(lpclf);
- }
+ if (!pcf) {
+ FIXME("failed for CLSID=%s\n", debugstr_guid(rclsid));
+ return CLASS_E_CLASSNOTAVAILABLE;
}
- else
- {
- WARN("-- CLSID not found\n");
- hres = CLASS_E_CLASSNOTAVAILABLE;
- }
+
+ hres = IClassFactory_QueryInterface(pcf, iid, ppv);
+ IClassFactory_Release(pcf);
+
TRACE("-- pointer to class factory: %p\n",*ppv);
return hres;
}
@@ -153,206 +283,216 @@
}
/*************************************************************************
+ * Shell Memory Allocator
+ */
+
+/* set the vtable later */
+extern ICOM_VTABLE(IMalloc) VT_Shell_IMalloc32;
+
+/* this is the static object instance */
+typedef struct {
+ ICOM_VFIELD(IMalloc);
+ DWORD dummy;
+} _ShellMalloc;
+
+_ShellMalloc Shell_Malloc = { &VT_Shell_IMalloc32,1};
+
+/* this is the global allocator of shell32 */
+IMalloc * ShellTaskAllocator = NULL;
+
+/******************************************************************************
+ * IShellMalloc_QueryInterface [VTABLE]
+ */
+static HRESULT WINAPI IShellMalloc_fnQueryInterface(LPMALLOC iface, REFIID refiid, LPVOID *obj)
+{
+ TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
+
+ if (IsEqualIID(refiid, &IID_IUnknown) || IsEqualIID(refiid, &IID_IMalloc)) {
+ *obj = (LPMALLOC) &Shell_Malloc;
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+/******************************************************************************
+ * IShellMalloc_AddRefRelease [VTABLE]
+ */
+static ULONG WINAPI IShellMalloc_fnAddRefRelease(LPMALLOC iface)
+{
+ return 1;
+}
+
+/******************************************************************************
+ * IShellMalloc_Alloc [VTABLE]
+ */
+static LPVOID WINAPI IShellMalloc_fnAlloc(LPMALLOC iface, DWORD cb)
+{
+ LPVOID addr;
+
+ addr = (LPVOID) LocalAlloc(GMEM_ZEROINIT, cb);
+ TRACE("(%p,%ld);\n",addr,cb);
+ return addr;
+}
+
+/******************************************************************************
+ * IShellMalloc_Realloc [VTABLE]
+ */
+static LPVOID WINAPI IShellMalloc_fnRealloc(LPMALLOC iface, LPVOID pv, DWORD cb)
+{
+ LPVOID addr;
+
+ 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;
+ }
+ }
+
+ TRACE("(%p->%p,%ld)\n",pv,addr,cb);
+ return addr;
+}
+
+/******************************************************************************
+ * IShellMalloc_Free [VTABLE]
+ */
+static VOID WINAPI IShellMalloc_fnFree(LPMALLOC iface, LPVOID pv)
+{
+ TRACE("(%p)\n",pv);
+ LocalFree((HANDLE) pv);
+}
+
+/******************************************************************************
+ * IShellMalloc_GetSize [VTABLE]
+ */
+static DWORD WINAPI IShellMalloc_fnGetSize(LPMALLOC iface, LPVOID pv)
+{
+ DWORD cb = (DWORD) LocalSize((HANDLE)pv);
+ TRACE("(%p,%ld)\n", pv, cb);
+ return cb;
+}
+
+/******************************************************************************
+ * IShellMalloc_DidAlloc [VTABLE]
+ */
+static INT WINAPI IShellMalloc_fnDidAlloc(LPMALLOC iface, LPVOID pv)
+{
+ TRACE("(%p)\n",pv);
+ return -1;
+}
+
+/******************************************************************************
+ * IShellMalloc_HeapMinimize [VTABLE]
+ */
+static VOID WINAPI IShellMalloc_fnHeapMinimize(LPMALLOC iface)
+{
+ TRACE("()\n");
+}
+
+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
+};
+
+/*************************************************************************
* 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).
+ * 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;
+
TRACE("(%p)\n", lpmal);
- return CoGetMalloc(MEMCTX_TASK, lpmal);
+
+ if (!ShellTaskAllocator)
+ {
+ 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;
+}
+
+/*************************************************************************
+ * SHAlloc [SHELL32.196]
+ *
+ * NOTES
+ * exported by ordinal
+ */
+LPVOID WINAPI SHAlloc(DWORD len)
+{
+ IMalloc * ppv;
+ LPBYTE ret;
+
+ 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;
+}
+
+/*************************************************************************
+ * SHFree [SHELL32.195]
+ *
+ * NOTES
+ * exported by ordinal
+ */
+void WINAPI SHFree(LPVOID pv)
+{
+ IMalloc * ppv;
+
+ TRACE("%p\n",pv);
+ if (!ShellTaskAllocator) SHGetMalloc(&ppv);
+ IMalloc_Free(ShellTaskAllocator, pv);
}
/*************************************************************************
* SHGetDesktopFolder [SHELL32.@]
*/
-LPSHELLFOLDER pdesktopfolder=NULL;
-
DWORD WINAPI SHGetDesktopFolder(IShellFolder **psf)
{
HRESULT hres = S_OK;
- LPCLASSFACTORY lpclf;
TRACE("%p->(%p)\n",psf,*psf);
- *psf=NULL;
-
- if (!pdesktopfolder)
- {
- lpclf = IClassFactory_Constructor(&CLSID_ShellDesktop);
- if(lpclf)
- {
- hres = IClassFactory_CreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
- IClassFactory_Release(lpclf);
- }
- }
-
- if (pdesktopfolder)
- {
- /* even if we create the folder, add a ref so the application can´t destroy the folder*/
- IShellFolder_AddRef(pdesktopfolder);
- *psf = pdesktopfolder;
- }
+ if(!psf) return E_INVALIDARG;
+ *psf = NULL;
+ hres = ISF_Desktop_Constructor(NULL, &IID_IShellFolder,(LPVOID*)psf);
TRACE("-- %p->(%p)\n",psf, *psf);
return hres;
}
/**************************************************************************
-* IClassFactory Implementation
-*/
-
-typedef struct
-{
- /* IUnknown fields */
- ICOM_VFIELD(IClassFactory);
- DWORD ref;
- CLSID *rclsid;
-} IClassFactoryImpl;
-
-static ICOM_VTABLE(IClassFactory) clfvt;
-
-/**************************************************************************
- * IClassFactory_Constructor
- */
-
-LPCLASSFACTORY IClassFactory_Constructor(REFCLSID rclsid)
-{
- IClassFactoryImpl* lpclf;
-
- lpclf= (IClassFactoryImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl));
- lpclf->ref = 1;
- ICOM_VTBL(lpclf) = &clfvt;
- lpclf->rclsid = (CLSID*)rclsid;
-
- TRACE("(%p)->()\n",lpclf);
- InterlockedIncrement(&shell32_ObjCount);
- return (LPCLASSFACTORY)lpclf;
-}
-/**************************************************************************
- * IClassFactory_QueryInterface
- */
-static HRESULT WINAPI IClassFactory_fnQueryInterface(
- LPCLASSFACTORY iface, REFIID riid, LPVOID *ppvObj)
-{
- ICOM_THIS(IClassFactoryImpl,iface);
- TRACE("(%p)->(\n\tIID:\t%s)\n",This,debugstr_guid(riid));
-
- *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);
- return S_OK;
- }
- TRACE("-- Interface: %s E_NOINTERFACE\n", debugstr_guid(riid));
- return E_NOINTERFACE;
-}
-/******************************************************************************
- * IClassFactory_AddRef
- */
-static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface)
-{
- ICOM_THIS(IClassFactoryImpl,iface);
- TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
- InterlockedIncrement(&shell32_ObjCount);
- return InterlockedIncrement(&This->ref);
-}
-/******************************************************************************
- * IClassFactory_Release
- */
-static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface)
-{
- 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;
-}
-/******************************************************************************
- * IClassFactory_CreateInstance
- */
-static HRESULT WINAPI IClassFactory_fnCreateInstance(
- LPCLASSFACTORY iface, LPUNKNOWN pUnknown, REFIID riid, LPVOID *ppObject)
-{
- ICOM_THIS(IClassFactoryImpl,iface);
- IUnknown *pObj = NULL;
- HRESULT hres;
-
- TRACE("%p->(%p,\n\tIID:\t%s,%p)\n",This,pUnknown,debugstr_guid(riid),ppObject);
-
- *ppObject = NULL;
-
- if(pUnknown)
- {
- return(CLASS_E_NOAGGREGATION);
- }
-
- 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);
- }
-
- if (!pObj)
- {
- return(E_OUTOFMEMORY);
- }
-
- hres = IUnknown_QueryInterface(pObj,riid, ppObject);
- IUnknown_Release(pObj);
-
- TRACE("-- Object created: (%p)->%p\n",This,*ppObject);
-
- return hres;
-}
-/******************************************************************************
- * IClassFactory_LockServer
- */
-static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
-{
- ICOM_THIS(IClassFactoryImpl,iface);
- TRACE("%p->(0x%x), not implemented\n",This, fLock);
- return E_NOTIMPL;
-}
-
-static ICOM_VTABLE(IClassFactory) clfvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- IClassFactory_fnQueryInterface,
- IClassFactory_fnAddRef,
- IClassFactory_fnRelease,
- IClassFactory_fnCreateInstance,
- IClassFactory_fnLockServer
-};
-
-/**************************************************************************
* Default ClassFactory Implementation
*
* SHCreateDefClassObject
@@ -362,7 +502,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 +533,6 @@
lpclf->riidInst = riidInst;
TRACE("(%p)\n\tIID:\t%s\n",lpclf, debugstr_guid(riidInst));
- InterlockedIncrement(&shell32_ObjCount);
return (LPCLASSFACTORY)lpclf;
}
/**************************************************************************
@@ -409,19 +547,13 @@
*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;
}
/******************************************************************************
@@ -432,7 +564,6 @@
ICOM_THIS(IDefClFImpl,iface);
TRACE("(%p)->(count=%lu)\n",This,This->ref);
- InterlockedIncrement(&shell32_ObjCount);
return InterlockedIncrement(&This->ref);
}
/******************************************************************************
@@ -443,8 +574,6 @@
ICOM_THIS(IDefClFImpl,iface);
TRACE("(%p)->(count=%lu)\n",This,This->ref);
- InterlockedDecrement(&shell32_ObjCount);
-
if (!InterlockedDecrement(&This->ref))
{
if (This->pcRefDll) InterlockedDecrement(This->pcRefDll);
@@ -467,9 +596,6 @@
*ppvObject = NULL;
- if(pUnkOuter)
- return(CLASS_E_NOAGGREGATION);
-
if ( This->riidInst==NULL ||
IsEqualCLSID(riid, This->riidInst) ||
IsEqualCLSID(riid, &IID_IUnknown) )
@@ -510,20 +636,15 @@
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;
}
/*************************************************************************
@@ -649,7 +770,7 @@
if(lpDropFileStruct->fWide == FALSE) {
LPSTR lpszFileA = NULL;
-
+
if(lpszwFile) {
lpszFileA = (LPSTR) HeapAlloc(GetProcessHeap(), 0, lLength);
if(lpszFileA == NULL) {
diff --git a/dlls/shell32/shellord.c b/dlls/shell32/shellord.c
index bdb8481..c636f33 100644
--- a/dlls/shell32/shellord.c
+++ b/dlls/shell32/shellord.c
@@ -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
diff --git a/dlls/shell32/shellstring.c b/dlls/shell32/shellstring.c
index c1e622a..8f7e6d4 100644
--- a/dlls/shell32/shellstring.c
+++ b/dlls/shell32/shellstring.c
@@ -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,
diff --git a/dlls/shell32/shlfolder.c b/dlls/shell32/shlfolder.c
index a7086b9..afdc544 100644
--- a/dlls/shell32/shlfolder.c
+++ b/dlls/shell32/shlfolder.c
@@ -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;
+ IGenericSFImpl * sf;
- TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
+ TRACE("unkOut=%p %s\n",pUnkOuter, shdebugstr_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;
+ if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown)) return CLASS_E_NOAGGREGATION;
+ sf=(IGenericSFImpl*) LocalAlloc(GMEM_ZEROINIT,sizeof(IGenericSFImpl));
+ if (!sf) return E_OUTOFMEMORY;
- 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;
+ 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);
+
+ /* we have to return the inner IUnknown */
+ *ppv = _IUnknown_(sf);
+
+ shell32_ObjCount++;
+ TRACE("--%p\n", *ppv);
+ return S_OK;
}
+
+/**************************************************************************
+* 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->pidlRoot = ILCombine(pidlRoot, pidlFolder);
+ if (!_ILIsSpecialFolder(pidlFolder)) { /* only file system paths */
+ char sNewPath[MAX_PATH];
+ char * sPos;
+
+ 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;
+}
+
/**************************************************************************
* IShellFolder_Constructor
-*
-* NOTES
-* THIS points to the parent folder
*/
-
-IShellFolder * IShellFolder_Constructor(
- IShellFolder2 * iface,
- LPITEMIDLIST pidl)
+IGenericSFImpl * IShellFolder_Constructor()
{
- IGenericSFImpl * sf;
- DWORD dwSize=0;
-
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
+ IGenericSFImpl * sf=(IGenericSFImpl*) LocalAlloc(GMEM_ZEROINIT,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_SFFile;
+ sf->pclsid = (CLSID*)&CLSID_ShellFSFolder;
sf->pUnkOuter = _IUnknown_(sf);
- TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
- pdump(pidl);
-
- if(pidl && iface) /* do we have a pidl? */
- {
- int len;
-
- sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
-
- if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
- {
- if(This->sMyPath) /* get the size of the parents path */
- {
- dwSize += strlen(This->sMyPath) ;
- TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
- }
-
- dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
- sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
-
- if(!sf->sMyPath) return NULL;
- *(sf->sMyPath)=0x00;
-
- if(This->sMyPath) /* if the parent has a path, get it*/
- {
- strcpy(sf->sMyPath, This->sMyPath);
- PathAddBackslashA (sf->sMyPath);
- }
-
- len = strlen(sf->sMyPath);
- _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
- }
-
- TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
-
- pdump (sf->absPidl);
- }
+ 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
};
/****************************************************************************
diff --git a/dlls/shell32/undocshell.h b/dlls/shell32/undocshell.h
index 38ccc1e..227c208 100644
--- a/dlls/shell32/undocshell.h
+++ b/dlls/shell32/undocshell.h
@@ -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,
diff --git a/include/wine/obj_shellfolder.h b/include/wine/obj_shellfolder.h
index def4a9c..faa3e14 100644
--- a/include/wine/obj_shellfolder.h
+++ b/include/wine/obj_shellfolder.h
@@ -31,24 +31,15 @@
* STRRET
*/
#define STRRET_WSTR 0x0000
-#define STRRET_ASTR 0x0003
+#define STRRET_OFFSET 0x0001
+#define STRRET_CSTR 0x0002
-#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)
-
-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,6 +354,46 @@
/*** 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) */