- 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
This commit is contained in:
Juergen Schmied 2002-07-02 02:05:17 +00:00 committed by Alexandre Julliard
parent 17a2fe0f71
commit 23b808791e
14 changed files with 849 additions and 668 deletions

View File

@ -1046,18 +1046,18 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
/* 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 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
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 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
{
/* 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 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
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 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
/* 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 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
WIN32_FIND_DATAA FindFileData;
HANDLE hFind;
while (searchMore)
while (searchMore)
{
/* filter is a list... title\0ext\0......\0\0 */
@ -1169,7 +1169,7 @@ static LRESULT FILEDLG95_InitControls(HWND hwnd)
} else {
searchMore = FALSE;
initDir = MemAlloc(MAX_PATH);
GetCurrentDirectoryA(MAX_PATH, initDir);
fodInfos->ofnInfos->lpstrInitialDir = initDir;
@ -2680,11 +2680,11 @@ static HRESULT COMDLG32_StrRetToStrNA (LPVOID dest, DWORD len, LPSTRRET src, LPI
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 @@ LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl)
* 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 @@ LPITEMIDLIST GetPidlFromName(IShellFolder *lpsf,LPCSTR lpcstrFileName)
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 @@ static void MemFree(void *mem)
HeapFree(GetProcessHeap(),0,mem);
}
}

View File

@ -111,12 +111,12 @@ static HRESULT COMDLG32_StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, LPI
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 @@ ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
{
ICOM_THIS(IShellBrowserImpl, iface);
TRACE("(%p)\n", This);
TRACE("(%p,%lu)\n", This, This->ref);
return ++(This->ref);
}
@ -224,11 +224,12 @@ ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
{
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 @@ ULONG WINAPI IShellBrowserImpl_IServiceProvider_Release(IServiceProvider * iface
* 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!

View File

@ -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 @@ BOOL GetShellOle(void)
pOleGetClipboard=(void*)GetProcAddress(hShellOle32,"OleGetClipboard");
pOleInitialize(NULL);
refClipCount++;
}
}
return TRUE;

View File

@ -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 @@ BOOL pcheck (LPCITEMIDLIST pidl)
}
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;
}

View File

@ -1162,7 +1162,11 @@ LPITEMIDLIST _ILCreateSpecial(LPCSTR szGUID)
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 @@ LPITEMIDLIST _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT uInSize)
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 @@ LPITEMIDLIST _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT uInSize)
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 @@ LPITEMIDLIST _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT uInSize)
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;
}

View File

@ -996,12 +996,6 @@ BOOL WINAPI Shell32LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
case DLL_PROCESS_DETACH:
shell32_hInstance = 0;
if (pdesktopfolder)
{
IShellFolder_Release(pdesktopfolder);
pdesktopfolder = NULL;
}
SIC_Destroy();
FreeChangeNotifications();

View File

