ntdll: More compatible exception information for protection faults.
[wine/multimedia.git] / dlls / ole32 / defaulthandler.c
blob7f742bccbabcad03ba506db093aafe9e83a165fd
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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"
62 #include "wine/unicode.h"
63 #include "wine/debug.h"
65 WINE_DEFAULT_DEBUG_CHANNEL(ole);
67 /****************************************************************************
68 * DefaultHandler
71 struct DefaultHandler
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 */
80 LONG ref;
82 /* IUnknown implementation of the outer object. */
83 IUnknown* outerUnknown;
85 /* Class Id that this handler object represents. */
86 CLSID clsid;
88 /* IUnknown implementation of the datacache. */
89 IUnknown* 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 */
107 LPWSTR containerApp;
108 LPWSTR containerObj;
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 */
118 DWORD dwAdvConn;
121 typedef struct DefaultHandler DefaultHandler;
124 * Here, I define utility functions to help with the casting of the
125 * "This" parameter.
126 * There is a version to accommodate all of the VTables implemented
127 * by this object.
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(
171 IUnknown* iface,
172 REFIID riid,
173 void** ppvObject)
175 DefaultHandler *This = impl_from_NDIUnknown(iface);
177 /* Perform a sanity check on the parameters. */
178 if (!ppvObject)
179 return E_INVALIDARG;
181 *ppvObject = NULL;
183 if (IsEqualIID(&IID_IUnknown, riid))
184 *ppvObject = iface;
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));
200 return hr;
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
212 * successful.
214 IUnknown_AddRef((IUnknown*)*ppvObject);
216 return S_OK;
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(
228 IUnknown* iface)
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(
243 IUnknown* iface)
245 DefaultHandler *This = impl_from_NDIUnknown(iface);
246 ULONG ref;
248 /* Decrease the reference count on this object. */
249 ref = InterlockedDecrement(&This->ref);
251 if (!ref) DefaultHandler_Destroy(This);
253 return ref;
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(
267 IOleObject* iface,
268 REFIID riid,
269 void** ppvObject)
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(
282 IOleObject* iface)
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(
295 IOleObject* iface)
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(
311 IOleObject* iface,
312 IOleClientSite* pClientSite)
314 DefaultHandler *This = impl_from_IOleObject(iface);
315 HRESULT hr = S_OK;
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
324 * was one.
326 if (This->clientSite)
327 IOleClientSite_Release(This->clientSite);
329 This->clientSite = pClientSite;
331 if (This->clientSite)
332 IOleClientSite_AddRef(This->clientSite);
334 return S_OK;
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(
346 IOleObject* iface,
347 IOleClientSite** ppClientSite)
349 DefaultHandler *This = impl_from_IOleObject(iface);
351 /* Sanity check. */
352 if (!ppClientSite)
353 return E_POINTER;
355 *ppClientSite = This->clientSite;
357 if (This->clientSite)
358 IOleClientSite_AddRef(This->clientSite);
360 return S_OK;
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(
372 IOleObject* iface,
373 LPCOLESTR szContainerApp,
374 LPCOLESTR szContainerObj)
376 DefaultHandler *This = impl_from_IOleObject(iface);
378 TRACE("(%p, %s, %s)\n",
379 iface,
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. */
393 if (szContainerApp)
395 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
396 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
397 strcpyW( This->containerApp, szContainerApp );
400 if (szContainerObj)
402 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
403 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
404 strcpyW( This->containerObj, szContainerObj );
406 return S_OK;
409 /* undos the work done by DefaultHandler_Run */
410 static void WINAPI DefaultHandler_Stop(DefaultHandler *This)
412 if (!This->pOleDelegate)
413 return;
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(
443 IOleObject* iface,
444 DWORD dwSaveOption)
446 DefaultHandler *This = impl_from_IOleObject(iface);
447 HRESULT hr;
449 TRACE("(%ld)\n", dwSaveOption);
451 if (!This->pOleDelegate)
452 return S_OK;
454 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
456 DefaultHandler_Stop(This);
458 return hr;
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(
469 IOleObject* iface,
470 DWORD dwWhichMoniker,
471 IMoniker* pmk)
473 DefaultHandler *This = impl_from_IOleObject(iface);
475 TRACE("(%p, %ld, %p)\n",
476 iface,
477 dwWhichMoniker,
478 pmk);
480 if (This->pOleDelegate)
481 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
483 return S_OK;
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(
494 IOleObject* iface,
495 DWORD dwAssign,
496 DWORD dwWhichMoniker,
497 IMoniker** ppmk)
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,
506 ppmk);
508 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
509 if (This->clientSite)
511 return IOleClientSite_GetMoniker(This->clientSite,
512 dwAssign,
513 dwWhichMoniker,
514 ppmk);
518 return E_FAIL;
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(
529 IOleObject* iface,
530 IDataObject* pDataObject,
531 BOOL fCreation,
532 DWORD dwReserved)
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,
541 dwReserved);
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(
553 IOleObject* iface,
554 DWORD dwReserved,
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,
564 ppDataObject);
566 return OLE_E_NOTRUNNING;
569 static HRESULT WINAPI DefaultHandler_DoVerb(
570 IOleObject* iface,
571 LONG iVerb,
572 struct tagMSG* lpmsg,
573 IOleClientSite* pActiveSite,
574 LONG lindex,
575 HWND hwndParent,
576 LPCRECT lprcPosRect)
578 DefaultHandler *This = impl_from_IOleObject(iface);
579 IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
580 HRESULT hr;
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
595 * to OleRegEnumVerbs
597 * See Windows documentation for more details on IOleObject methods.
599 static HRESULT WINAPI DefaultHandler_EnumVerbs(
600 IOleObject* iface,
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);
613 else
614 return hr;
617 static HRESULT WINAPI DefaultHandler_Update(
618 IOleObject* iface)
620 FIXME(": Stub\n");
621 return E_NOTIMPL;
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(
632 IOleObject* iface)
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(
647 IOleObject* iface,
648 CLSID* pClsid)
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);
660 /* Sanity check. */
661 if (!pClsid)
662 return E_POINTER;
664 memcpy(pClsid, &This->clsid, sizeof(CLSID));
666 return S_OK;
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(
678 IOleObject* iface,
679 DWORD dwFormOfType,
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(
697 IOleObject* iface,
698 DWORD dwDrawAspect,
699 SIZEL* psizel)
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(
721 IOleObject* iface,
722 DWORD dwDrawAspect,
723 SIZEL* psizel)
725 DVTARGETDEVICE* targetDevice;
726 IViewObject2* cacheView = NULL;
727 HRESULT hres;
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);
737 if (FAILED(hres))
738 return E_UNEXPECTED;
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.
748 targetDevice = NULL;
750 hres = IViewObject2_GetExtent(cacheView,
751 dwDrawAspect,
753 targetDevice,
754 psizel);
757 * Cleanup
759 IViewObject2_Release(cacheView);
761 return hres;
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(
773 IOleObject* iface,
774 IAdviseSink* pAdvSink,
775 DWORD* pdwConnection)
777 HRESULT hres = S_OK;
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);
786 if (SUCCEEDED(hres))
787 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
788 pAdvSink,
789 pdwConnection);
791 return hres;
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(
803 IOleObject* iface,
804 DWORD dwConnection)
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
812 * a connection.
814 if (!This->oleAdviseHolder)
815 return OLE_E_NOCONNECTION;
817 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
818 dwConnection);
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(
830 IOleObject* iface,
831 IEnumSTATDATA** ppenumAdvise)
833 DefaultHandler *This = impl_from_IOleObject(iface);
835 TRACE("(%p, %p)\n", iface, ppenumAdvise);
837 /* Sanity check */
838 if (!ppenumAdvise)
839 return E_POINTER;
841 *ppenumAdvise = NULL;
843 if (!This->oleAdviseHolder)
844 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder,
845 ppenumAdvise);
847 return S_OK;
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(
859 IOleObject* iface,
860 DWORD dwAspect,
861 DWORD* pdwStatus)
863 HRESULT hres;
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);
876 if (FAILED(hres))
877 *pdwStatus = 0;
879 return S_OK;
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(
890 IOleObject* iface,
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(
914 IDataObject* iface,
915 REFIID riid,
916 void** ppvObject)
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(
929 IDataObject* iface)
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(
942 IDataObject* iface)
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(
957 IDataObject* iface,
958 LPFORMATETC pformatetcIn,
959 STGMEDIUM* pmedium)
961 IDataObject* cacheDataObject = NULL;
962 HRESULT hres;
964 DefaultHandler *This = impl_from_IDataObject(iface);
966 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
968 hres = IUnknown_QueryInterface(This->dataCache,
969 &IID_IDataObject,
970 (void**)&cacheDataObject);
972 if (FAILED(hres))
973 return E_UNEXPECTED;
975 hres = IDataObject_GetData(cacheDataObject,
976 pformatetcIn,
977 pmedium);
979 IDataObject_Release(cacheDataObject);
981 return hres;
984 static HRESULT WINAPI DefaultHandler_GetDataHere(
985 IDataObject* iface,
986 LPFORMATETC pformatetc,
987 STGMEDIUM* pmedium)
989 FIXME(": Stub\n");
990 return E_NOTIMPL;
993 /************************************************************************
994 * DefaultHandler_QueryGetData (IDataObject)
996 * The default handler's implementation of this method delegates to
997 * the cache.
999 * See Windows documentation for more details on IDataObject methods.
1001 static HRESULT WINAPI DefaultHandler_QueryGetData(
1002 IDataObject* iface,
1003 LPFORMATETC pformatetc)
1005 IDataObject* cacheDataObject = NULL;
1006 HRESULT hres;
1008 DefaultHandler *This = impl_from_IDataObject(iface);
1010 TRACE("(%p, %p)\n", iface, pformatetc);
1012 hres = IUnknown_QueryInterface(This->dataCache,
1013 &IID_IDataObject,
1014 (void**)&cacheDataObject);
1016 if (FAILED(hres))
1017 return E_UNEXPECTED;
1019 hres = IDataObject_QueryGetData(cacheDataObject,
1020 pformatetc);
1022 IDataObject_Release(cacheDataObject);
1024 return hres;
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(
1035 IDataObject* iface,
1036 LPFORMATETC pformatetcIn,
1037 LPFORMATETC pformatetcOut)
1039 DefaultHandler *This = impl_from_IDataObject(iface);
1040 IDataObject *pDataObject;
1041 HRESULT hr;
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
1056 * the cache.
1058 * See Windows documentation for more details on IDataObject methods.
1060 static HRESULT WINAPI DefaultHandler_SetData(
1061 IDataObject* iface,
1062 LPFORMATETC pformatetc,
1063 STGMEDIUM* pmedium,
1064 BOOL fRelease)
1066 DefaultHandler *This = impl_from_IDataObject(iface);
1067 IDataObject* cacheDataObject = NULL;
1068 HRESULT hres;
1070 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1072 hres = IUnknown_QueryInterface(This->dataCache,
1073 &IID_IDataObject,
1074 (void**)&cacheDataObject);
1076 if (FAILED(hres))
1077 return E_UNEXPECTED;
1079 hres = IDataObject_SetData(cacheDataObject,
1080 pformatetc,
1081 pmedium,
1082 fRelease);
1084 IDataObject_Release(cacheDataObject);
1086 return hres;
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(
1098 IDataObject* iface,
1099 DWORD dwDirection,
1100 IEnumFORMATETC** ppenumFormatEtc)
1102 HRESULT hres;
1103 DefaultHandler *This = impl_from_IDataObject(iface);
1105 TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
1107 hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1109 return hres;
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(
1121 IDataObject* iface,
1122 FORMATETC* pformatetc,
1123 DWORD advf,
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,
1139 iface,
1140 pformatetc,
1141 advf,
1142 pAdvSink,
1143 pdwConnection);
1145 return hres;
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(
1157 IDataObject* iface,
1158 DWORD dwConnection)
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,
1172 dwConnection);
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(
1184 IDataObject* iface,
1185 IEnumSTATDATA** ppenumAdvise)
1187 DefaultHandler *This = impl_from_IDataObject(iface);
1189 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1191 /* Sanity check */
1192 if (!ppenumAdvise)
1193 return E_POINTER;
1195 *ppenumAdvise = NULL;
1197 /* If we have a data advise holder object, delegate. */
1198 if (This->dataAdviseHolder)
1199 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1200 ppenumAdvise);
1202 return S_OK;
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,
1217 REFIID riid,
1218 void** ppvObject)
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,
1258 LPCLSID lpClsid)
1260 FIXME("()\n");
1261 return S_OK;
1264 static HRESULT WINAPI DefaultHandler_Run(
1265 IRunnableObject* iface,
1266 IBindCtx* pbc)
1268 DefaultHandler *This = impl_from_IRunnableObject(iface);
1269 HRESULT hr;
1271 FIXME("(%p): semi-stub\n", pbc);
1273 /* already running? if so nothing to do */
1274 if (This->pOleDelegate)
1275 return S_OK;
1277 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1278 &IID_IOleObject, (void **)&This->pOleDelegate);
1279 if (FAILED(hr))
1280 return hr;
1282 hr = IOleObject_Advise(This->pOleDelegate,
1283 (IAdviseSink *)&This->lpvtblIAdviseSink,
1284 &This->dwAdvConn);
1286 if (SUCCEEDED(hr) && This->clientSite)
1287 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1289 if (SUCCEEDED(hr))
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
1304 * - IOleCache_OnRun
1307 if (SUCCEEDED(hr))
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);
1314 if (FAILED(hr))
1315 DefaultHandler_Stop(This);
1317 return hr;
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);
1330 TRACE("()\n");
1332 if (This->pOleDelegate)
1333 return TRUE;
1334 else
1335 return FALSE;
1338 /************************************************************************
1339 * DefaultHandler_LockRunning (IRunnableObject)
1341 * See Windows documentation for more details on IRunnableObject methods.
1343 static HRESULT WINAPI DefaultHandler_LockRunning(
1344 IRunnableObject* iface,
1345 BOOL fLock,
1346 BOOL fLastUnlockCloses)
1348 FIXME("()\n");
1349 return S_OK;
1352 /************************************************************************
1353 * DefaultHandler_SetContainedObject (IRunnableObject)
1355 * See Windows documentation for more details on IRunnableObject methods.
1357 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1358 IRunnableObject* iface,
1359 BOOL fContained)
1361 FIXME("()\n");
1362 return S_OK;
1365 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1366 IAdviseSink *iface,
1367 REFIID riid,
1368 void **ppvObject)
1370 if (IsEqualIID(riid, &IID_IUnknown) ||
1371 IsEqualIID(riid, &IID_IAdviseSink))
1373 *ppvObject = iface;
1374 IAdviseSink_AddRef(iface);
1375 return S_OK;
1378 return E_NOINTERFACE;
1381 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1382 IAdviseSink *iface)
1384 DefaultHandler *This = impl_from_IAdviseSink(iface);
1386 return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1389 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1390 IAdviseSink *iface)
1392 DefaultHandler *This = impl_from_IAdviseSink(iface);
1394 return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1397 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1398 IAdviseSink *iface,
1399 FORMATETC *pFormatetc,
1400 STGMEDIUM *pStgmed)
1402 FIXME(": stub\n");
1405 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1406 IAdviseSink *iface,
1407 DWORD dwAspect,
1408 LONG lindex)
1410 FIXME(": stub\n");
1413 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1414 IAdviseSink *iface,
1415 IMoniker *pmk)
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(
1426 IAdviseSink *iface)
1428 DefaultHandler *This = impl_from_IAdviseSink(iface);
1430 TRACE("()\n");
1432 if (This->oleAdviseHolder)
1433 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1436 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1437 IAdviseSink *iface)
1439 DefaultHandler *This = impl_from_IAdviseSink(iface);
1441 TRACE("()\n");
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,
1509 DefaultHandler_Run,
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(
1531 REFCLSID clsid,
1532 LPUNKNOWN pUnkOuter)
1534 DefaultHandler* This = NULL;
1537 * Allocate space for the object.
1539 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1541 if (!This)
1542 return This;
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.
1554 This->ref = 1;
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
1560 * lifetime.
1562 if (!pUnkOuter)
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,
1573 clsid,
1574 &IID_IUnknown,
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;
1592 return This;
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(
1643 REFCLSID clsid,
1644 LPUNKNOWN pUnkOuter,
1645 REFIID riid,
1646 LPVOID* ppvObj)
1648 DefaultHandler* newHandler = NULL;
1649 HRESULT hr = S_OK;
1651 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1654 * Sanity check
1656 if (!ppvObj)
1657 return E_POINTER;
1659 *ppvObj = NULL;
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);
1675 if (!newHandler)
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);
1689 return hr;