ole32: Add DebugInfo to critical sections.
[wine/hacks.git] / dlls / ole32 / defaulthandler.c
blob9486813f1051b1ed80d1ddc4aba3f3b7b462b38d
1 /*
2 * OLE 2 default object handler
4 * Copyright 1999 Francis Beaudet
5 * Copyright 2000 Abey George
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * NOTES:
22 * The OLE2 default object handler supports a whole whack of
23 * interfaces including:
24 * IOleObject, IDataObject, IPersistStorage, IViewObject2,
25 * IRunnableObject, IOleCache2, IOleCacheControl and much more.
27 * All the implementation details are taken from: Inside OLE
28 * second edition by Kraig Brockschmidt,
30 * TODO
31 * - This implementation of the default handler does not launch the
32 * server in the DoVerb, Update, GetData, GetDataHere and Run
33 * methods. When it is fixed to do so, all the methods will have
34 * to be revisited to allow delegating to the running object
36 * - All methods in the class that use the class ID should be
37 * aware that it is possible for a class to be treated as
38 * another one and go into emulation mode. Nothing has been
39 * done in this area.
41 * - Some functions still return E_NOTIMPL they have to be
42 * implemented. Most of those are related to the running of the
43 * actual server.
45 * - All the methods related to notification and advise sinks are
46 * in place but no notifications are sent to the sinks yet.
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <string.h>
52 #define COBJMACROS
54 #include "windef.h"
55 #include "winbase.h"
56 #include "winuser.h"
57 #include "winerror.h"
58 #include "ole2.h"
60 #include "compobj_private.h"
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 if (This->dataAdviseHolder)
420 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
421 if (This->pDataDelegate)
423 IDataObject_Release(This->pDataDelegate);
424 This->pDataDelegate = NULL;
426 if (This->pPSDelegate)
428 IPersistStorage_Release(This->pPSDelegate);
429 This->pPSDelegate = NULL;
431 IOleObject_Release(This->pOleDelegate);
432 This->pOleDelegate = NULL;
435 /************************************************************************
436 * DefaultHandler_Close (IOleObject)
438 * The default handler's implementation of this method is meaningless
439 * without a running server so it does nothing.
441 * See Windows documentation for more details on IOleObject methods.
443 static HRESULT WINAPI DefaultHandler_Close(
444 IOleObject* iface,
445 DWORD dwSaveOption)
447 DefaultHandler *This = impl_from_IOleObject(iface);
448 HRESULT hr;
450 TRACE("(%d)\n", dwSaveOption);
452 if (!This->pOleDelegate)
453 return S_OK;
455 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
457 DefaultHandler_Stop(This);
459 return hr;
462 /************************************************************************
463 * DefaultHandler_SetMoniker (IOleObject)
465 * The default handler's implementation of this method does nothing.
467 * See Windows documentation for more details on IOleObject methods.
469 static HRESULT WINAPI DefaultHandler_SetMoniker(
470 IOleObject* iface,
471 DWORD dwWhichMoniker,
472 IMoniker* pmk)
474 DefaultHandler *This = impl_from_IOleObject(iface);
476 TRACE("(%p, %d, %p)\n",
477 iface,
478 dwWhichMoniker,
479 pmk);
481 if (This->pOleDelegate)
482 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
484 return S_OK;
487 /************************************************************************
488 * DefaultHandler_GetMoniker (IOleObject)
490 * Delegate this request to the client site if we have one.
492 * See Windows documentation for more details on IOleObject methods.
494 static HRESULT WINAPI DefaultHandler_GetMoniker(
495 IOleObject* iface,
496 DWORD dwAssign,
497 DWORD dwWhichMoniker,
498 IMoniker** ppmk)
500 DefaultHandler *This = impl_from_IOleObject(iface);
502 TRACE("(%p, %d, %d, %p)\n",
503 iface, dwAssign, dwWhichMoniker, ppmk);
505 if (This->pOleDelegate)
506 return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
507 ppmk);
509 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
510 if (This->clientSite)
512 return IOleClientSite_GetMoniker(This->clientSite,
513 dwAssign,
514 dwWhichMoniker,
515 ppmk);
519 return E_FAIL;
522 /************************************************************************
523 * DefaultHandler_InitFromData (IOleObject)
525 * This method is meaningless if the server is not running
527 * See Windows documentation for more details on IOleObject methods.
529 static HRESULT WINAPI DefaultHandler_InitFromData(
530 IOleObject* iface,
531 IDataObject* pDataObject,
532 BOOL fCreation,
533 DWORD dwReserved)
535 DefaultHandler *This = impl_from_IOleObject(iface);
537 TRACE("(%p, %p, %d, %d)\n",
538 iface, pDataObject, fCreation, dwReserved);
540 if (This->pOleDelegate)
541 return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
542 dwReserved);
543 return OLE_E_NOTRUNNING;
546 /************************************************************************
547 * DefaultHandler_GetClipboardData (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_GetClipboardData(
554 IOleObject* iface,
555 DWORD dwReserved,
556 IDataObject** ppDataObject)
558 DefaultHandler *This = impl_from_IOleObject(iface);
560 TRACE("(%p, %d, %p)\n",
561 iface, dwReserved, ppDataObject);
563 if (This->pOleDelegate)
564 return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
565 ppDataObject);
567 return OLE_E_NOTRUNNING;
570 static HRESULT WINAPI DefaultHandler_DoVerb(
571 IOleObject* iface,
572 LONG iVerb,
573 struct tagMSG* lpmsg,
574 IOleClientSite* pActiveSite,
575 LONG lindex,
576 HWND hwndParent,
577 LPCRECT lprcPosRect)
579 DefaultHandler *This = impl_from_IOleObject(iface);
580 IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
581 HRESULT hr;
583 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
585 hr = IRunnableObject_Run(pRunnableObj, NULL);
586 if (FAILED(hr)) return hr;
588 return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
589 lindex, hwndParent, lprcPosRect);
592 /************************************************************************
593 * DefaultHandler_EnumVerbs (IOleObject)
595 * The default handler implementation of this method simply delegates
596 * to OleRegEnumVerbs
598 * See Windows documentation for more details on IOleObject methods.
600 static HRESULT WINAPI DefaultHandler_EnumVerbs(
601 IOleObject* iface,
602 IEnumOLEVERB** ppEnumOleVerb)
604 DefaultHandler *This = impl_from_IOleObject(iface);
605 HRESULT hr = OLE_S_USEREG;
607 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
609 if (This->pOleDelegate)
610 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
612 if (hr == OLE_S_USEREG)
613 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
614 else
615 return hr;
618 static HRESULT WINAPI DefaultHandler_Update(
619 IOleObject* iface)
621 FIXME(": Stub\n");
622 return E_NOTIMPL;
625 /************************************************************************
626 * DefaultHandler_IsUpToDate (IOleObject)
628 * This method is meaningless if the server is not running
630 * See Windows documentation for more details on IOleObject methods.
632 static HRESULT WINAPI DefaultHandler_IsUpToDate(
633 IOleObject* iface)
635 TRACE("(%p)\n", iface);
637 return OLE_E_NOTRUNNING;
640 /************************************************************************
641 * DefaultHandler_GetUserClassID (IOleObject)
643 * TODO: Map to a new class ID if emulation is active.
645 * See Windows documentation for more details on IOleObject methods.
647 static HRESULT WINAPI DefaultHandler_GetUserClassID(
648 IOleObject* iface,
649 CLSID* pClsid)
651 DefaultHandler *This = impl_from_IOleObject(iface);
653 TRACE("(%p, %p)\n", iface, pClsid);
655 if (This->pOleDelegate)
656 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
658 /* Sanity check. */
659 if (!pClsid)
660 return E_POINTER;
662 memcpy(pClsid, &This->clsid, sizeof(CLSID));
664 return S_OK;
667 /************************************************************************
668 * DefaultHandler_GetUserType (IOleObject)
670 * The default handler implementation of this method simply delegates
671 * to OleRegGetUserType
673 * See Windows documentation for more details on IOleObject methods.
675 static HRESULT WINAPI DefaultHandler_GetUserType(
676 IOleObject* iface,
677 DWORD dwFormOfType,
678 LPOLESTR* pszUserType)
680 DefaultHandler *This = impl_from_IOleObject(iface);
682 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
684 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
687 /************************************************************************
688 * DefaultHandler_SetExtent (IOleObject)
690 * This method is meaningless if the server is not running
692 * See Windows documentation for more details on IOleObject methods.
694 static HRESULT WINAPI DefaultHandler_SetExtent(
695 IOleObject* iface,
696 DWORD dwDrawAspect,
697 SIZEL* psizel)
699 DefaultHandler *This = impl_from_IOleObject(iface);
701 TRACE("(%p, %x, (%d x %d))\n", iface,
702 dwDrawAspect, psizel->cx, psizel->cy);
704 if (This->pOleDelegate)
705 IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
707 return OLE_E_NOTRUNNING;
710 /************************************************************************
711 * DefaultHandler_GetExtent (IOleObject)
713 * The default handler's implementation of this method returns uses
714 * the cache to locate the aspect and extract the extent from it.
716 * See Windows documentation for more details on IOleObject methods.
718 static HRESULT WINAPI DefaultHandler_GetExtent(
719 IOleObject* iface,
720 DWORD dwDrawAspect,
721 SIZEL* psizel)
723 DVTARGETDEVICE* targetDevice;
724 IViewObject2* cacheView = NULL;
725 HRESULT hres;
727 DefaultHandler *This = impl_from_IOleObject(iface);
729 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
731 if (This->pOleDelegate)
732 return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
734 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
735 if (FAILED(hres))
736 return E_UNEXPECTED;
739 * Prepare the call to the cache's GetExtent method.
741 * Here we would build a valid DVTARGETDEVICE structure
742 * but, since we are calling into the data cache, we
743 * know it's implementation and we'll skip this
744 * extra work until later.
746 targetDevice = NULL;
748 hres = IViewObject2_GetExtent(cacheView,
749 dwDrawAspect,
751 targetDevice,
752 psizel);
755 * Cleanup
757 IViewObject2_Release(cacheView);
759 return hres;
762 /************************************************************************
763 * DefaultHandler_Advise (IOleObject)
765 * The default handler's implementation of this method simply
766 * delegates to the OleAdviseHolder.
768 * See Windows documentation for more details on IOleObject methods.
770 static HRESULT WINAPI DefaultHandler_Advise(
771 IOleObject* iface,
772 IAdviseSink* pAdvSink,
773 DWORD* pdwConnection)
775 HRESULT hres = S_OK;
776 DefaultHandler *This = impl_from_IOleObject(iface);
778 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
780 /* Make sure we have an advise holder before we start. */
781 if (!This->oleAdviseHolder)
782 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
784 if (SUCCEEDED(hres))
785 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
786 pAdvSink,
787 pdwConnection);
789 return hres;
792 /************************************************************************
793 * DefaultHandler_Unadvise (IOleObject)
795 * The default handler's implementation of this method simply
796 * delegates to the OleAdviseHolder.
798 * See Windows documentation for more details on IOleObject methods.
800 static HRESULT WINAPI DefaultHandler_Unadvise(
801 IOleObject* iface,
802 DWORD dwConnection)
804 DefaultHandler *This = impl_from_IOleObject(iface);
806 TRACE("(%p, %d)\n", iface, dwConnection);
809 * If we don't have an advise holder yet, it means we don't have
810 * a connection.
812 if (!This->oleAdviseHolder)
813 return OLE_E_NOCONNECTION;
815 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
816 dwConnection);
819 /************************************************************************
820 * DefaultHandler_EnumAdvise (IOleObject)
822 * The default handler's implementation of this method simply
823 * delegates to the OleAdviseHolder.
825 * See Windows documentation for more details on IOleObject methods.
827 static HRESULT WINAPI DefaultHandler_EnumAdvise(
828 IOleObject* iface,
829 IEnumSTATDATA** ppenumAdvise)
831 DefaultHandler *This = impl_from_IOleObject(iface);
833 TRACE("(%p, %p)\n", iface, ppenumAdvise);
835 /* Sanity check */
836 if (!ppenumAdvise)
837 return E_POINTER;
839 *ppenumAdvise = NULL;
841 if (!This->oleAdviseHolder)
842 return S_OK;
844 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
847 /************************************************************************
848 * DefaultHandler_GetMiscStatus (IOleObject)
850 * The default handler's implementation of this method simply delegates
851 * to OleRegGetMiscStatus.
853 * See Windows documentation for more details on IOleObject methods.
855 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
856 IOleObject* iface,
857 DWORD dwAspect,
858 DWORD* pdwStatus)
860 HRESULT hres;
861 DefaultHandler *This = impl_from_IOleObject(iface);
863 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
865 if (This->pOleDelegate)
866 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
868 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
870 if (FAILED(hres))
871 *pdwStatus = 0;
873 return S_OK;
876 /************************************************************************
877 * DefaultHandler_SetColorScheme (IOleObject)
879 * This method is meaningless if the server is not running
881 * See Windows documentation for more details on IOleObject methods.
883 static HRESULT WINAPI DefaultHandler_SetColorScheme(
884 IOleObject* iface,
885 struct tagLOGPALETTE* pLogpal)
887 DefaultHandler *This = impl_from_IOleObject(iface);
889 TRACE("(%p, %p))\n", iface, pLogpal);
891 if (This->pOleDelegate)
892 return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
894 return OLE_E_NOTRUNNING;
897 /*********************************************************
898 * Methods implementation for the IDataObject part of
899 * the DefaultHandler class.
902 /************************************************************************
903 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
905 * See Windows documentation for more details on IUnknown methods.
907 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
908 IDataObject* iface,
909 REFIID riid,
910 void** ppvObject)
912 DefaultHandler *This = impl_from_IDataObject(iface);
914 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
917 /************************************************************************
918 * DefaultHandler_IDataObject_AddRef (IUnknown)
920 * See Windows documentation for more details on IUnknown methods.
922 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
923 IDataObject* iface)
925 DefaultHandler *This = impl_from_IDataObject(iface);
927 return IUnknown_AddRef(This->outerUnknown);
930 /************************************************************************
931 * DefaultHandler_IDataObject_Release (IUnknown)
933 * See Windows documentation for more details on IUnknown methods.
935 static ULONG WINAPI DefaultHandler_IDataObject_Release(
936 IDataObject* iface)
938 DefaultHandler *This = impl_from_IDataObject(iface);
940 return IUnknown_Release(This->outerUnknown);
943 /************************************************************************
944 * DefaultHandler_GetData
946 * Get Data from a source dataobject using format pformatetcIn->cfFormat
947 * See Windows documentation for more details on GetData.
948 * Default handler's implementation of this method delegates to the cache.
950 static HRESULT WINAPI DefaultHandler_GetData(
951 IDataObject* iface,
952 LPFORMATETC pformatetcIn,
953 STGMEDIUM* pmedium)
955 IDataObject* cacheDataObject = NULL;
956 HRESULT hres;
958 DefaultHandler *This = impl_from_IDataObject(iface);
960 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
962 hres = IUnknown_QueryInterface(This->dataCache,
963 &IID_IDataObject,
964 (void**)&cacheDataObject);
966 if (FAILED(hres))
967 return E_UNEXPECTED;
969 hres = IDataObject_GetData(cacheDataObject,
970 pformatetcIn,
971 pmedium);
973 IDataObject_Release(cacheDataObject);
975 if (FAILED(hres) && This->pDataDelegate)
976 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
978 return hres;
981 static HRESULT WINAPI DefaultHandler_GetDataHere(
982 IDataObject* iface,
983 LPFORMATETC pformatetc,
984 STGMEDIUM* pmedium)
986 FIXME(": Stub\n");
987 return E_NOTIMPL;
990 /************************************************************************
991 * DefaultHandler_QueryGetData (IDataObject)
993 * The default handler's implementation of this method delegates to
994 * the cache.
996 * See Windows documentation for more details on IDataObject methods.
998 static HRESULT WINAPI DefaultHandler_QueryGetData(
999 IDataObject* iface,
1000 LPFORMATETC pformatetc)
1002 IDataObject* cacheDataObject = NULL;
1003 HRESULT hres;
1005 DefaultHandler *This = impl_from_IDataObject(iface);
1007 TRACE("(%p, %p)\n", iface, pformatetc);
1009 hres = IUnknown_QueryInterface(This->dataCache,
1010 &IID_IDataObject,
1011 (void**)&cacheDataObject);
1013 if (FAILED(hres))
1014 return E_UNEXPECTED;
1016 hres = IDataObject_QueryGetData(cacheDataObject,
1017 pformatetc);
1019 IDataObject_Release(cacheDataObject);
1021 if (FAILED(hres) && This->pDataDelegate)
1022 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
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);
1041 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1043 if (!This->pDataDelegate)
1044 return OLE_E_NOTRUNNING;
1046 return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1049 /************************************************************************
1050 * DefaultHandler_SetData (IDataObject)
1052 * The default handler's implementation of this method delegates to
1053 * the cache.
1055 * See Windows documentation for more details on IDataObject methods.
1057 static HRESULT WINAPI DefaultHandler_SetData(
1058 IDataObject* iface,
1059 LPFORMATETC pformatetc,
1060 STGMEDIUM* pmedium,
1061 BOOL fRelease)
1063 DefaultHandler *This = impl_from_IDataObject(iface);
1064 IDataObject* cacheDataObject = NULL;
1065 HRESULT hres;
1067 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1069 hres = IUnknown_QueryInterface(This->dataCache,
1070 &IID_IDataObject,
1071 (void**)&cacheDataObject);
1073 if (FAILED(hres))
1074 return E_UNEXPECTED;
1076 hres = IDataObject_SetData(cacheDataObject,
1077 pformatetc,
1078 pmedium,
1079 fRelease);
1081 IDataObject_Release(cacheDataObject);
1083 return hres;
1086 /************************************************************************
1087 * DefaultHandler_EnumFormatEtc (IDataObject)
1089 * The default handler's implementation of This method simply delegates
1090 * to OleRegEnumFormatEtc.
1092 * See Windows documentation for more details on IDataObject methods.
1094 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1095 IDataObject* iface,
1096 DWORD dwDirection,
1097 IEnumFORMATETC** ppenumFormatEtc)
1099 HRESULT hres;
1100 DefaultHandler *This = impl_from_IDataObject(iface);
1102 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1104 hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1106 return hres;
1109 /************************************************************************
1110 * DefaultHandler_DAdvise (IDataObject)
1112 * The default handler's implementation of this method simply
1113 * delegates to the DataAdviseHolder.
1115 * See Windows documentation for more details on IDataObject methods.
1117 static HRESULT WINAPI DefaultHandler_DAdvise(
1118 IDataObject* iface,
1119 FORMATETC* pformatetc,
1120 DWORD advf,
1121 IAdviseSink* pAdvSink,
1122 DWORD* pdwConnection)
1124 HRESULT hres = S_OK;
1125 DefaultHandler *This = impl_from_IDataObject(iface);
1127 TRACE("(%p, %p, %d, %p, %p)\n",
1128 iface, pformatetc, advf, pAdvSink, pdwConnection);
1130 /* Make sure we have a data advise holder before we start. */
1131 if (!This->dataAdviseHolder)
1133 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1134 if (SUCCEEDED(hres) && This->pDataDelegate)
1135 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1138 if (SUCCEEDED(hres))
1139 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1140 iface,
1141 pformatetc,
1142 advf,
1143 pAdvSink,
1144 pdwConnection);
1146 return hres;
1149 /************************************************************************
1150 * DefaultHandler_DUnadvise (IDataObject)
1152 * The default handler's implementation of this method simply
1153 * delegates to the DataAdviseHolder.
1155 * See Windows documentation for more details on IDataObject methods.
1157 static HRESULT WINAPI DefaultHandler_DUnadvise(
1158 IDataObject* iface,
1159 DWORD dwConnection)
1161 DefaultHandler *This = impl_from_IDataObject(iface);
1163 TRACE("(%p, %d)\n", iface, dwConnection);
1166 * If we don't have a data advise holder yet, it means that
1167 * we don't have any connections..
1169 if (!This->dataAdviseHolder)
1170 return OLE_E_NOCONNECTION;
1172 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1173 dwConnection);
1176 /************************************************************************
1177 * DefaultHandler_EnumDAdvise (IDataObject)
1179 * The default handler's implementation of this method simply
1180 * delegates to the DataAdviseHolder.
1182 * See Windows documentation for more details on IDataObject methods.
1184 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1185 IDataObject* iface,
1186 IEnumSTATDATA** ppenumAdvise)
1188 DefaultHandler *This = impl_from_IDataObject(iface);
1190 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1192 /* Sanity check */
1193 if (!ppenumAdvise)
1194 return E_POINTER;
1196 *ppenumAdvise = NULL;
1198 /* If we have a data advise holder object, delegate. */
1199 if (This->dataAdviseHolder)
1200 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1201 ppenumAdvise);
1203 return S_OK;
1206 /*********************************************************
1207 * Methods implementation for the IRunnableObject part
1208 * of the DefaultHandler class.
1211 /************************************************************************
1212 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1214 * See Windows documentation for more details on IUnknown methods.
1216 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1217 IRunnableObject* iface,
1218 REFIID riid,
1219 void** ppvObject)
1221 DefaultHandler *This = impl_from_IRunnableObject(iface);
1223 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1226 /************************************************************************
1227 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1229 * See Windows documentation for more details on IUnknown methods.
1231 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1232 IRunnableObject* iface)
1234 DefaultHandler *This = impl_from_IRunnableObject(iface);
1236 return IUnknown_AddRef(This->outerUnknown);
1239 /************************************************************************
1240 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1242 * See Windows documentation for more details on IUnknown methods.
1244 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1245 IRunnableObject* iface)
1247 DefaultHandler *This = impl_from_IRunnableObject(iface);
1249 return IUnknown_Release(This->outerUnknown);
1252 /************************************************************************
1253 * DefaultHandler_GetRunningClass (IRunnableObject)
1255 * See Windows documentation for more details on IRunnableObject methods.
1257 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1258 IRunnableObject* iface,
1259 LPCLSID lpClsid)
1261 FIXME("()\n");
1262 return S_OK;
1265 static HRESULT WINAPI DefaultHandler_Run(
1266 IRunnableObject* iface,
1267 IBindCtx* pbc)
1269 DefaultHandler *This = impl_from_IRunnableObject(iface);
1270 HRESULT hr;
1272 FIXME("(%p): semi-stub\n", pbc);
1274 /* already running? if so nothing to do */
1275 if (This->pOleDelegate)
1276 return S_OK;
1278 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1279 &IID_IOleObject, (void **)&This->pOleDelegate);
1280 if (FAILED(hr))
1281 return hr;
1283 hr = IOleObject_Advise(This->pOleDelegate,
1284 (IAdviseSink *)&This->lpvtblIAdviseSink,
1285 &This->dwAdvConn);
1287 if (SUCCEEDED(hr) && This->clientSite)
1288 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1290 if (SUCCEEDED(hr))
1292 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1293 (void **)&This->pPSDelegate);
1294 if (This->pPSDelegate)
1295 hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
1298 if (SUCCEEDED(hr) && This->containerApp)
1299 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1300 This->containerObj);
1302 /* FIXME: do more stuff here:
1303 * - IOleObject_GetMiscStatus
1304 * - IOleObject_GetMoniker
1305 * - IOleCache_OnRun
1308 if (SUCCEEDED(hr))
1309 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1310 (void **)&This->pDataDelegate);
1312 if (SUCCEEDED(hr) && This->dataAdviseHolder)
1313 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1315 if (FAILED(hr))
1316 DefaultHandler_Stop(This);
1318 return hr;
1321 /************************************************************************
1322 * DefaultHandler_IsRunning (IRunnableObject)
1324 * See Windows documentation for more details on IRunnableObject methods.
1326 static BOOL WINAPI DefaultHandler_IsRunning(
1327 IRunnableObject* iface)
1329 DefaultHandler *This = impl_from_IRunnableObject(iface);
1331 TRACE("()\n");
1333 if (This->pOleDelegate)
1334 return TRUE;
1335 else
1336 return FALSE;
1339 /************************************************************************
1340 * DefaultHandler_LockRunning (IRunnableObject)
1342 * See Windows documentation for more details on IRunnableObject methods.
1344 static HRESULT WINAPI DefaultHandler_LockRunning(
1345 IRunnableObject* iface,
1346 BOOL fLock,
1347 BOOL fLastUnlockCloses)
1349 FIXME("()\n");
1350 return S_OK;
1353 /************************************************************************
1354 * DefaultHandler_SetContainedObject (IRunnableObject)
1356 * See Windows documentation for more details on IRunnableObject methods.
1358 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1359 IRunnableObject* iface,
1360 BOOL fContained)
1362 FIXME("()\n");
1363 return S_OK;
1366 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1367 IAdviseSink *iface,
1368 REFIID riid,
1369 void **ppvObject)
1371 if (IsEqualIID(riid, &IID_IUnknown) ||
1372 IsEqualIID(riid, &IID_IAdviseSink))
1374 *ppvObject = iface;
1375 IAdviseSink_AddRef(iface);
1376 return S_OK;
1379 return E_NOINTERFACE;
1382 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1383 IAdviseSink *iface)
1385 DefaultHandler *This = impl_from_IAdviseSink(iface);
1387 return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1390 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1391 IAdviseSink *iface)
1393 DefaultHandler *This = impl_from_IAdviseSink(iface);
1395 return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1398 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1399 IAdviseSink *iface,
1400 FORMATETC *pFormatetc,
1401 STGMEDIUM *pStgmed)
1403 FIXME(": stub\n");
1406 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1407 IAdviseSink *iface,
1408 DWORD dwAspect,
1409 LONG lindex)
1411 FIXME(": stub\n");
1414 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1415 IAdviseSink *iface,
1416 IMoniker *pmk)
1418 DefaultHandler *This = impl_from_IAdviseSink(iface);
1420 TRACE("(%p)\n", pmk);
1422 if (This->oleAdviseHolder)
1423 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1426 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1427 IAdviseSink *iface)
1429 DefaultHandler *This = impl_from_IAdviseSink(iface);
1431 TRACE("()\n");
1433 if (This->oleAdviseHolder)
1434 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1437 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1438 IAdviseSink *iface)
1440 DefaultHandler *This = impl_from_IAdviseSink(iface);
1442 TRACE("()\n");
1444 if (This->oleAdviseHolder)
1445 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1447 DefaultHandler_Stop(This);
1451 * Virtual function tables for the DefaultHandler class.
1453 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1455 DefaultHandler_QueryInterface,
1456 DefaultHandler_AddRef,
1457 DefaultHandler_Release,
1458 DefaultHandler_SetClientSite,
1459 DefaultHandler_GetClientSite,
1460 DefaultHandler_SetHostNames,
1461 DefaultHandler_Close,
1462 DefaultHandler_SetMoniker,
1463 DefaultHandler_GetMoniker,
1464 DefaultHandler_InitFromData,
1465 DefaultHandler_GetClipboardData,
1466 DefaultHandler_DoVerb,
1467 DefaultHandler_EnumVerbs,
1468 DefaultHandler_Update,
1469 DefaultHandler_IsUpToDate,
1470 DefaultHandler_GetUserClassID,
1471 DefaultHandler_GetUserType,
1472 DefaultHandler_SetExtent,
1473 DefaultHandler_GetExtent,
1474 DefaultHandler_Advise,
1475 DefaultHandler_Unadvise,
1476 DefaultHandler_EnumAdvise,
1477 DefaultHandler_GetMiscStatus,
1478 DefaultHandler_SetColorScheme
1481 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1483 DefaultHandler_NDIUnknown_QueryInterface,
1484 DefaultHandler_NDIUnknown_AddRef,
1485 DefaultHandler_NDIUnknown_Release,
1488 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1490 DefaultHandler_IDataObject_QueryInterface,
1491 DefaultHandler_IDataObject_AddRef,
1492 DefaultHandler_IDataObject_Release,
1493 DefaultHandler_GetData,
1494 DefaultHandler_GetDataHere,
1495 DefaultHandler_QueryGetData,
1496 DefaultHandler_GetCanonicalFormatEtc,
1497 DefaultHandler_SetData,
1498 DefaultHandler_EnumFormatEtc,
1499 DefaultHandler_DAdvise,
1500 DefaultHandler_DUnadvise,
1501 DefaultHandler_EnumDAdvise
1504 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1506 DefaultHandler_IRunnableObject_QueryInterface,
1507 DefaultHandler_IRunnableObject_AddRef,
1508 DefaultHandler_IRunnableObject_Release,
1509 DefaultHandler_GetRunningClass,
1510 DefaultHandler_Run,
1511 DefaultHandler_IsRunning,
1512 DefaultHandler_LockRunning,
1513 DefaultHandler_SetContainedObject
1516 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1518 DefaultHandler_IAdviseSink_QueryInterface,
1519 DefaultHandler_IAdviseSink_AddRef,
1520 DefaultHandler_IAdviseSink_Release,
1521 DefaultHandler_IAdviseSink_OnDataChange,
1522 DefaultHandler_IAdviseSink_OnViewChange,
1523 DefaultHandler_IAdviseSink_OnRename,
1524 DefaultHandler_IAdviseSink_OnSave,
1525 DefaultHandler_IAdviseSink_OnClose
1528 /*********************************************************
1529 * Methods implementation for the DefaultHandler class.
1531 static DefaultHandler* DefaultHandler_Construct(
1532 REFCLSID clsid,
1533 LPUNKNOWN pUnkOuter)
1535 DefaultHandler* This = NULL;
1538 * Allocate space for the object.
1540 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1542 if (!This)
1543 return This;
1545 This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1546 This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1547 This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1548 This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1549 This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1552 * Start with one reference count. The caller of this function
1553 * must release the interface pointer when it is done.
1555 This->ref = 1;
1558 * Initialize the outer unknown
1559 * We don't keep a reference on the outer unknown since, the way
1560 * aggregation works, our lifetime is at least as large as it's
1561 * lifetime.
1563 if (!pUnkOuter)
1564 pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1566 This->outerUnknown = pUnkOuter;
1569 * Create a datacache object.
1570 * We aggregate with the datacache. Make sure we pass our outer
1571 * unknown as the datacache's outer unknown.
1573 CreateDataCache(This->outerUnknown,
1574 clsid,
1575 &IID_IUnknown,
1576 (void**)&This->dataCache);
1579 * Initialize the other data members of the class.
1581 memcpy(&This->clsid, clsid, sizeof(CLSID));
1582 This->clientSite = NULL;
1583 This->oleAdviseHolder = NULL;
1584 This->dataAdviseHolder = NULL;
1585 This->containerApp = NULL;
1586 This->containerObj = NULL;
1587 This->pOleDelegate = NULL;
1588 This->pPSDelegate = NULL;
1589 This->pDataDelegate = NULL;
1591 This->dwAdvConn = 0;
1593 return This;
1596 static void DefaultHandler_Destroy(
1597 DefaultHandler* This)
1599 /* release delegates */
1600 DefaultHandler_Stop(This);
1602 /* Free the strings idenfitying the object */
1603 HeapFree( GetProcessHeap(), 0, This->containerApp );
1604 This->containerApp = NULL;
1605 HeapFree( GetProcessHeap(), 0, This->containerObj );
1606 This->containerObj = NULL;
1608 /* Release our reference to the data cache. */
1609 if (This->dataCache)
1611 IUnknown_Release(This->dataCache);
1612 This->dataCache = NULL;
1615 /* Same thing for the client site. */
1616 if (This->clientSite)
1618 IOleClientSite_Release(This->clientSite);
1619 This->clientSite = NULL;
1622 /* And the advise holder. */
1623 if (This->oleAdviseHolder)
1625 IOleAdviseHolder_Release(This->oleAdviseHolder);
1626 This->oleAdviseHolder = NULL;
1629 /* And the data advise holder. */
1630 if (This->dataAdviseHolder)
1632 IDataAdviseHolder_Release(This->dataAdviseHolder);
1633 This->dataAdviseHolder = NULL;
1636 /* Free the actual default handler structure. */
1637 HeapFree(GetProcessHeap(), 0, This);
1640 /******************************************************************************
1641 * OleCreateDefaultHandler [OLE32.@]
1643 HRESULT WINAPI OleCreateDefaultHandler(
1644 REFCLSID clsid,
1645 LPUNKNOWN pUnkOuter,
1646 REFIID riid,
1647 LPVOID* ppvObj)
1649 DefaultHandler* newHandler = NULL;
1650 HRESULT hr = S_OK;
1652 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1655 * Sanity check
1657 if (!ppvObj)
1658 return E_POINTER;
1660 *ppvObj = NULL;
1663 * If This handler is constructed for aggregation, make sure
1664 * the caller is requesting the IUnknown interface.
1665 * This is necessary because it's the only time the non-delegating
1666 * IUnknown pointer can be returned to the outside.
1668 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
1669 return CLASS_E_NOAGGREGATION;
1672 * Try to construct a new instance of the class.
1674 newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1676 if (!newHandler)
1677 return E_OUTOFMEMORY;
1680 * Make sure it supports the interface required by the caller.
1682 hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1685 * Release the reference obtained in the constructor. If
1686 * the QueryInterface was unsuccessful, it will free the class.
1688 IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
1690 return hr;