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
,
81 /****************************************************************************
87 IOleObject IOleObject_iface
;
88 IUnknown IUnknown_iface
;
89 IDataObject IDataObject_iface
;
90 IRunnableObject IRunnableObject_iface
;
91 IAdviseSink IAdviseSink_iface
;
92 IPersistStorage IPersistStorage_iface
;
94 /* Reference count of this object */
97 /* IUnknown implementation of the outer object. */
98 IUnknown
* outerUnknown
;
100 /* Class Id that this handler object represents. */
103 /* IUnknown implementation of the datacache. */
105 /* IPersistStorage implementation of the datacache. */
106 IPersistStorage
* dataCache_PersistStg
;
108 /* Client site for the embedded object. */
109 IOleClientSite
* clientSite
;
112 * The IOleAdviseHolder maintains the connections
113 * on behalf of the default handler.
115 IOleAdviseHolder
* oleAdviseHolder
;
118 * The IDataAdviseHolder maintains the data
119 * connections on behalf of the default handler.
121 IDataAdviseHolder
* dataAdviseHolder
;
123 /* Name of the container and object contained */
127 /* IOleObject delegate */
128 IOleObject
*pOleDelegate
;
129 /* IPersistStorage delegate */
130 IPersistStorage
*pPSDelegate
;
131 /* IDataObject delegate */
132 IDataObject
*pDataDelegate
;
133 enum object_state object_state
;
135 /* connection cookie for the advise on the delegate OLE object */
138 /* storage passed to Load or InitNew */
140 enum storage_state storage_state
;
142 /* optional class factory for object */
143 IClassFactory
*pCFObject
;
144 /* TRUE if acting as an inproc server instead of an inproc handler */
148 typedef struct DefaultHandler DefaultHandler
;
150 static inline DefaultHandler
*impl_from_IOleObject( IOleObject
*iface
)
152 return CONTAINING_RECORD(iface
, DefaultHandler
, IOleObject_iface
);
155 static inline DefaultHandler
*impl_from_IUnknown( IUnknown
*iface
)
157 return CONTAINING_RECORD(iface
, DefaultHandler
, IUnknown_iface
);
160 static inline DefaultHandler
*impl_from_IDataObject( IDataObject
*iface
)
162 return CONTAINING_RECORD(iface
, DefaultHandler
, IDataObject_iface
);
165 static inline DefaultHandler
*impl_from_IRunnableObject( IRunnableObject
*iface
)
167 return CONTAINING_RECORD(iface
, DefaultHandler
, IRunnableObject_iface
);
170 static inline DefaultHandler
*impl_from_IAdviseSink( IAdviseSink
*iface
)
172 return CONTAINING_RECORD(iface
, DefaultHandler
, IAdviseSink_iface
);
175 static inline DefaultHandler
*impl_from_IPersistStorage( IPersistStorage
*iface
)
177 return CONTAINING_RECORD(iface
, DefaultHandler
, IPersistStorage_iface
);
180 static void DefaultHandler_Destroy(DefaultHandler
* This
);
182 static inline BOOL
object_is_running(DefaultHandler
*This
)
184 return IRunnableObject_IsRunning(&This
->IRunnableObject_iface
);
187 /*********************************************************
188 * Method implementation for the non delegating IUnknown
189 * part of the DefaultHandler class.
192 /************************************************************************
193 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
195 * See Windows documentation for more details on IUnknown methods.
197 * This version of QueryInterface will not delegate its implementation
198 * to the outer unknown.
200 static HRESULT WINAPI
DefaultHandler_NDIUnknown_QueryInterface(
205 DefaultHandler
*This
= impl_from_IUnknown(iface
);
212 if (IsEqualIID(&IID_IUnknown
, riid
))
214 else if (IsEqualIID(&IID_IOleObject
, riid
))
215 *ppvObject
= &This
->IOleObject_iface
;
216 else if (IsEqualIID(&IID_IDataObject
, riid
))
217 *ppvObject
= &This
->IDataObject_iface
;
218 else if (IsEqualIID(&IID_IRunnableObject
, riid
))
219 *ppvObject
= &This
->IRunnableObject_iface
;
220 else if (IsEqualIID(&IID_IPersist
, riid
) ||
221 IsEqualIID(&IID_IPersistStorage
, riid
))
222 *ppvObject
= &This
->IPersistStorage_iface
;
223 else if (IsEqualIID(&IID_IViewObject
, riid
) ||
224 IsEqualIID(&IID_IViewObject2
, riid
) ||
225 IsEqualIID(&IID_IOleCache
, riid
) ||
226 IsEqualIID(&IID_IOleCache2
, riid
))
228 HRESULT hr
= IUnknown_QueryInterface(This
->dataCache
, riid
, ppvObject
);
229 if (FAILED(hr
)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid
));
232 else if (This
->inproc_server
&& This
->pOleDelegate
)
234 return IUnknown_QueryInterface(This
->pOleDelegate
, riid
, ppvObject
);
237 /* Check that we obtained an interface. */
238 if (*ppvObject
== NULL
)
240 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid
));
241 return E_NOINTERFACE
;
245 * Query Interface always increases the reference count by one when it is
248 IUnknown_AddRef((IUnknown
*)*ppvObject
);
253 /************************************************************************
254 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
256 * See Windows documentation for more details on IUnknown methods.
258 * This version of QueryInterface will not delegate its implementation
259 * to the outer unknown.
261 static ULONG WINAPI
DefaultHandler_NDIUnknown_AddRef(
264 DefaultHandler
*This
= impl_from_IUnknown(iface
);
265 return InterlockedIncrement(&This
->ref
);
268 /************************************************************************
269 * DefaultHandler_NDIUnknown_Release (IUnknown)
271 * See Windows documentation for more details on IUnknown methods.
273 * This version of QueryInterface will not delegate its implementation
274 * to the outer unknown.
276 static ULONG WINAPI
DefaultHandler_NDIUnknown_Release(
279 DefaultHandler
*This
= impl_from_IUnknown(iface
);
282 ref
= InterlockedDecrement(&This
->ref
);
284 if (!ref
) DefaultHandler_Destroy(This
);
289 /*********************************************************
290 * Methods implementation for the IOleObject part of
291 * the DefaultHandler class.
294 /************************************************************************
295 * DefaultHandler_QueryInterface (IUnknown)
297 * See Windows documentation for more details on IUnknown methods.
299 static HRESULT WINAPI
DefaultHandler_QueryInterface(
304 DefaultHandler
*This
= impl_from_IOleObject(iface
);
306 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
309 /************************************************************************
310 * DefaultHandler_AddRef (IUnknown)
312 * See Windows documentation for more details on IUnknown methods.
314 static ULONG WINAPI
DefaultHandler_AddRef(
317 DefaultHandler
*This
= impl_from_IOleObject(iface
);
319 return IUnknown_AddRef(This
->outerUnknown
);
322 /************************************************************************
323 * DefaultHandler_Release (IUnknown)
325 * See Windows documentation for more details on IUnknown methods.
327 static ULONG WINAPI
DefaultHandler_Release(
330 DefaultHandler
*This
= impl_from_IOleObject(iface
);
332 return IUnknown_Release(This
->outerUnknown
);
335 /************************************************************************
336 * DefaultHandler_SetClientSite (IOleObject)
338 * The default handler's implementation of this method only keeps the
339 * client site pointer for future reference.
341 * See Windows documentation for more details on IOleObject methods.
343 static HRESULT WINAPI
DefaultHandler_SetClientSite(
345 IOleClientSite
* pClientSite
)
347 DefaultHandler
*This
= impl_from_IOleObject(iface
);
350 TRACE("(%p, %p)\n", iface
, pClientSite
);
352 if (object_is_running(This
))
353 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, pClientSite
);
356 * Make sure we release the previous client site if there
359 if (This
->clientSite
)
360 IOleClientSite_Release(This
->clientSite
);
362 This
->clientSite
= pClientSite
;
364 if (This
->clientSite
)
365 IOleClientSite_AddRef(This
->clientSite
);
370 /************************************************************************
371 * DefaultHandler_GetClientSite (IOleObject)
373 * The default handler's implementation of this method returns the
374 * last pointer set in IOleObject_SetClientSite.
376 * See Windows documentation for more details on IOleObject methods.
378 static HRESULT WINAPI
DefaultHandler_GetClientSite(
380 IOleClientSite
** ppClientSite
)
382 DefaultHandler
*This
= impl_from_IOleObject(iface
);
387 *ppClientSite
= This
->clientSite
;
389 if (This
->clientSite
)
390 IOleClientSite_AddRef(This
->clientSite
);
395 /************************************************************************
396 * DefaultHandler_SetHostNames (IOleObject)
398 * The default handler's implementation of this method just stores
399 * the strings and returns S_OK.
401 * See Windows documentation for more details on IOleObject methods.
403 static HRESULT WINAPI
DefaultHandler_SetHostNames(
405 LPCOLESTR szContainerApp
,
406 LPCOLESTR szContainerObj
)
408 DefaultHandler
*This
= impl_from_IOleObject(iface
);
410 TRACE("(%p, %s, %s)\n",
412 debugstr_w(szContainerApp
),
413 debugstr_w(szContainerObj
));
415 if (object_is_running(This
))
416 IOleObject_SetHostNames(This
->pOleDelegate
, szContainerApp
, szContainerObj
);
418 /* Be sure to cleanup before re-assigning the strings. */
419 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
420 This
->containerApp
= NULL
;
421 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
422 This
->containerObj
= NULL
;
426 if ((This
->containerApp
= HeapAlloc( GetProcessHeap(), 0,
427 (lstrlenW(szContainerApp
) + 1) * sizeof(WCHAR
) )))
428 strcpyW( This
->containerApp
, szContainerApp
);
433 if ((This
->containerObj
= HeapAlloc( GetProcessHeap(), 0,
434 (lstrlenW(szContainerObj
) + 1) * sizeof(WCHAR
) )))
435 strcpyW( This
->containerObj
, szContainerObj
);
440 static void release_delegates(DefaultHandler
*This
)
442 if (This
->pDataDelegate
)
444 IDataObject_Release(This
->pDataDelegate
);
445 This
->pDataDelegate
= NULL
;
447 if (This
->pPSDelegate
)
449 IPersistStorage_Release(This
->pPSDelegate
);
450 This
->pPSDelegate
= NULL
;
452 if (This
->pOleDelegate
)
454 IOleObject_Release(This
->pOleDelegate
);
455 This
->pOleDelegate
= NULL
;
459 /* undoes the work done by DefaultHandler_Run */
460 static void DefaultHandler_Stop(DefaultHandler
*This
)
462 if (!object_is_running(This
))
465 IOleObject_Unadvise(This
->pOleDelegate
, This
->dwAdvConn
);
467 /* FIXME: call IOleCache_OnStop */
469 if (This
->dataAdviseHolder
)
470 DataAdviseHolder_OnDisconnect(This
->dataAdviseHolder
);
472 This
->object_state
= object_state_not_running
;
475 /************************************************************************
476 * DefaultHandler_Close (IOleObject)
478 * The default handler's implementation of this method is meaningless
479 * without a running server so it does nothing.
481 * See Windows documentation for more details on IOleObject methods.
483 static HRESULT WINAPI
DefaultHandler_Close(
487 DefaultHandler
*This
= impl_from_IOleObject(iface
);
490 TRACE("(%d)\n", dwSaveOption
);
492 if (!object_is_running(This
))
495 hr
= IOleObject_Close(This
->pOleDelegate
, dwSaveOption
);
497 DefaultHandler_Stop(This
);
498 release_delegates(This
);
503 /************************************************************************
504 * DefaultHandler_SetMoniker (IOleObject)
506 * The default handler's implementation of this method does nothing.
508 * See Windows documentation for more details on IOleObject methods.
510 static HRESULT WINAPI
DefaultHandler_SetMoniker(
512 DWORD dwWhichMoniker
,
515 DefaultHandler
*This
= impl_from_IOleObject(iface
);
517 TRACE("(%p, %d, %p)\n",
522 if (object_is_running(This
))
523 return IOleObject_SetMoniker(This
->pOleDelegate
, dwWhichMoniker
, pmk
);
528 /************************************************************************
529 * DefaultHandler_GetMoniker (IOleObject)
531 * Delegate this request to the client site if we have one.
533 * See Windows documentation for more details on IOleObject methods.
535 static HRESULT WINAPI
DefaultHandler_GetMoniker(
538 DWORD dwWhichMoniker
,
541 DefaultHandler
*This
= impl_from_IOleObject(iface
);
543 TRACE("(%p, %d, %d, %p)\n",
544 iface
, dwAssign
, dwWhichMoniker
, ppmk
);
546 if (object_is_running(This
))
547 return IOleObject_GetMoniker(This
->pOleDelegate
, dwAssign
, dwWhichMoniker
,
550 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
551 if (This
->clientSite
)
553 return IOleClientSite_GetMoniker(This
->clientSite
,
563 /************************************************************************
564 * DefaultHandler_InitFromData (IOleObject)
566 * This method is meaningless if the server is not running
568 * See Windows documentation for more details on IOleObject methods.
570 static HRESULT WINAPI
DefaultHandler_InitFromData(
572 IDataObject
* pDataObject
,
576 DefaultHandler
*This
= impl_from_IOleObject(iface
);
578 TRACE("(%p, %p, %d, %d)\n",
579 iface
, pDataObject
, fCreation
, dwReserved
);
581 if (object_is_running(This
))
582 return IOleObject_InitFromData(This
->pOleDelegate
, pDataObject
, fCreation
,
584 return OLE_E_NOTRUNNING
;
587 /************************************************************************
588 * DefaultHandler_GetClipboardData (IOleObject)
590 * This method is meaningless if the server is not running
592 * See Windows documentation for more details on IOleObject methods.
594 static HRESULT WINAPI
DefaultHandler_GetClipboardData(
597 IDataObject
** ppDataObject
)
599 DefaultHandler
*This
= impl_from_IOleObject(iface
);
601 TRACE("(%p, %d, %p)\n",
602 iface
, dwReserved
, ppDataObject
);
604 if (object_is_running(This
))
605 return IOleObject_GetClipboardData(This
->pOleDelegate
, dwReserved
,
608 return OLE_E_NOTRUNNING
;
611 static HRESULT WINAPI
DefaultHandler_DoVerb(
614 struct tagMSG
* lpmsg
,
615 IOleClientSite
* pActiveSite
,
620 DefaultHandler
*This
= impl_from_IOleObject(iface
);
621 IRunnableObject
*pRunnableObj
= &This
->IRunnableObject_iface
;
624 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb
, lpmsg
, pActiveSite
, lindex
, hwndParent
, wine_dbgstr_rect(lprcPosRect
));
626 hr
= IRunnableObject_Run(pRunnableObj
, NULL
);
627 if (FAILED(hr
)) return hr
;
629 return IOleObject_DoVerb(This
->pOleDelegate
, iVerb
, lpmsg
, pActiveSite
,
630 lindex
, hwndParent
, lprcPosRect
);
633 /************************************************************************
634 * DefaultHandler_EnumVerbs (IOleObject)
636 * The default handler implementation of this method simply delegates
639 * See Windows documentation for more details on IOleObject methods.
641 static HRESULT WINAPI
DefaultHandler_EnumVerbs(
643 IEnumOLEVERB
** ppEnumOleVerb
)
645 DefaultHandler
*This
= impl_from_IOleObject(iface
);
646 HRESULT hr
= OLE_S_USEREG
;
648 TRACE("(%p, %p)\n", iface
, ppEnumOleVerb
);
650 if (object_is_running(This
))
651 hr
= IOleObject_EnumVerbs(This
->pOleDelegate
, ppEnumOleVerb
);
653 if (hr
== OLE_S_USEREG
)
654 return OleRegEnumVerbs(&This
->clsid
, ppEnumOleVerb
);
659 static HRESULT WINAPI
DefaultHandler_Update(
662 DefaultHandler
*This
= impl_from_IOleObject(iface
);
663 TRACE("(%p)\n", iface
);
665 if (!object_is_running(This
))
667 FIXME("Should run object\n");
670 return IOleObject_Update(This
->pOleDelegate
);
673 /************************************************************************
674 * DefaultHandler_IsUpToDate (IOleObject)
676 * This method is meaningless if the server is not running
678 * See Windows documentation for more details on IOleObject methods.
680 static HRESULT WINAPI
DefaultHandler_IsUpToDate(
683 DefaultHandler
*This
= impl_from_IOleObject(iface
);
684 TRACE("(%p)\n", iface
);
686 if (object_is_running(This
))
687 return IOleObject_IsUpToDate(This
->pOleDelegate
);
689 return OLE_E_NOTRUNNING
;
692 /************************************************************************
693 * DefaultHandler_GetUserClassID (IOleObject)
695 * TODO: Map to a new class ID if emulation is active.
697 * See Windows documentation for more details on IOleObject methods.
699 static HRESULT WINAPI
DefaultHandler_GetUserClassID(
703 DefaultHandler
*This
= impl_from_IOleObject(iface
);
705 TRACE("(%p, %p)\n", iface
, pClsid
);
707 if (object_is_running(This
))
708 return IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
713 *pClsid
= This
->clsid
;
718 /************************************************************************
719 * DefaultHandler_GetUserType (IOleObject)
721 * The default handler implementation of this method simply delegates
722 * to OleRegGetUserType
724 * See Windows documentation for more details on IOleObject methods.
726 static HRESULT WINAPI
DefaultHandler_GetUserType(
729 LPOLESTR
* pszUserType
)
731 DefaultHandler
*This
= impl_from_IOleObject(iface
);
733 TRACE("(%p, %d, %p)\n", iface
, dwFormOfType
, pszUserType
);
734 if (object_is_running(This
))
735 return IOleObject_GetUserType(This
->pOleDelegate
, dwFormOfType
, pszUserType
);
737 return OleRegGetUserType(&This
->clsid
, dwFormOfType
, pszUserType
);
740 /************************************************************************
741 * DefaultHandler_SetExtent (IOleObject)
743 * This method is meaningless if the server is not running
745 * See Windows documentation for more details on IOleObject methods.
747 static HRESULT WINAPI
DefaultHandler_SetExtent(
752 DefaultHandler
*This
= impl_from_IOleObject(iface
);
754 TRACE("(%p, %x, (%d x %d))\n", iface
,
755 dwDrawAspect
, psizel
->cx
, psizel
->cy
);
757 if (object_is_running(This
))
758 return IOleObject_SetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
760 return OLE_E_NOTRUNNING
;
763 /************************************************************************
764 * DefaultHandler_GetExtent (IOleObject)
766 * The default handler's implementation of this method returns uses
767 * the cache to locate the aspect and extract the extent from it.
769 * See Windows documentation for more details on IOleObject methods.
771 static HRESULT WINAPI
DefaultHandler_GetExtent(
776 DVTARGETDEVICE
* targetDevice
;
777 IViewObject2
* cacheView
= NULL
;
780 DefaultHandler
*This
= impl_from_IOleObject(iface
);
782 TRACE("(%p, %x, %p)\n", iface
, dwDrawAspect
, psizel
);
784 if (object_is_running(This
))
785 return IOleObject_GetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
787 hres
= IUnknown_QueryInterface(This
->dataCache
, &IID_IViewObject2
, (void**)&cacheView
);
792 * Prepare the call to the cache's GetExtent method.
794 * Here we would build a valid DVTARGETDEVICE structure
795 * but, since we are calling into the data cache, we
796 * know its implementation and we'll skip this
797 * extra work until later.
801 hres
= IViewObject2_GetExtent(cacheView
,
807 IViewObject2_Release(cacheView
);
812 /************************************************************************
813 * DefaultHandler_Advise (IOleObject)
815 * The default handler's implementation of this method simply
816 * delegates to the OleAdviseHolder.
818 * See Windows documentation for more details on IOleObject methods.
820 static HRESULT WINAPI
DefaultHandler_Advise(
822 IAdviseSink
* pAdvSink
,
823 DWORD
* pdwConnection
)
826 DefaultHandler
*This
= impl_from_IOleObject(iface
);
828 TRACE("(%p, %p, %p)\n", iface
, pAdvSink
, pdwConnection
);
830 /* Make sure we have an advise holder before we start. */
831 if (!This
->oleAdviseHolder
)
832 hres
= CreateOleAdviseHolder(&This
->oleAdviseHolder
);
835 hres
= IOleAdviseHolder_Advise(This
->oleAdviseHolder
,
842 /************************************************************************
843 * DefaultHandler_Unadvise (IOleObject)
845 * The default handler's implementation of this method simply
846 * delegates to the OleAdviseHolder.
848 * See Windows documentation for more details on IOleObject methods.
850 static HRESULT WINAPI
DefaultHandler_Unadvise(
854 DefaultHandler
*This
= impl_from_IOleObject(iface
);
856 TRACE("(%p, %d)\n", iface
, dwConnection
);
859 * If we don't have an advise holder yet, it means we don't have
862 if (!This
->oleAdviseHolder
)
863 return OLE_E_NOCONNECTION
;
865 return IOleAdviseHolder_Unadvise(This
->oleAdviseHolder
,
869 /************************************************************************
870 * DefaultHandler_EnumAdvise (IOleObject)
872 * The default handler's implementation of this method simply
873 * delegates to the OleAdviseHolder.
875 * See Windows documentation for more details on IOleObject methods.
877 static HRESULT WINAPI
DefaultHandler_EnumAdvise(
879 IEnumSTATDATA
** ppenumAdvise
)
881 DefaultHandler
*This
= impl_from_IOleObject(iface
);
883 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
888 *ppenumAdvise
= NULL
;
890 if (!This
->oleAdviseHolder
)
893 return IOleAdviseHolder_EnumAdvise(This
->oleAdviseHolder
, ppenumAdvise
);
896 /************************************************************************
897 * DefaultHandler_GetMiscStatus (IOleObject)
899 * The default handler's implementation of this method simply delegates
900 * to OleRegGetMiscStatus.
902 * See Windows documentation for more details on IOleObject methods.
904 static HRESULT WINAPI
DefaultHandler_GetMiscStatus(
910 DefaultHandler
*This
= impl_from_IOleObject(iface
);
912 TRACE("(%p, %x, %p)\n", iface
, dwAspect
, pdwStatus
);
914 if (object_is_running(This
))
915 return IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
917 hres
= OleRegGetMiscStatus(&This
->clsid
, dwAspect
, pdwStatus
);
925 /************************************************************************
926 * DefaultHandler_SetColorScheme (IOleObject)
928 * This method is meaningless if the server is not running
930 * See Windows documentation for more details on IOleObject methods.
932 static HRESULT WINAPI
DefaultHandler_SetColorScheme(
934 struct tagLOGPALETTE
* pLogpal
)
936 DefaultHandler
*This
= impl_from_IOleObject(iface
);
938 TRACE("(%p, %p))\n", iface
, pLogpal
);
940 if (object_is_running(This
))
941 return IOleObject_SetColorScheme(This
->pOleDelegate
, pLogpal
);
943 return OLE_E_NOTRUNNING
;
946 /*********************************************************
947 * Methods implementation for the IDataObject part of
948 * the DefaultHandler class.
951 /************************************************************************
952 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
954 * See Windows documentation for more details on IUnknown methods.
956 static HRESULT WINAPI
DefaultHandler_IDataObject_QueryInterface(
961 DefaultHandler
*This
= impl_from_IDataObject(iface
);
963 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
966 /************************************************************************
967 * DefaultHandler_IDataObject_AddRef (IUnknown)
969 * See Windows documentation for more details on IUnknown methods.
971 static ULONG WINAPI
DefaultHandler_IDataObject_AddRef(
974 DefaultHandler
*This
= impl_from_IDataObject(iface
);
976 return IUnknown_AddRef(This
->outerUnknown
);
979 /************************************************************************
980 * DefaultHandler_IDataObject_Release (IUnknown)
982 * See Windows documentation for more details on IUnknown methods.
984 static ULONG WINAPI
DefaultHandler_IDataObject_Release(
987 DefaultHandler
*This
= impl_from_IDataObject(iface
);
989 return IUnknown_Release(This
->outerUnknown
);
992 /************************************************************************
993 * DefaultHandler_GetData
995 * Get Data from a source dataobject using format pformatetcIn->cfFormat
996 * See Windows documentation for more details on GetData.
997 * Default handler's implementation of this method delegates to the cache.
999 static HRESULT WINAPI
DefaultHandler_GetData(
1001 LPFORMATETC pformatetcIn
,
1004 IDataObject
* cacheDataObject
= NULL
;
1007 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1009 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pmedium
);
1011 hres
= IUnknown_QueryInterface(This
->dataCache
,
1013 (void**)&cacheDataObject
);
1016 return E_UNEXPECTED
;
1018 hres
= IDataObject_GetData(cacheDataObject
,
1022 IDataObject_Release(cacheDataObject
);
1024 if (FAILED(hres
) && This
->pDataDelegate
)
1025 hres
= IDataObject_GetData(This
->pDataDelegate
, pformatetcIn
, pmedium
);
1030 static HRESULT WINAPI
DefaultHandler_GetDataHere(
1032 LPFORMATETC pformatetc
,
1039 /************************************************************************
1040 * DefaultHandler_QueryGetData (IDataObject)
1042 * The default handler's implementation of this method delegates to
1045 * See Windows documentation for more details on IDataObject methods.
1047 static HRESULT WINAPI
DefaultHandler_QueryGetData(
1049 LPFORMATETC pformatetc
)
1051 IDataObject
* cacheDataObject
= NULL
;
1054 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1056 TRACE("(%p, %p)\n", iface
, pformatetc
);
1058 hres
= IUnknown_QueryInterface(This
->dataCache
,
1060 (void**)&cacheDataObject
);
1063 return E_UNEXPECTED
;
1065 hres
= IDataObject_QueryGetData(cacheDataObject
,
1068 IDataObject_Release(cacheDataObject
);
1070 if (FAILED(hres
) && This
->pDataDelegate
)
1071 hres
= IDataObject_QueryGetData(This
->pDataDelegate
, pformatetc
);
1076 /************************************************************************
1077 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1079 * This method is meaningless if the server is not running
1081 * See Windows documentation for more details on IDataObject methods.
1083 static HRESULT WINAPI
DefaultHandler_GetCanonicalFormatEtc(
1085 LPFORMATETC pformatetcIn
,
1086 LPFORMATETC pformatetcOut
)
1088 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1090 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pformatetcOut
);
1092 if (!This
->pDataDelegate
)
1093 return OLE_E_NOTRUNNING
;
1095 return IDataObject_GetCanonicalFormatEtc(This
->pDataDelegate
, pformatetcIn
, pformatetcOut
);
1098 /************************************************************************
1099 * DefaultHandler_SetData (IDataObject)
1101 * The default handler's implementation of this method delegates to
1104 * See Windows documentation for more details on IDataObject methods.
1106 static HRESULT WINAPI
DefaultHandler_SetData(
1108 LPFORMATETC pformatetc
,
1112 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1113 IDataObject
* cacheDataObject
= NULL
;
1116 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1118 hres
= IUnknown_QueryInterface(This
->dataCache
,
1120 (void**)&cacheDataObject
);
1123 return E_UNEXPECTED
;
1125 hres
= IDataObject_SetData(cacheDataObject
,
1130 IDataObject_Release(cacheDataObject
);
1135 /************************************************************************
1136 * DefaultHandler_EnumFormatEtc (IDataObject)
1138 * The default handler's implementation of This method simply delegates
1139 * to OleRegEnumFormatEtc.
1141 * See Windows documentation for more details on IDataObject methods.
1143 static HRESULT WINAPI
DefaultHandler_EnumFormatEtc(
1146 IEnumFORMATETC
** ppenumFormatEtc
)
1148 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1150 TRACE("(%p, %x, %p)\n", iface
, dwDirection
, ppenumFormatEtc
);
1152 return OleRegEnumFormatEtc(&This
->clsid
, dwDirection
, ppenumFormatEtc
);
1155 /************************************************************************
1156 * DefaultHandler_DAdvise (IDataObject)
1158 * The default handler's implementation of this method simply
1159 * delegates to the DataAdviseHolder.
1161 * See Windows documentation for more details on IDataObject methods.
1163 static HRESULT WINAPI
DefaultHandler_DAdvise(
1165 FORMATETC
* pformatetc
,
1167 IAdviseSink
* pAdvSink
,
1168 DWORD
* pdwConnection
)
1170 HRESULT hres
= S_OK
;
1171 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1173 TRACE("(%p, %p, %d, %p, %p)\n",
1174 iface
, pformatetc
, advf
, pAdvSink
, pdwConnection
);
1176 /* Make sure we have a data advise holder before we start. */
1177 if (!This
->dataAdviseHolder
)
1179 hres
= CreateDataAdviseHolder(&This
->dataAdviseHolder
);
1180 if (SUCCEEDED(hres
) && This
->pDataDelegate
)
1181 DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1184 if (SUCCEEDED(hres
))
1185 hres
= IDataAdviseHolder_Advise(This
->dataAdviseHolder
,
1195 /************************************************************************
1196 * DefaultHandler_DUnadvise (IDataObject)
1198 * The default handler's implementation of this method simply
1199 * delegates to the DataAdviseHolder.
1201 * See Windows documentation for more details on IDataObject methods.
1203 static HRESULT WINAPI
DefaultHandler_DUnadvise(
1207 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1209 TRACE("(%p, %d)\n", iface
, dwConnection
);
1212 * If we don't have a data advise holder yet, it means that
1213 * we don't have any connections..
1215 if (!This
->dataAdviseHolder
)
1216 return OLE_E_NOCONNECTION
;
1218 return IDataAdviseHolder_Unadvise(This
->dataAdviseHolder
,
1222 /************************************************************************
1223 * DefaultHandler_EnumDAdvise (IDataObject)
1225 * The default handler's implementation of this method simply
1226 * delegates to the DataAdviseHolder.
1228 * See Windows documentation for more details on IDataObject methods.
1230 static HRESULT WINAPI
DefaultHandler_EnumDAdvise(
1232 IEnumSTATDATA
** ppenumAdvise
)
1234 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1236 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
1241 *ppenumAdvise
= NULL
;
1243 /* If we have a data advise holder object, delegate. */
1244 if (This
->dataAdviseHolder
)
1245 return IDataAdviseHolder_EnumAdvise(This
->dataAdviseHolder
,
1251 /*********************************************************
1252 * Methods implementation for the IRunnableObject part
1253 * of the DefaultHandler class.
1256 /************************************************************************
1257 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1259 * See Windows documentation for more details on IUnknown methods.
1261 static HRESULT WINAPI
DefaultHandler_IRunnableObject_QueryInterface(
1262 IRunnableObject
* iface
,
1266 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1268 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1271 /************************************************************************
1272 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1274 * See Windows documentation for more details on IUnknown methods.
1276 static ULONG WINAPI
DefaultHandler_IRunnableObject_AddRef(
1277 IRunnableObject
* iface
)
1279 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1281 return IUnknown_AddRef(This
->outerUnknown
);
1284 /************************************************************************
1285 * DefaultHandler_IRunnableObject_Release (IUnknown)
1287 * See Windows documentation for more details on IUnknown methods.
1289 static ULONG WINAPI
DefaultHandler_IRunnableObject_Release(
1290 IRunnableObject
* iface
)
1292 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1294 return IUnknown_Release(This
->outerUnknown
);
1297 /************************************************************************
1298 * DefaultHandler_GetRunningClass (IRunnableObject)
1300 * See Windows documentation for more details on IRunnableObject methods.
1302 static HRESULT WINAPI
DefaultHandler_GetRunningClass(
1303 IRunnableObject
* iface
,
1310 static HRESULT WINAPI
DefaultHandler_Run(
1311 IRunnableObject
* iface
,
1314 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1317 FIXME("(%p): semi-stub\n", pbc
);
1319 /* already running? if so nothing to do */
1320 if (object_is_running(This
))
1323 release_delegates(This
);
1325 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_LOCAL_SERVER
,
1326 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1330 This
->object_state
= object_state_running
;
1332 hr
= IOleObject_Advise(This
->pOleDelegate
, &This
->IAdviseSink_iface
, &This
->dwAdvConn
);
1334 if (SUCCEEDED(hr
) && This
->clientSite
)
1335 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, This
->clientSite
);
1339 IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
,
1340 (void **)&This
->pPSDelegate
);
1341 if (This
->pPSDelegate
)
1343 if(This
->storage_state
== storage_state_initialised
)
1344 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, This
->storage
);
1345 else if(This
->storage_state
== storage_state_loaded
)
1346 hr
= IPersistStorage_Load(This
->pPSDelegate
, This
->storage
);
1350 if (SUCCEEDED(hr
) && This
->containerApp
)
1351 hr
= IOleObject_SetHostNames(This
->pOleDelegate
, This
->containerApp
,
1352 This
->containerObj
);
1354 /* FIXME: do more stuff here:
1355 * - IOleObject_GetMiscStatus
1356 * - IOleObject_GetMoniker
1361 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
,
1362 (void **)&This
->pDataDelegate
);
1364 if (SUCCEEDED(hr
) && This
->dataAdviseHolder
)
1365 hr
= DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1369 DefaultHandler_Stop(This
);
1370 release_delegates(This
);
1376 /************************************************************************
1377 * DefaultHandler_IsRunning (IRunnableObject)
1379 * See Windows documentation for more details on IRunnableObject methods.
1381 static BOOL WINAPI
DefaultHandler_IsRunning(
1382 IRunnableObject
* iface
)
1384 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1388 if (This
->object_state
== object_state_running
)
1394 /************************************************************************
1395 * DefaultHandler_LockRunning (IRunnableObject)
1397 * See Windows documentation for more details on IRunnableObject methods.
1399 static HRESULT WINAPI
DefaultHandler_LockRunning(
1400 IRunnableObject
* iface
,
1402 BOOL fLastUnlockCloses
)
1408 /************************************************************************
1409 * DefaultHandler_SetContainedObject (IRunnableObject)
1411 * See Windows documentation for more details on IRunnableObject methods.
1413 static HRESULT WINAPI
DefaultHandler_SetContainedObject(
1414 IRunnableObject
* iface
,
1421 static HRESULT WINAPI
DefaultHandler_IAdviseSink_QueryInterface(
1426 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1427 IsEqualIID(riid
, &IID_IAdviseSink
))
1430 IAdviseSink_AddRef(iface
);
1434 return E_NOINTERFACE
;
1437 static ULONG WINAPI
DefaultHandler_IAdviseSink_AddRef(
1440 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1442 return IUnknown_AddRef(&This
->IUnknown_iface
);
1445 static ULONG WINAPI
DefaultHandler_IAdviseSink_Release(
1448 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1450 return IUnknown_Release(&This
->IUnknown_iface
);
1453 static void WINAPI
DefaultHandler_IAdviseSink_OnDataChange(
1455 FORMATETC
*pFormatetc
,
1461 static void WINAPI
DefaultHandler_IAdviseSink_OnViewChange(
1469 static void WINAPI
DefaultHandler_IAdviseSink_OnRename(
1473 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1475 TRACE("(%p)\n", pmk
);
1477 if (This
->oleAdviseHolder
)
1478 IOleAdviseHolder_SendOnRename(This
->oleAdviseHolder
, pmk
);
1481 static void WINAPI
DefaultHandler_IAdviseSink_OnSave(
1484 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1488 if (This
->oleAdviseHolder
)
1489 IOleAdviseHolder_SendOnSave(This
->oleAdviseHolder
);
1492 static void WINAPI
DefaultHandler_IAdviseSink_OnClose(
1495 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1499 if (This
->oleAdviseHolder
)
1500 IOleAdviseHolder_SendOnClose(This
->oleAdviseHolder
);
1502 DefaultHandler_Stop(This
);
1506 /************************************************************************
1507 * DefaultHandler_IPersistStorage_QueryInterface
1510 static HRESULT WINAPI
DefaultHandler_IPersistStorage_QueryInterface(
1511 IPersistStorage
* iface
,
1515 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1517 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1520 /************************************************************************
1521 * DefaultHandler_IPersistStorage_AddRef
1524 static ULONG WINAPI
DefaultHandler_IPersistStorage_AddRef(
1525 IPersistStorage
* iface
)
1527 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1529 return IUnknown_AddRef(This
->outerUnknown
);
1532 /************************************************************************
1533 * DefaultHandler_IPersistStorage_Release
1536 static ULONG WINAPI
DefaultHandler_IPersistStorage_Release(
1537 IPersistStorage
* iface
)
1539 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1541 return IUnknown_Release(This
->outerUnknown
);
1544 /************************************************************************
1545 * DefaultHandler_IPersistStorage_GetClassID
1548 static HRESULT WINAPI
DefaultHandler_IPersistStorage_GetClassID(
1549 IPersistStorage
* iface
,
1552 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1555 TRACE("(%p)->(%p)\n", iface
, clsid
);
1557 if(object_is_running(This
))
1558 hr
= IPersistStorage_GetClassID(This
->pPSDelegate
, clsid
);
1560 hr
= IPersistStorage_GetClassID(This
->dataCache_PersistStg
, clsid
);
1565 /************************************************************************
1566 * DefaultHandler_IPersistStorage_IsDirty
1569 static HRESULT WINAPI
DefaultHandler_IPersistStorage_IsDirty(
1570 IPersistStorage
* iface
)
1572 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1575 TRACE("(%p)\n", iface
);
1577 hr
= IPersistStorage_IsDirty(This
->dataCache_PersistStg
);
1578 if(hr
!= S_FALSE
) return hr
;
1580 if(object_is_running(This
))
1581 hr
= IPersistStorage_IsDirty(This
->pPSDelegate
);
1586 /***********************************************************************
1588 * The format of '\1Ole' stream is as follows:
1590 * DWORD Version == 0x02000001
1591 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1592 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1593 * supplied by the app that creates the data structure. May be
1594 * ignored on processing].
1596 * DWORD Reserved == 0
1597 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1598 * CLSID clsid - class id of object capable of processing the moniker
1599 * BYTE data[] - moniker data for a link
1602 static const WCHAR OleStream
[] = {1,'O','l','e',0};
1607 DWORD link_update_opt
;
1610 } ole_stream_header_t
;
1611 static const DWORD ole_stream_version
= 0x02000001;
1613 static HRESULT
load_ole_stream(DefaultHandler
*This
, IStorage
*storage
)
1618 hr
= IStorage_OpenStream(storage
, OleStream
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stream
);
1623 ole_stream_header_t header
;
1625 hr
= IStream_Read(stream
, &header
, sizeof(header
), &read
);
1626 if(hr
== S_OK
&& read
== sizeof(header
) && header
.version
== ole_stream_version
)
1628 if(header
.flags
& 1)
1630 /* FIXME: Read the moniker and deal with the link */
1631 FIXME("Linked objects are not supported yet\n");
1636 WARN("Incorrect OleStream header\n");
1637 hr
= DV_E_CLIPFORMAT
;
1639 IStream_Release(stream
);
1642 hr
= STORAGE_CreateOleStream(storage
, 0);
1647 /************************************************************************
1648 * DefaultHandler_IPersistStorage_InitNew
1651 static HRESULT WINAPI
DefaultHandler_IPersistStorage_InitNew(
1652 IPersistStorage
* iface
,
1655 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1658 TRACE("(%p)->(%p)\n", iface
, pStg
);
1659 hr
= STORAGE_CreateOleStream(pStg
, 0);
1660 if (hr
!= S_OK
) return hr
;
1662 hr
= IPersistStorage_InitNew(This
->dataCache_PersistStg
, pStg
);
1664 if(SUCCEEDED(hr
) && object_is_running(This
))
1665 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, pStg
);
1669 IStorage_AddRef(pStg
);
1670 This
->storage
= pStg
;
1671 This
->storage_state
= storage_state_initialised
;
1678 /************************************************************************
1679 * DefaultHandler_IPersistStorage_Load
1682 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Load(
1683 IPersistStorage
* iface
,
1686 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1689 TRACE("(%p)->(%p)\n", iface
, pStg
);
1691 hr
= load_ole_stream(This
, pStg
);
1694 hr
= IPersistStorage_Load(This
->dataCache_PersistStg
, pStg
);
1696 if(SUCCEEDED(hr
) && object_is_running(This
))
1697 hr
= IPersistStorage_Load(This
->pPSDelegate
, pStg
);
1701 IStorage_AddRef(pStg
);
1702 This
->storage
= pStg
;
1703 This
->storage_state
= storage_state_loaded
;
1709 /************************************************************************
1710 * DefaultHandler_IPersistStorage_Save
1713 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Save(
1714 IPersistStorage
* iface
,
1718 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1721 TRACE("(%p)->(%p, %d)\n", iface
, pStgSave
, fSameAsLoad
);
1723 hr
= IPersistStorage_Save(This
->dataCache_PersistStg
, pStgSave
, fSameAsLoad
);
1724 if(SUCCEEDED(hr
) && object_is_running(This
))
1725 hr
= IPersistStorage_Save(This
->pPSDelegate
, pStgSave
, fSameAsLoad
);
1731 /************************************************************************
1732 * DefaultHandler_IPersistStorage_SaveCompleted
1735 static HRESULT WINAPI
DefaultHandler_IPersistStorage_SaveCompleted(
1736 IPersistStorage
* iface
,
1739 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1742 TRACE("(%p)->(%p)\n", iface
, pStgNew
);
1744 hr
= IPersistStorage_SaveCompleted(This
->dataCache_PersistStg
, pStgNew
);
1746 if(SUCCEEDED(hr
) && object_is_running(This
))
1747 hr
= IPersistStorage_SaveCompleted(This
->pPSDelegate
, pStgNew
);
1751 IStorage_AddRef(pStgNew
);
1752 if(This
->storage
) IStorage_Release(This
->storage
);
1753 This
->storage
= pStgNew
;
1754 This
->storage_state
= storage_state_loaded
;
1761 /************************************************************************
1762 * DefaultHandler_IPersistStorage_HandsOffStorage
1765 static HRESULT WINAPI
DefaultHandler_IPersistStorage_HandsOffStorage(
1766 IPersistStorage
* iface
)
1768 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1771 TRACE("(%p)\n", iface
);
1773 hr
= IPersistStorage_HandsOffStorage(This
->dataCache_PersistStg
);
1775 if(SUCCEEDED(hr
) && object_is_running(This
))
1776 hr
= IPersistStorage_HandsOffStorage(This
->pPSDelegate
);
1778 if(This
->storage
) IStorage_Release(This
->storage
);
1779 This
->storage
= NULL
;
1780 This
->storage_state
= storage_state_uninitialised
;
1787 * Virtual function tables for the DefaultHandler class.
1789 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable
=
1791 DefaultHandler_QueryInterface
,
1792 DefaultHandler_AddRef
,
1793 DefaultHandler_Release
,
1794 DefaultHandler_SetClientSite
,
1795 DefaultHandler_GetClientSite
,
1796 DefaultHandler_SetHostNames
,
1797 DefaultHandler_Close
,
1798 DefaultHandler_SetMoniker
,
1799 DefaultHandler_GetMoniker
,
1800 DefaultHandler_InitFromData
,
1801 DefaultHandler_GetClipboardData
,
1802 DefaultHandler_DoVerb
,
1803 DefaultHandler_EnumVerbs
,
1804 DefaultHandler_Update
,
1805 DefaultHandler_IsUpToDate
,
1806 DefaultHandler_GetUserClassID
,
1807 DefaultHandler_GetUserType
,
1808 DefaultHandler_SetExtent
,
1809 DefaultHandler_GetExtent
,
1810 DefaultHandler_Advise
,
1811 DefaultHandler_Unadvise
,
1812 DefaultHandler_EnumAdvise
,
1813 DefaultHandler_GetMiscStatus
,
1814 DefaultHandler_SetColorScheme
1817 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable
=
1819 DefaultHandler_NDIUnknown_QueryInterface
,
1820 DefaultHandler_NDIUnknown_AddRef
,
1821 DefaultHandler_NDIUnknown_Release
,
1824 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable
=
1826 DefaultHandler_IDataObject_QueryInterface
,
1827 DefaultHandler_IDataObject_AddRef
,
1828 DefaultHandler_IDataObject_Release
,
1829 DefaultHandler_GetData
,
1830 DefaultHandler_GetDataHere
,
1831 DefaultHandler_QueryGetData
,
1832 DefaultHandler_GetCanonicalFormatEtc
,
1833 DefaultHandler_SetData
,
1834 DefaultHandler_EnumFormatEtc
,
1835 DefaultHandler_DAdvise
,
1836 DefaultHandler_DUnadvise
,
1837 DefaultHandler_EnumDAdvise
1840 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable
=
1842 DefaultHandler_IRunnableObject_QueryInterface
,
1843 DefaultHandler_IRunnableObject_AddRef
,
1844 DefaultHandler_IRunnableObject_Release
,
1845 DefaultHandler_GetRunningClass
,
1847 DefaultHandler_IsRunning
,
1848 DefaultHandler_LockRunning
,
1849 DefaultHandler_SetContainedObject
1852 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable
=
1854 DefaultHandler_IAdviseSink_QueryInterface
,
1855 DefaultHandler_IAdviseSink_AddRef
,
1856 DefaultHandler_IAdviseSink_Release
,
1857 DefaultHandler_IAdviseSink_OnDataChange
,
1858 DefaultHandler_IAdviseSink_OnViewChange
,
1859 DefaultHandler_IAdviseSink_OnRename
,
1860 DefaultHandler_IAdviseSink_OnSave
,
1861 DefaultHandler_IAdviseSink_OnClose
1864 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable
=
1866 DefaultHandler_IPersistStorage_QueryInterface
,
1867 DefaultHandler_IPersistStorage_AddRef
,
1868 DefaultHandler_IPersistStorage_Release
,
1869 DefaultHandler_IPersistStorage_GetClassID
,
1870 DefaultHandler_IPersistStorage_IsDirty
,
1871 DefaultHandler_IPersistStorage_InitNew
,
1872 DefaultHandler_IPersistStorage_Load
,
1873 DefaultHandler_IPersistStorage_Save
,
1874 DefaultHandler_IPersistStorage_SaveCompleted
,
1875 DefaultHandler_IPersistStorage_HandsOffStorage
1878 /*********************************************************
1879 * Methods implementation for the DefaultHandler class.
1881 static DefaultHandler
* DefaultHandler_Construct(
1883 LPUNKNOWN pUnkOuter
,
1887 DefaultHandler
* This
= NULL
;
1890 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler
));
1895 This
->IOleObject_iface
.lpVtbl
= &DefaultHandler_IOleObject_VTable
;
1896 This
->IUnknown_iface
.lpVtbl
= &DefaultHandler_NDIUnknown_VTable
;
1897 This
->IDataObject_iface
.lpVtbl
= &DefaultHandler_IDataObject_VTable
;
1898 This
->IRunnableObject_iface
.lpVtbl
= &DefaultHandler_IRunnableObject_VTable
;
1899 This
->IAdviseSink_iface
.lpVtbl
= &DefaultHandler_IAdviseSink_VTable
;
1900 This
->IPersistStorage_iface
.lpVtbl
= &DefaultHandler_IPersistStorage_VTable
;
1902 This
->inproc_server
= (flags
& EMBDHLP_INPROC_SERVER
) ? TRUE
: FALSE
;
1905 * Start with one reference count. The caller of this function
1906 * must release the interface pointer when it is done.
1911 * Initialize the outer unknown
1912 * We don't keep a reference on the outer unknown since, the way
1913 * aggregation works, our lifetime is at least as large as its
1917 pUnkOuter
= &This
->IUnknown_iface
;
1919 This
->outerUnknown
= pUnkOuter
;
1922 * Create a datacache object.
1923 * We aggregate with the datacache. Make sure we pass our outer
1924 * unknown as the datacache's outer unknown.
1926 hr
= CreateDataCache(This
->outerUnknown
,
1929 (void**)&This
->dataCache
);
1932 hr
= IUnknown_QueryInterface(This
->dataCache
, &IID_IPersistStorage
, (void**)&This
->dataCache_PersistStg
);
1933 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
1934 * reference on the outer object */
1936 IUnknown_Release(This
->outerUnknown
);
1938 IUnknown_Release(This
->dataCache
);
1942 ERR("Unexpected error creating data cache\n");
1943 HeapFree(GetProcessHeap(), 0, This
);
1947 This
->clsid
= *clsid
;
1948 This
->clientSite
= NULL
;
1949 This
->oleAdviseHolder
= NULL
;
1950 This
->dataAdviseHolder
= NULL
;
1951 This
->containerApp
= NULL
;
1952 This
->containerObj
= NULL
;
1953 This
->pOleDelegate
= NULL
;
1954 This
->pPSDelegate
= NULL
;
1955 This
->pDataDelegate
= NULL
;
1956 This
->object_state
= object_state_not_running
;
1958 This
->dwAdvConn
= 0;
1959 This
->storage
= NULL
;
1960 This
->storage_state
= storage_state_uninitialised
;
1962 if (This
->inproc_server
&& !(flags
& EMBDHLP_DELAYCREATE
))
1965 This
->pCFObject
= NULL
;
1967 hr
= IClassFactory_CreateInstance(pCF
, NULL
, &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1969 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
1970 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1972 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
, (void **)&This
->pPSDelegate
);
1974 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
, (void **)&This
->pDataDelegate
);
1976 This
->object_state
= object_state_running
;
1978 WARN("object creation failed with error %08x\n", hr
);
1982 This
->pCFObject
= pCF
;
1983 if (pCF
) IClassFactory_AddRef(pCF
);
1989 static void DefaultHandler_Destroy(
1990 DefaultHandler
* This
)
1992 TRACE("(%p)\n", This
);
1994 /* AddRef/Release may be called on this object during destruction.
1995 * Prevent the object being destroyed recursively by artificially raising
1996 * the reference count. */
1999 /* release delegates */
2000 DefaultHandler_Stop(This
);
2001 release_delegates(This
);
2003 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
2004 This
->containerApp
= NULL
;
2005 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
2006 This
->containerObj
= NULL
;
2008 if (This
->dataCache
)
2010 /* to balance out the release of dataCache_PersistStg which will result
2011 * in a reference being released from the outer unknown */
2012 IUnknown_AddRef(This
->outerUnknown
);
2013 IPersistStorage_Release(This
->dataCache_PersistStg
);
2014 IUnknown_Release(This
->dataCache
);
2015 This
->dataCache_PersistStg
= NULL
;
2016 This
->dataCache
= NULL
;
2019 if (This
->clientSite
)
2021 IOleClientSite_Release(This
->clientSite
);
2022 This
->clientSite
= NULL
;
2025 if (This
->oleAdviseHolder
)
2027 IOleAdviseHolder_Release(This
->oleAdviseHolder
);
2028 This
->oleAdviseHolder
= NULL
;
2031 if (This
->dataAdviseHolder
)
2033 IDataAdviseHolder_Release(This
->dataAdviseHolder
);
2034 This
->dataAdviseHolder
= NULL
;
2039 IStorage_Release(This
->storage
);
2040 This
->storage
= NULL
;
2043 if (This
->pCFObject
)
2045 IClassFactory_Release(This
->pCFObject
);
2046 This
->pCFObject
= NULL
;
2049 HeapFree(GetProcessHeap(), 0, This
);
2052 /******************************************************************************
2053 * OleCreateEmbeddingHelper [OLE32.@]
2055 HRESULT WINAPI
OleCreateEmbeddingHelper(
2057 LPUNKNOWN pUnkOuter
,
2063 DefaultHandler
* newHandler
= NULL
;
2066 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
, flags
, pCF
, debugstr_guid(riid
), ppvObj
);
2074 * If This handler is constructed for aggregation, make sure
2075 * the caller is requesting the IUnknown interface.
2076 * This is necessary because it's the only time the non-delegating
2077 * IUnknown pointer can be returned to the outside.
2079 if (pUnkOuter
&& !IsEqualIID(&IID_IUnknown
, riid
))
2080 return CLASS_E_NOAGGREGATION
;
2083 * Try to construct a new instance of the class.
2085 newHandler
= DefaultHandler_Construct(clsid
, pUnkOuter
, flags
, pCF
);
2088 return E_OUTOFMEMORY
;
2091 * Make sure it supports the interface required by the caller.
2093 hr
= IUnknown_QueryInterface(&newHandler
->IUnknown_iface
, riid
, ppvObj
);
2096 * Release the reference obtained in the constructor. If
2097 * the QueryInterface was unsuccessful, it will free the class.
2099 IUnknown_Release(&newHandler
->IUnknown_iface
);
2105 /******************************************************************************
2106 * OleCreateDefaultHandler [OLE32.@]
2108 HRESULT WINAPI
OleCreateDefaultHandler(REFCLSID clsid
, LPUNKNOWN pUnkOuter
,
2109 REFIID riid
, LPVOID
* ppvObj
)
2111 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
,debugstr_guid(riid
), ppvObj
);
2112 return OleCreateEmbeddingHelper(clsid
, pUnkOuter
, EMBDHLP_INPROC_HANDLER
| EMBDHLP_CREATENOW
,
2113 NULL
, riid
, ppvObj
);
2116 typedef struct HandlerCF
2118 IClassFactory IClassFactory_iface
;
2123 static inline HandlerCF
*impl_from_IClassFactory(IClassFactory
*iface
)
2125 return CONTAINING_RECORD(iface
, HandlerCF
, IClassFactory_iface
);
2128 static HRESULT WINAPI
2129 HandlerCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
, LPVOID
*ppv
)
2132 if (IsEqualIID(riid
,&IID_IUnknown
) ||
2133 IsEqualIID(riid
,&IID_IClassFactory
))
2136 IClassFactory_AddRef(iface
);
2139 return E_NOINTERFACE
;
2142 static ULONG WINAPI
HandlerCF_AddRef(LPCLASSFACTORY iface
)
2144 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2145 return InterlockedIncrement(&This
->refs
);
2148 static ULONG WINAPI
HandlerCF_Release(LPCLASSFACTORY iface
)
2150 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2151 ULONG refs
= InterlockedDecrement(&This
->refs
);
2153 HeapFree(GetProcessHeap(), 0, This
);
2157 static HRESULT WINAPI
2158 HandlerCF_CreateInstance(LPCLASSFACTORY iface
, LPUNKNOWN pUnk
,
2159 REFIID riid
, LPVOID
*ppv
)
2161 HandlerCF
*This
= impl_from_IClassFactory(iface
);
2162 return OleCreateDefaultHandler(&This
->clsid
, pUnk
, riid
, ppv
);
2165 static HRESULT WINAPI
HandlerCF_LockServer(LPCLASSFACTORY iface
, BOOL fLock
)
2167 FIXME("(%d), stub!\n",fLock
);
2171 static const IClassFactoryVtbl HandlerClassFactoryVtbl
= {
2172 HandlerCF_QueryInterface
,
2175 HandlerCF_CreateInstance
,
2176 HandlerCF_LockServer
2179 HRESULT
HandlerCF_Create(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
2182 HandlerCF
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
2183 if (!This
) return E_OUTOFMEMORY
;
2184 This
->IClassFactory_iface
.lpVtbl
= &HandlerClassFactoryVtbl
;
2186 This
->clsid
= *rclsid
;
2188 hr
= IUnknown_QueryInterface((IUnknown
*)&This
->IClassFactory_iface
, riid
, ppv
);
2190 HeapFree(GetProcessHeap(), 0, This
);