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