crypt32: Fix adding trusted roots to store.
[wine/zf.git] / dlls / ole32 / defaulthandler.c
blobc1045c154667cea16e8335c414687ead2e4f53e0
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 static const WCHAR OleStream[] = {1,'O','l','e',0};
1762 typedef struct
1764 DWORD version;
1765 DWORD flags;
1766 DWORD link_update_opt;
1767 DWORD res;
1768 DWORD moniker_size;
1769 } ole_stream_header_t;
1770 static const DWORD ole_stream_version = 0x02000001;
1772 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1774 IStream *stream;
1775 HRESULT hr;
1777 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1779 if(SUCCEEDED(hr))
1781 DWORD read;
1782 ole_stream_header_t header;
1784 hr = IStream_Read(stream, &header, sizeof(header), &read);
1785 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1787 if(header.flags & 1)
1789 /* FIXME: Read the moniker and deal with the link */
1790 FIXME("Linked objects are not supported yet\n");
1793 else
1795 WARN("Incorrect OleStream header\n");
1796 hr = DV_E_CLIPFORMAT;
1798 IStream_Release(stream);
1800 else
1801 hr = STORAGE_CreateOleStream(storage, 0);
1803 return hr;
1806 /************************************************************************
1807 * DefaultHandler_IPersistStorage_InitNew
1810 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1811 IPersistStorage* iface,
1812 IStorage* pStg)
1814 DefaultHandler *This = impl_from_IPersistStorage(iface);
1815 HRESULT hr;
1817 TRACE("(%p)->(%p)\n", iface, pStg);
1818 hr = STORAGE_CreateOleStream(pStg, 0);
1819 if (hr != S_OK) return hr;
1821 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1823 if(SUCCEEDED(hr) && object_is_running(This))
1825 start_object_call( This );
1826 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1827 end_object_call( This );
1830 if(SUCCEEDED(hr))
1832 IStorage_AddRef(pStg);
1833 This->storage = pStg;
1834 This->storage_state = storage_state_initialised;
1837 return hr;
1841 /************************************************************************
1842 * DefaultHandler_IPersistStorage_Load
1845 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1846 IPersistStorage* iface,
1847 IStorage* pStg)
1849 DefaultHandler *This = impl_from_IPersistStorage(iface);
1850 HRESULT hr;
1852 TRACE("(%p)->(%p)\n", iface, pStg);
1854 hr = load_ole_stream(This, pStg);
1856 if(SUCCEEDED(hr))
1857 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1859 if(SUCCEEDED(hr) && object_is_running(This))
1861 start_object_call( This );
1862 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1863 end_object_call( This );
1866 if(SUCCEEDED(hr))
1868 IStorage_AddRef(pStg);
1869 This->storage = pStg;
1870 This->storage_state = storage_state_loaded;
1872 return hr;
1876 /************************************************************************
1877 * DefaultHandler_IPersistStorage_Save
1880 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1881 IPersistStorage* iface,
1882 IStorage* pStgSave,
1883 BOOL fSameAsLoad)
1885 DefaultHandler *This = impl_from_IPersistStorage(iface);
1886 HRESULT hr;
1888 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1890 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1891 if(SUCCEEDED(hr) && object_is_running(This))
1893 start_object_call( This );
1894 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1895 end_object_call( This );
1898 return hr;
1902 /************************************************************************
1903 * DefaultHandler_IPersistStorage_SaveCompleted
1906 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1907 IPersistStorage* iface,
1908 IStorage* pStgNew)
1910 DefaultHandler *This = impl_from_IPersistStorage(iface);
1911 HRESULT hr;
1913 TRACE("(%p)->(%p)\n", iface, pStgNew);
1915 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1917 if(SUCCEEDED(hr) && object_is_running(This))
1919 start_object_call( This );
1920 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1921 end_object_call( This );
1924 if(pStgNew)
1926 IStorage_AddRef(pStgNew);
1927 if(This->storage) IStorage_Release(This->storage);
1928 This->storage = pStgNew;
1929 This->storage_state = storage_state_loaded;
1932 return hr;
1936 /************************************************************************
1937 * DefaultHandler_IPersistStorage_HandsOffStorage
1940 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1941 IPersistStorage* iface)
1943 DefaultHandler *This = impl_from_IPersistStorage(iface);
1944 HRESULT hr;
1946 TRACE("(%p)\n", iface);
1948 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1950 if(SUCCEEDED(hr) && object_is_running(This))
1952 start_object_call( This );
1953 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1954 end_object_call( This );
1957 if(This->storage) IStorage_Release(This->storage);
1958 This->storage = NULL;
1959 This->storage_state = storage_state_uninitialised;
1961 return hr;
1966 * Virtual function tables for the DefaultHandler class.
1968 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1970 DefaultHandler_QueryInterface,
1971 DefaultHandler_AddRef,
1972 DefaultHandler_Release,
1973 DefaultHandler_SetClientSite,
1974 DefaultHandler_GetClientSite,
1975 DefaultHandler_SetHostNames,
1976 DefaultHandler_Close,
1977 DefaultHandler_SetMoniker,
1978 DefaultHandler_GetMoniker,
1979 DefaultHandler_InitFromData,
1980 DefaultHandler_GetClipboardData,
1981 DefaultHandler_DoVerb,
1982 DefaultHandler_EnumVerbs,
1983 DefaultHandler_Update,
1984 DefaultHandler_IsUpToDate,
1985 DefaultHandler_GetUserClassID,
1986 DefaultHandler_GetUserType,
1987 DefaultHandler_SetExtent,
1988 DefaultHandler_GetExtent,
1989 DefaultHandler_Advise,
1990 DefaultHandler_Unadvise,
1991 DefaultHandler_EnumAdvise,
1992 DefaultHandler_GetMiscStatus,
1993 DefaultHandler_SetColorScheme
1996 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1998 DefaultHandler_NDIUnknown_QueryInterface,
1999 DefaultHandler_NDIUnknown_AddRef,
2000 DefaultHandler_NDIUnknown_Release,
2003 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
2005 DefaultHandler_IDataObject_QueryInterface,
2006 DefaultHandler_IDataObject_AddRef,
2007 DefaultHandler_IDataObject_Release,
2008 DefaultHandler_GetData,
2009 DefaultHandler_GetDataHere,
2010 DefaultHandler_QueryGetData,
2011 DefaultHandler_GetCanonicalFormatEtc,
2012 DefaultHandler_SetData,
2013 DefaultHandler_EnumFormatEtc,
2014 DefaultHandler_DAdvise,
2015 DefaultHandler_DUnadvise,
2016 DefaultHandler_EnumDAdvise
2019 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
2021 DefaultHandler_IRunnableObject_QueryInterface,
2022 DefaultHandler_IRunnableObject_AddRef,
2023 DefaultHandler_IRunnableObject_Release,
2024 DefaultHandler_GetRunningClass,
2025 DefaultHandler_Run,
2026 DefaultHandler_IsRunning,
2027 DefaultHandler_LockRunning,
2028 DefaultHandler_SetContainedObject
2031 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
2033 DefaultHandler_IAdviseSink_QueryInterface,
2034 DefaultHandler_IAdviseSink_AddRef,
2035 DefaultHandler_IAdviseSink_Release,
2036 DefaultHandler_IAdviseSink_OnDataChange,
2037 DefaultHandler_IAdviseSink_OnViewChange,
2038 DefaultHandler_IAdviseSink_OnRename,
2039 DefaultHandler_IAdviseSink_OnSave,
2040 DefaultHandler_IAdviseSink_OnClose
2043 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
2045 DefaultHandler_IPersistStorage_QueryInterface,
2046 DefaultHandler_IPersistStorage_AddRef,
2047 DefaultHandler_IPersistStorage_Release,
2048 DefaultHandler_IPersistStorage_GetClassID,
2049 DefaultHandler_IPersistStorage_IsDirty,
2050 DefaultHandler_IPersistStorage_InitNew,
2051 DefaultHandler_IPersistStorage_Load,
2052 DefaultHandler_IPersistStorage_Save,
2053 DefaultHandler_IPersistStorage_SaveCompleted,
2054 DefaultHandler_IPersistStorage_HandsOffStorage
2057 /*********************************************************
2058 * Methods implementation for the DefaultHandler class.
2060 static DefaultHandler* DefaultHandler_Construct(
2061 REFCLSID clsid,
2062 LPUNKNOWN pUnkOuter,
2063 DWORD flags,
2064 IClassFactory *pCF)
2066 DefaultHandler* This = NULL;
2067 HRESULT hr;
2069 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
2071 if (!This)
2072 return This;
2074 This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable;
2075 This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable;
2076 This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable;
2077 This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable;
2078 This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable;
2079 This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable;
2081 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) != 0;
2084 * Start with one reference count. The caller of this function
2085 * must release the interface pointer when it is done.
2087 This->ref = 1;
2090 * Initialize the outer unknown
2091 * We don't keep a reference on the outer unknown since, the way
2092 * aggregation works, our lifetime is at least as large as its
2093 * lifetime.
2095 if (!pUnkOuter)
2096 pUnkOuter = &This->IUnknown_iface;
2098 This->outerUnknown = pUnkOuter;
2101 * Create a datacache object.
2102 * We aggregate with the datacache. Make sure we pass our outer
2103 * unknown as the datacache's outer unknown.
2105 hr = CreateDataCache(This->outerUnknown,
2106 clsid,
2107 &IID_IUnknown,
2108 (void**)&This->dataCache);
2109 if(SUCCEEDED(hr))
2111 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
2112 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
2113 * reference on the outer object */
2114 if (SUCCEEDED(hr))
2115 IUnknown_Release(This->outerUnknown);
2116 else
2117 IUnknown_Release(This->dataCache);
2119 if(FAILED(hr))
2121 ERR("Unexpected error creating data cache\n");
2122 HeapFree(GetProcessHeap(), 0, This);
2123 return NULL;
2126 This->clsid = *clsid;
2127 This->clientSite = NULL;
2128 This->oleAdviseHolder = NULL;
2129 This->dataAdviseHolder = NULL;
2130 This->containerApp = NULL;
2131 This->containerObj = NULL;
2132 This->pOleDelegate = NULL;
2133 This->pPSDelegate = NULL;
2134 This->pDataDelegate = NULL;
2135 This->object_state = object_state_not_running;
2136 This->in_call = 0;
2138 This->dwAdvConn = 0;
2139 This->storage = NULL;
2140 This->storage_state = storage_state_uninitialised;
2142 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
2144 HRESULT hr;
2145 This->pCFObject = NULL;
2146 if (pCF)
2147 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
2148 else
2149 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
2150 &IID_IOleObject, (void **)&This->pOleDelegate);
2151 if (SUCCEEDED(hr))
2152 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
2153 if (SUCCEEDED(hr))
2154 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
2155 if (SUCCEEDED(hr))
2156 This->object_state = object_state_running;
2157 if (FAILED(hr))
2158 WARN("object creation failed with error %08x\n", hr);
2160 else
2162 This->pCFObject = pCF;
2163 if (pCF) IClassFactory_AddRef(pCF);
2166 return This;
2169 static void DefaultHandler_Destroy(
2170 DefaultHandler* This)
2172 TRACE("(%p)\n", This);
2174 /* AddRef/Release may be called on this object during destruction.
2175 * Prevent the object being destroyed recursively by artificially raising
2176 * the reference count. */
2177 This->ref = 10000;
2179 /* release delegates */
2180 DefaultHandler_Stop(This);
2182 HeapFree( GetProcessHeap(), 0, This->containerApp );
2183 This->containerApp = NULL;
2184 HeapFree( GetProcessHeap(), 0, This->containerObj );
2185 This->containerObj = NULL;
2187 if (This->dataCache)
2189 /* to balance out the release of dataCache_PersistStg which will result
2190 * in a reference being released from the outer unknown */
2191 IUnknown_AddRef(This->outerUnknown);
2192 IPersistStorage_Release(This->dataCache_PersistStg);
2193 IUnknown_Release(This->dataCache);
2194 This->dataCache_PersistStg = NULL;
2195 This->dataCache = NULL;
2198 if (This->clientSite)
2200 IOleClientSite_Release(This->clientSite);
2201 This->clientSite = NULL;
2204 if (This->oleAdviseHolder)
2206 IOleAdviseHolder_Release(This->oleAdviseHolder);
2207 This->oleAdviseHolder = NULL;
2210 if (This->dataAdviseHolder)
2212 IDataAdviseHolder_Release(This->dataAdviseHolder);
2213 This->dataAdviseHolder = NULL;
2216 if (This->storage)
2218 IStorage_Release(This->storage);
2219 This->storage = NULL;
2222 if (This->pCFObject)
2224 IClassFactory_Release(This->pCFObject);
2225 This->pCFObject = NULL;
2228 HeapFree(GetProcessHeap(), 0, This);
2231 /******************************************************************************
2232 * OleCreateEmbeddingHelper [OLE32.@]
2234 HRESULT WINAPI OleCreateEmbeddingHelper(
2235 REFCLSID clsid,
2236 LPUNKNOWN pUnkOuter,
2237 DWORD flags,
2238 IClassFactory *pCF,
2239 REFIID riid,
2240 LPVOID* ppvObj)
2242 DefaultHandler* newHandler = NULL;
2243 HRESULT hr = S_OK;
2245 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2247 if (!ppvObj)
2248 return E_POINTER;
2250 *ppvObj = NULL;
2253 * If This handler is constructed for aggregation, make sure
2254 * the caller is requesting the IUnknown interface.
2255 * This is necessary because it's the only time the non-delegating
2256 * IUnknown pointer can be returned to the outside.
2258 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2259 return CLASS_E_NOAGGREGATION;
2262 * Try to construct a new instance of the class.
2264 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2266 if (!newHandler)
2267 return E_OUTOFMEMORY;
2270 * Make sure it supports the interface required by the caller.
2272 hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj);
2275 * Release the reference obtained in the constructor. If
2276 * the QueryInterface was unsuccessful, it will free the class.
2278 IUnknown_Release(&newHandler->IUnknown_iface);
2280 return hr;
2284 /******************************************************************************
2285 * OleCreateDefaultHandler [OLE32.@]
2287 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
2288 REFIID riid, LPVOID* ppvObj)
2290 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
2291 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
2292 NULL, riid, ppvObj);
2295 typedef struct HandlerCF
2297 IClassFactory IClassFactory_iface;
2298 LONG refs;
2299 CLSID clsid;
2300 } HandlerCF;
2302 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
2304 return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
2307 static HRESULT WINAPI
2308 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
2310 *ppv = NULL;
2311 if (IsEqualIID(riid,&IID_IUnknown) ||
2312 IsEqualIID(riid,&IID_IClassFactory))
2314 *ppv = iface;
2315 IClassFactory_AddRef(iface);
2316 return S_OK;
2318 return E_NOINTERFACE;
2321 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
2323 HandlerCF *This = impl_from_IClassFactory(iface);
2324 return InterlockedIncrement(&This->refs);
2327 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
2329 HandlerCF *This = impl_from_IClassFactory(iface);
2330 ULONG refs = InterlockedDecrement(&This->refs);
2331 if (!refs)
2332 HeapFree(GetProcessHeap(), 0, This);
2333 return refs;
2336 static HRESULT WINAPI
2337 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
2338 REFIID riid, LPVOID *ppv)
2340 HandlerCF *This = impl_from_IClassFactory(iface);
2341 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
2344 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
2346 FIXME("(%d), stub!\n",fLock);
2347 return S_OK;
2350 static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
2351 HandlerCF_QueryInterface,
2352 HandlerCF_AddRef,
2353 HandlerCF_Release,
2354 HandlerCF_CreateInstance,
2355 HandlerCF_LockServer
2358 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
2360 HRESULT hr;
2361 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2362 if (!This) return E_OUTOFMEMORY;
2363 This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
2364 This->refs = 0;
2365 This->clsid = *rclsid;
2367 hr = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv);
2368 if (FAILED(hr))
2369 HeapFree(GetProcessHeap(), 0, This);
2371 return hr;