mfplat: Remove duplicated GUID entry from attribute tracing.
[wine/zf.git] / dlls / ole32 / defaulthandler.c
blob81ffa1e6dbca73911c0654340608bde467f1fb1d
1 /*
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
21 * NOTES:
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,
30 * TODO
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
39 * done in this area.
41 * - Some functions still return E_NOTIMPL they have to be
42 * implemented. Most of those are related to the running of the
43 * actual server.
45 * - All the methods related to notification and advise sinks are
46 * in place but no notifications are sent to the sinks yet.
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <string.h>
52 #define COBJMACROS
54 #include "windef.h"
55 #include "winbase.h"
56 #include "winuser.h"
57 #include "winerror.h"
58 #include "ole2.h"
60 #include "compobj_private.h"
61 #include "storage32.h"
63 #include "wine/debug.h"
65 WINE_DEFAULT_DEBUG_CHANNEL(ole);
67 enum storage_state
69 storage_state_uninitialised,
70 storage_state_initialised,
71 storage_state_loaded
74 enum object_state
76 object_state_not_running,
77 object_state_running,
78 object_state_deferred_close
81 /****************************************************************************
82 * DefaultHandler
85 struct DefaultHandler
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 */
95 LONG ref;
97 /* IUnknown implementation of the outer object. */
98 IUnknown* outerUnknown;
100 /* Class Id that this handler object represents. */
101 CLSID clsid;
103 /* IUnknown implementation of the datacache. */
104 IUnknown* 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 */
124 LPWSTR containerApp;
125 LPWSTR containerObj;
127 /* IOleObject delegate */
128 IOleObject *pOleDelegate;
129 /* IPersistStorage delegate */
130 IPersistStorage *pPSDelegate;
131 /* IDataObject delegate */
132 IDataObject *pDataDelegate;
133 enum object_state object_state;
134 ULONG in_call;
136 /* connection cookie for the advise on the delegate OLE object */
137 DWORD dwAdvConn;
139 /* storage passed to Load or InitNew */
140 IStorage *storage;
141 enum storage_state storage_state;
143 /* optional class factory for object */
144 IClassFactory *pCFObject;
145 /* TRUE if acting as an inproc server instead of an inproc handler */
146 BOOL inproc_server;
149 typedef struct DefaultHandler DefaultHandler;
151 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
153 return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface);
156 static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface )
158 return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface);
161 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
163 return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface);
166 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
168 return CONTAINING_RECORD(iface, DefaultHandler, IRunnableObject_iface);
171 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
173 return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface);
176 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
178 return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface);
181 static void DefaultHandler_Destroy(DefaultHandler* This);
183 static inline BOOL object_is_running(DefaultHandler *This)
185 return IRunnableObject_IsRunning(&This->IRunnableObject_iface);
188 static void DefaultHandler_Stop(DefaultHandler *This);
190 static inline void start_object_call(DefaultHandler *This)
192 This->in_call++;
195 static inline void end_object_call(DefaultHandler *This)
197 This->in_call--;
198 if (This->in_call == 0 && This->object_state == object_state_deferred_close)
199 DefaultHandler_Stop( This );
202 /*********************************************************
203 * Method implementation for the non delegating IUnknown
204 * part of the DefaultHandler class.
207 /************************************************************************
208 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
210 * See Windows documentation for more details on IUnknown methods.
212 * This version of QueryInterface will not delegate its implementation
213 * to the outer unknown.
215 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
216 IUnknown* iface,
217 REFIID riid,
218 void** ppvObject)
220 DefaultHandler *This = impl_from_IUnknown(iface);
222 if (!ppvObject)
223 return E_INVALIDARG;
225 *ppvObject = NULL;
227 if (IsEqualIID(&IID_IUnknown, riid))
228 *ppvObject = iface;
229 else if (IsEqualIID(&IID_IOleObject, riid))
230 *ppvObject = &This->IOleObject_iface;
231 else if (IsEqualIID(&IID_IDataObject, riid))
232 *ppvObject = &This->IDataObject_iface;
233 else if (IsEqualIID(&IID_IRunnableObject, riid))
234 *ppvObject = &This->IRunnableObject_iface;
235 else if (IsEqualIID(&IID_IPersist, riid) ||
236 IsEqualIID(&IID_IPersistStorage, riid))
237 *ppvObject = &This->IPersistStorage_iface;
238 else if (IsEqualIID(&IID_IViewObject, riid) ||
239 IsEqualIID(&IID_IViewObject2, riid) ||
240 IsEqualIID(&IID_IOleCache, riid) ||
241 IsEqualIID(&IID_IOleCache2, riid))
243 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
244 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
245 return hr;
247 else if (This->inproc_server && This->pOleDelegate)
249 return IOleObject_QueryInterface(This->pOleDelegate, riid, ppvObject);
252 /* Check that we obtained an interface. */
253 if (*ppvObject == NULL)
255 WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
256 return E_NOINTERFACE;
260 * Query Interface always increases the reference count by one when it is
261 * successful.
263 IUnknown_AddRef((IUnknown*)*ppvObject);
265 return S_OK;
268 /************************************************************************
269 * DefaultHandler_NDIUnknown_AddRef (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_AddRef(
277 IUnknown* iface)
279 DefaultHandler *This = impl_from_IUnknown(iface);
280 return InterlockedIncrement(&This->ref);
283 /************************************************************************
284 * DefaultHandler_NDIUnknown_Release (IUnknown)
286 * See Windows documentation for more details on IUnknown methods.
288 * This version of QueryInterface will not delegate its implementation
289 * to the outer unknown.
291 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
292 IUnknown* iface)
294 DefaultHandler *This = impl_from_IUnknown(iface);
295 ULONG ref;
297 ref = InterlockedDecrement(&This->ref);
299 if (!ref) DefaultHandler_Destroy(This);
301 return ref;
304 /*********************************************************
305 * Methods implementation for the IOleObject part of
306 * the DefaultHandler class.
309 /************************************************************************
310 * DefaultHandler_QueryInterface (IUnknown)
312 * See Windows documentation for more details on IUnknown methods.
314 static HRESULT WINAPI DefaultHandler_QueryInterface(
315 IOleObject* iface,
316 REFIID riid,
317 void** ppvObject)
319 DefaultHandler *This = impl_from_IOleObject(iface);
321 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
324 /************************************************************************
325 * DefaultHandler_AddRef (IUnknown)
327 * See Windows documentation for more details on IUnknown methods.
329 static ULONG WINAPI DefaultHandler_AddRef(
330 IOleObject* iface)
332 DefaultHandler *This = impl_from_IOleObject(iface);
334 return IUnknown_AddRef(This->outerUnknown);
337 /************************************************************************
338 * DefaultHandler_Release (IUnknown)
340 * See Windows documentation for more details on IUnknown methods.
342 static ULONG WINAPI DefaultHandler_Release(
343 IOleObject* iface)
345 DefaultHandler *This = impl_from_IOleObject(iface);
347 return IUnknown_Release(This->outerUnknown);
350 /************************************************************************
351 * DefaultHandler_SetClientSite (IOleObject)
353 * The default handler's implementation of this method only keeps the
354 * client site pointer for future reference.
356 * See Windows documentation for more details on IOleObject methods.
358 static HRESULT WINAPI DefaultHandler_SetClientSite(
359 IOleObject* iface,
360 IOleClientSite* pClientSite)
362 DefaultHandler *This = impl_from_IOleObject(iface);
363 HRESULT hr = S_OK;
365 TRACE("(%p, %p)\n", iface, pClientSite);
367 if (object_is_running(This))
369 start_object_call( This );
370 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
371 end_object_call( This );
375 * Make sure we release the previous client site if there
376 * was one.
378 if (This->clientSite)
379 IOleClientSite_Release(This->clientSite);
381 This->clientSite = pClientSite;
383 if (This->clientSite)
384 IOleClientSite_AddRef(This->clientSite);
386 return hr;
389 /************************************************************************
390 * DefaultHandler_GetClientSite (IOleObject)
392 * The default handler's implementation of this method returns the
393 * last pointer set in IOleObject_SetClientSite.
395 * See Windows documentation for more details on IOleObject methods.
397 static HRESULT WINAPI DefaultHandler_GetClientSite(
398 IOleObject* iface,
399 IOleClientSite** ppClientSite)
401 DefaultHandler *This = impl_from_IOleObject(iface);
403 if (!ppClientSite)
404 return E_POINTER;
406 *ppClientSite = This->clientSite;
408 if (This->clientSite)
409 IOleClientSite_AddRef(This->clientSite);
411 return S_OK;
414 /************************************************************************
415 * DefaultHandler_SetHostNames (IOleObject)
417 * The default handler's implementation of this method just stores
418 * the strings and returns S_OK.
420 * See Windows documentation for more details on IOleObject methods.
422 static HRESULT WINAPI DefaultHandler_SetHostNames(
423 IOleObject* iface,
424 LPCOLESTR szContainerApp,
425 LPCOLESTR szContainerObj)
427 DefaultHandler *This = impl_from_IOleObject(iface);
429 TRACE("(%p, %s, %s)\n",
430 iface,
431 debugstr_w(szContainerApp),
432 debugstr_w(szContainerObj));
434 if (object_is_running(This))
436 start_object_call( This );
437 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
438 end_object_call( This );
441 /* Be sure to cleanup before re-assigning the strings. */
442 HeapFree( GetProcessHeap(), 0, This->containerApp );
443 This->containerApp = NULL;
444 HeapFree( GetProcessHeap(), 0, This->containerObj );
445 This->containerObj = NULL;
447 if (szContainerApp)
449 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
450 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
451 lstrcpyW( This->containerApp, szContainerApp );
454 if (szContainerObj)
456 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
457 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
458 lstrcpyW( This->containerObj, szContainerObj );
460 return S_OK;
463 static void release_delegates(DefaultHandler *This)
465 if (This->pDataDelegate)
467 IDataObject_Release(This->pDataDelegate);
468 This->pDataDelegate = NULL;
470 if (This->pPSDelegate)
472 IPersistStorage_Release(This->pPSDelegate);
473 This->pPSDelegate = NULL;
475 if (This->pOleDelegate)
477 IOleObject_Release(This->pOleDelegate);
478 This->pOleDelegate = NULL;
482 /* undoes the work done by DefaultHandler_Run */
483 static void DefaultHandler_Stop(DefaultHandler *This)
485 IOleCacheControl *cache_ctrl;
486 HRESULT hr;
488 if (This->object_state == object_state_not_running)
489 return;
491 hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
492 if (SUCCEEDED(hr))
494 hr = IOleCacheControl_OnStop( cache_ctrl );
495 IOleCacheControl_Release( cache_ctrl );
498 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
500 if (This->dataAdviseHolder)
501 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
503 This->object_state = object_state_not_running;
504 release_delegates( This );
507 /************************************************************************
508 * DefaultHandler_Close (IOleObject)
510 * The default handler's implementation of this method is meaningless
511 * without a running server so it does nothing.
513 * See Windows documentation for more details on IOleObject methods.
515 static HRESULT WINAPI DefaultHandler_Close(
516 IOleObject* iface,
517 DWORD dwSaveOption)
519 DefaultHandler *This = impl_from_IOleObject(iface);
520 HRESULT hr;
522 TRACE("(%d)\n", dwSaveOption);
524 if (!object_is_running(This))
525 return S_OK;
527 start_object_call( This );
528 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
529 end_object_call( This );
531 DefaultHandler_Stop(This);
533 return hr;
536 /************************************************************************
537 * DefaultHandler_SetMoniker (IOleObject)
539 * The default handler's implementation of this method does nothing.
541 * See Windows documentation for more details on IOleObject methods.
543 static HRESULT WINAPI DefaultHandler_SetMoniker(
544 IOleObject* iface,
545 DWORD dwWhichMoniker,
546 IMoniker* pmk)
548 DefaultHandler *This = impl_from_IOleObject(iface);
549 HRESULT hr = S_OK;
551 TRACE("(%p, %d, %p)\n", iface, dwWhichMoniker, pmk);
553 if (object_is_running(This))
555 start_object_call( This );
556 hr = IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
557 end_object_call( This );
560 return hr;
563 /************************************************************************
564 * DefaultHandler_GetMoniker (IOleObject)
566 * Delegate this request to the client site if we have one.
568 * See Windows documentation for more details on IOleObject methods.
570 static HRESULT WINAPI DefaultHandler_GetMoniker(
571 IOleObject* iface,
572 DWORD dwAssign,
573 DWORD dwWhichMoniker,
574 IMoniker** ppmk)
576 DefaultHandler *This = impl_from_IOleObject(iface);
577 HRESULT hr;
579 TRACE("(%p, %d, %d, %p)\n",
580 iface, dwAssign, dwWhichMoniker, ppmk);
582 if (object_is_running(This))
584 start_object_call( This );
585 hr = IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
586 ppmk);
587 end_object_call( This );
588 return hr;
591 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
592 if (This->clientSite)
594 return IOleClientSite_GetMoniker(This->clientSite,
595 dwAssign,
596 dwWhichMoniker,
597 ppmk);
601 return E_FAIL;
604 /************************************************************************
605 * DefaultHandler_InitFromData (IOleObject)
607 * This method is meaningless if the server is not running
609 * See Windows documentation for more details on IOleObject methods.
611 static HRESULT WINAPI DefaultHandler_InitFromData(
612 IOleObject* iface,
613 IDataObject* pDataObject,
614 BOOL fCreation,
615 DWORD dwReserved)
617 DefaultHandler *This = impl_from_IOleObject(iface);
618 HRESULT hr = OLE_E_NOTRUNNING;
620 TRACE("(%p, %p, %d, %d)\n",
621 iface, pDataObject, fCreation, dwReserved);
623 if (object_is_running(This))
625 start_object_call( This );
626 hr = IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
627 dwReserved);
628 end_object_call( This );
631 return hr;
634 /************************************************************************
635 * DefaultHandler_GetClipboardData (IOleObject)
637 * This method is meaningless if the server is not running
639 * See Windows documentation for more details on IOleObject methods.
641 static HRESULT WINAPI DefaultHandler_GetClipboardData(
642 IOleObject* iface,
643 DWORD dwReserved,
644 IDataObject** ppDataObject)
646 DefaultHandler *This = impl_from_IOleObject(iface);
647 HRESULT hr = OLE_E_NOTRUNNING;
649 TRACE("(%p, %d, %p)\n",
650 iface, dwReserved, ppDataObject);
652 if (object_is_running(This))
654 start_object_call( This );
655 hr = IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
656 ppDataObject);
657 end_object_call( This );
660 return hr;
663 static HRESULT WINAPI DefaultHandler_DoVerb(
664 IOleObject* iface,
665 LONG iVerb,
666 struct tagMSG* lpmsg,
667 IOleClientSite* pActiveSite,
668 LONG lindex,
669 HWND hwndParent,
670 LPCRECT lprcPosRect)
672 DefaultHandler *This = impl_from_IOleObject(iface);
673 IRunnableObject *pRunnableObj = &This->IRunnableObject_iface;
674 HRESULT hr;
676 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
678 hr = IRunnableObject_Run(pRunnableObj, NULL);
679 if (FAILED(hr)) return hr;
681 start_object_call( This );
682 hr = IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
683 lindex, hwndParent, lprcPosRect);
684 end_object_call( This );
686 return hr;
689 /************************************************************************
690 * DefaultHandler_EnumVerbs (IOleObject)
692 * The default handler implementation of this method simply delegates
693 * to OleRegEnumVerbs
695 * See Windows documentation for more details on IOleObject methods.
697 static HRESULT WINAPI DefaultHandler_EnumVerbs(
698 IOleObject* iface,
699 IEnumOLEVERB** ppEnumOleVerb)
701 DefaultHandler *This = impl_from_IOleObject(iface);
702 HRESULT hr = OLE_S_USEREG;
704 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
706 if (object_is_running(This))
708 start_object_call( This );
709 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
710 end_object_call( This );
713 if (hr == OLE_S_USEREG)
714 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
715 else
716 return hr;
719 static HRESULT WINAPI DefaultHandler_Update(
720 IOleObject* iface)
722 DefaultHandler *This = impl_from_IOleObject(iface);
723 HRESULT hr;
725 TRACE("(%p)\n", iface);
727 if (!object_is_running(This))
729 FIXME("Should run object\n");
730 return E_NOTIMPL;
733 start_object_call( This );
734 hr = IOleObject_Update(This->pOleDelegate);
735 end_object_call( This );
737 return hr;
740 /************************************************************************
741 * DefaultHandler_IsUpToDate (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_IsUpToDate(
748 IOleObject* iface)
750 DefaultHandler *This = impl_from_IOleObject(iface);
751 HRESULT hr = OLE_E_NOTRUNNING;
752 TRACE("(%p)\n", iface);
754 if (object_is_running(This))
756 start_object_call( This );
757 hr = IOleObject_IsUpToDate(This->pOleDelegate);
758 end_object_call( This );
761 return hr;
764 /************************************************************************
765 * DefaultHandler_GetUserClassID (IOleObject)
767 * TODO: Map to a new class ID if emulation is active.
769 * See Windows documentation for more details on IOleObject methods.
771 static HRESULT WINAPI DefaultHandler_GetUserClassID(
772 IOleObject* iface,
773 CLSID* pClsid)
775 DefaultHandler *This = impl_from_IOleObject(iface);
776 HRESULT hr;
778 TRACE("(%p, %p)\n", iface, pClsid);
780 if (object_is_running(This))
782 start_object_call( This );
783 hr = IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
784 end_object_call( This );
785 return hr;
788 if (!pClsid)
789 return E_POINTER;
791 *pClsid = This->clsid;
793 return S_OK;
796 /************************************************************************
797 * DefaultHandler_GetUserType (IOleObject)
799 * The default handler implementation of this method simply delegates
800 * to OleRegGetUserType
802 * See Windows documentation for more details on IOleObject methods.
804 static HRESULT WINAPI DefaultHandler_GetUserType(
805 IOleObject* iface,
806 DWORD dwFormOfType,
807 LPOLESTR* pszUserType)
809 DefaultHandler *This = impl_from_IOleObject(iface);
810 HRESULT hr;
812 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
813 if (object_is_running(This))
815 start_object_call( This );
816 hr = IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
817 end_object_call( This );
818 return hr;
821 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
824 /************************************************************************
825 * DefaultHandler_SetExtent (IOleObject)
827 * This method is meaningless if the server is not running
829 * See Windows documentation for more details on IOleObject methods.
831 static HRESULT WINAPI DefaultHandler_SetExtent(
832 IOleObject* iface,
833 DWORD dwDrawAspect,
834 SIZEL* psizel)
836 DefaultHandler *This = impl_from_IOleObject(iface);
837 HRESULT hr = OLE_E_NOTRUNNING;
839 TRACE("(%p, %x, (%d x %d))\n", iface,
840 dwDrawAspect, psizel->cx, psizel->cy);
842 if (object_is_running(This))
844 start_object_call( This );
845 hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
846 end_object_call( This );
849 return hr;
852 /************************************************************************
853 * DefaultHandler_GetExtent (IOleObject)
855 * The default handler's implementation of this method returns uses
856 * the cache to locate the aspect and extract the extent from it.
858 * See Windows documentation for more details on IOleObject methods.
860 static HRESULT WINAPI DefaultHandler_GetExtent(
861 IOleObject* iface,
862 DWORD dwDrawAspect,
863 SIZEL* psizel)
865 DVTARGETDEVICE* targetDevice;
866 IViewObject2* cacheView = NULL;
867 HRESULT hres;
869 DefaultHandler *This = impl_from_IOleObject(iface);
871 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
873 if (object_is_running(This))
875 start_object_call( This );
876 hres = IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
877 end_object_call( This );
878 return hres;
881 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
882 if (FAILED(hres))
883 return E_UNEXPECTED;
886 * Prepare the call to the cache's GetExtent method.
888 * Here we would build a valid DVTARGETDEVICE structure
889 * but, since we are calling into the data cache, we
890 * know its implementation and we'll skip this
891 * extra work until later.
893 targetDevice = NULL;
895 hres = IViewObject2_GetExtent(cacheView,
896 dwDrawAspect,
898 targetDevice,
899 psizel);
901 IViewObject2_Release(cacheView);
903 return hres;
906 /************************************************************************
907 * DefaultHandler_Advise (IOleObject)
909 * The default handler's implementation of this method simply
910 * delegates to the OleAdviseHolder.
912 * See Windows documentation for more details on IOleObject methods.
914 static HRESULT WINAPI DefaultHandler_Advise(
915 IOleObject* iface,
916 IAdviseSink* pAdvSink,
917 DWORD* pdwConnection)
919 HRESULT hres = S_OK;
920 DefaultHandler *This = impl_from_IOleObject(iface);
922 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
924 /* Make sure we have an advise holder before we start. */
925 if (!This->oleAdviseHolder)
926 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
928 if (SUCCEEDED(hres))
929 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
930 pAdvSink,
931 pdwConnection);
933 return hres;
936 /************************************************************************
937 * DefaultHandler_Unadvise (IOleObject)
939 * The default handler's implementation of this method simply
940 * delegates to the OleAdviseHolder.
942 * See Windows documentation for more details on IOleObject methods.
944 static HRESULT WINAPI DefaultHandler_Unadvise(
945 IOleObject* iface,
946 DWORD dwConnection)
948 DefaultHandler *This = impl_from_IOleObject(iface);
950 TRACE("(%p, %d)\n", iface, dwConnection);
953 * If we don't have an advise holder yet, it means we don't have
954 * a connection.
956 if (!This->oleAdviseHolder)
957 return OLE_E_NOCONNECTION;
959 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
960 dwConnection);
963 /************************************************************************
964 * DefaultHandler_EnumAdvise (IOleObject)
966 * The default handler's implementation of this method simply
967 * delegates to the OleAdviseHolder.
969 * See Windows documentation for more details on IOleObject methods.
971 static HRESULT WINAPI DefaultHandler_EnumAdvise(
972 IOleObject* iface,
973 IEnumSTATDATA** ppenumAdvise)
975 DefaultHandler *This = impl_from_IOleObject(iface);
977 TRACE("(%p, %p)\n", iface, ppenumAdvise);
979 if (!ppenumAdvise)
980 return E_POINTER;
982 *ppenumAdvise = NULL;
984 if (!This->oleAdviseHolder)
985 return S_OK;
987 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
990 /************************************************************************
991 * DefaultHandler_GetMiscStatus (IOleObject)
993 * The default handler's implementation of this method simply delegates
994 * to OleRegGetMiscStatus.
996 * See Windows documentation for more details on IOleObject methods.
998 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
999 IOleObject* iface,
1000 DWORD dwAspect,
1001 DWORD* pdwStatus)
1003 HRESULT hres;
1004 DefaultHandler *This = impl_from_IOleObject(iface);
1006 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
1008 if (object_is_running(This))
1010 start_object_call( This );
1011 hres = IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
1012 end_object_call( This );
1013 return hres;
1016 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
1018 if (FAILED(hres))
1019 *pdwStatus = 0;
1021 return hres;
1024 /************************************************************************
1025 * DefaultHandler_SetColorScheme (IOleObject)
1027 * This method is meaningless if the server is not running
1029 * See Windows documentation for more details on IOleObject methods.
1031 static HRESULT WINAPI DefaultHandler_SetColorScheme(
1032 IOleObject* iface,
1033 struct tagLOGPALETTE* pLogpal)
1035 DefaultHandler *This = impl_from_IOleObject(iface);
1036 HRESULT hr = OLE_E_NOTRUNNING;
1038 TRACE("(%p, %p))\n", iface, pLogpal);
1040 if (object_is_running(This))
1042 start_object_call( This );
1043 hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
1044 end_object_call( This );
1047 return hr;
1050 /*********************************************************
1051 * Methods implementation for the IDataObject part of
1052 * the DefaultHandler class.
1055 /************************************************************************
1056 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
1058 * See Windows documentation for more details on IUnknown methods.
1060 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
1061 IDataObject* iface,
1062 REFIID riid,
1063 void** ppvObject)
1065 DefaultHandler *This = impl_from_IDataObject(iface);
1067 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1070 /************************************************************************
1071 * DefaultHandler_IDataObject_AddRef (IUnknown)
1073 * See Windows documentation for more details on IUnknown methods.
1075 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
1076 IDataObject* iface)
1078 DefaultHandler *This = impl_from_IDataObject(iface);
1080 return IUnknown_AddRef(This->outerUnknown);
1083 /************************************************************************
1084 * DefaultHandler_IDataObject_Release (IUnknown)
1086 * See Windows documentation for more details on IUnknown methods.
1088 static ULONG WINAPI DefaultHandler_IDataObject_Release(
1089 IDataObject* iface)
1091 DefaultHandler *This = impl_from_IDataObject(iface);
1093 return IUnknown_Release(This->outerUnknown);
1096 /************************************************************************
1097 * DefaultHandler_GetData
1099 * Get Data from a source dataobject using format pformatetcIn->cfFormat
1100 * See Windows documentation for more details on GetData.
1101 * Default handler's implementation of this method delegates to the cache.
1103 static HRESULT WINAPI DefaultHandler_GetData(
1104 IDataObject* iface,
1105 LPFORMATETC pformatetcIn,
1106 STGMEDIUM* pmedium)
1108 IDataObject* cacheDataObject = NULL;
1109 HRESULT hres;
1111 DefaultHandler *This = impl_from_IDataObject(iface);
1113 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
1115 hres = IUnknown_QueryInterface(This->dataCache,
1116 &IID_IDataObject,
1117 (void**)&cacheDataObject);
1119 if (FAILED(hres))
1120 return E_UNEXPECTED;
1122 hres = IDataObject_GetData(cacheDataObject,
1123 pformatetcIn,
1124 pmedium);
1126 IDataObject_Release(cacheDataObject);
1128 if (hres == S_OK) return hres;
1130 if (object_is_running( This ))
1132 start_object_call(This);
1133 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1134 end_object_call(This);
1135 if (hres == S_OK) return hres;
1138 /* Query running state again, as the object may have closed during _GetData call */
1139 if (!object_is_running( This ))
1140 hres = OLE_E_NOTRUNNING;
1142 return hres;
1145 static HRESULT WINAPI DefaultHandler_GetDataHere(
1146 IDataObject* iface,
1147 LPFORMATETC pformatetc,
1148 STGMEDIUM* pmedium)
1150 FIXME(": Stub\n");
1151 return E_NOTIMPL;
1154 /************************************************************************
1155 * DefaultHandler_QueryGetData (IDataObject)
1157 * The default handler's implementation of this method delegates to
1158 * the cache.
1160 * See Windows documentation for more details on IDataObject methods.
1162 static HRESULT WINAPI DefaultHandler_QueryGetData(
1163 IDataObject* iface,
1164 LPFORMATETC pformatetc)
1166 IDataObject* cacheDataObject = NULL;
1167 HRESULT hres;
1169 DefaultHandler *This = impl_from_IDataObject(iface);
1171 TRACE("(%p, %p)\n", iface, pformatetc);
1173 hres = IUnknown_QueryInterface(This->dataCache,
1174 &IID_IDataObject,
1175 (void**)&cacheDataObject);
1177 if (FAILED(hres))
1178 return E_UNEXPECTED;
1180 hres = IDataObject_QueryGetData(cacheDataObject,
1181 pformatetc);
1183 IDataObject_Release(cacheDataObject);
1185 if (hres == S_OK) return hres;
1187 if (object_is_running( This ))
1189 start_object_call( This );
1190 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1191 end_object_call( This );
1192 if (hres == S_OK) return hres;
1195 /* Query running state again, as the object may have closed during _QueryGetData call */
1196 if (!object_is_running( This ))
1197 hres = OLE_E_NOTRUNNING;
1199 return hres;
1202 /************************************************************************
1203 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1205 * This method is meaningless if the server is not running
1207 * See Windows documentation for more details on IDataObject methods.
1209 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1210 IDataObject* iface,
1211 LPFORMATETC pformatetcIn,
1212 LPFORMATETC pformatetcOut)
1214 DefaultHandler *This = impl_from_IDataObject(iface);
1215 HRESULT hr;
1217 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1219 if (!object_is_running( This ))
1220 return OLE_E_NOTRUNNING;
1222 start_object_call( This );
1223 hr = IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1224 end_object_call( This );
1226 return hr;
1229 /************************************************************************
1230 * DefaultHandler_SetData (IDataObject)
1232 * The default handler's implementation of this method delegates to
1233 * the cache.
1235 * See Windows documentation for more details on IDataObject methods.
1237 static HRESULT WINAPI DefaultHandler_SetData(
1238 IDataObject* iface,
1239 LPFORMATETC pformatetc,
1240 STGMEDIUM* pmedium,
1241 BOOL fRelease)
1243 DefaultHandler *This = impl_from_IDataObject(iface);
1244 IDataObject* cacheDataObject = NULL;
1245 HRESULT hres;
1247 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1249 hres = IUnknown_QueryInterface(This->dataCache,
1250 &IID_IDataObject,
1251 (void**)&cacheDataObject);
1253 if (FAILED(hres))
1254 return E_UNEXPECTED;
1256 hres = IDataObject_SetData(cacheDataObject,
1257 pformatetc,
1258 pmedium,
1259 fRelease);
1261 IDataObject_Release(cacheDataObject);
1263 return hres;
1266 /************************************************************************
1267 * DefaultHandler_EnumFormatEtc (IDataObject)
1269 * The default handler's implementation of This method simply delegates
1270 * to OleRegEnumFormatEtc.
1272 * See Windows documentation for more details on IDataObject methods.
1274 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1275 IDataObject* iface,
1276 DWORD dwDirection,
1277 IEnumFORMATETC** ppenumFormatEtc)
1279 DefaultHandler *This = impl_from_IDataObject(iface);
1281 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1283 return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1286 /************************************************************************
1287 * DefaultHandler_DAdvise (IDataObject)
1289 * The default handler's implementation of this method simply
1290 * delegates to the DataAdviseHolder.
1292 * See Windows documentation for more details on IDataObject methods.
1294 static HRESULT WINAPI DefaultHandler_DAdvise(
1295 IDataObject* iface,
1296 FORMATETC* pformatetc,
1297 DWORD advf,
1298 IAdviseSink* pAdvSink,
1299 DWORD* pdwConnection)
1301 HRESULT hres = S_OK;
1302 DefaultHandler *This = impl_from_IDataObject(iface);
1304 TRACE("(%p, %p, %d, %p, %p)\n",
1305 iface, pformatetc, advf, pAdvSink, pdwConnection);
1307 /* Make sure we have a data advise holder before we start. */
1308 if (!This->dataAdviseHolder)
1310 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1311 if (SUCCEEDED(hres) && object_is_running( This ))
1313 start_object_call( This );
1314 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1315 end_object_call( This );
1319 if (SUCCEEDED(hres))
1320 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1321 iface,
1322 pformatetc,
1323 advf,
1324 pAdvSink,
1325 pdwConnection);
1327 return hres;
1330 /************************************************************************
1331 * DefaultHandler_DUnadvise (IDataObject)
1333 * The default handler's implementation of this method simply
1334 * delegates to the DataAdviseHolder.
1336 * See Windows documentation for more details on IDataObject methods.
1338 static HRESULT WINAPI DefaultHandler_DUnadvise(
1339 IDataObject* iface,
1340 DWORD dwConnection)
1342 DefaultHandler *This = impl_from_IDataObject(iface);
1344 TRACE("(%p, %d)\n", iface, dwConnection);
1347 * If we don't have a data advise holder yet, it means that
1348 * we don't have any connections..
1350 if (!This->dataAdviseHolder)
1351 return OLE_E_NOCONNECTION;
1353 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1354 dwConnection);
1357 /************************************************************************
1358 * DefaultHandler_EnumDAdvise (IDataObject)
1360 * The default handler's implementation of this method simply
1361 * delegates to the DataAdviseHolder.
1363 * See Windows documentation for more details on IDataObject methods.
1365 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1366 IDataObject* iface,
1367 IEnumSTATDATA** ppenumAdvise)
1369 DefaultHandler *This = impl_from_IDataObject(iface);
1371 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1373 if (!ppenumAdvise)
1374 return E_POINTER;
1376 *ppenumAdvise = NULL;
1378 /* If we have a data advise holder object, delegate. */
1379 if (This->dataAdviseHolder)
1380 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1381 ppenumAdvise);
1383 return S_OK;
1386 /*********************************************************
1387 * Methods implementation for the IRunnableObject part
1388 * of the DefaultHandler class.
1391 /************************************************************************
1392 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1394 * See Windows documentation for more details on IUnknown methods.
1396 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1397 IRunnableObject* iface,
1398 REFIID riid,
1399 void** ppvObject)
1401 DefaultHandler *This = impl_from_IRunnableObject(iface);
1403 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1406 /************************************************************************
1407 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1409 * See Windows documentation for more details on IUnknown methods.
1411 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1412 IRunnableObject* iface)
1414 DefaultHandler *This = impl_from_IRunnableObject(iface);
1416 return IUnknown_AddRef(This->outerUnknown);
1419 /************************************************************************
1420 * DefaultHandler_IRunnableObject_Release (IUnknown)
1422 * See Windows documentation for more details on IUnknown methods.
1424 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1425 IRunnableObject* iface)
1427 DefaultHandler *This = impl_from_IRunnableObject(iface);
1429 return IUnknown_Release(This->outerUnknown);
1432 /************************************************************************
1433 * DefaultHandler_GetRunningClass (IRunnableObject)
1435 * See Windows documentation for more details on IRunnableObject methods.
1437 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1438 IRunnableObject* iface,
1439 LPCLSID lpClsid)
1441 FIXME("()\n");
1442 return S_OK;
1445 static HRESULT WINAPI DefaultHandler_Run(
1446 IRunnableObject* iface,
1447 IBindCtx* pbc)
1449 DefaultHandler *This = impl_from_IRunnableObject(iface);
1450 HRESULT hr;
1451 IOleCacheControl *cache_ctrl;
1453 FIXME("(%p): semi-stub\n", pbc);
1455 /* already running? if so nothing to do */
1456 if (object_is_running(This))
1457 return S_OK;
1459 release_delegates(This);
1461 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
1462 &IID_IOleObject, (void **)&This->pOleDelegate);
1463 if (FAILED(hr))
1464 return hr;
1466 hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
1467 if (FAILED(hr)) goto fail;
1469 if (This->clientSite)
1471 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1472 if (FAILED(hr)) goto fail;
1475 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1476 (void **)&This->pPSDelegate);
1477 if (FAILED(hr)) goto fail;
1479 if (This->storage_state == storage_state_initialised)
1480 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1481 else if (This->storage_state == storage_state_loaded)
1482 hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1483 if (FAILED(hr)) goto fail;
1485 if (This->containerApp)
1487 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1488 This->containerObj);
1489 if (FAILED(hr)) goto fail;
1492 /* FIXME: do more stuff here:
1493 * - IOleObject_GetMiscStatus
1494 * - IOleObject_GetMoniker
1497 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1498 (void **)&This->pDataDelegate);
1499 if (FAILED(hr)) goto fail;
1501 This->object_state = object_state_running;
1503 if (This->dataAdviseHolder)
1505 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1506 if (FAILED(hr)) goto fail;
1509 hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
1510 if (FAILED(hr)) goto fail;
1511 hr = IOleCacheControl_OnRun( cache_ctrl, This->pDataDelegate );
1512 IOleCacheControl_Release( cache_ctrl );
1513 if (FAILED(hr)) goto fail;
1515 return hr;
1517 fail:
1518 DefaultHandler_Stop(This);
1519 return hr;
1522 /************************************************************************
1523 * DefaultHandler_IsRunning (IRunnableObject)
1525 * See Windows documentation for more details on IRunnableObject methods.
1527 static BOOL WINAPI DefaultHandler_IsRunning(
1528 IRunnableObject* iface)
1530 DefaultHandler *This = impl_from_IRunnableObject(iface);
1532 TRACE("()\n");
1534 if (This->object_state == object_state_running)
1535 return TRUE;
1536 else
1537 return FALSE;
1540 /************************************************************************
1541 * DefaultHandler_LockRunning (IRunnableObject)
1543 * See Windows documentation for more details on IRunnableObject methods.
1545 static HRESULT WINAPI DefaultHandler_LockRunning(
1546 IRunnableObject* iface,
1547 BOOL fLock,
1548 BOOL fLastUnlockCloses)
1550 FIXME("()\n");
1551 return S_OK;
1554 /************************************************************************
1555 * DefaultHandler_SetContainedObject (IRunnableObject)
1557 * See Windows documentation for more details on IRunnableObject methods.
1559 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1560 IRunnableObject* iface,
1561 BOOL fContained)
1563 FIXME("()\n");
1564 return S_OK;
1567 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1568 IAdviseSink *iface,
1569 REFIID riid,
1570 void **ppvObject)
1572 if (IsEqualIID(riid, &IID_IUnknown) ||
1573 IsEqualIID(riid, &IID_IAdviseSink))
1575 *ppvObject = iface;
1576 IAdviseSink_AddRef(iface);
1577 return S_OK;
1580 return E_NOINTERFACE;
1583 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1584 IAdviseSink *iface)
1586 DefaultHandler *This = impl_from_IAdviseSink(iface);
1588 return IUnknown_AddRef(&This->IUnknown_iface);
1591 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1592 IAdviseSink *iface)
1594 DefaultHandler *This = impl_from_IAdviseSink(iface);
1596 return IUnknown_Release(&This->IUnknown_iface);
1599 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1600 IAdviseSink *iface,
1601 FORMATETC *pFormatetc,
1602 STGMEDIUM *pStgmed)
1604 FIXME(": stub\n");
1607 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1608 IAdviseSink *iface,
1609 DWORD dwAspect,
1610 LONG lindex)
1612 FIXME(": stub\n");
1615 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1616 IAdviseSink *iface,
1617 IMoniker *pmk)
1619 DefaultHandler *This = impl_from_IAdviseSink(iface);
1621 TRACE("(%p)\n", pmk);
1623 if (This->oleAdviseHolder)
1624 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1627 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1628 IAdviseSink *iface)
1630 DefaultHandler *This = impl_from_IAdviseSink(iface);
1632 TRACE("()\n");
1634 if (This->oleAdviseHolder)
1635 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1638 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1639 IAdviseSink *iface)
1641 DefaultHandler *This = impl_from_IAdviseSink(iface);
1643 TRACE("()\n");
1645 if (This->oleAdviseHolder)
1646 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1648 if(!This->in_call)
1649 DefaultHandler_Stop(This);
1650 else
1652 TRACE("OnClose during call. Deferring shutdown\n");
1653 This->object_state = object_state_deferred_close;
1657 /************************************************************************
1658 * DefaultHandler_IPersistStorage_QueryInterface
1661 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1662 IPersistStorage* iface,
1663 REFIID riid,
1664 void** ppvObject)
1666 DefaultHandler *This = impl_from_IPersistStorage(iface);
1668 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1671 /************************************************************************
1672 * DefaultHandler_IPersistStorage_AddRef
1675 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1676 IPersistStorage* iface)
1678 DefaultHandler *This = impl_from_IPersistStorage(iface);
1680 return IUnknown_AddRef(This->outerUnknown);
1683 /************************************************************************
1684 * DefaultHandler_IPersistStorage_Release
1687 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1688 IPersistStorage* iface)
1690 DefaultHandler *This = impl_from_IPersistStorage(iface);
1692 return IUnknown_Release(This->outerUnknown);
1695 /************************************************************************
1696 * DefaultHandler_IPersistStorage_GetClassID
1699 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1700 IPersistStorage* iface,
1701 CLSID* clsid)
1703 DefaultHandler *This = impl_from_IPersistStorage(iface);
1704 HRESULT hr;
1706 TRACE("(%p)->(%p)\n", iface, clsid);
1708 if(object_is_running(This))
1710 start_object_call( This );
1711 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1712 end_object_call( This );
1714 else
1715 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1717 return hr;
1720 /************************************************************************
1721 * DefaultHandler_IPersistStorage_IsDirty
1724 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1725 IPersistStorage* iface)
1727 DefaultHandler *This = impl_from_IPersistStorage(iface);
1728 HRESULT hr;
1730 TRACE("(%p)\n", iface);
1732 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1733 if(hr != S_FALSE) return hr;
1735 if(object_is_running(This))
1737 start_object_call( This );
1738 hr = IPersistStorage_IsDirty(This->pPSDelegate);
1739 end_object_call( This );
1742 return hr;
1745 /***********************************************************************
1747 * The format of '\1Ole' stream is as follows:
1749 * DWORD Version == 0x02000001
1750 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1751 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1752 * supplied by the app that creates the data structure. May be
1753 * ignored on processing].
1755 * DWORD Reserved == 0
1756 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1757 * CLSID clsid - class id of object capable of processing the moniker
1758 * BYTE data[] - moniker data for a link
1761 typedef struct
1763 DWORD version;
1764 DWORD flags;
1765 DWORD link_update_opt;
1766 DWORD res;
1767 DWORD moniker_size;
1768 } ole_stream_header_t;
1769 static const DWORD ole_stream_version = 0x02000001;
1771 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1773 IStream *stream;
1774 HRESULT hr;
1776 hr = IStorage_OpenStream(storage, L"\1Ole", NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1778 if(SUCCEEDED(hr))
1780 DWORD read;
1781 ole_stream_header_t header;
1783 hr = IStream_Read(stream, &header, sizeof(header), &read);
1784 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1786 if(header.flags & 1)
1788 /* FIXME: Read the moniker and deal with the link */
1789 FIXME("Linked objects are not supported yet\n");
1792 else
1794 WARN("Incorrect OleStream header\n");
1795 hr = DV_E_CLIPFORMAT;
1797 IStream_Release(stream);
1799 else
1800 hr = STORAGE_CreateOleStream(storage, 0);
1802 return hr;
1805 /************************************************************************
1806 * DefaultHandler_IPersistStorage_InitNew
1809 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1810 IPersistStorage* iface,
1811 IStorage* pStg)
1813 DefaultHandler *This = impl_from_IPersistStorage(iface);
1814 HRESULT hr;
1816 TRACE("(%p)->(%p)\n", iface, pStg);
1817 hr = STORAGE_CreateOleStream(pStg, 0);
1818 if (hr != S_OK) return hr;
1820 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1822 if(SUCCEEDED(hr) && object_is_running(This))
1824 start_object_call( This );
1825 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1826 end_object_call( This );
1829 if(SUCCEEDED(hr))
1831 IStorage_AddRef(pStg);
1832 This->storage = pStg;
1833 This->storage_state = storage_state_initialised;
1836 return hr;
1840 /************************************************************************
1841 * DefaultHandler_IPersistStorage_Load
1844 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1845 IPersistStorage* iface,
1846 IStorage* pStg)
1848 DefaultHandler *This = impl_from_IPersistStorage(iface);
1849 HRESULT hr;
1851 TRACE("(%p)->(%p)\n", iface, pStg);
1853 hr = load_ole_stream(This, pStg);
1855 if(SUCCEEDED(hr))
1856 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1858 if(SUCCEEDED(hr) && object_is_running(This))
1860 start_object_call( This );
1861 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1862 end_object_call( This );
1865 if(SUCCEEDED(hr))
1867 IStorage_AddRef(pStg);
1868 This->storage = pStg;
1869 This->storage_state = storage_state_loaded;
1871 return hr;
1875 /************************************************************************
1876 * DefaultHandler_IPersistStorage_Save
1879 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1880 IPersistStorage* iface,
1881 IStorage* pStgSave,
1882 BOOL fSameAsLoad)
1884 DefaultHandler *This = impl_from_IPersistStorage(iface);
1885 HRESULT hr;
1887 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1889 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1890 if(SUCCEEDED(hr) && object_is_running(This))
1892 start_object_call( This );
1893 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1894 end_object_call( This );
1897 return hr;
1901 /************************************************************************
1902 * DefaultHandler_IPersistStorage_SaveCompleted
1905 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1906 IPersistStorage* iface,
1907 IStorage* pStgNew)
1909 DefaultHandler *This = impl_from_IPersistStorage(iface);
1910 HRESULT hr;
1912 TRACE("(%p)->(%p)\n", iface, pStgNew);
1914 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1916 if(SUCCEEDED(hr) && object_is_running(This))
1918 start_object_call( This );
1919 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1920 end_object_call( This );
1923 if(pStgNew)
1925 IStorage_AddRef(pStgNew);
1926 if(This->storage) IStorage_Release(This->storage);
1927 This->storage = pStgNew;
1928 This->storage_state = storage_state_loaded;
1931 return hr;
1935 /************************************************************************
1936 * DefaultHandler_IPersistStorage_HandsOffStorage
1939 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1940 IPersistStorage* iface)
1942 DefaultHandler *This = impl_from_IPersistStorage(iface);
1943 HRESULT hr;
1945 TRACE("(%p)\n", iface);
1947 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1949 if(SUCCEEDED(hr) && object_is_running(This))
1951 start_object_call( This );
1952 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1953 end_object_call( This );
1956 if(This->storage) IStorage_Release(This->storage);
1957 This->storage = NULL;
1958 This->storage_state = storage_state_uninitialised;
1960 return hr;
1965 * Virtual function tables for the DefaultHandler class.
1967 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1969 DefaultHandler_QueryInterface,
1970 DefaultHandler_AddRef,
1971 DefaultHandler_Release,
1972 DefaultHandler_SetClientSite,
1973 DefaultHandler_GetClientSite,
1974 DefaultHandler_SetHostNames,
1975 DefaultHandler_Close,
1976 DefaultHandler_SetMoniker,
1977 DefaultHandler_GetMoniker,
1978 DefaultHandler_InitFromData,
1979 DefaultHandler_GetClipboardData,
1980 DefaultHandler_DoVerb,
1981 DefaultHandler_EnumVerbs,
1982 DefaultHandler_Update,
1983 DefaultHandler_IsUpToDate,
1984 DefaultHandler_GetUserClassID,
1985 DefaultHandler_GetUserType,
1986 DefaultHandler_SetExtent,
1987 DefaultHandler_GetExtent,
1988 DefaultHandler_Advise,
1989 DefaultHandler_Unadvise,
1990 DefaultHandler_EnumAdvise,
1991 DefaultHandler_GetMiscStatus,
1992 DefaultHandler_SetColorScheme
1995 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1997 DefaultHandler_NDIUnknown_QueryInterface,
1998 DefaultHandler_NDIUnknown_AddRef,
1999 DefaultHandler_NDIUnknown_Release,
2002 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
2004 DefaultHandler_IDataObject_QueryInterface,
2005 DefaultHandler_IDataObject_AddRef,
2006 DefaultHandler_IDataObject_Release,
2007 DefaultHandler_GetData,
2008 DefaultHandler_GetDataHere,
2009 DefaultHandler_QueryGetData,
2010 DefaultHandler_GetCanonicalFormatEtc,
2011 DefaultHandler_SetData,
2012 DefaultHandler_EnumFormatEtc,
2013 DefaultHandler_DAdvise,
2014 DefaultHandler_DUnadvise,
2015 DefaultHandler_EnumDAdvise
2018 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
2020 DefaultHandler_IRunnableObject_QueryInterface,
2021 DefaultHandler_IRunnableObject_AddRef,
2022 DefaultHandler_IRunnableObject_Release,
2023 DefaultHandler_GetRunningClass,
2024 DefaultHandler_Run,
2025 DefaultHandler_IsRunning,
2026 DefaultHandler_LockRunning,
2027 DefaultHandler_SetContainedObject
2030 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
2032 DefaultHandler_IAdviseSink_QueryInterface,
2033 DefaultHandler_IAdviseSink_AddRef,
2034 DefaultHandler_IAdviseSink_Release,
2035 DefaultHandler_IAdviseSink_OnDataChange,
2036 DefaultHandler_IAdviseSink_OnViewChange,
2037 DefaultHandler_IAdviseSink_OnRename,
2038 DefaultHandler_IAdviseSink_OnSave,
2039 DefaultHandler_IAdviseSink_OnClose
2042 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
2044 DefaultHandler_IPersistStorage_QueryInterface,
2045 DefaultHandler_IPersistStorage_AddRef,
2046 DefaultHandler_IPersistStorage_Release,
2047 DefaultHandler_IPersistStorage_GetClassID,
2048 DefaultHandler_IPersistStorage_IsDirty,
2049 DefaultHandler_IPersistStorage_InitNew,
2050 DefaultHandler_IPersistStorage_Load,
2051 DefaultHandler_IPersistStorage_Save,
2052 DefaultHandler_IPersistStorage_SaveCompleted,
2053 DefaultHandler_IPersistStorage_HandsOffStorage
2056 /*********************************************************
2057 * Methods implementation for the DefaultHandler class.
2059 static DefaultHandler* DefaultHandler_Construct(
2060 REFCLSID clsid,
2061 LPUNKNOWN pUnkOuter,
2062 DWORD flags,
2063 IClassFactory *pCF)
2065 DefaultHandler* This = NULL;
2066 HRESULT hr;
2068 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
2070 if (!This)
2071 return This;
2073 This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable;
2074 This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable;
2075 This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable;
2076 This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable;
2077 This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable;
2078 This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable;
2080 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) != 0;
2083 * Start with one reference count. The caller of this function
2084 * must release the interface pointer when it is done.
2086 This->ref = 1;
2089 * Initialize the outer unknown
2090 * We don't keep a reference on the outer unknown since, the way
2091 * aggregation works, our lifetime is at least as large as its
2092 * lifetime.
2094 if (!pUnkOuter)
2095 pUnkOuter = &This->IUnknown_iface;
2097 This->outerUnknown = pUnkOuter;
2100 * Create a datacache object.
2101 * We aggregate with the datacache. Make sure we pass our outer
2102 * unknown as the datacache's outer unknown.
2104 hr = CreateDataCache(This->outerUnknown,
2105 clsid,
2106 &IID_IUnknown,
2107 (void**)&This->dataCache);
2108 if(SUCCEEDED(hr))
2110 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
2111 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
2112 * reference on the outer object */
2113 if (SUCCEEDED(hr))
2114 IUnknown_Release(This->outerUnknown);
2115 else
2116 IUnknown_Release(This->dataCache);
2118 if(FAILED(hr))
2120 ERR("Unexpected error creating data cache\n");
2121 HeapFree(GetProcessHeap(), 0, This);
2122 return NULL;
2125 This->clsid = *clsid;
2126 This->clientSite = NULL;
2127 This->oleAdviseHolder = NULL;
2128 This->dataAdviseHolder = NULL;
2129 This->containerApp = NULL;
2130 This->containerObj = NULL;
2131 This->pOleDelegate = NULL;
2132 This->pPSDelegate = NULL;
2133 This->pDataDelegate = NULL;
2134 This->object_state = object_state_not_running;
2135 This->in_call = 0;
2137 This->dwAdvConn = 0;
2138 This->storage = NULL;
2139 This->storage_state = storage_state_uninitialised;
2141 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
2143 HRESULT hr;
2144 This->pCFObject = NULL;
2145 if (pCF)
2146 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
2147 else
2148 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
2149 &IID_IOleObject, (void **)&This->pOleDelegate);
2150 if (SUCCEEDED(hr))
2151 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
2152 if (SUCCEEDED(hr))
2153 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
2154 if (SUCCEEDED(hr))
2155 This->object_state = object_state_running;
2156 if (FAILED(hr))
2157 WARN("object creation failed with error %08x\n", hr);
2159 else
2161 This->pCFObject = pCF;
2162 if (pCF) IClassFactory_AddRef(pCF);
2165 return This;
2168 static void DefaultHandler_Destroy(
2169 DefaultHandler* This)
2171 TRACE("(%p)\n", This);
2173 /* AddRef/Release may be called on this object during destruction.
2174 * Prevent the object being destroyed recursively by artificially raising
2175 * the reference count. */
2176 This->ref = 10000;
2178 /* release delegates */
2179 DefaultHandler_Stop(This);
2181 HeapFree( GetProcessHeap(), 0, This->containerApp );
2182 This->containerApp = NULL;
2183 HeapFree( GetProcessHeap(), 0, This->containerObj );
2184 This->containerObj = NULL;
2186 if (This->dataCache)
2188 /* to balance out the release of dataCache_PersistStg which will result
2189 * in a reference being released from the outer unknown */
2190 IUnknown_AddRef(This->outerUnknown);
2191 IPersistStorage_Release(This->dataCache_PersistStg);
2192 IUnknown_Release(This->dataCache);
2193 This->dataCache_PersistStg = NULL;
2194 This->dataCache = NULL;
2197 if (This->clientSite)
2199 IOleClientSite_Release(This->clientSite);
2200 This->clientSite = NULL;
2203 if (This->oleAdviseHolder)
2205 IOleAdviseHolder_Release(This->oleAdviseHolder);
2206 This->oleAdviseHolder = NULL;
2209 if (This->dataAdviseHolder)
2211 IDataAdviseHolder_Release(This->dataAdviseHolder);
2212 This->dataAdviseHolder = NULL;
2215 if (This->storage)
2217 IStorage_Release(This->storage);
2218 This->storage = NULL;
2221 if (This->pCFObject)
2223 IClassFactory_Release(This->pCFObject);
2224 This->pCFObject = NULL;
2227 HeapFree(GetProcessHeap(), 0, This);
2230 /******************************************************************************
2231 * OleCreateEmbeddingHelper [OLE32.@]
2233 HRESULT WINAPI OleCreateEmbeddingHelper(
2234 REFCLSID clsid,
2235 LPUNKNOWN pUnkOuter,
2236 DWORD flags,
2237 IClassFactory *pCF,
2238 REFIID riid,
2239 LPVOID* ppvObj)
2241 DefaultHandler* newHandler = NULL;
2242 HRESULT hr = S_OK;
2244 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2246 if (!ppvObj)
2247 return E_POINTER;
2249 *ppvObj = NULL;
2252 * If This handler is constructed for aggregation, make sure
2253 * the caller is requesting the IUnknown interface.
2254 * This is necessary because it's the only time the non-delegating
2255 * IUnknown pointer can be returned to the outside.
2257 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2258 return CLASS_E_NOAGGREGATION;
2261 * Try to construct a new instance of the class.
2263 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2265 if (!newHandler)
2266 return E_OUTOFMEMORY;
2269 * Make sure it supports the interface required by the caller.
2271 hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj);
2274 * Release the reference obtained in the constructor. If
2275 * the QueryInterface was unsuccessful, it will free the class.
2277 IUnknown_Release(&newHandler->IUnknown_iface);
2279 return hr;
2283 /******************************************************************************
2284 * OleCreateDefaultHandler [OLE32.@]
2286 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
2287 REFIID riid, LPVOID* ppvObj)
2289 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
2290 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
2291 NULL, riid, ppvObj);
2294 typedef struct HandlerCF
2296 IClassFactory IClassFactory_iface;
2297 LONG refs;
2298 CLSID clsid;
2299 } HandlerCF;
2301 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
2303 return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
2306 static HRESULT WINAPI
2307 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
2309 *ppv = NULL;
2310 if (IsEqualIID(riid,&IID_IUnknown) ||
2311 IsEqualIID(riid,&IID_IClassFactory))
2313 *ppv = iface;
2314 IClassFactory_AddRef(iface);
2315 return S_OK;
2317 return E_NOINTERFACE;
2320 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
2322 HandlerCF *This = impl_from_IClassFactory(iface);
2323 return InterlockedIncrement(&This->refs);
2326 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
2328 HandlerCF *This = impl_from_IClassFactory(iface);
2329 ULONG refs = InterlockedDecrement(&This->refs);
2330 if (!refs)
2331 HeapFree(GetProcessHeap(), 0, This);
2332 return refs;
2335 static HRESULT WINAPI
2336 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
2337 REFIID riid, LPVOID *ppv)
2339 HandlerCF *This = impl_from_IClassFactory(iface);
2340 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
2343 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
2345 FIXME("(%d), stub!\n",fLock);
2346 return S_OK;
2349 static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
2350 HandlerCF_QueryInterface,
2351 HandlerCF_AddRef,
2352 HandlerCF_Release,
2353 HandlerCF_CreateInstance,
2354 HandlerCF_LockServer
2357 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
2359 HRESULT hr;
2360 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2361 if (!This) return E_OUTOFMEMORY;
2362 This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
2363 This->refs = 0;
2364 This->clsid = *rclsid;
2366 hr = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv);
2367 if (FAILED(hr))
2368 HeapFree(GetProcessHeap(), 0, This);
2370 return hr;