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.
58 #include "wine/unicode.h"
60 #include "wine/debug.h"
62 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
64 /****************************************************************************
70 const IOleObjectVtbl
* lpVtbl
;
71 const IUnknownVtbl
* lpvtblIUnknown
;
72 const IDataObjectVtbl
* lpvtblIDataObject
;
73 const IRunnableObjectVtbl
* lpvtblIRunnableObject
;
74 const IAdviseSinkVtbl
*lpvtblIAdviseSink
;
76 /* Reference count of this object */
79 /* IUnknown implementation of the outer object. */
80 IUnknown
* outerUnknown
;
82 /* Class Id that this handler object represents. */
85 /* IUnknown implementation of the datacache. */
88 /* Client site for the embedded object. */
89 IOleClientSite
* clientSite
;
92 * The IOleAdviseHolder maintains the connections
93 * on behalf of the default handler.
95 IOleAdviseHolder
* oleAdviseHolder
;
98 * The IDataAdviseHolder maintains the data
99 * connections on behalf of the default handler.
101 IDataAdviseHolder
* dataAdviseHolder
;
103 /* Name of the container and object contained */
107 /* IOleObject delegate */
108 IOleObject
*pOleDelegate
;
109 /* IPersistStorage delegate */
110 IPersistStorage
*pPSDelegate
;
112 /* connection cookie for the advise on the delegate OLE object */
116 typedef struct DefaultHandler DefaultHandler
;
119 * Here, I define utility functions to help with the casting of the
121 * There is a version to accommodate all of the VTables implemented
124 static inline DefaultHandler
*impl_from_IOleObject( IOleObject
*iface
)
126 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpVtbl
));
129 static inline DefaultHandler
*impl_from_NDIUnknown( IUnknown
*iface
)
131 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIUnknown
));
134 static inline DefaultHandler
*impl_from_IDataObject( IDataObject
*iface
)
136 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIDataObject
));
139 static inline DefaultHandler
*impl_from_IRunnableObject( IRunnableObject
*iface
)
141 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIRunnableObject
));
144 static inline DefaultHandler
*impl_from_IAdviseSink( IAdviseSink
*iface
)
146 return (DefaultHandler
*)((char*)iface
- FIELD_OFFSET(DefaultHandler
, lpvtblIAdviseSink
));
149 static void DefaultHandler_Destroy(DefaultHandler
* This
);
152 /*********************************************************
153 * Method implementation for the non delegating IUnknown
154 * part of the DefaultHandler class.
157 /************************************************************************
158 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
160 * See Windows documentation for more details on IUnknown methods.
162 * This version of QueryInterface will not delegate it's implementation
163 * to the outer unknown.
165 static HRESULT WINAPI
DefaultHandler_NDIUnknown_QueryInterface(
170 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
172 /* Perform a sanity check on the parameters. */
178 if (IsEqualIID(&IID_IUnknown
, riid
))
180 else if (IsEqualIID(&IID_IOleObject
, riid
))
181 *ppvObject
= (IOleObject
*)&This
->lpVtbl
;
182 else if (IsEqualIID(&IID_IDataObject
, riid
))
183 *ppvObject
= (IDataObject
*)&This
->lpvtblIDataObject
;
184 else if (IsEqualIID(&IID_IRunnableObject
, riid
))
185 *ppvObject
= (IRunnableObject
*)&This
->lpvtblIRunnableObject
;
186 else if (IsEqualIID(&IID_IPersist
, riid
) ||
187 IsEqualIID(&IID_IPersistStorage
, riid
) ||
188 IsEqualIID(&IID_IViewObject
, riid
) ||
189 IsEqualIID(&IID_IViewObject2
, riid
) ||
190 IsEqualIID(&IID_IOleCache
, riid
) ||
191 IsEqualIID(&IID_IOleCache2
, riid
))
193 HRESULT hr
= IUnknown_QueryInterface(This
->dataCache
, riid
, ppvObject
);
194 if (FAILED(hr
)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid
));
198 /* Check that we obtained an interface. */
199 if (*ppvObject
== NULL
)
201 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid
));
202 return E_NOINTERFACE
;
206 * Query Interface always increases the reference count by one when it is
209 IUnknown_AddRef((IUnknown
*)*ppvObject
);
214 /************************************************************************
215 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
217 * See Windows documentation for more details on IUnknown methods.
219 * This version of QueryInterface will not delegate it's implementation
220 * to the outer unknown.
222 static ULONG WINAPI
DefaultHandler_NDIUnknown_AddRef(
225 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
226 return InterlockedIncrement(&This
->ref
);
229 /************************************************************************
230 * DefaultHandler_NDIUnknown_Release (IUnknown)
232 * See Windows documentation for more details on IUnknown methods.
234 * This version of QueryInterface will not delegate it's implementation
235 * to the outer unknown.
237 static ULONG WINAPI
DefaultHandler_NDIUnknown_Release(
240 DefaultHandler
*This
= impl_from_NDIUnknown(iface
);
243 /* Decrease the reference count on this object. */
244 ref
= InterlockedDecrement(&This
->ref
);
246 if (!ref
) DefaultHandler_Destroy(This
);
251 /*********************************************************
252 * Methods implementation for the IOleObject part of
253 * the DefaultHandler class.
256 /************************************************************************
257 * DefaultHandler_QueryInterface (IUnknown)
259 * See Windows documentation for more details on IUnknown methods.
261 static HRESULT WINAPI
DefaultHandler_QueryInterface(
266 DefaultHandler
*This
= impl_from_IOleObject(iface
);
268 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
271 /************************************************************************
272 * DefaultHandler_AddRef (IUnknown)
274 * See Windows documentation for more details on IUnknown methods.
276 static ULONG WINAPI
DefaultHandler_AddRef(
279 DefaultHandler
*This
= impl_from_IOleObject(iface
);
281 return IUnknown_AddRef(This
->outerUnknown
);
284 /************************************************************************
285 * DefaultHandler_Release (IUnknown)
287 * See Windows documentation for more details on IUnknown methods.
289 static ULONG WINAPI
DefaultHandler_Release(
292 DefaultHandler
*This
= impl_from_IOleObject(iface
);
294 return IUnknown_Release(This
->outerUnknown
);
297 /************************************************************************
298 * DefaultHandler_SetClientSite (IOleObject)
300 * The default handler's implementation of this method only keeps the
301 * client site pointer for future reference.
303 * See Windows documentation for more details on IOleObject methods.
305 static HRESULT WINAPI
DefaultHandler_SetClientSite(
307 IOleClientSite
* pClientSite
)
309 DefaultHandler
*This
= impl_from_IOleObject(iface
);
311 TRACE("(%p, %p)\n", iface
, pClientSite
);
314 * Make sure we release the previous client site if there
317 if (This
->clientSite
)
318 IOleClientSite_Release(This
->clientSite
);
320 This
->clientSite
= pClientSite
;
322 if (This
->clientSite
)
323 IOleClientSite_AddRef(This
->clientSite
);
328 /************************************************************************
329 * DefaultHandler_GetClientSite (IOleObject)
331 * The default handler's implementation of this method returns the
332 * last pointer set in IOleObject_SetClientSite.
334 * See Windows documentation for more details on IOleObject methods.
336 static HRESULT WINAPI
DefaultHandler_GetClientSite(
338 IOleClientSite
** ppClientSite
)
340 DefaultHandler
*This
= impl_from_IOleObject(iface
);
346 *ppClientSite
= This
->clientSite
;
348 if (This
->clientSite
)
349 IOleClientSite_AddRef(This
->clientSite
);
354 /************************************************************************
355 * DefaultHandler_SetHostNames (IOleObject)
357 * The default handler's implementation of this method just stores
358 * the strings and returns S_OK.
360 * See Windows documentation for more details on IOleObject methods.
362 static HRESULT WINAPI
DefaultHandler_SetHostNames(
364 LPCOLESTR szContainerApp
,
365 LPCOLESTR szContainerObj
)
367 DefaultHandler
*This
= impl_from_IOleObject(iface
);
369 TRACE("(%p, %s, %s)\n",
371 debugstr_w(szContainerApp
),
372 debugstr_w(szContainerObj
));
374 /* Be sure to cleanup before re-assinging the strings. */
375 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
376 This
->containerApp
= NULL
;
377 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
378 This
->containerObj
= NULL
;
380 /* Copy the string supplied. */
383 if ((This
->containerApp
= HeapAlloc( GetProcessHeap(), 0,
384 (lstrlenW(szContainerApp
) + 1) * sizeof(WCHAR
) )))
385 strcpyW( This
->containerApp
, szContainerApp
);
390 if ((This
->containerObj
= HeapAlloc( GetProcessHeap(), 0,
391 (lstrlenW(szContainerObj
) + 1) * sizeof(WCHAR
) )))
392 strcpyW( This
->containerObj
, szContainerObj
);
397 /************************************************************************
398 * DefaultHandler_Close (IOleObject)
400 * The default handler's implementation of this method is meaningless
401 * without a running server so it does nothing.
403 * See Windows documentation for more details on IOleObject methods.
405 static HRESULT WINAPI
DefaultHandler_Close(
413 /************************************************************************
414 * DefaultHandler_SetMoniker (IOleObject)
416 * The default handler's implementation of this method does nothing.
418 * See Windows documentation for more details on IOleObject methods.
420 static HRESULT WINAPI
DefaultHandler_SetMoniker(
422 DWORD dwWhichMoniker
,
425 TRACE("(%p, %ld, %p)\n",
433 /************************************************************************
434 * DefaultHandler_GetMoniker (IOleObject)
436 * Delegate this request to the client site if we have one.
438 * See Windows documentation for more details on IOleObject methods.
440 static HRESULT WINAPI
DefaultHandler_GetMoniker(
443 DWORD dwWhichMoniker
,
446 DefaultHandler
*This
= impl_from_IOleObject(iface
);
448 TRACE("(%p, %ld, %ld, %p)\n",
449 iface
, dwAssign
, dwWhichMoniker
, ppmk
);
451 if (This
->clientSite
)
453 return IOleClientSite_GetMoniker(This
->clientSite
,
463 /************************************************************************
464 * DefaultHandler_InitFromData (IOleObject)
466 * This method is meaningless if the server is not running
468 * See Windows documentation for more details on IOleObject methods.
470 static HRESULT WINAPI
DefaultHandler_InitFromData(
472 IDataObject
* pDataObject
,
476 TRACE("(%p, %p, %d, %ld)\n",
477 iface
, pDataObject
, fCreation
, dwReserved
);
479 return OLE_E_NOTRUNNING
;
482 /************************************************************************
483 * DefaultHandler_GetClipboardData (IOleObject)
485 * This method is meaningless if the server is not running
487 * See Windows documentation for more details on IOleObject methods.
489 static HRESULT WINAPI
DefaultHandler_GetClipboardData(
492 IDataObject
** ppDataObject
)
494 TRACE("(%p, %ld, %p)\n",
495 iface
, dwReserved
, ppDataObject
);
497 return OLE_E_NOTRUNNING
;
500 static HRESULT WINAPI
DefaultHandler_DoVerb(
503 struct tagMSG
* lpmsg
,
504 IOleClientSite
* pActiveSite
,
513 /************************************************************************
514 * DefaultHandler_EnumVerbs (IOleObject)
516 * The default handler implementation of this method simply delegates
519 * See Windows documentation for more details on IOleObject methods.
521 static HRESULT WINAPI
DefaultHandler_EnumVerbs(
523 IEnumOLEVERB
** ppEnumOleVerb
)
525 DefaultHandler
*This
= impl_from_IOleObject(iface
);
526 HRESULT hr
= OLE_S_USEREG
;
528 TRACE("(%p, %p)\n", iface
, ppEnumOleVerb
);
530 if (This
->pOleDelegate
)
531 hr
= IOleObject_EnumVerbs(This
->pOleDelegate
, ppEnumOleVerb
);
533 if (hr
== OLE_S_USEREG
)
534 return OleRegEnumVerbs(&This
->clsid
, ppEnumOleVerb
);
539 static HRESULT WINAPI
DefaultHandler_Update(
546 /************************************************************************
547 * DefaultHandler_IsUpToDate (IOleObject)
549 * This method is meaningless if the server is not running
551 * See Windows documentation for more details on IOleObject methods.
553 static HRESULT WINAPI
DefaultHandler_IsUpToDate(
556 TRACE("(%p)\n", iface
);
558 return OLE_E_NOTRUNNING
;
561 /************************************************************************
562 * DefaultHandler_GetUserClassID (IOleObject)
564 * TODO: Map to a new class ID if emulation is active.
566 * See Windows documentation for more details on IOleObject methods.
568 static HRESULT WINAPI
DefaultHandler_GetUserClassID(
572 DefaultHandler
*This
= impl_from_IOleObject(iface
);
574 TRACE("(%p, %p)\n", iface
, pClsid
);
576 if (This
->pOleDelegate
)
577 return IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
579 if (This
->pOleDelegate
)
580 return IOleObject_GetUserClassID(This
->pOleDelegate
, pClsid
);
586 memcpy(pClsid
, &This
->clsid
, sizeof(CLSID
));
591 /************************************************************************
592 * DefaultHandler_GetUserType (IOleObject)
594 * The default handler implementation of this method simply delegates
595 * to OleRegGetUserType
597 * See Windows documentation for more details on IOleObject methods.
599 static HRESULT WINAPI
DefaultHandler_GetUserType(
602 LPOLESTR
* pszUserType
)
604 DefaultHandler
*This
= impl_from_IOleObject(iface
);
606 TRACE("(%p, %ld, %p)\n", iface
, dwFormOfType
, pszUserType
);
608 return OleRegGetUserType(&This
->clsid
, dwFormOfType
, pszUserType
);
611 /************************************************************************
612 * DefaultHandler_SetExtent (IOleObject)
614 * This method is meaningless if the server is not running
616 * See Windows documentation for more details on IOleObject methods.
618 static HRESULT WINAPI
DefaultHandler_SetExtent(
623 TRACE("(%p, %lx, (%ld x %ld))\n", iface
,
624 dwDrawAspect
, psizel
->cx
, psizel
->cy
);
625 return OLE_E_NOTRUNNING
;
628 /************************************************************************
629 * DefaultHandler_GetExtent (IOleObject)
631 * The default handler's implementation of this method returns uses
632 * the cache to locate the aspect and extract the extent from it.
634 * See Windows documentation for more details on IOleObject methods.
636 static HRESULT WINAPI
DefaultHandler_GetExtent(
641 DVTARGETDEVICE
* targetDevice
;
642 IViewObject2
* cacheView
= NULL
;
645 DefaultHandler
*This
= impl_from_IOleObject(iface
);
647 TRACE("(%p, %lx, %p)\n", iface
, dwDrawAspect
, psizel
);
649 hres
= IUnknown_QueryInterface(This
->dataCache
, &IID_IViewObject2
, (void**)&cacheView
);
655 * Prepare the call to the cache's GetExtent method.
657 * Here we would build a valid DVTARGETDEVICE structure
658 * but, since we are calling into the data cache, we
659 * know it's implementation and we'll skip this
660 * extra work until later.
664 hres
= IViewObject2_GetExtent(cacheView
,
673 IViewObject2_Release(cacheView
);
678 /************************************************************************
679 * DefaultHandler_Advise (IOleObject)
681 * The default handler's implementation of this method simply
682 * delegates to the OleAdviseHolder.
684 * See Windows documentation for more details on IOleObject methods.
686 static HRESULT WINAPI
DefaultHandler_Advise(
688 IAdviseSink
* pAdvSink
,
689 DWORD
* pdwConnection
)
692 DefaultHandler
*This
= impl_from_IOleObject(iface
);
694 TRACE("(%p, %p, %p)\n", iface
, pAdvSink
, pdwConnection
);
696 /* Make sure we have an advise holder before we start. */
697 if (!This
->oleAdviseHolder
)
698 hres
= CreateOleAdviseHolder(&This
->oleAdviseHolder
);
701 hres
= IOleAdviseHolder_Advise(This
->oleAdviseHolder
,
708 /************************************************************************
709 * DefaultHandler_Unadvise (IOleObject)
711 * The default handler's implementation of this method simply
712 * delegates to the OleAdviseHolder.
714 * See Windows documentation for more details on IOleObject methods.
716 static HRESULT WINAPI
DefaultHandler_Unadvise(
720 DefaultHandler
*This
= impl_from_IOleObject(iface
);
722 TRACE("(%p, %ld)\n", iface
, dwConnection
);
725 * If we don't have an advise holder yet, it means we don't have
728 if (!This
->oleAdviseHolder
)
729 return OLE_E_NOCONNECTION
;
731 return IOleAdviseHolder_Unadvise(This
->oleAdviseHolder
,
735 /************************************************************************
736 * DefaultHandler_EnumAdvise (IOleObject)
738 * The default handler's implementation of this method simply
739 * delegates to the OleAdviseHolder.
741 * See Windows documentation for more details on IOleObject methods.
743 static HRESULT WINAPI
DefaultHandler_EnumAdvise(
745 IEnumSTATDATA
** ppenumAdvise
)
747 DefaultHandler
*This
= impl_from_IOleObject(iface
);
749 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
755 *ppenumAdvise
= NULL
;
757 if (!This
->oleAdviseHolder
)
758 return IOleAdviseHolder_EnumAdvise(This
->oleAdviseHolder
,
764 /************************************************************************
765 * DefaultHandler_GetMiscStatus (IOleObject)
767 * The default handler's implementation of this method simply delegates
768 * to OleRegGetMiscStatus.
770 * See Windows documentation for more details on IOleObject methods.
772 static HRESULT WINAPI
DefaultHandler_GetMiscStatus(
778 DefaultHandler
*This
= impl_from_IOleObject(iface
);
780 TRACE("(%p, %lx, %p)\n", iface
, dwAspect
, pdwStatus
);
782 if (This
->pOleDelegate
)
783 return IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
785 if (This
->pOleDelegate
)
786 return IOleObject_GetMiscStatus(This
->pOleDelegate
, dwAspect
, pdwStatus
);
788 hres
= OleRegGetMiscStatus(&This
->clsid
, dwAspect
, pdwStatus
);
796 /************************************************************************
797 * DefaultHandler_SetExtent (IOleObject)
799 * This method is meaningless if the server is not running
801 * See Windows documentation for more details on IOleObject methods.
803 static HRESULT WINAPI
DefaultHandler_SetColorScheme(
805 struct tagLOGPALETTE
* pLogpal
)
807 TRACE("(%p, %p))\n", iface
, pLogpal
);
808 return OLE_E_NOTRUNNING
;
811 /*********************************************************
812 * Methods implementation for the IDataObject part of
813 * the DefaultHandler class.
816 /************************************************************************
817 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
819 * See Windows documentation for more details on IUnknown methods.
821 static HRESULT WINAPI
DefaultHandler_IDataObject_QueryInterface(
826 DefaultHandler
*This
= impl_from_IDataObject(iface
);
828 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
831 /************************************************************************
832 * DefaultHandler_IDataObject_AddRef (IUnknown)
834 * See Windows documentation for more details on IUnknown methods.
836 static ULONG WINAPI
DefaultHandler_IDataObject_AddRef(
839 DefaultHandler
*This
= impl_from_IDataObject(iface
);
841 return IUnknown_AddRef(This
->outerUnknown
);
844 /************************************************************************
845 * DefaultHandler_IDataObject_Release (IUnknown)
847 * See Windows documentation for more details on IUnknown methods.
849 static ULONG WINAPI
DefaultHandler_IDataObject_Release(
852 DefaultHandler
*This
= impl_from_IDataObject(iface
);
854 return IUnknown_Release(This
->outerUnknown
);
857 /************************************************************************
858 * DefaultHandler_GetData
860 * Get Data from a source dataobject using format pformatetcIn->cfFormat
861 * See Windows documentation for more details on GetData.
862 * Default handler's implementation of this method delegates to the cache.
864 static HRESULT WINAPI
DefaultHandler_GetData(
866 LPFORMATETC pformatetcIn
,
869 IDataObject
* cacheDataObject
= NULL
;
872 DefaultHandler
*This
= impl_from_IDataObject(iface
);
874 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pmedium
);
876 hres
= IUnknown_QueryInterface(This
->dataCache
,
878 (void**)&cacheDataObject
);
883 hres
= IDataObject_GetData(cacheDataObject
,
887 IDataObject_Release(cacheDataObject
);
892 static HRESULT WINAPI
DefaultHandler_GetDataHere(
894 LPFORMATETC pformatetc
,
901 /************************************************************************
902 * DefaultHandler_QueryGetData (IDataObject)
904 * The default handler's implementation of this method delegates to
907 * See Windows documentation for more details on IDataObject methods.
909 static HRESULT WINAPI
DefaultHandler_QueryGetData(
911 LPFORMATETC pformatetc
)
913 IDataObject
* cacheDataObject
= NULL
;
916 DefaultHandler
*This
= impl_from_IDataObject(iface
);
918 TRACE("(%p, %p)\n", iface
, pformatetc
);
920 hres
= IUnknown_QueryInterface(This
->dataCache
,
922 (void**)&cacheDataObject
);
927 hres
= IDataObject_QueryGetData(cacheDataObject
,
930 IDataObject_Release(cacheDataObject
);
935 /************************************************************************
936 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
938 * This method is meaningless if the server is not running
940 * See Windows documentation for more details on IDataObject methods.
942 static HRESULT WINAPI
DefaultHandler_GetCanonicalFormatEtc(
944 LPFORMATETC pformatetcIn
,
945 LPFORMATETC pformatetcOut
)
947 DefaultHandler
*This
= impl_from_IDataObject(iface
);
948 IDataObject
*pDataObject
;
951 TRACE("(%p, %p, %p)\n", iface
, pformatetcIn
, pformatetcOut
);
953 if (!This
->pOleDelegate
)
954 return OLE_E_NOTRUNNING
;
956 hr
= IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IDataObject
, (void **)&pDataObject
);
957 return IDataObject_GetCanonicalFormatEtc(pDataObject
, pformatetcIn
, pformatetcOut
);
960 /************************************************************************
961 * DefaultHandler_SetData (IDataObject)
963 * The default handler's implementation of this method delegates to
966 * See Windows documentation for more details on IDataObject methods.
968 static HRESULT WINAPI
DefaultHandler_SetData(
970 LPFORMATETC pformatetc
,
974 DefaultHandler
*This
= impl_from_IDataObject(iface
);
975 IDataObject
* cacheDataObject
= NULL
;
978 TRACE("(%p, %p, %p, %d)\n", iface
, pformatetc
, pmedium
, fRelease
);
980 hres
= IUnknown_QueryInterface(This
->dataCache
,
982 (void**)&cacheDataObject
);
987 hres
= IDataObject_SetData(cacheDataObject
,
992 IDataObject_Release(cacheDataObject
);
997 /************************************************************************
998 * DefaultHandler_EnumFormatEtc (IDataObject)
1000 * The default handler's implementation of This method simply delegates
1001 * to OleRegEnumFormatEtc.
1003 * See Windows documentation for more details on IDataObject methods.
1005 static HRESULT WINAPI
DefaultHandler_EnumFormatEtc(
1008 IEnumFORMATETC
** ppenumFormatEtc
)
1011 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1013 TRACE("(%p, %lx, %p)\n", iface
, dwDirection
, ppenumFormatEtc
);
1015 hres
= OleRegEnumFormatEtc(&This
->clsid
, dwDirection
, ppenumFormatEtc
);
1020 /************************************************************************
1021 * DefaultHandler_DAdvise (IDataObject)
1023 * The default handler's implementation of this method simply
1024 * delegates to the DataAdviseHolder.
1026 * See Windows documentation for more details on IDataObject methods.
1028 static HRESULT WINAPI
DefaultHandler_DAdvise(
1030 FORMATETC
* pformatetc
,
1032 IAdviseSink
* pAdvSink
,
1033 DWORD
* pdwConnection
)
1035 HRESULT hres
= S_OK
;
1036 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1038 TRACE("(%p, %p, %ld, %p, %p)\n",
1039 iface
, pformatetc
, advf
, pAdvSink
, pdwConnection
);
1041 /* Make sure we have a data advise holder before we start. */
1042 if (!This
->dataAdviseHolder
)
1043 hres
= CreateDataAdviseHolder(&This
->dataAdviseHolder
);
1045 if (SUCCEEDED(hres
))
1046 hres
= IDataAdviseHolder_Advise(This
->dataAdviseHolder
,
1056 /************************************************************************
1057 * DefaultHandler_DUnadvise (IDataObject)
1059 * The default handler's implementation of this method simply
1060 * delegates to the DataAdviseHolder.
1062 * See Windows documentation for more details on IDataObject methods.
1064 static HRESULT WINAPI
DefaultHandler_DUnadvise(
1068 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1070 TRACE("(%p, %ld)\n", iface
, dwConnection
);
1073 * If we don't have a data advise holder yet, it means that
1074 * we don't have any connections..
1076 if (!This
->dataAdviseHolder
)
1077 return OLE_E_NOCONNECTION
;
1079 return IDataAdviseHolder_Unadvise(This
->dataAdviseHolder
,
1083 /************************************************************************
1084 * DefaultHandler_EnumDAdvise (IDataObject)
1086 * The default handler's implementation of this method simply
1087 * delegates to the DataAdviseHolder.
1089 * See Windows documentation for more details on IDataObject methods.
1091 static HRESULT WINAPI
DefaultHandler_EnumDAdvise(
1093 IEnumSTATDATA
** ppenumAdvise
)
1095 DefaultHandler
*This
= impl_from_IDataObject(iface
);
1097 TRACE("(%p, %p)\n", iface
, ppenumAdvise
);
1103 *ppenumAdvise
= NULL
;
1105 /* If we have a data advise holder object, delegate. */
1106 if (This
->dataAdviseHolder
)
1107 return IDataAdviseHolder_EnumAdvise(This
->dataAdviseHolder
,
1113 /*********************************************************
1114 * Methods implementation for the IRunnableObject part
1115 * of the DefaultHandler class.
1118 /************************************************************************
1119 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1121 * See Windows documentation for more details on IUnknown methods.
1123 static HRESULT WINAPI
DefaultHandler_IRunnableObject_QueryInterface(
1124 IRunnableObject
* iface
,
1128 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1130 return IUnknown_QueryInterface(This
->outerUnknown
, riid
, ppvObject
);
1133 /************************************************************************
1134 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1136 * See Windows documentation for more details on IUnknown methods.
1138 static ULONG WINAPI
DefaultHandler_IRunnableObject_AddRef(
1139 IRunnableObject
* iface
)
1141 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1143 return IUnknown_AddRef(This
->outerUnknown
);
1146 /************************************************************************
1147 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1149 * See Windows documentation for more details on IUnknown methods.
1151 static ULONG WINAPI
DefaultHandler_IRunnableObject_Release(
1152 IRunnableObject
* iface
)
1154 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1156 return IUnknown_Release(This
->outerUnknown
);
1159 /************************************************************************
1160 * DefaultHandler_GetRunningClass (IRunnableObject)
1162 * See Windows documentation for more details on IRunnableObject methods.
1164 static HRESULT WINAPI
DefaultHandler_GetRunningClass(
1165 IRunnableObject
* iface
,
1172 static HRESULT WINAPI
DefaultHandler_Run(
1173 IRunnableObject
* iface
,
1176 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1179 FIXME("(%p): semi-stub\n", pbc
);
1181 /* already running? if so nothing to do */
1182 if (This
->pOleDelegate
)
1185 hr
= CoCreateInstance(&This
->clsid
, NULL
, CLSCTX_LOCAL_SERVER
, &IID_IOleObject
, (void **)&This
->pOleDelegate
);
1189 hr
= IOleObject_Advise(This
->pOleDelegate
, (IAdviseSink
*)&This
->lpvtblIAdviseSink
, &This
->dwAdvConn
);
1191 if (SUCCEEDED(hr
) && This
->clientSite
)
1192 hr
= IOleObject_SetClientSite(This
->pOleDelegate
, This
->clientSite
);
1196 IOleObject_QueryInterface(This
->pOleDelegate
, &IID_IPersistStorage
, (void **)&This
->pPSDelegate
);
1197 if (This
->pPSDelegate
)
1198 hr
= IPersistStorage_InitNew(This
->pPSDelegate
, NULL
);
1201 if (SUCCEEDED(hr
) && This
->containerApp
)
1202 hr
= IOleObject_SetHostNames(This
->pOleDelegate
, This
->containerApp
, This
->containerObj
);
1204 /* FIXME: do more stuff here:
1205 * - IOleObject_GetMiscStatus
1206 * - IOleObject_GetMoniker
1207 * - advise data cache that we've connected somehow?
1210 /* FIXME: if we failed, Close the object */
1215 /************************************************************************
1216 * DefaultHandler_IsRunning (IRunnableObject)
1218 * See Windows documentation for more details on IRunnableObject methods.
1220 static BOOL WINAPI
DefaultHandler_IsRunning(
1221 IRunnableObject
* iface
)
1223 DefaultHandler
*This
= impl_from_IRunnableObject(iface
);
1227 if (This
->pOleDelegate
)
1233 /************************************************************************
1234 * DefaultHandler_LockRunning (IRunnableObject)
1236 * See Windows documentation for more details on IRunnableObject methods.
1238 static HRESULT WINAPI
DefaultHandler_LockRunning(
1239 IRunnableObject
* iface
,
1241 BOOL fLastUnlockCloses
)
1247 /************************************************************************
1248 * DefaultHandler_SetContainedObject (IRunnableObject)
1250 * See Windows documentation for more details on IRunnableObject methods.
1252 static HRESULT WINAPI
DefaultHandler_SetContainedObject(
1253 IRunnableObject
* iface
,
1260 static HRESULT WINAPI
DefaultHandler_IAdviseSink_QueryInterface(
1265 if (IsEqualIID(riid
, &IID_IUnknown
) ||
1266 IsEqualIID(riid
, &IID_IAdviseSink
))
1269 IAdviseSink_AddRef(iface
);
1273 return E_NOINTERFACE
;
1276 static ULONG WINAPI
DefaultHandler_IAdviseSink_AddRef(
1279 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1281 return IUnknown_AddRef((IUnknown
*)&This
->lpvtblIUnknown
);
1284 static ULONG WINAPI
DefaultHandler_IAdviseSink_Release(
1287 DefaultHandler
*This
= impl_from_IAdviseSink(iface
);
1289 return IUnknown_Release((IUnknown
*)&This
->lpvtblIUnknown
);
1292 static void WINAPI
DefaultHandler_IAdviseSink_OnDataChange(
1294 FORMATETC
*pFormatetc
,
1300 static void WINAPI
DefaultHandler_IAdviseSink_OnViewChange(
1308 static void WINAPI
DefaultHandler_IAdviseSink_OnRename(
1315 static void WINAPI
DefaultHandler_IAdviseSink_OnSave(
1321 static void WINAPI
DefaultHandler_IAdviseSink_OnClose(
1328 * Virtual function tables for the DefaultHandler class.
1330 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable
=
1332 DefaultHandler_QueryInterface
,
1333 DefaultHandler_AddRef
,
1334 DefaultHandler_Release
,
1335 DefaultHandler_SetClientSite
,
1336 DefaultHandler_GetClientSite
,
1337 DefaultHandler_SetHostNames
,
1338 DefaultHandler_Close
,
1339 DefaultHandler_SetMoniker
,
1340 DefaultHandler_GetMoniker
,
1341 DefaultHandler_InitFromData
,
1342 DefaultHandler_GetClipboardData
,
1343 DefaultHandler_DoVerb
,
1344 DefaultHandler_EnumVerbs
,
1345 DefaultHandler_Update
,
1346 DefaultHandler_IsUpToDate
,
1347 DefaultHandler_GetUserClassID
,
1348 DefaultHandler_GetUserType
,
1349 DefaultHandler_SetExtent
,
1350 DefaultHandler_GetExtent
,
1351 DefaultHandler_Advise
,
1352 DefaultHandler_Unadvise
,
1353 DefaultHandler_EnumAdvise
,
1354 DefaultHandler_GetMiscStatus
,
1355 DefaultHandler_SetColorScheme
1358 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable
=
1360 DefaultHandler_NDIUnknown_QueryInterface
,
1361 DefaultHandler_NDIUnknown_AddRef
,
1362 DefaultHandler_NDIUnknown_Release
,
1365 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable
=
1367 DefaultHandler_IDataObject_QueryInterface
,
1368 DefaultHandler_IDataObject_AddRef
,
1369 DefaultHandler_IDataObject_Release
,
1370 DefaultHandler_GetData
,
1371 DefaultHandler_GetDataHere
,
1372 DefaultHandler_QueryGetData
,
1373 DefaultHandler_GetCanonicalFormatEtc
,
1374 DefaultHandler_SetData
,
1375 DefaultHandler_EnumFormatEtc
,
1376 DefaultHandler_DAdvise
,
1377 DefaultHandler_DUnadvise
,
1378 DefaultHandler_EnumDAdvise
1381 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable
=
1383 DefaultHandler_IRunnableObject_QueryInterface
,
1384 DefaultHandler_IRunnableObject_AddRef
,
1385 DefaultHandler_IRunnableObject_Release
,
1386 DefaultHandler_GetRunningClass
,
1388 DefaultHandler_IsRunning
,
1389 DefaultHandler_LockRunning
,
1390 DefaultHandler_SetContainedObject
1393 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable
=
1395 DefaultHandler_IAdviseSink_QueryInterface
,
1396 DefaultHandler_IAdviseSink_AddRef
,
1397 DefaultHandler_IAdviseSink_Release
,
1398 DefaultHandler_IAdviseSink_OnDataChange
,
1399 DefaultHandler_IAdviseSink_OnViewChange
,
1400 DefaultHandler_IAdviseSink_OnRename
,
1401 DefaultHandler_IAdviseSink_OnSave
,
1402 DefaultHandler_IAdviseSink_OnClose
1405 /*********************************************************
1406 * Methods implementation for the DefaultHandler class.
1408 static DefaultHandler
* DefaultHandler_Construct(
1410 LPUNKNOWN pUnkOuter
)
1412 DefaultHandler
* This
= NULL
;
1415 * Allocate space for the object.
1417 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler
));
1422 This
->lpVtbl
= &DefaultHandler_IOleObject_VTable
;
1423 This
->lpvtblIUnknown
= &DefaultHandler_NDIUnknown_VTable
;
1424 This
->lpvtblIDataObject
= &DefaultHandler_IDataObject_VTable
;
1425 This
->lpvtblIRunnableObject
= &DefaultHandler_IRunnableObject_VTable
;
1426 This
->lpvtblIAdviseSink
= &DefaultHandler_IAdviseSink_VTable
;
1429 * Start with one reference count. The caller of this function
1430 * must release the interface pointer when it is done.
1435 * Initialize the outer unknown
1436 * We don't keep a reference on the outer unknown since, the way
1437 * aggregation works, our lifetime is at least as large as it's
1441 pUnkOuter
= (IUnknown
*)&This
->lpvtblIUnknown
;
1443 This
->outerUnknown
= pUnkOuter
;
1446 * Create a datacache object.
1447 * We aggregate with the datacache. Make sure we pass our outer
1448 * unknown as the datacache's outer unknown.
1450 CreateDataCache(This
->outerUnknown
,
1453 (void**)&This
->dataCache
);
1456 * Initialize the other data members of the class.
1458 memcpy(&This
->clsid
, clsid
, sizeof(CLSID
));
1459 This
->clientSite
= NULL
;
1460 This
->oleAdviseHolder
= NULL
;
1461 This
->dataAdviseHolder
= NULL
;
1462 This
->containerApp
= NULL
;
1463 This
->containerObj
= NULL
;
1464 This
->pOleDelegate
= NULL
;
1465 This
->pPSDelegate
= NULL
;
1467 This
->dwAdvConn
= 0;
1472 static void DefaultHandler_Destroy(
1473 DefaultHandler
* This
)
1475 if (This
->pOleDelegate
)
1476 IOleObject_Release(This
->pOleDelegate
);
1477 if (This
->pPSDelegate
)
1478 IPersistStorage_Release(This
->pPSDelegate
);
1480 /* Free the strings idenfitying the object */
1481 HeapFree( GetProcessHeap(), 0, This
->containerApp
);
1482 This
->containerApp
= NULL
;
1483 HeapFree( GetProcessHeap(), 0, This
->containerObj
);
1484 This
->containerObj
= NULL
;
1486 /* Release our reference to the data cache. */
1487 if (This
->dataCache
)
1489 IUnknown_Release(This
->dataCache
);
1490 This
->dataCache
= NULL
;
1493 /* Same thing for the client site. */
1494 if (This
->clientSite
)
1496 IOleClientSite_Release(This
->clientSite
);
1497 This
->clientSite
= NULL
;
1500 /* And the advise holder. */
1501 if (This
->oleAdviseHolder
)
1503 IOleAdviseHolder_Release(This
->oleAdviseHolder
);
1504 This
->oleAdviseHolder
= NULL
;
1507 /* And the data advise holder. */
1508 if (This
->dataAdviseHolder
)
1510 IDataAdviseHolder_Release(This
->dataAdviseHolder
);
1511 This
->dataAdviseHolder
= NULL
;
1514 /* Free the actual default handler structure. */
1515 HeapFree(GetProcessHeap(), 0, This
);
1518 /******************************************************************************
1519 * OleCreateDefaultHandler [OLE32.@]
1521 HRESULT WINAPI
OleCreateDefaultHandler(
1523 LPUNKNOWN pUnkOuter
,
1527 DefaultHandler
* newHandler
= NULL
;
1530 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid
), pUnkOuter
, debugstr_guid(riid
), ppvObj
);
1541 * If This handler is constructed for aggregation, make sure
1542 * the caller is requesting the IUnknown interface.
1543 * This is necessary because it's the only time the non-delegating
1544 * IUnknown pointer can be returned to the outside.
1546 if (pUnkOuter
&& !IsEqualIID(&IID_IUnknown
, riid
))
1547 return CLASS_E_NOAGGREGATION
;
1550 * Try to construct a new instance of the class.
1552 newHandler
= DefaultHandler_Construct(clsid
, pUnkOuter
);
1555 return E_OUTOFMEMORY
;
1558 * Make sure it supports the interface required by the caller.
1560 hr
= IUnknown_QueryInterface((IUnknown
*)&newHandler
->lpvtblIUnknown
, riid
, ppvObj
);
1563 * Release the reference obtained in the constructor. If
1564 * the QueryInterface was unsuccessful, it will free the class.
1566 IUnknown_Release((IUnknown
*)&newHandler
->lpvtblIUnknown
);