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;
177 else if (IsEqualIID(&IID_IPersist, riid) ||
178 IsEqualIID(&IID_IPersistStorage, riid) ||
179 IsEqualIID(&IID_IViewObject, riid) ||
180 IsEqualIID(&IID_IViewObject2, riid) ||
181 IsEqualIID(&IID_IOleCache, riid) ||
182 IsEqualIID(&IID_IOleCache2, riid))
184 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
185 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
189 /* Check that we obtained an interface. */
190 if (*ppvObject == NULL)
192 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
193 return E_NOINTERFACE;
197 * Query Interface always increases the reference count by one when it is
200 IUnknown_AddRef((IUnknown*)*ppvObject);
205 /************************************************************************
206 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
208 * See Windows documentation for more details on IUnknown methods.
210 * This version of QueryInterface will not delegate it's implementation
211 * to the outer unknown.
213 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
216 DefaultHandler *This = impl_from_NDIUnknown(iface);
217 return InterlockedIncrement(&This->ref);
220 /************************************************************************
221 * DefaultHandler_NDIUnknown_Release (IUnknown)
223 * See Windows documentation for more details on IUnknown methods.
225 * This version of QueryInterface will not delegate it's implementation
226 * to the outer unknown.
228 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
231 DefaultHandler *This = impl_from_NDIUnknown(iface);
234 /* Decrease the reference count on this object. */
235 ref = InterlockedDecrement(&This->ref);
237 if (!ref) DefaultHandler_Destroy(This);
242 /*********************************************************
243 * Methods implementation for the IOleObject part of
244 * the DefaultHandler class.
247 /************************************************************************
248 * DefaultHandler_QueryInterface (IUnknown)
250 * See Windows documentation for more details on IUnknown methods.
252 static HRESULT WINAPI DefaultHandler_QueryInterface(
257 DefaultHandler *This = impl_from_IOleObject(iface);
259 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
262 /************************************************************************
263 * DefaultHandler_AddRef (IUnknown)
265 * See Windows documentation for more details on IUnknown methods.
267 static ULONG WINAPI DefaultHandler_AddRef(
270 DefaultHandler *This = impl_from_IOleObject(iface);
272 return IUnknown_AddRef(This->outerUnknown);
275 /************************************************************************
276 * DefaultHandler_Release (IUnknown)
278 * See Windows documentation for more details on IUnknown methods.
280 static ULONG WINAPI DefaultHandler_Release(
283 DefaultHandler *This = impl_from_IOleObject(iface);
285 return IUnknown_Release(This->outerUnknown);
288 /************************************************************************
289 * DefaultHandler_SetClientSite (IOleObject)
291 * The default handler's implementation of this method only keeps the
292 * client site pointer for future reference.
294 * See Windows documentation for more details on IOleObject methods.
296 static HRESULT WINAPI DefaultHandler_SetClientSite(
298 IOleClientSite* pClientSite)
300 DefaultHandler *This = impl_from_IOleObject(iface);
302 TRACE("(%p, %p)\n", iface, pClientSite);
305 * Make sure we release the previous client site if there
308 if (This->clientSite)
309 IOleClientSite_Release(This->clientSite);
311 This->clientSite = pClientSite;
313 if (This->clientSite)
314 IOleClientSite_AddRef(This->clientSite);
319 /************************************************************************
320 * DefaultHandler_GetClientSite (IOleObject)
322 * The default handler's implementation of this method returns the
323 * last pointer set in IOleObject_SetClientSite.
325 * See Windows documentation for more details on IOleObject methods.
327 static HRESULT WINAPI DefaultHandler_GetClientSite(
329 IOleClientSite** ppClientSite)
331 DefaultHandler *This = impl_from_IOleObject(iface);
337 *ppClientSite = This->clientSite;
339 if (This->clientSite)
340 IOleClientSite_AddRef(This->clientSite);
345 /************************************************************************
346 * DefaultHandler_SetHostNames (IOleObject)
348 * The default handler's implementation of this method just stores
349 * the strings and returns S_OK.
351 * See Windows documentation for more details on IOleObject methods.
353 static HRESULT WINAPI DefaultHandler_SetHostNames(
355 LPCOLESTR szContainerApp,
356 LPCOLESTR szContainerObj)
358 DefaultHandler *This = impl_from_IOleObject(iface);
360 TRACE("(%p, %s, %s)\n",
362 debugstr_w(szContainerApp),
363 debugstr_w(szContainerObj));
365 /* Be sure to cleanup before re-assinging the strings. */
366 HeapFree( GetProcessHeap(), 0, This->containerApp );
367 This->containerApp = NULL;
368 HeapFree( GetProcessHeap(), 0, This->containerObj );
369 This->containerObj = NULL;
371 /* Copy the string supplied. */
374 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
375 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
376 strcpyW( This->containerApp, szContainerApp );
381 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
382 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
383 strcpyW( This->containerObj, szContainerObj );
388 /************************************************************************
389 * DefaultHandler_Close (IOleObject)
391 * The default handler's implementation of this method is meaningless
392 * without a running server so it does nothing.
394 * See Windows documentation for more details on IOleObject methods.
396 static HRESULT WINAPI DefaultHandler_Close(
404 /************************************************************************
405 * DefaultHandler_SetMoniker (IOleObject)
407 * The default handler's implementation of this method does nothing.
409 * See Windows documentation for more details on IOleObject methods.
411 static HRESULT WINAPI DefaultHandler_SetMoniker(
413 DWORD dwWhichMoniker,
416 TRACE("(%p, %ld, %p)\n",
424 /************************************************************************
425 * DefaultHandler_GetMoniker (IOleObject)
427 * Delegate this request to the client site if we have one.
429 * See Windows documentation for more details on IOleObject methods.
431 static HRESULT WINAPI DefaultHandler_GetMoniker(
434 DWORD dwWhichMoniker,
437 DefaultHandler *This = impl_from_IOleObject(iface);
439 TRACE("(%p, %ld, %ld, %p)\n",
440 iface, dwAssign, dwWhichMoniker, ppmk);
442 if (This->clientSite)
444 return IOleClientSite_GetMoniker(This->clientSite,
454 /************************************************************************
455 * DefaultHandler_InitFromData (IOleObject)
457 * This method is meaningless if the server is not running
459 * See Windows documentation for more details on IOleObject methods.
461 static HRESULT WINAPI DefaultHandler_InitFromData(
463 IDataObject* pDataObject,
467 TRACE("(%p, %p, %d, %ld)\n",
468 iface, pDataObject, fCreation, dwReserved);
470 return OLE_E_NOTRUNNING;
473 /************************************************************************
474 * DefaultHandler_GetClipboardData (IOleObject)
476 * This method is meaningless if the server is not running
478 * See Windows documentation for more details on IOleObject methods.
480 static HRESULT WINAPI DefaultHandler_GetClipboardData(
483 IDataObject** ppDataObject)
485 TRACE("(%p, %ld, %p)\n",
486 iface, dwReserved, ppDataObject);
488 return OLE_E_NOTRUNNING;
491 static HRESULT WINAPI DefaultHandler_DoVerb(
494 struct tagMSG* lpmsg,
495 IOleClientSite* pActiveSite,
504 /************************************************************************
505 * DefaultHandler_EnumVerbs (IOleObject)
507 * The default handler implementation of this method simply delegates
510 * See Windows documentation for more details on IOleObject methods.
512 static HRESULT WINAPI DefaultHandler_EnumVerbs(
514 IEnumOLEVERB** ppEnumOleVerb)
516 DefaultHandler *This = impl_from_IOleObject(iface);
517 HRESULT hr = OLE_S_USEREG;
519 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
521 if (This->pOleDelegate)
522 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
524 if (hr == OLE_S_USEREG)
525 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
530 static HRESULT WINAPI DefaultHandler_Update(
537 /************************************************************************
538 * DefaultHandler_IsUpToDate (IOleObject)
540 * This method is meaningless if the server is not running
542 * See Windows documentation for more details on IOleObject methods.
544 static HRESULT WINAPI DefaultHandler_IsUpToDate(
547 TRACE("(%p)\n", iface);
549 return OLE_E_NOTRUNNING;
552 /************************************************************************
553 * DefaultHandler_GetUserClassID (IOleObject)
555 * TODO: Map to a new class ID if emulation is active.
557 * See Windows documentation for more details on IOleObject methods.
559 static HRESULT WINAPI DefaultHandler_GetUserClassID(
563 DefaultHandler *This = impl_from_IOleObject(iface);
565 TRACE("(%p, %p)\n", iface, pClsid);
567 if (This->pOleDelegate)
568 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
574 memcpy(pClsid, &This->clsid, sizeof(CLSID));
579 /************************************************************************
580 * DefaultHandler_GetUserType (IOleObject)
582 * The default handler implementation of this method simply delegates
583 * to OleRegGetUserType
585 * See Windows documentation for more details on IOleObject methods.
587 static HRESULT WINAPI DefaultHandler_GetUserType(
590 LPOLESTR* pszUserType)
592 DefaultHandler *This = impl_from_IOleObject(iface);
594 TRACE("(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType);
596 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
599 /************************************************************************
600 * DefaultHandler_SetExtent (IOleObject)
602 * This method is meaningless if the server is not running
604 * See Windows documentation for more details on IOleObject methods.
606 static HRESULT WINAPI DefaultHandler_SetExtent(
611 TRACE("(%p, %lx, (%ld x %ld))\n", iface,
612 dwDrawAspect, psizel->cx, psizel->cy);
613 return OLE_E_NOTRUNNING;
616 /************************************************************************
617 * DefaultHandler_GetExtent (IOleObject)
619 * The default handler's implementation of this method returns uses
620 * the cache to locate the aspect and extract the extent from it.
622 * See Windows documentation for more details on IOleObject methods.
624 static HRESULT WINAPI DefaultHandler_GetExtent(
629 DVTARGETDEVICE* targetDevice;
630 IViewObject2* cacheView = NULL;
633 DefaultHandler *This = impl_from_IOleObject(iface);
635 TRACE("(%p, %lx, %p)\n", iface, dwDrawAspect, psizel);
637 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
643 * Prepare the call to the cache's GetExtent method.
645 * Here we would build a valid DVTARGETDEVICE structure
646 * but, since we are calling into the data cache, we
647 * know it's implementation and we'll skip this
648 * extra work until later.
652 hres = IViewObject2_GetExtent(cacheView,
661 IViewObject2_Release(cacheView);
666 /************************************************************************
667 * DefaultHandler_Advise (IOleObject)
669 * The default handler's implementation of this method simply
670 * delegates to the OleAdviseHolder.
672 * See Windows documentation for more details on IOleObject methods.
674 static HRESULT WINAPI DefaultHandler_Advise(
676 IAdviseSink* pAdvSink,
677 DWORD* pdwConnection)
680 DefaultHandler *This = impl_from_IOleObject(iface);
682 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
684 /* Make sure we have an advise holder before we start. */
685 if (!This->oleAdviseHolder)
686 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
689 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
696 /************************************************************************
697 * DefaultHandler_Unadvise (IOleObject)
699 * The default handler's implementation of this method simply
700 * delegates to the OleAdviseHolder.
702 * See Windows documentation for more details on IOleObject methods.
704 static HRESULT WINAPI DefaultHandler_Unadvise(
708 DefaultHandler *This = impl_from_IOleObject(iface);
710 TRACE("(%p, %ld)\n", iface, dwConnection);
713 * If we don't have an advise holder yet, it means we don't have
716 if (!This->oleAdviseHolder)
717 return OLE_E_NOCONNECTION;
719 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
723 /************************************************************************
724 * DefaultHandler_EnumAdvise (IOleObject)
726 * The default handler's implementation of this method simply
727 * delegates to the OleAdviseHolder.
729 * See Windows documentation for more details on IOleObject methods.
731 static HRESULT WINAPI DefaultHandler_EnumAdvise(
733 IEnumSTATDATA** ppenumAdvise)
735 DefaultHandler *This = impl_from_IOleObject(iface);
737 TRACE("(%p, %p)\n", iface, ppenumAdvise);
743 *ppenumAdvise = NULL;
745 if (!This->oleAdviseHolder)
746 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder,
752 /************************************************************************
753 * DefaultHandler_GetMiscStatus (IOleObject)
755 * The default handler's implementation of this method simply delegates
756 * to OleRegGetMiscStatus.
758 * See Windows documentation for more details on IOleObject methods.
760 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
766 DefaultHandler *This = impl_from_IOleObject(iface);
768 TRACE("(%p, %lx, %p)\n", iface, dwAspect, pdwStatus);
770 if (This->pOleDelegate)
771 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
773 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
781 /************************************************************************
782 * DefaultHandler_SetExtent (IOleObject)
784 * This method is meaningless if the server is not running
786 * See Windows documentation for more details on IOleObject methods.
788 static HRESULT WINAPI DefaultHandler_SetColorScheme(
790 struct tagLOGPALETTE* pLogpal)
792 TRACE("(%p, %p))\n", iface, pLogpal);
793 return OLE_E_NOTRUNNING;
796 /*********************************************************
797 * Methods implementation for the IDataObject part of
798 * the DefaultHandler class.
801 /************************************************************************
802 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
804 * See Windows documentation for more details on IUnknown methods.
806 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
811 DefaultHandler *This = impl_from_IDataObject(iface);
813 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
816 /************************************************************************
817 * DefaultHandler_IDataObject_AddRef (IUnknown)
819 * See Windows documentation for more details on IUnknown methods.
821 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
824 DefaultHandler *This = impl_from_IDataObject(iface);
826 return IUnknown_AddRef(This->outerUnknown);
829 /************************************************************************
830 * DefaultHandler_IDataObject_Release (IUnknown)
832 * See Windows documentation for more details on IUnknown methods.
834 static ULONG WINAPI DefaultHandler_IDataObject_Release(
837 DefaultHandler *This = impl_from_IDataObject(iface);
839 return IUnknown_Release(This->outerUnknown);
842 /************************************************************************
843 * DefaultHandler_GetData
845 * Get Data from a source dataobject using format pformatetcIn->cfFormat
846 * See Windows documentation for more details on GetData.
847 * Default handler's implementation of this method delegates to the cache.
849 static HRESULT WINAPI DefaultHandler_GetData(
851 LPFORMATETC pformatetcIn,
854 IDataObject* cacheDataObject = NULL;
857 DefaultHandler *This = impl_from_IDataObject(iface);
859 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
861 hres = IUnknown_QueryInterface(This->dataCache,
863 (void**)&cacheDataObject);
868 hres = IDataObject_GetData(cacheDataObject,
872 IDataObject_Release(cacheDataObject);
877 static HRESULT WINAPI DefaultHandler_GetDataHere(
879 LPFORMATETC pformatetc,
886 /************************************************************************
887 * DefaultHandler_QueryGetData (IDataObject)
889 * The default handler's implementation of this method delegates to
892 * See Windows documentation for more details on IDataObject methods.
894 static HRESULT WINAPI DefaultHandler_QueryGetData(
896 LPFORMATETC pformatetc)
898 IDataObject* cacheDataObject = NULL;
901 DefaultHandler *This = impl_from_IDataObject(iface);
903 TRACE("(%p, %p)\n", iface, pformatetc);
905 hres = IUnknown_QueryInterface(This->dataCache,
907 (void**)&cacheDataObject);
912 hres = IDataObject_QueryGetData(cacheDataObject,
915 IDataObject_Release(cacheDataObject);
920 /************************************************************************
921 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
923 * This method is meaningless if the server is not running
925 * See Windows documentation for more details on IDataObject methods.
927 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
929 LPFORMATETC pformatetcIn,
930 LPFORMATETC pformatetcOut)
932 DefaultHandler *This = impl_from_IDataObject(iface);
933 IDataObject *pDataObject;
936 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
938 if (!This->pOleDelegate)
939 return OLE_E_NOTRUNNING;
941 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&pDataObject);
942 return IDataObject_GetCanonicalFormatEtc(pDataObject, pformatetcIn, pformatetcOut);
945 /************************************************************************
946 * DefaultHandler_SetData (IDataObject)
948 * The default handler's implementation of this method delegates to
951 * See Windows documentation for more details on IDataObject methods.
953 static HRESULT WINAPI DefaultHandler_SetData(
955 LPFORMATETC pformatetc,
959 DefaultHandler *This = impl_from_IDataObject(iface);
960 IDataObject* cacheDataObject = NULL;
963 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
965 hres = IUnknown_QueryInterface(This->dataCache,
967 (void**)&cacheDataObject);
972 hres = IDataObject_SetData(cacheDataObject,
977 IDataObject_Release(cacheDataObject);
982 /************************************************************************
983 * DefaultHandler_EnumFormatEtc (IDataObject)
985 * The default handler's implementation of This method simply delegates
986 * to OleRegEnumFormatEtc.
988 * See Windows documentation for more details on IDataObject methods.
990 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
993 IEnumFORMATETC** ppenumFormatEtc)
996 DefaultHandler *This = impl_from_IDataObject(iface);
998 TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
1000 hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1005 /************************************************************************
1006 * DefaultHandler_DAdvise (IDataObject)
1008 * The default handler's implementation of this method simply
1009 * delegates to the DataAdviseHolder.
1011 * See Windows documentation for more details on IDataObject methods.
1013 static HRESULT WINAPI DefaultHandler_DAdvise(
1015 FORMATETC* pformatetc,
1017 IAdviseSink* pAdvSink,
1018 DWORD* pdwConnection)
1020 HRESULT hres = S_OK;
1021 DefaultHandler *This = impl_from_IDataObject(iface);
1023 TRACE("(%p, %p, %ld, %p, %p)\n",
1024 iface, pformatetc, advf, pAdvSink, pdwConnection);
1026 /* Make sure we have a data advise holder before we start. */
1027 if (!This->dataAdviseHolder)
1028 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1030 if (SUCCEEDED(hres))
1031 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1041 /************************************************************************
1042 * DefaultHandler_DUnadvise (IDataObject)
1044 * The default handler's implementation of this method simply
1045 * delegates to the DataAdviseHolder.
1047 * See Windows documentation for more details on IDataObject methods.
1049 static HRESULT WINAPI DefaultHandler_DUnadvise(
1053 DefaultHandler *This = impl_from_IDataObject(iface);
1055 TRACE("(%p, %ld)\n", iface, dwConnection);
1058 * If we don't have a data advise holder yet, it means that
1059 * we don't have any connections..
1061 if (!This->dataAdviseHolder)
1062 return OLE_E_NOCONNECTION;
1064 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1068 /************************************************************************
1069 * DefaultHandler_EnumDAdvise (IDataObject)
1071 * The default handler's implementation of this method simply
1072 * delegates to the DataAdviseHolder.
1074 * See Windows documentation for more details on IDataObject methods.
1076 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1078 IEnumSTATDATA** ppenumAdvise)
1080 DefaultHandler *This = impl_from_IDataObject(iface);
1082 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1088 *ppenumAdvise = NULL;
1090 /* If we have a data advise holder object, delegate. */
1091 if (This->dataAdviseHolder)
1092 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1098 /*********************************************************
1099 * Methods implementation for the IRunnableObject part
1100 * of the DefaultHandler class.
1103 /************************************************************************
1104 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1106 * See Windows documentation for more details on IUnknown methods.
1108 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1109 IRunnableObject* iface,
1113 DefaultHandler *This = impl_from_IRunnableObject(iface);
1115 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1118 /************************************************************************
1119 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1121 * See Windows documentation for more details on IUnknown methods.
1123 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1124 IRunnableObject* iface)
1126 DefaultHandler *This = impl_from_IRunnableObject(iface);
1128 return IUnknown_AddRef(This->outerUnknown);
1131 /************************************************************************
1132 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1134 * See Windows documentation for more details on IUnknown methods.
1136 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1137 IRunnableObject* iface)
1139 DefaultHandler *This = impl_from_IRunnableObject(iface);
1141 return IUnknown_Release(This->outerUnknown);
1144 /************************************************************************
1145 * DefaultHandler_GetRunningClass (IRunnableObject)
1147 * See Windows documentation for more details on IRunnableObject methods.
1149 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1150 IRunnableObject* iface,
1157 static HRESULT WINAPI DefaultHandler_Run(
1158 IRunnableObject* iface,
1161 DefaultHandler *This = impl_from_IRunnableObject(iface);
1164 FIXME("(%p): semi-stub\n", pbc);
1166 /* already running? if so nothing to do */
1167 if (This->pOleDelegate)
1170 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER, &IID_IOleObject, (void **)&This->pOleDelegate);
1174 if (This->clientSite)
1175 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1179 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
1180 if (This->pPSDelegate)
1181 hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
1184 if (SUCCEEDED(hr) && This->containerApp)
1185 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp, This->containerObj);
1187 /* FIXME: do more stuff here:
1188 * - IOleObject_GetMiscStatus
1189 * - IOleObject_Advise
1190 * - IOleObject_GetMoniker
1191 * - advise data cache that we've connected somehow?
1194 /* FIXME: if we failed, Close the object */
1199 /************************************************************************
1200 * DefaultHandler_IsRunning (IRunnableObject)
1202 * See Windows documentation for more details on IRunnableObject methods.
1204 static BOOL WINAPI DefaultHandler_IsRunning(
1205 IRunnableObject* iface)
1207 DefaultHandler *This = impl_from_IRunnableObject(iface);
1211 if (This->pOleDelegate)
1217 /************************************************************************
1218 * DefaultHandler_LockRunning (IRunnableObject)
1220 * See Windows documentation for more details on IRunnableObject methods.
1222 static HRESULT WINAPI DefaultHandler_LockRunning(
1223 IRunnableObject* iface,
1225 BOOL fLastUnlockCloses)
1231 /************************************************************************
1232 * DefaultHandler_SetContainedObject (IRunnableObject)
1234 * See Windows documentation for more details on IRunnableObject methods.
1236 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1237 IRunnableObject* iface,
1245 * Virtual function tables for the DefaultHandler class.
1247 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1249 DefaultHandler_QueryInterface,
1250 DefaultHandler_AddRef,
1251 DefaultHandler_Release,
1252 DefaultHandler_SetClientSite,
1253 DefaultHandler_GetClientSite,
1254 DefaultHandler_SetHostNames,
1255 DefaultHandler_Close,
1256 DefaultHandler_SetMoniker,
1257 DefaultHandler_GetMoniker,
1258 DefaultHandler_InitFromData,
1259 DefaultHandler_GetClipboardData,
1260 DefaultHandler_DoVerb,
1261 DefaultHandler_EnumVerbs,
1262 DefaultHandler_Update,
1263 DefaultHandler_IsUpToDate,
1264 DefaultHandler_GetUserClassID,
1265 DefaultHandler_GetUserType,
1266 DefaultHandler_SetExtent,
1267 DefaultHandler_GetExtent,
1268 DefaultHandler_Advise,
1269 DefaultHandler_Unadvise,
1270 DefaultHandler_EnumAdvise,
1271 DefaultHandler_GetMiscStatus,
1272 DefaultHandler_SetColorScheme
1275 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1277 DefaultHandler_NDIUnknown_QueryInterface,
1278 DefaultHandler_NDIUnknown_AddRef,
1279 DefaultHandler_NDIUnknown_Release,
1282 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1284 DefaultHandler_IDataObject_QueryInterface,
1285 DefaultHandler_IDataObject_AddRef,
1286 DefaultHandler_IDataObject_Release,
1287 DefaultHandler_GetData,
1288 DefaultHandler_GetDataHere,
1289 DefaultHandler_QueryGetData,
1290 DefaultHandler_GetCanonicalFormatEtc,
1291 DefaultHandler_SetData,
1292 DefaultHandler_EnumFormatEtc,
1293 DefaultHandler_DAdvise,
1294 DefaultHandler_DUnadvise,
1295 DefaultHandler_EnumDAdvise
1298 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1300 DefaultHandler_IRunnableObject_QueryInterface,
1301 DefaultHandler_IRunnableObject_AddRef,
1302 DefaultHandler_IRunnableObject_Release,
1303 DefaultHandler_GetRunningClass,
1305 DefaultHandler_IsRunning,
1306 DefaultHandler_LockRunning,
1307 DefaultHandler_SetContainedObject
1310 /*********************************************************
1311 * Methods implementation for the DefaultHandler class.
1313 static DefaultHandler* DefaultHandler_Construct(
1315 LPUNKNOWN pUnkOuter)
1317 DefaultHandler* This = NULL;
1320 * Allocate space for the object.
1322 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1327 This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1328 This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1329 This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1330 This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1333 * Start with one reference count. The caller of this function
1334 * must release the interface pointer when it is done.
1339 * Initialize the outer unknown
1340 * We don't keep a reference on the outer unknown since, the way
1341 * aggregation works, our lifetime is at least as large as it's
1345 pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1347 This->outerUnknown = pUnkOuter;
1350 * Create a datacache object.
1351 * We aggregate with the datacache. Make sure we pass our outer
1352 * unknown as the datacache's outer unknown.
1354 CreateDataCache(This->outerUnknown,
1357 (void**)&This->dataCache);
1360 * Initialize the other data members of the class.
1362 memcpy(&This->clsid, clsid, sizeof(CLSID));
1363 This->clientSite = NULL;
1364 This->oleAdviseHolder = NULL;
1365 This->dataAdviseHolder = NULL;
1366 This->containerApp = NULL;
1367 This->containerObj = NULL;
1368 This->pOleDelegate = NULL;
1369 This->pPSDelegate = NULL;
1374 static void DefaultHandler_Destroy(
1375 DefaultHandler* This)
1377 if (This->pOleDelegate)
1378 IOleObject_Release(This->pOleDelegate);
1379 if (This->pPSDelegate)
1380 IPersistStorage_Release(This->pPSDelegate);
1382 /* Free the strings idenfitying the object */
1383 HeapFree( GetProcessHeap(), 0, This->containerApp );
1384 This->containerApp = NULL;
1385 HeapFree( GetProcessHeap(), 0, This->containerObj );
1386 This->containerObj = NULL;
1388 /* Release our reference to the data cache. */
1389 if (This->dataCache)
1391 IUnknown_Release(This->dataCache);
1392 This->dataCache = NULL;
1395 /* Same thing for the client site. */
1396 if (This->clientSite)
1398 IOleClientSite_Release(This->clientSite);
1399 This->clientSite = NULL;
1402 /* And the advise holder. */
1403 if (This->oleAdviseHolder)
1405 IOleAdviseHolder_Release(This->oleAdviseHolder);
1406 This->oleAdviseHolder = NULL;
1409 /* And the data advise holder. */
1410 if (This->dataAdviseHolder)
1412 IDataAdviseHolder_Release(This->dataAdviseHolder);
1413 This->dataAdviseHolder = NULL;
1416 /* Free the actual default handler structure. */
1417 HeapFree(GetProcessHeap(), 0, This);
1420 /******************************************************************************
1421 * OleCreateDefaultHandler [OLE32.@]
1423 HRESULT WINAPI OleCreateDefaultHandler(
1425 LPUNKNOWN pUnkOuter,
1429 DefaultHandler* newHandler = NULL;
1432 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1443 * If This handler is constructed for aggregation, make sure
1444 * the caller is requesting the IUnknown interface.
1445 * This is necessary because it's the only time the non-delegating
1446 * IUnknown pointer can be returned to the outside.
1448 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
1449 return CLASS_E_NOAGGREGATION;
1452 * Try to construct a new instance of the class.
1454 newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1457 return E_OUTOFMEMORY;
1460 * Make sure it supports the interface required by the caller.
1462 hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1465 * Release the reference obtained in the constructor. If
1466 * the QueryInterface was unsuccessful, it will free the class.
1468 IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);