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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * The OLE2 default object handler supports a whole whack of
23 * interfaces including:
24 * IOleObject, IDataObject, IPersistStorage, IViewObject2,
25 * IRunnableObject, IOleCache2, IOleCacheControl and much more.
27 * All the implementation details are taken from: Inside OLE
28 * second edition by Kraig Brockschmidt,
31 * - This implementation of the default handler does not launch the
32 * server in the DoVerb, Update, GetData, GetDataHere and Run
33 * methods. When it is fixed to do so, all the methods will have
34 * to be revisited to allow delegating to the running object
36 * - All methods in the class that use the class ID should be
37 * aware that it is possible for a class to be treated as
38 * another one and go into emulation mode. Nothing has been
41 * - Some functions still return E_NOTIMPL they have to be
42 * implemented. Most of those are related to the running of the
45 * - All the methods related to notification and advise sinks are
46 * in place but no notifications are sent to the sinks yet.
60 #include "compobj_private.h"
62 #include "wine/unicode.h"
63 #include "wine/debug.h"
65 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
67 /****************************************************************************
73 const IOleObjectVtbl
* lpVtbl
;
74 const IUnknownVtbl
* lpvtblIUnknown
;
75 const IDataObjectVtbl
* lpvtblIDataObject
;
76 const IRunnableObjectVtbl
* lpvtblIRunnableObject
;
77 const IAdviseSinkVtbl
*lpvtblIAdviseSink
;
79 /* Reference count of this object */
82 /* IUnknown implementation of the outer object. */
83 IUnknown
* outerUnknown
;
85 /* Class Id that this handler object represents. */
88 /* IUnknown implementation of the datacache. */
91 /* Client site for the embedded object. */
92 IOleClientSite
* clientSite
;
95 * The IOleAdviseHolder maintains the connections
96 * on behalf of the default handler.
98 IOleAdviseHolder
* oleAdviseHolder
;
101 * The IDataAdviseHolder maintains the data
102 * connections on behalf of the default handler.
104 IDataAdviseHolder
* dataAdviseHolder
;
106 /* Name of the container and object contained */
110 /* IOleObject delegate */
111 IOleObject
*pOleDelegate
;
112 /* IPersistStorage delegate */
113 IPersistStorage
*pPSDelegate
;
114 /* IDataObject delegate */
115 IDataObject
*pDataDelegate
;
117 /* connection cookie for the advise on the delegate OLE object */
121 typedef struct DefaultHandler DefaultHandler
;
124 * Here, I define utility functions to help with the casting of the
126 * There is a version to accommodate all of the VTables implemented
129 static inline DefaultHandler
*impl_from_IOleObject( IOleObject
*iface
)
131 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpVtbl
));
134 static inline DefaultHandler
*impl_from_NDIUnknown( IUnknown
*iface
)
136 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIUnknown
));
139 static inline DefaultHandler
*impl_from_IDataObject( IDataObject
*iface
)
141 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIDataObject
));
144 static inline DefaultHandler
*impl_from_IRunnableObject( IRunnableObject
*iface
)
146 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIRunnableObject
));
149 static inline DefaultHandler
*impl_from_IAdviseSink( IAdviseSink
*iface
)
151 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIAdviseSink
));
154 static void DefaultHandler_Destroy(DefaultHandler
* This
);
157 /*********************************************************
158 * Method implementation for the non delegating IUnknown
159 * part of the DefaultHandler class.
162 /************************************************************************
163 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
165 * See Windows documentation for more details on IUnknown methods.
167 * This version of QueryInterface will not delegate it's implementation
168 * to the outer unknown.
170 static HRESULT WINAPI
DefaultHandler_NDIUnknown_QueryInterface(
175 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
177 /* Perform a sanity check on the parameters. */
183 if (IsEqualIID(&IID_IUnknown
, riid
))
185 else if (IsEqualIID(&IID_IOleObject
, riid
))
186 *ppvObject
= (IOleObject
*)&This
->lpVtbl
;
187 else if (IsEqualIID(&IID_IDataObject
, riid
))
188 *ppvObject
= (IDataObject
*)&This
->lpvtblIDataObject
;
189 else if (IsEqualIID(&IID_IRunnableObject
, riid
))
190 *ppvObject
= (IRunnableObject
*)&This
->lpvtblIRunnableObject
;
191 else if (IsEqualIID(&IID_IPersist
, riid
) ||
192 IsEqualIID(&IID_IPersistStorage
, riid
) ||
193 IsEqualIID(&IID_IViewObject
, riid
) ||
194 IsEqualIID(&IID_IViewObject2
, riid
) ||
195 IsEqualIID(&IID_IOleCache
, riid
) ||
196 IsEqualIID(&IID_IOleCache2
, riid
))
198 HRESULT hr
= IUnknown_QueryInterface(This
->dataCache
, riid
, ppvObject
);
199 if (FAILED(hr
)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid
));
203 /* Check that we obtained an interface. */
204 if (*ppvObject
== NULL
)
206 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid
));
207 return E_NOINTERFACE
;
211 * Query Interface always increases the reference count by one when it is
214 IUnknown_AddRef((IUnknown
*)*ppvObject
);
219 /************************************************************************
220 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
222 * See Windows documentation for more details on IUnknown methods.
224 * This version of QueryInterface will not delegate it's implementation
225 * to the outer unknown.
227 static ULONG WINAPI
DefaultHandler_NDIUnknown_AddRef(
230 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
231 return InterlockedIncrement(&This
->ref
);
234 /************************************************************************
235 * DefaultHandler_NDIUnknown_Release (IUnknown)
237 * See Windows documentation for more details on IUnknown methods.
239 * This version of QueryInterface will not delegate it's implementation
240 * to the outer unknown.
242 static ULONG WINAPI
DefaultHandler_NDIUnknown_Release(
245 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
248 /* Decrease the reference count on this object. */
249 ref
= InterlockedDecrement(&This
->ref
);
251 if (!ref
) DefaultHandler_Destroy(This
);
256 /*********************************************************
257 * Methods implementation for the IOleObject part of
258 * the DefaultHandler class.
261 /************************************************************************
262 * DefaultHandler_QueryInterface (IUnknown)
264 * See Windows documentation for more details on IUnknown methods.
266 static HRESULT WINAPI
DefaultHandler_QueryInterface(
271 DefaultHandler
*This
= impl_from_IOleObject(iface
);
273 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
276 /************************************************************************
277 * DefaultHandler_AddRef (IUnknown)
279 * See Windows documentation for more details on IUnknown methods.
281 static ULONG WINAPI
DefaultHandler_AddRef(
284 DefaultHandler
*This
= impl_from_IOleObject(iface
);
286 return IUnknown_AddRef(This
->outerUnknown
);
289 /************************************************************************
290 * DefaultHandler_Release (IUnknown)
292 * See Windows documentation for more details on IUnknown methods.
294 static ULONG WINAPI
DefaultHandler_Release(
297 DefaultHandler
*This
= impl_from_IOleObject(iface
);
299 return IUnknown_Release(This
->outerUnknown
);
302 /************************************************************************
303 * DefaultHandler_SetClientSite (IOleObject)
305 * The default handler's implementation of this method only keeps the
306 * client site pointer for future reference.
308 * See Windows documentation for more details on IOleObject methods.
310 static HRESULT WINAPI
DefaultHandler_SetClientSite(
312 IOleClientSite
* pClientSite
)
314 DefaultHandler
*This
= impl_from_IOleObject(iface
);
317 TRACE("(%p, %p)\n", iface
, pClientSite
);
319 if (This
->pOleDelegate
)
320 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, pClientSite
);
323 * Make sure we release the previous client site if there
326 if (This
->clientSite
)
327 IOleClientSite_Release(This
->clientSite
);
329 This
->clientSite
= pClientSite
;
331 if (This
->clientSite
)
332 IOleClientSite_AddRef(This
->clientSite
);
337 /************************************************************************
338 * DefaultHandler_GetClientSite (IOleObject)
340 * The default handler's implementation of this method returns the
341 * last pointer set in IOleObject_SetClientSite.
343 * See Windows documentation for more details on IOleObject methods.
345 static HRESULT WINAPI
DefaultHandler_GetClientSite(
347 IOleClientSite
** ppClientSite
)
349 DefaultHandler
*This
= impl_from_IOleObject(iface
);
355 *ppClientSite
= This
->clientSite
;
357 if (This
->clientSite
)
358 IOleClientSite_AddRef(This
->clientSite
);
363 /************************************************************************
364 * DefaultHandler_SetHostNames (IOleObject)
366 * The default handler's implementation of this method just stores
367 * the strings and returns S_OK.
369 * See Windows documentation for more details on IOleObject methods.
371 static HRESULT WINAPI
DefaultHandler_SetHostNames(
373 LPCOLESTR szContainerApp
,
374 LPCOLESTR szContainerObj
)
376 DefaultHandler
*This
= impl_from_IOleObject(iface
);
378 TRACE("(%p, %s, %s)\n",
380 debugstr_w(szContainerApp
),
381 debugstr_w(szContainerObj
));
383 if (This
->pOleDelegate
)
384 IOleObject_SetHostNames(This
->pOleDelegate
, szContainerApp
, szContainerObj
);
386 /* Be sure to cleanup before re-assinging the strings. */
387 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
388 This
->containerApp
= NULL
;
389 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
390 This
->containerObj
= NULL
;
392 /* Copy the string supplied. */
395 if ((This
->containerApp
= HeapAlloc( GetProcessHeap(), 0,
396 (lstrlenW(szContainerApp
) + 1) * sizeof(WCHAR
) )))
397 strcpyW( This
->containerApp
, szContainerApp
);
402 if ((This
->containerObj
= HeapAlloc( GetProcessHeap(), 0,
403 (lstrlenW(szContainerObj
) + 1) * sizeof(WCHAR
) )))
404 strcpyW( This
->containerObj
, szContainerObj
);
409 /* undos the work done by DefaultHandler_Run */
410 static void WINAPI
DefaultHandler_Stop(DefaultHandler
*This
)
412 if (!This
->pOleDelegate
)
415 IOleObject_Unadvise(This
->pOleDelegate
, This
->dwAdvConn
);
417 /* FIXME: call IOleCache_OnStop */
419 DataAdviseHolder_OnDisconnect(This
->dataAdviseHolder
);
420 if (This
->pDataDelegate
)
422 IDataObject_Release(This
->pDataDelegate
);
423 This
->pDataDelegate
= NULL
;
425 if (This
->pPSDelegate
)
427 IPersistStorage_Release(This
->pPSDelegate
);
428 This
->pPSDelegate
= NULL
;
430 IOleObject_Release(This
->pOleDelegate
);
431 This
->pOleDelegate
= NULL
;
434 /************************************************************************
435 * DefaultHandler_Close (IOleObject)
437 * The default handler's implementation of this method is meaningless
438 * without a running server so it does nothing.
440 * See Windows documentation for more details on IOleObject methods.
442 static HRESULT WINAPI
DefaultHandler_Close(
446 DefaultHandler
*This
= impl_from_IOleObject(iface
);
449 TRACE("(%ld)\n", dwSaveOption
);
451 if (!This
->pOleDelegate
)
454 hr
= IOleObject_Close(This
->pOleDelegate
, dwSaveOption
);
456 DefaultHandler_Stop(This
);
461 /************************************************************************
462 * DefaultHandler_SetMoniker (IOleObject)
464 * The default handler's implementation of this method does nothing.
466 * See Windows documentation for more details on IOleObject methods.
468 static HRESULT WINAPI
DefaultHandler_SetMoniker(
470 DWORD dwWhichMoniker
,
473 DefaultHandler
*This
= impl_from_IOleObject(iface
);
475 TRACE("(%p, %ld, %p)\n",
480 if (This
->pOleDelegate
)
481 return IOleObject_SetMoniker(This
->pOleDelegate
, dwWhichMoniker
, pmk
);
486 /************************************************************************
487 * DefaultHandler_GetMoniker (IOleObject)
489 * Delegate this request to the client site if we have one.
491 * See Windows documentation for more details on IOleObject methods.
493 static HRESULT WINAPI
DefaultHandler_GetMoniker(
496 DWORD dwWhichMoniker
,
499 DefaultHandler
*This
= impl_from_IOleObject(iface
);
501 TRACE("(%p, %ld, %ld, %p)\n",
502 iface
, dwAssign
, dwWhichMoniker
, ppmk
);
504 if (This
->pOleDelegate
)
505 return IOleObject_GetMoniker(This
->pOleDelegate
, dwAssign
, dwWhichMoniker
,
508 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
509 if (This
->clientSite
)
511 return IOleClientSite_GetMoniker(This
->clientSite
,
521 /************************************************************************
522 * DefaultHandler_InitFromData (IOleObject)
524 * This method is meaningless if the server is not running
526 * See Windows documentation for more details on IOleObject methods.
528 static HRESULT WINAPI
DefaultHandler_InitFromData(
530 IDataObject
* pDataObject
,
534 DefaultHandler
*This
= impl_from_IOleObject(iface
);
536 TRACE("(%p, %p, %d, %ld)\n",
537 iface
, pDataObject
, fCreation
, dwReserved
);
539 if (This
->pOleDelegate
)
540 return IOleObject_InitFromData(This
->pOleDelegate
, pDataObject
, fCreation
,
542 return OLE_E_NOTRUNNING
;
545 /************************************************************************
546 * DefaultHandler_GetClipboardData (IOleObject)
548 * This method is meaningless if the server is not running
550 * See Windows documentation for more details on IOleObject methods.
552 static HRESULT WINAPI
DefaultHandler_GetClipboardData(
555 IDataObject
** ppDataObject
)
557 DefaultHandler
*This
= impl_from_IOleObject(iface
);
559 TRACE("(%p, %ld, %p)\n",
560 iface
, dwReserved
, ppDataObject
);
562 if (This
->pOleDelegate
)
563 return IOleObject_GetClipboardData(This
->pOleDelegate
, dwReserved
,
566 return OLE_E_NOTRUNNING
;
569 static HRESULT WINAPI
DefaultHandler_DoVerb(
572 struct tagMSG
* lpmsg
,
573 IOleClientSite
* pActiveSite
,
578 DefaultHandler
*This
= impl_from_IOleObject(iface
);
579 IRunnableObject
*pRunnableObj
= (IRunnableObject
*)&This
->lpvtblIRunnableObject
;
582 TRACE("(%ld, %p, %p, %ld, %p, %s)\n", iVerb
, lpmsg
, pActiveSite
, lindex
, hwndParent
, wine_dbgstr_rect(lprcPosRect
));
584 hr
= IRunnableObject_Run(pRunnableObj
, NULL
);
585 if (FAILED(hr
)) return hr
;
587 return IOleObject_DoVerb(This
->pOleDelegate
, iVerb
, lpmsg
, pActiveSite
,
588 lindex
, hwndParent
, lprcPosRect
);
591 /************************************************************************
592 * DefaultHandler_EnumVerbs (IOleObject)
594 * The default handler implementation of this method simply delegates
597 * See Windows documentation for more details on IOleObject methods.
599 static HRESULT WINAPI
DefaultHandler_EnumVerbs(
601 IEnumOLEVERB
** ppEnumOleVerb
)
603 DefaultHandler
*This
= impl_from_IOleObject(iface
);
604 HRESULT hr
= OLE_S_USEREG
;
606 TRACE("(%p, %p)\n", iface
, ppEnumOleVerb
);
608 if (This
->pOleDelegate
)
609 hr
= IOleObject_EnumVerbs(This
->pOleDelegate
, ppEnumOleVerb
);
611 if (hr
== OLE_S_USEREG
)
612 return OleRegEnumVerbs(&This
->clsid
, ppEnumOleVerb
);
617 static HRESULT WINAPI
DefaultHandler_Update(
624 /************************************************************************
625 * DefaultHandler_IsUpToDate (IOleObject)
627 * This method is meaningless if the server is not running
629 * See Windows documentation for more details on IOleObject methods.
631 static HRESULT WINAPI
DefaultHandler_IsUpToDate(
634 TRACE("(%p)\n", iface
);
636 return OLE_E_NOTRUNNING
;
639 /************************************************************************
640 * DefaultHandler_GetUserClassID (IOleObject)
642 * TODO: Map to a new class ID if emulation is active.
644 * See Windows documentation for more details on IOleObject methods.
646 static HRESULT WINAPI
DefaultHandler_GetUserClassID(
650 DefaultHandler
*This
= impl_from_IOleObject(iface
);
652 TRACE("(%p, %p)\n", iface
, pClsid
);
654 if (This
->pOleDelegate
)
655 return IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
657 if (This
->pOleDelegate
)
658 return IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
664 memcpy(pClsid
, &This
->clsid
, sizeof(CLSID
));
669 /************************************************************************
670 * DefaultHandler_GetUserType (IOleObject)
672 * The default handler implementation of this method simply delegates
673 * to OleRegGetUserType
675 * See Windows documentation for more details on IOleObject methods.
677 static HRESULT WINAPI
DefaultHandler_GetUserType(
680 LPOLESTR
* pszUserType
)
682 DefaultHandler
*This
= impl_from_IOleObject(iface
);
684 TRACE("(%p, %ld, %p)\n", iface
, dwFormOfType
, pszUserType
);
686 return OleRegGetUserType(&This
->clsid
, dwFormOfType
, pszUserType
);
689 /************************************************************************
690 * DefaultHandler_SetExtent (IOleObject)
692 * This method is meaningless if the server is not running
694 * See Windows documentation for more details on IOleObject methods.
696 static HRESULT WINAPI
DefaultHandler_SetExtent(
701 DefaultHandler
*This
= impl_from_IOleObject(iface
);
703 TRACE("(%p, %lx, (%ld x %ld))\n", iface
,
704 dwDrawAspect
, psizel
->cx
, psizel
->cy
);
706 if (This
->pOleDelegate
)
707 IOleObject_SetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
709 return OLE_E_NOTRUNNING
;
712 /************************************************************************
713 * DefaultHandler_GetExtent (IOleObject)
715 * The default handler's implementation of this method returns uses
716 * the cache to locate the aspect and extract the extent from it.
718 * See Windows documentation for more details on IOleObject methods.
720 static HRESULT WINAPI
DefaultHandler_GetExtent(
725 DVTARGETDEVICE
* targetDevice
;
726 IViewObject2
* cacheView
= NULL
;
729 DefaultHandler
*This
= impl_from_IOleObject(iface
);
731 TRACE("(%p, %lx, %p)\n", iface
, dwDrawAspect
, psizel
);
733 if (This
->pOleDelegate
)
734 return IOleObject_GetExtent(This
->pOleDelegate
, dwDrawAspect
, psizel
);
736 hres
= IUnknown_QueryInterface(This
->dataCache
, &IID_IViewObject2
, (void**)&cacheView
);
741 * Prepare the call to the cache's GetExtent method.
743 * Here we would build a valid DVTARGETDEVICE structure
744 * but, since we are calling into the data cache, we
745 * know it's implementation and we'll skip this
746 * extra work until later.
750 hres
= IViewObject2_GetExtent(cacheView
,
759 IViewObject2_Release(cacheView
);
764 /************************************************************************
765 * DefaultHandler_Advise (IOleObject)
767 * The default handler's implementation of this method simply
768 * delegates to the OleAdviseHolder.
770 * See Windows documentation for more details on IOleObject methods.
772 static HRESULT WINAPI
DefaultHandler_Advise(
774 IAdviseSink
* pAdvSink
,
775 DWORD
* pdwConnection
)
778 DefaultHandler
*This
= impl_from_IOleObject(iface
);
780 TRACE("(%p, %p, %p)\n", iface
, pAdvSink
, pdwConnection
);
782 /* Make sure we have an advise holder before we start. */
783 if (!This
->oleAdviseHolder
)
784 hres
= CreateOleAdviseHolder(&This
->oleAdviseHolder
);
787 hres
= IOleAdviseHolder_Advise(This
->oleAdviseHolder
,
794 /************************************************************************
795 * DefaultHandler_Unadvise (IOleObject)
797 * The default handler's implementation of this method simply
798 * delegates to the OleAdviseHolder.
800 * See Windows documentation for more details on IOleObject methods.
802 static HRESULT WINAPI
DefaultHandler_Unadvise(
806 DefaultHandler
*This
= impl_from_IOleObject(iface
);
808 TRACE("(%p, %ld)\n", iface
, dwConnection
);
811 * If we don't have an advise holder yet, it means we don't have
814 if (!This
->oleAdviseHolder
)
815 return OLE_E_NOCONNECTION
;
817 return IOleAdviseHolder_Unadvise(This
->oleAdviseHolder
,
821 /************************************************************************
822 * DefaultHandler_EnumAdvise (IOleObject)
824 * The default handler's implementation of this method simply
825 * delegates to the OleAdviseHolder.
827 * See Windows documentation for more details on IOleObject methods.
829 static HRESULT WINAPI
DefaultHandler_EnumAdvise(
831 IEnumSTATDATA
** ppenumAdvise
)
833 DefaultHandler
*This
= impl_from_IOleObject(iface
);
835 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
841 *ppenumAdvise
= NULL
;
843 if (!This
->oleAdviseHolder
)
844 return IOleAdviseHolder_EnumAdvise(This
->oleAdviseHolder
,
850 /************************************************************************
851 * DefaultHandler_GetMiscStatus (IOleObject)
853 * The default handler's implementation of this method simply delegates
854 * to OleRegGetMiscStatus.
856 * See Windows documentation for more details on IOleObject methods.
858 static HRESULT WINAPI
DefaultHandler_GetMiscStatus(
864 DefaultHandler
*This
= impl_from_IOleObject(iface
);
866 TRACE("(%p, %lx, %p)\n", iface
, dwAspect
, pdwStatus
);
868 if (This
->pOleDelegate
)
869 return IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
871 if (This
->pOleDelegate
)
872 return IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
874 hres
= OleRegGetMiscStatus(&This
->clsid
, dwAspect
, pdwStatus
);
882 /************************************************************************
883 * DefaultHandler_SetColorScheme (IOleObject)
885 * This method is meaningless if the server is not running
887 * See Windows documentation for more details on IOleObject methods.
889 static HRESULT WINAPI
DefaultHandler_SetColorScheme(
891 struct tagLOGPALETTE
* pLogpal
)
893 DefaultHandler
*This
= impl_from_IOleObject(iface
);
895 TRACE("(%p, %p))\n", iface
, pLogpal
);
897 if (This
->pOleDelegate
)
898 return IOleObject_SetColorScheme(This
->pOleDelegate
, pLogpal
);
900 return OLE_E_NOTRUNNING
;
903 /*********************************************************
904 * Methods implementation for the IDataObject part of
905 * the DefaultHandler class.
908 /************************************************************************
909 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
911 * See Windows documentation for more details on IUnknown methods.
913 static HRESULT WINAPI
DefaultHandler_IDataObject_QueryInterface(
918 DefaultHandler
*This
= impl_from_IDataObject(iface
);
920 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
923 /************************************************************************
924 * DefaultHandler_IDataObject_AddRef (IUnknown)
926 * See Windows documentation for more details on IUnknown methods.
928 static ULONG WINAPI
DefaultHandler_IDataObject_AddRef(
931 DefaultHandler
*This
= impl_from_IDataObject(iface
);
933 return IUnknown_AddRef(This
->outerUnknown
);
936 /************************************************************************
937 * DefaultHandler_IDataObject_Release (IUnknown)
939 * See Windows documentation for more details on IUnknown methods.
941 static ULONG WINAPI
DefaultHandler_IDataObject_Release(
944 DefaultHandler
*This
= impl_from_IDataObject(iface
);
946 return IUnknown_Release(This
->outerUnknown
);
949 /************************************************************************
950 * DefaultHandler_GetData
952 * Get Data from a source dataobject using format pformatetcIn->cfFormat
953 * See Windows documentation for more details on GetData.
954 * Default handler's implementation of this method delegates to the cache.
956 static HRESULT WINAPI
DefaultHandler_GetData(
958 LPFORMATETC pformatetcIn
,
961 IDataObject
* cacheDataObject
= NULL
;
964 DefaultHandler
*This
= impl_from_IDataObject(iface
);
966 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pmedium
);
968 hres
= IUnknown_QueryInterface(This
->dataCache
,
970 (void**)&cacheDataObject
);
975 hres
= IDataObject_GetData(cacheDataObject
,
979 IDataObject_Release(cacheDataObject
);
984 static HRESULT WINAPI
DefaultHandler_GetDataHere(
986 LPFORMATETC pformatetc
,
993 /************************************************************************
994 * DefaultHandler_QueryGetData (IDataObject)
996 * The default handler's implementation of this method delegates to
999 * See Windows documentation for more details on IDataObject methods.
1001 static HRESULT WINAPI
DefaultHandler_QueryGetData(
1003 LPFORMATETC pformatetc
)
1005 IDataObject
* cacheDataObject
= NULL
;
1008 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1010 TRACE("(%p, %p)\n", iface
, pformatetc
);
1012 hres
= IUnknown_QueryInterface(This
->dataCache
,
1014 (void**)&cacheDataObject
);
1017 return E_UNEXPECTED
;
1019 hres
= IDataObject_QueryGetData(cacheDataObject
,
1022 IDataObject_Release(cacheDataObject
);
1027 /************************************************************************
1028 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1030 * This method is meaningless if the server is not running
1032 * See Windows documentation for more details on IDataObject methods.
1034 static HRESULT WINAPI
DefaultHandler_GetCanonicalFormatEtc(
1036 LPFORMATETC pformatetcIn
,
1037 LPFORMATETC pformatetcOut
)
1039 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1040 IDataObject
*pDataObject
;
1043 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pformatetcOut
);
1045 if (!This
->pOleDelegate
)
1046 return OLE_E_NOTRUNNING
;
1048 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
, (void **)&pDataObject
);
1049 return IDataObject_GetCanonicalFormatEtc(pDataObject
, pformatetcIn
, pformatetcOut
);
1052 /************************************************************************
1053 * DefaultHandler_SetData (IDataObject)
1055 * The default handler's implementation of this method delegates to
1058 * See Windows documentation for more details on IDataObject methods.
1060 static HRESULT WINAPI
DefaultHandler_SetData(
1062 LPFORMATETC pformatetc
,
1066 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1067 IDataObject
* cacheDataObject
= NULL
;
1070 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
1072 hres
= IUnknown_QueryInterface(This
->dataCache
,
1074 (void**)&cacheDataObject
);
1077 return E_UNEXPECTED
;
1079 hres
= IDataObject_SetData(cacheDataObject
,
1084 IDataObject_Release(cacheDataObject
);
1089 /************************************************************************
1090 * DefaultHandler_EnumFormatEtc (IDataObject)
1092 * The default handler's implementation of This method simply delegates
1093 * to OleRegEnumFormatEtc.
1095 * See Windows documentation for more details on IDataObject methods.
1097 static HRESULT WINAPI
DefaultHandler_EnumFormatEtc(
1100 IEnumFORMATETC
** ppenumFormatEtc
)
1103 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1105 TRACE("(%p, %lx, %p)\n", iface
, dwDirection
, ppenumFormatEtc
);
1107 hres
= OleRegEnumFormatEtc(&This
->clsid
, dwDirection
, ppenumFormatEtc
);
1112 /************************************************************************
1113 * DefaultHandler_DAdvise (IDataObject)
1115 * The default handler's implementation of this method simply
1116 * delegates to the DataAdviseHolder.
1118 * See Windows documentation for more details on IDataObject methods.
1120 static HRESULT WINAPI
DefaultHandler_DAdvise(
1122 FORMATETC
* pformatetc
,
1124 IAdviseSink
* pAdvSink
,
1125 DWORD
* pdwConnection
)
1127 HRESULT hres
= S_OK
;
1128 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1130 TRACE("(%p, %p, %ld, %p, %p)\n",
1131 iface
, pformatetc
, advf
, pAdvSink
, pdwConnection
);
1133 /* Make sure we have a data advise holder before we start. */
1134 if (!This
->dataAdviseHolder
)
1135 hres
= CreateDataAdviseHolder(&This
->dataAdviseHolder
);
1137 if (SUCCEEDED(hres
))
1138 hres
= IDataAdviseHolder_Advise(This
->dataAdviseHolder
,
1148 /************************************************************************
1149 * DefaultHandler_DUnadvise (IDataObject)
1151 * The default handler's implementation of this method simply
1152 * delegates to the DataAdviseHolder.
1154 * See Windows documentation for more details on IDataObject methods.
1156 static HRESULT WINAPI
DefaultHandler_DUnadvise(
1160 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1162 TRACE("(%p, %ld)\n", iface
, dwConnection
);
1165 * If we don't have a data advise holder yet, it means that
1166 * we don't have any connections..
1168 if (!This
->dataAdviseHolder
)
1169 return OLE_E_NOCONNECTION
;
1171 return IDataAdviseHolder_Unadvise(This
->dataAdviseHolder
,
1175 /************************************************************************
1176 * DefaultHandler_EnumDAdvise (IDataObject)
1178 * The default handler's implementation of this method simply
1179 * delegates to the DataAdviseHolder.
1181 * See Windows documentation for more details on IDataObject methods.
1183 static HRESULT WINAPI
DefaultHandler_EnumDAdvise(
1185 IEnumSTATDATA
** ppenumAdvise
)
1187 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1189 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
1195 *ppenumAdvise
= NULL
;
1197 /* If we have a data advise holder object, delegate. */
1198 if (This
->dataAdviseHolder
)
1199 return IDataAdviseHolder_EnumAdvise(This
->dataAdviseHolder
,
1205 /*********************************************************
1206 * Methods implementation for the IRunnableObject part
1207 * of the DefaultHandler class.
1210 /************************************************************************
1211 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1213 * See Windows documentation for more details on IUnknown methods.
1215 static HRESULT WINAPI
DefaultHandler_IRunnableObject_QueryInterface(
1216 IRunnableObject
* iface
,
1220 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1222 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1225 /************************************************************************
1226 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1228 * See Windows documentation for more details on IUnknown methods.
1230 static ULONG WINAPI
DefaultHandler_IRunnableObject_AddRef(
1231 IRunnableObject
* iface
)
1233 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1235 return IUnknown_AddRef(This
->outerUnknown
);
1238 /************************************************************************
1239 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1241 * See Windows documentation for more details on IUnknown methods.
1243 static ULONG WINAPI
DefaultHandler_IRunnableObject_Release(
1244 IRunnableObject
* iface
)
1246 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1248 return IUnknown_Release(This
->outerUnknown
);
1251 /************************************************************************
1252 * DefaultHandler_GetRunningClass (IRunnableObject)
1254 * See Windows documentation for more details on IRunnableObject methods.
1256 static HRESULT WINAPI
DefaultHandler_GetRunningClass(
1257 IRunnableObject
* iface
,
1264 static HRESULT WINAPI
DefaultHandler_Run(
1265 IRunnableObject
* iface
,
1268 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1271 FIXME("(%p): semi-stub\n", pbc
);
1273 /* already running? if so nothing to do */
1274 if (This
->pOleDelegate
)
1277 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_LOCAL_SERVER
,
1278 &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1282 hr
= IOleObject_Advise(This
->pOleDelegate
,
1283 (IAdviseSink
*)&This
->lpvtblIAdviseSink
,
1286 if (SUCCEEDED(hr
) && This
->clientSite
)
1287 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, This
->clientSite
);
1291 IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
,
1292 (void **)&This
->pPSDelegate
);
1293 if (This
->pPSDelegate
)
1294 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, NULL
);
1297 if (SUCCEEDED(hr
) && This
->containerApp
)
1298 hr
= IOleObject_SetHostNames(This
->pOleDelegate
, This
->containerApp
,
1299 This
->containerObj
);
1301 /* FIXME: do more stuff here:
1302 * - IOleObject_GetMiscStatus
1303 * - IOleObject_GetMoniker
1308 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
,
1309 (void **)&This
->pDataDelegate
);
1311 if (SUCCEEDED(hr
) && This
->dataAdviseHolder
)
1312 hr
= DataAdviseHolder_OnConnect(This
->dataAdviseHolder
, This
->pDataDelegate
);
1315 DefaultHandler_Stop(This
);
1320 /************************************************************************
1321 * DefaultHandler_IsRunning (IRunnableObject)
1323 * See Windows documentation for more details on IRunnableObject methods.
1325 static BOOL WINAPI
DefaultHandler_IsRunning(
1326 IRunnableObject
* iface
)
1328 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1332 if (This
->pOleDelegate
)
1338 /************************************************************************
1339 * DefaultHandler_LockRunning (IRunnableObject)
1341 * See Windows documentation for more details on IRunnableObject methods.
1343 static HRESULT WINAPI
DefaultHandler_LockRunning(
1344 IRunnableObject
* iface
,
1346 BOOL fLastUnlockCloses
)
1352 /************************************************************************
1353 * DefaultHandler_SetContainedObject (IRunnableObject)
1355 * See Windows documentation for more details on IRunnableObject methods.
1357 static HRESULT WINAPI
DefaultHandler_SetContainedObject(
1358 IRunnableObject
* iface
,
1365 static HRESULT WINAPI
DefaultHandler_IAdviseSink_QueryInterface(
1370 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1371 IsEqualIID(riid
, &IID_IAdviseSink
))
1374 IAdviseSink_AddRef(iface
);
1378 return E_NOINTERFACE
;
1381 static ULONG WINAPI
DefaultHandler_IAdviseSink_AddRef(
1384 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1386 return IUnknown_AddRef((IUnknown
*)&This
->lpvtblIUnknown
);
1389 static ULONG WINAPI
DefaultHandler_IAdviseSink_Release(
1392 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1394 return IUnknown_Release((IUnknown
*)&This
->lpvtblIUnknown
);
1397 static void WINAPI
DefaultHandler_IAdviseSink_OnDataChange(
1399 FORMATETC
*pFormatetc
,
1405 static void WINAPI
DefaultHandler_IAdviseSink_OnViewChange(
1413 static void WINAPI
DefaultHandler_IAdviseSink_OnRename(
1417 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1419 TRACE("(%p)\n", pmk
);
1421 if (This
->oleAdviseHolder
)
1422 IOleAdviseHolder_SendOnRename(This
->oleAdviseHolder
, pmk
);
1425 static void WINAPI
DefaultHandler_IAdviseSink_OnSave(
1428 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1432 if (This
->oleAdviseHolder
)
1433 IOleAdviseHolder_SendOnSave(This
->oleAdviseHolder
);
1436 static void WINAPI
DefaultHandler_IAdviseSink_OnClose(
1439 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1443 if (This
->oleAdviseHolder
)
1444 IOleAdviseHolder_SendOnClose(This
->oleAdviseHolder
);
1446 DefaultHandler_Stop(This
);
1450 * Virtual function tables for the DefaultHandler class.
1452 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable
=
1454 DefaultHandler_QueryInterface
,
1455 DefaultHandler_AddRef
,
1456 DefaultHandler_Release
,
1457 DefaultHandler_SetClientSite
,
1458 DefaultHandler_GetClientSite
,
1459 DefaultHandler_SetHostNames
,
1460 DefaultHandler_Close
,
1461 DefaultHandler_SetMoniker
,
1462 DefaultHandler_GetMoniker
,
1463 DefaultHandler_InitFromData
,
1464 DefaultHandler_GetClipboardData
,
1465 DefaultHandler_DoVerb
,
1466 DefaultHandler_EnumVerbs
,
1467 DefaultHandler_Update
,
1468 DefaultHandler_IsUpToDate
,
1469 DefaultHandler_GetUserClassID
,
1470 DefaultHandler_GetUserType
,
1471 DefaultHandler_SetExtent
,
1472 DefaultHandler_GetExtent
,
1473 DefaultHandler_Advise
,
1474 DefaultHandler_Unadvise
,
1475 DefaultHandler_EnumAdvise
,
1476 DefaultHandler_GetMiscStatus
,
1477 DefaultHandler_SetColorScheme
1480 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable
=
1482 DefaultHandler_NDIUnknown_QueryInterface
,
1483 DefaultHandler_NDIUnknown_AddRef
,
1484 DefaultHandler_NDIUnknown_Release
,
1487 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable
=
1489 DefaultHandler_IDataObject_QueryInterface
,
1490 DefaultHandler_IDataObject_AddRef
,
1491 DefaultHandler_IDataObject_Release
,
1492 DefaultHandler_GetData
,
1493 DefaultHandler_GetDataHere
,
1494 DefaultHandler_QueryGetData
,
1495 DefaultHandler_GetCanonicalFormatEtc
,
1496 DefaultHandler_SetData
,
1497 DefaultHandler_EnumFormatEtc
,
1498 DefaultHandler_DAdvise
,
1499 DefaultHandler_DUnadvise
,
1500 DefaultHandler_EnumDAdvise
1503 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable
=
1505 DefaultHandler_IRunnableObject_QueryInterface
,
1506 DefaultHandler_IRunnableObject_AddRef
,
1507 DefaultHandler_IRunnableObject_Release
,
1508 DefaultHandler_GetRunningClass
,
1510 DefaultHandler_IsRunning
,
1511 DefaultHandler_LockRunning
,
1512 DefaultHandler_SetContainedObject
1515 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable
=
1517 DefaultHandler_IAdviseSink_QueryInterface
,
1518 DefaultHandler_IAdviseSink_AddRef
,
1519 DefaultHandler_IAdviseSink_Release
,
1520 DefaultHandler_IAdviseSink_OnDataChange
,
1521 DefaultHandler_IAdviseSink_OnViewChange
,
1522 DefaultHandler_IAdviseSink_OnRename
,
1523 DefaultHandler_IAdviseSink_OnSave
,
1524 DefaultHandler_IAdviseSink_OnClose
1527 /*********************************************************
1528 * Methods implementation for the DefaultHandler class.
1530 static DefaultHandler
* DefaultHandler_Construct(
1532 LPUNKNOWN pUnkOuter
)
1534 DefaultHandler
* This
= NULL
;
1537 * Allocate space for the object.
1539 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler
));
1544 This
->lpVtbl
= &DefaultHandler_IOleObject_VTable
;
1545 This
->lpvtblIUnknown
= &DefaultHandler_NDIUnknown_VTable
;
1546 This
->lpvtblIDataObject
= &DefaultHandler_IDataObject_VTable
;
1547 This
->lpvtblIRunnableObject
= &DefaultHandler_IRunnableObject_VTable
;
1548 This
->lpvtblIAdviseSink
= &DefaultHandler_IAdviseSink_VTable
;
1551 * Start with one reference count. The caller of this function
1552 * must release the interface pointer when it is done.
1557 * Initialize the outer unknown
1558 * We don't keep a reference on the outer unknown since, the way
1559 * aggregation works, our lifetime is at least as large as it's
1563 pUnkOuter
= (IUnknown
*)&This
->lpvtblIUnknown
;
1565 This
->outerUnknown
= pUnkOuter
;
1568 * Create a datacache object.
1569 * We aggregate with the datacache. Make sure we pass our outer
1570 * unknown as the datacache's outer unknown.
1572 CreateDataCache(This
->outerUnknown
,
1575 (void**)&This
->dataCache
);
1578 * Initialize the other data members of the class.
1580 memcpy(&This
->clsid
, clsid
, sizeof(CLSID
));
1581 This
->clientSite
= NULL
;
1582 This
->oleAdviseHolder
= NULL
;
1583 This
->dataAdviseHolder
= NULL
;
1584 This
->containerApp
= NULL
;
1585 This
->containerObj
= NULL
;
1586 This
->pOleDelegate
= NULL
;
1587 This
->pPSDelegate
= NULL
;
1588 This
->pDataDelegate
= NULL
;
1590 This
->dwAdvConn
= 0;
1595 static void DefaultHandler_Destroy(
1596 DefaultHandler
* This
)
1598 /* release delegates */
1599 DefaultHandler_Stop(This
);
1601 /* Free the strings idenfitying the object */
1602 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
1603 This
->containerApp
= NULL
;
1604 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
1605 This
->containerObj
= NULL
;
1607 /* Release our reference to the data cache. */
1608 if (This
->dataCache
)
1610 IUnknown_Release(This
->dataCache
);
1611 This
->dataCache
= NULL
;
1614 /* Same thing for the client site. */
1615 if (This
->clientSite
)
1617 IOleClientSite_Release(This
->clientSite
);
1618 This
->clientSite
= NULL
;
1621 /* And the advise holder. */
1622 if (This
->oleAdviseHolder
)
1624 IOleAdviseHolder_Release(This
->oleAdviseHolder
);
1625 This
->oleAdviseHolder
= NULL
;
1628 /* And the data advise holder. */
1629 if (This
->dataAdviseHolder
)
1631 IDataAdviseHolder_Release(This
->dataAdviseHolder
);
1632 This
->dataAdviseHolder
= NULL
;
1635 /* Free the actual default handler structure. */
1636 HeapFree(GetProcessHeap(), 0, This
);
1639 /******************************************************************************
1640 * OleCreateDefaultHandler [OLE32.@]
1642 HRESULT WINAPI
OleCreateDefaultHandler(
1644 LPUNKNOWN pUnkOuter
,
1648 DefaultHandler
* newHandler
= NULL
;
1651 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
, debugstr_guid(riid
), ppvObj
);
1662 * If This handler is constructed for aggregation, make sure
1663 * the caller is requesting the IUnknown interface.
1664 * This is necessary because it's the only time the non-delegating
1665 * IUnknown pointer can be returned to the outside.
1667 if (pUnkOuter
&& !IsEqualIID(&IID_IUnknown
, riid
))
1668 return CLASS_E_NOAGGREGATION
;
1671 * Try to construct a new instance of the class.
1673 newHandler
= DefaultHandler_Construct(clsid
, pUnkOuter
);
1676 return E_OUTOFMEMORY
;
1679 * Make sure it supports the interface required by the caller.
1681 hr
= IUnknown_QueryInterface((IUnknown
*)&newHandler
->lpvtblIUnknown
, riid
, ppvObj
);
1684 * Release the reference obtained in the constructor. If
1685 * the QueryInterface was unsuccessful, it will free the class.
1687 IUnknown_Release((IUnknown
*)&newHandler
->lpvtblIUnknown
);