From ebdea25edc5d4d8d57fd9eb9c7e49109d3de6d23 Mon Sep 17 00:00:00 2001 From: Francis Beaudet Date: Sun, 2 May 1999 09:27:08 +0000 Subject: [PATCH] Implemented the OLE object default handler and data cache. --- dlls/shell32/shlview.c | 2 +- include/ole2.h | 11 + include/wine/obj_oleobj.h | 14 +- include/wine/obj_oleview.h | 4 +- ole/Makefile.in | 2 + ole/datacache.c | 1304 ++++++++++++++++++++++++++++ ole/defaulthandler.c | 1659 ++++++++++++++++++++++++++++++++++++ ole/ole2.c | 329 ++++++- ole/ole2stubs.c | 49 +- ole/oleobj.c | 601 ++++++++++--- relay32/ole32.spec | 4 +- 11 files changed, 3810 insertions(+), 169 deletions(-) create mode 100644 ole/datacache.c create mode 100644 ole/defaulthandler.c diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c index debd81fa83b..60dfb1c9c1a 100644 --- a/dlls/shell32/shlview.c +++ b/dlls/shell32/shlview.c @@ -1752,7 +1752,7 @@ static HRESULT WINAPI ISVViewObject_Draw( HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, - pfnContinue pfnContinue, + IVO_ContCallback pfnContinue, DWORD dwContinue) { diff --git a/include/ole2.h b/include/ole2.h index 9688b6b91c4..3047412431e 100644 --- a/include/ole2.h +++ b/include/ole2.h @@ -40,7 +40,13 @@ HRESULT WINAPI ReadClassStm(IStream *pStm,REFCLSID pclsid); HRESULT WINAPI OleSave(LPPERSISTSTORAGE pPS, LPSTORAGE pStg, BOOL fSameAsLoad); +HRESULT WINAPI OleRegGetUserType(REFCLSID clsid, + DWORD dwFormOfType, + LPOLESTR* pszUserType); HRESULT WINAPI OleRegGetMiscStatus (REFCLSID clsid, DWORD dwAspect, DWORD* pdwStatus); +HRESULT WINAPI OleRegEnumFormatEtc (REFCLSID clsid, + DWORD dwDirection, + LPENUMFORMATETC* ppenumFormatetc); HRESULT WINAPI CreateStreamOnHGlobal (HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM* ppstm); HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum); BOOL WINAPI OleIsRunning(LPOLEOBJECT pObject); @@ -79,6 +85,11 @@ HRESULT WINAPI WriteFmtUserTypeStg(LPSTORAGE pstg, CLIPFORMAT cf, LPOLESTR l HRESULT WINAPI OleTranslateAccelerator (LPOLEINPLACEFRAME lpFrame, LPOLEINPLACEFRAMEINFO lpFrameInfo, LPMSG lpmsg); HRESULT WINAPI OleCreateFromData(LPDATAOBJECT pSrcDataObj, REFIID riid, DWORD renderopt, LPFORMATETC pFormatEtc, LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID* ppvObj); +HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPVOID* ppvObj); +HRESULT WINAPI CreateOleAdviseHolder (LPOLEADVISEHOLDER *ppOAHolder); #endif /* __WINE_OLE2_H */ diff --git a/include/wine/obj_oleobj.h b/include/wine/obj_oleobj.h index 95962af44d5..c7ab5b30620 100644 --- a/include/wine/obj_oleobj.h +++ b/include/wine/obj_oleobj.h @@ -109,7 +109,7 @@ ICOM_DEFINE(IOleObject,IUnknown) #define IOleObject_AddRef(p) ICOM_CALL (AddRef,p) #define IOleObject_Release(p) ICOM_CALL (Release,p) /*** IOleObject methods ***/ -#define IOleObject_SetClientSite(p,a,b,c,d) ICOM_CALL1(SetClientSite,p,a) +#define IOleObject_SetClientSite(p,a) ICOM_CALL1(SetClientSite,p,a) #define IOleObject_GetClientSite(p,a,b) ICOM_CALL1(GetClientSite,p,a) #define IOleObject_SetHostNames(p,a,b) ICOM_CALL2(SetHostNames,p,a,b) #define IOleObject_Close(p,a,b) ICOM_CALL1(Close,p,a) @@ -156,12 +156,12 @@ ICOM_DEFINE(IOleAdviseHolder,IUnknown) #define IOleAdviseHolder_AddRef(p) ICOM_CALL (AddRef,p) #define IOleAdviseHolder_Release(p) ICOM_CALL (Release,p) /*** IOleAdviseHolder methods ***/ -#define IOleAdviseHolder_Advise(p,a,b) ICOM_CALL2(UpdateCache,p,a,b) -#define IOleAdviseHolder_Unadvise(p,a) ICOM_CALL1(OnStop,p,a) -#define IOleAdviseHolder_EnumAdvise(p,a) ICOM_CALL1(OnStop,p,a) -#define IOleAdviseHolder_SendOnRename(p,a) ICOM_CALL1(OnStop,p,a) -#define IOleAdviseHolder_SendOnSave(p) ICOM_CALL (OnStop,p) -#define IOleAdviseHolder_SendOnClose(p) ICOM_CALL (OnStop,p) +#define IOleAdviseHolder_Advise(p,a,b) ICOM_CALL2(Advise,p,a,b) +#define IOleAdviseHolder_Unadvise(p,a) ICOM_CALL1(Unadvise,p,a) +#define IOleAdviseHolder_EnumAdvise(p,a) ICOM_CALL1(EnumAdvise,p,a) +#define IOleAdviseHolder_SendOnRename(p,a) ICOM_CALL1(SendOnRename,p,a) +#define IOleAdviseHolder_SendOnSave(p) ICOM_CALL (SendOnSave,p) +#define IOleAdviseHolder_SendOnClose(p) ICOM_CALL (SendOnClose,p) #endif diff --git a/include/wine/obj_oleview.h b/include/wine/obj_oleview.h index e35e1642a4e..3d213d4804e 100644 --- a/include/wine/obj_oleview.h +++ b/include/wine/obj_oleview.h @@ -29,11 +29,11 @@ typedef struct IViewObject2 IViewObject2, *LPVIEWOBJECT2; /***************************************************************************** * IViewObject interface */ -typedef BOOL (CALLBACK* pfnContinue)(DWORD); +typedef BOOL (CALLBACK* IVO_ContCallback)(DWORD); #define ICOM_INTERFACE IViewObject #define IViewObject_METHODS \ - ICOM_METHOD10(HRESULT,Draw, DWORD,dwDrawAspect, LONG,lindex, void*,pvAspect, DVTARGETDEVICE*,ptd, HDC,hdcTargetDev, HDC,hdcDraw, LPCRECTL,lprcBounds, LPCRECTL,lprcWBounds, pfnContinue,, DWORD,dwContinue) \ + ICOM_METHOD10(HRESULT,Draw, DWORD,dwDrawAspect, LONG,lindex, void*,pvAspect, DVTARGETDEVICE*,ptd, HDC,hdcTargetDev, HDC,hdcDraw, LPCRECTL,lprcBounds, LPCRECTL,lprcWBounds, IVO_ContCallback, pfnContinue, DWORD,dwContinue) \ ICOM_METHOD6(HRESULT,GetColorSet, DWORD,dwDrawAspect, LONG,lindex, void*,pvAspect, DVTARGETDEVICE*,ptd, HDC,hicTargetDevice, LOGPALETTE**,ppColorSet) \ ICOM_METHOD4(HRESULT,Freeze, DWORD,dwDrawAspect, LONG,lindex, void*,pvAspect, DWORD*,pdwFreeze) \ ICOM_METHOD1(HRESULT,Unfreeze, DWORD,dwFreeze) \ diff --git a/ole/Makefile.in b/ole/Makefile.in index eba4ed6ae33..831d3b56002 100644 --- a/ole/Makefile.in +++ b/ole/Makefile.in @@ -10,6 +10,8 @@ C_SRCS = \ bindctx.c \ compobj.c \ compositemoniker.c \ + datacache.c \ + defaulthandler.c \ filemoniker.c \ guid.c \ hglobalstream.c \ diff --git a/ole/datacache.c b/ole/datacache.c new file mode 100644 index 00000000000..9ae2921291a --- /dev/null +++ b/ole/datacache.c @@ -0,0 +1,1304 @@ +/* + * OLE 2 Data cache + * + * Copyright 1999 Francis Beaudet + * + * NOTES: + * The OLE2 data cache supports a whole whack of + * interfaces including: + * IDataObject, IPersistStorage, IViewObject2, + * IOleCache2 and IOleCacheControl. + * + * All the implementation details are taken from: Inside OLE + * second edition by Kraig Brockschmidt, + * + * TODO + * Allmost everything is to be done. Handling the cached data, + * handling the representations, drawing the representations of + * the cached data... yada yada. + */ +#include + +#include "winuser.h" +#include "winerror.h" +#include "ole2.h" +#include "debug.h" + +DEFAULT_DEBUG_CHANNEL(ole) + +/**************************************************************************** + * AdviseSinkListNode + */ +typedef struct AdviseSinkListNode +{ + +} AdviseSinkListNode; + +/**************************************************************************** + * DataCache + */ +struct DataCache +{ + /* + * List all interface VTables here + */ + ICOM_VTABLE(IDataObject)* lpvtbl1; + ICOM_VTABLE(IUnknown)* lpvtbl2; + ICOM_VTABLE(IPersistStorage)* lpvtbl3; + ICOM_VTABLE(IViewObject2)* lpvtbl4; + ICOM_VTABLE(IOleCache2)* lpvtbl5; + ICOM_VTABLE(IOleCacheControl)* lpvtbl6; + + /* + * Reference count of this object + */ + ULONG ref; + + /* + * IUnknown implementation of the outer object. + */ + IUnknown* outerUnknown; + + /* + * This storage pointer is set through a call to + * IPersistStorage_Load. This is where the visual + * representation of the object is stored. + */ + IStorage* presentationStorage; +}; + +typedef struct DataCache DataCache; + +/* + * Here, I define utility macros to help with the casting of the + * "this" parameter. + * There is a version to accomodate all of the VTables implemented + * by this object. + */ +#define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name; +#define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((void*)name)-sizeof(void*)); +#define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((void*)name)-2*sizeof(void*)); +#define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((void*)name)-3*sizeof(void*)); +#define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((void*)name)-4*sizeof(void*)); +#define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((void*)name)-5*sizeof(void*)); + +/* + * Prototypes for the methods of the DataCache class. + */ +static DataCache* DataCache_Construct(REFCLSID clsid, + LPUNKNOWN pUnkOuter); +static void DataCache_Destroy(DataCache* ptrToDestroy); + +/* + * Prototypes for the methods of the DataCache class + * that implement non delegating IUnknown methods. + */ +static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface( + IUnknown* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_NDIUnknown_AddRef( + IUnknown* iface); +static ULONG WINAPI DataCache_NDIUnknown_Release( + IUnknown* iface); + +/* + * Prototypes for the methods of the DataCache class + * that implement IDataObject methods. + */ +static HRESULT WINAPI DataCache_IDataObject_QueryInterface( + IDataObject* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IDataObject_AddRef( + IDataObject* iface); +static ULONG WINAPI DataCache_IDataObject_Release( + IDataObject* iface); +static HRESULT WINAPI DataCache_GetData( + IDataObject* iface, + LPFORMATETC pformatetcIn, + STGMEDIUM* pmedium); +static HRESULT WINAPI DataCache_GetDataHere( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium); +static HRESULT WINAPI DataCache_QueryGetData( + IDataObject* iface, + LPFORMATETC pformatetc); +static HRESULT WINAPI DataCache_GetCanonicalFormatEtc( + IDataObject* iface, + LPFORMATETC pformatectIn, + LPFORMATETC pformatetcOut); +static HRESULT WINAPI DataCache_IDataObject_SetData( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease); +static HRESULT WINAPI DataCache_EnumFormatEtc( + IDataObject* iface, + DWORD dwDirection, + IEnumFORMATETC** ppenumFormatEtc); +static HRESULT WINAPI DataCache_DAdvise( + IDataObject* iface, + FORMATETC* pformatetc, + DWORD advf, + IAdviseSink* pAdvSink, + DWORD* pdwConnection); +static HRESULT WINAPI DataCache_DUnadvise( + IDataObject* iface, + DWORD dwConnection); +static HRESULT WINAPI DataCache_EnumDAdvise( + IDataObject* iface, + IEnumSTATDATA** ppenumAdvise); + +/* + * Prototypes for the methods of the DataCache class + * that implement IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface( + IPersistStorage* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IPersistStorage_AddRef( + IPersistStorage* iface); +static ULONG WINAPI DataCache_IPersistStorage_Release( + IPersistStorage* iface); +static HRESULT WINAPI DataCache_GetClassID( + const IPersistStorage* iface, + CLSID* pClassID); +static HRESULT WINAPI DataCache_IsDirty( + IPersistStorage* iface); +static HRESULT WINAPI DataCache_InitNew( + IPersistStorage* iface, + IStorage* pStg); +static HRESULT WINAPI DataCache_Load( + IPersistStorage* iface, + IStorage* pStg); +static HRESULT WINAPI DataCache_Save( + IPersistStorage* iface, + IStorage* pStg, + BOOL fSameAsLoad); +static HRESULT WINAPI DataCache_SaveCompleted( + IPersistStorage* iface, + IStorage* pStgNew); +static HRESULT WINAPI DataCache_HandsOffStorage( + IPersistStorage* iface); + +/* + * Prototypes for the methods of the DataCache class + * that implement IViewObject2 methods. + */ +static HRESULT WINAPI DataCache_IViewObject2_QueryInterface( + IViewObject2* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IViewObject2_AddRef( + IViewObject2* iface); +static ULONG WINAPI DataCache_IViewObject2_Release( + IViewObject2* iface); +static HRESULT WINAPI DataCache_Draw( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hdcTargetDev, + HDC hdcDraw, + LPCRECTL lprcBounds, + LPCRECTL lprcWBounds, + IVO_ContCallback pfnContinue, + DWORD dwContinue); +static HRESULT WINAPI DataCache_GetColorSet( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hicTargetDevice, + LOGPALETTE** ppColorSet); +static HRESULT WINAPI DataCache_Freeze( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DWORD* pdwFreeze); +static HRESULT WINAPI DataCache_Unfreeze( + IViewObject2* iface, + DWORD dwFreeze); +static HRESULT WINAPI DataCache_SetAdvise( + IViewObject2* iface, + DWORD aspects, + DWORD advf, + IAdviseSink* pAdvSink); +static HRESULT WINAPI DataCache_GetAdvise( + IViewObject2* iface, + DWORD* pAspects, + DWORD* pAdvf, + IAdviseSink** ppAdvSink); +static HRESULT WINAPI DataCache_GetExtent( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + DVTARGETDEVICE* ptd, + LPSIZEL lpsizel); + +/* + * Prototypes for the methods of the DataCache class + * that implement IOleCache2 methods. + */ +static HRESULT WINAPI DataCache_IOleCache2_QueryInterface( + IOleCache2* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IOleCache2_AddRef( + IOleCache2* iface); +static ULONG WINAPI DataCache_IOleCache2_Release( + IOleCache2* iface); +static HRESULT WINAPI DataCache_Cache( + IOleCache2* iface, + FORMATETC* pformatetc, + DWORD advf, + DWORD* pdwConnection); +static HRESULT WINAPI DataCache_Uncache( + IOleCache2* iface, + DWORD dwConnection); +static HRESULT WINAPI DataCache_EnumCache( + IOleCache2* iface, + IEnumSTATDATA** ppenumSTATDATA); +static HRESULT WINAPI DataCache_InitCache( + IOleCache2* iface, + IDataObject* pDataObject); +static HRESULT WINAPI DataCache_IOleCache2_SetData( + IOleCache2* iface, + FORMATETC* pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease); +static HRESULT WINAPI DataCache_UpdateCache( + IOleCache2* iface, + LPDATAOBJECT pDataObject, + DWORD grfUpdf, + LPVOID pReserved); +static HRESULT WINAPI DataCache_DiscardCache( + IOleCache2* iface, + DWORD dwDiscardOptions); + +/* + * Prototypes for the methods of the DataCache class + * that implement IOleCacheControl methods. + */ +static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface( + IOleCacheControl* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataCache_IOleCacheControl_AddRef( + IOleCacheControl* iface); +static ULONG WINAPI DataCache_IOleCacheControl_Release( + IOleCacheControl* iface); +static HRESULT WINAPI DataCache_OnRun( + IOleCacheControl* iface, + LPDATAOBJECT pDataObject); +static HRESULT WINAPI DataCache_OnStop( + IOleCacheControl* iface); + +/* + * Virtual function tables for the DataCache class. + */ +static ICOM_VTABLE(IUnknown) DataCache_NDIUnknown_VTable = +{ + DataCache_NDIUnknown_QueryInterface, + DataCache_NDIUnknown_AddRef, + DataCache_NDIUnknown_Release +}; + +static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable = +{ + DataCache_IDataObject_QueryInterface, + DataCache_IDataObject_AddRef, + DataCache_IDataObject_Release, + DataCache_GetData, + DataCache_GetDataHere, + DataCache_QueryGetData, + DataCache_GetCanonicalFormatEtc, + DataCache_IDataObject_SetData, + DataCache_EnumFormatEtc, + DataCache_DAdvise, + DataCache_DUnadvise, + DataCache_EnumDAdvise +}; + +static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable = +{ + DataCache_IPersistStorage_QueryInterface, + DataCache_IPersistStorage_AddRef, + DataCache_IPersistStorage_Release, + DataCache_GetClassID, + DataCache_IsDirty, + DataCache_InitNew, + DataCache_Load, + DataCache_Save, + DataCache_SaveCompleted, + DataCache_HandsOffStorage +}; + +static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable = +{ + DataCache_IViewObject2_QueryInterface, + DataCache_IViewObject2_AddRef, + DataCache_IViewObject2_Release, + DataCache_Draw, + DataCache_GetColorSet, + DataCache_Freeze, + DataCache_Unfreeze, + DataCache_SetAdvise, + DataCache_GetAdvise, + DataCache_GetExtent +}; + +static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable = +{ + DataCache_IOleCache2_QueryInterface, + DataCache_IOleCache2_AddRef, + DataCache_IOleCache2_Release, + DataCache_Cache, + DataCache_Uncache, + DataCache_EnumCache, + DataCache_InitCache, + DataCache_IOleCache2_SetData, + DataCache_UpdateCache, + DataCache_DiscardCache +}; + +static ICOM_VTABLE(IOleCacheControl) DataCache_IOleCacheControl_VTable = +{ + DataCache_IOleCacheControl_QueryInterface, + DataCache_IOleCacheControl_AddRef, + DataCache_IOleCacheControl_Release, + DataCache_OnRun, + DataCache_OnStop +}; + +/****************************************************************************** + * CreateDataCache [OLE32.54] + */ +HRESULT WINAPI CreateDataCache( + LPUNKNOWN pUnkOuter, + REFCLSID rclsid, + REFIID riid, + LPVOID* ppvObj) +{ + DataCache* newCache = NULL; + HRESULT hr = S_OK; + char xclsid[50]; + char xriid[50]; + + WINE_StringFromCLSID((LPCLSID)rclsid,xclsid); + WINE_StringFromCLSID((LPCLSID)riid,xriid); + + TRACE(ole, "(%s, %p, %s, %p)\n", xclsid, pUnkOuter, xriid, ppvObj); + + /* + * Sanity check + */ + if (ppvObj==0) + return E_POINTER; + + *ppvObj = 0; + + /* + * If this cache is constructed for aggregation, make sure + * the caller is requesting the IUnknown interface. + * This is necessary because it's the only time the non-delegating + * IUnknown pointer can be returned to the outside. + */ + if ( (pUnkOuter!=NULL) && + (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) ) + return CLASS_E_NOAGGREGATION; + + /* + * Try to construct a new instance of the class. + */ + newCache = DataCache_Construct(rclsid, + pUnkOuter); + + if (newCache == 0) + return E_OUTOFMEMORY; + + /* + * Make sure it supports the interface required by the caller. + */ + hr = IUnknown_QueryInterface((IUnknown*)&(newCache->lpvtbl2), riid, ppvObj); + + /* + * Release the reference obtained in the constructor. If + * the QueryInterface was unsuccessful, it will free the class. + */ + IUnknown_Release((IUnknown*)&(newCache->lpvtbl2)); + + return hr; +} + +/********************************************************* + * Method implementation for DataCache class. + */ +static DataCache* DataCache_Construct( + REFCLSID clsid, + LPUNKNOWN pUnkOuter) +{ + DataCache* newObject = 0; + + /* + * Allocate space for the object. + */ + newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache)); + + if (newObject==0) + return newObject; + + /* + * Initialize the virtual function table. + */ + newObject->lpvtbl1 = &DataCache_IDataObject_VTable; + newObject->lpvtbl2 = &DataCache_NDIUnknown_VTable; + newObject->lpvtbl3 = &DataCache_IPersistStorage_VTable; + newObject->lpvtbl4 = &DataCache_IViewObject2_VTable; + newObject->lpvtbl5 = &DataCache_IOleCache2_VTable; + newObject->lpvtbl6 = &DataCache_IOleCacheControl_VTable; + + /* + * Start with one reference count. The caller of this function + * must release the interface pointer when it is done. + */ + newObject->ref = 1; + + /* + * Initialize the outer unknown + * We don't keep a reference on the outer unknown since, the way + * aggregation works, our lifetime is at least as large as it's + * lifetime. + */ + if (pUnkOuter==NULL) + pUnkOuter = (IUnknown*)&(newObject->lpvtbl2); + + newObject->outerUnknown = pUnkOuter; + + /* + * Initialize the other members of the structure. + */ + newObject->presentationStorage = NULL; + + return newObject; +} + +static void DataCache_Destroy( + DataCache* ptrToDestroy) +{ + if (ptrToDestroy->presentationStorage != NULL) + { + IStorage_Release(ptrToDestroy->presentationStorage); + ptrToDestroy->presentationStorage = NULL; + } + + /* + * Free the datacache pointer. + */ + HeapFree(GetProcessHeap(), 0, ptrToDestroy); +} + +/********************************************************* + * Method implementation for the non delegating IUnknown + * part of the DataCache class. + */ + +/************************************************************************ + * DefaultHandler_NDIUnknown_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface( + IUnknown* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_NDIUnknown(DataCache, iface); + + /* + * Perform a sanity check on the parameters. + */ + if ( (this==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = iface; + } + else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0) + { + *ppvObject = (IDataObject*)&(this->lpvtbl1); + } + else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) || + (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) ) + { + *ppvObject = (IPersistStorage*)&(this->lpvtbl3); + } + else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) || + (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) ) + { + *ppvObject = (IViewObject2*)&(this->lpvtbl4); + } + else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) || + (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) ) + { + *ppvObject = (IOleCache2*)&(this->lpvtbl5); + } + else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0) + { + *ppvObject = (IOleCacheControl*)&(this->lpvtbl6); + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + { + char clsid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,clsid); + + WARN(ole, + "() : asking for un supported interface %s\n", + clsid); + + return E_NOINTERFACE; + } + + /* + * Query Interface always increases the reference count by one when it is + * successful. + */ + IUnknown_AddRef((IUnknown*)*ppvObject); + + return S_OK;; +} + +/************************************************************************ + * DataCache_NDIUnknown_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static ULONG WINAPI DataCache_NDIUnknown_AddRef( + IUnknown* iface) +{ + _ICOM_THIS_From_NDIUnknown(DataCache, iface); + + this->ref++; + + return this->ref; +} + +/************************************************************************ + * DataCache_NDIUnknown_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static ULONG WINAPI DataCache_NDIUnknown_Release( + IUnknown* iface) +{ + _ICOM_THIS_From_NDIUnknown(DataCache, iface); + + /* + * Decrease the reference count on this object. + */ + this->ref--; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (this->ref==0) + { + DataCache_Destroy(this); + + return 0; + } + + return this->ref; +} + +/********************************************************* + * Method implementation for the IDataObject + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IDataObject_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IDataObject_QueryInterface( + IDataObject* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IDataObject(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IDataObject_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IDataObject_AddRef( + IDataObject* iface) +{ + _ICOM_THIS_From_IDataObject(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IDataObject_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IDataObject_Release( + IDataObject* iface) +{ + _ICOM_THIS_From_IDataObject(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +static HRESULT WINAPI DataCache_GetData( + IDataObject* iface, + LPFORMATETC pformatetcIn, + STGMEDIUM* pmedium) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_GetDataHere( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_QueryGetData( + IDataObject* iface, + LPFORMATETC pformatetc) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_EnumFormatEtc (IDataObject) + * + * The data cache doesn't implement this method. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_GetCanonicalFormatEtc( + IDataObject* iface, + LPFORMATETC pformatectIn, + LPFORMATETC pformatetcOut) +{ + TRACE(ole,"()\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_IDataObject_SetData (IDataObject) + * + * This method is delegated to the IOleCache2 implementation. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_IDataObject_SetData( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease) +{ + IOleCache2* oleCache = NULL; + HRESULT hres; + + TRACE(ole,"(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease); + + hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache); + + if (FAILED(hres)) + return E_UNEXPECTED; + + hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease); + + IOleCache2_Release(oleCache); + + return hres;; +} + +/************************************************************************ + * DataCache_EnumFormatEtc (IDataObject) + * + * The data cache doesn't implement this method. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_EnumFormatEtc( + IDataObject* iface, + DWORD dwDirection, + IEnumFORMATETC** ppenumFormatEtc) +{ + TRACE(ole,"()\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_DAdvise (IDataObject) + * + * The data cache doesn't support connections. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_DAdvise( + IDataObject* iface, + FORMATETC* pformatetc, + DWORD advf, + IAdviseSink* pAdvSink, + DWORD* pdwConnection) +{ + TRACE(ole,"()\n"); + return OLE_E_ADVISENOTSUPPORTED; +} + +/************************************************************************ + * DataCache_DUnadvise (IDataObject) + * + * The data cache doesn't support connections. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_DUnadvise( + IDataObject* iface, + DWORD dwConnection) +{ + TRACE(ole,"()\n"); + return OLE_E_NOCONNECTION; +} + +/************************************************************************ + * DataCache_EnumDAdvise (IDataObject) + * + * The data cache doesn't support connections. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DataCache_EnumDAdvise( + IDataObject* iface, + IEnumSTATDATA** ppenumAdvise) +{ + TRACE(ole,"()\n"); + return OLE_E_ADVISENOTSUPPORTED; +} + +/********************************************************* + * Method implementation for the IDataObject + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IPersistStorage_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface( + IPersistStorage* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IPersistStorage_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IPersistStorage_AddRef( + IPersistStorage* iface) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IPersistStorage_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IPersistStorage_Release( + IPersistStorage* iface) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +/************************************************************************ + * DataCache_GetClassID (IPersistStorage) + * + * The data cache doesn't implement this method. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_GetClassID( + const IPersistStorage* iface, + CLSID* pClassID) +{ + TRACE(ole,"(%p, %p)\n", iface, pClassID); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_IsDirty( + IPersistStorage* iface) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_InitNew (IPersistStorage) + * + * The data cache implementation of IPersistStorage_InitNew simply stores + * the storage pointer. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_InitNew( + IPersistStorage* iface, + IStorage* pStg) +{ + TRACE(ole, "(%p, %p)\n", iface, pStg); + + return DataCache_Load(iface, pStg); +} + +/************************************************************************ + * DataCache_Load (IPersistStorage) + * + * The data cache implementation of IPersistStorage_Load doesn't + * actually load anything. Instead, it holds on to the storage pointer + * and it will load the presentation information when the + * IDataObject_GetData or IViewObject2_Draw methods are called. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_Load( + IPersistStorage* iface, + IStorage* pStg) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + TRACE(ole, "(%p, %p)\n", iface, pStg); + + if (this->presentationStorage != NULL) + { + IStorage_Release(this->presentationStorage); + } + + this->presentationStorage = pStg; + + if (this->presentationStorage != NULL) + { + IStorage_AddRef(this->presentationStorage); + } + + return S_OK; +} + +static HRESULT WINAPI DataCache_Save( + IPersistStorage* iface, + IStorage* pStg, + BOOL fSameAsLoad) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DataCache_SaveCompleted (IPersistStorage) + * + * This method is called to tell the cache to release the storage + * pointer it's currentlu holding. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_SaveCompleted( + IPersistStorage* iface, + IStorage* pStgNew) +{ + TRACE(ole, "(%p, %p)\n", iface, pStgNew); + + /* + * First, make sure we get our hands off any storage we have. + */ + DataCache_HandsOffStorage(iface); + + /* + * Then, attach to the new storage. + */ + DataCache_Load(iface, pStgNew); + + return S_OK; +} + +/************************************************************************ + * DataCache_HandsOffStorage (IPersistStorage) + * + * This method is called to tell the cache to release the storage + * pointer it's currentlu holding. + * + * See Windows documentation for more details on IPersistStorage methods. + */ +static HRESULT WINAPI DataCache_HandsOffStorage( + IPersistStorage* iface) +{ + _ICOM_THIS_From_IPersistStorage(DataCache, iface); + + TRACE(ole,"\n"); + + if (this->presentationStorage != NULL) + { + IStorage_Release(this->presentationStorage); + this->presentationStorage = NULL; + } + + return S_OK; +} + +/********************************************************* + * Method implementation for the IViewObject2 + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IViewObject2_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IViewObject2_QueryInterface( + IViewObject2* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IViewObject2_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IViewObject2_AddRef( + IViewObject2* iface) +{ + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IViewObject2_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IViewObject2_Release( + IViewObject2* iface) +{ + _ICOM_THIS_From_IViewObject2(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +static HRESULT WINAPI DataCache_Draw( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hdcTargetDev, + HDC hdcDraw, + LPCRECTL lprcBounds, + LPCRECTL lprcWBounds, + IVO_ContCallback pfnContinue, + DWORD dwContinue) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_GetColorSet( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hicTargetDevice, + LOGPALETTE** ppColorSet) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_Freeze( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DWORD* pdwFreeze) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_Unfreeze( + IViewObject2* iface, + DWORD dwFreeze) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_SetAdvise( + IViewObject2* iface, + DWORD aspects, + DWORD advf, + IAdviseSink* pAdvSink) +{ + FIXME(ole,"stub\n"); + return S_OK; +} + +static HRESULT WINAPI DataCache_GetAdvise( + IViewObject2* iface, + DWORD* pAspects, + DWORD* pAdvf, + IAdviseSink** ppAdvSink) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_GetExtent( + IViewObject2* iface, + DWORD dwDrawAspect, + LONG lindex, + DVTARGETDEVICE* ptd, + LPSIZEL lpsizel) +{ + lpsizel->cx = 5000; + lpsizel->cy = 5000; + + FIXME(ole,"stub\n"); + + return S_OK; +} + + +/********************************************************* + * Method implementation for the IOleCache2 + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IOleCache2_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IOleCache2_QueryInterface( + IOleCache2* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IOleCache2(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IOleCache2_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IOleCache2_AddRef( + IOleCache2* iface) +{ + _ICOM_THIS_From_IOleCache2(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IOleCache2_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IOleCache2_Release( + IOleCache2* iface) +{ + _ICOM_THIS_From_IOleCache2(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +static HRESULT WINAPI DataCache_Cache( + IOleCache2* iface, + FORMATETC* pformatetc, + DWORD advf, + DWORD* pdwConnection) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_Uncache( + IOleCache2* iface, + DWORD dwConnection) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_EnumCache( + IOleCache2* iface, + IEnumSTATDATA** ppenumSTATDATA) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_InitCache( + IOleCache2* iface, + IDataObject* pDataObject) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_IOleCache2_SetData( + IOleCache2* iface, + FORMATETC* pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_UpdateCache( + IOleCache2* iface, + LPDATAOBJECT pDataObject, + DWORD grfUpdf, + LPVOID pReserved) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_DiscardCache( + IOleCache2* iface, + DWORD dwDiscardOptions) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + + +/********************************************************* + * Method implementation for the IOleCacheControl + * part of the DataCache class. + */ + +/************************************************************************ + * DataCache_IOleCacheControl_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface( + IOleCacheControl* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IOleCacheControl(DataCache, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DataCache_IOleCacheControl_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IOleCacheControl_AddRef( + IOleCacheControl* iface) +{ + _ICOM_THIS_From_IOleCacheControl(DataCache, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DataCache_IOleCacheControl_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataCache_IOleCacheControl_Release( + IOleCacheControl* iface) +{ + _ICOM_THIS_From_IOleCacheControl(DataCache, iface); + + return IUnknown_Release(this->outerUnknown); +} + +static HRESULT WINAPI DataCache_OnRun( + IOleCacheControl* iface, + LPDATAOBJECT pDataObject) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataCache_OnStop( + IOleCacheControl* iface) +{ + FIXME(ole,"stub\n"); + return E_NOTIMPL; +} + + diff --git a/ole/defaulthandler.c b/ole/defaulthandler.c new file mode 100644 index 00000000000..00f7da58df9 --- /dev/null +++ b/ole/defaulthandler.c @@ -0,0 +1,1659 @@ +/* + * OLE 2 default object handler + * + * Copyright 1999 Francis Beaudet + * + * NOTES: + * The OLE2 default object handler supports a whole whack of + * interfaces including: + * IOleObject, IDataObject, IPersistStorage, IViewObject2, + * IRunnableObject, IOleCache2, IOleCacheControl and much more. + * + * All the implementation details are taken from: Inside OLE + * second edition by Kraig Brockschmidt, + * + * TODO + * - This implementation of the default handler does not launch the + * server in the DoVerb, Update, GetData, GetDataHere and Run + * methods. When it is fixed to do so, all the methods will have + * to be revisited to allow delegating to the running object + * + * - All methods in the class that use the class ID should be + * aware that it is possible for a class to be treated as + * another one and go into emulation mode. Nothing has been + * done in this area. + * + * - Some functions still return E_NOTIMPL they have to be + * implemented most of those are related to the running of the + * actual server. + * + * - All the methods releated to notification and advise sinks are + * in place but no notifications are sent to the sinks yet. + */ +#include + +#include "winuser.h" +#include "winerror.h" +#include "ole2.h" +#include "debug.h" + +DEFAULT_DEBUG_CHANNEL(ole) + +/**************************************************************************** + * DefaultHandler + * + */ +struct DefaultHandler +{ + /* + * List all interface VTables here + */ + ICOM_VTABLE(IOleObject)* lpvtbl1; + ICOM_VTABLE(IUnknown)* lpvtbl2; + ICOM_VTABLE(IDataObject)* lpvtbl3; + ICOM_VTABLE(IRunnableObject)* lpvtbl4; + + /* + * Reference count of this object + */ + ULONG ref; + + /* + * IUnknown implementation of the outer object. + */ + IUnknown* outerUnknown; + + /* + * Class Id that this handler object represents. + */ + CLSID clsid; + + /* + * IUnknown implementation of the datacache. + */ + IUnknown* dataCache; + + /* + * Client site for the embedded object. + */ + IOleClientSite* clientSite; + + /* + * The IOleAdviseHolder maintains the connections + * on behalf of the default handler. + */ + IOleAdviseHolder* oleAdviseHolder; + + /* + * The IDataAdviseHolder maintains the data + * connections on behalf of the default handler. + */ + IDataAdviseHolder* dataAdviseHolder; + + /* + * Name of the container and object contained + */ + BSTR containerApp; + BSTR containerObj; + +}; + +typedef struct DefaultHandler DefaultHandler; + +/* + * Here, I define utility macros to help with the casting of the + * "this" parameter. + * There is a version to accomodate all of the VTables implemented + * by this object. + */ +#define _ICOM_THIS_From_IOleObject(class,name) class* this = (class*)name; +#define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((void*)name)-sizeof(void*)); +#define _ICOM_THIS_From_IDataObject(class, name) class* this = (class*)(((void*)name)-2*sizeof(void*)); +#define _ICOM_THIS_From_IRunnableObject(class, name) class* this = (class*)(((void*)name)-3*sizeof(void*)); + +/* + * Prototypes for the methods of the DefaultHandler class. + */ +static DefaultHandler* DefaultHandler_Construct(REFCLSID clsid, + LPUNKNOWN pUnkOuter); +static void DefaultHandler_Destroy(DefaultHandler* ptrToDestroy); + +/* + * Prototypes for the methods of the DefaultHandler class + * that implement non delegating IUnknown methods. + */ +static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface( + IUnknown* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef( + IUnknown* iface); +static ULONG WINAPI DefaultHandler_NDIUnknown_Release( + IUnknown* iface); + +/* + * Prototypes for the methods of the DefaultHandler class + * that implement IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_QueryInterface( + IOleObject* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DefaultHandler_AddRef( + IOleObject* iface); +static ULONG WINAPI DefaultHandler_Release( + IOleObject* iface); +static HRESULT WINAPI DefaultHandler_SetClientSite( + IOleObject* iface, + IOleClientSite* pClientSite); +static HRESULT WINAPI DefaultHandler_GetClientSite( + IOleObject* iface, + IOleClientSite** ppClientSite); +static HRESULT WINAPI DefaultHandler_SetHostNames( + IOleObject* iface, + LPCOLESTR szContainerApp, + LPCOLESTR szContainerObj); +static HRESULT WINAPI DefaultHandler_Close( + IOleObject* iface, + DWORD dwSaveOption); +static HRESULT WINAPI DefaultHandler_SetMoniker( + IOleObject* iface, + DWORD dwWhichMoniker, + IMoniker* pmk); +static HRESULT WINAPI DefaultHandler_GetMoniker( + IOleObject* iface, + DWORD dwAssign, + DWORD dwWhichMoniker, + IMoniker** ppmk); +static HRESULT WINAPI DefaultHandler_InitFromData( + IOleObject* iface, + IDataObject* pDataObject, + BOOL fCreation, + DWORD dwReserved); +static HRESULT WINAPI DefaultHandler_GetClipboardData( + IOleObject* iface, + DWORD dwReserved, + IDataObject** ppDataObject); +static HRESULT WINAPI DefaultHandler_DoVerb( + IOleObject* iface, + LONG iVerb, + LPMSG lpmsg, + IOleClientSite* pActiveSite, + LONG lindex, + HWND hwndParent, + LPCRECT lprcPosRect); +static HRESULT WINAPI DefaultHandler_EnumVerbs( + IOleObject* iface, + IEnumOLEVERB** ppEnumOleVerb); +static HRESULT WINAPI DefaultHandler_Update( + IOleObject* iface); +static HRESULT WINAPI DefaultHandler_IsUpToDate( + IOleObject* iface); +static HRESULT WINAPI DefaultHandler_GetUserClassID( + IOleObject* iface, + CLSID* pClsid); +static HRESULT WINAPI DefaultHandler_GetUserType( + IOleObject* iface, + DWORD dwFormOfType, + LPOLESTR* pszUserType); +static HRESULT WINAPI DefaultHandler_SetExtent( + IOleObject* iface, + DWORD dwDrawAspect, + SIZEL* psizel); +static HRESULT WINAPI DefaultHandler_GetExtent( + IOleObject* iface, + DWORD dwDrawAspect, + SIZEL* psizel); +static HRESULT WINAPI DefaultHandler_Advise( + IOleObject* iface, + IAdviseSink* pAdvSink, + DWORD* pdwConnection); +static HRESULT WINAPI DefaultHandler_Unadvise( + IOleObject* iface, + DWORD dwConnection); +static HRESULT WINAPI DefaultHandler_EnumAdvise( + IOleObject* iface, + IEnumSTATDATA** ppenumAdvise); +static HRESULT WINAPI DefaultHandler_GetMiscStatus( + IOleObject* iface, + DWORD dwAspect, + DWORD* pdwStatus); +static HRESULT WINAPI DefaultHandler_SetColorScheme( + IOleObject* iface, + LOGPALETTE* pLogpal); + +/* + * Prototypes for the methods of the DefaultHandler class + * that implement IDataObject methods. + */ +static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface( + IDataObject* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DefaultHandler_IDataObject_AddRef( + IDataObject* iface); +static ULONG WINAPI DefaultHandler_IDataObject_Release( + IDataObject* iface); +static HRESULT WINAPI DefaultHandler_GetData( + IDataObject* iface, + LPFORMATETC pformatetcIn, + STGMEDIUM* pmedium); +static HRESULT WINAPI DefaultHandler_GetDataHere( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium); +static HRESULT WINAPI DefaultHandler_QueryGetData( + IDataObject* iface, + LPFORMATETC pformatetc); +static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc( + IDataObject* iface, + LPFORMATETC pformatectIn, + LPFORMATETC pformatetcOut); +static HRESULT WINAPI DefaultHandler_SetData( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease); +static HRESULT WINAPI DefaultHandler_EnumFormatEtc( + IDataObject* iface, + DWORD dwDirection, + IEnumFORMATETC** ppenumFormatEtc); +static HRESULT WINAPI DefaultHandler_DAdvise( + IDataObject* iface, + FORMATETC* pformatetc, + DWORD advf, + IAdviseSink* pAdvSink, + DWORD* pdwConnection); +static HRESULT WINAPI DefaultHandler_DUnadvise( + IDataObject* iface, + DWORD dwConnection); +static HRESULT WINAPI DefaultHandler_EnumDAdvise( + IDataObject* iface, + IEnumSTATDATA** ppenumAdvise); + +/* + * Prototypes for the methods of the DefaultHandler class + * that implement IRunnableObject methods. + */ +static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface( + IRunnableObject* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef( + IRunnableObject* iface); +static ULONG WINAPI DefaultHandler_IRunnableObject_Release( + IRunnableObject* iface); +static HRESULT WINAPI DefaultHandler_GetRunningClass( + IRunnableObject* iface, + LPCLSID lpClsid); +static HRESULT WINAPI DefaultHandler_Run( + IRunnableObject* iface, + IBindCtx* pbc); +static BOOL WINAPI DefaultHandler_IsRunning( + IRunnableObject* iface); +static HRESULT WINAPI DefaultHandler_LockRunning( + IRunnableObject* iface, + BOOL fLock, + BOOL fLastUnlockCloses); +static HRESULT WINAPI DefaultHandler_SetContainedObject( + IRunnableObject* iface, + BOOL fContained); + + +/* + * Virtual function tables for the DefaultHandler class. + */ +static ICOM_VTABLE(IOleObject) DefaultHandler_IOleObject_VTable = +{ + DefaultHandler_QueryInterface, + DefaultHandler_AddRef, + DefaultHandler_Release, + DefaultHandler_SetClientSite, + DefaultHandler_GetClientSite, + DefaultHandler_SetHostNames, + DefaultHandler_Close, + DefaultHandler_SetMoniker, + DefaultHandler_GetMoniker, + DefaultHandler_InitFromData, + DefaultHandler_GetClipboardData, + DefaultHandler_DoVerb, + DefaultHandler_EnumVerbs, + DefaultHandler_Update, + DefaultHandler_IsUpToDate, + DefaultHandler_GetUserClassID, + DefaultHandler_GetUserType, + DefaultHandler_SetExtent, + DefaultHandler_GetExtent, + DefaultHandler_Advise, + DefaultHandler_Unadvise, + DefaultHandler_EnumAdvise, + DefaultHandler_GetMiscStatus, + DefaultHandler_SetColorScheme +}; + +static ICOM_VTABLE(IUnknown) DefaultHandler_NDIUnknown_VTable = +{ + DefaultHandler_NDIUnknown_QueryInterface, + DefaultHandler_NDIUnknown_AddRef, + DefaultHandler_NDIUnknown_Release, +}; + +static ICOM_VTABLE(IDataObject) DefaultHandler_IDataObject_VTable = +{ + DefaultHandler_IDataObject_QueryInterface, + DefaultHandler_IDataObject_AddRef, + DefaultHandler_IDataObject_Release, + DefaultHandler_GetData, + DefaultHandler_GetDataHere, + DefaultHandler_QueryGetData, + DefaultHandler_GetCanonicalFormatEtc, + DefaultHandler_SetData, + DefaultHandler_EnumFormatEtc, + DefaultHandler_DAdvise, + DefaultHandler_DUnadvise, + DefaultHandler_EnumDAdvise +}; + +static ICOM_VTABLE(IRunnableObject) DefaultHandler_IRunnableObject_VTable = +{ + DefaultHandler_IRunnableObject_QueryInterface, + DefaultHandler_IRunnableObject_AddRef, + DefaultHandler_IRunnableObject_Release, + DefaultHandler_GetRunningClass, + DefaultHandler_Run, + DefaultHandler_IsRunning, + DefaultHandler_LockRunning, + DefaultHandler_SetContainedObject +}; + +/****************************************************************************** + * OleCreateDefaultHandler [OLE32.90] + */ +HRESULT WINAPI OleCreateDefaultHandler( + REFCLSID clsid, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPVOID* ppvObj) +{ + DefaultHandler* newHandler = NULL; + HRESULT hr = S_OK; + char xclsid[50]; + char xriid[50]; + + WINE_StringFromCLSID((LPCLSID)clsid,xclsid); + WINE_StringFromCLSID((LPCLSID)riid,xriid); + + TRACE(ole, "(%s, %p, %s, %p)\n", xclsid, pUnkOuter, xriid, ppvObj); + + /* + * Sanity check + */ + if (ppvObj==0) + return E_POINTER; + + *ppvObj = 0; + + /* + * If this handler is constructed for aggregation, make sure + * the caller is requesting the IUnknown interface. + * This is necessary because it's the only time the non-delegating + * IUnknown pointer can be returned to the outside. + */ + if ( (pUnkOuter!=NULL) && + (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) ) + return CLASS_E_NOAGGREGATION; + + /* + * Try to construct a new instance of the class. + */ + newHandler = DefaultHandler_Construct(clsid, + pUnkOuter); + + if (newHandler == 0) + return E_OUTOFMEMORY; + + /* + * Make sure it supports the interface required by the caller. + */ + hr = IUnknown_QueryInterface((IUnknown*)&(newHandler->lpvtbl2), riid, ppvObj); + + /* + * Release the reference obtained in the constructor. If + * the QueryInterface was unsuccessful, it will free the class. + */ + IUnknown_Release((IUnknown*)&(newHandler->lpvtbl2)); + + return hr; +} + +/********************************************************* + * Methods implementation for the DefaultHandler class. + */ +static DefaultHandler* DefaultHandler_Construct( + REFCLSID clsid, + LPUNKNOWN pUnkOuter) +{ + DefaultHandler* newObject = 0; + + /* + * Allocate space for the object. + */ + newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler)); + + if (newObject==0) + return newObject; + + /* + * Initialize the virtual function table. + */ + newObject->lpvtbl1 = &DefaultHandler_IOleObject_VTable; + newObject->lpvtbl2 = &DefaultHandler_NDIUnknown_VTable; + newObject->lpvtbl3 = &DefaultHandler_IDataObject_VTable; + newObject->lpvtbl4 = &DefaultHandler_IRunnableObject_VTable; + + /* + * Start with one reference count. The caller of this function + * must release the interface pointer when it is done. + */ + newObject->ref = 1; + + /* + * Initialize the outer unknown + * We don't keep a reference on the outer unknown since, the way + * aggregation works, our lifetime is at least as large as it's + * lifetime. + */ + if (pUnkOuter==NULL) + pUnkOuter = (IUnknown*)&(newObject->lpvtbl2); + + newObject->outerUnknown = pUnkOuter; + + /* + * Create a datacache object. + * We aggregate with the datacache. Make sure we pass our outer + * unknown as the datacache's outer unknown. + */ + CreateDataCache(newObject->outerUnknown, + clsid, + &IID_IUnknown, + (void**)&newObject->dataCache); + + /* + * Initialize the other data members of the class. + */ + memcpy(&(newObject->clsid), clsid, sizeof(CLSID)); + newObject->clientSite = NULL; + newObject->oleAdviseHolder = NULL; + newObject->dataAdviseHolder = NULL; + newObject->containerApp = NULL; + newObject->containerObj = NULL; + + return newObject; +} + +static void DefaultHandler_Destroy( + DefaultHandler* ptrToDestroy) +{ + /* + * Free the strings idenfitying the object + */ + if (ptrToDestroy->containerApp!=NULL) + { + SysFreeString(ptrToDestroy->containerApp); + ptrToDestroy->containerApp = NULL; + } + + if (ptrToDestroy->containerObj!=NULL) + { + SysFreeString(ptrToDestroy->containerObj); + ptrToDestroy->containerObj = NULL; + } + + /* + * Release our reference to the data cache. + */ + if (ptrToDestroy->dataCache!=NULL) + { + IUnknown_Release(ptrToDestroy->dataCache); + ptrToDestroy->dataCache = NULL; + } + + /* + * Same thing for the client site. + */ + if (ptrToDestroy->clientSite!=NULL) + { + IOleClientSite_Release(ptrToDestroy->clientSite); + ptrToDestroy->clientSite = NULL; + } + + /* + * And the advise holder. + */ + if (ptrToDestroy->oleAdviseHolder!=NULL) + { + IOleClientSite_Release(ptrToDestroy->oleAdviseHolder); + ptrToDestroy->oleAdviseHolder = NULL; + } + + /* + * And the data advise holder. + */ + if (ptrToDestroy->dataAdviseHolder!=NULL) + { + IOleClientSite_Release(ptrToDestroy->dataAdviseHolder); + ptrToDestroy->dataAdviseHolder = NULL; + } + + + /* + * Free the actual default handler structure. + */ + HeapFree(GetProcessHeap(), 0, ptrToDestroy); +} + +/********************************************************* + * Method implementation for the non delegating IUnknown + * part of the DefaultHandler class. + */ + +/************************************************************************ + * DefaultHandler_NDIUnknown_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface( + IUnknown* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_NDIUnknown(DefaultHandler, iface); + + /* + * Perform a sanity check on the parameters. + */ + if ( (this==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = iface; + } + else if (memcmp(&IID_IOleObject, riid, sizeof(IID_IOleObject)) == 0) + { + *ppvObject = (IOleObject*)&(this->lpvtbl1); + } + else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0) + { + *ppvObject = (IDataObject*)&(this->lpvtbl3); + } + else if (memcmp(&IID_IRunnableObject, riid, sizeof(IID_IRunnableObject)) == 0) + { + *ppvObject = (IRunnableObject*)&(this->lpvtbl4); + } + else + { + /* + * Blind aggregate the data cache to "inherit" it's interfaces. + */ + IUnknown_QueryInterface(this->dataCache, riid, ppvObject); + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + { + char clsid[50]; + + WINE_StringFromCLSID((LPCLSID)riid,clsid); + + WARN(ole, + "() : asking for un supported interface %s\n", + clsid); + + return E_NOINTERFACE; + } + + /* + * Query Interface always increases the reference count by one when it is + * successful. + */ + IUnknown_AddRef((IUnknown*)*ppvObject); + + return S_OK;; +} + +/************************************************************************ + * DefaultHandler_NDIUnknown_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef( + IUnknown* iface) +{ + _ICOM_THIS_From_NDIUnknown(DefaultHandler, iface); + + this->ref++; + + return this->ref; +} + +/************************************************************************ + * DefaultHandler_NDIUnknown_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + * + * This version of QueryInterface will not delegate it's implementation + * to the outer unknown. + */ +static ULONG WINAPI DefaultHandler_NDIUnknown_Release( + IUnknown* iface) +{ + _ICOM_THIS_From_NDIUnknown(DefaultHandler, iface); + + /* + * Decrease the reference count on this object. + */ + this->ref--; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (this->ref==0) + { + DefaultHandler_Destroy(this); + + return 0; + } + + return this->ref; +} + +/********************************************************* + * Methods implementation for the IOleObject part of + * the DefaultHandler class. + */ + +/************************************************************************ + * DefaultHandler_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DefaultHandler_QueryInterface( + IOleObject* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DefaultHandler_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DefaultHandler_AddRef( + IOleObject* iface) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DefaultHandler_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DefaultHandler_Release( + IOleObject* iface) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + return IUnknown_Release(this->outerUnknown); +} + +/************************************************************************ + * DefaultHandler_SetClientSite (IOleObject) + * + * The default handler's implementation of this method only keeps the + * client site pointer for future reference. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_SetClientSite( + IOleObject* iface, + IOleClientSite* pClientSite) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p)\n", iface, pClientSite); + + /* + * Make sure we release the previous client site if there + * was one. + */ + if (this->clientSite!=NULL) + { + IOleClientSite_Release(this->clientSite); + } + + this->clientSite = pClientSite; + + if (this->clientSite!=NULL) + { + IOleClientSite_AddRef(this->clientSite); + } + + return S_OK; +} + +/************************************************************************ + * DefaultHandler_GetClientSite (IOleObject) + * + * The default handler's implementation of this method returns the + * last pointer set in IOleObject_SetClientSite. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetClientSite( + IOleObject* iface, + IOleClientSite** ppClientSite) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + /* + * Sanity check. + */ + if (ppClientSite == NULL) + return E_POINTER; + + *ppClientSite = this->clientSite; + + if (*ppClientSite!=NULL) + { + IOleClientSite_Release(*ppClientSite); + } + + return S_OK; +} + +/************************************************************************ + * DefaultHandler_SetHostNames (IOleObject) + * + * The default handler's implementation of this method just stores + * the strings and returns S_OK. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_SetHostNames( + IOleObject* iface, + LPCOLESTR szContainerApp, + LPCOLESTR szContainerObj) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %s, %s)\n", + iface, + debugstr_w(szContainerApp), + debugstr_w(szContainerObj)); + + /* + * Be sure to cleanup before re-assinging the strings. + */ + if (this->containerApp!=NULL) + { + SysFreeString(this->containerApp); + this->containerApp = NULL; + } + + if (this->containerObj!=NULL) + { + SysFreeString(this->containerObj); + this->containerObj = NULL; + } + + /* + * Copy the string supplied. + */ + if (szContainerApp != NULL) + this->containerApp = SysAllocString(szContainerApp); + + if (szContainerObj != NULL) + this->containerObj = SysAllocString(szContainerObj); + + return S_OK; +} + +/************************************************************************ + * DefaultHandler_Close (IOleObject) + * + * The default handler's implementation of this method is meaningless + * without a running server so it does nothing. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_Close( + IOleObject* iface, + DWORD dwSaveOption) +{ + TRACE(ole, "()\n"); + return S_OK; +} + +/************************************************************************ + * DefaultHandler_SetMoniker (IOleObject) + * + * The default handler's implementation of this method does nothing. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_SetMoniker( + IOleObject* iface, + DWORD dwWhichMoniker, + IMoniker* pmk) +{ + TRACE(ole, "(%p, %ld, %p)\n", + iface, + dwWhichMoniker, + pmk); + + return S_OK; +} + +/************************************************************************ + * DefaultHandler_GetMoniker (IOleObject) + * + * Delegate this request to the client site if we have one. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetMoniker( + IOleObject* iface, + DWORD dwAssign, + DWORD dwWhichMoniker, + IMoniker** ppmk) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %ld, %ld, %p)\n", + iface, dwAssign, dwWhichMoniker, ppmk); + + if (this->clientSite) + { + return IOleClientSite_GetMoniker(this->clientSite, + dwAssign, + dwWhichMoniker, + ppmk); + + } + + return E_UNSPEC; +} + +/************************************************************************ + * DefaultHandler_InitFromData (IOleObject) + * + * This method is meaningless if the server is not running + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_InitFromData( + IOleObject* iface, + IDataObject* pDataObject, + BOOL fCreation, + DWORD dwReserved) +{ + TRACE(ole, "(%p, %p, %d, %ld)\n", + iface, pDataObject, fCreation, dwReserved); + + return OLE_E_NOTRUNNING; +} + +/************************************************************************ + * DefaultHandler_GetClipboardData (IOleObject) + * + * This method is meaningless if the server is not running + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetClipboardData( + IOleObject* iface, + DWORD dwReserved, + IDataObject** ppDataObject) +{ + TRACE(ole, "(%p, %ld, %p)\n", + iface, dwReserved, ppDataObject); + + return OLE_E_NOTRUNNING; +} + +static HRESULT WINAPI DefaultHandler_DoVerb( + IOleObject* iface, + LONG iVerb, + LPMSG lpmsg, + IOleClientSite* pActiveSite, + LONG lindex, + HWND hwndParent, + LPCRECT lprcPosRect) +{ + FIXME(ole, ": Stub\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DefaultHandler_EnumVerbs (IOleObject) + * + * The default handler implementation of this method simply delegates + * to OleRegEnumVerbs + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_EnumVerbs( + IOleObject* iface, + IEnumOLEVERB** ppEnumOleVerb) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p)\n", iface, ppEnumOleVerb); + + return OleRegEnumVerbs(&this->clsid, ppEnumOleVerb); +} + +static HRESULT WINAPI DefaultHandler_Update( + IOleObject* iface) +{ + FIXME(ole, ": Stub\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DefaultHandler_IsUpToDate (IOleObject) + * + * This method is meaningless if the server is not running + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_IsUpToDate( + IOleObject* iface) +{ + TRACE(ole, "(%p)\n", iface); + + return OLE_E_NOTRUNNING; +} + +/************************************************************************ + * DefaultHandler_GetUserClassID (IOleObject) + * + * TODO: Map to a new class ID if emulation is active. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetUserClassID( + IOleObject* iface, + CLSID* pClsid) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p)\n", iface, pClsid); + + /* + * Sanity check. + */ + if (pClsid==NULL) + return E_POINTER; + + memcpy(pClsid, &this->clsid, sizeof(CLSID)); + + return S_OK; +} + +/************************************************************************ + * DefaultHandler_GetUserType (IOleObject) + * + * The default handler implementation of this method simply delegates + * to OleRegGetUserType + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetUserType( + IOleObject* iface, + DWORD dwFormOfType, + LPOLESTR* pszUserType) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType); + + return OleRegGetUserType(&this->clsid, dwFormOfType, pszUserType); +} + +/************************************************************************ + * DefaultHandler_SetExtent (IOleObject) + * + * This method is meaningless if the server is not running + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_SetExtent( + IOleObject* iface, + DWORD dwDrawAspect, + SIZEL* psizel) +{ + TRACE(ole, "(%p, %lx, (%d,%d))\n", iface, dwDrawAspect, psizel->cx, psizel->cy); + return OLE_E_NOTRUNNING; +} + +/************************************************************************ + * DefaultHandler_GetExtent (IOleObject) + * + * The default handler's implementation of this method returns uses + * the cache to locate the aspect and extract the extent from it. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetExtent( + IOleObject* iface, + DWORD dwDrawAspect, + SIZEL* psizel) +{ + DVTARGETDEVICE* targetDevice; + IViewObject2* cacheView = NULL; + HRESULT hres; + + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %lx, %p)\n", iface, dwDrawAspect, psizel); + + hres = IUnknown_QueryInterface(this->dataCache, &IID_IViewObject2, (void**)&cacheView); + + if (FAILED(hres)) + return E_UNEXPECTED; + + /* + * Prepare the call to the cache's GetExtent method. + * + * Here we would build a valid DVTARGETDEVICE structure + * but, since we are calling into the data cache, we + * know it's implementation and we'll skip this + * extra work until later. + */ + targetDevice = NULL; + + hres = IViewObject2_GetExtent(cacheView, + dwDrawAspect, + -1, + targetDevice, + psizel); + + /* + * Cleanup + */ + IViewObject2_Release(cacheView); + + return hres; +} + +/************************************************************************ + * DefaultHandler_Advise (IOleObject) + * + * The default handler's implementation of this method simply + * delegates to the OleAdviseHolder. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_Advise( + IOleObject* iface, + IAdviseSink* pAdvSink, + DWORD* pdwConnection) +{ + HRESULT hres = S_OK; + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p, %p)\n", iface, pAdvSink, pdwConnection); + + /* + * Make sure we have an advise holder before we start. + */ + if (this->oleAdviseHolder==NULL) + { + hres = CreateOleAdviseHolder(&this->oleAdviseHolder); + } + + if (SUCCEEDED(hres)) + { + hres = IOleAdviseHolder_Advise(this->oleAdviseHolder, + pAdvSink, + pdwConnection); + } + + return hres; +} + +/************************************************************************ + * DefaultHandler_Unadvise (IOleObject) + * + * The default handler's implementation of this method simply + * delegates to the OleAdviseHolder. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_Unadvise( + IOleObject* iface, + DWORD dwConnection) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %ld)\n", iface, dwConnection); + + /* + * If we don't have an advise holder yet, it means we don't have + * a connection. + */ + if (this->oleAdviseHolder==NULL) + return OLE_E_NOCONNECTION; + + return IOleAdviseHolder_Unadvise(this->oleAdviseHolder, + dwConnection); +} + +/************************************************************************ + * DefaultHandler_EnumAdvise (IOleObject) + * + * The default handler's implementation of this method simply + * delegates to the OleAdviseHolder. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_EnumAdvise( + IOleObject* iface, + IEnumSTATDATA** ppenumAdvise) +{ + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p)\n", iface, ppenumAdvise); + + /* + * Sanity check + */ + if (ppenumAdvise==NULL) + return E_POINTER; + + /* + * Initialize the out parameter. + */ + *ppenumAdvise = NULL; + + if (this->oleAdviseHolder==NULL) + return IOleAdviseHolder_EnumAdvise(this->oleAdviseHolder, + ppenumAdvise); + + return S_OK; +} + +/************************************************************************ + * DefaultHandler_GetMiscStatus (IOleObject) + * + * The default handler's implementation of this method simply delegates + * to OleRegGetMiscStatus. + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetMiscStatus( + IOleObject* iface, + DWORD dwAspect, + DWORD* pdwStatus) +{ + HRESULT hres; + _ICOM_THIS_From_IOleObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %lx, %p)\n", iface, dwAspect, pdwStatus); + + hres = OleRegGetMiscStatus(&(this->clsid), dwAspect, pdwStatus); + + if (FAILED(hres)) + *pdwStatus = 0; + + return S_OK; +} + +/************************************************************************ + * DefaultHandler_SetExtent (IOleObject) + * + * This method is meaningless if the server is not running + * + * See Windows documentation for more details on IOleObject methods. + */ +static HRESULT WINAPI DefaultHandler_SetColorScheme( + IOleObject* iface, + LOGPALETTE* pLogpal) +{ + TRACE(ole, "(%p, %p))\n", iface, pLogpal); + return OLE_E_NOTRUNNING; +} + +/********************************************************* + * Methods implementation for the IDataObject part of + * the DefaultHandler class. + */ + +/************************************************************************ + * DefaultHandler_IDataObject_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface( + IDataObject* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DefaultHandler_IDataObject_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DefaultHandler_IDataObject_AddRef( + IDataObject* iface) +{ + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DefaultHandler_IDataObject_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DefaultHandler_IDataObject_Release( + IDataObject* iface) +{ + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + return IUnknown_Release(this->outerUnknown); +} + +static HRESULT WINAPI DefaultHandler_GetData( + IDataObject* iface, + LPFORMATETC pformatetcIn, + STGMEDIUM* pmedium) +{ + FIXME(ole, ": Stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DefaultHandler_GetDataHere( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium) +{ + FIXME(ole, ": Stub\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DefaultHandler_QueryGetData (IDataObject) + * + * The default handler's implementation of this method delegates to + * the cache. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DefaultHandler_QueryGetData( + IDataObject* iface, + LPFORMATETC pformatetc) +{ + IDataObject* cacheDataObject = NULL; + HRESULT hres; + + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p)\n", iface, pformatetc); + + hres = IUnknown_QueryInterface(this->dataCache, + &IID_IDataObject, + (void**)&cacheDataObject); + + if (FAILED(hres)) + return E_UNEXPECTED; + + hres = IDataObject_QueryGetData(cacheDataObject, + pformatetc); + + IDataObject_Release(cacheDataObject); + + return hres; +} + +/************************************************************************ + * DefaultHandler_GetCanonicalFormatEtc (IDataObject) + * + * This method is meaningless if the server is not running + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc( + IDataObject* iface, + LPFORMATETC pformatectIn, + LPFORMATETC pformatetcOut) +{ + FIXME(ole, "(%p, %p, %p)\n", iface, pformatectIn, pformatetcOut); + + return OLE_E_NOTRUNNING; +} + +/************************************************************************ + * DefaultHandler_SetData (IDataObject) + * + * The default handler's implementation of this method delegates to + * the cache. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DefaultHandler_SetData( + IDataObject* iface, + LPFORMATETC pformatetc, + STGMEDIUM* pmedium, + BOOL fRelease) +{ + IDataObject* cacheDataObject = NULL; + HRESULT hres; + + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease); + + hres = IUnknown_QueryInterface(this->dataCache, + &IID_IDataObject, + (void**)&cacheDataObject); + + if (FAILED(hres)) + return E_UNEXPECTED; + + hres = IDataObject_SetData(cacheDataObject, + pformatetc, + pmedium, + fRelease); + + IDataObject_Release(cacheDataObject); + + return hres; +} + +/************************************************************************ + * DefaultHandler_EnumFormatEtc (IDataObject) + * + * The default handler's implementation of this method simply delegates + * to OleRegEnumFormatEtc. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DefaultHandler_EnumFormatEtc( + IDataObject* iface, + DWORD dwDirection, + IEnumFORMATETC** ppenumFormatEtc) +{ + HRESULT hres; + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc); + + hres = OleRegEnumFormatEtc(&(this->clsid), dwDirection, ppenumFormatEtc); + + return hres; +} + +/************************************************************************ + * DefaultHandler_DAdvise (IDataObject) + * + * The default handler's implementation of this method simply + * delegates to the DataAdviseHolder. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DefaultHandler_DAdvise( + IDataObject* iface, + FORMATETC* pformatetc, + DWORD advf, + IAdviseSink* pAdvSink, + DWORD* pdwConnection) +{ + HRESULT hres = S_OK; + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p, %ld, %p, %p)\n", + iface, pformatetc, advf, pAdvSink, pdwConnection); + + /* + * Make sure we have a data advise holder before we start. + */ + if (this->dataAdviseHolder==NULL) + { + hres = CreateDataAdviseHolder(&this->dataAdviseHolder); + } + + if (SUCCEEDED(hres)) + { + hres = IDataAdviseHolder_Advise(this->dataAdviseHolder, + iface, + pformatetc, + advf, + pAdvSink, + pdwConnection); + } + + return hres; +} + +/************************************************************************ + * DefaultHandler_DUnadvise (IDataObject) + * + * The default handler's implementation of this method simply + * delegates to the DataAdviseHolder. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DefaultHandler_DUnadvise( + IDataObject* iface, + DWORD dwConnection) +{ + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %ld)\n", iface, dwConnection); + + /* + * If we don't have a data advise holder yet, it means that + * we don't have any connections.. + */ + if (this->dataAdviseHolder==NULL) + { + return OLE_E_NOCONNECTION; + } + + return IDataAdviseHolder_Unadvise(this->dataAdviseHolder, + dwConnection); +} + +/************************************************************************ + * DefaultHandler_EnumDAdvise (IDataObject) + * + * The default handler's implementation of this method simply + * delegates to the DataAdviseHolder. + * + * See Windows documentation for more details on IDataObject methods. + */ +static HRESULT WINAPI DefaultHandler_EnumDAdvise( + IDataObject* iface, + IEnumSTATDATA** ppenumAdvise) +{ + _ICOM_THIS_From_IDataObject(DefaultHandler, iface); + + TRACE(ole, "(%p, %p)\n", iface, ppenumAdvise); + + /* + * Sanity check + */ + if (ppenumAdvise == NULL) + return E_POINTER; + + /* + * Initialize the out parameter. + */ + *ppenumAdvise = NULL; + + /* + * If we have a data advise holder object, delegate. + */ + if (this->dataAdviseHolder!=NULL) + { + return IDataAdviseHolder_EnumAdvise(this->dataAdviseHolder, + ppenumAdvise); + } + + return S_OK; +} + +/********************************************************* + * Methods implementation for the IRunnableObject part + * of the DefaultHandler class. + */ + +/************************************************************************ + * DefaultHandler_IRunnableObject_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface( + IRunnableObject* iface, + REFIID riid, + void** ppvObject) +{ + _ICOM_THIS_From_IRunnableObject(DefaultHandler, iface); + + return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject); +} + +/************************************************************************ + * DefaultHandler_IRunnableObject_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef( + IRunnableObject* iface) +{ + _ICOM_THIS_From_IRunnableObject(DefaultHandler, iface); + + return IUnknown_AddRef(this->outerUnknown); +} + +/************************************************************************ + * DefaultHandler_IRunnableObject_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DefaultHandler_IRunnableObject_Release( + IRunnableObject* iface) +{ + _ICOM_THIS_From_IRunnableObject(DefaultHandler, iface); + + return IUnknown_Release(this->outerUnknown); +} + +/************************************************************************ + * DefaultHandler_GetRunningClass (IRunnableObject) + * + * According to Brockscmidt, Chapter 19, the default handler's + * implementation of IRunnableobject does nothing until the object + * is actually running. + * + * See Windows documentation for more details on IRunnableObject methods. + */ +static HRESULT WINAPI DefaultHandler_GetRunningClass( + IRunnableObject* iface, + LPCLSID lpClsid) +{ + TRACE(ole, "()\n"); + return S_OK; +} + +static HRESULT WINAPI DefaultHandler_Run( + IRunnableObject* iface, + IBindCtx* pbc) +{ + FIXME(ole, ": Stub\n"); + return E_NOTIMPL; +} + +/************************************************************************ + * DefaultHandler_IsRunning (IRunnableObject) + * + * According to Brockscmidt, Chapter 19, the default handler's + * implementation of IRunnableobject does nothing until the object + * is actually running. + * + * See Windows documentation for more details on IRunnableObject methods. + */ +static BOOL WINAPI DefaultHandler_IsRunning( + IRunnableObject* iface) +{ + TRACE(ole, "()\n"); + return S_FALSE; +} + +/************************************************************************ + * DefaultHandler_LockRunning (IRunnableObject) + * + * According to Brockscmidt, Chapter 19, the default handler's + * implementation of IRunnableobject does nothing until the object + * is actually running. + * + * See Windows documentation for more details on IRunnableObject methods. + */ +static HRESULT WINAPI DefaultHandler_LockRunning( + IRunnableObject* iface, + BOOL fLock, + BOOL fLastUnlockCloses) +{ + TRACE(ole, "()\n"); + return S_OK; +} + +/************************************************************************ + * DefaultHandler_SetContainedObject (IRunnableObject) + * + * According to Brockscmidt, Chapter 19, the default handler's + * implementation of IRunnableobject does nothing until the object + * is actually running. + * + * See Windows documentation for more details on IRunnableObject methods. + */ +static HRESULT WINAPI DefaultHandler_SetContainedObject( + IRunnableObject* iface, + BOOL fContained) +{ + TRACE(ole, "()\n"); + return S_OK; +} + diff --git a/ole/ole2.c b/ole/ole2.c index ccb37be4696..cb052ad1074 100644 --- a/ole/ole2.c +++ b/ole/ole2.c @@ -7,6 +7,8 @@ */ #include +#include +#include #include "winuser.h" #include "winerror.h" @@ -17,6 +19,7 @@ #include "wine/obj_clientserver.h" #include "debug.h" #include "ole2ver.h" +#include "winreg.h" DEFAULT_DEBUG_CHANNEL(ole) @@ -84,6 +87,11 @@ static const char OLEDD_DRAGTRACKERCLASS[] = "WineDragDropTracker32"; */ static DropTargetNode* targetListHead = NULL; +/****************************************************************************** + * These are the prototypes of miscelaneous utility methods + */ +static void OLEUTL_ReadRegistryDWORDValue(HKEY regKey, DWORD* pdwValue); + /****************************************************************************** * These are the prototypes of the utility methods used to manage a shared menu */ @@ -373,14 +381,97 @@ HRESULT WINAPI RevokeDragDrop( /*********************************************************************** * OleRegGetUserType (OLE32.122) + * + * This implementation of OleRegGetUserType ignores the dwFormOfType + * parameter and always returns the full name of the object. This is + * not too bad since this is the case for many objects because of the + * way they are registered. */ HRESULT WINAPI OleRegGetUserType( REFCLSID clsid, DWORD dwFormOfType, LPOLESTR* pszUserType) { - FIXME(ole,",stub!\n"); - return S_OK; + char xclsid[50]; + char keyName[60]; + DWORD dwKeyType; + DWORD cbData; + HKEY clsidKey; + LONG hres; + + /* + * Initialize the out parameter. + */ + *pszUserType = NULL; + + /* + * Build the key name we're looking for + */ + WINE_StringFromCLSID((LPCLSID)clsid, xclsid); + + strcpy(keyName, "CLSID\\"); + strcat(keyName, xclsid); + strcat(keyName, "\\"); + + TRACE(ole,"(%s, %ld, %p)\n", keyName, dwFormOfType, pszUserType); + + /* + * Open the class id Key + */ + hres = RegOpenKeyA(HKEY_CLASSES_ROOT, + keyName, + &clsidKey); + + if (hres != ERROR_SUCCESS) + return REGDB_E_CLASSNOTREG; + + /* + * Retrieve the size of the name string. + */ + cbData = 0; + + hres = RegQueryValueExA(clsidKey, + "", + NULL, + &dwKeyType, + NULL, + &cbData); + + if (hres!=ERROR_SUCCESS) + { + RegCloseKey(clsidKey); + return REGDB_E_READREGDB; + } + + /* + * Allocate a buffer for the registry value. + */ + *pszUserType = CoTaskMemAlloc(cbData); + + if (*pszUserType==NULL) + { + RegCloseKey(clsidKey); + return E_OUTOFMEMORY; + } + + hres = RegQueryValueExA(HKEY_CLASSES_ROOT, + "", + NULL, + &dwKeyType, + (LPBYTE)*pszUserType, + &cbData); + + RegCloseKey(clsidKey); + + if (hres!=ERROR_SUCCESS) + { + CoTaskMemFree(*pszUserType); + *pszUserType=NULL; + + return REGDB_E_READREGDB; + } + + return S_OK; } /*********************************************************************** @@ -492,8 +583,193 @@ HRESULT WINAPI OleRegGetMiscStatus( DWORD dwAspect, DWORD* pdwStatus) { - FIXME(ole,"(),stub!\n"); - return REGDB_E_CLASSNOTREG; + char xclsid[50]; + char keyName[60]; + HKEY clsidKey; + HKEY miscStatusKey; + HKEY aspectKey; + LONG result; + + /* + * Initialize the out parameter. + */ + *pdwStatus = 0; + + /* + * Build the key name we're looking for + */ + WINE_StringFromCLSID((LPCLSID)clsid, xclsid); + + strcpy(keyName, "CLSID\\"); + strcat(keyName, xclsid); + strcat(keyName, "\\"); + + TRACE(ole,"(%s, %ld, %p)\n", keyName, dwAspect, pdwStatus); + + /* + * Open the class id Key + */ + result = RegOpenKeyA(HKEY_CLASSES_ROOT, + keyName, + &clsidKey); + + if (result != ERROR_SUCCESS) + return REGDB_E_CLASSNOTREG; + + /* + * Get the MiscStatus + */ + result = RegOpenKeyA(clsidKey, + "MiscStatus", + &miscStatusKey); + + + if (result != ERROR_SUCCESS) + { + RegCloseKey(clsidKey); + return REGDB_E_READREGDB; + } + + /* + * Read the default value + */ + OLEUTL_ReadRegistryDWORDValue(miscStatusKey, pdwStatus); + + /* + * Open the key specific to the requested aspect. + */ + sprintf(keyName, "%ld", dwAspect); + + result = RegOpenKeyA(miscStatusKey, + keyName, + &aspectKey); + + if (result == ERROR_SUCCESS) + { + OLEUTL_ReadRegistryDWORDValue(aspectKey, pdwStatus); + RegCloseKey(aspectKey); + } + + /* + * Cleanup + */ + RegCloseKey(miscStatusKey); + RegCloseKey(clsidKey); + + return S_OK; +} + +/****************************************************************************** + * OleSetContainedObject [OLE32.128] + */ +HRESULT WINAPI OleSetContainedObject( + LPUNKNOWN pUnknown, + BOOL fContained) +{ + IRunnableObject* runnable = NULL; + HRESULT hres; + + TRACE(ole,"(%p,%x), stub!\n", pUnknown, fContained); + + hres = IUnknown_QueryInterface(pUnknown, + &IID_IRunnableObject, + (void**)&runnable); + + if (SUCCEEDED(hres)) + { + hres = IRunnableObject_SetContainedObject(runnable, fContained); + + IRunnableObject_Release(runnable); + + return hres; + } + + return S_OK; +} + +/****************************************************************************** + * OleLoad [OLE32.112] + */ +HRESULT WINAPI OleLoad( + LPSTORAGE pStg, + REFIID riid, + LPOLECLIENTSITE pClientSite, + LPVOID* ppvObj) +{ + IPersistStorage* persistStorage = NULL; + IOleObject* oleObject = NULL; + STATSTG storageInfo; + HRESULT hres; + + TRACE(ole,"(%p,%p,%p,%p)\n", pStg, riid, pClientSite, ppvObj); + + /* + * TODO, Conversion ... OleDoAutoConvert + */ + + /* + * Get the class ID for the object. + */ + hres = IStorage_Stat(pStg, &storageInfo, STATFLAG_NONAME); + + /* + * Now, try and create the handler for the object + */ + hres = CoCreateInstance(&storageInfo.clsid, + NULL, + CLSCTX_INPROC_HANDLER, + &IID_IOleObject, + (void**)&oleObject); + + /* + * If that fails, as it will most times, load the default + * OLE handler. + */ + if (FAILED(hres)) + { + hres = OleCreateDefaultHandler(&storageInfo.clsid, + NULL, + &IID_IOleObject, + (void**)&oleObject); + } + + /* + * If we couldn't find a handler... this is bad. Abort the whole thing. + */ + if (FAILED(hres)) + return hres; + + /* + * Inform the new object of it's client site. + */ + hres = IOleObject_SetClientSite(oleObject, pClientSite); + + /* + * Initialize the object with it's IPersistStorage interface. + */ + hres = IOleObject_QueryInterface(oleObject, + &IID_IPersistStorage, + (void**)&persistStorage); + + if (SUCCEEDED(hres)) + { + IPersistStorage_Load(persistStorage, pStg); + + IPersistStorage_Release(persistStorage); + persistStorage = NULL; + } + + /* + * Return the requested interface to the caller. + */ + hres = IOleObject_QueryInterface(oleObject, riid, ppvObj); + + /* + * Cleanup interfaces used internally + */ + IOleObject_Release(oleObject); + + return hres; } /*********************************************************************** @@ -1739,4 +2015,49 @@ static DWORD OLEDD_GetButtonState() return keyMask; } +/*** + * OLEDD_GetButtonState() + * + * This method will read the default value of the registry key in + * parameter and extract a DWORD value from it. The registry key value + * can be in a string key or a DWORD key. + * + * params: + * regKey - Key to read the default value from + * pdwValue - Pointer to the location where the DWORD + * value is returned. This value is not modified + * if the value is not found. + */ + +static void OLEUTL_ReadRegistryDWORDValue( + HKEY regKey, + DWORD* pdwValue) +{ + char buffer[20]; + DWORD dwKeyType; + DWORD cbData = 20; + LONG lres; + + lres = RegQueryValueExA(regKey, + "", + NULL, + &dwKeyType, + (LPBYTE)buffer, + &cbData); + + if (lres==ERROR_SUCCESS) + { + switch (dwKeyType) + { + case REG_DWORD: + *pdwValue = *(DWORD*)buffer; + break; + case REG_EXPAND_SZ: + case REG_MULTI_SZ: + case REG_SZ: + *pdwValue = (DWORD)strtoul(buffer, NULL, 10); + break; + } + } +} diff --git a/ole/ole2stubs.c b/ole/ole2stubs.c index 224526eb825..4fdf40ede19 100644 --- a/ole/ole2stubs.c +++ b/ole/ole2stubs.c @@ -159,24 +159,6 @@ HRESULT WINAPI OleQueryCreateFromData(LPDATAOBJECT pSrcDataObject) return S_OK; } -/****************************************************************************** - * CreateDataAdviseHolder [OLE32.53] - */ -HRESULT WINAPI CreateDataAdviseHolder(LPDATAADVISEHOLDER* ppDAHolder) -{ - FIXME(ole,"(%p), stub!\n", ppDAHolder); - return S_OK; -} - -/****************************************************************************** - * OleLoad [OLE32.112] - */ -HRESULT WINAPI OleLoad(LPSTORAGE pStg, REFIID riid, LPOLECLIENTSITE pClientSite, LPVOID* ppvObj) -{ - FIXME(ole,"(%p,%p,%p,%p), stub!\n", pStg, riid, pClientSite, ppvObj); - return S_OK; -} - /****************************************************************************** * ReadFmtUserTypeStg [OLE32.136] */ @@ -206,15 +188,6 @@ HRESULT WINAPI OleRun(LPUNKNOWN pUnknown) return S_OK; } -/****************************************************************************** - * OleSetContainedObject [OLE32.128] - */ -HRESULT WINAPI OleSetContainedObject(LPUNKNOWN pUnknown, BOOL fContained) -{ - FIXME(ole,"(%p,%x), stub!\n", pUnknown, fContained); - return S_OK; -} - /****************************************************************************** * OleCreateLinkFromData [OLE32.95] */ @@ -228,15 +201,6 @@ HRESULT WINAPI OleCreateLinkFromData(LPDATAOBJECT pSrcDataObj, REFIID riid, return S_OK; } -/****************************************************************************** - * CreateDataCache [OLE32.54] - */ -HRESULT WINAPI CreateDataCache(LPUNKNOWN pUnkOuter, REFCLSID rclsid, REFIID iid, LPVOID* ppv) -{ - FIXME(ole,"(%p,%p,%p,%p), stub!\n", pUnkOuter, rclsid, iid, ppv); - return S_OK; -} - /****************************************************************************** * OleIsRunning [OLE32.111] */ @@ -255,6 +219,19 @@ HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum) return S_OK; } +/*********************************************************************** + * OleRegEnumFormatEtc [OLE32.119] + */ +HRESULT WINAPI OleRegEnumFormatEtc ( + REFCLSID clsid, + DWORD dwDirection, + LPENUMFORMATETC* ppenumFormatetc) +{ + FIXME(ole,"(%p, %ld, %p), stub!\n", clsid, dwDirection, ppenumFormatetc); + + return S_OK; +} + /*********************************************************************** * OleSave [OLE32.124] */ diff --git a/ole/oleobj.c b/ole/oleobj.c index 9157e2a262e..63cf2e85704 100644 --- a/ole/oleobj.c +++ b/ole/oleobj.c @@ -2,6 +2,7 @@ * OLE2 COM objects * * Copyright 1998 Eric Kohl + * Copyright 1999 Francis Beaudet */ @@ -15,150 +16,273 @@ DEFAULT_DEBUG_CHANNEL(ole) /************************************************************************** - * IOleAdviseHolder Implementation + * OleAdviseHolderImpl Implementation */ -typedef struct +typedef struct OleAdviseHolderImpl { - ICOM_VTABLE(IOleAdviseHolder)* lpvtbl; - DWORD ref; -} IOleAdviseHolderImpl; + ICOM_VTABLE(IOleAdviseHolder)* lpvtbl; -static HRESULT WINAPI IOleAdviseHolder_fnQueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*); -static ULONG WINAPI IOleAdviseHolder_fnAddRef(LPOLEADVISEHOLDER); -static ULONG WINAPI IOleAdviseHolder_fnRelease(LPOLEADVISEHOLDER); -static HRESULT WINAPI IOleAdviseHolder_fnAdvise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*); -static HRESULT WINAPI IOleAdviseHolder_fnUnadvise (LPOLEADVISEHOLDER, DWORD); -static HRESULT WINAPI IOleAdviseHolder_fnEnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **); -static HRESULT WINAPI IOleAdviseHolder_fnSendOnRename (LPOLEADVISEHOLDER, IMoniker *); -static HRESULT WINAPI IOleAdviseHolder_fnSendOnSave (LPOLEADVISEHOLDER); -static HRESULT WINAPI IOleAdviseHolder_fnSendOnClose (LPOLEADVISEHOLDER); + DWORD ref; + + DWORD maxSinks; + IAdviseSink** arrayOfSinks; + +} OleAdviseHolderImpl; + +static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor(); +static void OleAdviseHolderImpl_Destructor(OleAdviseHolderImpl* ptrToDestroy); +static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface(LPOLEADVISEHOLDER,REFIID,LPVOID*); +static ULONG WINAPI OleAdviseHolderImpl_AddRef(LPOLEADVISEHOLDER); +static ULONG WINAPI OleAdviseHolderImpl_Release(LPOLEADVISEHOLDER); +static HRESULT WINAPI OleAdviseHolderImpl_Advise(LPOLEADVISEHOLDER, IAdviseSink*, DWORD*); +static HRESULT WINAPI OleAdviseHolderImpl_Unadvise (LPOLEADVISEHOLDER, DWORD); +static HRESULT WINAPI OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER, IEnumSTATDATA **); +static HRESULT WINAPI OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER, IMoniker *); +static HRESULT WINAPI OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER); +static HRESULT WINAPI OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER); /************************************************************************** - * IOleAdviseHolder_VTable + * OleAdviseHolderImpl_VTable */ static struct ICOM_VTABLE(IOleAdviseHolder) oahvt = { - IOleAdviseHolder_fnQueryInterface, - IOleAdviseHolder_fnAddRef, - IOleAdviseHolder_fnRelease, - IOleAdviseHolder_fnAdvise, - IOleAdviseHolder_fnUnadvise, - IOleAdviseHolder_fnEnumAdvise, - IOleAdviseHolder_fnSendOnRename, - IOleAdviseHolder_fnSendOnSave, - IOleAdviseHolder_fnSendOnClose + OleAdviseHolderImpl_QueryInterface, + OleAdviseHolderImpl_AddRef, + OleAdviseHolderImpl_Release, + OleAdviseHolderImpl_Advise, + OleAdviseHolderImpl_Unadvise, + OleAdviseHolderImpl_EnumAdvise, + OleAdviseHolderImpl_SendOnRename, + OleAdviseHolderImpl_SendOnSave, + OleAdviseHolderImpl_SendOnClose }; /************************************************************************** - * IOleAdviseHolder_Constructor + * OleAdviseHolderImpl_Constructor */ -LPOLEADVISEHOLDER IOleAdviseHolder_Constructor() +static LPOLEADVISEHOLDER OleAdviseHolderImpl_Constructor() { - IOleAdviseHolderImpl* lpoah; + OleAdviseHolderImpl* lpoah; + DWORD index; - lpoah= (IOleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IOleAdviseHolderImpl)); - lpoah->ref = 1; - lpoah->lpvtbl = &oahvt; - FIXME (ole, "(%p)->()\n", lpoah); + lpoah= (OleAdviseHolderImpl*)HeapAlloc(GetProcessHeap(), + 0, + sizeof(OleAdviseHolderImpl)); + + lpoah->lpvtbl = &oahvt; + lpoah->ref = 1; + lpoah->maxSinks = 10; + lpoah->arrayOfSinks = HeapAlloc(GetProcessHeap(), + 0, + lpoah->maxSinks * sizeof(IAdviseSink*)); - return (LPOLEADVISEHOLDER)lpoah; + for (index = 0; index < lpoah->maxSinks; index++) + lpoah->arrayOfSinks[index]=0; + + return (LPOLEADVISEHOLDER)lpoah; } /************************************************************************** - * IOleAdviseHolder_QueryInterface + * OleAdviseHolderImpl_Destructor */ -static HRESULT WINAPI -IOleAdviseHolder_fnQueryInterface (LPOLEADVISEHOLDER iface, REFIID riid, LPVOID *ppvObj) +static void OleAdviseHolderImpl_Destructor( + OleAdviseHolderImpl* ptrToDestroy) { - ICOM_THIS(IOleAdviseHolderImpl, iface); - char xriid[50]; - WINE_StringFromCLSID((LPCLSID)riid,xriid); - FIXME (ole, "(%p)->(\n\tIID:\t%s)\n", This, xriid); + DWORD index; - *ppvObj = NULL; - - if(IsEqualIID(riid, &IID_IUnknown)) { - /* IUnknown */ - *ppvObj = This; - } - else if(IsEqualIID(riid, &IID_IOleAdviseHolder)) { - /* IOleAdviseHolder */ - *ppvObj = (IOleAdviseHolder*) This; + for (index = 0; index < ptrToDestroy->maxSinks; index++) + { + if (ptrToDestroy->arrayOfSinks[index]!=0) + { + IAdviseSink_Release(ptrToDestroy->arrayOfSinks[index]); + ptrToDestroy->arrayOfSinks[index] = NULL; } + } + + HeapFree(GetProcessHeap(), + 0, + ptrToDestroy->arrayOfSinks); + - if(*ppvObj) { - (*(LPOLEADVISEHOLDER*)ppvObj)->lpvtbl->fnAddRef(iface); - FIXME (ole, "-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj); - return S_OK; - } + HeapFree(GetProcessHeap(), + 0, + ptrToDestroy); +} - FIXME (ole, "-- Interface: E_NOINTERFACE\n"); +/************************************************************************** + * OleAdviseHolderImpl_QueryInterface + */ +static HRESULT WINAPI OleAdviseHolderImpl_QueryInterface( + LPOLEADVISEHOLDER iface, + REFIID riid, + LPVOID* ppvObj) +{ + ICOM_THIS(OleAdviseHolderImpl, iface); + + /* + * Sanity check + */ + if (ppvObj==NULL) + return E_POINTER; + + *ppvObj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown)) + { + /* IUnknown */ + *ppvObj = This; + } + else if(IsEqualIID(riid, &IID_IOleAdviseHolder)) + { + /* IOleAdviseHolder */ + *ppvObj = (IOleAdviseHolder*) This; + } + + if(*ppvObj == NULL) return E_NOINTERFACE; + + /* + * A successful QI always increments the reference count. + */ + IUnknown_AddRef((IUnknown*)*ppvObj); + + return S_OK; } /****************************************************************************** - * IOleAdviseHolder_AddRef + * OleAdviseHolderImpl_AddRef */ -static ULONG WINAPI -IOleAdviseHolder_fnAddRef (LPOLEADVISEHOLDER iface) +static ULONG WINAPI OleAdviseHolderImpl_AddRef( + LPOLEADVISEHOLDER iface) { - ICOM_THIS(IOleAdviseHolderImpl, iface); - FIXME (ole, "(%p)->(count=%lu)\n", This, This->ref); - return ++(This->ref); + ICOM_THIS(OleAdviseHolderImpl, iface); + + return ++(This->ref); } /****************************************************************************** - * IOleAdviseHolder_Release + * OleAdviseHolderImpl_Release */ -static ULONG WINAPI -IOleAdviseHolder_fnRelease (LPOLEADVISEHOLDER iface) +static ULONG WINAPI OleAdviseHolderImpl_Release( + LPOLEADVISEHOLDER iface) { - ICOM_THIS(IOleAdviseHolderImpl, iface); - FIXME (ole, "(%p)->(count=%lu)\n", This, This->ref); - if (!--(This->ref)) { - FIXME (ole, "-- destroying IOleAdviseHolder(%p)\n", This); - HeapFree(GetProcessHeap(),0,This); - return 0; - } - return This->ref; + ICOM_THIS(OleAdviseHolderImpl, iface); + + This->ref--; + + if (This->ref == 0) + { + OleAdviseHolderImpl_Destructor(This); + + return 0; + } + + return This->ref; } /****************************************************************************** - * IOleAdviseHolder_Advise + * OleAdviseHolderImpl_Advise + */ +static HRESULT WINAPI OleAdviseHolderImpl_Advise( + LPOLEADVISEHOLDER iface, + IAdviseSink* pAdvise, + DWORD* pdwConnection) +{ + DWORD index; + + ICOM_THIS(OleAdviseHolderImpl, iface); + + TRACE(ole, "(%p, %p, %p)\n", This, pAdvise, pdwConnection); + + /* + * Sanity check + */ + if (pdwConnection==NULL) + return E_POINTER; + + *pdwConnection = 0; + + /* + * Find a free spot in the array. + */ + for (index = 0; index < This->maxSinks; index++) + { + if (This->arrayOfSinks[index]==NULL) + break; + } + + /* + * If the array is full, we need to grow it. + */ + if (index == This->maxSinks) + { + DWORD i; + + This->maxSinks+=10; + + This->arrayOfSinks = HeapReAlloc(GetProcessHeap(), + 0, + This->arrayOfSinks, + This->maxSinks*sizeof(IAdviseSink*)); + + for (i=index;i < This->maxSinks; i++) + This->arrayOfSinks[i]=0; + } + + /* + * Store the new sink + */ + This->arrayOfSinks[index] = pAdvise; + + if (This->arrayOfSinks[index]!=NULL) + IAdviseSink_AddRef(This->arrayOfSinks[index]); + + /* + * Return the index as the cookie. + */ + *pdwConnection = index; + + return S_OK; +} + +/****************************************************************************** + * OleAdviseHolderImpl_Unadvise + */ +static HRESULT WINAPI OleAdviseHolderImpl_Unadvise( + LPOLEADVISEHOLDER iface, + DWORD dwConnection) +{ + ICOM_THIS(OleAdviseHolderImpl, iface); + + TRACE(ole, "(%p, %lu)\n", This, dwConnection); + + /* + * Check for invalid cookies. + */ + if (dwConnection >= This->maxSinks) + return OLE_E_NOCONNECTION; + + if (This->arrayOfSinks[dwConnection] == NULL) + return OLE_E_NOCONNECTION; + + /* + * Release the sink and mark the spot in the list as free. + */ + IAdviseSink_Release(This->arrayOfSinks[dwConnection]); + This->arrayOfSinks[dwConnection] = NULL; + + return S_OK; +} + +/****************************************************************************** + * OleAdviseHolderImpl_EnumAdvise */ static HRESULT WINAPI -IOleAdviseHolder_fnAdvise (LPOLEADVISEHOLDER iface, - IAdviseSink *pAdvise, DWORD *pdwConnection) +OleAdviseHolderImpl_EnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise) { - ICOM_THIS(IOleAdviseHolderImpl, iface); - FIXME (ole, "(%p)->(%p %p)\n", This, pAdvise, pdwConnection); - - *pdwConnection = 0; - - return S_OK; -} - -/****************************************************************************** - * IOleAdviseHolder_Unadvise - */ -static HRESULT WINAPI -IOleAdviseHolder_fnUnadvise (LPOLEADVISEHOLDER iface, DWORD dwConnection) -{ - ICOM_THIS(IOleAdviseHolderImpl, iface); - FIXME (ole, "(%p)->(%lu)\n", This, dwConnection); - - return S_OK; -} - -/****************************************************************************** - * IOleAdviseHolder_EnumAdvise - */ -static HRESULT WINAPI -IOleAdviseHolder_fnEnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAdvise) -{ - ICOM_THIS(IOleAdviseHolderImpl, iface); + ICOM_THIS(OleAdviseHolderImpl, iface); FIXME (ole, "(%p)->(%p)\n", This, ppenumAdvise); *ppenumAdvise = NULL; @@ -167,12 +291,12 @@ IOleAdviseHolder_fnEnumAdvise (LPOLEADVISEHOLDER iface, IEnumSTATDATA **ppenumAd } /****************************************************************************** - * IOleAdviseHolder_SendOnRename + * OleAdviseHolderImpl_SendOnRename */ static HRESULT WINAPI -IOleAdviseHolder_fnSendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk) +OleAdviseHolderImpl_SendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk) { - ICOM_THIS(IOleAdviseHolderImpl, iface); + ICOM_THIS(OleAdviseHolderImpl, iface); FIXME (ole, "(%p)->(%p)\n", This, pmk); @@ -180,12 +304,12 @@ IOleAdviseHolder_fnSendOnRename (LPOLEADVISEHOLDER iface, IMoniker *pmk) } /****************************************************************************** - * IOleAdviseHolder_SendOnSave + * OleAdviseHolderImpl_SendOnSave */ static HRESULT WINAPI -IOleAdviseHolder_fnSendOnSave (LPOLEADVISEHOLDER iface) +OleAdviseHolderImpl_SendOnSave (LPOLEADVISEHOLDER iface) { - ICOM_THIS(IOleAdviseHolderImpl, iface); + ICOM_THIS(OleAdviseHolderImpl, iface); FIXME (ole, "(%p)\n", This); @@ -193,18 +317,232 @@ IOleAdviseHolder_fnSendOnSave (LPOLEADVISEHOLDER iface) } /****************************************************************************** - * IOleAdviseHolder_SendOnClose + * OleAdviseHolderImpl_SendOnClose */ static HRESULT WINAPI -IOleAdviseHolder_fnSendOnClose (LPOLEADVISEHOLDER iface) +OleAdviseHolderImpl_SendOnClose (LPOLEADVISEHOLDER iface) { - ICOM_THIS(IOleAdviseHolderImpl, iface); + ICOM_THIS(OleAdviseHolderImpl, iface); FIXME (ole, "(%p)\n", This); return S_OK; } +/************************************************************************** + * DataAdviseHolder Implementation + */ +typedef struct DataAdviseHolder +{ + ICOM_VTABLE(IDataAdviseHolder)* lpvtbl; + + DWORD ref; +} DataAdviseHolder; + +/************************************************************************** + * DataAdviseHolder method prototypes + */ +static IDataAdviseHolder* DataAdviseHolder_Constructor(); +static void DataAdviseHolder_Destructor(DataAdviseHolder* ptrToDestroy); +static HRESULT WINAPI DataAdviseHolder_QueryInterface( + IDataAdviseHolder* iface, + REFIID riid, + void** ppvObject); +static ULONG WINAPI DataAdviseHolder_AddRef( + IDataAdviseHolder* iface); +static ULONG WINAPI DataAdviseHolder_Release( + IDataAdviseHolder* iface); +static HRESULT WINAPI DataAdviseHolder_Advise( + IDataAdviseHolder* iface, + IDataObject* pDataObject, + FORMATETC* pFetc, + DWORD advf, + IAdviseSink* pAdvise, + DWORD* pdwConnection); +static HRESULT WINAPI DataAdviseHolder_Unadvise( + IDataAdviseHolder* iface, + DWORD dwConnection); +static HRESULT WINAPI DataAdviseHolder_EnumAdvise( + IDataAdviseHolder* iface, + IEnumSTATDATA** ppenumAdvise); +static HRESULT WINAPI DataAdviseHolder_SendOnDataChange( + IDataAdviseHolder* iface, + IDataObject* pDataObject, + DWORD dwReserved, + DWORD advf); + +/************************************************************************** + * DataAdviseHolderImpl_VTable + */ +static struct ICOM_VTABLE(IDataAdviseHolder) DataAdviseHolderImpl_VTable = +{ + DataAdviseHolder_QueryInterface, + DataAdviseHolder_AddRef, + DataAdviseHolder_Release, + DataAdviseHolder_Advise, + DataAdviseHolder_Unadvise, + DataAdviseHolder_EnumAdvise, + DataAdviseHolder_SendOnDataChange +}; + +/****************************************************************************** + * DataAdviseHolder_Constructor + */ +static IDataAdviseHolder* DataAdviseHolder_Constructor() +{ + DataAdviseHolder* newHolder; + + newHolder = (DataAdviseHolder*)HeapAlloc(GetProcessHeap(), + 0, + sizeof(DataAdviseHolder)); + + newHolder->lpvtbl = &DataAdviseHolderImpl_VTable; + newHolder->ref = 1; + + return (IDataAdviseHolder*)newHolder; +} + +/****************************************************************************** + * DataAdviseHolder_Destructor + */ +static void DataAdviseHolder_Destructor( + DataAdviseHolder* ptrToDestroy) +{ + HeapFree(GetProcessHeap(), + 0, + ptrToDestroy); +} + +/************************************************************************ + * DataAdviseHolder_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI DataAdviseHolder_QueryInterface( + IDataAdviseHolder* iface, + REFIID riid, + void** ppvObject) +{ + ICOM_THIS(DataAdviseHolder, iface); + + /* + * Perform a sanity check on the parameters. + */ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if ( (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) || + (memcmp(&IID_IDataAdviseHolder, riid, sizeof(IID_IDataAdviseHolder)) == 0) ) + { + *ppvObject = iface; + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + { + return E_NOINTERFACE; + } + + /* + * Query Interface always increases the reference count by one when it is + * successful. + */ + IUnknown_AddRef((IUnknown*)*ppvObject); + + return S_OK;; +} + +/************************************************************************ + * DataAdviseHolder_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataAdviseHolder_AddRef( + IDataAdviseHolder* iface) +{ + ICOM_THIS(DataAdviseHolder, iface); + + This->ref++; + + return This->ref; +} + +/************************************************************************ + * DataAdviseHolder_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI DataAdviseHolder_Release( + IDataAdviseHolder* iface) +{ + ICOM_THIS(DataAdviseHolder, iface); + + /* + * Decrease the reference count on this object. + */ + This->ref--; + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (This->ref==0) + { + DataAdviseHolder_Destructor(This); + + return 0; + } + + return This->ref; +} + +static HRESULT WINAPI DataAdviseHolder_Advise( + IDataAdviseHolder* iface, + IDataObject* pDataObject, + FORMATETC* pFetc, + DWORD advf, + IAdviseSink* pAdvise, + DWORD* pdwConnection) +{ + FIXME(ole, "(): stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataAdviseHolder_Unadvise( + IDataAdviseHolder* iface, + DWORD dwConnection) +{ + FIXME(ole, "(): stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataAdviseHolder_EnumAdvise( + IDataAdviseHolder* iface, + IEnumSTATDATA** ppenumAdvise) +{ + FIXME(ole, "(): stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI DataAdviseHolder_SendOnDataChange( + IDataAdviseHolder* iface, + IDataObject* pDataObject, + DWORD dwReserved, + DWORD advf) +{ + FIXME(ole, "(): stub\n"); + return E_NOTIMPL; +} + /*********************************************************************** * API functions */ @@ -212,15 +550,44 @@ IOleAdviseHolder_fnSendOnClose (LPOLEADVISEHOLDER iface) /*********************************************************************** * CreateOleAdviseHolder [OLE32.59] */ -HRESULT WINAPI CreateOleAdviseHolder (LPOLEADVISEHOLDER *ppOAHolder) +HRESULT WINAPI CreateOleAdviseHolder( + LPOLEADVISEHOLDER *ppOAHolder) { - FIXME(ole,"(%p): stub!\n", ppOAHolder); + TRACE(ole, "(%p)\n", ppOAHolder); - *ppOAHolder = IOleAdviseHolder_Constructor (); - if (*ppOAHolder) - return S_OK; + /* + * Sanity check, + */ + if (ppOAHolder==NULL) + return E_POINTER; - *ppOAHolder = 0; - return E_OUTOFMEMORY; + *ppOAHolder = OleAdviseHolderImpl_Constructor (); + + if (*ppOAHolder != NULL) + return S_OK; + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * CreateDataAdviseHolder [OLE32.53] + */ +HRESULT WINAPI CreateDataAdviseHolder( + LPDATAADVISEHOLDER* ppDAHolder) +{ + TRACE(ole,"(%p)\n", ppDAHolder); + + /* + * Sanity check, + */ + if (ppDAHolder==NULL) + return E_POINTER; + + *ppDAHolder = DataAdviseHolder_Constructor(); + + if (*ppDAHolder != NULL) + return S_OK; + + return E_OUTOFMEMORY; } diff --git a/relay32/ole32.spec b/relay32/ole32.spec index 766ad445138..f631705ef98 100644 --- a/relay32/ole32.spec +++ b/relay32/ole32.spec @@ -90,7 +90,7 @@ type win32 87 stub OleConvertOLESTREAMToIStorage 88 stub OleConvertOLESTREAMToIStorageEx 89 stdcall OleCreate(ptr ptr long ptr ptr ptr ptr) OleCreate - 90 stub OleCreateDefaultHandler + 90 stdcall OleCreateDefaultHandler(ptr ptr ptr ptr) OleCreateDefaultHandler 91 stub OleCreateEmbeddingHelper 92 stdcall OleCreateFromData(ptr ptr long ptr ptr ptr ptr) OleCreateFromData 93 stdcall OleCreateFromFile(ptr ptr ptr long ptr ptr ptr ptr) OleCreateFromFile @@ -119,7 +119,7 @@ type win32 116 stub OleNoteObjectVisible 117 stdcall OleQueryCreateFromData(ptr) OleQueryCreateFromData 118 stdcall OleQueryLinkFromData(ptr) OleQueryLinkFromData -119 stub OleRegEnumFormatEtc +119 stdcall OleRegEnumFormatEtc(ptr long ptr) OleRegEnumFormatEtc 120 stdcall OleRegEnumVerbs(long ptr) OleRegEnumVerbs 121 stdcall OleRegGetMiscStatus(ptr long ptr) OleRegGetMiscStatus 122 stdcall OleRegGetUserType(long long ptr) OleRegGetUserType