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"
61 #include "storage32.h"
63 #include "wine/unicode.h"
64 #include "wine/debug.h"
66 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
70 storage_state_uninitialised
,
71 storage_state_initialised
,
77 object_state_not_running
,
79 object_state_deferred_close
82 /****************************************************************************
88 IOleObject IOleObject_iface
;
89 IUnknown IUnknown_iface
;
90 IDataObject IDataObject_iface
;
91 IRunnableObject IRunnableObject_iface
;
92 IAdviseSink IAdviseSink_iface
;
93 IPersistStorage IPersistStorage_iface
;
95 /* Reference count of this object */
98 /* IUnknown implementation of the outer object. */
99 IUnknown
* outerUnknown
;
101 /* Class Id that this handler object represents. */
104 /* IUnknown implementation of the datacache. */
106 /* IPersistStorage implementation of the datacache. */
107 IPersistStorage
* dataCache_PersistStg
;
109 /* Client site for the embedded object. */
110 IOleClientSite
* clientSite
;
113 * The IOleAdviseHolder maintains the connections
114 * on behalf of the default handler.
116 IOleAdviseHolder
* oleAdviseHolder
;
119 * The IDataAdviseHolder maintains the data
120 * connections on behalf of the default handler.
122 IDataAdviseHolder
* dataAdviseHolder
;
124 /* Name of the container and object contained */
128 /* IOleObject delegate */
129 IOleObject
*pOleDelegate
;
130 /* IPersistStorage delegate */
131 IPersistStorage
*pPSDelegate
;
132 /* IDataObject delegate */
133 IDataObject
*pDataDelegate
;
134 enum object_state object_state
;
137 /* connection cookie for the advise on the delegate OLE object */
140 /* storage passed to Load or InitNew */
142 enum storage_state storage_state
;
144 /* optional class factory for object */
145 IClassFactory
*pCFObject
;
146 /* TRUE if acting as an inproc server instead of an inproc handler */
150 typedef struct DefaultHandler DefaultHandler
;
152 static inline DefaultHandler
*impl_from_IOleObject( IOleObject
*iface
)
154 return CONTAINING_RECORD(iface
, DefaultHandler
, IOleObject_iface
);
157 static inline DefaultHandler
*impl_from_IUnknown( IUnknown
*iface
)
159 return CONTAINING_RECORD(iface
, DefaultHandler
, IUnknown_iface
);
162 static inline DefaultHandler
*impl_from_IDataObject( IDataObject
*iface
)
164 return CONTAINING_RECORD(iface
, DefaultHandler
, IDataObject_iface
);
167 static inline DefaultHandler
*impl_from_IRunnableObject( IRunnableObject
*iface
)
169 return CONTAINING_RECORD(iface
, DefaultHandler
, IRunnableObject_iface
);
172 static inline DefaultHandler
*impl_from_IAdviseSink( IAdviseSink
*iface
)
174 return CONTAINING_RECORD(iface
, DefaultHandler
, IAdviseSink_iface
);
177 static inline DefaultHandler
*impl_from_IPersistStorage( IPersistStorage
*iface
)
179 return CONTAINING_RECORD(iface
, DefaultHandler
, IPersistStorage_iface
);
182 static void DefaultHandler_Destroy(DefaultHandler
* This
);
184 static inline BOOL
object_is_running(DefaultHandler
*This
)
186 return IRunnableObject_IsRunning(&This
->IRunnableObject_iface
);
189 static void DefaultHandler_Stop(DefaultHandler
*This
);
191 static inline void start_object_call(DefaultHandler
*This
)
196 static inline void end_object_call(DefaultHandler
*This
)
199 if (This
->in_call
== 0 && This
->object_state
== object_state_deferred_close
)
200 DefaultHandler_Stop( This
);
203 /*********************************************************
204 * Method implementation for the non delegating IUnknown
205 * part of the DefaultHandler class.
208 /************************************************************************
209 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
211 * See Windows documentation for more details on IUnknown methods.
213 * This version of QueryInterface will not delegate its implementation
214 * to the outer unknown.
216 static HRESULT WINAPI
DefaultHandler_NDIUnknown_QueryInterface(
221 DefaultHandler
*This
= impl_from_IUnknown(iface
);
228 if (IsEqualIID(&IID_IUnknown
, riid
))
230 else if (IsEqualIID(&IID_IOleObject
, riid
))
231 *ppvObject
= &This
->IOleObject_iface
;
232 else if (IsEqualIID(&IID_IDataObject
, riid
))
233 *ppvObject
= &This
->IDataObject_iface
;
234 else if (IsEqualIID(&IID_IRunnableObject
, riid
))
235 *ppvObject
= &This
->IRunnableObject_iface
;
236 else if (IsEqualIID(&IID_IPersist
, riid
) ||
237 IsEqualIID(&IID_IPersistStorage
, riid
))
238 *ppvObject
= &This
->IPersistStorage_iface
;
239 else if (IsEqualIID(&IID_IViewObject
, riid
) ||
240 IsEqualIID(&IID_IViewObject2
, riid
) ||
241 IsEqualIID(&IID_IOleCache
, riid
) ||
242 IsEqualIID(&IID_IOleCache2
, riid
))
244 HRESULT hr
= IUnknown_QueryInterface(This
->dataCache
, riid
, ppvObject
);
245 if (FAILED(hr
)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid
));
248 else if (This
->inproc_server
&& This
->pOleDelegate
)
250 return IOleObject_QueryInterface(This
->pOleDelegate
, riid
, ppvObject
);
253 /* Check that we obtained an interface. */
254 if (*ppvObject
== NULL
)
256 WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid
));
257 return E_NOINTERFACE
;
261 * Query Interface always increases the reference count by one when it is
264 IUnknown_AddRef((IUnknown
*)*ppvObject
);
269 /************************************************************************
270 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
272 * See Windows documentation for more details on IUnknown methods.
274 * This version of QueryInterface will not delegate its implementation
275 * to the outer unknown.
277 static ULONG WINAPI
DefaultHandler_NDIUnknown_AddRef(
280 DefaultHandler
*This
= impl_from_IUnknown(iface
);
281 return InterlockedIncrement(&This
->ref
);
284 /************************************************************************
285 * DefaultHandler_NDIUnknown_Release (IUnknown)
287 * See Windows documentation for more details on IUnknown methods.
289 * This version of QueryInterface will not delegate its implementation
290 * to the outer unknown.
292 static ULONG WINAPI
DefaultHandler_NDIUnknown_Release(
295 DefaultHandler
*This
= impl_from_IUnknown(iface
);
298 ref
= InterlockedDecrement(&This
->ref
);
300 if (!ref
) DefaultHandler_Destroy(This
);
305 /*********************************************************
306 * Methods implementation for the IOleObject part of
307 * the DefaultHandler class.
310 /************************************************************************
311 * DefaultHandler_QueryInterface (IUnknown)
313 * See Windows documentation for more details on IUnknown methods.
315 static HRESULT WINAPI
DefaultHandler_QueryInterface(
320 DefaultHandler
*This
= impl_from_IOleObject(iface
);
322 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
325 /************************************************************************
326 * DefaultHandler_AddRef (IUnknown)
328 * See Windows documentation for more details on IUnknown methods.
330 static ULONG WINAPI
DefaultHandler_AddRef(
333 DefaultHandler
*This
= impl_from_IOleObject(iface
);
335 return IUnknown_AddRef(This
->outerUnknown
);
338 /************************************************************************
339 * DefaultHandler_Release (IUnknown)
341 * See Windows documentation for more details on IUnknown methods.
343 static ULONG WINAPI
DefaultHandler_Release(
346 DefaultHandler
*This
= impl_from_IOleObject(iface
);
348 return IUnknown_Release(This
->outerUnknown
);
351 /************************************************************************
352 * DefaultHandler_SetClientSite (IOleObject)
354 * The default handler's implementation of this method only keeps the
355 * client site pointer for future reference.
357 * See Windows documentation for more details on IOleObject methods.
359 static HRESULT WINAPI
DefaultHandler_SetClientSite(
361 IOleClientSite
* pClientSite
)
363 DefaultHandler
*This
= impl_from_IOleObject(iface
);
366 TRACE("(%p, %p)\n", iface
, pClientSite
);
368 if (object_is_running(This
))
370 start_object_call( This
);
371 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, pClientSite
);
372 end_object_call( This
);
376 * Make sure we release the previous client site if there
379 if (This
->clientSite
)
380 IOleClientSite_Release(This
->clientSite
);
382 This
->clientSite
= pClientSite
;
384 if (This
->clientSite
)
385 IOleClientSite_AddRef(This
->clientSite
);
390 /************************************************************************
391 * DefaultHandler_GetClientSite (IOleObject)
393 * The default handler's implementation of this method returns the
394 * last pointer set in IOleObject_SetClientSite.
396 * See Windows documentation for more details on IOleObject methods.
398 static HRESULT WINAPI
DefaultHandler_GetClientSite(
400 IOleClientSite
** ppClientSite
)
402 DefaultHandler
*This
= impl_from_IOleObject(iface
);
407 *ppClientSite
= This
->clientSite
;
409 if (This
->clientSite
)
410 IOleClientSite_AddRef(This
->clientSite
);
415 /************************************************************************
416 * DefaultHandler_SetHostNames (IOleObject)
418 * The default handler's implementation of this method just stores
419 * the strings and returns S_OK.
421 * See Windows documentation for more details on IOleObject methods.
423 static HRESULT WINAPI
DefaultHandler_SetHostNames(
425 LPCOLESTR szContainerApp
,
426 LPCOLESTR szContainerObj
)
428 DefaultHandler
*This
= impl_from_IOleObject(iface
);
430 TRACE("(%p, %s, %s)\n",
432 debugstr_w(szContainerApp
),
433 debugstr_w(szContainerObj
));
435 if (object_is_running(This
))
437 start_object_call( This
);
438 IOleObject_SetHostNames(This
->pOleDelegate
, szContainerApp
, szContainerObj
);
439 end_object_call( This
);
442 /* Be sure to cleanup before re-assigning the strings. */
443 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
444 This
->containerApp
= NULL
;
445 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
446 This
->containerObj
= NULL
;
450 if ((This
->containerApp
= HeapAlloc( GetProcessHeap(), 0,
451 (lstrlenW(szContainerApp
) + 1) * sizeof(WCHAR
) )))
452 strcpyW( This
->containerApp
, szContainerApp
);
457 if ((This
->containerObj
= HeapAlloc( GetProcessHeap(), 0,
458 (lstrlenW(szContainerObj
) + 1) * sizeof(WCHAR
) )))
459 strcpyW( This
->containerObj
, szContainerObj
);
464 static void release_delegates(DefaultHandler
*This
)
466 if (This
->pDataDelegate
)
468 IDataObject_Release(This
->pDataDelegate
);
469 This
->pDataDelegate
= NULL
;
471 if (This
->pPSDelegate
)
473 IPersistStorage_Release(This
->pPSDelegate
);
474 This
->pPSDelegate
= NULL
;
476 if (This
->pOleDelegate
)
478 IOleObject_Release(This
->pOleDelegate
);
479 This
->pOleDelegate
= NULL
;
483 /* undoes the work done by DefaultHandler_Run */
484 static void DefaultHandler_Stop(DefaultHandler
*This
)
486 IOleCacheControl
*cache_ctrl
;
489 if (This
->object_state
== object_state_not_running
)
492 hr
= IUnknown_QueryInterface( This
->dataCache
, &IID_IOleCacheControl
, (void **)&cache_ctrl
);
495 hr
= IOleCacheControl_OnStop( cache_ctrl
);
496 IOleCacheControl_Release( cache_ctrl
);
499 IOleObject_Unadvise(This
->pOleDelegate
, This
->dwAdvConn
);
501 if (This
->dataAdviseHolder
)
502 DataAdviseHolder_OnDisconnect(This
->dataAdviseHolder
);
504 This
->object_state
= object_state_not_running
;
505 release_delegates( This
);
508 /************************************************************************
509 * DefaultHandler_Close (IOleObject)
511 * The default handler's implementation of this method is meaningless
512 * without a running server so it does nothing.
514 * See Windows documentation for more details on IOleObject methods.
516 static HRESULT WINAPI
DefaultHandler_Close(
520 DefaultHandler
*This
= impl_from_IOleObject(iface
);
523 TRACE("(%d)\n", dwSaveOption
);
525 if (!object_is_running(This
))
528 start_object_call( This
);
529 hr
= IOleObject_Close(This
->pOleDelegate
, dwSaveOption
);
530 end_object_call( This
);
532 DefaultHandler_Stop(This
);
537 /************************************************************************
538 * DefaultHandler_SetMoniker (IOleObject)
540 * The default handler's implementation of this method does nothing.
542 * See Windows documentation for more details on IOleObject methods.
544 static HRESULT WINAPI
DefaultHandler_SetMoniker(
546 DWORD dwWhichMoniker
,
549 DefaultHandler
*This
= impl_from_IOleObject(iface
);
552 TRACE("(%p, %d, %p)\n", iface
, dwWhichMoniker
, pmk
);
554 if (object_is_running(This
))
556 start_object_call( This
);
557 hr
= IOleObject_SetMoniker(This
->pOleDelegate
, dwWhichMoniker
, pmk
);
558 end_object_call( This
);
564 /************************************************************************
565 * DefaultHandler_GetMoniker (IOleObject)
567 * Delegate this request to the client site if we have one.
569 * See Windows documentation for more details on IOleObject methods.
571 static HRESULT WINAPI
DefaultHandler_GetMoniker(
574 DWORD dwWhichMoniker
,
577 DefaultHandler
*This
= impl_from_IOleObject(iface
);
580 TRACE("(%p, %d, %d, %p)\n",
581 iface
, dwAssign
, dwWhichMoniker
, ppmk
);
583 if (object_is_running(This
))
585 start_object_call( This
);
586 hr
= IOleObject_GetMoniker(This
->pOleDelegate
, dwAssign
, dwWhichMoniker
,
588 end_object_call( This
);
592 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
593 if (This
->clientSite
)
595 return IOleClientSite_GetMoniker(This
->clientSite
,
605 /************************************************************************
606 * DefaultHandler_InitFromData (IOleObject)
608 * This method is meaningless if the server is not running
610 * See Windows documentation for more details on IOleObject methods.
612 static HRESULT WINAPI
DefaultHandler_InitFromData(
614 IDataObject
* pDataObject
,
618 DefaultHandler
*This
= impl_from_IOleObject(iface
);
619 HRESULT hr
= OLE_E_NOTRUNNING
;
621 TRACE("(%p, %p, %d, %d)\n",
622 iface
, pDataObject
, fCreation
, dwReserved
);
624 if (object_is_running(This
))
626 start_object_call( This
);
627 hr
= IOleObject_InitFromData(This
->pOleDelegate
, pDataObject
, fCreation
,
629 end_object_call( This
);
635 /************************************************************************
636 * DefaultHandler_GetClipboardData (IOleObject)
638 * This method is meaningless if the server is not running
640 * See Windows documentation for more details on IOleObject methods.
642 static HRESULT WINAPI
DefaultHandler_GetClipboardData(
645 IDataObject
** ppDataObject
)
647 DefaultHandler
*This
= impl_from_IOleObject(iface
);
648 HRESULT hr
= OLE_E_NOTRUNNING
;
650 TRACE("(%p, %d, %p)\n",
651 iface
, dwReserved
, ppDataObject
);
653 if (object_is_running(This
))
655 start_object_call( This
);
656 hr
= IOleObject_GetClipboardData(This
->pOleDelegate
, dwReserved
,
658 end_object_call( This
);
664 static HRESULT WINAPI
DefaultHandler_DoVerb(
667 struct tagMSG
* lpmsg
,
668 IOleClientSite
* pActiveSite
,
673 DefaultHandler
*This
= impl_from_IOleObject(iface
);
674 IRunnableObject
*pRunnableObj
= &This
->IRunnableObject_iface
;
677 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb
, lpmsg
, pActiveSite
, lindex
, hwndParent
, wine_dbgstr_rect(lprcPosRect
));
679 hr
= IRunnableObject_Run(pRunnableObj
, NULL
);
680 if (FAILED(hr
)) return hr
;
682 start_object_call( This
);
683 hr
= IOleObject_DoVerb(This
->pOleDelegate
, iVerb
, lpmsg
, pActiveSite
,
684 lindex
, hwndParent
, lprcPosRect
);
685 end_object_call( This
);
690 /************************************************************************
691 * DefaultHandler_EnumVerbs (IOleObject)
693 * The default handler implementation of this method simply delegates
696 * See Windows documentation for more details on IOleObject methods.
698 static HRESULT WINAPI
DefaultHandler_EnumVerbs(
700 IEnumOLEVERB
** ppEnumOleVerb
)
702 DefaultHandler
*This
= impl_from_IOleObject(iface
);
703 HRESULT hr
= OLE_S_USEREG
;
705 TRACE("(%p, %p)\n", iface
, ppEnumOleVerb
);
707 if (object_is_running(This
))
709 start_object_call( This
);
710 hr
= IOleObject_EnumVerbs(This
->pOleDelegate
, ppEnumOleVerb
);
711 end_object_call( This
);
714 if (hr
== OLE_S_USEREG
)
715 return OleRegEnumVerbs(&This
->clsid
, ppEnumOleVerb
);
720 static HRESULT WINAPI
DefaultHandler_Update(
723 DefaultHandler
*This
= impl_from_IOleObject(iface
);
726 TRACE("(%p)\n", iface
);
728 if (!object_is_running(This
))
730 FIXME("Should run object\n");
734 start_object_call( This
);
735 hr
= IOleObject_Update(This
->pOleDelegate
);
736 end_object_call( This
);
741 /************************************************************************
742 * DefaultHandler_IsUpToDate (IOleObject)
744 * This method is meaningless if the server is not running
746 * See Windows documentation for more details on IOleObject methods.
748 static HRESULT WINAPI
DefaultHandler_IsUpToDate(
751 DefaultHandler
*This
= impl_from_IOleObject(iface
);
752 HRESULT hr
= OLE_E_NOTRUNNING
;
753 TRACE("(%p)\n", iface
);
755 if (object_is_running(This
))
757 start_object_call( This
);
758 hr
= IOleObject_IsUpToDate(This
->pOleDelegate
);
759 end_object_call( This
);
765 /************************************************************************
766 * DefaultHandler_GetUserClassID (IOleObject)
768 * TODO: Map to a new class ID if emulation is active.
770 * See Windows documentation for more details on IOleObject methods.
772 static HRESULT WINAPI
DefaultHandler_GetUserClassID(
776 DefaultHandler
*This
= impl_from_IOleObject(iface
);
779 TRACE("(%p, %p)\n", iface
, pClsid
);
781 if (object_is_running(This
))
783 start_object_call( This
);
784 hr
= IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
785 end_object_call( This
);
792 *pClsid
= This
->clsid
;
797 /************************************************************************
798 * DefaultHandler_GetUserType (IOleObject)
800 * The default handler implementation of this method simply delegates
801 * to OleRegGetUserType
803 * See Windows documentation for more details on IOleObject methods.
805 static HRESULT WINAPI
DefaultHandler_GetUserType(
808 LPOLESTR
* pszUserType
)
810 DefaultHandler
*This
= impl_from_IOleObject(iface
);
813 TRACE("(%p, %d, %p)\n", iface
, dwFormOfType
, pszUserType
);
814 if (object_is_running(This
))
816 start_object_call( This
);
817 hr
= IOleObject_GetUserType(This
->pOleDelegate
, dwFormOfType
, pszUserType
);
818 end_object_call( This
);
822 return OleRegGetUserType(&This
->clsid
, dwFormOfType
, pszUserType
);
825 /************************************************************************
826 * DefaultHandler_SetExtent (IOleObject)
828 * This method is meaningless if the server is not running
830 * See Windows documentation for more details on IOleObject methods.
832 static HRESULT WINAPI
DefaultHandler_SetExtent(
837 DefaultHandler
*This
= impl_from_IOleObject(iface
);
838 HRESULT hr
= OLE_E_NOTRUNNING
;
840 TRACE("(%p, %x, (%d x %d))\n", iface
,
841 dwDrawAspect
, psizel
->cx
, psizel
->cy
);
843 if (object_is_running(This
))
845 start_object_call( This
);
846 hr
= IOleObject_SetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
847 end_object_call( This
);
853 /************************************************************************
854 * DefaultHandler_GetExtent (IOleObject)
856 * The default handler's implementation of this method returns uses
857 * the cache to locate the aspect and extract the extent from it.
859 * See Windows documentation for more details on IOleObject methods.
861 static HRESULT WINAPI
DefaultHandler_GetExtent(
866 DVTARGETDEVICE
* targetDevice
;
867 IViewObject2
* cacheView
= NULL
;
870 DefaultHandler
*This
= impl_from_IOleObject(iface
);
872 TRACE("(%p, %x, %p)\n", iface
, dwDrawAspect
, psizel
);
874 if (object_is_running(This
))
876 start_object_call( This
);
877 hres
= IOleObject_GetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
878 end_object_call( This
);
882 hres
= IUnknown_QueryInterface(This
->dataCache
, &IID_IViewObject2
, (void**)&cacheView
);
887 * Prepare the call to the cache's GetExtent method.
889 * Here we would build a valid DVTARGETDEVICE structure
890 * but, since we are calling into the data cache, we
891 * know its implementation and we'll skip this
892 * extra work until later.
896 hres
= IViewObject2_GetExtent(cacheView
,
902 IViewObject2_Release(cacheView
);
907 /************************************************************************
908 * DefaultHandler_Advise (IOleObject)
910 * The default handler's implementation of this method simply
911 * delegates to the OleAdviseHolder.
913 * See Windows documentation for more details on IOleObject methods.
915 static HRESULT WINAPI
DefaultHandler_Advise(
917 IAdviseSink
* pAdvSink
,
918 DWORD
* pdwConnection
)
921 DefaultHandler
*This
= impl_from_IOleObject(iface
);
923 TRACE("(%p, %p, %p)\n", iface
, pAdvSink
, pdwConnection
);
925 /* Make sure we have an advise holder before we start. */
926 if (!This
->oleAdviseHolder
)
927 hres
= CreateOleAdviseHolder(&This
->oleAdviseHolder
);
930 hres
= IOleAdviseHolder_Advise(This
->oleAdviseHolder
,
937 /************************************************************************
938 * DefaultHandler_Unadvise (IOleObject)
940 * The default handler's implementation of this method simply
941 * delegates to the OleAdviseHolder.
943 * See Windows documentation for more details on IOleObject methods.
945 static HRESULT WINAPI
DefaultHandler_Unadvise(
949 DefaultHandler
*This
= impl_from_IOleObject(iface
);
951 TRACE("(%p, %d)\n", iface
, dwConnection
);
954 * If we don't have an advise holder yet, it means we don't have
957 if (!This
->oleAdviseHolder
)
958 return OLE_E_NOCONNECTION
;
960 return IOleAdviseHolder_Unadvise(This
->oleAdviseHolder
,
964 /************************************************************************
965 * DefaultHandler_EnumAdvise (IOleObject)
967 * The default handler's implementation of this method simply
968 * delegates to the OleAdviseHolder.
970 * See Windows documentation for more details on IOleObject methods.
972 static HRESULT WINAPI
DefaultHandler_EnumAdvise(
974 IEnumSTATDATA
** ppenumAdvise
)
976 DefaultHandler
*This
= impl_from_IOleObject(iface
);
978 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
983 *ppenumAdvise
= NULL
;
985 if (!This
->oleAdviseHolder
)
988 return IOleAdviseHolder_EnumAdvise(This
->oleAdviseHolder
, ppenumAdvise
);
991 /************************************************************************
992 * DefaultHandler_GetMiscStatus (IOleObject)
994 * The default handler's implementation of this method simply delegates
995 * to OleRegGetMiscStatus.
997 * See Windows documentation for more details on IOleObject methods.
999 static HRESULT WINAPI
DefaultHandler_GetMiscStatus(
1005 DefaultHandler
*This
= impl_from_IOleObject(iface
);
1007 TRACE("(%p, %x, %p)\n", iface
, dwAspect
, pdwStatus
);
1009 if (object_is_running(This
))
1011 start_object_call( This
);
1012 hres
= IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
1013 end_object_call( This
);
1017 hres
= OleRegGetMiscStatus(&This
->clsid
, dwAspect
, pdwStatus
);
1025 /************************************************************************
1026 * DefaultHandler_SetColorScheme (IOleObject)
1028 * This method is meaningless if the server is not running
1030 * See Windows documentation for more details on IOleObject methods.
1032 static HRESULT WINAPI
DefaultHandler_SetColorScheme(
1034 struct tagLOGPALETTE
* pLogpal
)
1036 DefaultHandler
*This
= impl_from_IOleObject(iface
);
1037 HRESULT hr
= OLE_E_NOTRUNNING
;
1039 TRACE("(%p, %p))\n", iface
, pLogpal
);
1041 if (object_is_running(This
))
1043 start_object_call( This
);
1044 hr
= IOleObject_SetColorScheme(This
->pOleDelegate
, pLogpal
);
1045 end_object_call( This
);
1051 /*********************************************************
1052 * Methods implementation for the IDataObject part of
1053 * the DefaultHandler class.
1056 /************************************************************************
1057 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
1059 * See Windows documentation for more details on IUnknown methods.
1061 static HRESULT WINAPI
DefaultHandler_IDataObject_QueryInterface(
1066 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1068 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1071 /************************************************************************
1072 * DefaultHandler_IDataObject_AddRef (IUnknown)
1074 * See Windows documentation for more details on IUnknown methods.
1076 static ULONG WINAPI
DefaultHandler_IDataObject_AddRef(
1079 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1081 return IUnknown_AddRef(This
->outerUnknown
);
1084 /************************************************************************
1085 * DefaultHandler_IDataObject_Release (IUnknown)
1087 * See Windows documentation for more details on IUnknown methods.
1089 static ULONG WINAPI
DefaultHandler_IDataObject_Release(
1092 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1094 return IUnknown_Release(This
->outerUnknown
);
1097 /************************************************************************
1098 * DefaultHandler_GetData
1100 * Get Data from a source dataobject using format pformatetcIn->cfFormat
1101 * See Windows documentation for more details on GetData.
1102 * Default handler's implementation of this method delegates to the cache.
1104 static HRESULT WINAPI
DefaultHandler_GetData(
1106 LPFORMATETC pformatetcIn
,
1109 IDataObject
* cacheDataObject
= NULL
;
1112 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1114 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pmedium
);
1116 hres
= IUnknown_QueryInterface(This
->dataCache
,
1118 (void**)&cacheDataObject
);
1121 return E_UNEXPECTED
;
1123 hres
= IDataObject_GetData(cacheDataObject
,
1127 IDataObject_Release(cacheDataObject
);
1129 if (hres
== S_OK
) return hres
;
1131 if (object_is_running( This
))
1133 start_object_call(This
);
1134 hres
= IDataObject_GetData(This
->pDataDelegate
, pformatetcIn
, pmedium
);
1135 end_object_call(This
);
1136 if (hres
== S_OK
) return hres
;
1139 /* Query running state again, as the object may have closed during _GetData call */
1140 if (!object_is_running( This
))
1141 hres
= OLE_E_NOTRUNNING
;
1146 static HRESULT WINAPI
DefaultHandler_GetDataHere(
1148 LPFORMATETC pformatetc
,
1155 /************************************************************************
1156 * DefaultHandler_QueryGetData (IDataObject)
1158 * The default handler's implementation of this method delegates to
1161 * See Windows documentation for more details on IDataObject methods.
1163 static HRESULT WINAPI
DefaultHandler_QueryGetData(
1165 LPFORMATETC pformatetc
)
1167 IDataObject
* cacheDataObject
= NULL
;
1170 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1172 TRACE("(%p, %p)\n", iface
, pformatetc
);
1174 hres
= IUnknown_QueryInterface(This
->dataCache
,
1176 (void**)&cacheDataObject
);
1179 return E_UNEXPECTED
;
1181 hres
= IDataObject_QueryGetData(cacheDataObject
,
1184 IDataObject_Release(cacheDataObject
);
1186 if (hres
== S_OK
) return hres
;
1188 if (object_is_running( This
))
1190 start_object_call( This
);
1191 hres
= IDataObject_QueryGetData(This
->pDataDelegate
, pformatetc
);
1192 end_object_call( This
);
1193 if (hres
== S_OK
) return hres
;
1196 /* Query running state again, as the object may have closed during _QueryGetData call */
1197 if (!object_is_running( This
))
1198 hres
= OLE_E_NOTRUNNING
;
1203 /************************************************************************
1204 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1206 * This method is meaningless if the server is not running
1208 * See Windows documentation for more details on IDataObject methods.
1210 static HRESULT WINAPI
DefaultHandler_GetCanonicalFormatEtc(
1212 LPFORMATETC pformatetcIn
,
1213 LPFORMATETC pformatetcOut
)
1215 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1218 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pformatetcOut
);
1220 if (!object_is_running( This
))
1221 return OLE_E_NOTRUNNING
;
1223 start_object_call( This
);
1224 hr
= IDataObject_GetCanonicalFormatEtc(This
->pDataDelegate
, pformatetcIn
, pformatetcOut
);
1225 end_object_call( This
);
1230 /************************************************************************
1231 * DefaultHandler_SetData (IDataObject)
1233 * The default handler's implementation of this method delegates to
1236 * See Windows documentation for more details on IDataObject methods.
1238 static HRESULT WINAPI
DefaultHandler_SetData(
1240 LPFORMATETC pformatetc
,
1244 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1245 IDataObject
* cacheDataObject
= NULL
;
1248 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1250 hres
= IUnknown_QueryInterface(This
->dataCache
,
1252 (void**)&cacheDataObject
);
1255 return E_UNEXPECTED
;
1257 hres
= IDataObject_SetData(cacheDataObject
,
1262 IDataObject_Release(cacheDataObject
);
1267 /************************************************************************
1268 * DefaultHandler_EnumFormatEtc (IDataObject)
1270 * The default handler's implementation of This method simply delegates
1271 * to OleRegEnumFormatEtc.
1273 * See Windows documentation for more details on IDataObject methods.
1275 static HRESULT WINAPI
DefaultHandler_EnumFormatEtc(
1278 IEnumFORMATETC
** ppenumFormatEtc
)
1280 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1282 TRACE("(%p, %x, %p)\n", iface
, dwDirection
, ppenumFormatEtc
);
1284 return OleRegEnumFormatEtc(&This
->clsid
, dwDirection
, ppenumFormatEtc
);
1287 /************************************************************************
1288 * DefaultHandler_DAdvise (IDataObject)
1290 * The default handler's implementation of this method simply
1291 * delegates to the DataAdviseHolder.
1293 * See Windows documentation for more details on IDataObject methods.
1295 static HRESULT WINAPI
DefaultHandler_DAdvise(
1297 FORMATETC
* pformatetc
,
1299 IAdviseSink
* pAdvSink
,
1300 DWORD
* pdwConnection
)
1302 HRESULT hres
= S_OK
;
1303 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1305 TRACE("(%p, %p, %d, %p, %p)\n",
1306 iface
, pformatetc
, advf
, pAdvSink
, pdwConnection
);
1308 /* Make sure we have a data advise holder before we start. */
1309 if (!This
->dataAdviseHolder
)
1311 hres
= CreateDataAdviseHolder(&This
->dataAdviseHolder
);
1312 if (SUCCEEDED(hres
) && object_is_running( This
))
1314 start_object_call( This
);
1315 DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1316 end_object_call( This
);
1320 if (SUCCEEDED(hres
))
1321 hres
= IDataAdviseHolder_Advise(This
->dataAdviseHolder
,
1331 /************************************************************************
1332 * DefaultHandler_DUnadvise (IDataObject)
1334 * The default handler's implementation of this method simply
1335 * delegates to the DataAdviseHolder.
1337 * See Windows documentation for more details on IDataObject methods.
1339 static HRESULT WINAPI
DefaultHandler_DUnadvise(
1343 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1345 TRACE("(%p, %d)\n", iface
, dwConnection
);
1348 * If we don't have a data advise holder yet, it means that
1349 * we don't have any connections..
1351 if (!This
->dataAdviseHolder
)
1352 return OLE_E_NOCONNECTION
;
1354 return IDataAdviseHolder_Unadvise(This
->dataAdviseHolder
,
1358 /************************************************************************
1359 * DefaultHandler_EnumDAdvise (IDataObject)
1361 * The default handler's implementation of this method simply
1362 * delegates to the DataAdviseHolder.
1364 * See Windows documentation for more details on IDataObject methods.
1366 static HRESULT WINAPI
DefaultHandler_EnumDAdvise(
1368 IEnumSTATDATA
** ppenumAdvise
)
1370 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1372 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
1377 *ppenumAdvise
= NULL
;
1379 /* If we have a data advise holder object, delegate. */
1380 if (This
->dataAdviseHolder
)
1381 return IDataAdviseHolder_EnumAdvise(This
->dataAdviseHolder
,
1387 /*********************************************************
1388 * Methods implementation for the IRunnableObject part
1389 * of the DefaultHandler class.
1392 /************************************************************************
1393 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1395 * See Windows documentation for more details on IUnknown methods.
1397 static HRESULT WINAPI
DefaultHandler_IRunnableObject_QueryInterface(
1398 IRunnableObject
* iface
,
1402 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1404 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1407 /************************************************************************
1408 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1410 * See Windows documentation for more details on IUnknown methods.
1412 static ULONG WINAPI
DefaultHandler_IRunnableObject_AddRef(
1413 IRunnableObject
* iface
)
1415 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1417 return IUnknown_AddRef(This
->outerUnknown
);
1420 /************************************************************************
1421 * DefaultHandler_IRunnableObject_Release (IUnknown)
1423 * See Windows documentation for more details on IUnknown methods.
1425 static ULONG WINAPI
DefaultHandler_IRunnableObject_Release(
1426 IRunnableObject
* iface
)
1428 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1430 return IUnknown_Release(This
->outerUnknown
);
1433 /************************************************************************
1434 * DefaultHandler_GetRunningClass (IRunnableObject)
1436 * See Windows documentation for more details on IRunnableObject methods.
1438 static HRESULT WINAPI
DefaultHandler_GetRunningClass(
1439 IRunnableObject
* iface
,
1446 static HRESULT WINAPI
DefaultHandler_Run(
1447 IRunnableObject
* iface
,
1450 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1452 IOleCacheControl
*cache_ctrl
;
1454 FIXME("(%p): semi-stub\n", pbc
);
1456 /* already running? if so nothing to do */
1457 if (object_is_running(This
))
1460 release_delegates(This
);
1462 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_LOCAL_SERVER
| CLSCTX_REMOTE_SERVER
,
1463 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1467 hr
= IOleObject_Advise(This
->pOleDelegate
, &This
->IAdviseSink_iface
, &This
->dwAdvConn
);
1468 if (FAILED(hr
)) goto fail
;
1470 if (This
->clientSite
)
1472 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, This
->clientSite
);
1473 if (FAILED(hr
)) goto fail
;
1476 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
,
1477 (void **)&This
->pPSDelegate
);
1478 if (FAILED(hr
)) goto fail
;
1480 if (This
->storage_state
== storage_state_initialised
)
1481 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, This
->storage
);
1482 else if (This
->storage_state
== storage_state_loaded
)
1483 hr
= IPersistStorage_Load(This
->pPSDelegate
, This
->storage
);
1484 if (FAILED(hr
)) goto fail
;
1486 if (This
->containerApp
)
1488 hr
= IOleObject_SetHostNames(This
->pOleDelegate
, This
->containerApp
,
1489 This
->containerObj
);
1490 if (FAILED(hr
)) goto fail
;
1493 /* FIXME: do more stuff here:
1494 * - IOleObject_GetMiscStatus
1495 * - IOleObject_GetMoniker
1498 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
,
1499 (void **)&This
->pDataDelegate
);
1500 if (FAILED(hr
)) goto fail
;
1502 This
->object_state
= object_state_running
;
1504 if (This
->dataAdviseHolder
)
1506 hr
= DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1507 if (FAILED(hr
)) goto fail
;
1510 hr
= IUnknown_QueryInterface( This
->dataCache
, &IID_IOleCacheControl
, (void **)&cache_ctrl
);
1511 if (FAILED(hr
)) goto fail
;
1512 hr
= IOleCacheControl_OnRun( cache_ctrl
, This
->pDataDelegate
);
1513 IOleCacheControl_Release( cache_ctrl
);
1514 if (FAILED(hr
)) goto fail
;
1519 DefaultHandler_Stop(This
);
1523 /************************************************************************
1524 * DefaultHandler_IsRunning (IRunnableObject)
1526 * See Windows documentation for more details on IRunnableObject methods.
1528 static BOOL WINAPI
DefaultHandler_IsRunning(
1529 IRunnableObject
* iface
)
1531 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1535 if (This
->object_state
== object_state_running
)
1541 /************************************************************************
1542 * DefaultHandler_LockRunning (IRunnableObject)
1544 * See Windows documentation for more details on IRunnableObject methods.
1546 static HRESULT WINAPI
DefaultHandler_LockRunning(
1547 IRunnableObject
* iface
,
1549 BOOL fLastUnlockCloses
)
1555 /************************************************************************
1556 * DefaultHandler_SetContainedObject (IRunnableObject)
1558 * See Windows documentation for more details on IRunnableObject methods.
1560 static HRESULT WINAPI
DefaultHandler_SetContainedObject(
1561 IRunnableObject
* iface
,
1568 static HRESULT WINAPI
DefaultHandler_IAdviseSink_QueryInterface(
1573 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1574 IsEqualIID(riid
, &IID_IAdviseSink
))
1577 IAdviseSink_AddRef(iface
);
1581 return E_NOINTERFACE
;
1584 static ULONG WINAPI
DefaultHandler_IAdviseSink_AddRef(
1587 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1589 return IUnknown_AddRef(&This
->IUnknown_iface
);
1592 static ULONG WINAPI
DefaultHandler_IAdviseSink_Release(
1595 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1597 return IUnknown_Release(&This
->IUnknown_iface
);
1600 static void WINAPI
DefaultHandler_IAdviseSink_OnDataChange(
1602 FORMATETC
*pFormatetc
,
1608 static void WINAPI
DefaultHandler_IAdviseSink_OnViewChange(
1616 static void WINAPI
DefaultHandler_IAdviseSink_OnRename(
1620 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1622 TRACE("(%p)\n", pmk
);
1624 if (This
->oleAdviseHolder
)
1625 IOleAdviseHolder_SendOnRename(This
->oleAdviseHolder
, pmk
);
1628 static void WINAPI
DefaultHandler_IAdviseSink_OnSave(
1631 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1635 if (This
->oleAdviseHolder
)
1636 IOleAdviseHolder_SendOnSave(This
->oleAdviseHolder
);
1639 static void WINAPI
DefaultHandler_IAdviseSink_OnClose(
1642 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1646 if (This
->oleAdviseHolder
)
1647 IOleAdviseHolder_SendOnClose(This
->oleAdviseHolder
);
1650 DefaultHandler_Stop(This
);
1653 TRACE("OnClose during call. Deferring shutdown\n");
1654 This
->object_state
= object_state_deferred_close
;
1658 /************************************************************************
1659 * DefaultHandler_IPersistStorage_QueryInterface
1662 static HRESULT WINAPI
DefaultHandler_IPersistStorage_QueryInterface(
1663 IPersistStorage
* iface
,
1667 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1669 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1672 /************************************************************************
1673 * DefaultHandler_IPersistStorage_AddRef
1676 static ULONG WINAPI
DefaultHandler_IPersistStorage_AddRef(
1677 IPersistStorage
* iface
)
1679 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1681 return IUnknown_AddRef(This
->outerUnknown
);
1684 /************************************************************************
1685 * DefaultHandler_IPersistStorage_Release
1688 static ULONG WINAPI
DefaultHandler_IPersistStorage_Release(
1689 IPersistStorage
* iface
)
1691 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1693 return IUnknown_Release(This
->outerUnknown
);
1696 /************************************************************************
1697 * DefaultHandler_IPersistStorage_GetClassID
1700 static HRESULT WINAPI
DefaultHandler_IPersistStorage_GetClassID(
1701 IPersistStorage
* iface
,
1704 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1707 TRACE("(%p)->(%p)\n", iface
, clsid
);
1709 if(object_is_running(This
))
1711 start_object_call( This
);
1712 hr
= IPersistStorage_GetClassID(This
->pPSDelegate
, clsid
);
1713 end_object_call( This
);
1716 hr
= IPersistStorage_GetClassID(This
->dataCache_PersistStg
, clsid
);
1721 /************************************************************************
1722 * DefaultHandler_IPersistStorage_IsDirty
1725 static HRESULT WINAPI
DefaultHandler_IPersistStorage_IsDirty(
1726 IPersistStorage
* iface
)
1728 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1731 TRACE("(%p)\n", iface
);
1733 hr
= IPersistStorage_IsDirty(This
->dataCache_PersistStg
);
1734 if(hr
!= S_FALSE
) return hr
;
1736 if(object_is_running(This
))
1738 start_object_call( This
);
1739 hr
= IPersistStorage_IsDirty(This
->pPSDelegate
);
1740 end_object_call( This
);
1746 /***********************************************************************
1748 * The format of '\1Ole' stream is as follows:
1750 * DWORD Version == 0x02000001
1751 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1752 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1753 * supplied by the app that creates the data structure. May be
1754 * ignored on processing].
1756 * DWORD Reserved == 0
1757 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1758 * CLSID clsid - class id of object capable of processing the moniker
1759 * BYTE data[] - moniker data for a link
1762 static const WCHAR OleStream
[] = {1,'O','l','e',0};
1767 DWORD link_update_opt
;
1770 } ole_stream_header_t
;
1771 static const DWORD ole_stream_version
= 0x02000001;
1773 static HRESULT
load_ole_stream(DefaultHandler
*This
, IStorage
*storage
)
1778 hr
= IStorage_OpenStream(storage
, OleStream
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stream
);
1783 ole_stream_header_t header
;
1785 hr
= IStream_Read(stream
, &header
, sizeof(header
), &read
);
1786 if(hr
== S_OK
&& read
== sizeof(header
) && header
.version
== ole_stream_version
)
1788 if(header
.flags
& 1)
1790 /* FIXME: Read the moniker and deal with the link */
1791 FIXME("Linked objects are not supported yet\n");
1796 WARN("Incorrect OleStream header\n");
1797 hr
= DV_E_CLIPFORMAT
;
1799 IStream_Release(stream
);
1802 hr
= STORAGE_CreateOleStream(storage
, 0);
1807 /************************************************************************
1808 * DefaultHandler_IPersistStorage_InitNew
1811 static HRESULT WINAPI
DefaultHandler_IPersistStorage_InitNew(
1812 IPersistStorage
* iface
,
1815 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1818 TRACE("(%p)->(%p)\n", iface
, pStg
);
1819 hr
= STORAGE_CreateOleStream(pStg
, 0);
1820 if (hr
!= S_OK
) return hr
;
1822 hr
= IPersistStorage_InitNew(This
->dataCache_PersistStg
, pStg
);
1824 if(SUCCEEDED(hr
) && object_is_running(This
))
1826 start_object_call( This
);
1827 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, pStg
);
1828 end_object_call( This
);
1833 IStorage_AddRef(pStg
);
1834 This
->storage
= pStg
;
1835 This
->storage_state
= storage_state_initialised
;
1842 /************************************************************************
1843 * DefaultHandler_IPersistStorage_Load
1846 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Load(
1847 IPersistStorage
* iface
,
1850 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1853 TRACE("(%p)->(%p)\n", iface
, pStg
);
1855 hr
= load_ole_stream(This
, pStg
);
1858 hr
= IPersistStorage_Load(This
->dataCache_PersistStg
, pStg
);
1860 if(SUCCEEDED(hr
) && object_is_running(This
))
1862 start_object_call( This
);
1863 hr
= IPersistStorage_Load(This
->pPSDelegate
, pStg
);
1864 end_object_call( This
);
1869 IStorage_AddRef(pStg
);
1870 This
->storage
= pStg
;
1871 This
->storage_state
= storage_state_loaded
;
1877 /************************************************************************
1878 * DefaultHandler_IPersistStorage_Save
1881 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Save(
1882 IPersistStorage
* iface
,
1886 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1889 TRACE("(%p)->(%p, %d)\n", iface
, pStgSave
, fSameAsLoad
);
1891 hr
= IPersistStorage_Save(This
->dataCache_PersistStg
, pStgSave
, fSameAsLoad
);
1892 if(SUCCEEDED(hr
) && object_is_running(This
))
1894 start_object_call( This
);
1895 hr
= IPersistStorage_Save(This
->pPSDelegate
, pStgSave
, fSameAsLoad
);
1896 end_object_call( This
);
1903 /************************************************************************
1904 * DefaultHandler_IPersistStorage_SaveCompleted
1907 static HRESULT WINAPI
DefaultHandler_IPersistStorage_SaveCompleted(
1908 IPersistStorage
* iface
,
1911 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1914 TRACE("(%p)->(%p)\n", iface
, pStgNew
);
1916 hr
= IPersistStorage_SaveCompleted(This
->dataCache_PersistStg
, pStgNew
);
1918 if(SUCCEEDED(hr
) && object_is_running(This
))
1920 start_object_call( This
);
1921 hr
= IPersistStorage_SaveCompleted(This
->pPSDelegate
, pStgNew
);
1922 end_object_call( This
);
1927 IStorage_AddRef(pStgNew
);
1928 if(This
->storage
) IStorage_Release(This
->storage
);
1929 This
->storage
= pStgNew
;
1930 This
->storage_state
= storage_state_loaded
;
1937 /************************************************************************
1938 * DefaultHandler_IPersistStorage_HandsOffStorage
1941 static HRESULT WINAPI
DefaultHandler_IPersistStorage_HandsOffStorage(
1942 IPersistStorage
* iface
)
1944 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1947 TRACE("(%p)\n", iface
);
1949 hr
= IPersistStorage_HandsOffStorage(This
->dataCache_PersistStg
);
1951 if(SUCCEEDED(hr
) && object_is_running(This
))
1953 start_object_call( This
);
1954 hr
= IPersistStorage_HandsOffStorage(This
->pPSDelegate
);
1955 end_object_call( This
);
1958 if(This
->storage
) IStorage_Release(This
->storage
);
1959 This
->storage
= NULL
;
1960 This
->storage_state
= storage_state_uninitialised
;
1967 * Virtual function tables for the DefaultHandler class.
1969 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable
=
1971 DefaultHandler_QueryInterface
,
1972 DefaultHandler_AddRef
,
1973 DefaultHandler_Release
,
1974 DefaultHandler_SetClientSite
,
1975 DefaultHandler_GetClientSite
,
1976 DefaultHandler_SetHostNames
,
1977 DefaultHandler_Close
,
1978 DefaultHandler_SetMoniker
,
1979 DefaultHandler_GetMoniker
,
1980 DefaultHandler_InitFromData
,
1981 DefaultHandler_GetClipboardData
,
1982 DefaultHandler_DoVerb
,
1983 DefaultHandler_EnumVerbs
,
1984 DefaultHandler_Update
,
1985 DefaultHandler_IsUpToDate
,
1986 DefaultHandler_GetUserClassID
,
1987 DefaultHandler_GetUserType
,
1988 DefaultHandler_SetExtent
,
1989 DefaultHandler_GetExtent
,
1990 DefaultHandler_Advise
,
1991 DefaultHandler_Unadvise
,
1992 DefaultHandler_EnumAdvise
,
1993 DefaultHandler_GetMiscStatus
,
1994 DefaultHandler_SetColorScheme
1997 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable
=
1999 DefaultHandler_NDIUnknown_QueryInterface
,
2000 DefaultHandler_NDIUnknown_AddRef
,
2001 DefaultHandler_NDIUnknown_Release
,
2004 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable
=
2006 DefaultHandler_IDataObject_QueryInterface
,
2007 DefaultHandler_IDataObject_AddRef
,
2008 DefaultHandler_IDataObject_Release
,
2009 DefaultHandler_GetData
,
2010 DefaultHandler_GetDataHere
,
2011 DefaultHandler_QueryGetData
,
2012 DefaultHandler_GetCanonicalFormatEtc
,
2013 DefaultHandler_SetData
,
2014 DefaultHandler_EnumFormatEtc
,
2015 DefaultHandler_DAdvise
,
2016 DefaultHandler_DUnadvise
,
2017 DefaultHandler_EnumDAdvise
2020 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable
=
2022 DefaultHandler_IRunnableObject_QueryInterface
,
2023 DefaultHandler_IRunnableObject_AddRef
,
2024 DefaultHandler_IRunnableObject_Release
,
2025 DefaultHandler_GetRunningClass
,
2027 DefaultHandler_IsRunning
,
2028 DefaultHandler_LockRunning
,
2029 DefaultHandler_SetContainedObject
2032 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable
=
2034 DefaultHandler_IAdviseSink_QueryInterface
,
2035 DefaultHandler_IAdviseSink_AddRef
,
2036 DefaultHandler_IAdviseSink_Release
,
2037 DefaultHandler_IAdviseSink_OnDataChange
,
2038 DefaultHandler_IAdviseSink_OnViewChange
,
2039 DefaultHandler_IAdviseSink_OnRename
,
2040 DefaultHandler_IAdviseSink_OnSave
,
2041 DefaultHandler_IAdviseSink_OnClose
2044 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable
=
2046 DefaultHandler_IPersistStorage_QueryInterface
,
2047 DefaultHandler_IPersistStorage_AddRef
,
2048 DefaultHandler_IPersistStorage_Release
,
2049 DefaultHandler_IPersistStorage_GetClassID
,
2050 DefaultHandler_IPersistStorage_IsDirty
,
2051 DefaultHandler_IPersistStorage_InitNew
,
2052 DefaultHandler_IPersistStorage_Load
,
2053 DefaultHandler_IPersistStorage_Save
,
2054 DefaultHandler_IPersistStorage_SaveCompleted
,
2055 DefaultHandler_IPersistStorage_HandsOffStorage
2058 /*********************************************************
2059 * Methods implementation for the DefaultHandler class.
2061 static DefaultHandler
* DefaultHandler_Construct(
2063 LPUNKNOWN pUnkOuter
,
2067 DefaultHandler
* This
= NULL
;
2070 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler
));
2075 This
->IOleObject_iface
.lpVtbl
= &DefaultHandler_IOleObject_VTable
;
2076 This
->IUnknown_iface
.lpVtbl
= &DefaultHandler_NDIUnknown_VTable
;
2077 This
->IDataObject_iface
.lpVtbl
= &DefaultHandler_IDataObject_VTable
;
2078 This
->IRunnableObject_iface
.lpVtbl
= &DefaultHandler_IRunnableObject_VTable
;
2079 This
->IAdviseSink_iface
.lpVtbl
= &DefaultHandler_IAdviseSink_VTable
;
2080 This
->IPersistStorage_iface
.lpVtbl
= &DefaultHandler_IPersistStorage_VTable
;
2082 This
->inproc_server
= (flags
& EMBDHLP_INPROC_SERVER
) != 0;
2085 * Start with one reference count. The caller of this function
2086 * must release the interface pointer when it is done.
2091 * Initialize the outer unknown
2092 * We don't keep a reference on the outer unknown since, the way
2093 * aggregation works, our lifetime is at least as large as its
2097 pUnkOuter
= &This
->IUnknown_iface
;
2099 This
->outerUnknown
= pUnkOuter
;
2102 * Create a datacache object.
2103 * We aggregate with the datacache. Make sure we pass our outer
2104 * unknown as the datacache's outer unknown.
2106 hr
= CreateDataCache(This
->outerUnknown
,
2109 (void**)&This
->dataCache
);
2112 hr
= IUnknown_QueryInterface(This
->dataCache
, &IID_IPersistStorage
, (void**)&This
->dataCache_PersistStg
);
2113 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
2114 * reference on the outer object */
2116 IUnknown_Release(This
->outerUnknown
);
2118 IUnknown_Release(This
->dataCache
);
2122 ERR("Unexpected error creating data cache\n");
2123 HeapFree(GetProcessHeap(), 0, This
);
2127 This
->clsid
= *clsid
;
2128 This
->clientSite
= NULL
;
2129 This
->oleAdviseHolder
= NULL
;
2130 This
->dataAdviseHolder
= NULL
;
2131 This
->containerApp
= NULL
;
2132 This
->containerObj
= NULL
;
2133 This
->pOleDelegate
= NULL
;
2134 This
->pPSDelegate
= NULL
;
2135 This
->pDataDelegate
= NULL
;
2136 This
->object_state
= object_state_not_running
;
2139 This
->dwAdvConn
= 0;
2140 This
->storage
= NULL
;
2141 This
->storage_state
= storage_state_uninitialised
;
2143 if (This
->inproc_server
&& !(flags
& EMBDHLP_DELAYCREATE
))
2146 This
->pCFObject
= NULL
;
2148 hr
= IClassFactory_CreateInstance(pCF
, NULL
, &IID_IOleObject
, (void **)&This
->pOleDelegate
);
2150 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
2151 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
2153 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
, (void **)&This
->pPSDelegate
);
2155 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
, (void **)&This
->pDataDelegate
);
2157 This
->object_state
= object_state_running
;
2159 WARN("object creation failed with error %08x\n", hr
);
2163 This
->pCFObject
= pCF
;
2164 if (pCF
) IClassFactory_AddRef(pCF
);
2170 static void DefaultHandler_Destroy(
2171 DefaultHandler
* This
)
2173 TRACE("(%p)\n", This
);
2175 /* AddRef/Release may be called on this object during destruction.
2176 * Prevent the object being destroyed recursively by artificially raising
2177 * the reference count. */
2180 /* release delegates */
2181 DefaultHandler_Stop(This
);
2183 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
2184 This
->containerApp
= NULL
;
2185 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
2186 This
->containerObj
= NULL
;
2188 if (This
->dataCache
)
2190 /* to balance out the release of dataCache_PersistStg which will result
2191 * in a reference being released from the outer unknown */
2192 IUnknown_AddRef(This
->outerUnknown
);
2193 IPersistStorage_Release(This
->dataCache_PersistStg
);
2194 IUnknown_Release(This
->dataCache
);
2195 This
->dataCache_PersistStg
= NULL
;
2196 This
->dataCache
= NULL
;
2199 if (This
->clientSite
)
2201 IOleClientSite_Release(This
->clientSite
);
2202 This
->clientSite
= NULL
;
2205 if (This
->oleAdviseHolder
)
2207 IOleAdviseHolder_Release(This
->oleAdviseHolder
);
2208 This
->oleAdviseHolder
= NULL
;
2211 if (This
->dataAdviseHolder
)
2213 IDataAdviseHolder_Release(This
->dataAdviseHolder
);
2214 This
->dataAdviseHolder
= NULL
;
2219 IStorage_Release(This
->storage
);
2220 This
->storage
= NULL
;
2223 if (This
->pCFObject
)
2225 IClassFactory_Release(This
->pCFObject
);
2226 This
->pCFObject
= NULL
;
2229 HeapFree(GetProcessHeap(), 0, This
);
2232 /******************************************************************************
2233 * OleCreateEmbeddingHelper [OLE32.@]
2235 HRESULT WINAPI
OleCreateEmbeddingHelper(
2237 LPUNKNOWN pUnkOuter
,
2243 DefaultHandler
* newHandler
= NULL
;
2246 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
, flags
, pCF
, debugstr_guid(riid
), ppvObj
);
2254 * If This handler is constructed for aggregation, make sure
2255 * the caller is requesting the IUnknown interface.
2256 * This is necessary because it's the only time the non-delegating
2257 * IUnknown pointer can be returned to the outside.
2259 if (pUnkOuter
&& !IsEqualIID(&IID_IUnknown
, riid
))
2260 return CLASS_E_NOAGGREGATION
;
2263 * Try to construct a new instance of the class.
2265 newHandler
= DefaultHandler_Construct(clsid
, pUnkOuter
, flags
, pCF
);
2268 return E_OUTOFMEMORY
;
2271 * Make sure it supports the interface required by the caller.
2273 hr
= IUnknown_QueryInterface(&newHandler
->IUnknown_iface
, riid
, ppvObj
);
2276 * Release the reference obtained in the constructor. If
2277 * the QueryInterface was unsuccessful, it will free the class.
2279 IUnknown_Release(&newHandler
->IUnknown_iface
);
2285 /******************************************************************************
2286 * OleCreateDefaultHandler [OLE32.@]
2288 HRESULT WINAPI
OleCreateDefaultHandler(REFCLSID clsid
, LPUNKNOWN pUnkOuter
,
2289 REFIID riid
, LPVOID
* ppvObj
)
2291 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
,debugstr_guid(riid
), ppvObj
);
2292 return OleCreateEmbeddingHelper(clsid
, pUnkOuter
, EMBDHLP_INPROC_HANDLER
| EMBDHLP_CREATENOW
,
2293 NULL
, riid
, ppvObj
);
2296 typedef struct HandlerCF
2298 IClassFactory IClassFactory_iface
;
2303 static inline HandlerCF
*impl_from_IClassFactory(IClassFactory
*iface
)
2305 return CONTAINING_RECORD(iface
, HandlerCF
, IClassFactory_iface
);
2308 static HRESULT WINAPI
2309 HandlerCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
, LPVOID
*ppv
)
2312 if (IsEqualIID(riid
,&IID_IUnknown
) ||
2313 IsEqualIID(riid
,&IID_IClassFactory
))
2316 IClassFactory_AddRef(iface
);
2319 return E_NOINTERFACE
;
2322 static ULONG WINAPI
HandlerCF_AddRef(LPCLASSFACTORY iface
)
2324 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2325 return InterlockedIncrement(&This
->refs
);
2328 static ULONG WINAPI
HandlerCF_Release(LPCLASSFACTORY iface
)
2330 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2331 ULONG refs
= InterlockedDecrement(&This
->refs
);
2333 HeapFree(GetProcessHeap(), 0, This
);
2337 static HRESULT WINAPI
2338 HandlerCF_CreateInstance(LPCLASSFACTORY iface
, LPUNKNOWN pUnk
,
2339 REFIID riid
, LPVOID
*ppv
)
2341 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2342 return OleCreateDefaultHandler(&This
->clsid
, pUnk
, riid
, ppv
);
2345 static HRESULT WINAPI
HandlerCF_LockServer(LPCLASSFACTORY iface
, BOOL fLock
)
2347 FIXME("(%d), stub!\n",fLock
);
2351 static const IClassFactoryVtbl HandlerClassFactoryVtbl
= {
2352 HandlerCF_QueryInterface
,
2355 HandlerCF_CreateInstance
,
2356 HandlerCF_LockServer
2359 HRESULT
HandlerCF_Create(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
2362 HandlerCF
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
2363 if (!This
) return E_OUTOFMEMORY
;
2364 This
->IClassFactory_iface
.lpVtbl
= &HandlerClassFactoryVtbl
;
2366 This
->clsid
= *rclsid
;
2368 hr
= IClassFactory_QueryInterface(&This
->IClassFactory_iface
, riid
, ppv
);
2370 HeapFree(GetProcessHeap(), 0, This
);