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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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.
60 #include "compobj_private.h"
62 #include "wine/unicode.h"
63 #include "wine/debug.h"
65 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
69 storage_state_uninitialised
,
70 storage_state_initialised
,
76 object_state_not_running
,
80 /****************************************************************************
86 IOleObject IOleObject_iface
;
87 IUnknown IUnknown_iface
;
88 IDataObject IDataObject_iface
;
89 IRunnableObject IRunnableObject_iface
;
90 IAdviseSink IAdviseSink_iface
;
91 IPersistStorage IPersistStorage_iface
;
93 /* Reference count of this object */
96 /* IUnknown implementation of the outer object. */
97 IUnknown
* outerUnknown
;
99 /* Class Id that this handler object represents. */
102 /* IUnknown implementation of the datacache. */
104 /* IPersistStorage implementation of the datacache. */
105 IPersistStorage
* dataCache_PersistStg
;
107 /* Client site for the embedded object. */
108 IOleClientSite
* clientSite
;
111 * The IOleAdviseHolder maintains the connections
112 * on behalf of the default handler.
114 IOleAdviseHolder
* oleAdviseHolder
;
117 * The IDataAdviseHolder maintains the data
118 * connections on behalf of the default handler.
120 IDataAdviseHolder
* dataAdviseHolder
;
122 /* Name of the container and object contained */
126 /* IOleObject delegate */
127 IOleObject
*pOleDelegate
;
128 /* IPersistStorage delegate */
129 IPersistStorage
*pPSDelegate
;
130 /* IDataObject delegate */
131 IDataObject
*pDataDelegate
;
132 enum object_state object_state
;
134 /* connection cookie for the advise on the delegate OLE object */
137 /* storage passed to Load or InitNew */
139 enum storage_state storage_state
;
141 /* optional class factory for object */
142 IClassFactory
*pCFObject
;
143 /* TRUE if acting as an inproc server instead of an inproc handler */
147 typedef struct DefaultHandler DefaultHandler
;
149 static inline DefaultHandler
*impl_from_IOleObject( IOleObject
*iface
)
151 return CONTAINING_RECORD(iface
, DefaultHandler
, IOleObject_iface
);
154 static inline DefaultHandler
*impl_from_IUnknown( IUnknown
*iface
)
156 return CONTAINING_RECORD(iface
, DefaultHandler
, IUnknown_iface
);
159 static inline DefaultHandler
*impl_from_IDataObject( IDataObject
*iface
)
161 return CONTAINING_RECORD(iface
, DefaultHandler
, IDataObject_iface
);
164 static inline DefaultHandler
*impl_from_IRunnableObject( IRunnableObject
*iface
)
166 return CONTAINING_RECORD(iface
, DefaultHandler
, IRunnableObject_iface
);
169 static inline DefaultHandler
*impl_from_IAdviseSink( IAdviseSink
*iface
)
171 return CONTAINING_RECORD(iface
, DefaultHandler
, IAdviseSink_iface
);
174 static inline DefaultHandler
*impl_from_IPersistStorage( IPersistStorage
*iface
)
176 return CONTAINING_RECORD(iface
, DefaultHandler
, IPersistStorage_iface
);
179 static void DefaultHandler_Destroy(DefaultHandler
* This
);
181 static inline BOOL
object_is_running(DefaultHandler
*This
)
183 return IRunnableObject_IsRunning(&This
->IRunnableObject_iface
);
186 /*********************************************************
187 * Method implementation for the non delegating IUnknown
188 * part of the DefaultHandler class.
191 /************************************************************************
192 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
194 * See Windows documentation for more details on IUnknown methods.
196 * This version of QueryInterface will not delegate its implementation
197 * to the outer unknown.
199 static HRESULT WINAPI
DefaultHandler_NDIUnknown_QueryInterface(
204 DefaultHandler
*This
= impl_from_IUnknown(iface
);
211 if (IsEqualIID(&IID_IUnknown
, riid
))
213 else if (IsEqualIID(&IID_IOleObject
, riid
))
214 *ppvObject
= &This
->IOleObject_iface
;
215 else if (IsEqualIID(&IID_IDataObject
, riid
))
216 *ppvObject
= &This
->IDataObject_iface
;
217 else if (IsEqualIID(&IID_IRunnableObject
, riid
))
218 *ppvObject
= &This
->IRunnableObject_iface
;
219 else if (IsEqualIID(&IID_IPersist
, riid
) ||
220 IsEqualIID(&IID_IPersistStorage
, riid
))
221 *ppvObject
= &This
->IPersistStorage_iface
;
222 else if (IsEqualIID(&IID_IViewObject
, riid
) ||
223 IsEqualIID(&IID_IViewObject2
, riid
) ||
224 IsEqualIID(&IID_IOleCache
, riid
) ||
225 IsEqualIID(&IID_IOleCache2
, riid
))
227 HRESULT hr
= IUnknown_QueryInterface(This
->dataCache
, riid
, ppvObject
);
228 if (FAILED(hr
)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid
));
231 else if (This
->inproc_server
&& This
->pOleDelegate
)
233 return IUnknown_QueryInterface(This
->pOleDelegate
, riid
, ppvObject
);
236 /* Check that we obtained an interface. */
237 if (*ppvObject
== NULL
)
239 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid
));
240 return E_NOINTERFACE
;
244 * Query Interface always increases the reference count by one when it is
247 IUnknown_AddRef((IUnknown
*)*ppvObject
);
252 /************************************************************************
253 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
255 * See Windows documentation for more details on IUnknown methods.
257 * This version of QueryInterface will not delegate its implementation
258 * to the outer unknown.
260 static ULONG WINAPI
DefaultHandler_NDIUnknown_AddRef(
263 DefaultHandler
*This
= impl_from_IUnknown(iface
);
264 return InterlockedIncrement(&This
->ref
);
267 /************************************************************************
268 * DefaultHandler_NDIUnknown_Release (IUnknown)
270 * See Windows documentation for more details on IUnknown methods.
272 * This version of QueryInterface will not delegate its implementation
273 * to the outer unknown.
275 static ULONG WINAPI
DefaultHandler_NDIUnknown_Release(
278 DefaultHandler
*This
= impl_from_IUnknown(iface
);
281 ref
= InterlockedDecrement(&This
->ref
);
283 if (!ref
) DefaultHandler_Destroy(This
);
288 /*********************************************************
289 * Methods implementation for the IOleObject part of
290 * the DefaultHandler class.
293 /************************************************************************
294 * DefaultHandler_QueryInterface (IUnknown)
296 * See Windows documentation for more details on IUnknown methods.
298 static HRESULT WINAPI
DefaultHandler_QueryInterface(
303 DefaultHandler
*This
= impl_from_IOleObject(iface
);
305 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
308 /************************************************************************
309 * DefaultHandler_AddRef (IUnknown)
311 * See Windows documentation for more details on IUnknown methods.
313 static ULONG WINAPI
DefaultHandler_AddRef(
316 DefaultHandler
*This
= impl_from_IOleObject(iface
);
318 return IUnknown_AddRef(This
->outerUnknown
);
321 /************************************************************************
322 * DefaultHandler_Release (IUnknown)
324 * See Windows documentation for more details on IUnknown methods.
326 static ULONG WINAPI
DefaultHandler_Release(
329 DefaultHandler
*This
= impl_from_IOleObject(iface
);
331 return IUnknown_Release(This
->outerUnknown
);
334 /************************************************************************
335 * DefaultHandler_SetClientSite (IOleObject)
337 * The default handler's implementation of this method only keeps the
338 * client site pointer for future reference.
340 * See Windows documentation for more details on IOleObject methods.
342 static HRESULT WINAPI
DefaultHandler_SetClientSite(
344 IOleClientSite
* pClientSite
)
346 DefaultHandler
*This
= impl_from_IOleObject(iface
);
349 TRACE("(%p, %p)\n", iface
, pClientSite
);
351 if (object_is_running(This
))
352 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, pClientSite
);
355 * Make sure we release the previous client site if there
358 if (This
->clientSite
)
359 IOleClientSite_Release(This
->clientSite
);
361 This
->clientSite
= pClientSite
;
363 if (This
->clientSite
)
364 IOleClientSite_AddRef(This
->clientSite
);
369 /************************************************************************
370 * DefaultHandler_GetClientSite (IOleObject)
372 * The default handler's implementation of this method returns the
373 * last pointer set in IOleObject_SetClientSite.
375 * See Windows documentation for more details on IOleObject methods.
377 static HRESULT WINAPI
DefaultHandler_GetClientSite(
379 IOleClientSite
** ppClientSite
)
381 DefaultHandler
*This
= impl_from_IOleObject(iface
);
386 *ppClientSite
= This
->clientSite
;
388 if (This
->clientSite
)
389 IOleClientSite_AddRef(This
->clientSite
);
394 /************************************************************************
395 * DefaultHandler_SetHostNames (IOleObject)
397 * The default handler's implementation of this method just stores
398 * the strings and returns S_OK.
400 * See Windows documentation for more details on IOleObject methods.
402 static HRESULT WINAPI
DefaultHandler_SetHostNames(
404 LPCOLESTR szContainerApp
,
405 LPCOLESTR szContainerObj
)
407 DefaultHandler
*This
= impl_from_IOleObject(iface
);
409 TRACE("(%p, %s, %s)\n",
411 debugstr_w(szContainerApp
),
412 debugstr_w(szContainerObj
));
414 if (object_is_running(This
))
415 IOleObject_SetHostNames(This
->pOleDelegate
, szContainerApp
, szContainerObj
);
417 /* Be sure to cleanup before re-assigning the strings. */
418 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
419 This
->containerApp
= NULL
;
420 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
421 This
->containerObj
= NULL
;
425 if ((This
->containerApp
= HeapAlloc( GetProcessHeap(), 0,
426 (lstrlenW(szContainerApp
) + 1) * sizeof(WCHAR
) )))
427 strcpyW( This
->containerApp
, szContainerApp
);
432 if ((This
->containerObj
= HeapAlloc( GetProcessHeap(), 0,
433 (lstrlenW(szContainerObj
) + 1) * sizeof(WCHAR
) )))
434 strcpyW( This
->containerObj
, szContainerObj
);
439 static void release_delegates(DefaultHandler
*This
)
441 if (This
->pDataDelegate
)
443 IDataObject_Release(This
->pDataDelegate
);
444 This
->pDataDelegate
= NULL
;
446 if (This
->pPSDelegate
)
448 IPersistStorage_Release(This
->pPSDelegate
);
449 This
->pPSDelegate
= NULL
;
451 if (This
->pOleDelegate
)
453 IOleObject_Release(This
->pOleDelegate
);
454 This
->pOleDelegate
= NULL
;
458 /* undoes the work done by DefaultHandler_Run */
459 static void DefaultHandler_Stop(DefaultHandler
*This
)
461 if (!object_is_running(This
))
464 IOleObject_Unadvise(This
->pOleDelegate
, This
->dwAdvConn
);
466 /* FIXME: call IOleCache_OnStop */
468 if (This
->dataAdviseHolder
)
469 DataAdviseHolder_OnDisconnect(This
->dataAdviseHolder
);
471 This
->object_state
= object_state_not_running
;
474 /************************************************************************
475 * DefaultHandler_Close (IOleObject)
477 * The default handler's implementation of this method is meaningless
478 * without a running server so it does nothing.
480 * See Windows documentation for more details on IOleObject methods.
482 static HRESULT WINAPI
DefaultHandler_Close(
486 DefaultHandler
*This
= impl_from_IOleObject(iface
);
489 TRACE("(%d)\n", dwSaveOption
);
491 if (!object_is_running(This
))
494 hr
= IOleObject_Close(This
->pOleDelegate
, dwSaveOption
);
496 DefaultHandler_Stop(This
);
497 release_delegates(This
);
502 /************************************************************************
503 * DefaultHandler_SetMoniker (IOleObject)
505 * The default handler's implementation of this method does nothing.
507 * See Windows documentation for more details on IOleObject methods.
509 static HRESULT WINAPI
DefaultHandler_SetMoniker(
511 DWORD dwWhichMoniker
,
514 DefaultHandler
*This
= impl_from_IOleObject(iface
);
516 TRACE("(%p, %d, %p)\n",
521 if (object_is_running(This
))
522 return IOleObject_SetMoniker(This
->pOleDelegate
, dwWhichMoniker
, pmk
);
527 /************************************************************************
528 * DefaultHandler_GetMoniker (IOleObject)
530 * Delegate this request to the client site if we have one.
532 * See Windows documentation for more details on IOleObject methods.
534 static HRESULT WINAPI
DefaultHandler_GetMoniker(
537 DWORD dwWhichMoniker
,
540 DefaultHandler
*This
= impl_from_IOleObject(iface
);
542 TRACE("(%p, %d, %d, %p)\n",
543 iface
, dwAssign
, dwWhichMoniker
, ppmk
);
545 if (object_is_running(This
))
546 return IOleObject_GetMoniker(This
->pOleDelegate
, dwAssign
, dwWhichMoniker
,
549 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
550 if (This
->clientSite
)
552 return IOleClientSite_GetMoniker(This
->clientSite
,
562 /************************************************************************
563 * DefaultHandler_InitFromData (IOleObject)
565 * This method is meaningless if the server is not running
567 * See Windows documentation for more details on IOleObject methods.
569 static HRESULT WINAPI
DefaultHandler_InitFromData(
571 IDataObject
* pDataObject
,
575 DefaultHandler
*This
= impl_from_IOleObject(iface
);
577 TRACE("(%p, %p, %d, %d)\n",
578 iface
, pDataObject
, fCreation
, dwReserved
);
580 if (object_is_running(This
))
581 return IOleObject_InitFromData(This
->pOleDelegate
, pDataObject
, fCreation
,
583 return OLE_E_NOTRUNNING
;
586 /************************************************************************
587 * DefaultHandler_GetClipboardData (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_GetClipboardData(
596 IDataObject
** ppDataObject
)
598 DefaultHandler
*This
= impl_from_IOleObject(iface
);
600 TRACE("(%p, %d, %p)\n",
601 iface
, dwReserved
, ppDataObject
);
603 if (object_is_running(This
))
604 return IOleObject_GetClipboardData(This
->pOleDelegate
, dwReserved
,
607 return OLE_E_NOTRUNNING
;
610 static HRESULT WINAPI
DefaultHandler_DoVerb(
613 struct tagMSG
* lpmsg
,
614 IOleClientSite
* pActiveSite
,
619 DefaultHandler
*This
= impl_from_IOleObject(iface
);
620 IRunnableObject
*pRunnableObj
= &This
->IRunnableObject_iface
;
623 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb
, lpmsg
, pActiveSite
, lindex
, hwndParent
, wine_dbgstr_rect(lprcPosRect
));
625 hr
= IRunnableObject_Run(pRunnableObj
, NULL
);
626 if (FAILED(hr
)) return hr
;
628 return IOleObject_DoVerb(This
->pOleDelegate
, iVerb
, lpmsg
, pActiveSite
,
629 lindex
, hwndParent
, lprcPosRect
);
632 /************************************************************************
633 * DefaultHandler_EnumVerbs (IOleObject)
635 * The default handler implementation of this method simply delegates
638 * See Windows documentation for more details on IOleObject methods.
640 static HRESULT WINAPI
DefaultHandler_EnumVerbs(
642 IEnumOLEVERB
** ppEnumOleVerb
)
644 DefaultHandler
*This
= impl_from_IOleObject(iface
);
645 HRESULT hr
= OLE_S_USEREG
;
647 TRACE("(%p, %p)\n", iface
, ppEnumOleVerb
);
649 if (object_is_running(This
))
650 hr
= IOleObject_EnumVerbs(This
->pOleDelegate
, ppEnumOleVerb
);
652 if (hr
== OLE_S_USEREG
)
653 return OleRegEnumVerbs(&This
->clsid
, ppEnumOleVerb
);
658 static HRESULT WINAPI
DefaultHandler_Update(
661 DefaultHandler
*This
= impl_from_IOleObject(iface
);
662 TRACE("(%p)\n", iface
);
664 if (!object_is_running(This
))
666 FIXME("Should run object\n");
669 return IOleObject_Update(This
->pOleDelegate
);
672 /************************************************************************
673 * DefaultHandler_IsUpToDate (IOleObject)
675 * This method is meaningless if the server is not running
677 * See Windows documentation for more details on IOleObject methods.
679 static HRESULT WINAPI
DefaultHandler_IsUpToDate(
682 DefaultHandler
*This
= impl_from_IOleObject(iface
);
683 TRACE("(%p)\n", iface
);
685 if (object_is_running(This
))
686 return IOleObject_IsUpToDate(This
->pOleDelegate
);
688 return OLE_E_NOTRUNNING
;
691 /************************************************************************
692 * DefaultHandler_GetUserClassID (IOleObject)
694 * TODO: Map to a new class ID if emulation is active.
696 * See Windows documentation for more details on IOleObject methods.
698 static HRESULT WINAPI
DefaultHandler_GetUserClassID(
702 DefaultHandler
*This
= impl_from_IOleObject(iface
);
704 TRACE("(%p, %p)\n", iface
, pClsid
);
706 if (object_is_running(This
))
707 return IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
712 *pClsid
= This
->clsid
;
717 /************************************************************************
718 * DefaultHandler_GetUserType (IOleObject)
720 * The default handler implementation of this method simply delegates
721 * to OleRegGetUserType
723 * See Windows documentation for more details on IOleObject methods.
725 static HRESULT WINAPI
DefaultHandler_GetUserType(
728 LPOLESTR
* pszUserType
)
730 DefaultHandler
*This
= impl_from_IOleObject(iface
);
732 TRACE("(%p, %d, %p)\n", iface
, dwFormOfType
, pszUserType
);
733 if (object_is_running(This
))
734 return IOleObject_GetUserType(This
->pOleDelegate
, dwFormOfType
, pszUserType
);
736 return OleRegGetUserType(&This
->clsid
, dwFormOfType
, pszUserType
);
739 /************************************************************************
740 * DefaultHandler_SetExtent (IOleObject)
742 * This method is meaningless if the server is not running
744 * See Windows documentation for more details on IOleObject methods.
746 static HRESULT WINAPI
DefaultHandler_SetExtent(
751 DefaultHandler
*This
= impl_from_IOleObject(iface
);
753 TRACE("(%p, %x, (%d x %d))\n", iface
,
754 dwDrawAspect
, psizel
->cx
, psizel
->cy
);
756 if (object_is_running(This
))
757 return IOleObject_SetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
759 return OLE_E_NOTRUNNING
;
762 /************************************************************************
763 * DefaultHandler_GetExtent (IOleObject)
765 * The default handler's implementation of this method returns uses
766 * the cache to locate the aspect and extract the extent from it.
768 * See Windows documentation for more details on IOleObject methods.
770 static HRESULT WINAPI
DefaultHandler_GetExtent(
775 DVTARGETDEVICE
* targetDevice
;
776 IViewObject2
* cacheView
= NULL
;
779 DefaultHandler
*This
= impl_from_IOleObject(iface
);
781 TRACE("(%p, %x, %p)\n", iface
, dwDrawAspect
, psizel
);
783 if (object_is_running(This
))
784 return IOleObject_GetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
786 hres
= IUnknown_QueryInterface(This
->dataCache
, &IID_IViewObject2
, (void**)&cacheView
);
791 * Prepare the call to the cache's GetExtent method.
793 * Here we would build a valid DVTARGETDEVICE structure
794 * but, since we are calling into the data cache, we
795 * know its implementation and we'll skip this
796 * extra work until later.
800 hres
= IViewObject2_GetExtent(cacheView
,
806 IViewObject2_Release(cacheView
);
811 /************************************************************************
812 * DefaultHandler_Advise (IOleObject)
814 * The default handler's implementation of this method simply
815 * delegates to the OleAdviseHolder.
817 * See Windows documentation for more details on IOleObject methods.
819 static HRESULT WINAPI
DefaultHandler_Advise(
821 IAdviseSink
* pAdvSink
,
822 DWORD
* pdwConnection
)
825 DefaultHandler
*This
= impl_from_IOleObject(iface
);
827 TRACE("(%p, %p, %p)\n", iface
, pAdvSink
, pdwConnection
);
829 /* Make sure we have an advise holder before we start. */
830 if (!This
->oleAdviseHolder
)
831 hres
= CreateOleAdviseHolder(&This
->oleAdviseHolder
);
834 hres
= IOleAdviseHolder_Advise(This
->oleAdviseHolder
,
841 /************************************************************************
842 * DefaultHandler_Unadvise (IOleObject)
844 * The default handler's implementation of this method simply
845 * delegates to the OleAdviseHolder.
847 * See Windows documentation for more details on IOleObject methods.
849 static HRESULT WINAPI
DefaultHandler_Unadvise(
853 DefaultHandler
*This
= impl_from_IOleObject(iface
);
855 TRACE("(%p, %d)\n", iface
, dwConnection
);
858 * If we don't have an advise holder yet, it means we don't have
861 if (!This
->oleAdviseHolder
)
862 return OLE_E_NOCONNECTION
;
864 return IOleAdviseHolder_Unadvise(This
->oleAdviseHolder
,
868 /************************************************************************
869 * DefaultHandler_EnumAdvise (IOleObject)
871 * The default handler's implementation of this method simply
872 * delegates to the OleAdviseHolder.
874 * See Windows documentation for more details on IOleObject methods.
876 static HRESULT WINAPI
DefaultHandler_EnumAdvise(
878 IEnumSTATDATA
** ppenumAdvise
)
880 DefaultHandler
*This
= impl_from_IOleObject(iface
);
882 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
887 *ppenumAdvise
= NULL
;
889 if (!This
->oleAdviseHolder
)
892 return IOleAdviseHolder_EnumAdvise(This
->oleAdviseHolder
, ppenumAdvise
);
895 /************************************************************************
896 * DefaultHandler_GetMiscStatus (IOleObject)
898 * The default handler's implementation of this method simply delegates
899 * to OleRegGetMiscStatus.
901 * See Windows documentation for more details on IOleObject methods.
903 static HRESULT WINAPI
DefaultHandler_GetMiscStatus(
909 DefaultHandler
*This
= impl_from_IOleObject(iface
);
911 TRACE("(%p, %x, %p)\n", iface
, dwAspect
, pdwStatus
);
913 if (object_is_running(This
))
914 return IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
916 hres
= OleRegGetMiscStatus(&This
->clsid
, dwAspect
, pdwStatus
);
924 /************************************************************************
925 * DefaultHandler_SetColorScheme (IOleObject)
927 * This method is meaningless if the server is not running
929 * See Windows documentation for more details on IOleObject methods.
931 static HRESULT WINAPI
DefaultHandler_SetColorScheme(
933 struct tagLOGPALETTE
* pLogpal
)
935 DefaultHandler
*This
= impl_from_IOleObject(iface
);
937 TRACE("(%p, %p))\n", iface
, pLogpal
);
939 if (object_is_running(This
))
940 return IOleObject_SetColorScheme(This
->pOleDelegate
, pLogpal
);
942 return OLE_E_NOTRUNNING
;
945 /*********************************************************
946 * Methods implementation for the IDataObject part of
947 * the DefaultHandler class.
950 /************************************************************************
951 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
953 * See Windows documentation for more details on IUnknown methods.
955 static HRESULT WINAPI
DefaultHandler_IDataObject_QueryInterface(
960 DefaultHandler
*This
= impl_from_IDataObject(iface
);
962 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
965 /************************************************************************
966 * DefaultHandler_IDataObject_AddRef (IUnknown)
968 * See Windows documentation for more details on IUnknown methods.
970 static ULONG WINAPI
DefaultHandler_IDataObject_AddRef(
973 DefaultHandler
*This
= impl_from_IDataObject(iface
);
975 return IUnknown_AddRef(This
->outerUnknown
);
978 /************************************************************************
979 * DefaultHandler_IDataObject_Release (IUnknown)
981 * See Windows documentation for more details on IUnknown methods.
983 static ULONG WINAPI
DefaultHandler_IDataObject_Release(
986 DefaultHandler
*This
= impl_from_IDataObject(iface
);
988 return IUnknown_Release(This
->outerUnknown
);
991 /************************************************************************
992 * DefaultHandler_GetData
994 * Get Data from a source dataobject using format pformatetcIn->cfFormat
995 * See Windows documentation for more details on GetData.
996 * Default handler's implementation of this method delegates to the cache.
998 static HRESULT WINAPI
DefaultHandler_GetData(
1000 LPFORMATETC pformatetcIn
,
1003 IDataObject
* cacheDataObject
= NULL
;
1006 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1008 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pmedium
);
1010 hres
= IUnknown_QueryInterface(This
->dataCache
,
1012 (void**)&cacheDataObject
);
1015 return E_UNEXPECTED
;
1017 hres
= IDataObject_GetData(cacheDataObject
,
1021 IDataObject_Release(cacheDataObject
);
1023 if (FAILED(hres
) && This
->pDataDelegate
)
1024 hres
= IDataObject_GetData(This
->pDataDelegate
, pformatetcIn
, pmedium
);
1029 static HRESULT WINAPI
DefaultHandler_GetDataHere(
1031 LPFORMATETC pformatetc
,
1038 /************************************************************************
1039 * DefaultHandler_QueryGetData (IDataObject)
1041 * The default handler's implementation of this method delegates to
1044 * See Windows documentation for more details on IDataObject methods.
1046 static HRESULT WINAPI
DefaultHandler_QueryGetData(
1048 LPFORMATETC pformatetc
)
1050 IDataObject
* cacheDataObject
= NULL
;
1053 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1055 TRACE("(%p, %p)\n", iface
, pformatetc
);
1057 hres
= IUnknown_QueryInterface(This
->dataCache
,
1059 (void**)&cacheDataObject
);
1062 return E_UNEXPECTED
;
1064 hres
= IDataObject_QueryGetData(cacheDataObject
,
1067 IDataObject_Release(cacheDataObject
);
1069 if (FAILED(hres
) && This
->pDataDelegate
)
1070 hres
= IDataObject_QueryGetData(This
->pDataDelegate
, pformatetc
);
1075 /************************************************************************
1076 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1078 * This method is meaningless if the server is not running
1080 * See Windows documentation for more details on IDataObject methods.
1082 static HRESULT WINAPI
DefaultHandler_GetCanonicalFormatEtc(
1084 LPFORMATETC pformatetcIn
,
1085 LPFORMATETC pformatetcOut
)
1087 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1089 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pformatetcOut
);
1091 if (!This
->pDataDelegate
)
1092 return OLE_E_NOTRUNNING
;
1094 return IDataObject_GetCanonicalFormatEtc(This
->pDataDelegate
, pformatetcIn
, pformatetcOut
);
1097 /************************************************************************
1098 * DefaultHandler_SetData (IDataObject)
1100 * The default handler's implementation of this method delegates to
1103 * See Windows documentation for more details on IDataObject methods.
1105 static HRESULT WINAPI
DefaultHandler_SetData(
1107 LPFORMATETC pformatetc
,
1111 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1112 IDataObject
* cacheDataObject
= NULL
;
1115 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1117 hres
= IUnknown_QueryInterface(This
->dataCache
,
1119 (void**)&cacheDataObject
);
1122 return E_UNEXPECTED
;
1124 hres
= IDataObject_SetData(cacheDataObject
,
1129 IDataObject_Release(cacheDataObject
);
1134 /************************************************************************
1135 * DefaultHandler_EnumFormatEtc (IDataObject)
1137 * The default handler's implementation of This method simply delegates
1138 * to OleRegEnumFormatEtc.
1140 * See Windows documentation for more details on IDataObject methods.
1142 static HRESULT WINAPI
DefaultHandler_EnumFormatEtc(
1145 IEnumFORMATETC
** ppenumFormatEtc
)
1147 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1149 TRACE("(%p, %x, %p)\n", iface
, dwDirection
, ppenumFormatEtc
);
1151 return OleRegEnumFormatEtc(&This
->clsid
, dwDirection
, ppenumFormatEtc
);
1154 /************************************************************************
1155 * DefaultHandler_DAdvise (IDataObject)
1157 * The default handler's implementation of this method simply
1158 * delegates to the DataAdviseHolder.
1160 * See Windows documentation for more details on IDataObject methods.
1162 static HRESULT WINAPI
DefaultHandler_DAdvise(
1164 FORMATETC
* pformatetc
,
1166 IAdviseSink
* pAdvSink
,
1167 DWORD
* pdwConnection
)
1169 HRESULT hres
= S_OK
;
1170 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1172 TRACE("(%p, %p, %d, %p, %p)\n",
1173 iface
, pformatetc
, advf
, pAdvSink
, pdwConnection
);
1175 /* Make sure we have a data advise holder before we start. */
1176 if (!This
->dataAdviseHolder
)
1178 hres
= CreateDataAdviseHolder(&This
->dataAdviseHolder
);
1179 if (SUCCEEDED(hres
) && This
->pDataDelegate
)
1180 DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1183 if (SUCCEEDED(hres
))
1184 hres
= IDataAdviseHolder_Advise(This
->dataAdviseHolder
,
1194 /************************************************************************
1195 * DefaultHandler_DUnadvise (IDataObject)
1197 * The default handler's implementation of this method simply
1198 * delegates to the DataAdviseHolder.
1200 * See Windows documentation for more details on IDataObject methods.
1202 static HRESULT WINAPI
DefaultHandler_DUnadvise(
1206 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1208 TRACE("(%p, %d)\n", iface
, dwConnection
);
1211 * If we don't have a data advise holder yet, it means that
1212 * we don't have any connections..
1214 if (!This
->dataAdviseHolder
)
1215 return OLE_E_NOCONNECTION
;
1217 return IDataAdviseHolder_Unadvise(This
->dataAdviseHolder
,
1221 /************************************************************************
1222 * DefaultHandler_EnumDAdvise (IDataObject)
1224 * The default handler's implementation of this method simply
1225 * delegates to the DataAdviseHolder.
1227 * See Windows documentation for more details on IDataObject methods.
1229 static HRESULT WINAPI
DefaultHandler_EnumDAdvise(
1231 IEnumSTATDATA
** ppenumAdvise
)
1233 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1235 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
1240 *ppenumAdvise
= NULL
;
1242 /* If we have a data advise holder object, delegate. */
1243 if (This
->dataAdviseHolder
)
1244 return IDataAdviseHolder_EnumAdvise(This
->dataAdviseHolder
,
1250 /*********************************************************
1251 * Methods implementation for the IRunnableObject part
1252 * of the DefaultHandler class.
1255 /************************************************************************
1256 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1258 * See Windows documentation for more details on IUnknown methods.
1260 static HRESULT WINAPI
DefaultHandler_IRunnableObject_QueryInterface(
1261 IRunnableObject
* iface
,
1265 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1267 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1270 /************************************************************************
1271 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1273 * See Windows documentation for more details on IUnknown methods.
1275 static ULONG WINAPI
DefaultHandler_IRunnableObject_AddRef(
1276 IRunnableObject
* iface
)
1278 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1280 return IUnknown_AddRef(This
->outerUnknown
);
1283 /************************************************************************
1284 * DefaultHandler_IRunnableObject_Release (IUnknown)
1286 * See Windows documentation for more details on IUnknown methods.
1288 static ULONG WINAPI
DefaultHandler_IRunnableObject_Release(
1289 IRunnableObject
* iface
)
1291 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1293 return IUnknown_Release(This
->outerUnknown
);
1296 /************************************************************************
1297 * DefaultHandler_GetRunningClass (IRunnableObject)
1299 * See Windows documentation for more details on IRunnableObject methods.
1301 static HRESULT WINAPI
DefaultHandler_GetRunningClass(
1302 IRunnableObject
* iface
,
1309 static HRESULT WINAPI
DefaultHandler_Run(
1310 IRunnableObject
* iface
,
1313 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1316 FIXME("(%p): semi-stub\n", pbc
);
1318 /* already running? if so nothing to do */
1319 if (object_is_running(This
))
1322 release_delegates(This
);
1324 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_LOCAL_SERVER
,
1325 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1329 This
->object_state
= object_state_running
;
1331 hr
= IOleObject_Advise(This
->pOleDelegate
, &This
->IAdviseSink_iface
, &This
->dwAdvConn
);
1333 if (SUCCEEDED(hr
) && This
->clientSite
)
1334 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, This
->clientSite
);
1338 IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
,
1339 (void **)&This
->pPSDelegate
);
1340 if (This
->pPSDelegate
)
1342 if(This
->storage_state
== storage_state_initialised
)
1343 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, This
->storage
);
1344 else if(This
->storage_state
== storage_state_loaded
)
1345 hr
= IPersistStorage_Load(This
->pPSDelegate
, This
->storage
);
1349 if (SUCCEEDED(hr
) && This
->containerApp
)
1350 hr
= IOleObject_SetHostNames(This
->pOleDelegate
, This
->containerApp
,
1351 This
->containerObj
);
1353 /* FIXME: do more stuff here:
1354 * - IOleObject_GetMiscStatus
1355 * - IOleObject_GetMoniker
1360 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
,
1361 (void **)&This
->pDataDelegate
);
1363 if (SUCCEEDED(hr
) && This
->dataAdviseHolder
)
1364 hr
= DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1368 DefaultHandler_Stop(This
);
1369 release_delegates(This
);
1375 /************************************************************************
1376 * DefaultHandler_IsRunning (IRunnableObject)
1378 * See Windows documentation for more details on IRunnableObject methods.
1380 static BOOL WINAPI
DefaultHandler_IsRunning(
1381 IRunnableObject
* iface
)
1383 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1387 if (This
->object_state
== object_state_running
)
1393 /************************************************************************
1394 * DefaultHandler_LockRunning (IRunnableObject)
1396 * See Windows documentation for more details on IRunnableObject methods.
1398 static HRESULT WINAPI
DefaultHandler_LockRunning(
1399 IRunnableObject
* iface
,
1401 BOOL fLastUnlockCloses
)
1407 /************************************************************************
1408 * DefaultHandler_SetContainedObject (IRunnableObject)
1410 * See Windows documentation for more details on IRunnableObject methods.
1412 static HRESULT WINAPI
DefaultHandler_SetContainedObject(
1413 IRunnableObject
* iface
,
1420 static HRESULT WINAPI
DefaultHandler_IAdviseSink_QueryInterface(
1425 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1426 IsEqualIID(riid
, &IID_IAdviseSink
))
1429 IAdviseSink_AddRef(iface
);
1433 return E_NOINTERFACE
;
1436 static ULONG WINAPI
DefaultHandler_IAdviseSink_AddRef(
1439 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1441 return IUnknown_AddRef(&This
->IUnknown_iface
);
1444 static ULONG WINAPI
DefaultHandler_IAdviseSink_Release(
1447 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1449 return IUnknown_Release(&This
->IUnknown_iface
);
1452 static void WINAPI
DefaultHandler_IAdviseSink_OnDataChange(
1454 FORMATETC
*pFormatetc
,
1460 static void WINAPI
DefaultHandler_IAdviseSink_OnViewChange(
1468 static void WINAPI
DefaultHandler_IAdviseSink_OnRename(
1472 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1474 TRACE("(%p)\n", pmk
);
1476 if (This
->oleAdviseHolder
)
1477 IOleAdviseHolder_SendOnRename(This
->oleAdviseHolder
, pmk
);
1480 static void WINAPI
DefaultHandler_IAdviseSink_OnSave(
1483 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1487 if (This
->oleAdviseHolder
)
1488 IOleAdviseHolder_SendOnSave(This
->oleAdviseHolder
);
1491 static void WINAPI
DefaultHandler_IAdviseSink_OnClose(
1494 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1498 if (This
->oleAdviseHolder
)
1499 IOleAdviseHolder_SendOnClose(This
->oleAdviseHolder
);
1501 DefaultHandler_Stop(This
);
1505 /************************************************************************
1506 * DefaultHandler_IPersistStorage_QueryInterface
1509 static HRESULT WINAPI
DefaultHandler_IPersistStorage_QueryInterface(
1510 IPersistStorage
* iface
,
1514 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1516 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1519 /************************************************************************
1520 * DefaultHandler_IPersistStorage_AddRef
1523 static ULONG WINAPI
DefaultHandler_IPersistStorage_AddRef(
1524 IPersistStorage
* iface
)
1526 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1528 return IUnknown_AddRef(This
->outerUnknown
);
1531 /************************************************************************
1532 * DefaultHandler_IPersistStorage_Release
1535 static ULONG WINAPI
DefaultHandler_IPersistStorage_Release(
1536 IPersistStorage
* iface
)
1538 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1540 return IUnknown_Release(This
->outerUnknown
);
1543 /************************************************************************
1544 * DefaultHandler_IPersistStorage_GetClassID
1547 static HRESULT WINAPI
DefaultHandler_IPersistStorage_GetClassID(
1548 IPersistStorage
* iface
,
1551 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1554 TRACE("(%p)->(%p)\n", iface
, clsid
);
1556 if(object_is_running(This
))
1557 hr
= IPersistStorage_GetClassID(This
->pPSDelegate
, clsid
);
1559 hr
= IPersistStorage_GetClassID(This
->dataCache_PersistStg
, clsid
);
1564 /************************************************************************
1565 * DefaultHandler_IPersistStorage_IsDirty
1568 static HRESULT WINAPI
DefaultHandler_IPersistStorage_IsDirty(
1569 IPersistStorage
* iface
)
1571 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1574 TRACE("(%p)\n", iface
);
1576 hr
= IPersistStorage_IsDirty(This
->dataCache_PersistStg
);
1577 if(hr
!= S_FALSE
) return hr
;
1579 if(object_is_running(This
))
1580 hr
= IPersistStorage_IsDirty(This
->pPSDelegate
);
1585 /***********************************************************************
1588 * Creates the '\1Ole' stream.
1589 * The format of this stream is as follows:
1591 * DWORD Version == 0x02000001
1592 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1593 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1594 * supplied by the app that creates the data structure. May be
1595 * ignored on processing].
1597 * DWORD Reserved == 0
1598 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1599 * CLSID clsid - class id of object capable of processing the moniker
1600 * BYTE data[] - moniker data for a link
1603 static const WCHAR OleStream
[] = {1,'O','l','e',0};
1608 DWORD link_update_opt
;
1611 } ole_stream_header_t
;
1612 static const DWORD ole_stream_version
= 0x02000001;
1614 static void init_ole_stream(IStorage
*storage
)
1619 hr
= IStorage_CreateStream(storage
, OleStream
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stream
);
1623 ole_stream_header_t header
;
1625 header
.version
= ole_stream_version
;
1627 header
.link_update_opt
= 0;
1629 header
.moniker_size
= 0;
1631 IStream_Write(stream
, &header
, sizeof(header
), &written
);
1632 IStream_Release(stream
);
1637 static HRESULT
load_ole_stream(DefaultHandler
*This
, IStorage
*storage
)
1642 hr
= IStorage_OpenStream(storage
, OleStream
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stream
);
1647 ole_stream_header_t header
;
1649 hr
= IStream_Read(stream
, &header
, sizeof(header
), &read
);
1650 if(hr
== S_OK
&& read
== sizeof(header
) && header
.version
== ole_stream_version
)
1652 if(header
.flags
& 1)
1654 /* FIXME: Read the moniker and deal with the link */
1655 FIXME("Linked objects are not supported yet\n");
1660 WARN("Incorrect OleStream header\n");
1661 hr
= DV_E_CLIPFORMAT
;
1663 IStream_Release(stream
);
1667 init_ole_stream(storage
);
1673 /************************************************************************
1674 * DefaultHandler_IPersistStorage_InitNew
1677 static HRESULT WINAPI
DefaultHandler_IPersistStorage_InitNew(
1678 IPersistStorage
* iface
,
1681 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1684 TRACE("(%p)->(%p)\n", iface
, pStg
);
1685 init_ole_stream(pStg
);
1687 hr
= IPersistStorage_InitNew(This
->dataCache_PersistStg
, pStg
);
1689 if(SUCCEEDED(hr
) && object_is_running(This
))
1690 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, pStg
);
1694 IStorage_AddRef(pStg
);
1695 This
->storage
= pStg
;
1696 This
->storage_state
= storage_state_initialised
;
1703 /************************************************************************
1704 * DefaultHandler_IPersistStorage_Load
1707 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Load(
1708 IPersistStorage
* iface
,
1711 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1714 TRACE("(%p)->(%p)\n", iface
, pStg
);
1716 hr
= load_ole_stream(This
, pStg
);
1719 hr
= IPersistStorage_Load(This
->dataCache_PersistStg
, pStg
);
1721 if(SUCCEEDED(hr
) && object_is_running(This
))
1722 hr
= IPersistStorage_Load(This
->pPSDelegate
, pStg
);
1726 IStorage_AddRef(pStg
);
1727 This
->storage
= pStg
;
1728 This
->storage_state
= storage_state_loaded
;
1734 /************************************************************************
1735 * DefaultHandler_IPersistStorage_Save
1738 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Save(
1739 IPersistStorage
* iface
,
1743 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1746 TRACE("(%p)->(%p, %d)\n", iface
, pStgSave
, fSameAsLoad
);
1748 hr
= IPersistStorage_Save(This
->dataCache_PersistStg
, pStgSave
, fSameAsLoad
);
1749 if(SUCCEEDED(hr
) && object_is_running(This
))
1750 hr
= IPersistStorage_Save(This
->pPSDelegate
, pStgSave
, fSameAsLoad
);
1756 /************************************************************************
1757 * DefaultHandler_IPersistStorage_SaveCompleted
1760 static HRESULT WINAPI
DefaultHandler_IPersistStorage_SaveCompleted(
1761 IPersistStorage
* iface
,
1764 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1767 TRACE("(%p)->(%p)\n", iface
, pStgNew
);
1769 hr
= IPersistStorage_SaveCompleted(This
->dataCache_PersistStg
, pStgNew
);
1771 if(SUCCEEDED(hr
) && object_is_running(This
))
1772 hr
= IPersistStorage_SaveCompleted(This
->pPSDelegate
, pStgNew
);
1776 IStorage_AddRef(pStgNew
);
1777 if(This
->storage
) IStorage_Release(This
->storage
);
1778 This
->storage
= pStgNew
;
1779 This
->storage_state
= storage_state_loaded
;
1786 /************************************************************************
1787 * DefaultHandler_IPersistStorage_HandsOffStorage
1790 static HRESULT WINAPI
DefaultHandler_IPersistStorage_HandsOffStorage(
1791 IPersistStorage
* iface
)
1793 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1796 TRACE("(%p)\n", iface
);
1798 hr
= IPersistStorage_HandsOffStorage(This
->dataCache_PersistStg
);
1800 if(SUCCEEDED(hr
) && object_is_running(This
))
1801 hr
= IPersistStorage_HandsOffStorage(This
->pPSDelegate
);
1803 if(This
->storage
) IStorage_Release(This
->storage
);
1804 This
->storage
= NULL
;
1805 This
->storage_state
= storage_state_uninitialised
;
1812 * Virtual function tables for the DefaultHandler class.
1814 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable
=
1816 DefaultHandler_QueryInterface
,
1817 DefaultHandler_AddRef
,
1818 DefaultHandler_Release
,
1819 DefaultHandler_SetClientSite
,
1820 DefaultHandler_GetClientSite
,
1821 DefaultHandler_SetHostNames
,
1822 DefaultHandler_Close
,
1823 DefaultHandler_SetMoniker
,
1824 DefaultHandler_GetMoniker
,
1825 DefaultHandler_InitFromData
,
1826 DefaultHandler_GetClipboardData
,
1827 DefaultHandler_DoVerb
,
1828 DefaultHandler_EnumVerbs
,
1829 DefaultHandler_Update
,
1830 DefaultHandler_IsUpToDate
,
1831 DefaultHandler_GetUserClassID
,
1832 DefaultHandler_GetUserType
,
1833 DefaultHandler_SetExtent
,
1834 DefaultHandler_GetExtent
,
1835 DefaultHandler_Advise
,
1836 DefaultHandler_Unadvise
,
1837 DefaultHandler_EnumAdvise
,
1838 DefaultHandler_GetMiscStatus
,
1839 DefaultHandler_SetColorScheme
1842 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable
=
1844 DefaultHandler_NDIUnknown_QueryInterface
,
1845 DefaultHandler_NDIUnknown_AddRef
,
1846 DefaultHandler_NDIUnknown_Release
,
1849 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable
=
1851 DefaultHandler_IDataObject_QueryInterface
,
1852 DefaultHandler_IDataObject_AddRef
,
1853 DefaultHandler_IDataObject_Release
,
1854 DefaultHandler_GetData
,
1855 DefaultHandler_GetDataHere
,
1856 DefaultHandler_QueryGetData
,
1857 DefaultHandler_GetCanonicalFormatEtc
,
1858 DefaultHandler_SetData
,
1859 DefaultHandler_EnumFormatEtc
,
1860 DefaultHandler_DAdvise
,
1861 DefaultHandler_DUnadvise
,
1862 DefaultHandler_EnumDAdvise
1865 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable
=
1867 DefaultHandler_IRunnableObject_QueryInterface
,
1868 DefaultHandler_IRunnableObject_AddRef
,
1869 DefaultHandler_IRunnableObject_Release
,
1870 DefaultHandler_GetRunningClass
,
1872 DefaultHandler_IsRunning
,
1873 DefaultHandler_LockRunning
,
1874 DefaultHandler_SetContainedObject
1877 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable
=
1879 DefaultHandler_IAdviseSink_QueryInterface
,
1880 DefaultHandler_IAdviseSink_AddRef
,
1881 DefaultHandler_IAdviseSink_Release
,
1882 DefaultHandler_IAdviseSink_OnDataChange
,
1883 DefaultHandler_IAdviseSink_OnViewChange
,
1884 DefaultHandler_IAdviseSink_OnRename
,
1885 DefaultHandler_IAdviseSink_OnSave
,
1886 DefaultHandler_IAdviseSink_OnClose
1889 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable
=
1891 DefaultHandler_IPersistStorage_QueryInterface
,
1892 DefaultHandler_IPersistStorage_AddRef
,
1893 DefaultHandler_IPersistStorage_Release
,
1894 DefaultHandler_IPersistStorage_GetClassID
,
1895 DefaultHandler_IPersistStorage_IsDirty
,
1896 DefaultHandler_IPersistStorage_InitNew
,
1897 DefaultHandler_IPersistStorage_Load
,
1898 DefaultHandler_IPersistStorage_Save
,
1899 DefaultHandler_IPersistStorage_SaveCompleted
,
1900 DefaultHandler_IPersistStorage_HandsOffStorage
1903 /*********************************************************
1904 * Methods implementation for the DefaultHandler class.
1906 static DefaultHandler
* DefaultHandler_Construct(
1908 LPUNKNOWN pUnkOuter
,
1912 DefaultHandler
* This
= NULL
;
1915 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler
));
1920 This
->IOleObject_iface
.lpVtbl
= &DefaultHandler_IOleObject_VTable
;
1921 This
->IUnknown_iface
.lpVtbl
= &DefaultHandler_NDIUnknown_VTable
;
1922 This
->IDataObject_iface
.lpVtbl
= &DefaultHandler_IDataObject_VTable
;
1923 This
->IRunnableObject_iface
.lpVtbl
= &DefaultHandler_IRunnableObject_VTable
;
1924 This
->IAdviseSink_iface
.lpVtbl
= &DefaultHandler_IAdviseSink_VTable
;
1925 This
->IPersistStorage_iface
.lpVtbl
= &DefaultHandler_IPersistStorage_VTable
;
1927 This
->inproc_server
= (flags
& EMBDHLP_INPROC_SERVER
) ? TRUE
: FALSE
;
1930 * Start with one reference count. The caller of this function
1931 * must release the interface pointer when it is done.
1936 * Initialize the outer unknown
1937 * We don't keep a reference on the outer unknown since, the way
1938 * aggregation works, our lifetime is at least as large as its
1942 pUnkOuter
= &This
->IUnknown_iface
;
1944 This
->outerUnknown
= pUnkOuter
;
1947 * Create a datacache object.
1948 * We aggregate with the datacache. Make sure we pass our outer
1949 * unknown as the datacache's outer unknown.
1951 hr
= CreateDataCache(This
->outerUnknown
,
1954 (void**)&This
->dataCache
);
1957 hr
= IUnknown_QueryInterface(This
->dataCache
, &IID_IPersistStorage
, (void**)&This
->dataCache_PersistStg
);
1958 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
1959 * reference on the outer object */
1961 IUnknown_Release(This
->outerUnknown
);
1963 IUnknown_Release(This
->dataCache
);
1967 ERR("Unexpected error creating data cache\n");
1968 HeapFree(GetProcessHeap(), 0, This
);
1972 This
->clsid
= *clsid
;
1973 This
->clientSite
= NULL
;
1974 This
->oleAdviseHolder
= NULL
;
1975 This
->dataAdviseHolder
= NULL
;
1976 This
->containerApp
= NULL
;
1977 This
->containerObj
= NULL
;
1978 This
->pOleDelegate
= NULL
;
1979 This
->pPSDelegate
= NULL
;
1980 This
->pDataDelegate
= NULL
;
1981 This
->object_state
= object_state_not_running
;
1983 This
->dwAdvConn
= 0;
1984 This
->storage
= NULL
;
1985 This
->storage_state
= storage_state_uninitialised
;
1987 if (This
->inproc_server
&& !(flags
& EMBDHLP_DELAYCREATE
))
1990 This
->pCFObject
= NULL
;
1992 hr
= IClassFactory_CreateInstance(pCF
, NULL
, &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1994 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
1995 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1997 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
, (void **)&This
->pPSDelegate
);
1999 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
, (void **)&This
->pDataDelegate
);
2001 This
->object_state
= object_state_running
;
2003 WARN("object creation failed with error %08x\n", hr
);
2007 This
->pCFObject
= pCF
;
2008 if (pCF
) IClassFactory_AddRef(pCF
);
2014 static void DefaultHandler_Destroy(
2015 DefaultHandler
* This
)
2017 TRACE("(%p)\n", This
);
2019 /* AddRef/Release may be called on this object during destruction.
2020 * Prevent the object being destroyed recursively by artificially raising
2021 * the reference count. */
2024 /* release delegates */
2025 DefaultHandler_Stop(This
);
2026 release_delegates(This
);
2028 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
2029 This
->containerApp
= NULL
;
2030 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
2031 This
->containerObj
= NULL
;
2033 if (This
->dataCache
)
2035 /* to balance out the release of dataCache_PersistStg which will result
2036 * in a reference being released from the outer unknown */
2037 IUnknown_AddRef(This
->outerUnknown
);
2038 IPersistStorage_Release(This
->dataCache_PersistStg
);
2039 IUnknown_Release(This
->dataCache
);
2040 This
->dataCache_PersistStg
= NULL
;
2041 This
->dataCache
= NULL
;
2044 if (This
->clientSite
)
2046 IOleClientSite_Release(This
->clientSite
);
2047 This
->clientSite
= NULL
;
2050 if (This
->oleAdviseHolder
)
2052 IOleAdviseHolder_Release(This
->oleAdviseHolder
);
2053 This
->oleAdviseHolder
= NULL
;
2056 if (This
->dataAdviseHolder
)
2058 IDataAdviseHolder_Release(This
->dataAdviseHolder
);
2059 This
->dataAdviseHolder
= NULL
;
2064 IStorage_Release(This
->storage
);
2065 This
->storage
= NULL
;
2068 if (This
->pCFObject
)
2070 IClassFactory_Release(This
->pCFObject
);
2071 This
->pCFObject
= NULL
;
2074 HeapFree(GetProcessHeap(), 0, This
);
2077 /******************************************************************************
2078 * OleCreateEmbeddingHelper [OLE32.@]
2080 HRESULT WINAPI
OleCreateEmbeddingHelper(
2082 LPUNKNOWN pUnkOuter
,
2088 DefaultHandler
* newHandler
= NULL
;
2091 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
, flags
, pCF
, debugstr_guid(riid
), ppvObj
);
2099 * If This handler is constructed for aggregation, make sure
2100 * the caller is requesting the IUnknown interface.
2101 * This is necessary because it's the only time the non-delegating
2102 * IUnknown pointer can be returned to the outside.
2104 if (pUnkOuter
&& !IsEqualIID(&IID_IUnknown
, riid
))
2105 return CLASS_E_NOAGGREGATION
;
2108 * Try to construct a new instance of the class.
2110 newHandler
= DefaultHandler_Construct(clsid
, pUnkOuter
, flags
, pCF
);
2113 return E_OUTOFMEMORY
;
2116 * Make sure it supports the interface required by the caller.
2118 hr
= IUnknown_QueryInterface(&newHandler
->IUnknown_iface
, riid
, ppvObj
);
2121 * Release the reference obtained in the constructor. If
2122 * the QueryInterface was unsuccessful, it will free the class.
2124 IUnknown_Release(&newHandler
->IUnknown_iface
);
2130 /******************************************************************************
2131 * OleCreateDefaultHandler [OLE32.@]
2133 HRESULT WINAPI
OleCreateDefaultHandler(REFCLSID clsid
, LPUNKNOWN pUnkOuter
,
2134 REFIID riid
, LPVOID
* ppvObj
)
2136 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
,debugstr_guid(riid
), ppvObj
);
2137 return OleCreateEmbeddingHelper(clsid
, pUnkOuter
, EMBDHLP_INPROC_HANDLER
| EMBDHLP_CREATENOW
,
2138 NULL
, riid
, ppvObj
);
2141 typedef struct HandlerCF
2143 IClassFactory IClassFactory_iface
;
2148 static inline HandlerCF
*impl_from_IClassFactory(IClassFactory
*iface
)
2150 return CONTAINING_RECORD(iface
, HandlerCF
, IClassFactory_iface
);
2153 static HRESULT WINAPI
2154 HandlerCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
, LPVOID
*ppv
)
2157 if (IsEqualIID(riid
,&IID_IUnknown
) ||
2158 IsEqualIID(riid
,&IID_IClassFactory
))
2161 IClassFactory_AddRef(iface
);
2164 return E_NOINTERFACE
;
2167 static ULONG WINAPI
HandlerCF_AddRef(LPCLASSFACTORY iface
)
2169 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2170 return InterlockedIncrement(&This
->refs
);
2173 static ULONG WINAPI
HandlerCF_Release(LPCLASSFACTORY iface
)
2175 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2176 ULONG refs
= InterlockedDecrement(&This
->refs
);
2178 HeapFree(GetProcessHeap(), 0, This
);
2182 static HRESULT WINAPI
2183 HandlerCF_CreateInstance(LPCLASSFACTORY iface
, LPUNKNOWN pUnk
,
2184 REFIID riid
, LPVOID
*ppv
)
2186 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2187 return OleCreateDefaultHandler(&This
->clsid
, pUnk
, riid
, ppv
);
2190 static HRESULT WINAPI
HandlerCF_LockServer(LPCLASSFACTORY iface
, BOOL fLock
)
2192 FIXME("(%d), stub!\n",fLock
);
2196 static const IClassFactoryVtbl HandlerClassFactoryVtbl
= {
2197 HandlerCF_QueryInterface
,
2200 HandlerCF_CreateInstance
,
2201 HandlerCF_LockServer
2204 HRESULT
HandlerCF_Create(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
2207 HandlerCF
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
2208 if (!This
) return E_OUTOFMEMORY
;
2209 This
->IClassFactory_iface
.lpVtbl
= &HandlerClassFactoryVtbl
;
2211 This
->clsid
= *rclsid
;
2213 hr
= IUnknown_QueryInterface((IUnknown
*)&This
->IClassFactory_iface
, riid
, ppv
);
2215 HeapFree(GetProcessHeap(), 0, This
);