2 * OLE 2 default object handler
4 * Copyright 1999 Francis Beaudet
5 * Copyright 2000 Abey George
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * The OLE2 default object handler supports a whole whack of
23 * interfaces including:
24 * IOleObject, IDataObject, IPersistStorage, IViewObject2,
25 * IRunnableObject, IOleCache2, IOleCacheControl and much more.
27 * All the implementation details are taken from: Inside OLE
28 * second edition by Kraig Brockschmidt,
31 * - This implementation of the default handler does not launch the
32 * server in the DoVerb, Update, GetData, GetDataHere and Run
33 * methods. When it is fixed to do so, all the methods will have
34 * to be revisited to allow delegating to the running object
36 * - All methods in the class that use the class ID should be
37 * aware that it is possible for a class to be treated as
38 * another one and go into emulation mode. Nothing has been
41 * - Some functions still return E_NOTIMPL they have to be
42 * implemented. Most of those are related to the running of the
45 * - All the methods related to notification and advise sinks are
46 * in place but no notifications are sent to the sinks yet.
60 #include "compobj_private.h"
62 #include "wine/unicode.h"
63 #include "wine/debug.h"
65 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
69 storage_state_uninitialised
,
70 storage_state_initialised
,
76 object_state_not_running
,
80 /****************************************************************************
86 const IOleObjectVtbl
* lpVtbl
;
87 const IUnknownVtbl
* lpvtblIUnknown
;
88 const IDataObjectVtbl
* lpvtblIDataObject
;
89 const IRunnableObjectVtbl
* lpvtblIRunnableObject
;
90 const IAdviseSinkVtbl
*lpvtblIAdviseSink
;
91 const IPersistStorageVtbl
*lpvtblIPersistStorage
;
93 /* Reference count of this object */
96 /* IUnknown implementation of the outer object. */
97 IUnknown
* outerUnknown
;
99 /* Class Id that this handler object represents. */
102 /* IUnknown implementation of the datacache. */
104 /* IPersistStorage implementation of the datacache. */
105 IPersistStorage
* dataCache_PersistStg
;
107 /* Client site for the embedded object. */
108 IOleClientSite
* clientSite
;
111 * The IOleAdviseHolder maintains the connections
112 * on behalf of the default handler.
114 IOleAdviseHolder
* oleAdviseHolder
;
117 * The IDataAdviseHolder maintains the data
118 * connections on behalf of the default handler.
120 IDataAdviseHolder
* dataAdviseHolder
;
122 /* Name of the container and object contained */
126 /* IOleObject delegate */
127 IOleObject
*pOleDelegate
;
128 /* IPersistStorage delegate */
129 IPersistStorage
*pPSDelegate
;
130 /* IDataObject delegate */
131 IDataObject
*pDataDelegate
;
132 enum object_state object_state
;
134 /* connection cookie for the advise on the delegate OLE object */
137 /* storage passed to Load or InitNew */
139 enum storage_state storage_state
;
141 /* optional class factory for object */
142 IClassFactory
*pCFObject
;
143 /* TRUE if acting as an inproc server instead of an inproc handler */
147 typedef struct DefaultHandler DefaultHandler
;
149 static inline DefaultHandler
*impl_from_IOleObject( IOleObject
*iface
)
151 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpVtbl
));
154 static inline DefaultHandler
*impl_from_NDIUnknown( IUnknown
*iface
)
156 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIUnknown
));
159 static inline DefaultHandler
*impl_from_IDataObject( IDataObject
*iface
)
161 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIDataObject
));
164 static inline DefaultHandler
*impl_from_IRunnableObject( IRunnableObject
*iface
)
166 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIRunnableObject
));
169 static inline DefaultHandler
*impl_from_IAdviseSink( IAdviseSink
*iface
)
171 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIAdviseSink
));
174 static inline DefaultHandler
*impl_from_IPersistStorage( IPersistStorage
*iface
)
176 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIPersistStorage
));
179 static void DefaultHandler_Destroy(DefaultHandler
* This
);
181 static inline BOOL
object_is_running(DefaultHandler
*This
)
183 return IRunnableObject_IsRunning((IRunnableObject
*)&This
->lpvtblIRunnableObject
);
186 /*********************************************************
187 * Method implementation for the non delegating IUnknown
188 * part of the DefaultHandler class.
191 /************************************************************************
192 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
194 * See Windows documentation for more details on IUnknown methods.
196 * This version of QueryInterface will not delegate its implementation
197 * to the outer unknown.
199 static HRESULT WINAPI
DefaultHandler_NDIUnknown_QueryInterface(
204 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
211 if (IsEqualIID(&IID_IUnknown
, riid
))
213 else if (IsEqualIID(&IID_IOleObject
, riid
))
214 *ppvObject
= &This
->lpVtbl
;
215 else if (IsEqualIID(&IID_IDataObject
, riid
))
216 *ppvObject
= &This
->lpvtblIDataObject
;
217 else if (IsEqualIID(&IID_IRunnableObject
, riid
))
218 *ppvObject
= &This
->lpvtblIRunnableObject
;
219 else if (IsEqualIID(&IID_IPersist
, riid
) ||
220 IsEqualIID(&IID_IPersistStorage
, riid
))
221 *ppvObject
= &This
->lpvtblIPersistStorage
;
222 else if (IsEqualIID(&IID_IViewObject
, riid
) ||
223 IsEqualIID(&IID_IViewObject2
, riid
) ||
224 IsEqualIID(&IID_IOleCache
, riid
) ||
225 IsEqualIID(&IID_IOleCache2
, riid
))
227 HRESULT hr
= IUnknown_QueryInterface(This
->dataCache
, riid
, ppvObject
);
228 if (FAILED(hr
)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid
));
231 else if (This
->inproc_server
&& This
->pOleDelegate
)
233 HRESULT hr
= IUnknown_QueryInterface(This
->pOleDelegate
, riid
, ppvObject
);
238 /* Check that we obtained an interface. */
239 if (*ppvObject
== NULL
)
241 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid
));
242 return E_NOINTERFACE
;
246 * Query Interface always increases the reference count by one when it is
249 IUnknown_AddRef((IUnknown
*)*ppvObject
);
254 /************************************************************************
255 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
257 * See Windows documentation for more details on IUnknown methods.
259 * This version of QueryInterface will not delegate its implementation
260 * to the outer unknown.
262 static ULONG WINAPI
DefaultHandler_NDIUnknown_AddRef(
265 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
266 return InterlockedIncrement(&This
->ref
);
269 /************************************************************************
270 * DefaultHandler_NDIUnknown_Release (IUnknown)
272 * See Windows documentation for more details on IUnknown methods.
274 * This version of QueryInterface will not delegate its implementation
275 * to the outer unknown.
277 static ULONG WINAPI
DefaultHandler_NDIUnknown_Release(
280 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
283 ref
= InterlockedDecrement(&This
->ref
);
285 if (!ref
) DefaultHandler_Destroy(This
);
290 /*********************************************************
291 * Methods implementation for the IOleObject part of
292 * the DefaultHandler class.
295 /************************************************************************
296 * DefaultHandler_QueryInterface (IUnknown)
298 * See Windows documentation for more details on IUnknown methods.
300 static HRESULT WINAPI
DefaultHandler_QueryInterface(
305 DefaultHandler
*This
= impl_from_IOleObject(iface
);
307 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
310 /************************************************************************
311 * DefaultHandler_AddRef (IUnknown)
313 * See Windows documentation for more details on IUnknown methods.
315 static ULONG WINAPI
DefaultHandler_AddRef(
318 DefaultHandler
*This
= impl_from_IOleObject(iface
);
320 return IUnknown_AddRef(This
->outerUnknown
);
323 /************************************************************************
324 * DefaultHandler_Release (IUnknown)
326 * See Windows documentation for more details on IUnknown methods.
328 static ULONG WINAPI
DefaultHandler_Release(
331 DefaultHandler
*This
= impl_from_IOleObject(iface
);
333 return IUnknown_Release(This
->outerUnknown
);
336 /************************************************************************
337 * DefaultHandler_SetClientSite (IOleObject)
339 * The default handler's implementation of this method only keeps the
340 * client site pointer for future reference.
342 * See Windows documentation for more details on IOleObject methods.
344 static HRESULT WINAPI
DefaultHandler_SetClientSite(
346 IOleClientSite
* pClientSite
)
348 DefaultHandler
*This
= impl_from_IOleObject(iface
);
351 TRACE("(%p, %p)\n", iface
, pClientSite
);
353 if (object_is_running(This
))
354 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, pClientSite
);
357 * Make sure we release the previous client site if there
360 if (This
->clientSite
)
361 IOleClientSite_Release(This
->clientSite
);
363 This
->clientSite
= pClientSite
;
365 if (This
->clientSite
)
366 IOleClientSite_AddRef(This
->clientSite
);
371 /************************************************************************
372 * DefaultHandler_GetClientSite (IOleObject)
374 * The default handler's implementation of this method returns the
375 * last pointer set in IOleObject_SetClientSite.
377 * See Windows documentation for more details on IOleObject methods.
379 static HRESULT WINAPI
DefaultHandler_GetClientSite(
381 IOleClientSite
** ppClientSite
)
383 DefaultHandler
*This
= impl_from_IOleObject(iface
);
388 *ppClientSite
= This
->clientSite
;
390 if (This
->clientSite
)
391 IOleClientSite_AddRef(This
->clientSite
);
396 /************************************************************************
397 * DefaultHandler_SetHostNames (IOleObject)
399 * The default handler's implementation of this method just stores
400 * the strings and returns S_OK.
402 * See Windows documentation for more details on IOleObject methods.
404 static HRESULT WINAPI
DefaultHandler_SetHostNames(
406 LPCOLESTR szContainerApp
,
407 LPCOLESTR szContainerObj
)
409 DefaultHandler
*This
= impl_from_IOleObject(iface
);
411 TRACE("(%p, %s, %s)\n",
413 debugstr_w(szContainerApp
),
414 debugstr_w(szContainerObj
));
416 if (object_is_running(This
))
417 IOleObject_SetHostNames(This
->pOleDelegate
, szContainerApp
, szContainerObj
);
419 /* Be sure to cleanup before re-assigning the strings. */
420 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
421 This
->containerApp
= NULL
;
422 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
423 This
->containerObj
= NULL
;
427 if ((This
->containerApp
= HeapAlloc( GetProcessHeap(), 0,
428 (lstrlenW(szContainerApp
) + 1) * sizeof(WCHAR
) )))
429 strcpyW( This
->containerApp
, szContainerApp
);
434 if ((This
->containerObj
= HeapAlloc( GetProcessHeap(), 0,
435 (lstrlenW(szContainerObj
) + 1) * sizeof(WCHAR
) )))
436 strcpyW( This
->containerObj
, szContainerObj
);
441 static void release_delegates(DefaultHandler
*This
)
443 if (This
->pDataDelegate
)
445 IDataObject_Release(This
->pDataDelegate
);
446 This
->pDataDelegate
= NULL
;
448 if (This
->pPSDelegate
)
450 IPersistStorage_Release(This
->pPSDelegate
);
451 This
->pPSDelegate
= NULL
;
453 if (This
->pOleDelegate
)
455 IOleObject_Release(This
->pOleDelegate
);
456 This
->pOleDelegate
= NULL
;
460 /* undoes the work done by DefaultHandler_Run */
461 static void DefaultHandler_Stop(DefaultHandler
*This
)
463 if (!object_is_running(This
))
466 IOleObject_Unadvise(This
->pOleDelegate
, This
->dwAdvConn
);
468 /* FIXME: call IOleCache_OnStop */
470 if (This
->dataAdviseHolder
)
471 DataAdviseHolder_OnDisconnect(This
->dataAdviseHolder
);
473 This
->object_state
= object_state_not_running
;
476 /************************************************************************
477 * DefaultHandler_Close (IOleObject)
479 * The default handler's implementation of this method is meaningless
480 * without a running server so it does nothing.
482 * See Windows documentation for more details on IOleObject methods.
484 static HRESULT WINAPI
DefaultHandler_Close(
488 DefaultHandler
*This
= impl_from_IOleObject(iface
);
491 TRACE("(%d)\n", dwSaveOption
);
493 if (!object_is_running(This
))
496 hr
= IOleObject_Close(This
->pOleDelegate
, dwSaveOption
);
498 DefaultHandler_Stop(This
);
499 release_delegates(This
);
504 /************************************************************************
505 * DefaultHandler_SetMoniker (IOleObject)
507 * The default handler's implementation of this method does nothing.
509 * See Windows documentation for more details on IOleObject methods.
511 static HRESULT WINAPI
DefaultHandler_SetMoniker(
513 DWORD dwWhichMoniker
,
516 DefaultHandler
*This
= impl_from_IOleObject(iface
);
518 TRACE("(%p, %d, %p)\n",
523 if (object_is_running(This
))
524 return IOleObject_SetMoniker(This
->pOleDelegate
, dwWhichMoniker
, pmk
);
529 /************************************************************************
530 * DefaultHandler_GetMoniker (IOleObject)
532 * Delegate this request to the client site if we have one.
534 * See Windows documentation for more details on IOleObject methods.
536 static HRESULT WINAPI
DefaultHandler_GetMoniker(
539 DWORD dwWhichMoniker
,
542 DefaultHandler
*This
= impl_from_IOleObject(iface
);
544 TRACE("(%p, %d, %d, %p)\n",
545 iface
, dwAssign
, dwWhichMoniker
, ppmk
);
547 if (object_is_running(This
))
548 return IOleObject_GetMoniker(This
->pOleDelegate
, dwAssign
, dwWhichMoniker
,
551 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
552 if (This
->clientSite
)
554 return IOleClientSite_GetMoniker(This
->clientSite
,
564 /************************************************************************
565 * DefaultHandler_InitFromData (IOleObject)
567 * This method is meaningless if the server is not running
569 * See Windows documentation for more details on IOleObject methods.
571 static HRESULT WINAPI
DefaultHandler_InitFromData(
573 IDataObject
* pDataObject
,
577 DefaultHandler
*This
= impl_from_IOleObject(iface
);
579 TRACE("(%p, %p, %d, %d)\n",
580 iface
, pDataObject
, fCreation
, dwReserved
);
582 if (object_is_running(This
))
583 return IOleObject_InitFromData(This
->pOleDelegate
, pDataObject
, fCreation
,
585 return OLE_E_NOTRUNNING
;
588 /************************************************************************
589 * DefaultHandler_GetClipboardData (IOleObject)
591 * This method is meaningless if the server is not running
593 * See Windows documentation for more details on IOleObject methods.
595 static HRESULT WINAPI
DefaultHandler_GetClipboardData(
598 IDataObject
** ppDataObject
)
600 DefaultHandler
*This
= impl_from_IOleObject(iface
);
602 TRACE("(%p, %d, %p)\n",
603 iface
, dwReserved
, ppDataObject
);
605 if (object_is_running(This
))
606 return IOleObject_GetClipboardData(This
->pOleDelegate
, dwReserved
,
609 return OLE_E_NOTRUNNING
;
612 static HRESULT WINAPI
DefaultHandler_DoVerb(
615 struct tagMSG
* lpmsg
,
616 IOleClientSite
* pActiveSite
,
621 DefaultHandler
*This
= impl_from_IOleObject(iface
);
622 IRunnableObject
*pRunnableObj
= (IRunnableObject
*)&This
->lpvtblIRunnableObject
;
625 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb
, lpmsg
, pActiveSite
, lindex
, hwndParent
, wine_dbgstr_rect(lprcPosRect
));
627 hr
= IRunnableObject_Run(pRunnableObj
, NULL
);
628 if (FAILED(hr
)) return hr
;
630 return IOleObject_DoVerb(This
->pOleDelegate
, iVerb
, lpmsg
, pActiveSite
,
631 lindex
, hwndParent
, lprcPosRect
);
634 /************************************************************************
635 * DefaultHandler_EnumVerbs (IOleObject)
637 * The default handler implementation of this method simply delegates
640 * See Windows documentation for more details on IOleObject methods.
642 static HRESULT WINAPI
DefaultHandler_EnumVerbs(
644 IEnumOLEVERB
** ppEnumOleVerb
)
646 DefaultHandler
*This
= impl_from_IOleObject(iface
);
647 HRESULT hr
= OLE_S_USEREG
;
649 TRACE("(%p, %p)\n", iface
, ppEnumOleVerb
);
651 if (object_is_running(This
))
652 hr
= IOleObject_EnumVerbs(This
->pOleDelegate
, ppEnumOleVerb
);
654 if (hr
== OLE_S_USEREG
)
655 return OleRegEnumVerbs(&This
->clsid
, ppEnumOleVerb
);
660 static HRESULT WINAPI
DefaultHandler_Update(
663 DefaultHandler
*This
= impl_from_IOleObject(iface
);
664 TRACE("(%p)\n", iface
);
666 if (!object_is_running(This
))
668 FIXME("Should run object\n");
671 return IOleObject_Update(This
->pOleDelegate
);
674 /************************************************************************
675 * DefaultHandler_IsUpToDate (IOleObject)
677 * This method is meaningless if the server is not running
679 * See Windows documentation for more details on IOleObject methods.
681 static HRESULT WINAPI
DefaultHandler_IsUpToDate(
684 DefaultHandler
*This
= impl_from_IOleObject(iface
);
685 TRACE("(%p)\n", iface
);
687 if (object_is_running(This
))
688 return IOleObject_IsUpToDate(This
->pOleDelegate
);
690 return OLE_E_NOTRUNNING
;
693 /************************************************************************
694 * DefaultHandler_GetUserClassID (IOleObject)
696 * TODO: Map to a new class ID if emulation is active.
698 * See Windows documentation for more details on IOleObject methods.
700 static HRESULT WINAPI
DefaultHandler_GetUserClassID(
704 DefaultHandler
*This
= impl_from_IOleObject(iface
);
706 TRACE("(%p, %p)\n", iface
, pClsid
);
708 if (object_is_running(This
))
709 return IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
714 *pClsid
= This
->clsid
;
719 /************************************************************************
720 * DefaultHandler_GetUserType (IOleObject)
722 * The default handler implementation of this method simply delegates
723 * to OleRegGetUserType
725 * See Windows documentation for more details on IOleObject methods.
727 static HRESULT WINAPI
DefaultHandler_GetUserType(
730 LPOLESTR
* pszUserType
)
732 DefaultHandler
*This
= impl_from_IOleObject(iface
);
734 TRACE("(%p, %d, %p)\n", iface
, dwFormOfType
, pszUserType
);
735 if (object_is_running(This
))
736 return IOleObject_GetUserType(This
->pOleDelegate
, dwFormOfType
, pszUserType
);
738 return OleRegGetUserType(&This
->clsid
, dwFormOfType
, pszUserType
);
741 /************************************************************************
742 * DefaultHandler_SetExtent (IOleObject)
744 * This method is meaningless if the server is not running
746 * See Windows documentation for more details on IOleObject methods.
748 static HRESULT WINAPI
DefaultHandler_SetExtent(
753 DefaultHandler
*This
= impl_from_IOleObject(iface
);
755 TRACE("(%p, %x, (%d x %d))\n", iface
,
756 dwDrawAspect
, psizel
->cx
, psizel
->cy
);
758 if (object_is_running(This
))
759 return IOleObject_SetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
761 return OLE_E_NOTRUNNING
;
764 /************************************************************************
765 * DefaultHandler_GetExtent (IOleObject)
767 * The default handler's implementation of this method returns uses
768 * the cache to locate the aspect and extract the extent from it.
770 * See Windows documentation for more details on IOleObject methods.
772 static HRESULT WINAPI
DefaultHandler_GetExtent(
777 DVTARGETDEVICE
* targetDevice
;
778 IViewObject2
* cacheView
= NULL
;
781 DefaultHandler
*This
= impl_from_IOleObject(iface
);
783 TRACE("(%p, %x, %p)\n", iface
, dwDrawAspect
, psizel
);
785 if (object_is_running(This
))
786 return IOleObject_GetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
788 hres
= IUnknown_QueryInterface(This
->dataCache
, &IID_IViewObject2
, (void**)&cacheView
);
793 * Prepare the call to the cache's GetExtent method.
795 * Here we would build a valid DVTARGETDEVICE structure
796 * but, since we are calling into the data cache, we
797 * know its implementation and we'll skip this
798 * extra work until later.
802 hres
= IViewObject2_GetExtent(cacheView
,
808 IViewObject2_Release(cacheView
);
813 /************************************************************************
814 * DefaultHandler_Advise (IOleObject)
816 * The default handler's implementation of this method simply
817 * delegates to the OleAdviseHolder.
819 * See Windows documentation for more details on IOleObject methods.
821 static HRESULT WINAPI
DefaultHandler_Advise(
823 IAdviseSink
* pAdvSink
,
824 DWORD
* pdwConnection
)
827 DefaultHandler
*This
= impl_from_IOleObject(iface
);
829 TRACE("(%p, %p, %p)\n", iface
, pAdvSink
, pdwConnection
);
831 /* Make sure we have an advise holder before we start. */
832 if (!This
->oleAdviseHolder
)
833 hres
= CreateOleAdviseHolder(&This
->oleAdviseHolder
);
836 hres
= IOleAdviseHolder_Advise(This
->oleAdviseHolder
,
843 /************************************************************************
844 * DefaultHandler_Unadvise (IOleObject)
846 * The default handler's implementation of this method simply
847 * delegates to the OleAdviseHolder.
849 * See Windows documentation for more details on IOleObject methods.
851 static HRESULT WINAPI
DefaultHandler_Unadvise(
855 DefaultHandler
*This
= impl_from_IOleObject(iface
);
857 TRACE("(%p, %d)\n", iface
, dwConnection
);
860 * If we don't have an advise holder yet, it means we don't have
863 if (!This
->oleAdviseHolder
)
864 return OLE_E_NOCONNECTION
;
866 return IOleAdviseHolder_Unadvise(This
->oleAdviseHolder
,
870 /************************************************************************
871 * DefaultHandler_EnumAdvise (IOleObject)
873 * The default handler's implementation of this method simply
874 * delegates to the OleAdviseHolder.
876 * See Windows documentation for more details on IOleObject methods.
878 static HRESULT WINAPI
DefaultHandler_EnumAdvise(
880 IEnumSTATDATA
** ppenumAdvise
)
882 DefaultHandler
*This
= impl_from_IOleObject(iface
);
884 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
889 *ppenumAdvise
= NULL
;
891 if (!This
->oleAdviseHolder
)
894 return IOleAdviseHolder_EnumAdvise(This
->oleAdviseHolder
, ppenumAdvise
);
897 /************************************************************************
898 * DefaultHandler_GetMiscStatus (IOleObject)
900 * The default handler's implementation of this method simply delegates
901 * to OleRegGetMiscStatus.
903 * See Windows documentation for more details on IOleObject methods.
905 static HRESULT WINAPI
DefaultHandler_GetMiscStatus(
911 DefaultHandler
*This
= impl_from_IOleObject(iface
);
913 TRACE("(%p, %x, %p)\n", iface
, dwAspect
, pdwStatus
);
915 if (object_is_running(This
))
916 return IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
918 hres
= OleRegGetMiscStatus(&This
->clsid
, dwAspect
, pdwStatus
);
926 /************************************************************************
927 * DefaultHandler_SetColorScheme (IOleObject)
929 * This method is meaningless if the server is not running
931 * See Windows documentation for more details on IOleObject methods.
933 static HRESULT WINAPI
DefaultHandler_SetColorScheme(
935 struct tagLOGPALETTE
* pLogpal
)
937 DefaultHandler
*This
= impl_from_IOleObject(iface
);
939 TRACE("(%p, %p))\n", iface
, pLogpal
);
941 if (object_is_running(This
))
942 return IOleObject_SetColorScheme(This
->pOleDelegate
, pLogpal
);
944 return OLE_E_NOTRUNNING
;
947 /*********************************************************
948 * Methods implementation for the IDataObject part of
949 * the DefaultHandler class.
952 /************************************************************************
953 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
955 * See Windows documentation for more details on IUnknown methods.
957 static HRESULT WINAPI
DefaultHandler_IDataObject_QueryInterface(
962 DefaultHandler
*This
= impl_from_IDataObject(iface
);
964 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
967 /************************************************************************
968 * DefaultHandler_IDataObject_AddRef (IUnknown)
970 * See Windows documentation for more details on IUnknown methods.
972 static ULONG WINAPI
DefaultHandler_IDataObject_AddRef(
975 DefaultHandler
*This
= impl_from_IDataObject(iface
);
977 return IUnknown_AddRef(This
->outerUnknown
);
980 /************************************************************************
981 * DefaultHandler_IDataObject_Release (IUnknown)
983 * See Windows documentation for more details on IUnknown methods.
985 static ULONG WINAPI
DefaultHandler_IDataObject_Release(
988 DefaultHandler
*This
= impl_from_IDataObject(iface
);
990 return IUnknown_Release(This
->outerUnknown
);
993 /************************************************************************
994 * DefaultHandler_GetData
996 * Get Data from a source dataobject using format pformatetcIn->cfFormat
997 * See Windows documentation for more details on GetData.
998 * Default handler's implementation of this method delegates to the cache.
1000 static HRESULT WINAPI
DefaultHandler_GetData(
1002 LPFORMATETC pformatetcIn
,
1005 IDataObject
* cacheDataObject
= NULL
;
1008 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1010 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pmedium
);
1012 hres
= IUnknown_QueryInterface(This
->dataCache
,
1014 (void**)&cacheDataObject
);
1017 return E_UNEXPECTED
;
1019 hres
= IDataObject_GetData(cacheDataObject
,
1023 IDataObject_Release(cacheDataObject
);
1025 if (FAILED(hres
) && This
->pDataDelegate
)
1026 hres
= IDataObject_GetData(This
->pDataDelegate
, pformatetcIn
, pmedium
);
1031 static HRESULT WINAPI
DefaultHandler_GetDataHere(
1033 LPFORMATETC pformatetc
,
1040 /************************************************************************
1041 * DefaultHandler_QueryGetData (IDataObject)
1043 * The default handler's implementation of this method delegates to
1046 * See Windows documentation for more details on IDataObject methods.
1048 static HRESULT WINAPI
DefaultHandler_QueryGetData(
1050 LPFORMATETC pformatetc
)
1052 IDataObject
* cacheDataObject
= NULL
;
1055 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1057 TRACE("(%p, %p)\n", iface
, pformatetc
);
1059 hres
= IUnknown_QueryInterface(This
->dataCache
,
1061 (void**)&cacheDataObject
);
1064 return E_UNEXPECTED
;
1066 hres
= IDataObject_QueryGetData(cacheDataObject
,
1069 IDataObject_Release(cacheDataObject
);
1071 if (FAILED(hres
) && This
->pDataDelegate
)
1072 hres
= IDataObject_QueryGetData(This
->pDataDelegate
, pformatetc
);
1077 /************************************************************************
1078 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1080 * This method is meaningless if the server is not running
1082 * See Windows documentation for more details on IDataObject methods.
1084 static HRESULT WINAPI
DefaultHandler_GetCanonicalFormatEtc(
1086 LPFORMATETC pformatetcIn
,
1087 LPFORMATETC pformatetcOut
)
1089 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1091 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pformatetcOut
);
1093 if (!This
->pDataDelegate
)
1094 return OLE_E_NOTRUNNING
;
1096 return IDataObject_GetCanonicalFormatEtc(This
->pDataDelegate
, pformatetcIn
, pformatetcOut
);
1099 /************************************************************************
1100 * DefaultHandler_SetData (IDataObject)
1102 * The default handler's implementation of this method delegates to
1105 * See Windows documentation for more details on IDataObject methods.
1107 static HRESULT WINAPI
DefaultHandler_SetData(
1109 LPFORMATETC pformatetc
,
1113 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1114 IDataObject
* cacheDataObject
= NULL
;
1117 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1119 hres
= IUnknown_QueryInterface(This
->dataCache
,
1121 (void**)&cacheDataObject
);
1124 return E_UNEXPECTED
;
1126 hres
= IDataObject_SetData(cacheDataObject
,
1131 IDataObject_Release(cacheDataObject
);
1136 /************************************************************************
1137 * DefaultHandler_EnumFormatEtc (IDataObject)
1139 * The default handler's implementation of This method simply delegates
1140 * to OleRegEnumFormatEtc.
1142 * See Windows documentation for more details on IDataObject methods.
1144 static HRESULT WINAPI
DefaultHandler_EnumFormatEtc(
1147 IEnumFORMATETC
** ppenumFormatEtc
)
1150 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1152 TRACE("(%p, %x, %p)\n", iface
, dwDirection
, ppenumFormatEtc
);
1154 hres
= OleRegEnumFormatEtc(&This
->clsid
, dwDirection
, ppenumFormatEtc
);
1159 /************************************************************************
1160 * DefaultHandler_DAdvise (IDataObject)
1162 * The default handler's implementation of this method simply
1163 * delegates to the DataAdviseHolder.
1165 * See Windows documentation for more details on IDataObject methods.
1167 static HRESULT WINAPI
DefaultHandler_DAdvise(
1169 FORMATETC
* pformatetc
,
1171 IAdviseSink
* pAdvSink
,
1172 DWORD
* pdwConnection
)
1174 HRESULT hres
= S_OK
;
1175 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1177 TRACE("(%p, %p, %d, %p, %p)\n",
1178 iface
, pformatetc
, advf
, pAdvSink
, pdwConnection
);
1180 /* Make sure we have a data advise holder before we start. */
1181 if (!This
->dataAdviseHolder
)
1183 hres
= CreateDataAdviseHolder(&This
->dataAdviseHolder
);
1184 if (SUCCEEDED(hres
) && This
->pDataDelegate
)
1185 DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1188 if (SUCCEEDED(hres
))
1189 hres
= IDataAdviseHolder_Advise(This
->dataAdviseHolder
,
1199 /************************************************************************
1200 * DefaultHandler_DUnadvise (IDataObject)
1202 * The default handler's implementation of this method simply
1203 * delegates to the DataAdviseHolder.
1205 * See Windows documentation for more details on IDataObject methods.
1207 static HRESULT WINAPI
DefaultHandler_DUnadvise(
1211 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1213 TRACE("(%p, %d)\n", iface
, dwConnection
);
1216 * If we don't have a data advise holder yet, it means that
1217 * we don't have any connections..
1219 if (!This
->dataAdviseHolder
)
1220 return OLE_E_NOCONNECTION
;
1222 return IDataAdviseHolder_Unadvise(This
->dataAdviseHolder
,
1226 /************************************************************************
1227 * DefaultHandler_EnumDAdvise (IDataObject)
1229 * The default handler's implementation of this method simply
1230 * delegates to the DataAdviseHolder.
1232 * See Windows documentation for more details on IDataObject methods.
1234 static HRESULT WINAPI
DefaultHandler_EnumDAdvise(
1236 IEnumSTATDATA
** ppenumAdvise
)
1238 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1240 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
1245 *ppenumAdvise
= NULL
;
1247 /* If we have a data advise holder object, delegate. */
1248 if (This
->dataAdviseHolder
)
1249 return IDataAdviseHolder_EnumAdvise(This
->dataAdviseHolder
,
1255 /*********************************************************
1256 * Methods implementation for the IRunnableObject part
1257 * of the DefaultHandler class.
1260 /************************************************************************
1261 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1263 * See Windows documentation for more details on IUnknown methods.
1265 static HRESULT WINAPI
DefaultHandler_IRunnableObject_QueryInterface(
1266 IRunnableObject
* iface
,
1270 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1272 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1275 /************************************************************************
1276 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1278 * See Windows documentation for more details on IUnknown methods.
1280 static ULONG WINAPI
DefaultHandler_IRunnableObject_AddRef(
1281 IRunnableObject
* iface
)
1283 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1285 return IUnknown_AddRef(This
->outerUnknown
);
1288 /************************************************************************
1289 * DefaultHandler_IRunnableObject_Release (IUnknown)
1291 * See Windows documentation for more details on IUnknown methods.
1293 static ULONG WINAPI
DefaultHandler_IRunnableObject_Release(
1294 IRunnableObject
* iface
)
1296 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1298 return IUnknown_Release(This
->outerUnknown
);
1301 /************************************************************************
1302 * DefaultHandler_GetRunningClass (IRunnableObject)
1304 * See Windows documentation for more details on IRunnableObject methods.
1306 static HRESULT WINAPI
DefaultHandler_GetRunningClass(
1307 IRunnableObject
* iface
,
1314 static HRESULT WINAPI
DefaultHandler_Run(
1315 IRunnableObject
* iface
,
1318 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1321 FIXME("(%p): semi-stub\n", pbc
);
1323 /* already running? if so nothing to do */
1324 if (object_is_running(This
))
1327 release_delegates(This
);
1329 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_LOCAL_SERVER
,
1330 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1334 This
->object_state
= object_state_running
;
1336 hr
= IOleObject_Advise(This
->pOleDelegate
,
1337 (IAdviseSink
*)&This
->lpvtblIAdviseSink
,
1340 if (SUCCEEDED(hr
) && This
->clientSite
)
1341 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, This
->clientSite
);
1345 IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
,
1346 (void **)&This
->pPSDelegate
);
1347 if (This
->pPSDelegate
)
1349 if(This
->storage_state
== storage_state_initialised
)
1350 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, This
->storage
);
1351 else if(This
->storage_state
== storage_state_loaded
)
1352 hr
= IPersistStorage_Load(This
->pPSDelegate
, This
->storage
);
1356 if (SUCCEEDED(hr
) && This
->containerApp
)
1357 hr
= IOleObject_SetHostNames(This
->pOleDelegate
, This
->containerApp
,
1358 This
->containerObj
);
1360 /* FIXME: do more stuff here:
1361 * - IOleObject_GetMiscStatus
1362 * - IOleObject_GetMoniker
1367 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
,
1368 (void **)&This
->pDataDelegate
);
1370 if (SUCCEEDED(hr
) && This
->dataAdviseHolder
)
1371 hr
= DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1375 DefaultHandler_Stop(This
);
1376 release_delegates(This
);
1382 /************************************************************************
1383 * DefaultHandler_IsRunning (IRunnableObject)
1385 * See Windows documentation for more details on IRunnableObject methods.
1387 static BOOL WINAPI
DefaultHandler_IsRunning(
1388 IRunnableObject
* iface
)
1390 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1394 if (This
->object_state
== object_state_running
)
1400 /************************************************************************
1401 * DefaultHandler_LockRunning (IRunnableObject)
1403 * See Windows documentation for more details on IRunnableObject methods.
1405 static HRESULT WINAPI
DefaultHandler_LockRunning(
1406 IRunnableObject
* iface
,
1408 BOOL fLastUnlockCloses
)
1414 /************************************************************************
1415 * DefaultHandler_SetContainedObject (IRunnableObject)
1417 * See Windows documentation for more details on IRunnableObject methods.
1419 static HRESULT WINAPI
DefaultHandler_SetContainedObject(
1420 IRunnableObject
* iface
,
1427 static HRESULT WINAPI
DefaultHandler_IAdviseSink_QueryInterface(
1432 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1433 IsEqualIID(riid
, &IID_IAdviseSink
))
1436 IAdviseSink_AddRef(iface
);
1440 return E_NOINTERFACE
;
1443 static ULONG WINAPI
DefaultHandler_IAdviseSink_AddRef(
1446 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1448 return IUnknown_AddRef((IUnknown
*)&This
->lpvtblIUnknown
);
1451 static ULONG WINAPI
DefaultHandler_IAdviseSink_Release(
1454 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1456 return IUnknown_Release((IUnknown
*)&This
->lpvtblIUnknown
);
1459 static void WINAPI
DefaultHandler_IAdviseSink_OnDataChange(
1461 FORMATETC
*pFormatetc
,
1467 static void WINAPI
DefaultHandler_IAdviseSink_OnViewChange(
1475 static void WINAPI
DefaultHandler_IAdviseSink_OnRename(
1479 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1481 TRACE("(%p)\n", pmk
);
1483 if (This
->oleAdviseHolder
)
1484 IOleAdviseHolder_SendOnRename(This
->oleAdviseHolder
, pmk
);
1487 static void WINAPI
DefaultHandler_IAdviseSink_OnSave(
1490 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1494 if (This
->oleAdviseHolder
)
1495 IOleAdviseHolder_SendOnSave(This
->oleAdviseHolder
);
1498 static void WINAPI
DefaultHandler_IAdviseSink_OnClose(
1501 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1505 if (This
->oleAdviseHolder
)
1506 IOleAdviseHolder_SendOnClose(This
->oleAdviseHolder
);
1508 DefaultHandler_Stop(This
);
1512 /************************************************************************
1513 * DefaultHandler_IPersistStorage_QueryInterface
1516 static HRESULT WINAPI
DefaultHandler_IPersistStorage_QueryInterface(
1517 IPersistStorage
* iface
,
1521 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1523 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1526 /************************************************************************
1527 * DefaultHandler_IPersistStorage_AddRef
1530 static ULONG WINAPI
DefaultHandler_IPersistStorage_AddRef(
1531 IPersistStorage
* iface
)
1533 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1535 return IUnknown_AddRef(This
->outerUnknown
);
1538 /************************************************************************
1539 * DefaultHandler_IPersistStorage_Release
1542 static ULONG WINAPI
DefaultHandler_IPersistStorage_Release(
1543 IPersistStorage
* iface
)
1545 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1547 return IUnknown_Release(This
->outerUnknown
);
1550 /************************************************************************
1551 * DefaultHandler_IPersistStorage_GetClassID
1554 static HRESULT WINAPI
DefaultHandler_IPersistStorage_GetClassID(
1555 IPersistStorage
* iface
,
1558 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1561 TRACE("(%p)->(%p)\n", iface
, clsid
);
1563 if(object_is_running(This
))
1564 hr
= IPersistStorage_GetClassID(This
->pPSDelegate
, clsid
);
1566 hr
= IPersistStorage_GetClassID(This
->dataCache_PersistStg
, clsid
);
1571 /************************************************************************
1572 * DefaultHandler_IPersistStorage_IsDirty
1575 static HRESULT WINAPI
DefaultHandler_IPersistStorage_IsDirty(
1576 IPersistStorage
* iface
)
1578 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1581 TRACE("(%p)\n", iface
);
1583 hr
= IPersistStorage_IsDirty(This
->dataCache_PersistStg
);
1584 if(hr
!= S_FALSE
) return hr
;
1586 if(object_is_running(This
))
1587 hr
= IPersistStorage_IsDirty(This
->pPSDelegate
);
1592 /***********************************************************************
1595 * Creates the '\1Ole' stream.
1596 * The format of this stream is as follows:
1598 * DWORD Version == 0x02000001
1599 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1600 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1601 * supplied by the app that creates the data structure. May be
1602 * ignored on processing].
1604 * DWORD Reserved == 0
1605 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1606 * CLSID clsid - class id of object capable of processing the moniker
1607 * BYTE data[] - moniker data for a link
1610 static const WCHAR OleStream
[] = {1,'O','l','e',0};
1615 DWORD link_update_opt
;
1618 } ole_stream_header_t
;
1619 static const DWORD ole_stream_version
= 0x02000001;
1621 static void init_ole_stream(IStorage
*storage
)
1626 hr
= IStorage_CreateStream(storage
, OleStream
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stream
);
1630 ole_stream_header_t header
;
1632 header
.version
= ole_stream_version
;
1634 header
.link_update_opt
= 0;
1636 header
.moniker_size
= 0;
1638 IStream_Write(stream
, &header
, sizeof(header
), &written
);
1639 IStream_Release(stream
);
1644 static HRESULT
load_ole_stream(DefaultHandler
*This
, IStorage
*storage
)
1649 hr
= IStorage_OpenStream(storage
, OleStream
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stream
);
1654 ole_stream_header_t header
;
1656 hr
= IStream_Read(stream
, &header
, sizeof(header
), &read
);
1657 if(hr
== S_OK
&& read
== sizeof(header
) && header
.version
== ole_stream_version
)
1659 if(header
.flags
& 1)
1661 /* FIXME: Read the moniker and deal with the link */
1662 FIXME("Linked objects are not supported yet\n");
1667 WARN("Incorrect OleStream header\n");
1668 hr
= DV_E_CLIPFORMAT
;
1670 IStream_Release(stream
);
1674 init_ole_stream(storage
);
1680 /************************************************************************
1681 * DefaultHandler_IPersistStorage_InitNew
1684 static HRESULT WINAPI
DefaultHandler_IPersistStorage_InitNew(
1685 IPersistStorage
* iface
,
1688 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1691 TRACE("(%p)->(%p)\n", iface
, pStg
);
1692 init_ole_stream(pStg
);
1694 hr
= IPersistStorage_InitNew(This
->dataCache_PersistStg
, pStg
);
1696 if(SUCCEEDED(hr
) && object_is_running(This
))
1697 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, pStg
);
1701 IStorage_AddRef(pStg
);
1702 This
->storage
= pStg
;
1703 This
->storage_state
= storage_state_initialised
;
1710 /************************************************************************
1711 * DefaultHandler_IPersistStorage_Load
1714 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Load(
1715 IPersistStorage
* iface
,
1718 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1721 TRACE("(%p)->(%p)\n", iface
, pStg
);
1723 hr
= load_ole_stream(This
, pStg
);
1726 hr
= IPersistStorage_Load(This
->dataCache_PersistStg
, pStg
);
1728 if(SUCCEEDED(hr
) && object_is_running(This
))
1729 hr
= IPersistStorage_Load(This
->pPSDelegate
, pStg
);
1733 IStorage_AddRef(pStg
);
1734 This
->storage
= pStg
;
1735 This
->storage_state
= storage_state_loaded
;
1741 /************************************************************************
1742 * DefaultHandler_IPersistStorage_Save
1745 static HRESULT WINAPI
DefaultHandler_IPersistStorage_Save(
1746 IPersistStorage
* iface
,
1750 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1753 TRACE("(%p)->(%p, %d)\n", iface
, pStgSave
, fSameAsLoad
);
1755 hr
= IPersistStorage_Save(This
->dataCache_PersistStg
, pStgSave
, fSameAsLoad
);
1756 if(SUCCEEDED(hr
) && object_is_running(This
))
1757 hr
= IPersistStorage_Save(This
->pPSDelegate
, pStgSave
, fSameAsLoad
);
1763 /************************************************************************
1764 * DefaultHandler_IPersistStorage_SaveCompleted
1767 static HRESULT WINAPI
DefaultHandler_IPersistStorage_SaveCompleted(
1768 IPersistStorage
* iface
,
1771 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1774 TRACE("(%p)->(%p)\n", iface
, pStgNew
);
1776 hr
= IPersistStorage_SaveCompleted(This
->dataCache_PersistStg
, pStgNew
);
1778 if(SUCCEEDED(hr
) && object_is_running(This
))
1779 hr
= IPersistStorage_SaveCompleted(This
->pPSDelegate
, pStgNew
);
1783 IStorage_AddRef(pStgNew
);
1784 if(This
->storage
) IStorage_Release(This
->storage
);
1785 This
->storage
= pStgNew
;
1786 This
->storage_state
= storage_state_loaded
;
1793 /************************************************************************
1794 * DefaultHandler_IPersistStorage_HandsOffStorage
1797 static HRESULT WINAPI
DefaultHandler_IPersistStorage_HandsOffStorage(
1798 IPersistStorage
* iface
)
1800 DefaultHandler
*This
= impl_from_IPersistStorage(iface
);
1803 TRACE("(%p)\n", iface
);
1805 hr
= IPersistStorage_HandsOffStorage(This
->dataCache_PersistStg
);
1807 if(SUCCEEDED(hr
) && object_is_running(This
))
1808 hr
= IPersistStorage_HandsOffStorage(This
->pPSDelegate
);
1810 if(This
->storage
) IStorage_Release(This
->storage
);
1811 This
->storage
= NULL
;
1812 This
->storage_state
= storage_state_uninitialised
;
1819 * Virtual function tables for the DefaultHandler class.
1821 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable
=
1823 DefaultHandler_QueryInterface
,
1824 DefaultHandler_AddRef
,
1825 DefaultHandler_Release
,
1826 DefaultHandler_SetClientSite
,
1827 DefaultHandler_GetClientSite
,
1828 DefaultHandler_SetHostNames
,
1829 DefaultHandler_Close
,
1830 DefaultHandler_SetMoniker
,
1831 DefaultHandler_GetMoniker
,
1832 DefaultHandler_InitFromData
,
1833 DefaultHandler_GetClipboardData
,
1834 DefaultHandler_DoVerb
,
1835 DefaultHandler_EnumVerbs
,
1836 DefaultHandler_Update
,
1837 DefaultHandler_IsUpToDate
,
1838 DefaultHandler_GetUserClassID
,
1839 DefaultHandler_GetUserType
,
1840 DefaultHandler_SetExtent
,
1841 DefaultHandler_GetExtent
,
1842 DefaultHandler_Advise
,
1843 DefaultHandler_Unadvise
,
1844 DefaultHandler_EnumAdvise
,
1845 DefaultHandler_GetMiscStatus
,
1846 DefaultHandler_SetColorScheme
1849 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable
=
1851 DefaultHandler_NDIUnknown_QueryInterface
,
1852 DefaultHandler_NDIUnknown_AddRef
,
1853 DefaultHandler_NDIUnknown_Release
,
1856 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable
=
1858 DefaultHandler_IDataObject_QueryInterface
,
1859 DefaultHandler_IDataObject_AddRef
,
1860 DefaultHandler_IDataObject_Release
,
1861 DefaultHandler_GetData
,
1862 DefaultHandler_GetDataHere
,
1863 DefaultHandler_QueryGetData
,
1864 DefaultHandler_GetCanonicalFormatEtc
,
1865 DefaultHandler_SetData
,
1866 DefaultHandler_EnumFormatEtc
,
1867 DefaultHandler_DAdvise
,
1868 DefaultHandler_DUnadvise
,
1869 DefaultHandler_EnumDAdvise
1872 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable
=
1874 DefaultHandler_IRunnableObject_QueryInterface
,
1875 DefaultHandler_IRunnableObject_AddRef
,
1876 DefaultHandler_IRunnableObject_Release
,
1877 DefaultHandler_GetRunningClass
,
1879 DefaultHandler_IsRunning
,
1880 DefaultHandler_LockRunning
,
1881 DefaultHandler_SetContainedObject
1884 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable
=
1886 DefaultHandler_IAdviseSink_QueryInterface
,
1887 DefaultHandler_IAdviseSink_AddRef
,
1888 DefaultHandler_IAdviseSink_Release
,
1889 DefaultHandler_IAdviseSink_OnDataChange
,
1890 DefaultHandler_IAdviseSink_OnViewChange
,
1891 DefaultHandler_IAdviseSink_OnRename
,
1892 DefaultHandler_IAdviseSink_OnSave
,
1893 DefaultHandler_IAdviseSink_OnClose
1896 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable
=
1898 DefaultHandler_IPersistStorage_QueryInterface
,
1899 DefaultHandler_IPersistStorage_AddRef
,
1900 DefaultHandler_IPersistStorage_Release
,
1901 DefaultHandler_IPersistStorage_GetClassID
,
1902 DefaultHandler_IPersistStorage_IsDirty
,
1903 DefaultHandler_IPersistStorage_InitNew
,
1904 DefaultHandler_IPersistStorage_Load
,
1905 DefaultHandler_IPersistStorage_Save
,
1906 DefaultHandler_IPersistStorage_SaveCompleted
,
1907 DefaultHandler_IPersistStorage_HandsOffStorage
1910 /*********************************************************
1911 * Methods implementation for the DefaultHandler class.
1913 static DefaultHandler
* DefaultHandler_Construct(
1915 LPUNKNOWN pUnkOuter
,
1919 DefaultHandler
* This
= NULL
;
1922 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler
));
1927 This
->lpVtbl
= &DefaultHandler_IOleObject_VTable
;
1928 This
->lpvtblIUnknown
= &DefaultHandler_NDIUnknown_VTable
;
1929 This
->lpvtblIDataObject
= &DefaultHandler_IDataObject_VTable
;
1930 This
->lpvtblIRunnableObject
= &DefaultHandler_IRunnableObject_VTable
;
1931 This
->lpvtblIAdviseSink
= &DefaultHandler_IAdviseSink_VTable
;
1932 This
->lpvtblIPersistStorage
= &DefaultHandler_IPersistStorage_VTable
;
1934 This
->inproc_server
= (flags
& EMBDHLP_INPROC_SERVER
) ? TRUE
: FALSE
;
1937 * Start with one reference count. The caller of this function
1938 * must release the interface pointer when it is done.
1943 * Initialize the outer unknown
1944 * We don't keep a reference on the outer unknown since, the way
1945 * aggregation works, our lifetime is at least as large as its
1949 pUnkOuter
= (IUnknown
*)&This
->lpvtblIUnknown
;
1951 This
->outerUnknown
= pUnkOuter
;
1954 * Create a datacache object.
1955 * We aggregate with the datacache. Make sure we pass our outer
1956 * unknown as the datacache's outer unknown.
1958 hr
= CreateDataCache(This
->outerUnknown
,
1961 (void**)&This
->dataCache
);
1964 hr
= IUnknown_QueryInterface(This
->dataCache
, &IID_IPersistStorage
, (void**)&This
->dataCache_PersistStg
);
1965 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
1966 * reference on the outer object */
1968 IUnknown_Release(This
->outerUnknown
);
1970 IUnknown_Release(This
->dataCache
);
1974 ERR("Unexpected error creating data cache\n");
1975 HeapFree(GetProcessHeap(), 0, This
);
1979 This
->clsid
= *clsid
;
1980 This
->clientSite
= NULL
;
1981 This
->oleAdviseHolder
= NULL
;
1982 This
->dataAdviseHolder
= NULL
;
1983 This
->containerApp
= NULL
;
1984 This
->containerObj
= NULL
;
1985 This
->pOleDelegate
= NULL
;
1986 This
->pPSDelegate
= NULL
;
1987 This
->pDataDelegate
= NULL
;
1988 This
->object_state
= object_state_not_running
;
1990 This
->dwAdvConn
= 0;
1991 This
->storage
= NULL
;
1992 This
->storage_state
= storage_state_uninitialised
;
1994 if (This
->inproc_server
&& !(flags
& EMBDHLP_DELAYCREATE
))
1997 This
->pCFObject
= NULL
;
1999 hr
= IClassFactory_CreateInstance(pCF
, NULL
, &IID_IOleObject
, (void **)&This
->pOleDelegate
);
2001 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_INPROC_SERVER
,
2002 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
2004 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
, (void **)&This
->pPSDelegate
);
2006 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
, (void **)&This
->pDataDelegate
);
2008 This
->object_state
= object_state_running
;
2010 WARN("object creation failed with error %08x\n", hr
);
2014 This
->pCFObject
= pCF
;
2015 if (pCF
) IClassFactory_AddRef(pCF
);
2021 static void DefaultHandler_Destroy(
2022 DefaultHandler
* This
)
2024 TRACE("(%p)\n", This
);
2026 /* AddRef/Release may be called on this object during destruction.
2027 * Prevent the object being destroyed recursively by artificially raising
2028 * the reference count. */
2031 /* release delegates */
2032 DefaultHandler_Stop(This
);
2033 release_delegates(This
);
2035 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
2036 This
->containerApp
= NULL
;
2037 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
2038 This
->containerObj
= NULL
;
2040 if (This
->dataCache
)
2042 /* to balance out the release of dataCache_PersistStg which will result
2043 * in a reference being released from the outer unknown */
2044 IUnknown_AddRef(This
->outerUnknown
);
2045 IPersistStorage_Release(This
->dataCache_PersistStg
);
2046 IUnknown_Release(This
->dataCache
);
2047 This
->dataCache_PersistStg
= NULL
;
2048 This
->dataCache
= NULL
;
2051 if (This
->clientSite
)
2053 IOleClientSite_Release(This
->clientSite
);
2054 This
->clientSite
= NULL
;
2057 if (This
->oleAdviseHolder
)
2059 IOleAdviseHolder_Release(This
->oleAdviseHolder
);
2060 This
->oleAdviseHolder
= NULL
;
2063 if (This
->dataAdviseHolder
)
2065 IDataAdviseHolder_Release(This
->dataAdviseHolder
);
2066 This
->dataAdviseHolder
= NULL
;
2071 IStorage_Release(This
->storage
);
2072 This
->storage
= NULL
;
2075 if (This
->pCFObject
)
2077 IClassFactory_Release(This
->pCFObject
);
2078 This
->pCFObject
= NULL
;
2081 HeapFree(GetProcessHeap(), 0, This
);
2084 /******************************************************************************
2085 * OleCreateEmbeddingHelper [OLE32.@]
2087 HRESULT WINAPI
OleCreateEmbeddingHelper(
2089 LPUNKNOWN pUnkOuter
,
2095 DefaultHandler
* newHandler
= NULL
;
2098 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
, flags
, pCF
, debugstr_guid(riid
), ppvObj
);
2106 * If This handler is constructed for aggregation, make sure
2107 * the caller is requesting the IUnknown interface.
2108 * This is necessary because it's the only time the non-delegating
2109 * IUnknown pointer can be returned to the outside.
2111 if (pUnkOuter
&& !IsEqualIID(&IID_IUnknown
, riid
))
2112 return CLASS_E_NOAGGREGATION
;
2115 * Try to construct a new instance of the class.
2117 newHandler
= DefaultHandler_Construct(clsid
, pUnkOuter
, flags
, pCF
);
2120 return E_OUTOFMEMORY
;
2123 * Make sure it supports the interface required by the caller.
2125 hr
= IUnknown_QueryInterface((IUnknown
*)&newHandler
->lpvtblIUnknown
, riid
, ppvObj
);
2128 * Release the reference obtained in the constructor. If
2129 * the QueryInterface was unsuccessful, it will free the class.
2131 IUnknown_Release((IUnknown
*)&newHandler
->lpvtblIUnknown
);
2137 /******************************************************************************
2138 * OleCreateDefaultHandler [OLE32.@]
2140 HRESULT WINAPI
OleCreateDefaultHandler(REFCLSID clsid
, LPUNKNOWN pUnkOuter
,
2141 REFIID riid
, LPVOID
* ppvObj
)
2143 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
,debugstr_guid(riid
), ppvObj
);
2144 return OleCreateEmbeddingHelper(clsid
, pUnkOuter
, EMBDHLP_INPROC_HANDLER
| EMBDHLP_CREATENOW
,
2145 NULL
, riid
, ppvObj
);
2148 typedef struct HandlerCF
2150 const IClassFactoryVtbl
*lpVtbl
;
2155 static HRESULT WINAPI
2156 HandlerCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
, LPVOID
*ppv
)
2159 if (IsEqualIID(riid
,&IID_IUnknown
) ||
2160 IsEqualIID(riid
,&IID_IClassFactory
))
2163 IClassFactory_AddRef(iface
);
2166 return E_NOINTERFACE
;
2169 static ULONG WINAPI
HandlerCF_AddRef(LPCLASSFACTORY iface
)
2171 HandlerCF
*This
= (HandlerCF
*)iface
;
2172 return InterlockedIncrement(&This
->refs
);
2175 static ULONG WINAPI
HandlerCF_Release(LPCLASSFACTORY iface
)
2177 HandlerCF
*This
= (HandlerCF
*)iface
;
2178 ULONG refs
= InterlockedDecrement(&This
->refs
);
2180 HeapFree(GetProcessHeap(), 0, This
);
2184 static HRESULT WINAPI
2185 HandlerCF_CreateInstance(LPCLASSFACTORY iface
, LPUNKNOWN pUnk
,
2186 REFIID riid
, LPVOID
*ppv
)
2188 HandlerCF
*This
= (HandlerCF
*)iface
;
2189 return OleCreateDefaultHandler(&This
->clsid
, pUnk
, riid
, ppv
);
2192 static HRESULT WINAPI
HandlerCF_LockServer(LPCLASSFACTORY iface
, BOOL fLock
)
2194 FIXME("(%d), stub!\n",fLock
);
2198 static const IClassFactoryVtbl HandlerClassFactoryVtbl
= {
2199 HandlerCF_QueryInterface
,
2202 HandlerCF_CreateInstance
,
2203 HandlerCF_LockServer
2206 HRESULT
HandlerCF_Create(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
2209 HandlerCF
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
2210 if (!This
) return E_OUTOFMEMORY
;
2211 This
->lpVtbl
= &HandlerClassFactoryVtbl
;
2213 This
->clsid
= *rclsid
;
2215 hr
= IUnknown_QueryInterface((IUnknown
*)&This
->lpVtbl
, riid
, ppv
);
2217 HeapFree(GetProcessHeap(), 0, This
);