gphoto2.ds: Set supported groups.
[wine.git] / dlls / ole32 / defaulthandler.c
blobe6c52cd0933bf8745a3564bd17b2c1c99de9c6f2
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/unicode.h"
64 #include "wine/debug.h"
66 WINE_DEFAULT_DEBUG_CHANNEL(ole);
68 enum storage_state
70 storage_state_uninitialised,
71 storage_state_initialised,
72 storage_state_loaded
75 enum object_state
77 object_state_not_running,
78 object_state_running,
79 object_state_deferred_close
82 /****************************************************************************
83 * DefaultHandler
86 struct DefaultHandler
88 IOleObject IOleObject_iface;
89 IUnknown IUnknown_iface;
90 IDataObject IDataObject_iface;
91 IRunnableObject IRunnableObject_iface;
92 IAdviseSink IAdviseSink_iface;
93 IPersistStorage IPersistStorage_iface;
95 /* Reference count of this object */
96 LONG ref;
98 /* IUnknown implementation of the outer object. */
99 IUnknown* outerUnknown;
101 /* Class Id that this handler object represents. */
102 CLSID clsid;
104 /* IUnknown implementation of the datacache. */
105 IUnknown* dataCache;
106 /* IPersistStorage implementation of the datacache. */
107 IPersistStorage* dataCache_PersistStg;
109 /* Client site for the embedded object. */
110 IOleClientSite* clientSite;
113 * The IOleAdviseHolder maintains the connections
114 * on behalf of the default handler.
116 IOleAdviseHolder* oleAdviseHolder;
119 * The IDataAdviseHolder maintains the data
120 * connections on behalf of the default handler.
122 IDataAdviseHolder* dataAdviseHolder;
124 /* Name of the container and object contained */
125 LPWSTR containerApp;
126 LPWSTR containerObj;
128 /* IOleObject delegate */
129 IOleObject *pOleDelegate;
130 /* IPersistStorage delegate */
131 IPersistStorage *pPSDelegate;
132 /* IDataObject delegate */
133 IDataObject *pDataDelegate;
134 enum object_state object_state;
135 ULONG in_call;
137 /* connection cookie for the advise on the delegate OLE object */
138 DWORD dwAdvConn;
140 /* storage passed to Load or InitNew */
141 IStorage *storage;
142 enum storage_state storage_state;
144 /* optional class factory for object */
145 IClassFactory *pCFObject;
146 /* TRUE if acting as an inproc server instead of an inproc handler */
147 BOOL inproc_server;
150 typedef struct DefaultHandler DefaultHandler;
152 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
154 return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface);
157 static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface )
159 return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface);
162 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
164 return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface);
167 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
169 return CONTAINING_RECORD(iface, DefaultHandler, IRunnableObject_iface);
172 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
174 return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface);
177 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
179 return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface);
182 static void DefaultHandler_Destroy(DefaultHandler* This);
184 static inline BOOL object_is_running(DefaultHandler *This)
186 return IRunnableObject_IsRunning(&This->IRunnableObject_iface);
189 static void DefaultHandler_Stop(DefaultHandler *This);
191 static inline void start_object_call(DefaultHandler *This)
193 This->in_call++;
196 static inline void end_object_call(DefaultHandler *This)
198 This->in_call--;
199 if (This->in_call == 0 && This->object_state == object_state_deferred_close)
200 DefaultHandler_Stop( This );
203 /*********************************************************
204 * Method implementation for the non delegating IUnknown
205 * part of the DefaultHandler class.
208 /************************************************************************
209 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
211 * See Windows documentation for more details on IUnknown methods.
213 * This version of QueryInterface will not delegate its implementation
214 * to the outer unknown.
216 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
217 IUnknown* iface,
218 REFIID riid,
219 void** ppvObject)
221 DefaultHandler *This = impl_from_IUnknown(iface);
223 if (!ppvObject)
224 return E_INVALIDARG;
226 *ppvObject = NULL;
228 if (IsEqualIID(&IID_IUnknown, riid))
229 *ppvObject = iface;
230 else if (IsEqualIID(&IID_IOleObject, riid))
231 *ppvObject = &This->IOleObject_iface;
232 else if (IsEqualIID(&IID_IDataObject, riid))
233 *ppvObject = &This->IDataObject_iface;
234 else if (IsEqualIID(&IID_IRunnableObject, riid))
235 *ppvObject = &This->IRunnableObject_iface;
236 else if (IsEqualIID(&IID_IPersist, riid) ||
237 IsEqualIID(&IID_IPersistStorage, riid))
238 *ppvObject = &This->IPersistStorage_iface;
239 else if (IsEqualIID(&IID_IViewObject, riid) ||
240 IsEqualIID(&IID_IViewObject2, riid) ||
241 IsEqualIID(&IID_IOleCache, riid) ||
242 IsEqualIID(&IID_IOleCache2, riid))
244 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
245 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
246 return hr;
248 else if (This->inproc_server && This->pOleDelegate)
250 return IOleObject_QueryInterface(This->pOleDelegate, riid, ppvObject);
253 /* Check that we obtained an interface. */
254 if (*ppvObject == NULL)
256 WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
257 return E_NOINTERFACE;
261 * Query Interface always increases the reference count by one when it is
262 * successful.
264 IUnknown_AddRef((IUnknown*)*ppvObject);
266 return S_OK;
269 /************************************************************************
270 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
272 * See Windows documentation for more details on IUnknown methods.
274 * This version of QueryInterface will not delegate its implementation
275 * to the outer unknown.
277 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
278 IUnknown* iface)
280 DefaultHandler *This = impl_from_IUnknown(iface);
281 return InterlockedIncrement(&This->ref);
284 /************************************************************************
285 * DefaultHandler_NDIUnknown_Release (IUnknown)
287 * See Windows documentation for more details on IUnknown methods.
289 * This version of QueryInterface will not delegate its implementation
290 * to the outer unknown.
292 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
293 IUnknown* iface)
295 DefaultHandler *This = impl_from_IUnknown(iface);
296 ULONG ref;
298 ref = InterlockedDecrement(&This->ref);
300 if (!ref) DefaultHandler_Destroy(This);
302 return ref;
305 /*********************************************************
306 * Methods implementation for the IOleObject part of
307 * the DefaultHandler class.
310 /************************************************************************
311 * DefaultHandler_QueryInterface (IUnknown)
313 * See Windows documentation for more details on IUnknown methods.
315 static HRESULT WINAPI DefaultHandler_QueryInterface(
316 IOleObject* iface,
317 REFIID riid,
318 void** ppvObject)
320 DefaultHandler *This = impl_from_IOleObject(iface);
322 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
325 /************************************************************************
326 * DefaultHandler_AddRef (IUnknown)
328 * See Windows documentation for more details on IUnknown methods.
330 static ULONG WINAPI DefaultHandler_AddRef(
331 IOleObject* iface)
333 DefaultHandler *This = impl_from_IOleObject(iface);
335 return IUnknown_AddRef(This->outerUnknown);
338 /************************************************************************
339 * DefaultHandler_Release (IUnknown)
341 * See Windows documentation for more details on IUnknown methods.
343 static ULONG WINAPI DefaultHandler_Release(
344 IOleObject* iface)
346 DefaultHandler *This = impl_from_IOleObject(iface);
348 return IUnknown_Release(This->outerUnknown);
351 /************************************************************************
352 * DefaultHandler_SetClientSite (IOleObject)
354 * The default handler's implementation of this method only keeps the
355 * client site pointer for future reference.
357 * See Windows documentation for more details on IOleObject methods.
359 static HRESULT WINAPI DefaultHandler_SetClientSite(
360 IOleObject* iface,
361 IOleClientSite* pClientSite)
363 DefaultHandler *This = impl_from_IOleObject(iface);
364 HRESULT hr = S_OK;
366 TRACE("(%p, %p)\n", iface, pClientSite);
368 if (object_is_running(This))
370 start_object_call( This );
371 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
372 end_object_call( This );
376 * Make sure we release the previous client site if there
377 * was one.
379 if (This->clientSite)
380 IOleClientSite_Release(This->clientSite);
382 This->clientSite = pClientSite;
384 if (This->clientSite)
385 IOleClientSite_AddRef(This->clientSite);
387 return hr;
390 /************************************************************************
391 * DefaultHandler_GetClientSite (IOleObject)
393 * The default handler's implementation of this method returns the
394 * last pointer set in IOleObject_SetClientSite.
396 * See Windows documentation for more details on IOleObject methods.
398 static HRESULT WINAPI DefaultHandler_GetClientSite(
399 IOleObject* iface,
400 IOleClientSite** ppClientSite)
402 DefaultHandler *This = impl_from_IOleObject(iface);
404 if (!ppClientSite)
405 return E_POINTER;
407 *ppClientSite = This->clientSite;
409 if (This->clientSite)
410 IOleClientSite_AddRef(This->clientSite);
412 return S_OK;
415 /************************************************************************
416 * DefaultHandler_SetHostNames (IOleObject)
418 * The default handler's implementation of this method just stores
419 * the strings and returns S_OK.
421 * See Windows documentation for more details on IOleObject methods.
423 static HRESULT WINAPI DefaultHandler_SetHostNames(
424 IOleObject* iface,
425 LPCOLESTR szContainerApp,
426 LPCOLESTR szContainerObj)
428 DefaultHandler *This = impl_from_IOleObject(iface);
430 TRACE("(%p, %s, %s)\n",
431 iface,
432 debugstr_w(szContainerApp),
433 debugstr_w(szContainerObj));
435 if (object_is_running(This))
437 start_object_call( This );
438 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
439 end_object_call( This );
442 /* Be sure to cleanup before re-assigning the strings. */
443 HeapFree( GetProcessHeap(), 0, This->containerApp );
444 This->containerApp = NULL;
445 HeapFree( GetProcessHeap(), 0, This->containerObj );
446 This->containerObj = NULL;
448 if (szContainerApp)
450 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
451 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
452 strcpyW( This->containerApp, szContainerApp );
455 if (szContainerObj)
457 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
458 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
459 strcpyW( This->containerObj, szContainerObj );
461 return S_OK;
464 static void release_delegates(DefaultHandler *This)
466 if (This->pDataDelegate)
468 IDataObject_Release(This->pDataDelegate);
469 This->pDataDelegate = NULL;
471 if (This->pPSDelegate)
473 IPersistStorage_Release(This->pPSDelegate);
474 This->pPSDelegate = NULL;
476 if (This->pOleDelegate)
478 IOleObject_Release(This->pOleDelegate);
479 This->pOleDelegate = NULL;
483 /* undoes the work done by DefaultHandler_Run */
484 static void DefaultHandler_Stop(DefaultHandler *This)
486 IOleCacheControl *cache_ctrl;
487 HRESULT hr;
489 if (This->object_state == object_state_not_running)
490 return;
492 hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
493 if (SUCCEEDED(hr))
495 hr = IOleCacheControl_OnStop( cache_ctrl );
496 IOleCacheControl_Release( cache_ctrl );
499 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
501 if (This->dataAdviseHolder)
502 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
504 This->object_state = object_state_not_running;
505 release_delegates( This );
508 /************************************************************************
509 * DefaultHandler_Close (IOleObject)
511 * The default handler's implementation of this method is meaningless
512 * without a running server so it does nothing.
514 * See Windows documentation for more details on IOleObject methods.
516 static HRESULT WINAPI DefaultHandler_Close(
517 IOleObject* iface,
518 DWORD dwSaveOption)
520 DefaultHandler *This = impl_from_IOleObject(iface);
521 HRESULT hr;
523 TRACE("(%d)\n", dwSaveOption);
525 if (!object_is_running(This))
526 return S_OK;
528 start_object_call( This );
529 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
530 end_object_call( This );
532 DefaultHandler_Stop(This);
534 return hr;
537 /************************************************************************
538 * DefaultHandler_SetMoniker (IOleObject)
540 * The default handler's implementation of this method does nothing.
542 * See Windows documentation for more details on IOleObject methods.
544 static HRESULT WINAPI DefaultHandler_SetMoniker(
545 IOleObject* iface,
546 DWORD dwWhichMoniker,
547 IMoniker* pmk)
549 DefaultHandler *This = impl_from_IOleObject(iface);
550 HRESULT hr = S_OK;
552 TRACE("(%p, %d, %p)\n", iface, dwWhichMoniker, pmk);
554 if (object_is_running(This))
556 start_object_call( This );
557 hr = IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
558 end_object_call( This );
561 return hr;
564 /************************************************************************
565 * DefaultHandler_GetMoniker (IOleObject)
567 * Delegate this request to the client site if we have one.
569 * See Windows documentation for more details on IOleObject methods.
571 static HRESULT WINAPI DefaultHandler_GetMoniker(
572 IOleObject* iface,
573 DWORD dwAssign,
574 DWORD dwWhichMoniker,
575 IMoniker** ppmk)
577 DefaultHandler *This = impl_from_IOleObject(iface);
578 HRESULT hr;
580 TRACE("(%p, %d, %d, %p)\n",
581 iface, dwAssign, dwWhichMoniker, ppmk);
583 if (object_is_running(This))
585 start_object_call( This );
586 hr = IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
587 ppmk);
588 end_object_call( This );
589 return hr;
592 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
593 if (This->clientSite)
595 return IOleClientSite_GetMoniker(This->clientSite,
596 dwAssign,
597 dwWhichMoniker,
598 ppmk);
602 return E_FAIL;
605 /************************************************************************
606 * DefaultHandler_InitFromData (IOleObject)
608 * This method is meaningless if the server is not running
610 * See Windows documentation for more details on IOleObject methods.
612 static HRESULT WINAPI DefaultHandler_InitFromData(
613 IOleObject* iface,
614 IDataObject* pDataObject,
615 BOOL fCreation,
616 DWORD dwReserved)
618 DefaultHandler *This = impl_from_IOleObject(iface);
619 HRESULT hr = OLE_E_NOTRUNNING;
621 TRACE("(%p, %p, %d, %d)\n",
622 iface, pDataObject, fCreation, dwReserved);
624 if (object_is_running(This))
626 start_object_call( This );
627 hr = IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
628 dwReserved);
629 end_object_call( This );
632 return hr;
635 /************************************************************************
636 * DefaultHandler_GetClipboardData (IOleObject)
638 * This method is meaningless if the server is not running
640 * See Windows documentation for more details on IOleObject methods.
642 static HRESULT WINAPI DefaultHandler_GetClipboardData(
643 IOleObject* iface,
644 DWORD dwReserved,
645 IDataObject** ppDataObject)
647 DefaultHandler *This = impl_from_IOleObject(iface);
648 HRESULT hr = OLE_E_NOTRUNNING;
650 TRACE("(%p, %d, %p)\n",
651 iface, dwReserved, ppDataObject);
653 if (object_is_running(This))
655 start_object_call( This );
656 hr = IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
657 ppDataObject);
658 end_object_call( This );
661 return hr;
664 static HRESULT WINAPI DefaultHandler_DoVerb(
665 IOleObject* iface,
666 LONG iVerb,
667 struct tagMSG* lpmsg,
668 IOleClientSite* pActiveSite,
669 LONG lindex,
670 HWND hwndParent,
671 LPCRECT lprcPosRect)
673 DefaultHandler *This = impl_from_IOleObject(iface);
674 IRunnableObject *pRunnableObj = &This->IRunnableObject_iface;
675 HRESULT hr;
677 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
679 hr = IRunnableObject_Run(pRunnableObj, NULL);
680 if (FAILED(hr)) return hr;
682 start_object_call( This );
683 hr = IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
684 lindex, hwndParent, lprcPosRect);
685 end_object_call( This );
687 return hr;
690 /************************************************************************
691 * DefaultHandler_EnumVerbs (IOleObject)
693 * The default handler implementation of this method simply delegates
694 * to OleRegEnumVerbs
696 * See Windows documentation for more details on IOleObject methods.
698 static HRESULT WINAPI DefaultHandler_EnumVerbs(
699 IOleObject* iface,
700 IEnumOLEVERB** ppEnumOleVerb)
702 DefaultHandler *This = impl_from_IOleObject(iface);
703 HRESULT hr = OLE_S_USEREG;
705 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
707 if (object_is_running(This))
709 start_object_call( This );
710 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
711 end_object_call( This );
714 if (hr == OLE_S_USEREG)
715 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
716 else
717 return hr;
720 static HRESULT WINAPI DefaultHandler_Update(
721 IOleObject* iface)
723 DefaultHandler *This = impl_from_IOleObject(iface);
724 HRESULT hr;
726 TRACE("(%p)\n", iface);
728 if (!object_is_running(This))
730 FIXME("Should run object\n");
731 return E_NOTIMPL;
734 start_object_call( This );
735 hr = IOleObject_Update(This->pOleDelegate);
736 end_object_call( This );
738 return hr;
741 /************************************************************************
742 * DefaultHandler_IsUpToDate (IOleObject)
744 * This method is meaningless if the server is not running
746 * See Windows documentation for more details on IOleObject methods.
748 static HRESULT WINAPI DefaultHandler_IsUpToDate(
749 IOleObject* iface)
751 DefaultHandler *This = impl_from_IOleObject(iface);
752 HRESULT hr = OLE_E_NOTRUNNING;
753 TRACE("(%p)\n", iface);
755 if (object_is_running(This))
757 start_object_call( This );
758 hr = IOleObject_IsUpToDate(This->pOleDelegate);
759 end_object_call( This );
762 return hr;
765 /************************************************************************
766 * DefaultHandler_GetUserClassID (IOleObject)
768 * TODO: Map to a new class ID if emulation is active.
770 * See Windows documentation for more details on IOleObject methods.
772 static HRESULT WINAPI DefaultHandler_GetUserClassID(
773 IOleObject* iface,
774 CLSID* pClsid)
776 DefaultHandler *This = impl_from_IOleObject(iface);
777 HRESULT hr;
779 TRACE("(%p, %p)\n", iface, pClsid);
781 if (object_is_running(This))
783 start_object_call( This );
784 hr = IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
785 end_object_call( This );
786 return hr;
789 if (!pClsid)
790 return E_POINTER;
792 *pClsid = This->clsid;
794 return S_OK;
797 /************************************************************************
798 * DefaultHandler_GetUserType (IOleObject)
800 * The default handler implementation of this method simply delegates
801 * to OleRegGetUserType
803 * See Windows documentation for more details on IOleObject methods.
805 static HRESULT WINAPI DefaultHandler_GetUserType(
806 IOleObject* iface,
807 DWORD dwFormOfType,
808 LPOLESTR* pszUserType)
810 DefaultHandler *This = impl_from_IOleObject(iface);
811 HRESULT hr;
813 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
814 if (object_is_running(This))
816 start_object_call( This );
817 hr = IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
818 end_object_call( This );
819 return hr;
822 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
825 /************************************************************************
826 * DefaultHandler_SetExtent (IOleObject)
828 * This method is meaningless if the server is not running
830 * See Windows documentation for more details on IOleObject methods.
832 static HRESULT WINAPI DefaultHandler_SetExtent(
833 IOleObject* iface,
834 DWORD dwDrawAspect,
835 SIZEL* psizel)
837 DefaultHandler *This = impl_from_IOleObject(iface);
838 HRESULT hr = OLE_E_NOTRUNNING;
840 TRACE("(%p, %x, (%d x %d))\n", iface,
841 dwDrawAspect, psizel->cx, psizel->cy);
843 if (object_is_running(This))
845 start_object_call( This );
846 hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
847 end_object_call( This );
850 return hr;
853 /************************************************************************
854 * DefaultHandler_GetExtent (IOleObject)
856 * The default handler's implementation of this method returns uses
857 * the cache to locate the aspect and extract the extent from it.
859 * See Windows documentation for more details on IOleObject methods.
861 static HRESULT WINAPI DefaultHandler_GetExtent(
862 IOleObject* iface,
863 DWORD dwDrawAspect,
864 SIZEL* psizel)
866 DVTARGETDEVICE* targetDevice;
867 IViewObject2* cacheView = NULL;
868 HRESULT hres;
870 DefaultHandler *This = impl_from_IOleObject(iface);
872 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
874 if (object_is_running(This))
876 start_object_call( This );
877 hres = IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
878 end_object_call( This );
879 return hres;
882 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
883 if (FAILED(hres))
884 return E_UNEXPECTED;
887 * Prepare the call to the cache's GetExtent method.
889 * Here we would build a valid DVTARGETDEVICE structure
890 * but, since we are calling into the data cache, we
891 * know its implementation and we'll skip this
892 * extra work until later.
894 targetDevice = NULL;
896 hres = IViewObject2_GetExtent(cacheView,
897 dwDrawAspect,
899 targetDevice,
900 psizel);
902 IViewObject2_Release(cacheView);
904 return hres;
907 /************************************************************************
908 * DefaultHandler_Advise (IOleObject)
910 * The default handler's implementation of this method simply
911 * delegates to the OleAdviseHolder.
913 * See Windows documentation for more details on IOleObject methods.
915 static HRESULT WINAPI DefaultHandler_Advise(
916 IOleObject* iface,
917 IAdviseSink* pAdvSink,
918 DWORD* pdwConnection)
920 HRESULT hres = S_OK;
921 DefaultHandler *This = impl_from_IOleObject(iface);
923 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
925 /* Make sure we have an advise holder before we start. */
926 if (!This->oleAdviseHolder)
927 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
929 if (SUCCEEDED(hres))
930 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
931 pAdvSink,
932 pdwConnection);
934 return hres;
937 /************************************************************************
938 * DefaultHandler_Unadvise (IOleObject)
940 * The default handler's implementation of this method simply
941 * delegates to the OleAdviseHolder.
943 * See Windows documentation for more details on IOleObject methods.
945 static HRESULT WINAPI DefaultHandler_Unadvise(
946 IOleObject* iface,
947 DWORD dwConnection)
949 DefaultHandler *This = impl_from_IOleObject(iface);
951 TRACE("(%p, %d)\n", iface, dwConnection);
954 * If we don't have an advise holder yet, it means we don't have
955 * a connection.
957 if (!This->oleAdviseHolder)
958 return OLE_E_NOCONNECTION;
960 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
961 dwConnection);
964 /************************************************************************
965 * DefaultHandler_EnumAdvise (IOleObject)
967 * The default handler's implementation of this method simply
968 * delegates to the OleAdviseHolder.
970 * See Windows documentation for more details on IOleObject methods.
972 static HRESULT WINAPI DefaultHandler_EnumAdvise(
973 IOleObject* iface,
974 IEnumSTATDATA** ppenumAdvise)
976 DefaultHandler *This = impl_from_IOleObject(iface);
978 TRACE("(%p, %p)\n", iface, ppenumAdvise);
980 if (!ppenumAdvise)
981 return E_POINTER;
983 *ppenumAdvise = NULL;
985 if (!This->oleAdviseHolder)
986 return S_OK;
988 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
991 /************************************************************************
992 * DefaultHandler_GetMiscStatus (IOleObject)
994 * The default handler's implementation of this method simply delegates
995 * to OleRegGetMiscStatus.
997 * See Windows documentation for more details on IOleObject methods.
999 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
1000 IOleObject* iface,
1001 DWORD dwAspect,
1002 DWORD* pdwStatus)
1004 HRESULT hres;
1005 DefaultHandler *This = impl_from_IOleObject(iface);
1007 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
1009 if (object_is_running(This))
1011 start_object_call( This );
1012 hres = IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
1013 end_object_call( This );
1014 return hres;
1017 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
1019 if (FAILED(hres))
1020 *pdwStatus = 0;
1022 return hres;
1025 /************************************************************************
1026 * DefaultHandler_SetColorScheme (IOleObject)
1028 * This method is meaningless if the server is not running
1030 * See Windows documentation for more details on IOleObject methods.
1032 static HRESULT WINAPI DefaultHandler_SetColorScheme(
1033 IOleObject* iface,
1034 struct tagLOGPALETTE* pLogpal)
1036 DefaultHandler *This = impl_from_IOleObject(iface);
1037 HRESULT hr = OLE_E_NOTRUNNING;
1039 TRACE("(%p, %p))\n", iface, pLogpal);
1041 if (object_is_running(This))
1043 start_object_call( This );
1044 hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
1045 end_object_call( This );
1048 return hr;
1051 /*********************************************************
1052 * Methods implementation for the IDataObject part of
1053 * the DefaultHandler class.
1056 /************************************************************************
1057 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
1059 * See Windows documentation for more details on IUnknown methods.
1061 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
1062 IDataObject* iface,
1063 REFIID riid,
1064 void** ppvObject)
1066 DefaultHandler *This = impl_from_IDataObject(iface);
1068 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1071 /************************************************************************
1072 * DefaultHandler_IDataObject_AddRef (IUnknown)
1074 * See Windows documentation for more details on IUnknown methods.
1076 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
1077 IDataObject* iface)
1079 DefaultHandler *This = impl_from_IDataObject(iface);
1081 return IUnknown_AddRef(This->outerUnknown);
1084 /************************************************************************
1085 * DefaultHandler_IDataObject_Release (IUnknown)
1087 * See Windows documentation for more details on IUnknown methods.
1089 static ULONG WINAPI DefaultHandler_IDataObject_Release(
1090 IDataObject* iface)
1092 DefaultHandler *This = impl_from_IDataObject(iface);
1094 return IUnknown_Release(This->outerUnknown);
1097 /************************************************************************
1098 * DefaultHandler_GetData
1100 * Get Data from a source dataobject using format pformatetcIn->cfFormat
1101 * See Windows documentation for more details on GetData.
1102 * Default handler's implementation of this method delegates to the cache.
1104 static HRESULT WINAPI DefaultHandler_GetData(
1105 IDataObject* iface,
1106 LPFORMATETC pformatetcIn,
1107 STGMEDIUM* pmedium)
1109 IDataObject* cacheDataObject = NULL;
1110 HRESULT hres;
1112 DefaultHandler *This = impl_from_IDataObject(iface);
1114 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
1116 hres = IUnknown_QueryInterface(This->dataCache,
1117 &IID_IDataObject,
1118 (void**)&cacheDataObject);
1120 if (FAILED(hres))
1121 return E_UNEXPECTED;
1123 hres = IDataObject_GetData(cacheDataObject,
1124 pformatetcIn,
1125 pmedium);
1127 IDataObject_Release(cacheDataObject);
1129 if (hres == S_OK) return hres;
1131 if (object_is_running( This ))
1133 start_object_call(This);
1134 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1135 end_object_call(This);
1136 if (hres == S_OK) return hres;
1139 /* Query running state again, as the object may have closed during _GetData call */
1140 if (!object_is_running( This ))
1141 hres = OLE_E_NOTRUNNING;
1143 return hres;
1146 static HRESULT WINAPI DefaultHandler_GetDataHere(
1147 IDataObject* iface,
1148 LPFORMATETC pformatetc,
1149 STGMEDIUM* pmedium)
1151 FIXME(": Stub\n");
1152 return E_NOTIMPL;
1155 /************************************************************************
1156 * DefaultHandler_QueryGetData (IDataObject)
1158 * The default handler's implementation of this method delegates to
1159 * the cache.
1161 * See Windows documentation for more details on IDataObject methods.
1163 static HRESULT WINAPI DefaultHandler_QueryGetData(
1164 IDataObject* iface,
1165 LPFORMATETC pformatetc)
1167 IDataObject* cacheDataObject = NULL;
1168 HRESULT hres;
1170 DefaultHandler *This = impl_from_IDataObject(iface);
1172 TRACE("(%p, %p)\n", iface, pformatetc);
1174 hres = IUnknown_QueryInterface(This->dataCache,
1175 &IID_IDataObject,
1176 (void**)&cacheDataObject);
1178 if (FAILED(hres))
1179 return E_UNEXPECTED;
1181 hres = IDataObject_QueryGetData(cacheDataObject,
1182 pformatetc);
1184 IDataObject_Release(cacheDataObject);
1186 if (hres == S_OK) return hres;
1188 if (object_is_running( This ))
1190 start_object_call( This );
1191 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1192 end_object_call( This );
1193 if (hres == S_OK) return hres;
1196 /* Query running state again, as the object may have closed during _QueryGetData call */
1197 if (!object_is_running( This ))
1198 hres = OLE_E_NOTRUNNING;
1200 return hres;
1203 /************************************************************************
1204 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1206 * This method is meaningless if the server is not running
1208 * See Windows documentation for more details on IDataObject methods.
1210 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1211 IDataObject* iface,
1212 LPFORMATETC pformatetcIn,
1213 LPFORMATETC pformatetcOut)
1215 DefaultHandler *This = impl_from_IDataObject(iface);
1216 HRESULT hr;
1218 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1220 if (!object_is_running( This ))
1221 return OLE_E_NOTRUNNING;
1223 start_object_call( This );
1224 hr = IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1225 end_object_call( This );
1227 return hr;
1230 /************************************************************************
1231 * DefaultHandler_SetData (IDataObject)
1233 * The default handler's implementation of this method delegates to
1234 * the cache.
1236 * See Windows documentation for more details on IDataObject methods.
1238 static HRESULT WINAPI DefaultHandler_SetData(
1239 IDataObject* iface,
1240 LPFORMATETC pformatetc,
1241 STGMEDIUM* pmedium,
1242 BOOL fRelease)
1244 DefaultHandler *This = impl_from_IDataObject(iface);
1245 IDataObject* cacheDataObject = NULL;
1246 HRESULT hres;
1248 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1250 hres = IUnknown_QueryInterface(This->dataCache,
1251 &IID_IDataObject,
1252 (void**)&cacheDataObject);
1254 if (FAILED(hres))
1255 return E_UNEXPECTED;
1257 hres = IDataObject_SetData(cacheDataObject,
1258 pformatetc,
1259 pmedium,
1260 fRelease);
1262 IDataObject_Release(cacheDataObject);
1264 return hres;
1267 /************************************************************************
1268 * DefaultHandler_EnumFormatEtc (IDataObject)
1270 * The default handler's implementation of This method simply delegates
1271 * to OleRegEnumFormatEtc.
1273 * See Windows documentation for more details on IDataObject methods.
1275 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1276 IDataObject* iface,
1277 DWORD dwDirection,
1278 IEnumFORMATETC** ppenumFormatEtc)
1280 DefaultHandler *This = impl_from_IDataObject(iface);
1282 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1284 return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1287 /************************************************************************
1288 * DefaultHandler_DAdvise (IDataObject)
1290 * The default handler's implementation of this method simply
1291 * delegates to the DataAdviseHolder.
1293 * See Windows documentation for more details on IDataObject methods.
1295 static HRESULT WINAPI DefaultHandler_DAdvise(
1296 IDataObject* iface,
1297 FORMATETC* pformatetc,
1298 DWORD advf,
1299 IAdviseSink* pAdvSink,
1300 DWORD* pdwConnection)
1302 HRESULT hres = S_OK;
1303 DefaultHandler *This = impl_from_IDataObject(iface);
1305 TRACE("(%p, %p, %d, %p, %p)\n",
1306 iface, pformatetc, advf, pAdvSink, pdwConnection);
1308 /* Make sure we have a data advise holder before we start. */
1309 if (!This->dataAdviseHolder)
1311 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1312 if (SUCCEEDED(hres) && object_is_running( This ))
1314 start_object_call( This );
1315 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1316 end_object_call( This );
1320 if (SUCCEEDED(hres))
1321 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1322 iface,
1323 pformatetc,
1324 advf,
1325 pAdvSink,
1326 pdwConnection);
1328 return hres;
1331 /************************************************************************
1332 * DefaultHandler_DUnadvise (IDataObject)
1334 * The default handler's implementation of this method simply
1335 * delegates to the DataAdviseHolder.
1337 * See Windows documentation for more details on IDataObject methods.
1339 static HRESULT WINAPI DefaultHandler_DUnadvise(
1340 IDataObject* iface,
1341 DWORD dwConnection)
1343 DefaultHandler *This = impl_from_IDataObject(iface);
1345 TRACE("(%p, %d)\n", iface, dwConnection);
1348 * If we don't have a data advise holder yet, it means that
1349 * we don't have any connections..
1351 if (!This->dataAdviseHolder)
1352 return OLE_E_NOCONNECTION;
1354 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1355 dwConnection);
1358 /************************************************************************
1359 * DefaultHandler_EnumDAdvise (IDataObject)
1361 * The default handler's implementation of this method simply
1362 * delegates to the DataAdviseHolder.
1364 * See Windows documentation for more details on IDataObject methods.
1366 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1367 IDataObject* iface,
1368 IEnumSTATDATA** ppenumAdvise)
1370 DefaultHandler *This = impl_from_IDataObject(iface);
1372 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1374 if (!ppenumAdvise)
1375 return E_POINTER;
1377 *ppenumAdvise = NULL;
1379 /* If we have a data advise holder object, delegate. */
1380 if (This->dataAdviseHolder)
1381 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1382 ppenumAdvise);
1384 return S_OK;
1387 /*********************************************************
1388 * Methods implementation for the IRunnableObject part
1389 * of the DefaultHandler class.
1392 /************************************************************************
1393 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1395 * See Windows documentation for more details on IUnknown methods.
1397 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1398 IRunnableObject* iface,
1399 REFIID riid,
1400 void** ppvObject)
1402 DefaultHandler *This = impl_from_IRunnableObject(iface);
1404 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1407 /************************************************************************
1408 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1410 * See Windows documentation for more details on IUnknown methods.
1412 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1413 IRunnableObject* iface)
1415 DefaultHandler *This = impl_from_IRunnableObject(iface);
1417 return IUnknown_AddRef(This->outerUnknown);
1420 /************************************************************************
1421 * DefaultHandler_IRunnableObject_Release (IUnknown)
1423 * See Windows documentation for more details on IUnknown methods.
1425 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1426 IRunnableObject* iface)
1428 DefaultHandler *This = impl_from_IRunnableObject(iface);
1430 return IUnknown_Release(This->outerUnknown);
1433 /************************************************************************
1434 * DefaultHandler_GetRunningClass (IRunnableObject)
1436 * See Windows documentation for more details on IRunnableObject methods.
1438 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1439 IRunnableObject* iface,
1440 LPCLSID lpClsid)
1442 FIXME("()\n");
1443 return S_OK;
1446 static HRESULT WINAPI DefaultHandler_Run(
1447 IRunnableObject* iface,
1448 IBindCtx* pbc)
1450 DefaultHandler *This = impl_from_IRunnableObject(iface);
1451 HRESULT hr;
1452 IOleCacheControl *cache_ctrl;
1454 FIXME("(%p): semi-stub\n", pbc);
1456 /* already running? if so nothing to do */
1457 if (object_is_running(This))
1458 return S_OK;
1460 release_delegates(This);
1462 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
1463 &IID_IOleObject, (void **)&This->pOleDelegate);
1464 if (FAILED(hr))
1465 return hr;
1467 hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
1468 if (FAILED(hr)) goto fail;
1470 if (This->clientSite)
1472 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1473 if (FAILED(hr)) goto fail;
1476 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1477 (void **)&This->pPSDelegate);
1478 if (FAILED(hr)) goto fail;
1480 if (This->storage_state == storage_state_initialised)
1481 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1482 else if (This->storage_state == storage_state_loaded)
1483 hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1484 if (FAILED(hr)) goto fail;
1486 if (This->containerApp)
1488 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1489 This->containerObj);
1490 if (FAILED(hr)) goto fail;
1493 /* FIXME: do more stuff here:
1494 * - IOleObject_GetMiscStatus
1495 * - IOleObject_GetMoniker
1498 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1499 (void **)&This->pDataDelegate);
1500 if (FAILED(hr)) goto fail;
1502 This->object_state = object_state_running;
1504 if (This->dataAdviseHolder)
1506 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1507 if (FAILED(hr)) goto fail;
1510 hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
1511 if (FAILED(hr)) goto fail;
1512 hr = IOleCacheControl_OnRun( cache_ctrl, This->pDataDelegate );
1513 IOleCacheControl_Release( cache_ctrl );
1514 if (FAILED(hr)) goto fail;
1516 return hr;
1518 fail:
1519 DefaultHandler_Stop(This);
1520 return hr;
1523 /************************************************************************
1524 * DefaultHandler_IsRunning (IRunnableObject)
1526 * See Windows documentation for more details on IRunnableObject methods.
1528 static BOOL WINAPI DefaultHandler_IsRunning(
1529 IRunnableObject* iface)
1531 DefaultHandler *This = impl_from_IRunnableObject(iface);
1533 TRACE("()\n");
1535 if (This->object_state == object_state_running)
1536 return TRUE;
1537 else
1538 return FALSE;
1541 /************************************************************************
1542 * DefaultHandler_LockRunning (IRunnableObject)
1544 * See Windows documentation for more details on IRunnableObject methods.
1546 static HRESULT WINAPI DefaultHandler_LockRunning(
1547 IRunnableObject* iface,
1548 BOOL fLock,
1549 BOOL fLastUnlockCloses)
1551 FIXME("()\n");
1552 return S_OK;
1555 /************************************************************************
1556 * DefaultHandler_SetContainedObject (IRunnableObject)
1558 * See Windows documentation for more details on IRunnableObject methods.
1560 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1561 IRunnableObject* iface,
1562 BOOL fContained)
1564 FIXME("()\n");
1565 return S_OK;
1568 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1569 IAdviseSink *iface,
1570 REFIID riid,
1571 void **ppvObject)
1573 if (IsEqualIID(riid, &IID_IUnknown) ||
1574 IsEqualIID(riid, &IID_IAdviseSink))
1576 *ppvObject = iface;
1577 IAdviseSink_AddRef(iface);
1578 return S_OK;
1581 return E_NOINTERFACE;
1584 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1585 IAdviseSink *iface)
1587 DefaultHandler *This = impl_from_IAdviseSink(iface);
1589 return IUnknown_AddRef(&This->IUnknown_iface);
1592 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1593 IAdviseSink *iface)
1595 DefaultHandler *This = impl_from_IAdviseSink(iface);
1597 return IUnknown_Release(&This->IUnknown_iface);
1600 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1601 IAdviseSink *iface,
1602 FORMATETC *pFormatetc,
1603 STGMEDIUM *pStgmed)
1605 FIXME(": stub\n");
1608 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1609 IAdviseSink *iface,
1610 DWORD dwAspect,
1611 LONG lindex)
1613 FIXME(": stub\n");
1616 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1617 IAdviseSink *iface,
1618 IMoniker *pmk)
1620 DefaultHandler *This = impl_from_IAdviseSink(iface);
1622 TRACE("(%p)\n", pmk);
1624 if (This->oleAdviseHolder)
1625 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1628 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1629 IAdviseSink *iface)
1631 DefaultHandler *This = impl_from_IAdviseSink(iface);
1633 TRACE("()\n");
1635 if (This->oleAdviseHolder)
1636 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1639 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1640 IAdviseSink *iface)
1642 DefaultHandler *This = impl_from_IAdviseSink(iface);
1644 TRACE("()\n");
1646 if (This->oleAdviseHolder)
1647 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1649 if(!This->in_call)
1650 DefaultHandler_Stop(This);
1651 else
1653 TRACE("OnClose during call. Deferring shutdown\n");
1654 This->object_state = object_state_deferred_close;
1658 /************************************************************************
1659 * DefaultHandler_IPersistStorage_QueryInterface
1662 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1663 IPersistStorage* iface,
1664 REFIID riid,
1665 void** ppvObject)
1667 DefaultHandler *This = impl_from_IPersistStorage(iface);
1669 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1672 /************************************************************************
1673 * DefaultHandler_IPersistStorage_AddRef
1676 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1677 IPersistStorage* iface)
1679 DefaultHandler *This = impl_from_IPersistStorage(iface);
1681 return IUnknown_AddRef(This->outerUnknown);
1684 /************************************************************************
1685 * DefaultHandler_IPersistStorage_Release
1688 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1689 IPersistStorage* iface)
1691 DefaultHandler *This = impl_from_IPersistStorage(iface);
1693 return IUnknown_Release(This->outerUnknown);
1696 /************************************************************************
1697 * DefaultHandler_IPersistStorage_GetClassID
1700 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1701 IPersistStorage* iface,
1702 CLSID* clsid)
1704 DefaultHandler *This = impl_from_IPersistStorage(iface);
1705 HRESULT hr;
1707 TRACE("(%p)->(%p)\n", iface, clsid);
1709 if(object_is_running(This))
1711 start_object_call( This );
1712 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1713 end_object_call( This );
1715 else
1716 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1718 return hr;
1721 /************************************************************************
1722 * DefaultHandler_IPersistStorage_IsDirty
1725 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1726 IPersistStorage* iface)
1728 DefaultHandler *This = impl_from_IPersistStorage(iface);
1729 HRESULT hr;
1731 TRACE("(%p)\n", iface);
1733 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1734 if(hr != S_FALSE) return hr;
1736 if(object_is_running(This))
1738 start_object_call( This );
1739 hr = IPersistStorage_IsDirty(This->pPSDelegate);
1740 end_object_call( This );
1743 return hr;
1746 /***********************************************************************
1748 * The format of '\1Ole' stream is as follows:
1750 * DWORD Version == 0x02000001
1751 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1752 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1753 * supplied by the app that creates the data structure. May be
1754 * ignored on processing].
1756 * DWORD Reserved == 0
1757 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1758 * CLSID clsid - class id of object capable of processing the moniker
1759 * BYTE data[] - moniker data for a link
1762 static const WCHAR OleStream[] = {1,'O','l','e',0};
1763 typedef struct
1765 DWORD version;
1766 DWORD flags;
1767 DWORD link_update_opt;
1768 DWORD res;
1769 DWORD moniker_size;
1770 } ole_stream_header_t;
1771 static const DWORD ole_stream_version = 0x02000001;
1773 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1775 IStream *stream;
1776 HRESULT hr;
1778 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1780 if(SUCCEEDED(hr))
1782 DWORD read;
1783 ole_stream_header_t header;
1785 hr = IStream_Read(stream, &header, sizeof(header), &read);
1786 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1788 if(header.flags & 1)
1790 /* FIXME: Read the moniker and deal with the link */
1791 FIXME("Linked objects are not supported yet\n");
1794 else
1796 WARN("Incorrect OleStream header\n");
1797 hr = DV_E_CLIPFORMAT;
1799 IStream_Release(stream);
1801 else
1802 hr = STORAGE_CreateOleStream(storage, 0);
1804 return hr;
1807 /************************************************************************
1808 * DefaultHandler_IPersistStorage_InitNew
1811 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1812 IPersistStorage* iface,
1813 IStorage* pStg)
1815 DefaultHandler *This = impl_from_IPersistStorage(iface);
1816 HRESULT hr;
1818 TRACE("(%p)->(%p)\n", iface, pStg);
1819 hr = STORAGE_CreateOleStream(pStg, 0);
1820 if (hr != S_OK) return hr;
1822 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1824 if(SUCCEEDED(hr) && object_is_running(This))
1826 start_object_call( This );
1827 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1828 end_object_call( This );
1831 if(SUCCEEDED(hr))
1833 IStorage_AddRef(pStg);
1834 This->storage = pStg;
1835 This->storage_state = storage_state_initialised;
1838 return hr;
1842 /************************************************************************
1843 * DefaultHandler_IPersistStorage_Load
1846 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1847 IPersistStorage* iface,
1848 IStorage* pStg)
1850 DefaultHandler *This = impl_from_IPersistStorage(iface);
1851 HRESULT hr;
1853 TRACE("(%p)->(%p)\n", iface, pStg);
1855 hr = load_ole_stream(This, pStg);
1857 if(SUCCEEDED(hr))
1858 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1860 if(SUCCEEDED(hr) && object_is_running(This))
1862 start_object_call( This );
1863 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1864 end_object_call( This );
1867 if(SUCCEEDED(hr))
1869 IStorage_AddRef(pStg);
1870 This->storage = pStg;
1871 This->storage_state = storage_state_loaded;
1873 return hr;
1877 /************************************************************************
1878 * DefaultHandler_IPersistStorage_Save
1881 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1882 IPersistStorage* iface,
1883 IStorage* pStgSave,
1884 BOOL fSameAsLoad)
1886 DefaultHandler *This = impl_from_IPersistStorage(iface);
1887 HRESULT hr;
1889 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1891 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1892 if(SUCCEEDED(hr) && object_is_running(This))
1894 start_object_call( This );
1895 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1896 end_object_call( This );
1899 return hr;
1903 /************************************************************************
1904 * DefaultHandler_IPersistStorage_SaveCompleted
1907 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1908 IPersistStorage* iface,
1909 IStorage* pStgNew)
1911 DefaultHandler *This = impl_from_IPersistStorage(iface);
1912 HRESULT hr;
1914 TRACE("(%p)->(%p)\n", iface, pStgNew);
1916 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1918 if(SUCCEEDED(hr) && object_is_running(This))
1920 start_object_call( This );
1921 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1922 end_object_call( This );
1925 if(pStgNew)
1927 IStorage_AddRef(pStgNew);
1928 if(This->storage) IStorage_Release(This->storage);
1929 This->storage = pStgNew;
1930 This->storage_state = storage_state_loaded;
1933 return hr;
1937 /************************************************************************
1938 * DefaultHandler_IPersistStorage_HandsOffStorage
1941 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1942 IPersistStorage* iface)
1944 DefaultHandler *This = impl_from_IPersistStorage(iface);
1945 HRESULT hr;
1947 TRACE("(%p)\n", iface);
1949 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1951 if(SUCCEEDED(hr) && object_is_running(This))
1953 start_object_call( This );
1954 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1955 end_object_call( This );
1958 if(This->storage) IStorage_Release(This->storage);
1959 This->storage = NULL;
1960 This->storage_state = storage_state_uninitialised;
1962 return hr;
1967 * Virtual function tables for the DefaultHandler class.
1969 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1971 DefaultHandler_QueryInterface,
1972 DefaultHandler_AddRef,
1973 DefaultHandler_Release,
1974 DefaultHandler_SetClientSite,
1975 DefaultHandler_GetClientSite,
1976 DefaultHandler_SetHostNames,
1977 DefaultHandler_Close,
1978 DefaultHandler_SetMoniker,
1979 DefaultHandler_GetMoniker,
1980 DefaultHandler_InitFromData,
1981 DefaultHandler_GetClipboardData,
1982 DefaultHandler_DoVerb,
1983 DefaultHandler_EnumVerbs,
1984 DefaultHandler_Update,
1985 DefaultHandler_IsUpToDate,
1986 DefaultHandler_GetUserClassID,
1987 DefaultHandler_GetUserType,
1988 DefaultHandler_SetExtent,
1989 DefaultHandler_GetExtent,
1990 DefaultHandler_Advise,
1991 DefaultHandler_Unadvise,
1992 DefaultHandler_EnumAdvise,
1993 DefaultHandler_GetMiscStatus,
1994 DefaultHandler_SetColorScheme
1997 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1999 DefaultHandler_NDIUnknown_QueryInterface,
2000 DefaultHandler_NDIUnknown_AddRef,
2001 DefaultHandler_NDIUnknown_Release,
2004 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
2006 DefaultHandler_IDataObject_QueryInterface,
2007 DefaultHandler_IDataObject_AddRef,
2008 DefaultHandler_IDataObject_Release,
2009 DefaultHandler_GetData,
2010 DefaultHandler_GetDataHere,
2011 DefaultHandler_QueryGetData,
2012 DefaultHandler_GetCanonicalFormatEtc,
2013 DefaultHandler_SetData,
2014 DefaultHandler_EnumFormatEtc,
2015 DefaultHandler_DAdvise,
2016 DefaultHandler_DUnadvise,
2017 DefaultHandler_EnumDAdvise
2020 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
2022 DefaultHandler_IRunnableObject_QueryInterface,
2023 DefaultHandler_IRunnableObject_AddRef,
2024 DefaultHandler_IRunnableObject_Release,
2025 DefaultHandler_GetRunningClass,
2026 DefaultHandler_Run,
2027 DefaultHandler_IsRunning,
2028 DefaultHandler_LockRunning,
2029 DefaultHandler_SetContainedObject
2032 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
2034 DefaultHandler_IAdviseSink_QueryInterface,
2035 DefaultHandler_IAdviseSink_AddRef,
2036 DefaultHandler_IAdviseSink_Release,
2037 DefaultHandler_IAdviseSink_OnDataChange,
2038 DefaultHandler_IAdviseSink_OnViewChange,
2039 DefaultHandler_IAdviseSink_OnRename,
2040 DefaultHandler_IAdviseSink_OnSave,
2041 DefaultHandler_IAdviseSink_OnClose
2044 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
2046 DefaultHandler_IPersistStorage_QueryInterface,
2047 DefaultHandler_IPersistStorage_AddRef,
2048 DefaultHandler_IPersistStorage_Release,
2049 DefaultHandler_IPersistStorage_GetClassID,
2050 DefaultHandler_IPersistStorage_IsDirty,
2051 DefaultHandler_IPersistStorage_InitNew,
2052 DefaultHandler_IPersistStorage_Load,
2053 DefaultHandler_IPersistStorage_Save,
2054 DefaultHandler_IPersistStorage_SaveCompleted,
2055 DefaultHandler_IPersistStorage_HandsOffStorage
2058 /*********************************************************
2059 * Methods implementation for the DefaultHandler class.
2061 static DefaultHandler* DefaultHandler_Construct(
2062 REFCLSID clsid,
2063 LPUNKNOWN pUnkOuter,
2064 DWORD flags,
2065 IClassFactory *pCF)
2067 DefaultHandler* This = NULL;
2068 HRESULT hr;
2070 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
2072 if (!This)
2073 return This;
2075 This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable;
2076 This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable;
2077 This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable;
2078 This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable;
2079 This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable;
2080 This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable;
2082 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) != 0;
2085 * Start with one reference count. The caller of this function
2086 * must release the interface pointer when it is done.
2088 This->ref = 1;
2091 * Initialize the outer unknown
2092 * We don't keep a reference on the outer unknown since, the way
2093 * aggregation works, our lifetime is at least as large as its
2094 * lifetime.
2096 if (!pUnkOuter)
2097 pUnkOuter = &This->IUnknown_iface;
2099 This->outerUnknown = pUnkOuter;
2102 * Create a datacache object.
2103 * We aggregate with the datacache. Make sure we pass our outer
2104 * unknown as the datacache's outer unknown.
2106 hr = CreateDataCache(This->outerUnknown,
2107 clsid,
2108 &IID_IUnknown,
2109 (void**)&This->dataCache);
2110 if(SUCCEEDED(hr))
2112 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
2113 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
2114 * reference on the outer object */
2115 if (SUCCEEDED(hr))
2116 IUnknown_Release(This->outerUnknown);
2117 else
2118 IUnknown_Release(This->dataCache);
2120 if(FAILED(hr))
2122 ERR("Unexpected error creating data cache\n");
2123 HeapFree(GetProcessHeap(), 0, This);
2124 return NULL;
2127 This->clsid = *clsid;
2128 This->clientSite = NULL;
2129 This->oleAdviseHolder = NULL;
2130 This->dataAdviseHolder = NULL;
2131 This->containerApp = NULL;
2132 This->containerObj = NULL;
2133 This->pOleDelegate = NULL;
2134 This->pPSDelegate = NULL;
2135 This->pDataDelegate = NULL;
2136 This->object_state = object_state_not_running;
2137 This->in_call = 0;
2139 This->dwAdvConn = 0;
2140 This->storage = NULL;
2141 This->storage_state = storage_state_uninitialised;
2143 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
2145 HRESULT hr;
2146 This->pCFObject = NULL;
2147 if (pCF)
2148 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
2149 else
2150 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
2151 &IID_IOleObject, (void **)&This->pOleDelegate);
2152 if (SUCCEEDED(hr))
2153 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
2154 if (SUCCEEDED(hr))
2155 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
2156 if (SUCCEEDED(hr))
2157 This->object_state = object_state_running;
2158 if (FAILED(hr))
2159 WARN("object creation failed with error %08x\n", hr);
2161 else
2163 This->pCFObject = pCF;
2164 if (pCF) IClassFactory_AddRef(pCF);
2167 return This;
2170 static void DefaultHandler_Destroy(
2171 DefaultHandler* This)
2173 TRACE("(%p)\n", This);
2175 /* AddRef/Release may be called on this object during destruction.
2176 * Prevent the object being destroyed recursively by artificially raising
2177 * the reference count. */
2178 This->ref = 10000;
2180 /* release delegates */
2181 DefaultHandler_Stop(This);
2183 HeapFree( GetProcessHeap(), 0, This->containerApp );
2184 This->containerApp = NULL;
2185 HeapFree( GetProcessHeap(), 0, This->containerObj );
2186 This->containerObj = NULL;
2188 if (This->dataCache)
2190 /* to balance out the release of dataCache_PersistStg which will result
2191 * in a reference being released from the outer unknown */
2192 IUnknown_AddRef(This->outerUnknown);
2193 IPersistStorage_Release(This->dataCache_PersistStg);
2194 IUnknown_Release(This->dataCache);
2195 This->dataCache_PersistStg = NULL;
2196 This->dataCache = NULL;
2199 if (This->clientSite)
2201 IOleClientSite_Release(This->clientSite);
2202 This->clientSite = NULL;
2205 if (This->oleAdviseHolder)
2207 IOleAdviseHolder_Release(This->oleAdviseHolder);
2208 This->oleAdviseHolder = NULL;
2211 if (This->dataAdviseHolder)
2213 IDataAdviseHolder_Release(This->dataAdviseHolder);
2214 This->dataAdviseHolder = NULL;
2217 if (This->storage)
2219 IStorage_Release(This->storage);
2220 This->storage = NULL;
2223 if (This->pCFObject)
2225 IClassFactory_Release(This->pCFObject);
2226 This->pCFObject = NULL;
2229 HeapFree(GetProcessHeap(), 0, This);
2232 /******************************************************************************
2233 * OleCreateEmbeddingHelper [OLE32.@]
2235 HRESULT WINAPI OleCreateEmbeddingHelper(
2236 REFCLSID clsid,
2237 LPUNKNOWN pUnkOuter,
2238 DWORD flags,
2239 IClassFactory *pCF,
2240 REFIID riid,
2241 LPVOID* ppvObj)
2243 DefaultHandler* newHandler = NULL;
2244 HRESULT hr = S_OK;
2246 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2248 if (!ppvObj)
2249 return E_POINTER;
2251 *ppvObj = NULL;
2254 * If This handler is constructed for aggregation, make sure
2255 * the caller is requesting the IUnknown interface.
2256 * This is necessary because it's the only time the non-delegating
2257 * IUnknown pointer can be returned to the outside.
2259 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2260 return CLASS_E_NOAGGREGATION;
2263 * Try to construct a new instance of the class.
2265 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2267 if (!newHandler)
2268 return E_OUTOFMEMORY;
2271 * Make sure it supports the interface required by the caller.
2273 hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj);
2276 * Release the reference obtained in the constructor. If
2277 * the QueryInterface was unsuccessful, it will free the class.
2279 IUnknown_Release(&newHandler->IUnknown_iface);
2281 return hr;
2285 /******************************************************************************
2286 * OleCreateDefaultHandler [OLE32.@]
2288 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
2289 REFIID riid, LPVOID* ppvObj)
2291 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
2292 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
2293 NULL, riid, ppvObj);
2296 typedef struct HandlerCF
2298 IClassFactory IClassFactory_iface;
2299 LONG refs;
2300 CLSID clsid;
2301 } HandlerCF;
2303 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
2305 return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
2308 static HRESULT WINAPI
2309 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
2311 *ppv = NULL;
2312 if (IsEqualIID(riid,&IID_IUnknown) ||
2313 IsEqualIID(riid,&IID_IClassFactory))
2315 *ppv = iface;
2316 IClassFactory_AddRef(iface);
2317 return S_OK;
2319 return E_NOINTERFACE;
2322 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
2324 HandlerCF *This = impl_from_IClassFactory(iface);
2325 return InterlockedIncrement(&This->refs);
2328 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
2330 HandlerCF *This = impl_from_IClassFactory(iface);
2331 ULONG refs = InterlockedDecrement(&This->refs);
2332 if (!refs)
2333 HeapFree(GetProcessHeap(), 0, This);
2334 return refs;
2337 static HRESULT WINAPI
2338 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
2339 REFIID riid, LPVOID *ppv)
2341 HandlerCF *This = impl_from_IClassFactory(iface);
2342 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
2345 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
2347 FIXME("(%d), stub!\n",fLock);
2348 return S_OK;
2351 static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
2352 HandlerCF_QueryInterface,
2353 HandlerCF_AddRef,
2354 HandlerCF_Release,
2355 HandlerCF_CreateInstance,
2356 HandlerCF_LockServer
2359 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
2361 HRESULT hr;
2362 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2363 if (!This) return E_OUTOFMEMORY;
2364 This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
2365 This->refs = 0;
2366 This->clsid = *rclsid;
2368 hr = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv);
2369 if (FAILED(hr))
2370 HeapFree(GetProcessHeap(), 0, This);
2372 return hr;