include: Add STORAGE_HOTPLUG_INFO structure.
[wine.git] / dlls / ole32 / defaulthandler.c
blobb69a054b572f2faea9af6661f4bd1ebf710ee886
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("%ld\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, %ld, %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, %ld, %ld, %p.\n", iface, dwAssign, dwWhichMoniker, ppmk);
581 if (object_is_running(This))
583 start_object_call( This );
584 hr = IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
585 ppmk);
586 end_object_call( This );
587 return hr;
590 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
591 if (This->clientSite)
593 return IOleClientSite_GetMoniker(This->clientSite,
594 dwAssign,
595 dwWhichMoniker,
596 ppmk);
600 return E_FAIL;
603 /************************************************************************
604 * DefaultHandler_InitFromData (IOleObject)
606 * This method is meaningless if the server is not running
608 * See Windows documentation for more details on IOleObject methods.
610 static HRESULT WINAPI DefaultHandler_InitFromData(
611 IOleObject* iface,
612 IDataObject* pDataObject,
613 BOOL fCreation,
614 DWORD dwReserved)
616 DefaultHandler *This = impl_from_IOleObject(iface);
617 HRESULT hr = OLE_E_NOTRUNNING;
619 TRACE("%p, %p, %d, %ld.\n", iface, pDataObject, fCreation, dwReserved);
621 if (object_is_running(This))
623 start_object_call( This );
624 hr = IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
625 dwReserved);
626 end_object_call( This );
629 return hr;
632 /************************************************************************
633 * DefaultHandler_GetClipboardData (IOleObject)
635 * This method is meaningless if the server is not running
637 * See Windows documentation for more details on IOleObject methods.
639 static HRESULT WINAPI DefaultHandler_GetClipboardData(
640 IOleObject* iface,
641 DWORD dwReserved,
642 IDataObject** ppDataObject)
644 DefaultHandler *This = impl_from_IOleObject(iface);
645 HRESULT hr = OLE_E_NOTRUNNING;
647 TRACE("%p, %ld, %p.\n", iface, dwReserved, ppDataObject);
649 if (object_is_running(This))
651 start_object_call( This );
652 hr = IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
653 ppDataObject);
654 end_object_call( This );
657 return hr;
660 static HRESULT WINAPI DefaultHandler_DoVerb(
661 IOleObject* iface,
662 LONG iVerb,
663 struct tagMSG* lpmsg,
664 IOleClientSite* pActiveSite,
665 LONG lindex,
666 HWND hwndParent,
667 LPCRECT lprcPosRect)
669 DefaultHandler *This = impl_from_IOleObject(iface);
670 IRunnableObject *pRunnableObj = &This->IRunnableObject_iface;
671 HRESULT hr;
673 TRACE("%ld, %p, %p, %ld, %p, %s.\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
675 hr = IRunnableObject_Run(pRunnableObj, NULL);
676 if (FAILED(hr)) return hr;
678 start_object_call( This );
679 hr = IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
680 lindex, hwndParent, lprcPosRect);
681 end_object_call( This );
683 return hr;
686 /************************************************************************
687 * DefaultHandler_EnumVerbs (IOleObject)
689 * The default handler implementation of this method simply delegates
690 * to OleRegEnumVerbs
692 * See Windows documentation for more details on IOleObject methods.
694 static HRESULT WINAPI DefaultHandler_EnumVerbs(
695 IOleObject* iface,
696 IEnumOLEVERB** ppEnumOleVerb)
698 DefaultHandler *This = impl_from_IOleObject(iface);
699 HRESULT hr = OLE_S_USEREG;
701 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
703 if (object_is_running(This))
705 start_object_call( This );
706 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
707 end_object_call( This );
710 if (hr == OLE_S_USEREG)
711 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
712 else
713 return hr;
716 static HRESULT WINAPI DefaultHandler_Update(
717 IOleObject* iface)
719 DefaultHandler *This = impl_from_IOleObject(iface);
720 HRESULT hr;
722 TRACE("(%p)\n", iface);
724 if (!object_is_running(This))
726 FIXME("Should run object\n");
727 return E_NOTIMPL;
730 start_object_call( This );
731 hr = IOleObject_Update(This->pOleDelegate);
732 end_object_call( This );
734 return hr;
737 /************************************************************************
738 * DefaultHandler_IsUpToDate (IOleObject)
740 * This method is meaningless if the server is not running
742 * See Windows documentation for more details on IOleObject methods.
744 static HRESULT WINAPI DefaultHandler_IsUpToDate(
745 IOleObject* iface)
747 DefaultHandler *This = impl_from_IOleObject(iface);
748 HRESULT hr = OLE_E_NOTRUNNING;
749 TRACE("(%p)\n", iface);
751 if (object_is_running(This))
753 start_object_call( This );
754 hr = IOleObject_IsUpToDate(This->pOleDelegate);
755 end_object_call( This );
758 return hr;
761 /************************************************************************
762 * DefaultHandler_GetUserClassID (IOleObject)
764 * TODO: Map to a new class ID if emulation is active.
766 * See Windows documentation for more details on IOleObject methods.
768 static HRESULT WINAPI DefaultHandler_GetUserClassID(
769 IOleObject* iface,
770 CLSID* pClsid)
772 DefaultHandler *This = impl_from_IOleObject(iface);
773 HRESULT hr;
775 TRACE("(%p, %p)\n", iface, pClsid);
777 if (object_is_running(This))
779 start_object_call( This );
780 hr = IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
781 end_object_call( This );
782 return hr;
785 if (!pClsid)
786 return E_POINTER;
788 *pClsid = This->clsid;
790 return S_OK;
793 /************************************************************************
794 * DefaultHandler_GetUserType (IOleObject)
796 * The default handler implementation of this method simply delegates
797 * to OleRegGetUserType
799 * See Windows documentation for more details on IOleObject methods.
801 static HRESULT WINAPI DefaultHandler_GetUserType(
802 IOleObject* iface,
803 DWORD dwFormOfType,
804 LPOLESTR* pszUserType)
806 DefaultHandler *This = impl_from_IOleObject(iface);
807 HRESULT hr;
809 TRACE("%p, %ld, %p.\n", iface, dwFormOfType, pszUserType);
810 if (object_is_running(This))
812 start_object_call( This );
813 hr = IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
814 end_object_call( This );
815 return hr;
818 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
821 /************************************************************************
822 * DefaultHandler_SetExtent (IOleObject)
824 * This method is meaningless if the server is not running
826 * See Windows documentation for more details on IOleObject methods.
828 static HRESULT WINAPI DefaultHandler_SetExtent(
829 IOleObject* iface,
830 DWORD dwDrawAspect,
831 SIZEL* psizel)
833 DefaultHandler *This = impl_from_IOleObject(iface);
834 HRESULT hr = OLE_E_NOTRUNNING;
836 TRACE("%p, %lx, (%ld x %ld))\n", iface, dwDrawAspect, psizel->cx, psizel->cy);
838 if (object_is_running(This))
840 start_object_call( This );
841 hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
842 end_object_call( This );
845 return hr;
848 /************************************************************************
849 * DefaultHandler_GetExtent (IOleObject)
851 * The default handler's implementation of this method returns uses
852 * the cache to locate the aspect and extract the extent from it.
854 * See Windows documentation for more details on IOleObject methods.
856 static HRESULT WINAPI DefaultHandler_GetExtent(
857 IOleObject* iface,
858 DWORD dwDrawAspect,
859 SIZEL* psizel)
861 DVTARGETDEVICE* targetDevice;
862 IViewObject2* cacheView = NULL;
863 HRESULT hres;
865 DefaultHandler *This = impl_from_IOleObject(iface);
867 TRACE("%p, %lx, %p.\n", iface, dwDrawAspect, psizel);
869 if (object_is_running(This))
871 start_object_call( This );
872 hres = IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
873 end_object_call( This );
874 return hres;
877 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
878 if (FAILED(hres))
879 return E_UNEXPECTED;
882 * Prepare the call to the cache's GetExtent method.
884 * Here we would build a valid DVTARGETDEVICE structure
885 * but, since we are calling into the data cache, we
886 * know its implementation and we'll skip this
887 * extra work until later.
889 targetDevice = NULL;
891 hres = IViewObject2_GetExtent(cacheView,
892 dwDrawAspect,
894 targetDevice,
895 psizel);
897 IViewObject2_Release(cacheView);
899 return hres;
902 /************************************************************************
903 * DefaultHandler_Advise (IOleObject)
905 * The default handler's implementation of this method simply
906 * delegates to the OleAdviseHolder.
908 * See Windows documentation for more details on IOleObject methods.
910 static HRESULT WINAPI DefaultHandler_Advise(
911 IOleObject* iface,
912 IAdviseSink* pAdvSink,
913 DWORD* pdwConnection)
915 HRESULT hres = S_OK;
916 DefaultHandler *This = impl_from_IOleObject(iface);
918 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
920 /* Make sure we have an advise holder before we start. */
921 if (!This->oleAdviseHolder)
922 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
924 if (SUCCEEDED(hres))
925 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
926 pAdvSink,
927 pdwConnection);
929 return hres;
932 /************************************************************************
933 * DefaultHandler_Unadvise (IOleObject)
935 * The default handler's implementation of this method simply
936 * delegates to the OleAdviseHolder.
938 * See Windows documentation for more details on IOleObject methods.
940 static HRESULT WINAPI DefaultHandler_Unadvise(
941 IOleObject* iface,
942 DWORD dwConnection)
944 DefaultHandler *This = impl_from_IOleObject(iface);
946 TRACE("%p, %ld.\n", iface, dwConnection);
949 * If we don't have an advise holder yet, it means we don't have
950 * a connection.
952 if (!This->oleAdviseHolder)
953 return OLE_E_NOCONNECTION;
955 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
956 dwConnection);
959 /************************************************************************
960 * DefaultHandler_EnumAdvise (IOleObject)
962 * The default handler's implementation of this method simply
963 * delegates to the OleAdviseHolder.
965 * See Windows documentation for more details on IOleObject methods.
967 static HRESULT WINAPI DefaultHandler_EnumAdvise(
968 IOleObject* iface,
969 IEnumSTATDATA** ppenumAdvise)
971 DefaultHandler *This = impl_from_IOleObject(iface);
973 TRACE("(%p, %p)\n", iface, ppenumAdvise);
975 if (!ppenumAdvise)
976 return E_POINTER;
978 *ppenumAdvise = NULL;
980 if (!This->oleAdviseHolder)
981 return S_OK;
983 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
986 /************************************************************************
987 * DefaultHandler_GetMiscStatus (IOleObject)
989 * The default handler's implementation of this method simply delegates
990 * to OleRegGetMiscStatus.
992 * See Windows documentation for more details on IOleObject methods.
994 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
995 IOleObject* iface,
996 DWORD dwAspect,
997 DWORD* pdwStatus)
999 HRESULT hres;
1000 DefaultHandler *This = impl_from_IOleObject(iface);
1002 TRACE("%p, %lx, %p.\n", iface, dwAspect, pdwStatus);
1004 if (object_is_running(This))
1006 start_object_call( This );
1007 hres = IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
1008 end_object_call( This );
1009 return hres;
1012 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
1014 if (FAILED(hres))
1015 *pdwStatus = 0;
1017 return hres;
1020 /************************************************************************
1021 * DefaultHandler_SetColorScheme (IOleObject)
1023 * This method is meaningless if the server is not running
1025 * See Windows documentation for more details on IOleObject methods.
1027 static HRESULT WINAPI DefaultHandler_SetColorScheme(
1028 IOleObject* iface,
1029 struct tagLOGPALETTE* pLogpal)
1031 DefaultHandler *This = impl_from_IOleObject(iface);
1032 HRESULT hr = OLE_E_NOTRUNNING;
1034 TRACE("(%p, %p))\n", iface, pLogpal);
1036 if (object_is_running(This))
1038 start_object_call( This );
1039 hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
1040 end_object_call( This );
1043 return hr;
1046 /*********************************************************
1047 * Methods implementation for the IDataObject part of
1048 * the DefaultHandler class.
1051 /************************************************************************
1052 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
1054 * See Windows documentation for more details on IUnknown methods.
1056 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
1057 IDataObject* iface,
1058 REFIID riid,
1059 void** ppvObject)
1061 DefaultHandler *This = impl_from_IDataObject(iface);
1063 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1066 /************************************************************************
1067 * DefaultHandler_IDataObject_AddRef (IUnknown)
1069 * See Windows documentation for more details on IUnknown methods.
1071 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
1072 IDataObject* iface)
1074 DefaultHandler *This = impl_from_IDataObject(iface);
1076 return IUnknown_AddRef(This->outerUnknown);
1079 /************************************************************************
1080 * DefaultHandler_IDataObject_Release (IUnknown)
1082 * See Windows documentation for more details on IUnknown methods.
1084 static ULONG WINAPI DefaultHandler_IDataObject_Release(
1085 IDataObject* iface)
1087 DefaultHandler *This = impl_from_IDataObject(iface);
1089 return IUnknown_Release(This->outerUnknown);
1092 /************************************************************************
1093 * DefaultHandler_GetData
1095 * Get Data from a source dataobject using format pformatetcIn->cfFormat
1096 * See Windows documentation for more details on GetData.
1097 * Default handler's implementation of this method delegates to the cache.
1099 static HRESULT WINAPI DefaultHandler_GetData(
1100 IDataObject* iface,
1101 LPFORMATETC pformatetcIn,
1102 STGMEDIUM* pmedium)
1104 IDataObject* cacheDataObject = NULL;
1105 HRESULT hres;
1107 DefaultHandler *This = impl_from_IDataObject(iface);
1109 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
1111 hres = IUnknown_QueryInterface(This->dataCache,
1112 &IID_IDataObject,
1113 (void**)&cacheDataObject);
1115 if (FAILED(hres))
1116 return E_UNEXPECTED;
1118 hres = IDataObject_GetData(cacheDataObject,
1119 pformatetcIn,
1120 pmedium);
1122 IDataObject_Release(cacheDataObject);
1124 if (hres == S_OK) return hres;
1126 if (object_is_running( This ))
1128 start_object_call(This);
1129 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1130 end_object_call(This);
1131 if (hres == S_OK) return hres;
1134 /* Query running state again, as the object may have closed during _GetData call */
1135 if (!object_is_running( This ))
1136 hres = OLE_E_NOTRUNNING;
1138 return hres;
1141 static HRESULT WINAPI DefaultHandler_GetDataHere(
1142 IDataObject* iface,
1143 LPFORMATETC pformatetc,
1144 STGMEDIUM* pmedium)
1146 FIXME(": Stub\n");
1147 return E_NOTIMPL;
1150 /************************************************************************
1151 * DefaultHandler_QueryGetData (IDataObject)
1153 * The default handler's implementation of this method delegates to
1154 * the cache.
1156 * See Windows documentation for more details on IDataObject methods.
1158 static HRESULT WINAPI DefaultHandler_QueryGetData(
1159 IDataObject* iface,
1160 LPFORMATETC pformatetc)
1162 IDataObject* cacheDataObject = NULL;
1163 HRESULT hres;
1165 DefaultHandler *This = impl_from_IDataObject(iface);
1167 TRACE("(%p, %p)\n", iface, pformatetc);
1169 hres = IUnknown_QueryInterface(This->dataCache,
1170 &IID_IDataObject,
1171 (void**)&cacheDataObject);
1173 if (FAILED(hres))
1174 return E_UNEXPECTED;
1176 hres = IDataObject_QueryGetData(cacheDataObject,
1177 pformatetc);
1179 IDataObject_Release(cacheDataObject);
1181 if (hres == S_OK) return hres;
1183 if (object_is_running( This ))
1185 start_object_call( This );
1186 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1187 end_object_call( This );
1188 if (hres == S_OK) return hres;
1191 /* Query running state again, as the object may have closed during _QueryGetData call */
1192 if (!object_is_running( This ))
1193 hres = OLE_E_NOTRUNNING;
1195 return hres;
1198 /************************************************************************
1199 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1201 * This method is meaningless if the server is not running
1203 * See Windows documentation for more details on IDataObject methods.
1205 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1206 IDataObject* iface,
1207 LPFORMATETC pformatetcIn,
1208 LPFORMATETC pformatetcOut)
1210 DefaultHandler *This = impl_from_IDataObject(iface);
1211 HRESULT hr;
1213 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1215 if (!object_is_running( This ))
1216 return OLE_E_NOTRUNNING;
1218 start_object_call( This );
1219 hr = IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1220 end_object_call( This );
1222 return hr;
1225 /************************************************************************
1226 * DefaultHandler_SetData (IDataObject)
1228 * The default handler's implementation of this method delegates to
1229 * the cache.
1231 * See Windows documentation for more details on IDataObject methods.
1233 static HRESULT WINAPI DefaultHandler_SetData(
1234 IDataObject* iface,
1235 LPFORMATETC pformatetc,
1236 STGMEDIUM* pmedium,
1237 BOOL fRelease)
1239 DefaultHandler *This = impl_from_IDataObject(iface);
1240 IDataObject* cacheDataObject = NULL;
1241 HRESULT hres;
1243 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1245 hres = IUnknown_QueryInterface(This->dataCache,
1246 &IID_IDataObject,
1247 (void**)&cacheDataObject);
1249 if (FAILED(hres))
1250 return E_UNEXPECTED;
1252 hres = IDataObject_SetData(cacheDataObject,
1253 pformatetc,
1254 pmedium,
1255 fRelease);
1257 IDataObject_Release(cacheDataObject);
1259 return hres;
1262 /************************************************************************
1263 * DefaultHandler_EnumFormatEtc (IDataObject)
1265 * The default handler's implementation of This method simply delegates
1266 * to OleRegEnumFormatEtc.
1268 * See Windows documentation for more details on IDataObject methods.
1270 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1271 IDataObject* iface,
1272 DWORD dwDirection,
1273 IEnumFORMATETC** ppenumFormatEtc)
1275 DefaultHandler *This = impl_from_IDataObject(iface);
1277 TRACE("%p, %lx, %p.\n", iface, dwDirection, ppenumFormatEtc);
1279 return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1282 /************************************************************************
1283 * DefaultHandler_DAdvise (IDataObject)
1285 * The default handler's implementation of this method simply
1286 * delegates to the DataAdviseHolder.
1288 * See Windows documentation for more details on IDataObject methods.
1290 static HRESULT WINAPI DefaultHandler_DAdvise(
1291 IDataObject* iface,
1292 FORMATETC* pformatetc,
1293 DWORD advf,
1294 IAdviseSink* pAdvSink,
1295 DWORD* pdwConnection)
1297 HRESULT hres = S_OK;
1298 DefaultHandler *This = impl_from_IDataObject(iface);
1300 TRACE("%p, %p, %ld, %p, %p.\n", iface, pformatetc, advf, pAdvSink, pdwConnection);
1302 /* Make sure we have a data advise holder before we start. */
1303 if (!This->dataAdviseHolder)
1305 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1306 if (SUCCEEDED(hres) && object_is_running( This ))
1308 start_object_call( This );
1309 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1310 end_object_call( This );
1314 if (SUCCEEDED(hres))
1315 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1316 iface,
1317 pformatetc,
1318 advf,
1319 pAdvSink,
1320 pdwConnection);
1322 return hres;
1325 /************************************************************************
1326 * DefaultHandler_DUnadvise (IDataObject)
1328 * The default handler's implementation of this method simply
1329 * delegates to the DataAdviseHolder.
1331 * See Windows documentation for more details on IDataObject methods.
1333 static HRESULT WINAPI DefaultHandler_DUnadvise(
1334 IDataObject* iface,
1335 DWORD dwConnection)
1337 DefaultHandler *This = impl_from_IDataObject(iface);
1339 TRACE("%p, %ld.\n", iface, dwConnection);
1342 * If we don't have a data advise holder yet, it means that
1343 * we don't have any connections..
1345 if (!This->dataAdviseHolder)
1346 return OLE_E_NOCONNECTION;
1348 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1349 dwConnection);
1352 /************************************************************************
1353 * DefaultHandler_EnumDAdvise (IDataObject)
1355 * The default handler's implementation of this method simply
1356 * delegates to the DataAdviseHolder.
1358 * See Windows documentation for more details on IDataObject methods.
1360 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1361 IDataObject* iface,
1362 IEnumSTATDATA** ppenumAdvise)
1364 DefaultHandler *This = impl_from_IDataObject(iface);
1366 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1368 if (!ppenumAdvise)
1369 return E_POINTER;
1371 *ppenumAdvise = NULL;
1373 /* If we have a data advise holder object, delegate. */
1374 if (This->dataAdviseHolder)
1375 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1376 ppenumAdvise);
1378 return S_OK;
1381 /*********************************************************
1382 * Methods implementation for the IRunnableObject part
1383 * of the DefaultHandler class.
1386 /************************************************************************
1387 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1389 * See Windows documentation for more details on IUnknown methods.
1391 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1392 IRunnableObject* iface,
1393 REFIID riid,
1394 void** ppvObject)
1396 DefaultHandler *This = impl_from_IRunnableObject(iface);
1398 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1401 /************************************************************************
1402 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1404 * See Windows documentation for more details on IUnknown methods.
1406 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1407 IRunnableObject* iface)
1409 DefaultHandler *This = impl_from_IRunnableObject(iface);
1411 return IUnknown_AddRef(This->outerUnknown);
1414 /************************************************************************
1415 * DefaultHandler_IRunnableObject_Release (IUnknown)
1417 * See Windows documentation for more details on IUnknown methods.
1419 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1420 IRunnableObject* iface)
1422 DefaultHandler *This = impl_from_IRunnableObject(iface);
1424 return IUnknown_Release(This->outerUnknown);
1427 /************************************************************************
1428 * DefaultHandler_GetRunningClass (IRunnableObject)
1430 * See Windows documentation for more details on IRunnableObject methods.
1432 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1433 IRunnableObject* iface,
1434 LPCLSID lpClsid)
1436 FIXME("()\n");
1437 return S_OK;
1440 static HRESULT WINAPI DefaultHandler_Run(
1441 IRunnableObject* iface,
1442 IBindCtx* pbc)
1444 DefaultHandler *This = impl_from_IRunnableObject(iface);
1445 HRESULT hr;
1446 IOleCacheControl *cache_ctrl;
1448 FIXME("(%p): semi-stub\n", pbc);
1450 /* already running? if so nothing to do */
1451 if (object_is_running(This))
1452 return S_OK;
1454 release_delegates(This);
1456 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
1457 &IID_IOleObject, (void **)&This->pOleDelegate);
1458 if (FAILED(hr))
1459 return hr;
1461 hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
1462 if (FAILED(hr)) goto fail;
1464 if (This->clientSite)
1466 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1467 if (FAILED(hr)) goto fail;
1470 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1471 (void **)&This->pPSDelegate);
1472 if (FAILED(hr)) goto fail;
1474 if (This->storage_state == storage_state_initialised)
1475 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1476 else if (This->storage_state == storage_state_loaded)
1477 hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1478 if (FAILED(hr)) goto fail;
1480 if (This->containerApp)
1482 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1483 This->containerObj);
1484 if (FAILED(hr)) goto fail;
1487 /* FIXME: do more stuff here:
1488 * - IOleObject_GetMiscStatus
1489 * - IOleObject_GetMoniker
1492 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1493 (void **)&This->pDataDelegate);
1494 if (FAILED(hr)) goto fail;
1496 This->object_state = object_state_running;
1498 if (This->dataAdviseHolder)
1500 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1501 if (FAILED(hr)) goto fail;
1504 hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
1505 if (FAILED(hr)) goto fail;
1506 hr = IOleCacheControl_OnRun( cache_ctrl, This->pDataDelegate );
1507 IOleCacheControl_Release( cache_ctrl );
1508 if (FAILED(hr)) goto fail;
1510 return hr;
1512 fail:
1513 DefaultHandler_Stop(This);
1514 return hr;
1517 /************************************************************************
1518 * DefaultHandler_IsRunning (IRunnableObject)
1520 * See Windows documentation for more details on IRunnableObject methods.
1522 static BOOL WINAPI DefaultHandler_IsRunning(
1523 IRunnableObject* iface)
1525 DefaultHandler *This = impl_from_IRunnableObject(iface);
1527 TRACE("()\n");
1529 if (This->object_state == object_state_running)
1530 return TRUE;
1531 else
1532 return FALSE;
1535 /************************************************************************
1536 * DefaultHandler_LockRunning (IRunnableObject)
1538 * See Windows documentation for more details on IRunnableObject methods.
1540 static HRESULT WINAPI DefaultHandler_LockRunning(
1541 IRunnableObject* iface,
1542 BOOL fLock,
1543 BOOL fLastUnlockCloses)
1545 FIXME("()\n");
1546 return S_OK;
1549 /************************************************************************
1550 * DefaultHandler_SetContainedObject (IRunnableObject)
1552 * See Windows documentation for more details on IRunnableObject methods.
1554 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1555 IRunnableObject* iface,
1556 BOOL fContained)
1558 FIXME("()\n");
1559 return S_OK;
1562 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1563 IAdviseSink *iface,
1564 REFIID riid,
1565 void **ppvObject)
1567 if (IsEqualIID(riid, &IID_IUnknown) ||
1568 IsEqualIID(riid, &IID_IAdviseSink))
1570 *ppvObject = iface;
1571 IAdviseSink_AddRef(iface);
1572 return S_OK;
1575 return E_NOINTERFACE;
1578 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1579 IAdviseSink *iface)
1581 DefaultHandler *This = impl_from_IAdviseSink(iface);
1583 return IUnknown_AddRef(&This->IUnknown_iface);
1586 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1587 IAdviseSink *iface)
1589 DefaultHandler *This = impl_from_IAdviseSink(iface);
1591 return IUnknown_Release(&This->IUnknown_iface);
1594 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1595 IAdviseSink *iface,
1596 FORMATETC *pFormatetc,
1597 STGMEDIUM *pStgmed)
1599 FIXME(": stub\n");
1602 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1603 IAdviseSink *iface,
1604 DWORD dwAspect,
1605 LONG lindex)
1607 FIXME(": stub\n");
1610 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1611 IAdviseSink *iface,
1612 IMoniker *pmk)
1614 DefaultHandler *This = impl_from_IAdviseSink(iface);
1616 TRACE("(%p)\n", pmk);
1618 if (This->oleAdviseHolder)
1619 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1622 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1623 IAdviseSink *iface)
1625 DefaultHandler *This = impl_from_IAdviseSink(iface);
1627 TRACE("()\n");
1629 if (This->oleAdviseHolder)
1630 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1633 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1634 IAdviseSink *iface)
1636 DefaultHandler *This = impl_from_IAdviseSink(iface);
1638 TRACE("()\n");
1640 if (This->oleAdviseHolder)
1641 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1643 if(!This->in_call)
1644 DefaultHandler_Stop(This);
1645 else
1647 TRACE("OnClose during call. Deferring shutdown\n");
1648 This->object_state = object_state_deferred_close;
1652 /************************************************************************
1653 * DefaultHandler_IPersistStorage_QueryInterface
1656 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1657 IPersistStorage* iface,
1658 REFIID riid,
1659 void** ppvObject)
1661 DefaultHandler *This = impl_from_IPersistStorage(iface);
1663 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1666 /************************************************************************
1667 * DefaultHandler_IPersistStorage_AddRef
1670 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1671 IPersistStorage* iface)
1673 DefaultHandler *This = impl_from_IPersistStorage(iface);
1675 return IUnknown_AddRef(This->outerUnknown);
1678 /************************************************************************
1679 * DefaultHandler_IPersistStorage_Release
1682 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1683 IPersistStorage* iface)
1685 DefaultHandler *This = impl_from_IPersistStorage(iface);
1687 return IUnknown_Release(This->outerUnknown);
1690 /************************************************************************
1691 * DefaultHandler_IPersistStorage_GetClassID
1694 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1695 IPersistStorage* iface,
1696 CLSID* clsid)
1698 DefaultHandler *This = impl_from_IPersistStorage(iface);
1699 HRESULT hr;
1701 TRACE("(%p)->(%p)\n", iface, clsid);
1703 if(object_is_running(This))
1705 start_object_call( This );
1706 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1707 end_object_call( This );
1709 else
1710 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1712 return hr;
1715 /************************************************************************
1716 * DefaultHandler_IPersistStorage_IsDirty
1719 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1720 IPersistStorage* iface)
1722 DefaultHandler *This = impl_from_IPersistStorage(iface);
1723 HRESULT hr;
1725 TRACE("(%p)\n", iface);
1727 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1728 if(hr != S_FALSE) return hr;
1730 if(object_is_running(This))
1732 start_object_call( This );
1733 hr = IPersistStorage_IsDirty(This->pPSDelegate);
1734 end_object_call( This );
1737 return hr;
1740 /***********************************************************************
1742 * The format of '\1Ole' stream is as follows:
1744 * DWORD Version == 0x02000001
1745 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1746 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1747 * supplied by the app that creates the data structure. May be
1748 * ignored on processing].
1750 * DWORD Reserved == 0
1751 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1752 * CLSID clsid - class id of object capable of processing the moniker
1753 * BYTE data[] - moniker data for a link
1756 typedef struct
1758 DWORD version;
1759 DWORD flags;
1760 DWORD link_update_opt;
1761 DWORD res;
1762 DWORD moniker_size;
1763 } ole_stream_header_t;
1764 static const DWORD ole_stream_version = 0x02000001;
1766 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1768 IStream *stream;
1769 HRESULT hr;
1771 hr = IStorage_OpenStream(storage, L"\1Ole", NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1773 if(SUCCEEDED(hr))
1775 DWORD read;
1776 ole_stream_header_t header;
1778 hr = IStream_Read(stream, &header, sizeof(header), &read);
1779 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1781 if(header.flags & 1)
1783 /* FIXME: Read the moniker and deal with the link */
1784 FIXME("Linked objects are not supported yet\n");
1787 else
1789 WARN("Incorrect OleStream header\n");
1790 hr = DV_E_CLIPFORMAT;
1792 IStream_Release(stream);
1794 else
1795 hr = STORAGE_CreateOleStream(storage, 0);
1797 return hr;
1800 /************************************************************************
1801 * DefaultHandler_IPersistStorage_InitNew
1804 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1805 IPersistStorage* iface,
1806 IStorage* pStg)
1808 DefaultHandler *This = impl_from_IPersistStorage(iface);
1809 HRESULT hr;
1811 TRACE("(%p)->(%p)\n", iface, pStg);
1812 hr = STORAGE_CreateOleStream(pStg, 0);
1813 if (hr != S_OK) return hr;
1815 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1817 if(SUCCEEDED(hr) && object_is_running(This))
1819 start_object_call( This );
1820 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1821 end_object_call( This );
1824 if(SUCCEEDED(hr))
1826 IStorage_AddRef(pStg);
1827 This->storage = pStg;
1828 This->storage_state = storage_state_initialised;
1831 return hr;
1835 /************************************************************************
1836 * DefaultHandler_IPersistStorage_Load
1839 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1840 IPersistStorage* iface,
1841 IStorage* pStg)
1843 DefaultHandler *This = impl_from_IPersistStorage(iface);
1844 HRESULT hr;
1846 TRACE("(%p)->(%p)\n", iface, pStg);
1848 hr = load_ole_stream(This, pStg);
1850 if(SUCCEEDED(hr))
1851 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1853 if(SUCCEEDED(hr) && object_is_running(This))
1855 start_object_call( This );
1856 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1857 end_object_call( This );
1860 if(SUCCEEDED(hr))
1862 IStorage_AddRef(pStg);
1863 This->storage = pStg;
1864 This->storage_state = storage_state_loaded;
1866 return hr;
1870 /************************************************************************
1871 * DefaultHandler_IPersistStorage_Save
1874 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1875 IPersistStorage* iface,
1876 IStorage* pStgSave,
1877 BOOL fSameAsLoad)
1879 DefaultHandler *This = impl_from_IPersistStorage(iface);
1880 HRESULT hr;
1882 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1884 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1885 if(SUCCEEDED(hr) && object_is_running(This))
1887 start_object_call( This );
1888 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1889 end_object_call( This );
1892 return hr;
1896 /************************************************************************
1897 * DefaultHandler_IPersistStorage_SaveCompleted
1900 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1901 IPersistStorage* iface,
1902 IStorage* pStgNew)
1904 DefaultHandler *This = impl_from_IPersistStorage(iface);
1905 HRESULT hr;
1907 TRACE("(%p)->(%p)\n", iface, pStgNew);
1909 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1911 if(SUCCEEDED(hr) && object_is_running(This))
1913 start_object_call( This );
1914 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1915 end_object_call( This );
1918 if(pStgNew)
1920 IStorage_AddRef(pStgNew);
1921 if(This->storage) IStorage_Release(This->storage);
1922 This->storage = pStgNew;
1923 This->storage_state = storage_state_loaded;
1926 return hr;
1930 /************************************************************************
1931 * DefaultHandler_IPersistStorage_HandsOffStorage
1934 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1935 IPersistStorage* iface)
1937 DefaultHandler *This = impl_from_IPersistStorage(iface);
1938 HRESULT hr;
1940 TRACE("(%p)\n", iface);
1942 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1944 if(SUCCEEDED(hr) && object_is_running(This))
1946 start_object_call( This );
1947 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1948 end_object_call( This );
1951 if(This->storage) IStorage_Release(This->storage);
1952 This->storage = NULL;
1953 This->storage_state = storage_state_uninitialised;
1955 return hr;
1960 * Virtual function tables for the DefaultHandler class.
1962 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1964 DefaultHandler_QueryInterface,
1965 DefaultHandler_AddRef,
1966 DefaultHandler_Release,
1967 DefaultHandler_SetClientSite,
1968 DefaultHandler_GetClientSite,
1969 DefaultHandler_SetHostNames,
1970 DefaultHandler_Close,
1971 DefaultHandler_SetMoniker,
1972 DefaultHandler_GetMoniker,
1973 DefaultHandler_InitFromData,
1974 DefaultHandler_GetClipboardData,
1975 DefaultHandler_DoVerb,
1976 DefaultHandler_EnumVerbs,
1977 DefaultHandler_Update,
1978 DefaultHandler_IsUpToDate,
1979 DefaultHandler_GetUserClassID,
1980 DefaultHandler_GetUserType,
1981 DefaultHandler_SetExtent,
1982 DefaultHandler_GetExtent,
1983 DefaultHandler_Advise,
1984 DefaultHandler_Unadvise,
1985 DefaultHandler_EnumAdvise,
1986 DefaultHandler_GetMiscStatus,
1987 DefaultHandler_SetColorScheme
1990 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1992 DefaultHandler_NDIUnknown_QueryInterface,
1993 DefaultHandler_NDIUnknown_AddRef,
1994 DefaultHandler_NDIUnknown_Release,
1997 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1999 DefaultHandler_IDataObject_QueryInterface,
2000 DefaultHandler_IDataObject_AddRef,
2001 DefaultHandler_IDataObject_Release,
2002 DefaultHandler_GetData,
2003 DefaultHandler_GetDataHere,
2004 DefaultHandler_QueryGetData,
2005 DefaultHandler_GetCanonicalFormatEtc,
2006 DefaultHandler_SetData,
2007 DefaultHandler_EnumFormatEtc,
2008 DefaultHandler_DAdvise,
2009 DefaultHandler_DUnadvise,
2010 DefaultHandler_EnumDAdvise
2013 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
2015 DefaultHandler_IRunnableObject_QueryInterface,
2016 DefaultHandler_IRunnableObject_AddRef,
2017 DefaultHandler_IRunnableObject_Release,
2018 DefaultHandler_GetRunningClass,
2019 DefaultHandler_Run,
2020 DefaultHandler_IsRunning,
2021 DefaultHandler_LockRunning,
2022 DefaultHandler_SetContainedObject
2025 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
2027 DefaultHandler_IAdviseSink_QueryInterface,
2028 DefaultHandler_IAdviseSink_AddRef,
2029 DefaultHandler_IAdviseSink_Release,
2030 DefaultHandler_IAdviseSink_OnDataChange,
2031 DefaultHandler_IAdviseSink_OnViewChange,
2032 DefaultHandler_IAdviseSink_OnRename,
2033 DefaultHandler_IAdviseSink_OnSave,
2034 DefaultHandler_IAdviseSink_OnClose
2037 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
2039 DefaultHandler_IPersistStorage_QueryInterface,
2040 DefaultHandler_IPersistStorage_AddRef,
2041 DefaultHandler_IPersistStorage_Release,
2042 DefaultHandler_IPersistStorage_GetClassID,
2043 DefaultHandler_IPersistStorage_IsDirty,
2044 DefaultHandler_IPersistStorage_InitNew,
2045 DefaultHandler_IPersistStorage_Load,
2046 DefaultHandler_IPersistStorage_Save,
2047 DefaultHandler_IPersistStorage_SaveCompleted,
2048 DefaultHandler_IPersistStorage_HandsOffStorage
2051 /*********************************************************
2052 * Methods implementation for the DefaultHandler class.
2054 static DefaultHandler* DefaultHandler_Construct(
2055 REFCLSID clsid,
2056 LPUNKNOWN pUnkOuter,
2057 DWORD flags,
2058 IClassFactory *pCF)
2060 DefaultHandler* This = NULL;
2061 HRESULT hr;
2063 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
2065 if (!This)
2066 return This;
2068 This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable;
2069 This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable;
2070 This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable;
2071 This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable;
2072 This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable;
2073 This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable;
2075 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) != 0;
2078 * Start with one reference count. The caller of this function
2079 * must release the interface pointer when it is done.
2081 This->ref = 1;
2084 * Initialize the outer unknown
2085 * We don't keep a reference on the outer unknown since, the way
2086 * aggregation works, our lifetime is at least as large as its
2087 * lifetime.
2089 if (!pUnkOuter)
2090 pUnkOuter = &This->IUnknown_iface;
2092 This->outerUnknown = pUnkOuter;
2095 * Create a datacache object.
2096 * We aggregate with the datacache. Make sure we pass our outer
2097 * unknown as the datacache's outer unknown.
2099 hr = CreateDataCache(This->outerUnknown,
2100 clsid,
2101 &IID_IUnknown,
2102 (void**)&This->dataCache);
2103 if(SUCCEEDED(hr))
2105 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
2106 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
2107 * reference on the outer object */
2108 if (SUCCEEDED(hr))
2109 IUnknown_Release(This->outerUnknown);
2110 else
2111 IUnknown_Release(This->dataCache);
2113 if(FAILED(hr))
2115 ERR("Unexpected error creating data cache\n");
2116 HeapFree(GetProcessHeap(), 0, This);
2117 return NULL;
2120 This->clsid = *clsid;
2121 This->clientSite = NULL;
2122 This->oleAdviseHolder = NULL;
2123 This->dataAdviseHolder = NULL;
2124 This->containerApp = NULL;
2125 This->containerObj = NULL;
2126 This->pOleDelegate = NULL;
2127 This->pPSDelegate = NULL;
2128 This->pDataDelegate = NULL;
2129 This->object_state = object_state_not_running;
2130 This->in_call = 0;
2132 This->dwAdvConn = 0;
2133 This->storage = NULL;
2134 This->storage_state = storage_state_uninitialised;
2136 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
2138 HRESULT hr;
2139 This->pCFObject = NULL;
2140 if (pCF)
2141 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
2142 else
2143 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
2144 &IID_IOleObject, (void **)&This->pOleDelegate);
2145 if (SUCCEEDED(hr))
2146 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
2147 if (SUCCEEDED(hr))
2148 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
2149 if (SUCCEEDED(hr))
2150 This->object_state = object_state_running;
2151 if (FAILED(hr))
2152 WARN("object creation failed with error %#lx\n", hr);
2154 else
2156 This->pCFObject = pCF;
2157 if (pCF) IClassFactory_AddRef(pCF);
2160 return This;
2163 static void DefaultHandler_Destroy(
2164 DefaultHandler* This)
2166 TRACE("(%p)\n", This);
2168 /* AddRef/Release may be called on this object during destruction.
2169 * Prevent the object being destroyed recursively by artificially raising
2170 * the reference count. */
2171 This->ref = 10000;
2173 /* release delegates */
2174 DefaultHandler_Stop(This);
2176 HeapFree( GetProcessHeap(), 0, This->containerApp );
2177 This->containerApp = NULL;
2178 HeapFree( GetProcessHeap(), 0, This->containerObj );
2179 This->containerObj = NULL;
2181 if (This->dataCache)
2183 /* to balance out the release of dataCache_PersistStg which will result
2184 * in a reference being released from the outer unknown */
2185 IUnknown_AddRef(This->outerUnknown);
2186 IPersistStorage_Release(This->dataCache_PersistStg);
2187 IUnknown_Release(This->dataCache);
2188 This->dataCache_PersistStg = NULL;
2189 This->dataCache = NULL;
2192 if (This->clientSite)
2194 IOleClientSite_Release(This->clientSite);
2195 This->clientSite = NULL;
2198 if (This->oleAdviseHolder)
2200 IOleAdviseHolder_Release(This->oleAdviseHolder);
2201 This->oleAdviseHolder = NULL;
2204 if (This->dataAdviseHolder)
2206 IDataAdviseHolder_Release(This->dataAdviseHolder);
2207 This->dataAdviseHolder = NULL;
2210 if (This->storage)
2212 IStorage_Release(This->storage);
2213 This->storage = NULL;
2216 if (This->pCFObject)
2218 IClassFactory_Release(This->pCFObject);
2219 This->pCFObject = NULL;
2222 HeapFree(GetProcessHeap(), 0, This);
2225 /******************************************************************************
2226 * OleCreateEmbeddingHelper [OLE32.@]
2228 HRESULT WINAPI OleCreateEmbeddingHelper(
2229 REFCLSID clsid,
2230 LPUNKNOWN pUnkOuter,
2231 DWORD flags,
2232 IClassFactory *pCF,
2233 REFIID riid,
2234 LPVOID* ppvObj)
2236 DefaultHandler* newHandler = NULL;
2237 HRESULT hr = S_OK;
2239 TRACE("%s, %p, %#lx, %p, %s, %p.\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2241 if (!ppvObj)
2242 return E_POINTER;
2244 *ppvObj = NULL;
2247 * If This handler is constructed for aggregation, make sure
2248 * the caller is requesting the IUnknown interface.
2249 * This is necessary because it's the only time the non-delegating
2250 * IUnknown pointer can be returned to the outside.
2252 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2253 return CLASS_E_NOAGGREGATION;
2256 * Try to construct a new instance of the class.
2258 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2260 if (!newHandler)
2261 return E_OUTOFMEMORY;
2264 * Make sure it supports the interface required by the caller.
2266 hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj);
2269 * Release the reference obtained in the constructor. If
2270 * the QueryInterface was unsuccessful, it will free the class.
2272 IUnknown_Release(&newHandler->IUnknown_iface);
2274 return hr;
2278 /******************************************************************************
2279 * OleCreateDefaultHandler [OLE32.@]
2281 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
2282 REFIID riid, LPVOID* ppvObj)
2284 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
2285 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
2286 NULL, riid, ppvObj);
2289 typedef struct HandlerCF
2291 IClassFactory IClassFactory_iface;
2292 LONG refs;
2293 CLSID clsid;
2294 } HandlerCF;
2296 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
2298 return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
2301 static HRESULT WINAPI
2302 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
2304 *ppv = NULL;
2305 if (IsEqualIID(riid,&IID_IUnknown) ||
2306 IsEqualIID(riid,&IID_IClassFactory))
2308 *ppv = iface;
2309 IClassFactory_AddRef(iface);
2310 return S_OK;
2312 return E_NOINTERFACE;
2315 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
2317 HandlerCF *This = impl_from_IClassFactory(iface);
2318 return InterlockedIncrement(&This->refs);
2321 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
2323 HandlerCF *This = impl_from_IClassFactory(iface);
2324 ULONG refs = InterlockedDecrement(&This->refs);
2325 if (!refs)
2326 HeapFree(GetProcessHeap(), 0, This);
2327 return refs;
2330 static HRESULT WINAPI
2331 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
2332 REFIID riid, LPVOID *ppv)
2334 HandlerCF *This = impl_from_IClassFactory(iface);
2335 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
2338 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
2340 FIXME("(%d), stub!\n",fLock);
2341 return S_OK;
2344 static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
2345 HandlerCF_QueryInterface,
2346 HandlerCF_AddRef,
2347 HandlerCF_Release,
2348 HandlerCF_CreateInstance,
2349 HandlerCF_LockServer
2352 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
2354 HRESULT hr;
2355 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2356 if (!This) return E_OUTOFMEMORY;
2357 This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
2358 This->refs = 0;
2359 This->clsid = *rclsid;
2361 hr = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv);
2362 if (FAILED(hr))
2363 HeapFree(GetProcessHeap(), 0, This);
2365 return hr;