2 * OLE 2 default object handler
4 * Copyright 1999 Francis Beaudet
5 * Copyright 2000 Abey George
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * The OLE2 default object handler supports a whole whack of
23 * interfaces including:
24 * IOleObject, IDataObject, IPersistStorage, IViewObject2,
25 * IRunnableObject, IOleCache2, IOleCacheControl and much more.
27 * All the implementation details are taken from: Inside OLE
28 * second edition by Kraig Brockschmidt,
31 * - This implementation of the default handler does not launch the
32 * server in the DoVerb, Update, GetData, GetDataHere and Run
33 * methods. When it is fixed to do so, all the methods will have
34 * to be revisited to allow delegating to the running object
36 * - All methods in the class that use the class ID should be
37 * aware that it is possible for a class to be treated as
38 * another one and go into emulation mode. Nothing has been
41 * - Some functions still return E_NOTIMPL they have to be
42 * implemented. Most of those are related to the running of the
45 * - All the methods related to notification and advise sinks are
46 * in place but no notifications are sent to the sinks yet.
58 #include "wine/unicode.h"
60 #include "wine/debug.h"
62 WINE_DEFAULT_DEBUG_CHANNEL(ole);
64 /****************************************************************************
70 const IOleObjectVtbl* lpVtbl;
71 const IUnknownVtbl* lpvtblIUnknown;
72 const IDataObjectVtbl* lpvtblIDataObject;
73 const IRunnableObjectVtbl* lpvtblIRunnableObject;
75 /* Reference count of this object */
78 /* IUnknown implementation of the outer object. */
79 IUnknown* outerUnknown;
81 /* Class Id that this handler object represents. */
84 /* IUnknown implementation of the datacache. */
87 /* Client site for the embedded object. */
88 IOleClientSite* clientSite;
91 * The IOleAdviseHolder maintains the connections
92 * on behalf of the default handler.
94 IOleAdviseHolder* oleAdviseHolder;
97 * The IDataAdviseHolder maintains the data
98 * connections on behalf of the default handler.
100 IDataAdviseHolder* dataAdviseHolder;
102 /* Name of the container and object contained */
106 /* IOleObject delegate */
107 IOleObject *pOleDelegate;
108 /* IPersistStorage delegate */
109 IPersistStorage *pPSDelegate;
112 typedef struct DefaultHandler DefaultHandler;
115 * Here, I define utility functions to help with the casting of the
117 * There is a version to accommodate all of the VTables implemented
120 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
122 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpVtbl));
125 static inline DefaultHandler *impl_from_NDIUnknown( IUnknown *iface )
127 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIUnknown));
130 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
132 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIDataObject));
135 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
137 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
140 static void DefaultHandler_Destroy(DefaultHandler* This);
143 /*********************************************************
144 * Method implementation for the non delegating IUnknown
145 * part of the DefaultHandler class.
148 /************************************************************************
149 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
151 * See Windows documentation for more details on IUnknown methods.
153 * This version of QueryInterface will not delegate it's implementation
154 * to the outer unknown.
156 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
161 DefaultHandler *This = impl_from_NDIUnknown(iface);
163 /* Perform a sanity check on the parameters. */
169 if (IsEqualIID(&IID_IUnknown, riid))
171 else if (IsEqualIID(&IID_IOleObject, riid))
172 *ppvObject = (IOleObject*)&This->lpVtbl;
173 else if (IsEqualIID(&IID_IDataObject, riid))
174 *ppvObject = (IDataObject*)&This->lpvtblIDataObject;
175 else if (IsEqualIID(&IID_IRunnableObject, riid))
176 *ppvObject = (IRunnableObject*)&This->lpvtblIRunnableObject;
180 * Blind aggregate the data cache to "inherit" it's interfaces.
182 if (IUnknown_QueryInterface(This->dataCache, riid, ppvObject) == S_OK)
186 /* Check that we obtained an interface. */
187 if (*ppvObject == NULL)
189 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
190 return E_NOINTERFACE;
194 * Query Interface always increases the reference count by one when it is
197 IUnknown_AddRef((IUnknown*)*ppvObject);
202 /************************************************************************
203 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
205 * See Windows documentation for more details on IUnknown methods.
207 * This version of QueryInterface will not delegate it's implementation
208 * to the outer unknown.
210 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
213 DefaultHandler *This = impl_from_NDIUnknown(iface);
214 return InterlockedIncrement(&This->ref);
217 /************************************************************************
218 * DefaultHandler_NDIUnknown_Release (IUnknown)
220 * See Windows documentation for more details on IUnknown methods.
222 * This version of QueryInterface will not delegate it's implementation
223 * to the outer unknown.
225 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
228 DefaultHandler *This = impl_from_NDIUnknown(iface);
231 /* Decrease the reference count on this object. */
232 ref = InterlockedDecrement(&This->ref);
234 if (!ref) DefaultHandler_Destroy(This);
239 /*********************************************************
240 * Methods implementation for the IOleObject part of
241 * the DefaultHandler class.
244 /************************************************************************
245 * DefaultHandler_QueryInterface (IUnknown)
247 * See Windows documentation for more details on IUnknown methods.
249 static HRESULT WINAPI DefaultHandler_QueryInterface(
254 DefaultHandler *This = impl_from_IOleObject(iface);
256 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
259 /************************************************************************
260 * DefaultHandler_AddRef (IUnknown)
262 * See Windows documentation for more details on IUnknown methods.
264 static ULONG WINAPI DefaultHandler_AddRef(
267 DefaultHandler *This = impl_from_IOleObject(iface);
269 return IUnknown_AddRef(This->outerUnknown);
272 /************************************************************************
273 * DefaultHandler_Release (IUnknown)
275 * See Windows documentation for more details on IUnknown methods.
277 static ULONG WINAPI DefaultHandler_Release(
280 DefaultHandler *This = impl_from_IOleObject(iface);
282 return IUnknown_Release(This->outerUnknown);
285 /************************************************************************
286 * DefaultHandler_SetClientSite (IOleObject)
288 * The default handler's implementation of this method only keeps the
289 * client site pointer for future reference.
291 * See Windows documentation for more details on IOleObject methods.
293 static HRESULT WINAPI DefaultHandler_SetClientSite(
295 IOleClientSite* pClientSite)
297 DefaultHandler *This = impl_from_IOleObject(iface);
299 TRACE("(%p, %p)\n", iface, pClientSite);
302 * Make sure we release the previous client site if there
305 if (This->clientSite)
306 IOleClientSite_Release(This->clientSite);
308 This->clientSite = pClientSite;
310 if (This->clientSite)
311 IOleClientSite_AddRef(This->clientSite);
316 /************************************************************************
317 * DefaultHandler_GetClientSite (IOleObject)
319 * The default handler's implementation of this method returns the
320 * last pointer set in IOleObject_SetClientSite.
322 * See Windows documentation for more details on IOleObject methods.
324 static HRESULT WINAPI DefaultHandler_GetClientSite(
326 IOleClientSite** ppClientSite)
328 DefaultHandler *This = impl_from_IOleObject(iface);
334 *ppClientSite = This->clientSite;
336 if (This->clientSite)
337 IOleClientSite_AddRef(This->clientSite);
342 /************************************************************************
343 * DefaultHandler_SetHostNames (IOleObject)
345 * The default handler's implementation of this method just stores
346 * the strings and returns S_OK.
348 * See Windows documentation for more details on IOleObject methods.
350 static HRESULT WINAPI DefaultHandler_SetHostNames(
352 LPCOLESTR szContainerApp,
353 LPCOLESTR szContainerObj)
355 DefaultHandler *This = impl_from_IOleObject(iface);
357 TRACE("(%p, %s, %s)\n",
359 debugstr_w(szContainerApp),
360 debugstr_w(szContainerObj));
362 /* Be sure to cleanup before re-assinging the strings. */
363 HeapFree( GetProcessHeap(), 0, This->containerApp );
364 This->containerApp = NULL;
365 HeapFree( GetProcessHeap(), 0, This->containerObj );
366 This->containerObj = NULL;
368 /* Copy the string supplied. */
371 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
372 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
373 strcpyW( This->containerApp, szContainerApp );
378 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
379 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
380 strcpyW( This->containerObj, szContainerObj );
385 /************************************************************************
386 * DefaultHandler_Close (IOleObject)
388 * The default handler's implementation of this method is meaningless
389 * without a running server so it does nothing.
391 * See Windows documentation for more details on IOleObject methods.
393 static HRESULT WINAPI DefaultHandler_Close(
401 /************************************************************************
402 * DefaultHandler_SetMoniker (IOleObject)
404 * The default handler's implementation of this method does nothing.
406 * See Windows documentation for more details on IOleObject methods.
408 static HRESULT WINAPI DefaultHandler_SetMoniker(
410 DWORD dwWhichMoniker,
413 TRACE("(%p, %ld, %p)\n",
421 /************************************************************************
422 * DefaultHandler_GetMoniker (IOleObject)
424 * Delegate this request to the client site if we have one.
426 * See Windows documentation for more details on IOleObject methods.
428 static HRESULT WINAPI DefaultHandler_GetMoniker(
431 DWORD dwWhichMoniker,
434 DefaultHandler *This = impl_from_IOleObject(iface);
436 TRACE("(%p, %ld, %ld, %p)\n",
437 iface, dwAssign, dwWhichMoniker, ppmk);
439 if (This->clientSite)
441 return IOleClientSite_GetMoniker(This->clientSite,
451 /************************************************************************
452 * DefaultHandler_InitFromData (IOleObject)
454 * This method is meaningless if the server is not running
456 * See Windows documentation for more details on IOleObject methods.
458 static HRESULT WINAPI DefaultHandler_InitFromData(
460 IDataObject* pDataObject,
464 TRACE("(%p, %p, %d, %ld)\n",
465 iface, pDataObject, fCreation, dwReserved);
467 return OLE_E_NOTRUNNING;
470 /************************************************************************
471 * DefaultHandler_GetClipboardData (IOleObject)
473 * This method is meaningless if the server is not running
475 * See Windows documentation for more details on IOleObject methods.
477 static HRESULT WINAPI DefaultHandler_GetClipboardData(
480 IDataObject** ppDataObject)
482 TRACE("(%p, %ld, %p)\n",
483 iface, dwReserved, ppDataObject);
485 return OLE_E_NOTRUNNING;
488 static HRESULT WINAPI DefaultHandler_DoVerb(
491 struct tagMSG* lpmsg,
492 IOleClientSite* pActiveSite,
501 /************************************************************************
502 * DefaultHandler_EnumVerbs (IOleObject)
504 * The default handler implementation of this method simply delegates
507 * See Windows documentation for more details on IOleObject methods.
509 static HRESULT WINAPI DefaultHandler_EnumVerbs(
511 IEnumOLEVERB** ppEnumOleVerb)
513 DefaultHandler *This = impl_from_IOleObject(iface);
515 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
517 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
520 static HRESULT WINAPI DefaultHandler_Update(
527 /************************************************************************
528 * DefaultHandler_IsUpToDate (IOleObject)
530 * This method is meaningless if the server is not running
532 * See Windows documentation for more details on IOleObject methods.
534 static HRESULT WINAPI DefaultHandler_IsUpToDate(
537 TRACE("(%p)\n", iface);
539 return OLE_E_NOTRUNNING;
542 /************************************************************************
543 * DefaultHandler_GetUserClassID (IOleObject)
545 * TODO: Map to a new class ID if emulation is active.
547 * See Windows documentation for more details on IOleObject methods.
549 static HRESULT WINAPI DefaultHandler_GetUserClassID(
553 DefaultHandler *This = impl_from_IOleObject(iface);
555 TRACE("(%p, %p)\n", iface, pClsid);
561 memcpy(pClsid, &This->clsid, sizeof(CLSID));
566 /************************************************************************
567 * DefaultHandler_GetUserType (IOleObject)
569 * The default handler implementation of this method simply delegates
570 * to OleRegGetUserType
572 * See Windows documentation for more details on IOleObject methods.
574 static HRESULT WINAPI DefaultHandler_GetUserType(
577 LPOLESTR* pszUserType)
579 DefaultHandler *This = impl_from_IOleObject(iface);
581 TRACE("(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType);
583 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
586 /************************************************************************
587 * DefaultHandler_SetExtent (IOleObject)
589 * This method is meaningless if the server is not running
591 * See Windows documentation for more details on IOleObject methods.
593 static HRESULT WINAPI DefaultHandler_SetExtent(
598 TRACE("(%p, %lx, (%ld x %ld))\n", iface,
599 dwDrawAspect, psizel->cx, psizel->cy);
600 return OLE_E_NOTRUNNING;
603 /************************************************************************
604 * DefaultHandler_GetExtent (IOleObject)
606 * The default handler's implementation of this method returns uses
607 * the cache to locate the aspect and extract the extent from it.
609 * See Windows documentation for more details on IOleObject methods.
611 static HRESULT WINAPI DefaultHandler_GetExtent(
616 DVTARGETDEVICE* targetDevice;
617 IViewObject2* cacheView = NULL;
620 DefaultHandler *This = impl_from_IOleObject(iface);
622 TRACE("(%p, %lx, %p)\n", iface, dwDrawAspect, psizel);
624 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
630 * Prepare the call to the cache's GetExtent method.
632 * Here we would build a valid DVTARGETDEVICE structure
633 * but, since we are calling into the data cache, we
634 * know it's implementation and we'll skip this
635 * extra work until later.
639 hres = IViewObject2_GetExtent(cacheView,
648 IViewObject2_Release(cacheView);
653 /************************************************************************
654 * DefaultHandler_Advise (IOleObject)
656 * The default handler's implementation of this method simply
657 * delegates to the OleAdviseHolder.
659 * See Windows documentation for more details on IOleObject methods.
661 static HRESULT WINAPI DefaultHandler_Advise(
663 IAdviseSink* pAdvSink,
664 DWORD* pdwConnection)
667 DefaultHandler *This = impl_from_IOleObject(iface);
669 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
671 /* Make sure we have an advise holder before we start. */
672 if (!This->oleAdviseHolder)
673 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
676 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
683 /************************************************************************
684 * DefaultHandler_Unadvise (IOleObject)
686 * The default handler's implementation of this method simply
687 * delegates to the OleAdviseHolder.
689 * See Windows documentation for more details on IOleObject methods.
691 static HRESULT WINAPI DefaultHandler_Unadvise(
695 DefaultHandler *This = impl_from_IOleObject(iface);
697 TRACE("(%p, %ld)\n", iface, dwConnection);
700 * If we don't have an advise holder yet, it means we don't have
703 if (!This->oleAdviseHolder)
704 return OLE_E_NOCONNECTION;
706 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
710 /************************************************************************
711 * DefaultHandler_EnumAdvise (IOleObject)
713 * The default handler's implementation of this method simply
714 * delegates to the OleAdviseHolder.
716 * See Windows documentation for more details on IOleObject methods.
718 static HRESULT WINAPI DefaultHandler_EnumAdvise(
720 IEnumSTATDATA** ppenumAdvise)
722 DefaultHandler *This = impl_from_IOleObject(iface);
724 TRACE("(%p, %p)\n", iface, ppenumAdvise);
730 *ppenumAdvise = NULL;
732 if (!This->oleAdviseHolder)
733 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder,
739 /************************************************************************
740 * DefaultHandler_GetMiscStatus (IOleObject)
742 * The default handler's implementation of this method simply delegates
743 * to OleRegGetMiscStatus.
745 * See Windows documentation for more details on IOleObject methods.
747 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
753 DefaultHandler *This = impl_from_IOleObject(iface);
755 TRACE("(%p, %lx, %p)\n", iface, dwAspect, pdwStatus);
757 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
765 /************************************************************************
766 * DefaultHandler_SetExtent (IOleObject)
768 * This method is meaningless if the server is not running
770 * See Windows documentation for more details on IOleObject methods.
772 static HRESULT WINAPI DefaultHandler_SetColorScheme(
774 struct tagLOGPALETTE* pLogpal)
776 TRACE("(%p, %p))\n", iface, pLogpal);
777 return OLE_E_NOTRUNNING;
780 /*********************************************************
781 * Methods implementation for the IDataObject part of
782 * the DefaultHandler class.
785 /************************************************************************
786 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
788 * See Windows documentation for more details on IUnknown methods.
790 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
795 DefaultHandler *This = impl_from_IDataObject(iface);
797 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
800 /************************************************************************
801 * DefaultHandler_IDataObject_AddRef (IUnknown)
803 * See Windows documentation for more details on IUnknown methods.
805 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
808 DefaultHandler *This = impl_from_IDataObject(iface);
810 return IUnknown_AddRef(This->outerUnknown);
813 /************************************************************************
814 * DefaultHandler_IDataObject_Release (IUnknown)
816 * See Windows documentation for more details on IUnknown methods.
818 static ULONG WINAPI DefaultHandler_IDataObject_Release(
821 DefaultHandler *This = impl_from_IDataObject(iface);
823 return IUnknown_Release(This->outerUnknown);
826 /************************************************************************
827 * DefaultHandler_GetData
829 * Get Data from a source dataobject using format pformatetcIn->cfFormat
830 * See Windows documentation for more details on GetData.
831 * Default handler's implementation of this method delegates to the cache.
833 static HRESULT WINAPI DefaultHandler_GetData(
835 LPFORMATETC pformatetcIn,
838 IDataObject* cacheDataObject = NULL;
841 DefaultHandler *This = impl_from_IDataObject(iface);
843 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
845 hres = IUnknown_QueryInterface(This->dataCache,
847 (void**)&cacheDataObject);
852 hres = IDataObject_GetData(cacheDataObject,
856 IDataObject_Release(cacheDataObject);
861 static HRESULT WINAPI DefaultHandler_GetDataHere(
863 LPFORMATETC pformatetc,
870 /************************************************************************
871 * DefaultHandler_QueryGetData (IDataObject)
873 * The default handler's implementation of this method delegates to
876 * See Windows documentation for more details on IDataObject methods.
878 static HRESULT WINAPI DefaultHandler_QueryGetData(
880 LPFORMATETC pformatetc)
882 IDataObject* cacheDataObject = NULL;
885 DefaultHandler *This = impl_from_IDataObject(iface);
887 TRACE("(%p, %p)\n", iface, pformatetc);
889 hres = IUnknown_QueryInterface(This->dataCache,
891 (void**)&cacheDataObject);
896 hres = IDataObject_QueryGetData(cacheDataObject,
899 IDataObject_Release(cacheDataObject);
904 /************************************************************************
905 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
907 * This method is meaningless if the server is not running
909 * See Windows documentation for more details on IDataObject methods.
911 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
913 LPFORMATETC pformatectIn,
914 LPFORMATETC pformatetcOut)
916 FIXME("(%p, %p, %p)\n", iface, pformatectIn, pformatetcOut);
918 return OLE_E_NOTRUNNING;
921 /************************************************************************
922 * DefaultHandler_SetData (IDataObject)
924 * The default handler's implementation of this method delegates to
927 * See Windows documentation for more details on IDataObject methods.
929 static HRESULT WINAPI DefaultHandler_SetData(
931 LPFORMATETC pformatetc,
935 IDataObject* cacheDataObject = NULL;
938 DefaultHandler *This = impl_from_IDataObject(iface);
940 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
942 hres = IUnknown_QueryInterface(This->dataCache,
944 (void**)&cacheDataObject);
949 hres = IDataObject_SetData(cacheDataObject,
954 IDataObject_Release(cacheDataObject);
959 /************************************************************************
960 * DefaultHandler_EnumFormatEtc (IDataObject)
962 * The default handler's implementation of This method simply delegates
963 * to OleRegEnumFormatEtc.
965 * See Windows documentation for more details on IDataObject methods.
967 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
970 IEnumFORMATETC** ppenumFormatEtc)
973 DefaultHandler *This = impl_from_IDataObject(iface);
975 TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
977 hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
982 /************************************************************************
983 * DefaultHandler_DAdvise (IDataObject)
985 * The default handler's implementation of this method simply
986 * delegates to the DataAdviseHolder.
988 * See Windows documentation for more details on IDataObject methods.
990 static HRESULT WINAPI DefaultHandler_DAdvise(
992 FORMATETC* pformatetc,
994 IAdviseSink* pAdvSink,
995 DWORD* pdwConnection)
998 DefaultHandler *This = impl_from_IDataObject(iface);
1000 TRACE("(%p, %p, %ld, %p, %p)\n",
1001 iface, pformatetc, advf, pAdvSink, pdwConnection);
1003 /* Make sure we have a data advise holder before we start. */
1004 if (!This->dataAdviseHolder)
1005 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1007 if (SUCCEEDED(hres))
1008 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1018 /************************************************************************
1019 * DefaultHandler_DUnadvise (IDataObject)
1021 * The default handler's implementation of this method simply
1022 * delegates to the DataAdviseHolder.
1024 * See Windows documentation for more details on IDataObject methods.
1026 static HRESULT WINAPI DefaultHandler_DUnadvise(
1030 DefaultHandler *This = impl_from_IDataObject(iface);
1032 TRACE("(%p, %ld)\n", iface, dwConnection);
1035 * If we don't have a data advise holder yet, it means that
1036 * we don't have any connections..
1038 if (!This->dataAdviseHolder)
1039 return OLE_E_NOCONNECTION;
1041 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1045 /************************************************************************
1046 * DefaultHandler_EnumDAdvise (IDataObject)
1048 * The default handler's implementation of this method simply
1049 * delegates to the DataAdviseHolder.
1051 * See Windows documentation for more details on IDataObject methods.
1053 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1055 IEnumSTATDATA** ppenumAdvise)
1057 DefaultHandler *This = impl_from_IDataObject(iface);
1059 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1065 *ppenumAdvise = NULL;
1067 /* If we have a data advise holder object, delegate. */
1068 if (This->dataAdviseHolder)
1069 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1075 /*********************************************************
1076 * Methods implementation for the IRunnableObject part
1077 * of the DefaultHandler class.
1080 /************************************************************************
1081 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1083 * See Windows documentation for more details on IUnknown methods.
1085 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1086 IRunnableObject* iface,
1090 DefaultHandler *This = impl_from_IRunnableObject(iface);
1092 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1095 /************************************************************************
1096 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1098 * See Windows documentation for more details on IUnknown methods.
1100 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1101 IRunnableObject* iface)
1103 DefaultHandler *This = impl_from_IRunnableObject(iface);
1105 return IUnknown_AddRef(This->outerUnknown);
1108 /************************************************************************
1109 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1111 * See Windows documentation for more details on IUnknown methods.
1113 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1114 IRunnableObject* iface)
1116 DefaultHandler *This = impl_from_IRunnableObject(iface);
1118 return IUnknown_Release(This->outerUnknown);
1121 /************************************************************************
1122 * DefaultHandler_GetRunningClass (IRunnableObject)
1124 * See Windows documentation for more details on IRunnableObject methods.
1126 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1127 IRunnableObject* iface,
1134 static HRESULT WINAPI DefaultHandler_Run(
1135 IRunnableObject* iface,
1138 DefaultHandler *This = impl_from_IRunnableObject(iface);
1141 FIXME("(%p): semi-stub\n", pbc);
1143 /* already running? if so nothing to do */
1144 if (This->pOleDelegate)
1147 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER, &IID_IOleObject, (void **)&This->pOleDelegate);
1151 if (This->clientSite)
1152 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1156 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
1157 if (This->pPSDelegate)
1158 hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
1161 if (SUCCEEDED(hr) && This->containerApp)
1162 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp, This->containerObj);
1164 /* FIXME: do more stuff here:
1165 * - IOleObject_GetMiscStatus
1166 * - IOleObject_Advise
1167 * - IOleObject_GetMoniker
1168 * - advise data cache that we've connected somehow?
1171 /* FIXME: if we failed, Close the object */
1176 /************************************************************************
1177 * DefaultHandler_IsRunning (IRunnableObject)
1179 * See Windows documentation for more details on IRunnableObject methods.
1181 static BOOL WINAPI DefaultHandler_IsRunning(
1182 IRunnableObject* iface)
1184 DefaultHandler *This = impl_from_IRunnableObject(iface);
1188 if (This->pOleDelegate)
1194 /************************************************************************
1195 * DefaultHandler_LockRunning (IRunnableObject)
1197 * See Windows documentation for more details on IRunnableObject methods.
1199 static HRESULT WINAPI DefaultHandler_LockRunning(
1200 IRunnableObject* iface,
1202 BOOL fLastUnlockCloses)
1208 /************************************************************************
1209 * DefaultHandler_SetContainedObject (IRunnableObject)
1211 * See Windows documentation for more details on IRunnableObject methods.
1213 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1214 IRunnableObject* iface,
1222 * Virtual function tables for the DefaultHandler class.
1224 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1226 DefaultHandler_QueryInterface,
1227 DefaultHandler_AddRef,
1228 DefaultHandler_Release,
1229 DefaultHandler_SetClientSite,
1230 DefaultHandler_GetClientSite,
1231 DefaultHandler_SetHostNames,
1232 DefaultHandler_Close,
1233 DefaultHandler_SetMoniker,
1234 DefaultHandler_GetMoniker,
1235 DefaultHandler_InitFromData,
1236 DefaultHandler_GetClipboardData,
1237 DefaultHandler_DoVerb,
1238 DefaultHandler_EnumVerbs,
1239 DefaultHandler_Update,
1240 DefaultHandler_IsUpToDate,
1241 DefaultHandler_GetUserClassID,
1242 DefaultHandler_GetUserType,
1243 DefaultHandler_SetExtent,
1244 DefaultHandler_GetExtent,
1245 DefaultHandler_Advise,
1246 DefaultHandler_Unadvise,
1247 DefaultHandler_EnumAdvise,
1248 DefaultHandler_GetMiscStatus,
1249 DefaultHandler_SetColorScheme
1252 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1254 DefaultHandler_NDIUnknown_QueryInterface,
1255 DefaultHandler_NDIUnknown_AddRef,
1256 DefaultHandler_NDIUnknown_Release,
1259 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1261 DefaultHandler_IDataObject_QueryInterface,
1262 DefaultHandler_IDataObject_AddRef,
1263 DefaultHandler_IDataObject_Release,
1264 DefaultHandler_GetData,
1265 DefaultHandler_GetDataHere,
1266 DefaultHandler_QueryGetData,
1267 DefaultHandler_GetCanonicalFormatEtc,
1268 DefaultHandler_SetData,
1269 DefaultHandler_EnumFormatEtc,
1270 DefaultHandler_DAdvise,
1271 DefaultHandler_DUnadvise,
1272 DefaultHandler_EnumDAdvise
1275 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1277 DefaultHandler_IRunnableObject_QueryInterface,
1278 DefaultHandler_IRunnableObject_AddRef,
1279 DefaultHandler_IRunnableObject_Release,
1280 DefaultHandler_GetRunningClass,
1282 DefaultHandler_IsRunning,
1283 DefaultHandler_LockRunning,
1284 DefaultHandler_SetContainedObject
1287 /*********************************************************
1288 * Methods implementation for the DefaultHandler class.
1290 static DefaultHandler* DefaultHandler_Construct(
1292 LPUNKNOWN pUnkOuter)
1294 DefaultHandler* This = NULL;
1297 * Allocate space for the object.
1299 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1304 This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1305 This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1306 This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1307 This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1310 * Start with one reference count. The caller of this function
1311 * must release the interface pointer when it is done.
1316 * Initialize the outer unknown
1317 * We don't keep a reference on the outer unknown since, the way
1318 * aggregation works, our lifetime is at least as large as it's
1322 pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1324 This->outerUnknown = pUnkOuter;
1327 * Create a datacache object.
1328 * We aggregate with the datacache. Make sure we pass our outer
1329 * unknown as the datacache's outer unknown.
1331 CreateDataCache(This->outerUnknown,
1334 (void**)&This->dataCache);
1337 * Initialize the other data members of the class.
1339 memcpy(&This->clsid, clsid, sizeof(CLSID));
1340 This->clientSite = NULL;
1341 This->oleAdviseHolder = NULL;
1342 This->dataAdviseHolder = NULL;
1343 This->containerApp = NULL;
1344 This->containerObj = NULL;
1345 This->pOleDelegate = NULL;
1346 This->pPSDelegate = NULL;
1351 static void DefaultHandler_Destroy(
1352 DefaultHandler* This)
1354 if (This->pOleDelegate)
1355 IOleObject_Release(This->pOleDelegate);
1356 if (This->pPSDelegate)
1357 IPersistStorage_Release(This->pPSDelegate);
1359 /* Free the strings idenfitying the object */
1360 HeapFree( GetProcessHeap(), 0, This->containerApp );
1361 This->containerApp = NULL;
1362 HeapFree( GetProcessHeap(), 0, This->containerObj );
1363 This->containerObj = NULL;
1365 /* Release our reference to the data cache. */
1366 if (This->dataCache)
1368 IUnknown_Release(This->dataCache);
1369 This->dataCache = NULL;
1372 /* Same thing for the client site. */
1373 if (This->clientSite)
1375 IOleClientSite_Release(This->clientSite);
1376 This->clientSite = NULL;
1379 /* And the advise holder. */
1380 if (This->oleAdviseHolder)
1382 IOleAdviseHolder_Release(This->oleAdviseHolder);
1383 This->oleAdviseHolder = NULL;
1386 /* And the data advise holder. */
1387 if (This->dataAdviseHolder)
1389 IDataAdviseHolder_Release(This->dataAdviseHolder);
1390 This->dataAdviseHolder = NULL;
1393 /* Free the actual default handler structure. */
1394 HeapFree(GetProcessHeap(), 0, This);
1397 /******************************************************************************
1398 * OleCreateDefaultHandler [OLE32.@]
1400 HRESULT WINAPI OleCreateDefaultHandler(
1402 LPUNKNOWN pUnkOuter,
1406 DefaultHandler* newHandler = NULL;
1409 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1420 * If This handler is constructed for aggregation, make sure
1421 * the caller is requesting the IUnknown interface.
1422 * This is necessary because it's the only time the non-delegating
1423 * IUnknown pointer can be returned to the outside.
1425 if (pUnkOuter && IsEqualIID(&IID_IUnknown, riid))
1426 return CLASS_E_NOAGGREGATION;
1429 * Try to construct a new instance of the class.
1431 newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1434 return E_OUTOFMEMORY;
1437 * Make sure it supports the interface required by the caller.
1439 hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1442 * Release the reference obtained in the constructor. If
1443 * the QueryInterface was unsuccessful, it will free the class.
1445 IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);