@ -65,14 +65,7 @@ extern INT (WINAPI *pFindMRUData) (HANDLE hList, LPCVOID lpData, DWORD cbDa
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 @@ LPCLASSFACTORY IClassFactory_Constructor(REFCLSID);
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 @@ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uI
/* 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);

View File

@ -958,10 +958,21 @@ static ICOM_VTABLE(IPersistStream) psvt =
/**************************************************************************
* 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 @@ IShellLinkA * IShellLink_Constructor(BOOL bUnicode)
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 @@ static ULONG WINAPI IShellLinkA_fnRelease(IShellLinkA * iface)
This->iIcoNdx = 0;
HeapFree(GetProcessHeap(),0,This);
LocalFree((HANDLE)This);
return 0;
}
return This->ref;
@ -1538,4 +1560,3 @@ static ICOM_VTABLE(IShellLinkW) slvtw =
IShellLinkW_fnResolve,
IShellLinkW_fnSetPath
};

View File

@ -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 @@ extern HRESULT IFSFolder_Constructor(
* 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 @@ LRESULT WINAPI SHCoCreateInstance(
}
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 @@ LRESULT WINAPI SHCoCreateInstance(
/*************************************************************************
* 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);
}
}
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;
}
@ -152,206 +282,216 @@ DWORD WINAPI SHCLSIDFromStringAW (LPVOID clsid, CLSID *id)
return SHCLSIDFromStringA (clsid, id);
}
/*************************************************************************
* 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
*
@ -362,7 +502,6 @@ static ICOM_VTABLE(IClassFactory) clfvt =
* 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 @@ IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll,
lpclf->riidInst = riidInst;
TRACE("(%p)\n\tIID:\t%s\n",lpclf, debugstr_guid(riidInst));
InterlockedIncrement(&shell32_ObjCount);
return (LPCLASSFACTORY)lpclf;
}
/**************************************************************************
@ -409,19 +547,13 @@ static HRESULT WINAPI IDefClF_fnQueryInterface(
*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 @@ static ULONG WINAPI IDefClF_fnAddRef(LPCLASSFACTORY iface)
ICOM_THIS(IDefClFImpl,iface);
TRACE("(%p)->(count=%lu)\n",This,This->ref);
InterlockedIncrement(&shell32_ObjCount);
return InterlockedIncrement(&This->ref);
}
/******************************************************************************
@ -443,8 +574,6 @@ static ULONG WINAPI IDefClF_fnRelease(LPCLASSFACTORY iface)
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 @@ static HRESULT WINAPI IDefClF_fnCreateInstance(
*ppvObject = NULL;
if(pUnkOuter)
return(CLASS_E_NOAGGREGATION);
if ( This->riidInst==NULL ||
IsEqualCLSID(riid, This->riidInst) ||
IsEqualCLSID(riid, &IID_IUnknown) )
@ -510,20 +636,15 @@ HRESULT WINAPI SHCreateDefClassObject(
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 @@ UINT WINAPI DragQueryFileW(
if(lpDropFileStruct->fWide == FALSE) {
LPSTR lpszFileA = NULL;
if(lpszwFile) {
lpszFileA = (LPSTR) HeapAlloc(GetProcessHeap(), 0, lLength);
if(lpszFileA == NULL) {

View File

@ -344,64 +344,6 @@ int WINAPIV ShellMessageBoxA(
return ret;
}
/*************************************************************************
* 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]
*

View File

@ -53,14 +53,14 @@ HRESULT WINAPI StrRetToStrNA (LPVOID dest, DWORD len, LPSTRRET src, const ITEMID
{
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 @@ HRESULT WINAPI StrRetToStrNW (LPVOID dest1, DWORD len, LPSTRRET src, const ITEMI
{
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,

View File

@ -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 @@ static HRESULT SHELL32_CoCreateInitSF (
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 @@ typedef struct
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 @@ typedef struct
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 @@ static IShellFolder * ISF_MyComputer_Constructor(void);
#define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
#define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
#define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
#define _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 @@ static IShellFolder * ISF_MyComputer_Constructor(void);
#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 @@ static HRESULT WINAPI IUnknown_fnQueryInterface(
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 @@ static HRESULT WINAPI IUnknown_fnQueryInterface(
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 @@ static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
{
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 @@ static shvheader GenericSFHeader [] =
#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 @@ static HRESULT WINAPI IShellFolder_fnQueryInterface(
_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 @@ static HRESULT WINAPI IShellFolder_fnParseDisplayName(
/* 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 @@ static HRESULT WINAPI IShellFolder_fnEnumObjects(
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 @@ static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITE
_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 @@ static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITE
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 @@ static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITE
}
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 @@ static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITE
}
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 @@ static HRESULT WINAPI IShellFolder_fnBindToStorage(
{
_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 @@ static HRESULT WINAPI IShellFolder_fnCreateViewObject(
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 @@ static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
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 @@ static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
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 @@ static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
}
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 @@ static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
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 @@ static HRESULT WINAPI IShellFolder_fnSetNameOf(
/* 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 @@ static HRESULT WINAPI IShellFolder_fnSetNameOf(
}
/* 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 @@ static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
/* 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 @@ static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
break;
}
hr = S_OK;
psd->str.uType = STRRET_CSTRA;
psd->str.uType = STRRET_CSTR;
}
return hr;
@ -1399,7 +1369,7 @@ static HRESULT WINAPI ISFHelper_fnQueryInterface(
{
_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 @@ static ULONG WINAPI ISFHelper_fnAddRef(
{
_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 @@ static HRESULT WINAPI ISFHelper_fnAddFolder(
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 @@ static HRESULT WINAPI ISFHelper_fnAddFolder(
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 @@ static HRESULT WINAPI ISFHelper_fnDeleteItems(
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 @@ static HRESULT WINAPI ISFHelper_fnDeleteItems(
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 @@ static HRESULT WINAPI ISFHelper_fnDeleteItems(
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 @@ static HRESULT WINAPI ISFHelper_fnCopyItems(
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 @@ static shvheader DesktopSFHeader [] =
* 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 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
{
_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 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
{
_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 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
*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 @@ static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEM
_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 @@ static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEM
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 @@ static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEM
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 @@ static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
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 @@ static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
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 @@ static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
{
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 @@ static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
break;
}
hr = S_OK;
psd->str.uType = STRRET_CSTRA;
psd->str.uType = STRRET_CSTR;
}
return hr;
@ -2155,9 +2150,9 @@ static IShellFolder * ISF_MyComputer_Constructor(void)
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 @@ static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCI
_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 @@ static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCI
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 @@ static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCI
{
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 @@ static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
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 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
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 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
{
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 @@ static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
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 @@ static ICOM_VTABLE(IShellFolder2) sfmcvt =
* 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 @@ static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
* 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 @@ static ULONG WINAPI ISFPersistFolder2_AddRef(
* 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 @@ static ULONG WINAPI ISFPersistFolder2_Release(
/************************************************************************
* 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 @@ static HRESULT WINAPI ISFPersistFolder2_GetClassID(
* 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
};
/****************************************************************************

View File

@ -858,6 +858,9 @@ HRESULT WINAPI SHCreateDefClassObject(
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,

View File

@ -31,24 +31,15 @@ extern "C" {
* 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 @@ typedef struct IPersistFolder IPersistFolder, *LPPERSISTFOLDER;
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 @@ ICOM_DEFINE(IShellFolder2, IShellFolder)
* 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 @@ ICOM_DEFINE(IPersistFolder2, IPersistFolder)
/*** 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) */