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.
48 #define WIN32_NO_STATUS
59 //#include "winuser.h"
60 //#include "winerror.h"
63 #include "compobj_private.h"
64 #include "storage32.h"
66 #include <wine/unicode.h>
67 #include <wine/debug.h>
69 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
73 storage_state_uninitialised
,
74 storage_state_initialised
,
80 object_state_not_running
,
84 /****************************************************************************
90 IOleObject IOleObject_iface
;
91 IUnknown IUnknown_iface
;
92 IDataObject IDataObject_iface
;
93 IRunnableObject IRunnableObject_iface
;
94 IAdviseSink IAdviseSink_iface
;
95 IPersistStorage IPersistStorage_iface
;
97 /* Reference count of this object */
100 /* IUnknown implementation of the outer object. */
101 IUnknown
* outerUnknown
;
103 /* Class Id that this handler object represents. */
106 /* IUnknown implementation of the datacache. */
108 /* IPersistStorage implementation of the datacache. */
109 IPersistStorage
* dataCache_PersistStg
;
111 /* Client site for the embedded object. */
112 IOleClientSite
* clientSite
;
115 * The IOleAdviseHolder maintains the connections
116 * on behalf of the default handler.
118 IOleAdviseHolder
* oleAdviseHolder
;
121 * The IDataAdviseHolder maintains the data
122 * connections on behalf of the default handler.
124 IDataAdviseHolder
* dataAdviseHolder
;
126 /* Name of the container and object contained */
130 /* IOleObject delegate */
131 IOleObject
*pOleDelegate
;
132 /* IPersistStorage delegate */
133 IPersistStorage
*pPSDelegate
;
134 /* IDataObject delegate */
135 IDataObject
*pDataDelegate
;
136 enum object_state object_state
;
138 /* connection cookie for the advise on the delegate OLE object */
141 /* storage passed to Load or InitNew */
143 enum storage_state storage_state
;
145 /* optional class factory for object */
146 IClassFactory
*pCFObject
;
147 /* TRUE if acting as an inproc server instead of an inproc handler */
151 typedef struct DefaultHandler DefaultHandler
;
153 static inline DefaultHandler
*impl_from_IOleObject( IOleObject
*iface
)
155 return CONTAINING_RECORD(iface
, DefaultHandler
, IOleObject_iface
);
158 static inline DefaultHandler
*impl_from_IUnknown( IUnknown
*iface
)
160 return CONTAINING_RECORD(iface
, DefaultHandler
, IUnknown_iface
);
163 static inline DefaultHandler
*impl_from_IDataObject( IDataObject
*iface
)
165 return CONTAINING_RECORD(iface
, DefaultHandler
, IDataObject_iface
);
168 static inline DefaultHandler
*impl_from_IRunnableObject( IRunnableObject
*iface
)
170 return CONTAINING_RECORD(iface
, DefaultHandler
, IRunnableObject_iface
);
173 static inline DefaultHandler
*impl_from_IAdviseSink( IAdviseSink
*iface
)
175 return CONTAINING_RECORD(iface
, DefaultHandler
, IAdviseSink_iface
);
178 static inline DefaultHandler
*impl_from_IPersistStorage( IPersistStorage
*iface
)
180 return CONTAINING_RECORD(iface
, DefaultHandler
, IPersistStorage_iface
);
183 static void DefaultHandler_Destroy(DefaultHandler
* This
);
185 static inline BOOL
object_is_running(DefaultHandler
*This
)
187 return IRunnableObject_IsRunning(&This
->IRunnableObject_iface
);
190 /*********************************************************
191 * Method implementation for the non delegating IUnknown
192 * part of the DefaultHandler class.
195 /************************************************************************
196 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
198 * See Windows documentation for more details on IUnknown methods.
200 * This version of QueryInterface will not delegate its implementation
201 * to the outer unknown.
203 static HRESULT WINAPI
DefaultHandler_NDIUnknown_QueryInterface(
208 DefaultHandler
*This
= impl_from_IUnknown(iface
);
215 if (IsEqualIID(&IID_IUnknown
, riid
))
217 else if (IsEqualIID(&IID_IOleObject
, riid
))
218 *ppvObject
= &This
->IOleObject_iface
;
219 else if (IsEqualIID(&IID_IDataObject
, riid
))
220 *ppvObject
= &This
->IDataObject_iface
;
221 else if (IsEqualIID(&IID_IRunnableObject
, riid
))
222 *ppvObject
= &This
->IRunnableObject_iface
;
223 else if (IsEqualIID(&IID_IPersist
, riid
) ||
224 IsEqualIID(&IID_IPersistStorage
, riid
))
225 *ppvObject
= &This
->IPersistStorage_iface
;
226 else if (IsEqualIID(&IID_IViewObject
, riid
) ||
227 IsEqualIID(&IID_IViewObject2
, riid
) ||
228 IsEqualIID(&IID_IOleCache
, riid
) ||
229 IsEqualIID(&IID_IOleCache2
, riid
))
231 HRESULT hr
= IUnknown_QueryInterface(This
->dataCache
, riid
, ppvObject
);
232 if (FAILED(hr
)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid
));
235 else if (This
->inproc_server
&& This
->pOleDelegate
)
237 return IOleObject_QueryInterface(This
->pOleDelegate
, riid
, ppvObject
);
240 /* Check that we obtained an interface. */
241 if (*ppvObject
== NULL
)
243 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid
));
244 return E_NOINTERFACE
;
248 * Query Interface always increases the reference count by one when it is
251 IUnknown_AddRef((IUnknown
*)*ppvObject
);
256 /************************************************************************
257 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
259 * See Windows documentation for more details on IUnknown methods.
261 * This version of QueryInterface will not delegate its implementation
262 * to the outer unknown.
264 static ULONG WINAPI
DefaultHandler_NDIUnknown_AddRef(
267 DefaultHandler
*This
= impl_from_IUnknown(iface
);
268 return InterlockedIncrement(&This
->ref
);
271 /************************************************************************
272 * DefaultHandler_NDIUnknown_Release (IUnknown)
274 * See Windows documentation for more details on IUnknown methods.
276 * This version of QueryInterface will not delegate its implementation
277 * to the outer unknown.
279 static ULONG WINAPI
DefaultHandler_NDIUnknown_Release(
282 DefaultHandler
*This
= impl_from_IUnknown(iface
);
285 ref
= InterlockedDecrement(&This
->ref
);
287 if (!ref
) DefaultHandler_Destroy(This
);
292 /*********************************************************
293 * Methods implementation for the IOleObject part of
294 * the DefaultHandler class.
297 /************************************************************************
298 * DefaultHandler_QueryInterface (IUnknown)
300 * See Windows documentation for more details on IUnknown methods.
302 static HRESULT WINAPI
DefaultHandler_QueryInterface(
307 DefaultHandler
*This
= impl_from_IOleObject(iface
);
309 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
312 /************************************************************************
313 * DefaultHandler_AddRef (IUnknown)
315 * See Windows documentation for more details on IUnknown methods.
317 static ULONG WINAPI
DefaultHandler_AddRef(
320 DefaultHandler
*This
= impl_from_IOleObject(iface
);
322 return IUnknown_AddRef(This
->outerUnknown
);
325 /************************************************************************
326 * DefaultHandler_Release (IUnknown)
328 * See Windows documentation for more details on IUnknown methods.
330 static ULONG WINAPI
DefaultHandler_Release(
333 DefaultHandler
*This
= impl_from_IOleObject(iface
);
335 return IUnknown_Release(This
->outerUnknown
);
338 /************************************************************************
339 * DefaultHandler_SetClientSite (IOleObject)
341 * The default handler's implementation of this method only keeps the
342 * client site pointer for future reference.
344 * See Windows documentation for more details on IOleObject methods.
346 static HRESULT WINAPI
DefaultHandler_SetClientSite(
348 IOleClientSite
* pClientSite
)
350 DefaultHandler
*This
= impl_from_IOleObject(iface
);
353 TRACE("(%p, %p)\n", iface
, pClientSite
);
355 if (object_is_running(This
))
356 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, pClientSite
);
359 * Make sure we release the previous client site if there
362 if (This
->clientSite
)
363 IOleClientSite_Release(This
->clientSite
);
365 This
->clientSite
= pClientSite
;
367 if (This
->clientSite
)
368 IOleClientSite_AddRef(This
->clientSite
);
373 /************************************************************************
374 * DefaultHandler_GetClientSite (IOleObject)
376 * The default handler's implementation of this method returns the
377 * last pointer set in IOleObject_SetClientSite.
379 * See Windows documentation for more details on IOleObject methods.
381 static HRESULT WINAPI
DefaultHandler_GetClientSite(
383 IOleClientSite
** ppClientSite
)
385 DefaultHandler
*This
= impl_from_IOleObject(iface
);
390 *ppClientSite
= This
->clientSite
;
392 if (This
->clientSite
)
393 IOleClientSite_AddRef(This
->clientSite
);
398 /************************************************************************
399 * DefaultHandler_SetHostNames (IOleObject)
401 * The default handler's implementation of this method just stores
402 * the strings and returns S_OK.
404 * See Windows documentation for more details on IOleObject methods.
406 static HRESULT WINAPI
DefaultHandler_SetHostNames(
408 LPCOLESTR szContainerApp
,
409 LPCOLESTR szContainerObj
)
411 DefaultHandler
*This
= impl_from_IOleObject(iface
);
413 TRACE("(%p, %s, %s)\n",
415 debugstr_w(szContainerApp
),
416 debugstr_w(szContainerObj
));
418 if (object_is_running(This
))
419 IOleObject_SetHostNames(This
->pOleDelegate
, szContainerApp
, szContainerObj
);
421 /* Be sure to cleanup before re-assigning the strings. */
422 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
423 This
->containerApp
= NULL
;
424 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
425 This
->containerObj
= NULL
;
429 if ((This
->containerApp
= HeapAlloc( GetProcessHeap(), 0,
430 (lstrlenW(szContainerApp
) + 1) * sizeof(WCHAR
) )))
431 strcpyW( This
->containerApp
, szContainerApp
);
436 if ((This
->containerObj
= HeapAlloc( GetProcessHeap(), 0,
437 (lstrlenW(szContainerObj
) + 1) * sizeof(WCHAR
) )))
438 strcpyW( This
->containerObj
, szContainerObj
);
443 static void release_delegates(DefaultHandler
*This
)
445 if (This
->pDataDelegate
)
447 IDataObject_Release(This
->pDataDelegate
);
448 This
->pDataDelegate
= NULL
;
450 if (This
->pPSDelegate
)
452 IPersistStorage_Release(This
->pPSDelegate
);
453 This
->pPSDelegate
= NULL
;
455 if (This
->pOleDelegate
)
457 IOleObject_Release(This
->pOleDelegate
);
458 This
->pOleDelegate
= NULL
;
462 /* undoes the work done by DefaultHandler_Run */
463 static void DefaultHandler_Stop(DefaultHandler
*This
)
465 if (!object_is_running(This
))
468 IOleObject_Unadvise(This
->pOleDelegate
, This
->dwAdvConn
);
470 /* FIXME: call IOleCache_OnStop */
472 if (This
->dataAdviseHolder
)
473 DataAdviseHolder_OnDisconnect(This
->dataAdviseHolder
);
475 This
->object_state
= object_state_not_running
;
478 /************************************************************************
479 * DefaultHandler_Close (IOleObject)
481 * The default handler's implementation of this method is meaningless
482 * without a running server so it does nothing.
484 * See Windows documentation for more details on IOleObject methods.
486 static HRESULT WINAPI
DefaultHandler_Close(
490 DefaultHandler
*This
= impl_from_IOleObject(iface
);
493 TRACE("(%d)\n", dwSaveOption
);
495 if (!object_is_running(This
))
498 hr
= IOleObject_Close(This
->pOleDelegate
, dwSaveOption
);
500 DefaultHandler_Stop(This
);
501 release_delegates(This
);
506 /************************************************************************
507 * DefaultHandler_SetMoniker (IOleObject)
509 * The default handler's implementation of this method does nothing.
511 * See Windows documentation for more details on IOleObject methods.
513 static HRESULT WINAPI
DefaultHandler_SetMoniker(
515 DWORD dwWhichMoniker
,
518 DefaultHandler
*This
= impl_from_IOleObject(iface
);
520 TRACE("(%p, %d, %p)\n",
525 if (object_is_running(This
))
526 return IOleObject_SetMoniker(This
->pOleDelegate
, dwWhichMoniker
, pmk
);
531 /************************************************************************
532 * DefaultHandler_GetMoniker (IOleObject)
534 * Delegate this request to the client site if we have one.
536 * See Windows documentation for more details on IOleObject methods.
538 static HRESULT WINAPI
DefaultHandler_GetMoniker(
541 DWORD dwWhichMoniker
,
544 DefaultHandler
*This
= impl_from_IOleObject(iface
);
546 TRACE("(%p, %d, %d, %p)\n",
547 iface
, dwAssign
, dwWhichMoniker
, ppmk
);
549 if (object_is_running(This
))
550 return IOleObject_GetMoniker(This
->pOleDelegate
, dwAssign
, dwWhichMoniker
,
553 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
554 if (This
->clientSite
)
556 return IOleClientSite_GetMoniker(This
->clientSite
,
566 /************************************************************************
567 * DefaultHandler_InitFromData (IOleObject)
569 * This method is meaningless if the server is not running
571 * See Windows documentation for more details on IOleObject methods.
573 static HRESULT WINAPI
DefaultHandler_InitFromData(
575 IDataObject
* pDataObject
,
579 DefaultHandler
*This
= impl_from_IOleObject(iface
);
581 TRACE("(%p, %p, %d, %d)\n",
582 iface
, pDataObject
, fCreation
, dwReserved
);
584 if (object_is_running(This
))
585 return IOleObject_InitFromData(This
->pOleDelegate
, pDataObject
, fCreation
,
587 return OLE_E_NOTRUNNING
;
590 /************************************************************************
591 * DefaultHandler_GetClipboardData (IOleObject)
593 * This method is meaningless if the server is not running
595 * See Windows documentation for more details on IOleObject methods.
597 static HRESULT WINAPI
DefaultHandler_GetClipboardData(
600 IDataObject
** ppDataObject
)
602 DefaultHandler
*This
= impl_from_IOleObject(iface
);
604 TRACE("(%p, %d, %p)\n",
605 iface
, dwReserved
, ppDataObject
);
607 if (object_is_running(This
))
608 return IOleObject_GetClipboardData(This
->pOleDelegate
, dwReserved
,
611 return OLE_E_NOTRUNNING
;
614 static HRESULT WINAPI
DefaultHandler_DoVerb(
617 struct tagMSG
* lpmsg
,
618 IOleClientSite
* pActiveSite
,
623 DefaultHandler
*This
= impl_from_IOleObject(iface
);
624 IRunnableObject
*pRunnableObj
= &This
->IRunnableObject_iface
;
627 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb
, lpmsg
, pActiveSite
, lindex
, hwndParent
, wine_dbgstr_rect(lprcPosRect
));
629 hr
= IRunnableObject_Run(pRunnableObj
, NULL
);
630 if (FAILED(hr
)) return hr
;
632 return IOleObject_DoVerb(This
->pOleDelegate
, iVerb
, lpmsg
, pActiveSite
,
633 lindex
, hwndParent
, lprcPosRect
);
636 /************************************************************************
637 * DefaultHandler_EnumVerbs (IOleObject)
639 * The default handler implementation of this method simply delegates
642 * See Windows documentation for more details on IOleObject methods.
644 static HRESULT WINAPI
DefaultHandler_EnumVerbs(
646 IEnumOLEVERB
** ppEnumOleVerb
)
648 DefaultHandler
*This
= impl_from_IOleObject(iface
);
649 HRESULT hr
= OLE_S_USEREG
;
651 TRACE("(%p, %p)\n", iface
, ppEnumOleVerb
);
653 if (object_is_running(This
))
654 hr
= IOleObject_EnumVerbs(This
->pOleDelegate
, ppEnumOleVerb
);
656 if (hr
== OLE_S_USEREG
)
657 return OleRegEnumVerbs(&This
->clsid
, ppEnumOleVerb
);
662 static HRESULT WINAPI
DefaultHandler_Update(
665 DefaultHandler
*This
= impl_from_IOleObject(iface
);
666 TRACE("(%p)\n", iface
);
668 if (!object_is_running(This
))
670 FIXME("Should run object\n");
673 return IOleObject_Update(This
->pOleDelegate
);
676 /************************************************************************
677 * DefaultHandler_IsUpToDate (IOleObject)
679 * This method is meaningless if the server is not running
681 * See Windows documentation for more details on IOleObject methods.
683 static HRESULT WINAPI
DefaultHandler_IsUpToDate(
686 DefaultHandler
*This
= impl_from_IOleObject(iface
);
687 TRACE("(%p)\n", iface
);
689 if (object_is_running(This
))
690 return IOleObject_IsUpToDate(This
->pOleDelegate
);
692 return OLE_E_NOTRUNNING
;
695 /************************************************************************
696 * DefaultHandler_GetUserClassID (IOleObject)
698 * TODO: Map to a new class ID if emulation is active.
700 * See Windows documentation for more details on IOleObject methods.
702 static HRESULT WINAPI
DefaultHandler_GetUserClassID(
706 DefaultHandler
*This
= impl_from_IOleObject(iface
);
708 TRACE("(%p, %p)\n", iface
, pClsid
);
710 if (object_is_running(This
))
711 return IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
716 *pClsid
= This
->clsid
;
721 /************************************************************************
722 * DefaultHandler_GetUserType (IOleObject)
724 * The default handler implementation of this method simply delegates
725 * to OleRegGetUserType
727 * See Windows documentation for more details on IOleObject methods.
729 static HRESULT WINAPI
DefaultHandler_GetUserType(
732 LPOLESTR
* pszUserType
)
734 DefaultHandler
*This
= impl_from_IOleObject(iface
);
736 TRACE("(%p, %d, %p)\n", iface
, dwFormOfType
, pszUserType
);
737 if (object_is_running(This
))
738 return IOleObject_GetUserType(This
->pOleDelegate
, dwFormOfType
, pszUserType
);
740 return OleRegGetUserType(&This
->clsid
, dwFormOfType
, pszUserType
);
743 /************************************************************************
744 * DefaultHandler_SetExtent (IOleObject)
746 * This method is meaningless if the server is not running
748 * See Windows documentation for more details on IOleObject methods.
750 static HRESULT WINAPI
DefaultHandler_SetExtent(
755 DefaultHandler
*This
= impl_from_IOleObject(iface
);
757 TRACE("(%p, %x, (%d x %d))\n", iface
,
758 dwDrawAspect
, psizel
->cx
, psizel
->cy
);
760 if (object_is_running(This
))
761 return IOleObject_SetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
763 return OLE_E_NOTRUNNING
;
766 /************************************************************************
767 * DefaultHandler_GetExtent (IOleObject)
769 * The default handler's implementation of this method returns uses
770 * the cache to locate the aspect and extract the extent from it.
772 * See Windows documentation for more details on IOleObject methods.
774 static HRESULT WINAPI
DefaultHandler_GetExtent(
779 DVTARGETDEVICE
* targetDevice
;
780 IViewObject2
* cacheView
= NULL
;
783 DefaultHandler
*This
= impl_from_IOleObject(iface
);
785 TRACE("(%p, %x, %p)\n", iface
, dwDrawAspect
, psizel
);
787 if (object_is_running(This
))
788 return IOleObject_GetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
790 hres
= IUnknown_QueryInterface(This
->dataCache
, &IID_IViewObject2
, (void**)&cacheView
);
795 * Prepare the call to the cache's GetExtent method.
797 * Here we would build a valid DVTARGETDEVICE structure
798 * but, since we are calling into the data cache, we
799 * know its implementation and we'll skip this
800 * extra work until later.
804 hres
= IViewObject2_GetExtent(cacheView
,
810 IViewObject2_Release(cacheView
);
815 /************************************************************************
816 * DefaultHandler_Advise (IOleObject)
818 * The default handler's implementation of this method simply
819 * delegates to the OleAdviseHolder.
821 * See Windows documentation for more details on IOleObject methods.
823 static HRESULT WINAPI
DefaultHandler_Advise(
825 IAdviseSink
* pAdvSink
,
826 DWORD
* pdwConnection
)
829 DefaultHandler
*This
= impl_from_IOleObject(iface
);
831 TRACE("(%p, %p, %p)\n", iface
, pAdvSink
, pdwConnection
);
833 /* Make sure we have an advise holder before we start. */
834 if (!This
->oleAdviseHolder
)
835 hres
= CreateOleAdviseHolder(&This
->oleAdviseHolder
);
838 hres
= IOleAdviseHolder_Advise(This
->oleAdviseHolder
,
845 /************************************************************************
846 * DefaultHandler_Unadvise (IOleObject)
848 * The default handler's implementation of this method simply
849 * delegates to the OleAdviseHolder.
851 * See Windows documentation for more details on IOleObject methods.
853 static HRESULT WINAPI
DefaultHandler_Unadvise(
857 DefaultHandler
*This
= impl_from_IOleObject(iface
);
859 TRACE("(%p, %d)\n", iface
, dwConnection
);
862 * If we don't have an advise holder yet, it means we don't have
865 if (!This
->oleAdviseHolder
)
866 return OLE_E_NOCONNECTION
;
868 return IOleAdviseHolder_Unadvise(This
->oleAdviseHolder
,
872 /************************************************************************
873 * DefaultHandler_EnumAdvise (IOleObject)
875 * The default handler's implementation of this method simply
876 * delegates to the OleAdviseHolder.
878 * See Windows documentation for more details on IOleObject methods.
880 static HRESULT WINAPI
DefaultHandler_EnumAdvise(
882 IEnumSTATDATA
** ppenumAdvise
)
884 DefaultHandler
*This
= impl_from_IOleObject(iface
);
886 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
891 *ppenumAdvise
= NULL
;
893 if (!This
->oleAdviseHolder
)
896 return IOleAdviseHolder_EnumAdvise(This
->oleAdviseHolder
, ppenumAdvise
);
899 /************************************************************************
900 * DefaultHandler_GetMiscStatus (IOleObject)
902 * The default handler's implementation of this method simply delegates
903 * to OleRegGetMiscStatus.
905 * See Windows documentation for more details on IOleObject methods.
907 static HRESULT WINAPI
DefaultHandler_GetMiscStatus(
913 DefaultHandler
*This
= impl_from_IOleObject(iface
);
915 TRACE("(%p, %x, %p)\n", iface
, dwAspect
, pdwStatus
);
917 if (object_is_running(This
))
918 return IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
920 hres
= OleRegGetMiscStatus(&This
->clsid
, dwAspect
, pdwStatus
);
928 /************************************************************************
929 * DefaultHandler_SetColorScheme (IOleObject)
931 * This method is meaningless if the server is not running
933 * See Windows documentation for more details on IOleObject methods.
935 static HRESULT WINAPI
DefaultHandler_SetColorScheme(
937 struct tagLOGPALETTE
* pLogpal
)
939 DefaultHandler
*This
= impl_from_IOleObject(iface
);
941 TRACE("(%p, %p))\n", iface
, pLogpal
);
943 if (object_is_running(This
))
944 return IOleObject_SetColorScheme(This
->pOleDelegate
, pLogpal
);
946 return OLE_E_NOTRUNNING
;
949 /*********************************************************
950 * Methods implementation for the IDataObject part of
951 * the DefaultHandler class.
954 /************************************************************************
955 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
957 * See Windows documentation for more details on IUnknown methods.
959 static HRESULT WINAPI
DefaultHandler_IDataObject_QueryInterface(
964 DefaultHandler
*This
= impl_from_IDataObject(iface
);
966 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
969 /************************************************************************
970 * DefaultHandler_IDataObject_AddRef (IUnknown)
972 * See Windows documentation for more details on IUnknown methods.
974 static ULONG WINAPI
DefaultHandler_IDataObject_AddRef(
977 DefaultHandler
*This
= impl_from_IDataObject(iface
);
979 return IUnknown_AddRef(This
->outerUnknown
);
982 /************************************************************************
983 * DefaultHandler_IDataObject_Release (IUnknown)
985 * See Windows documentation for more details on IUnknown methods.
987 static ULONG WINAPI
DefaultHandler_IDataObject_Release(
990 DefaultHandler
*This
= impl_from_IDataObject(iface
);
992 return IUnknown_Release(This
->outerUnknown
);
995 /************************************************************************
996 * DefaultHandler_GetData
998 * Get Data from a source dataobject using format pformatetcIn->cfFormat
999 * See Windows documentation for more details on GetData.
1000 * Default handler's implementation of this method delegates to the cache.
1002 static HRESULT WINAPI
DefaultHandler_GetData(
1004 LPFORMATETC pformatetcIn
,
1007 IDataObject
* cacheDataObject
= NULL
;
1010 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1012 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pmedium
);
1014 hres
= IUnknown_QueryInterface(This
->dataCache
,
1016 (void**)&cacheDataObject
);
1019 return E_UNEXPECTED
;
1021 hres
= IDataObject_GetData(cacheDataObject
,
1025 IDataObject_Release(cacheDataObject
);
1027 if (FAILED(hres
) && This
->pDataDelegate
)
1028 hres
= IDataObject_GetData(This
->pDataDelegate
, pformatetcIn
, pmedium
);
1033 static HRESULT WINAPI
DefaultHandler_GetDataHere(
1035 LPFORMATETC pformatetc
,
1042 /************************************************************************
1043 * DefaultHandler_QueryGetData (IDataObject)
1045 * The default handler's implementation of this method delegates to
1048 * See Windows documentation for more details on IDataObject methods.
1050 static HRESULT WINAPI
DefaultHandler_QueryGetData(
1052 LPFORMATETC pformatetc
)
1054 IDataObject
* cacheDataObject
= NULL
;
1057 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1059 TRACE("(%p, %p)\n", iface
, pformatetc
);
1061 hres
= IUnknown_QueryInterface(This
->dataCache
,
1063 (void**)&cacheDataObject
);
1066 return E_UNEXPECTED
;
1068 hres
= IDataObject_QueryGetData(cacheDataObject
,
1071 IDataObject_Release(cacheDataObject
);
1073 if (FAILED(hres
) && This
->pDataDelegate
)
1074 hres
= IDataObject_QueryGetData(This
->pDataDelegate
, pformatetc
);
1079 /************************************************************************
1080 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1082 * This method is meaningless if the server is not running
1084 * See Windows documentation for more details on IDataObject methods.
1086 static HRESULT WINAPI
DefaultHandler_GetCanonicalFormatEtc(
1088 LPFORMATETC pformatetcIn
,
1089 LPFORMATETC pformatetcOut
)
1091 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1093 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pformatetcOut
);
1095 if (!This
->pDataDelegate
)
1096 return OLE_E_NOTRUNNING
;
1098 return IDataObject_GetCanonicalFormatEtc(This
->pDataDelegate
, pformatetcIn
, pformatetcOut
);
1101 /************************************************************************
1102 * DefaultHandler_SetData (IDataObject)
1104 * The default handler's implementation of this method delegates to
1107 * See Windows documentation for more details on IDataObject methods.
1109 static HRESULT WINAPI
DefaultHandler_SetData(
1111 LPFORMATETC pformatetc
,
1115 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1116 IDataObject
* cacheDataObject
= NULL
;
1119 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1121 hres
= IUnknown_QueryInterface(This
->dataCache
,
1123 (void**)&cacheDataObject
);
1126 return E_UNEXPECTED
;
1128 hres
= IDataObject_SetData(cacheDataObject
,
1133 IDataObject_Release(cacheDataObject
);
1138 /************************************************************************
1139 * DefaultHandler_EnumFormatEtc (IDataObject)
1141 * The default handler's implementation of This method simply delegates
1142 * to OleRegEnumFormatEtc.
1144 * See Windows documentation for more details on IDataObject methods.
1146 static HRESULT WINAPI
DefaultHandler_EnumFormatEtc(
1149 IEnumFORMATETC
** ppenumFormatEtc
)
1151 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1153 TRACE("(%p, %x, %p)\n", iface
, dwDirection
, ppenumFormatEtc
);
1155 return OleRegEnumFormatEtc(&This
->clsid
, dwDirection
, ppenumFormatEtc
);
1158 /************************************************************************
1159 * DefaultHandler_DAdvise (IDataObject)
1161 * The default handler's implementation of this method simply
1162 * delegates to the DataAdviseHolder.
1164 * See Windows documentation for more details on IDataObject methods.
1166 static HRESULT WINAPI
DefaultHandler_DAdvise(
1168 FORMATETC
* pformatetc
,
1170 IAdviseSink
* pAdvSink
,
1171 DWORD
* pdwConnection
)
1173 HRESULT hres
= S_OK
;
1174 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1176 TRACE("(%p, %p, %d, %p, %p)\n",
1177 iface
, pformatetc
, advf
, pAdvSink
, pdwConnection
);
1179 /* Make sure we have a data advise holder before we start. */
1180 if (!This
->dataAdviseHolder
)
1182 hres
= CreateDataAdviseHolder(&This
->dataAdviseHolder
);
1183 if (SUCCEEDED(hres
) && This
->pDataDelegate
)
1184 DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1187 if (SUCCEEDED(hres
))
1188 hres
= IDataAdviseHolder_Advise(This
->dataAdviseHolder
,
1198 /************************************************************************
1199 * DefaultHandler_DUnadvise (IDataObject)
1201 * The default handler's implementation of this method simply
1202 * delegates to the DataAdviseHolder.
1204 * See Windows documentation for more details on IDataObject methods.
1206 static HRESULT WINAPI
DefaultHandler_DUnadvise(
1210 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1212 TRACE("(%p, %d)\n", iface
, dwConnection
);
1215 * If we don't have a data advise holder yet, it means that
1216 * we don't have any connections..
1218 if (!This
->dataAdviseHolder
)
1219 return OLE_E_NOCONNECTION
;
1221 return IDataAdviseHolder_Unadvise(This
->dataAdviseHolder
,
1225 /************************************************************************
1226 * DefaultHandler_EnumDAdvise (IDataObject)
1228 * The default handler's implementation of this method simply
1229 * delegates to the DataAdviseHolder.
1231 * See Windows documentation for more details on IDataObject methods.
1233 static HRESULT WINAPI
DefaultHandler_EnumDAdvise(
1235 IEnumSTATDATA
** ppenumAdvise
)
1237 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1239 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
1244 *ppenumAdvise
= NULL
;
1246 /* If we have a data advise holder object, delegate. */
1247 if (This
->dataAdviseHolder
)
1248 return IDataAdviseHolder_EnumAdvise(This
->dataAdviseHolder
,
1254 /*********************************************************
1255 * Methods implementation for the IRunnableObject part
1256 * of the DefaultHandler class.
1259 /************************************************************************
1260 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1262 * See Windows documentation for more details on IUnknown methods.
1264 static HRESULT WINAPI
DefaultHandler_IRunnableObject_QueryInterface(
1265 IRunnableObject
* iface
,
1269 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1271 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1274 /************************************************************************
1275 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1277 * See Windows documentation for more details on IUnknown methods.
1279 static ULONG WINAPI
DefaultHandler_IRunnableObject_AddRef(
1280 IRunnableObject
* iface
)
1282 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1284 return IUnknown_AddRef(This
->outerUnknown
);
1287 /************************************************************************
1288 * DefaultHandler_IRunnableObject_Release (IUnknown)
1290 * See Windows documentation for more details on IUnknown methods.
1292 static ULONG WINAPI
DefaultHandler_IRunnableObject_Release(
1293 IRunnableObject
* iface
)
1295 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1297 return IUnknown_Release(This
->outerUnknown
);
1300 /************************************************************************
1301 * DefaultHandler_GetRunningClass (IRunnableObject)
1303 * See Windows documentation for more details on IRunnableObject methods.
1305 static HRESULT WINAPI
DefaultHandler_GetRunningClass(
1306 IRunnableObject
* iface
,
1313 static HRESULT WINAPI
DefaultHandler_Run(
1314 IRunnableObject
* iface
,
1317 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1320 FIXME("(%p): semi-stub\n", pbc
);
1322 /* already running? if so nothing to do */
1323 if (object_is_running(This
))
1326 release_delegates(This
);
1328 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_LOCAL_SERVER
| CLSCTX_REMOTE_SERVER
,
1329 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1333 This
->object_state
= object_state_running
;
1335 hr
= IOleObject_Advise(This
->pOleDelegate
, &This
->IAdviseSink_iface
, &This
->dwAdvConn
);
1337 if (SUCCEEDED(hr
) && This
->clientSite
)
1338 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, This
->clientSite
);
1342 IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
,
1343 (void **)&This
->pPSDelegate
);
1344 if (This
->pPSDelegate
)
1346 if(This
->storage_state
== storage_state_initialised
)
1347 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, This
->storage
);
1348 else if(This
->storage_state
== storage_state_loaded
)
1349 hr
= IPersistStorage_Load(This
->pPSDelegate
, This
->storage
);
1353 if (SUCCEEDED(hr
) && This
->containerApp
)
1354 hr
= IOleObject_SetHostNames(This
->pOleDelegate
, This
->containerApp
,
1355 This
->containerObj
);
1357 /* FIXME: do more stuff here:
1358 * - IOleObject_GetMiscStatus
1359 * - IOleObject_GetMoniker
1364 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
,
1365 (void **)&This
->pDataDelegate
);
1367 if (SUCCEEDED(hr
) && This
->dataAdviseHolder
)
1368 hr
= DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1372 DefaultHandler_Stop(This
);
1373 release_delegates(This
);
1379 /************************************************************************
1380 * DefaultHandler_IsRunning (IRunnableObject)
1382 * See Windows documentation for more details on IRunnableObject methods.
1384 static BOOL WINAPI
DefaultHandler_IsRunning(
1385 IRunnableObject
* iface
)
1387 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1391 if (This
->object_state
== object_state_running
)
1397 /************************************************************************
1398 * DefaultHandler_LockRunning (IRunnableObject)
1400 * See Windows documentation for more details on IRunnableObject methods.
1402 static HRESULT WINAPI
DefaultHandler_LockRunning(
1403 IRunnableObject
* iface
,
1405 BOOL fLastUnlockCloses
)
1411 /************************************************************************
1412 * DefaultHandler_SetContainedObject (IRunnableObject)
1414 * See Windows documentation for more details on IRunnableObject methods.
1416 static HRESULT WINAPI
DefaultHandler_SetContainedObject(
1417 IRunnableObject
* iface
,
1424 static HRESULT WINAPI
DefaultHandler_IAdviseSink_QueryInterface(
1429 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1430 IsEqualIID(riid
, &IID_IAdviseSink
))
1433 IAdviseSink_AddRef(iface
);
1437 return E_NOINTERFACE
;
1440 static ULONG WINAPI
DefaultHandler_IAdviseSink_AddRef(
1443 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1445 return IUnknown_AddRef(&This
->IUnknown_iface
);
1448 static ULONG WINAPI
DefaultHandler_IAdviseSink_Release(
1451 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1453 return IUnknown_Release(&This
->IUnknown_iface
);
1456 static void WINAPI
DefaultHandler_IAdviseSink_OnDataChange(
1458 FORMATETC
*pFormatetc
,
1464 static void WINAPI
DefaultHandler_IAdviseSink_OnViewChange(
1472 static void WINAPI
DefaultHandler_IAdviseSink_OnRename(
1476 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1478 TRACE("(%p)\n", pmk
);
1480 if (This
->oleAdviseHolder
)
1481 IOleAdviseHolder_SendOnRename(This
->oleAdviseHolder
, pmk
);
1484 static void WINAPI
DefaultHandler_IAdviseSink_OnSave(
1487 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1491 if (This
->oleAdviseHolder
)
1492 IOleAdviseHolder_SendOnSave(This
->oleAdviseHolder
);
1495 static void WINAPI
DefaultHandler_IAdviseSink_OnClose(
1498 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1502 if (This
->oleAdviseHolder
)
1503 IOleAdviseHolder_SendOnClose(This
->oleAdviseHolder
);
1505 DefaultHandler_Stop(This
);
1509 /************************************************************************
1510 * DefaultHandler_IPersistStorage_QueryInterface
1513 static HRESULT WINAPI
DefaultHandler_IPersistStorage_QueryInterface(
1514 IPersistStorage
* iface
,
1518 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1520 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1523 /************************************************************************
1524 * DefaultHandler_IPersistStorage_AddRef
1527 static ULONG WINAPI
DefaultHandler_IPersistStorage_AddRef(
1528 IPersistStorage
* iface
)
1530 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1532 return IUnknown_AddRef(This
->outerUnknown
);
1535 /************************************************************************
1536 * DefaultHandler_IPersistStorage_Release
1539 static ULONG WINAPI
DefaultHandler_IPersistStorage_Release(
1540 IPersistStorage
* iface
)
1542 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1544 return IUnknown_Release(This
->outerUnknown
);
1547 /************************************************************************
1548 * DefaultHandler_IPersistStorage_GetClassID
1551 static HRESULT WINAPI
DefaultHandler_IPersistStorage_GetClassID(
1552 IPersistStorage
* iface
,
1555 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1558 TRACE("(%p)->(%p)\n", iface
, clsid
);
1560 if(object_is_running(This
))
1561 hr
= IPersistStorage_GetClassID(This
->pPSDelegate
, clsid
);
1563 hr
= IPersistStorage_GetClassID(This
->dataCache_PersistStg
, clsid
);
1568 /************************************************************************
1569 * DefaultHandler_IPersistStorage_IsDirty
1572 static HRESULT WINAPI
DefaultHandler_IPersistStorage_IsDirty(
1573 IPersistStorage
* iface
)
1575 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1578 TRACE("(%p)\n", iface
);
1580 hr
= IPersistStorage_IsDirty(This
->dataCache_PersistStg
);
1581 if(hr
!= S_FALSE
) return hr
;
1583 if(object_is_running(This
))
1584 hr
= IPersistStorage_IsDirty(This
->pPSDelegate
);
1589 /***********************************************************************
1591 * The format of '\1Ole' stream is as follows:
1593 * DWORD Version == 0x02000001
1594 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1595 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1596 * supplied by the app that creates the data structure. May be
1597 * ignored on processing].
1599 * DWORD Reserved == 0
1600 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1601 * CLSID clsid - class id of object capable of processing the moniker
1602 * BYTE data[] - moniker data for a link
1605 static const WCHAR OleStream
[] = {1,'O','l','e',0};
1610 DWORD link_update_opt
;
1613 } ole_stream_header_t
;
1614 static const DWORD ole_stream_version
= 0x02000001;
1616 static HRESULT
load_ole_stream(DefaultHandler
*This
, IStorage
*storage
)
1621 hr
= IStorage_OpenStream(storage
, OleStream
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stream
);
1626 ole_stream_header_t header
;
1628 hr
= IStream_Read(stream
, &header
, sizeof(header
), &read
);
1629 if(hr
== S_OK
&& read
== sizeof(header
) && header
.version
== ole_stream_version
)
1631 if(header
.flags
& 1)
1633 /* FIXME: Read the moniker and deal with the link */
1634 FIXME("Linked objects are not supported yet\n");
1639 WARN("Incorrect OleStream header\n");
1640 hr
= DV_E_CLIPFORMAT
;
1642 IStream_Release(stream
);
1645 hr
= STORAGE_CreateOleStream(storage
, 0);
1650 /************************************************************************
1651 * DefaultHandler_IPersistStorage_InitNew
1654 static HRESULT WINAPI
DefaultHandler_IPersistStorage_InitNew(
1655 IPersistStorage
* iface
,
1658 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1661 TRACE("(%p)->(%p)\n", iface
, pStg
);
1662 hr
= STORAGE_CreateOleStream(pStg
, 0);
1663 if (hr
!= S_OK
) return hr
;
1665 hr
= IPersistStorage_InitNew(This
->dataCache_PersistStg
, pStg
);
1667 if(SUCCEEDED(hr
) && object_is_running(This
))
1668 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, pStg
);
1672 IStorage_AddRef(pStg
);
1673 This
->storage
= pStg
;
1674 This
->storage_state
= storage_state_initialised
;
1681 /************************************************************************
1682 * DefaultHandler_IPersistStorage_Load
1685 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Load(
1686 IPersistStorage
* iface
,
1689 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1692 TRACE("(%p)->(%p)\n", iface
, pStg
);
1694 hr
= load_ole_stream(This
, pStg
);
1697 hr
= IPersistStorage_Load(This
->dataCache_PersistStg
, pStg
);
1699 if(SUCCEEDED(hr
) && object_is_running(This
))
1700 hr
= IPersistStorage_Load(This
->pPSDelegate
, pStg
);
1704 IStorage_AddRef(pStg
);
1705 This
->storage
= pStg
;
1706 This
->storage_state
= storage_state_loaded
;
1712 /************************************************************************
1713 * DefaultHandler_IPersistStorage_Save
1716 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Save(
1717 IPersistStorage
* iface
,
1721 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1724 TRACE("(%p)->(%p, %d)\n", iface
, pStgSave
, fSameAsLoad
);
1726 hr
= IPersistStorage_Save(This
->dataCache_PersistStg
, pStgSave
, fSameAsLoad
);
1727 if(SUCCEEDED(hr
) && object_is_running(This
))
1728 hr
= IPersistStorage_Save(This
->pPSDelegate
, pStgSave
, fSameAsLoad
);
1734 /************************************************************************
1735 * DefaultHandler_IPersistStorage_SaveCompleted
1738 static HRESULT WINAPI
DefaultHandler_IPersistStorage_SaveCompleted(
1739 IPersistStorage
* iface
,
1742 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1745 TRACE("(%p)->(%p)\n", iface
, pStgNew
);
1747 hr
= IPersistStorage_SaveCompleted(This
->dataCache_PersistStg
, pStgNew
);
1749 if(SUCCEEDED(hr
) && object_is_running(This
))
1750 hr
= IPersistStorage_SaveCompleted(This
->pPSDelegate
, pStgNew
);
1754 IStorage_AddRef(pStgNew
);
1755 if(This
->storage
) IStorage_Release(This
->storage
);
1756 This
->storage
= pStgNew
;
1757 This
->storage_state
= storage_state_loaded
;
1764 /************************************************************************
1765 * DefaultHandler_IPersistStorage_HandsOffStorage
1768 static HRESULT WINAPI
DefaultHandler_IPersistStorage_HandsOffStorage(
1769 IPersistStorage
* iface
)
1771 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1774 TRACE("(%p)\n", iface
);
1776 hr
= IPersistStorage_HandsOffStorage(This
->dataCache_PersistStg
);
1778 if(SUCCEEDED(hr
) && object_is_running(This
))
1779 hr
= IPersistStorage_HandsOffStorage(This
->pPSDelegate
);
1781 if(This
->storage
) IStorage_Release(This
->storage
);
1782 This
->storage
= NULL
;
1783 This
->storage_state
= storage_state_uninitialised
;
1790 * Virtual function tables for the DefaultHandler class.
1792 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable
=
1794 DefaultHandler_QueryInterface
,
1795 DefaultHandler_AddRef
,
1796 DefaultHandler_Release
,
1797 DefaultHandler_SetClientSite
,
1798 DefaultHandler_GetClientSite
,
1799 DefaultHandler_SetHostNames
,
1800 DefaultHandler_Close
,
1801 DefaultHandler_SetMoniker
,
1802 DefaultHandler_GetMoniker
,
1803 DefaultHandler_InitFromData
,
1804 DefaultHandler_GetClipboardData
,
1805 DefaultHandler_DoVerb
,
1806 DefaultHandler_EnumVerbs
,
1807 DefaultHandler_Update
,
1808 DefaultHandler_IsUpToDate
,
1809 DefaultHandler_GetUserClassID
,
1810 DefaultHandler_GetUserType
,
1811 DefaultHandler_SetExtent
,
1812 DefaultHandler_GetExtent
,
1813 DefaultHandler_Advise
,
1814 DefaultHandler_Unadvise
,
1815 DefaultHandler_EnumAdvise
,
1816 DefaultHandler_GetMiscStatus
,
1817 DefaultHandler_SetColorScheme
1820 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable
=
1822 DefaultHandler_NDIUnknown_QueryInterface
,
1823 DefaultHandler_NDIUnknown_AddRef
,
1824 DefaultHandler_NDIUnknown_Release
,
1827 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable
=
1829 DefaultHandler_IDataObject_QueryInterface
,
1830 DefaultHandler_IDataObject_AddRef
,
1831 DefaultHandler_IDataObject_Release
,
1832 DefaultHandler_GetData
,
1833 DefaultHandler_GetDataHere
,
1834 DefaultHandler_QueryGetData
,
1835 DefaultHandler_GetCanonicalFormatEtc
,
1836 DefaultHandler_SetData
,
1837 DefaultHandler_EnumFormatEtc
,
1838 DefaultHandler_DAdvise
,
1839 DefaultHandler_DUnadvise
,
1840 DefaultHandler_EnumDAdvise
1843 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable
=
1845 DefaultHandler_IRunnableObject_QueryInterface
,
1846 DefaultHandler_IRunnableObject_AddRef
,
1847 DefaultHandler_IRunnableObject_Release
,
1848 DefaultHandler_GetRunningClass
,
1850 DefaultHandler_IsRunning
,
1851 DefaultHandler_LockRunning
,
1852 DefaultHandler_SetContainedObject
1855 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable
=
1857 DefaultHandler_IAdviseSink_QueryInterface
,
1858 DefaultHandler_IAdviseSink_AddRef
,
1859 DefaultHandler_IAdviseSink_Release
,
1860 DefaultHandler_IAdviseSink_OnDataChange
,
1861 DefaultHandler_IAdviseSink_OnViewChange
,
1862 DefaultHandler_IAdviseSink_OnRename
,
1863 DefaultHandler_IAdviseSink_OnSave
,
1864 DefaultHandler_IAdviseSink_OnClose
1867 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable
=
1869 DefaultHandler_IPersistStorage_QueryInterface
,
1870 DefaultHandler_IPersistStorage_AddRef
,
1871 DefaultHandler_IPersistStorage_Release
,
1872 DefaultHandler_IPersistStorage_GetClassID
,
1873 DefaultHandler_IPersistStorage_IsDirty
,
1874 DefaultHandler_IPersistStorage_InitNew
,
1875 DefaultHandler_IPersistStorage_Load
,
1876 DefaultHandler_IPersistStorage_Save
,
1877 DefaultHandler_IPersistStorage_SaveCompleted
,
1878 DefaultHandler_IPersistStorage_HandsOffStorage
1881 /*********************************************************
1882 * Methods implementation for the DefaultHandler class.
1884 static DefaultHandler
* DefaultHandler_Construct(
1886 LPUNKNOWN pUnkOuter
,
1890 DefaultHandler
* This
= NULL
;
1893 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler
));
1898 This
->IOleObject_iface
.lpVtbl
= &DefaultHandler_IOleObject_VTable
;
1899 This
->IUnknown_iface
.lpVtbl
= &DefaultHandler_NDIUnknown_VTable
;
1900 This
->IDataObject_iface
.lpVtbl
= &DefaultHandler_IDataObject_VTable
;
1901 This
->IRunnableObject_iface
.lpVtbl
= &DefaultHandler_IRunnableObject_VTable
;
1902 This
->IAdviseSink_iface
.lpVtbl
= &DefaultHandler_IAdviseSink_VTable
;
1903 This
->IPersistStorage_iface
.lpVtbl
= &DefaultHandler_IPersistStorage_VTable
;
1905 This
->inproc_server
= (flags
& EMBDHLP_INPROC_SERVER
) != 0;
1908 * Start with one reference count. The caller of this function
1909 * must release the interface pointer when it is done.
1914 * Initialize the outer unknown
1915 * We don't keep a reference on the outer unknown since, the way
1916 * aggregation works, our lifetime is at least as large as its
1920 pUnkOuter
= &This
->IUnknown_iface
;
1922 This
->outerUnknown
= pUnkOuter
;
1925 * Create a datacache object.
1926 * We aggregate with the datacache. Make sure we pass our outer
1927 * unknown as the datacache's outer unknown.
1929 hr
= CreateDataCache(This
->outerUnknown
,
1932 (void**)&This
->dataCache
);
1935 hr
= IUnknown_QueryInterface(This
->dataCache
, &IID_IPersistStorage
, (void**)&This
->dataCache_PersistStg
);
1936 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
1937 * reference on the outer object */
1939 IUnknown_Release(This
->outerUnknown
);
1941 IUnknown_Release(This
->dataCache
);
1945 ERR("Unexpected error creating data cache\n");
1946 HeapFree(GetProcessHeap(), 0, This
);
1950 This
->clsid
= *clsid
;
1951 This
->clientSite
= NULL
;
1952 This
->oleAdviseHolder
= NULL
;
1953 This
->dataAdviseHolder
= NULL
;
1954 This
->containerApp
= NULL
;
1955 This
->containerObj
= NULL
;
1956 This
->pOleDelegate
= NULL
;
1957 This
->pPSDelegate
= NULL
;
1958 This
->pDataDelegate
= NULL
;
1959 This
->object_state
= object_state_not_running
;
1961 This
->dwAdvConn
= 0;
1962 This
->storage
= NULL
;
1963 This
->storage_state
= storage_state_uninitialised
;
1965 if (This
->inproc_server
&& !(flags
& EMBDHLP_DELAYCREATE
))
1968 This
->pCFObject
= NULL
;
1970 hr
= IClassFactory_CreateInstance(pCF
, NULL
, &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1972 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
1973 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1975 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
, (void **)&This
->pPSDelegate
);
1977 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
, (void **)&This
->pDataDelegate
);
1979 This
->object_state
= object_state_running
;
1981 WARN("object creation failed with error %08x\n", hr
);
1985 This
->pCFObject
= pCF
;
1986 if (pCF
) IClassFactory_AddRef(pCF
);
1992 static void DefaultHandler_Destroy(
1993 DefaultHandler
* This
)
1995 TRACE("(%p)\n", This
);
1997 /* AddRef/Release may be called on this object during destruction.
1998 * Prevent the object being destroyed recursively by artificially raising
1999 * the reference count. */
2002 /* release delegates */
2003 DefaultHandler_Stop(This
);
2004 release_delegates(This
);
2006 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
2007 This
->containerApp
= NULL
;
2008 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
2009 This
->containerObj
= NULL
;
2011 if (This
->dataCache
)
2013 /* to balance out the release of dataCache_PersistStg which will result
2014 * in a reference being released from the outer unknown */
2015 IUnknown_AddRef(This
->outerUnknown
);
2016 IPersistStorage_Release(This
->dataCache_PersistStg
);
2017 IUnknown_Release(This
->dataCache
);
2018 This
->dataCache_PersistStg
= NULL
;
2019 This
->dataCache
= NULL
;
2022 if (This
->clientSite
)
2024 IOleClientSite_Release(This
->clientSite
);
2025 This
->clientSite
= NULL
;
2028 if (This
->oleAdviseHolder
)
2030 IOleAdviseHolder_Release(This
->oleAdviseHolder
);
2031 This
->oleAdviseHolder
= NULL
;
2034 if (This
->dataAdviseHolder
)
2036 IDataAdviseHolder_Release(This
->dataAdviseHolder
);
2037 This
->dataAdviseHolder
= NULL
;
2042 IStorage_Release(This
->storage
);
2043 This
->storage
= NULL
;
2046 if (This
->pCFObject
)
2048 IClassFactory_Release(This
->pCFObject
);
2049 This
->pCFObject
= NULL
;
2052 HeapFree(GetProcessHeap(), 0, This
);
2055 /******************************************************************************
2056 * OleCreateEmbeddingHelper [OLE32.@]
2058 HRESULT WINAPI
OleCreateEmbeddingHelper(
2060 LPUNKNOWN pUnkOuter
,
2066 DefaultHandler
* newHandler
= NULL
;
2069 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
, flags
, pCF
, debugstr_guid(riid
), ppvObj
);
2077 * If This handler is constructed for aggregation, make sure
2078 * the caller is requesting the IUnknown interface.
2079 * This is necessary because it's the only time the non-delegating
2080 * IUnknown pointer can be returned to the outside.
2082 if (pUnkOuter
&& !IsEqualIID(&IID_IUnknown
, riid
))
2083 return CLASS_E_NOAGGREGATION
;
2086 * Try to construct a new instance of the class.
2088 newHandler
= DefaultHandler_Construct(clsid
, pUnkOuter
, flags
, pCF
);
2091 return E_OUTOFMEMORY
;
2094 * Make sure it supports the interface required by the caller.
2096 hr
= IUnknown_QueryInterface(&newHandler
->IUnknown_iface
, riid
, ppvObj
);
2099 * Release the reference obtained in the constructor. If
2100 * the QueryInterface was unsuccessful, it will free the class.
2102 IUnknown_Release(&newHandler
->IUnknown_iface
);
2108 /******************************************************************************
2109 * OleCreateDefaultHandler [OLE32.@]
2111 HRESULT WINAPI
OleCreateDefaultHandler(REFCLSID clsid
, LPUNKNOWN pUnkOuter
,
2112 REFIID riid
, LPVOID
* ppvObj
)
2114 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
,debugstr_guid(riid
), ppvObj
);
2115 return OleCreateEmbeddingHelper(clsid
, pUnkOuter
, EMBDHLP_INPROC_HANDLER
| EMBDHLP_CREATENOW
,
2116 NULL
, riid
, ppvObj
);
2119 typedef struct HandlerCF
2121 IClassFactory IClassFactory_iface
;
2126 static inline HandlerCF
*impl_from_IClassFactory(IClassFactory
*iface
)
2128 return CONTAINING_RECORD(iface
, HandlerCF
, IClassFactory_iface
);
2131 static HRESULT WINAPI
2132 HandlerCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
, LPVOID
*ppv
)
2135 if (IsEqualIID(riid
,&IID_IUnknown
) ||
2136 IsEqualIID(riid
,&IID_IClassFactory
))
2139 IClassFactory_AddRef(iface
);
2142 return E_NOINTERFACE
;
2145 static ULONG WINAPI
HandlerCF_AddRef(LPCLASSFACTORY iface
)
2147 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2148 return InterlockedIncrement(&This
->refs
);
2151 static ULONG WINAPI
HandlerCF_Release(LPCLASSFACTORY iface
)
2153 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2154 ULONG refs
= InterlockedDecrement(&This
->refs
);
2156 HeapFree(GetProcessHeap(), 0, This
);
2160 static HRESULT WINAPI
2161 HandlerCF_CreateInstance(LPCLASSFACTORY iface
, LPUNKNOWN pUnk
,
2162 REFIID riid
, LPVOID
*ppv
)
2164 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2165 return OleCreateDefaultHandler(&This
->clsid
, pUnk
, riid
, ppv
);
2168 static HRESULT WINAPI
HandlerCF_LockServer(LPCLASSFACTORY iface
, BOOL fLock
)
2170 FIXME("(%d), stub!\n",fLock
);
2174 static const IClassFactoryVtbl HandlerClassFactoryVtbl
= {
2175 HandlerCF_QueryInterface
,
2178 HandlerCF_CreateInstance
,
2179 HandlerCF_LockServer
2182 HRESULT
HandlerCF_Create(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
2185 HandlerCF
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
2186 if (!This
) return E_OUTOFMEMORY
;
2187 This
->IClassFactory_iface
.lpVtbl
= &HandlerClassFactoryVtbl
;
2189 This
->clsid
= *rclsid
;
2191 hr
= IUnknown_QueryInterface((IUnknown
*)&This
->IClassFactory_iface
, riid
, ppv
);
2193 HeapFree(GetProcessHeap(), 0, This
);