shell32/tests: Fix a test on several platforms.
[wine/multimedia.git] / dlls / ole32 / defaulthandler.c
blob833e6fd1ec129b33ca2e86c25725c5cd38067d83
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 enum storage_state
69 storage_state_uninitialised,
70 storage_state_initialised,
71 storage_state_loaded
74 /****************************************************************************
75 * DefaultHandler
78 struct DefaultHandler
80 const IOleObjectVtbl* lpVtbl;
81 const IUnknownVtbl* lpvtblIUnknown;
82 const IDataObjectVtbl* lpvtblIDataObject;
83 const IRunnableObjectVtbl* lpvtblIRunnableObject;
84 const IAdviseSinkVtbl *lpvtblIAdviseSink;
85 const IPersistStorageVtbl *lpvtblIPersistStorage;
87 /* Reference count of this object */
88 LONG ref;
90 /* IUnknown implementation of the outer object. */
91 IUnknown* outerUnknown;
93 /* Class Id that this handler object represents. */
94 CLSID clsid;
96 /* IUnknown implementation of the datacache. */
97 IUnknown* dataCache;
98 /* IPersistStorage implementation of the datacache. */
99 IPersistStorage* dataCache_PersistStg;
101 /* Client site for the embedded object. */
102 IOleClientSite* clientSite;
105 * The IOleAdviseHolder maintains the connections
106 * on behalf of the default handler.
108 IOleAdviseHolder* oleAdviseHolder;
111 * The IDataAdviseHolder maintains the data
112 * connections on behalf of the default handler.
114 IDataAdviseHolder* dataAdviseHolder;
116 /* Name of the container and object contained */
117 LPWSTR containerApp;
118 LPWSTR containerObj;
120 /* IOleObject delegate */
121 IOleObject *pOleDelegate;
122 /* IPersistStorage delegate */
123 IPersistStorage *pPSDelegate;
124 /* IDataObject delegate */
125 IDataObject *pDataDelegate;
127 /* connection cookie for the advise on the delegate OLE object */
128 DWORD dwAdvConn;
130 /* storage passed to Load or InitNew */
131 IStorage *storage;
132 enum storage_state storage_state;
135 typedef struct DefaultHandler DefaultHandler;
137 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
139 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpVtbl));
142 static inline DefaultHandler *impl_from_NDIUnknown( IUnknown *iface )
144 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIUnknown));
147 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
149 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIDataObject));
152 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
154 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
157 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
159 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink));
162 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
164 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIPersistStorage));
167 static void DefaultHandler_Destroy(DefaultHandler* This);
169 static inline BOOL object_is_running(DefaultHandler *This)
171 return IRunnableObject_IsRunning((IRunnableObject*)&This->lpvtblIRunnableObject);
174 /*********************************************************
175 * Method implementation for the non delegating IUnknown
176 * part of the DefaultHandler class.
179 /************************************************************************
180 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
182 * See Windows documentation for more details on IUnknown methods.
184 * This version of QueryInterface will not delegate its implementation
185 * to the outer unknown.
187 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
188 IUnknown* iface,
189 REFIID riid,
190 void** ppvObject)
192 DefaultHandler *This = impl_from_NDIUnknown(iface);
194 if (!ppvObject)
195 return E_INVALIDARG;
197 *ppvObject = NULL;
199 if (IsEqualIID(&IID_IUnknown, riid))
200 *ppvObject = iface;
201 else if (IsEqualIID(&IID_IOleObject, riid))
202 *ppvObject = (IOleObject*)&This->lpVtbl;
203 else if (IsEqualIID(&IID_IDataObject, riid))
204 *ppvObject = (IDataObject*)&This->lpvtblIDataObject;
205 else if (IsEqualIID(&IID_IRunnableObject, riid))
206 *ppvObject = (IRunnableObject*)&This->lpvtblIRunnableObject;
207 else if (IsEqualIID(&IID_IPersist, riid) ||
208 IsEqualIID(&IID_IPersistStorage, riid))
209 *ppvObject = &This->lpvtblIPersistStorage;
210 else if (IsEqualIID(&IID_IViewObject, riid) ||
211 IsEqualIID(&IID_IViewObject2, riid) ||
212 IsEqualIID(&IID_IOleCache, riid) ||
213 IsEqualIID(&IID_IOleCache2, riid))
215 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
216 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
217 return hr;
220 /* Check that we obtained an interface. */
221 if (*ppvObject == NULL)
223 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
224 return E_NOINTERFACE;
228 * Query Interface always increases the reference count by one when it is
229 * successful.
231 IUnknown_AddRef((IUnknown*)*ppvObject);
233 return S_OK;
236 /************************************************************************
237 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
239 * See Windows documentation for more details on IUnknown methods.
241 * This version of QueryInterface will not delegate its implementation
242 * to the outer unknown.
244 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
245 IUnknown* iface)
247 DefaultHandler *This = impl_from_NDIUnknown(iface);
248 return InterlockedIncrement(&This->ref);
251 /************************************************************************
252 * DefaultHandler_NDIUnknown_Release (IUnknown)
254 * See Windows documentation for more details on IUnknown methods.
256 * This version of QueryInterface will not delegate its implementation
257 * to the outer unknown.
259 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
260 IUnknown* iface)
262 DefaultHandler *This = impl_from_NDIUnknown(iface);
263 ULONG ref;
265 ref = InterlockedDecrement(&This->ref);
267 if (!ref) DefaultHandler_Destroy(This);
269 return ref;
272 /*********************************************************
273 * Methods implementation for the IOleObject part of
274 * the DefaultHandler class.
277 /************************************************************************
278 * DefaultHandler_QueryInterface (IUnknown)
280 * See Windows documentation for more details on IUnknown methods.
282 static HRESULT WINAPI DefaultHandler_QueryInterface(
283 IOleObject* iface,
284 REFIID riid,
285 void** ppvObject)
287 DefaultHandler *This = impl_from_IOleObject(iface);
289 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
292 /************************************************************************
293 * DefaultHandler_AddRef (IUnknown)
295 * See Windows documentation for more details on IUnknown methods.
297 static ULONG WINAPI DefaultHandler_AddRef(
298 IOleObject* iface)
300 DefaultHandler *This = impl_from_IOleObject(iface);
302 return IUnknown_AddRef(This->outerUnknown);
305 /************************************************************************
306 * DefaultHandler_Release (IUnknown)
308 * See Windows documentation for more details on IUnknown methods.
310 static ULONG WINAPI DefaultHandler_Release(
311 IOleObject* iface)
313 DefaultHandler *This = impl_from_IOleObject(iface);
315 return IUnknown_Release(This->outerUnknown);
318 /************************************************************************
319 * DefaultHandler_SetClientSite (IOleObject)
321 * The default handler's implementation of this method only keeps the
322 * client site pointer for future reference.
324 * See Windows documentation for more details on IOleObject methods.
326 static HRESULT WINAPI DefaultHandler_SetClientSite(
327 IOleObject* iface,
328 IOleClientSite* pClientSite)
330 DefaultHandler *This = impl_from_IOleObject(iface);
331 HRESULT hr = S_OK;
333 TRACE("(%p, %p)\n", iface, pClientSite);
335 if (object_is_running(This))
336 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
339 * Make sure we release the previous client site if there
340 * was one.
342 if (This->clientSite)
343 IOleClientSite_Release(This->clientSite);
345 This->clientSite = pClientSite;
347 if (This->clientSite)
348 IOleClientSite_AddRef(This->clientSite);
350 return S_OK;
353 /************************************************************************
354 * DefaultHandler_GetClientSite (IOleObject)
356 * The default handler's implementation of this method returns the
357 * last pointer set in IOleObject_SetClientSite.
359 * See Windows documentation for more details on IOleObject methods.
361 static HRESULT WINAPI DefaultHandler_GetClientSite(
362 IOleObject* iface,
363 IOleClientSite** ppClientSite)
365 DefaultHandler *This = impl_from_IOleObject(iface);
367 if (!ppClientSite)
368 return E_POINTER;
370 *ppClientSite = This->clientSite;
372 if (This->clientSite)
373 IOleClientSite_AddRef(This->clientSite);
375 return S_OK;
378 /************************************************************************
379 * DefaultHandler_SetHostNames (IOleObject)
381 * The default handler's implementation of this method just stores
382 * the strings and returns S_OK.
384 * See Windows documentation for more details on IOleObject methods.
386 static HRESULT WINAPI DefaultHandler_SetHostNames(
387 IOleObject* iface,
388 LPCOLESTR szContainerApp,
389 LPCOLESTR szContainerObj)
391 DefaultHandler *This = impl_from_IOleObject(iface);
393 TRACE("(%p, %s, %s)\n",
394 iface,
395 debugstr_w(szContainerApp),
396 debugstr_w(szContainerObj));
398 if (object_is_running(This))
399 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
401 /* Be sure to cleanup before re-assigning the strings. */
402 HeapFree( GetProcessHeap(), 0, This->containerApp );
403 This->containerApp = NULL;
404 HeapFree( GetProcessHeap(), 0, This->containerObj );
405 This->containerObj = NULL;
407 if (szContainerApp)
409 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
410 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
411 strcpyW( This->containerApp, szContainerApp );
414 if (szContainerObj)
416 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
417 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
418 strcpyW( This->containerObj, szContainerObj );
420 return S_OK;
423 /* undoes the work done by DefaultHandler_Run */
424 static void DefaultHandler_Stop(DefaultHandler *This)
426 if (!object_is_running(This))
427 return;
429 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
431 /* FIXME: call IOleCache_OnStop */
433 if (This->dataAdviseHolder)
434 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
435 if (This->pDataDelegate)
437 IDataObject_Release(This->pDataDelegate);
438 This->pDataDelegate = NULL;
440 if (This->pPSDelegate)
442 IPersistStorage_Release(This->pPSDelegate);
443 This->pPSDelegate = NULL;
445 IOleObject_Release(This->pOleDelegate);
446 This->pOleDelegate = NULL;
449 /************************************************************************
450 * DefaultHandler_Close (IOleObject)
452 * The default handler's implementation of this method is meaningless
453 * without a running server so it does nothing.
455 * See Windows documentation for more details on IOleObject methods.
457 static HRESULT WINAPI DefaultHandler_Close(
458 IOleObject* iface,
459 DWORD dwSaveOption)
461 DefaultHandler *This = impl_from_IOleObject(iface);
462 HRESULT hr;
464 TRACE("(%d)\n", dwSaveOption);
466 if (!object_is_running(This))
467 return S_OK;
469 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
471 DefaultHandler_Stop(This);
473 return hr;
476 /************************************************************************
477 * DefaultHandler_SetMoniker (IOleObject)
479 * The default handler's implementation of this method does nothing.
481 * See Windows documentation for more details on IOleObject methods.
483 static HRESULT WINAPI DefaultHandler_SetMoniker(
484 IOleObject* iface,
485 DWORD dwWhichMoniker,
486 IMoniker* pmk)
488 DefaultHandler *This = impl_from_IOleObject(iface);
490 TRACE("(%p, %d, %p)\n",
491 iface,
492 dwWhichMoniker,
493 pmk);
495 if (object_is_running(This))
496 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
498 return S_OK;
501 /************************************************************************
502 * DefaultHandler_GetMoniker (IOleObject)
504 * Delegate this request to the client site if we have one.
506 * See Windows documentation for more details on IOleObject methods.
508 static HRESULT WINAPI DefaultHandler_GetMoniker(
509 IOleObject* iface,
510 DWORD dwAssign,
511 DWORD dwWhichMoniker,
512 IMoniker** ppmk)
514 DefaultHandler *This = impl_from_IOleObject(iface);
516 TRACE("(%p, %d, %d, %p)\n",
517 iface, dwAssign, dwWhichMoniker, ppmk);
519 if (object_is_running(This))
520 return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
521 ppmk);
523 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
524 if (This->clientSite)
526 return IOleClientSite_GetMoniker(This->clientSite,
527 dwAssign,
528 dwWhichMoniker,
529 ppmk);
533 return E_FAIL;
536 /************************************************************************
537 * DefaultHandler_InitFromData (IOleObject)
539 * This method is meaningless if the server is not running
541 * See Windows documentation for more details on IOleObject methods.
543 static HRESULT WINAPI DefaultHandler_InitFromData(
544 IOleObject* iface,
545 IDataObject* pDataObject,
546 BOOL fCreation,
547 DWORD dwReserved)
549 DefaultHandler *This = impl_from_IOleObject(iface);
551 TRACE("(%p, %p, %d, %d)\n",
552 iface, pDataObject, fCreation, dwReserved);
554 if (object_is_running(This))
555 return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
556 dwReserved);
557 return OLE_E_NOTRUNNING;
560 /************************************************************************
561 * DefaultHandler_GetClipboardData (IOleObject)
563 * This method is meaningless if the server is not running
565 * See Windows documentation for more details on IOleObject methods.
567 static HRESULT WINAPI DefaultHandler_GetClipboardData(
568 IOleObject* iface,
569 DWORD dwReserved,
570 IDataObject** ppDataObject)
572 DefaultHandler *This = impl_from_IOleObject(iface);
574 TRACE("(%p, %d, %p)\n",
575 iface, dwReserved, ppDataObject);
577 if (object_is_running(This))
578 return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
579 ppDataObject);
581 return OLE_E_NOTRUNNING;
584 static HRESULT WINAPI DefaultHandler_DoVerb(
585 IOleObject* iface,
586 LONG iVerb,
587 struct tagMSG* lpmsg,
588 IOleClientSite* pActiveSite,
589 LONG lindex,
590 HWND hwndParent,
591 LPCRECT lprcPosRect)
593 DefaultHandler *This = impl_from_IOleObject(iface);
594 IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
595 HRESULT hr;
597 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
599 hr = IRunnableObject_Run(pRunnableObj, NULL);
600 if (FAILED(hr)) return hr;
602 return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
603 lindex, hwndParent, lprcPosRect);
606 /************************************************************************
607 * DefaultHandler_EnumVerbs (IOleObject)
609 * The default handler implementation of this method simply delegates
610 * to OleRegEnumVerbs
612 * See Windows documentation for more details on IOleObject methods.
614 static HRESULT WINAPI DefaultHandler_EnumVerbs(
615 IOleObject* iface,
616 IEnumOLEVERB** ppEnumOleVerb)
618 DefaultHandler *This = impl_from_IOleObject(iface);
619 HRESULT hr = OLE_S_USEREG;
621 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
623 if (object_is_running(This))
624 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
626 if (hr == OLE_S_USEREG)
627 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
628 else
629 return hr;
632 static HRESULT WINAPI DefaultHandler_Update(
633 IOleObject* iface)
635 DefaultHandler *This = impl_from_IOleObject(iface);
636 TRACE("(%p)\n", iface);
638 if (!object_is_running(This))
640 FIXME("Should run object\n");
641 return E_NOTIMPL;
643 return IOleObject_Update(This->pOleDelegate);
646 /************************************************************************
647 * DefaultHandler_IsUpToDate (IOleObject)
649 * This method is meaningless if the server is not running
651 * See Windows documentation for more details on IOleObject methods.
653 static HRESULT WINAPI DefaultHandler_IsUpToDate(
654 IOleObject* iface)
656 DefaultHandler *This = impl_from_IOleObject(iface);
657 TRACE("(%p)\n", iface);
659 if (object_is_running(This))
660 return IOleObject_IsUpToDate(This->pOleDelegate);
662 return OLE_E_NOTRUNNING;
665 /************************************************************************
666 * DefaultHandler_GetUserClassID (IOleObject)
668 * TODO: Map to a new class ID if emulation is active.
670 * See Windows documentation for more details on IOleObject methods.
672 static HRESULT WINAPI DefaultHandler_GetUserClassID(
673 IOleObject* iface,
674 CLSID* pClsid)
676 DefaultHandler *This = impl_from_IOleObject(iface);
678 TRACE("(%p, %p)\n", iface, pClsid);
680 if (object_is_running(This))
681 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
683 if (!pClsid)
684 return E_POINTER;
686 *pClsid = This->clsid;
688 return S_OK;
691 /************************************************************************
692 * DefaultHandler_GetUserType (IOleObject)
694 * The default handler implementation of this method simply delegates
695 * to OleRegGetUserType
697 * See Windows documentation for more details on IOleObject methods.
699 static HRESULT WINAPI DefaultHandler_GetUserType(
700 IOleObject* iface,
701 DWORD dwFormOfType,
702 LPOLESTR* pszUserType)
704 DefaultHandler *This = impl_from_IOleObject(iface);
706 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
707 if (object_is_running(This))
708 return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
710 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
713 /************************************************************************
714 * DefaultHandler_SetExtent (IOleObject)
716 * This method is meaningless if the server is not running
718 * See Windows documentation for more details on IOleObject methods.
720 static HRESULT WINAPI DefaultHandler_SetExtent(
721 IOleObject* iface,
722 DWORD dwDrawAspect,
723 SIZEL* psizel)
725 DefaultHandler *This = impl_from_IOleObject(iface);
727 TRACE("(%p, %x, (%d x %d))\n", iface,
728 dwDrawAspect, psizel->cx, psizel->cy);
730 if (object_is_running(This))
731 return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
733 return OLE_E_NOTRUNNING;
736 /************************************************************************
737 * DefaultHandler_GetExtent (IOleObject)
739 * The default handler's implementation of this method returns uses
740 * the cache to locate the aspect and extract the extent from it.
742 * See Windows documentation for more details on IOleObject methods.
744 static HRESULT WINAPI DefaultHandler_GetExtent(
745 IOleObject* iface,
746 DWORD dwDrawAspect,
747 SIZEL* psizel)
749 DVTARGETDEVICE* targetDevice;
750 IViewObject2* cacheView = NULL;
751 HRESULT hres;
753 DefaultHandler *This = impl_from_IOleObject(iface);
755 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
757 if (object_is_running(This))
758 return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
760 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
761 if (FAILED(hres))
762 return E_UNEXPECTED;
765 * Prepare the call to the cache's GetExtent method.
767 * Here we would build a valid DVTARGETDEVICE structure
768 * but, since we are calling into the data cache, we
769 * know its implementation and we'll skip this
770 * extra work until later.
772 targetDevice = NULL;
774 hres = IViewObject2_GetExtent(cacheView,
775 dwDrawAspect,
777 targetDevice,
778 psizel);
780 IViewObject2_Release(cacheView);
782 return hres;
785 /************************************************************************
786 * DefaultHandler_Advise (IOleObject)
788 * The default handler's implementation of this method simply
789 * delegates to the OleAdviseHolder.
791 * See Windows documentation for more details on IOleObject methods.
793 static HRESULT WINAPI DefaultHandler_Advise(
794 IOleObject* iface,
795 IAdviseSink* pAdvSink,
796 DWORD* pdwConnection)
798 HRESULT hres = S_OK;
799 DefaultHandler *This = impl_from_IOleObject(iface);
801 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
803 /* Make sure we have an advise holder before we start. */
804 if (!This->oleAdviseHolder)
805 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
807 if (SUCCEEDED(hres))
808 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
809 pAdvSink,
810 pdwConnection);
812 return hres;
815 /************************************************************************
816 * DefaultHandler_Unadvise (IOleObject)
818 * The default handler's implementation of this method simply
819 * delegates to the OleAdviseHolder.
821 * See Windows documentation for more details on IOleObject methods.
823 static HRESULT WINAPI DefaultHandler_Unadvise(
824 IOleObject* iface,
825 DWORD dwConnection)
827 DefaultHandler *This = impl_from_IOleObject(iface);
829 TRACE("(%p, %d)\n", iface, dwConnection);
832 * If we don't have an advise holder yet, it means we don't have
833 * a connection.
835 if (!This->oleAdviseHolder)
836 return OLE_E_NOCONNECTION;
838 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
839 dwConnection);
842 /************************************************************************
843 * DefaultHandler_EnumAdvise (IOleObject)
845 * The default handler's implementation of this method simply
846 * delegates to the OleAdviseHolder.
848 * See Windows documentation for more details on IOleObject methods.
850 static HRESULT WINAPI DefaultHandler_EnumAdvise(
851 IOleObject* iface,
852 IEnumSTATDATA** ppenumAdvise)
854 DefaultHandler *This = impl_from_IOleObject(iface);
856 TRACE("(%p, %p)\n", iface, ppenumAdvise);
858 if (!ppenumAdvise)
859 return E_POINTER;
861 *ppenumAdvise = NULL;
863 if (!This->oleAdviseHolder)
864 return S_OK;
866 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
869 /************************************************************************
870 * DefaultHandler_GetMiscStatus (IOleObject)
872 * The default handler's implementation of this method simply delegates
873 * to OleRegGetMiscStatus.
875 * See Windows documentation for more details on IOleObject methods.
877 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
878 IOleObject* iface,
879 DWORD dwAspect,
880 DWORD* pdwStatus)
882 HRESULT hres;
883 DefaultHandler *This = impl_from_IOleObject(iface);
885 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
887 if (object_is_running(This))
888 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
890 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
892 if (FAILED(hres))
893 *pdwStatus = 0;
895 return S_OK;
898 /************************************************************************
899 * DefaultHandler_SetColorScheme (IOleObject)
901 * This method is meaningless if the server is not running
903 * See Windows documentation for more details on IOleObject methods.
905 static HRESULT WINAPI DefaultHandler_SetColorScheme(
906 IOleObject* iface,
907 struct tagLOGPALETTE* pLogpal)
909 DefaultHandler *This = impl_from_IOleObject(iface);
911 TRACE("(%p, %p))\n", iface, pLogpal);
913 if (object_is_running(This))
914 return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
916 return OLE_E_NOTRUNNING;
919 /*********************************************************
920 * Methods implementation for the IDataObject part of
921 * the DefaultHandler class.
924 /************************************************************************
925 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
927 * See Windows documentation for more details on IUnknown methods.
929 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
930 IDataObject* iface,
931 REFIID riid,
932 void** ppvObject)
934 DefaultHandler *This = impl_from_IDataObject(iface);
936 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
939 /************************************************************************
940 * DefaultHandler_IDataObject_AddRef (IUnknown)
942 * See Windows documentation for more details on IUnknown methods.
944 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
945 IDataObject* iface)
947 DefaultHandler *This = impl_from_IDataObject(iface);
949 return IUnknown_AddRef(This->outerUnknown);
952 /************************************************************************
953 * DefaultHandler_IDataObject_Release (IUnknown)
955 * See Windows documentation for more details on IUnknown methods.
957 static ULONG WINAPI DefaultHandler_IDataObject_Release(
958 IDataObject* iface)
960 DefaultHandler *This = impl_from_IDataObject(iface);
962 return IUnknown_Release(This->outerUnknown);
965 /************************************************************************
966 * DefaultHandler_GetData
968 * Get Data from a source dataobject using format pformatetcIn->cfFormat
969 * See Windows documentation for more details on GetData.
970 * Default handler's implementation of this method delegates to the cache.
972 static HRESULT WINAPI DefaultHandler_GetData(
973 IDataObject* iface,
974 LPFORMATETC pformatetcIn,
975 STGMEDIUM* pmedium)
977 IDataObject* cacheDataObject = NULL;
978 HRESULT hres;
980 DefaultHandler *This = impl_from_IDataObject(iface);
982 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
984 hres = IUnknown_QueryInterface(This->dataCache,
985 &IID_IDataObject,
986 (void**)&cacheDataObject);
988 if (FAILED(hres))
989 return E_UNEXPECTED;
991 hres = IDataObject_GetData(cacheDataObject,
992 pformatetcIn,
993 pmedium);
995 IDataObject_Release(cacheDataObject);
997 if (FAILED(hres) && This->pDataDelegate)
998 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1000 return hres;
1003 static HRESULT WINAPI DefaultHandler_GetDataHere(
1004 IDataObject* iface,
1005 LPFORMATETC pformatetc,
1006 STGMEDIUM* pmedium)
1008 FIXME(": Stub\n");
1009 return E_NOTIMPL;
1012 /************************************************************************
1013 * DefaultHandler_QueryGetData (IDataObject)
1015 * The default handler's implementation of this method delegates to
1016 * the cache.
1018 * See Windows documentation for more details on IDataObject methods.
1020 static HRESULT WINAPI DefaultHandler_QueryGetData(
1021 IDataObject* iface,
1022 LPFORMATETC pformatetc)
1024 IDataObject* cacheDataObject = NULL;
1025 HRESULT hres;
1027 DefaultHandler *This = impl_from_IDataObject(iface);
1029 TRACE("(%p, %p)\n", iface, pformatetc);
1031 hres = IUnknown_QueryInterface(This->dataCache,
1032 &IID_IDataObject,
1033 (void**)&cacheDataObject);
1035 if (FAILED(hres))
1036 return E_UNEXPECTED;
1038 hres = IDataObject_QueryGetData(cacheDataObject,
1039 pformatetc);
1041 IDataObject_Release(cacheDataObject);
1043 if (FAILED(hres) && This->pDataDelegate)
1044 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1046 return hres;
1049 /************************************************************************
1050 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1052 * This method is meaningless if the server is not running
1054 * See Windows documentation for more details on IDataObject methods.
1056 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1057 IDataObject* iface,
1058 LPFORMATETC pformatetcIn,
1059 LPFORMATETC pformatetcOut)
1061 DefaultHandler *This = impl_from_IDataObject(iface);
1063 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1065 if (!This->pDataDelegate)
1066 return OLE_E_NOTRUNNING;
1068 return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1071 /************************************************************************
1072 * DefaultHandler_SetData (IDataObject)
1074 * The default handler's implementation of this method delegates to
1075 * the cache.
1077 * See Windows documentation for more details on IDataObject methods.
1079 static HRESULT WINAPI DefaultHandler_SetData(
1080 IDataObject* iface,
1081 LPFORMATETC pformatetc,
1082 STGMEDIUM* pmedium,
1083 BOOL fRelease)
1085 DefaultHandler *This = impl_from_IDataObject(iface);
1086 IDataObject* cacheDataObject = NULL;
1087 HRESULT hres;
1089 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1091 hres = IUnknown_QueryInterface(This->dataCache,
1092 &IID_IDataObject,
1093 (void**)&cacheDataObject);
1095 if (FAILED(hres))
1096 return E_UNEXPECTED;
1098 hres = IDataObject_SetData(cacheDataObject,
1099 pformatetc,
1100 pmedium,
1101 fRelease);
1103 IDataObject_Release(cacheDataObject);
1105 return hres;
1108 /************************************************************************
1109 * DefaultHandler_EnumFormatEtc (IDataObject)
1111 * The default handler's implementation of This method simply delegates
1112 * to OleRegEnumFormatEtc.
1114 * See Windows documentation for more details on IDataObject methods.
1116 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1117 IDataObject* iface,
1118 DWORD dwDirection,
1119 IEnumFORMATETC** ppenumFormatEtc)
1121 HRESULT hres;
1122 DefaultHandler *This = impl_from_IDataObject(iface);
1124 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1126 hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1128 return hres;
1131 /************************************************************************
1132 * DefaultHandler_DAdvise (IDataObject)
1134 * The default handler's implementation of this method simply
1135 * delegates to the DataAdviseHolder.
1137 * See Windows documentation for more details on IDataObject methods.
1139 static HRESULT WINAPI DefaultHandler_DAdvise(
1140 IDataObject* iface,
1141 FORMATETC* pformatetc,
1142 DWORD advf,
1143 IAdviseSink* pAdvSink,
1144 DWORD* pdwConnection)
1146 HRESULT hres = S_OK;
1147 DefaultHandler *This = impl_from_IDataObject(iface);
1149 TRACE("(%p, %p, %d, %p, %p)\n",
1150 iface, pformatetc, advf, pAdvSink, pdwConnection);
1152 /* Make sure we have a data advise holder before we start. */
1153 if (!This->dataAdviseHolder)
1155 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1156 if (SUCCEEDED(hres) && This->pDataDelegate)
1157 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1160 if (SUCCEEDED(hres))
1161 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1162 iface,
1163 pformatetc,
1164 advf,
1165 pAdvSink,
1166 pdwConnection);
1168 return hres;
1171 /************************************************************************
1172 * DefaultHandler_DUnadvise (IDataObject)
1174 * The default handler's implementation of this method simply
1175 * delegates to the DataAdviseHolder.
1177 * See Windows documentation for more details on IDataObject methods.
1179 static HRESULT WINAPI DefaultHandler_DUnadvise(
1180 IDataObject* iface,
1181 DWORD dwConnection)
1183 DefaultHandler *This = impl_from_IDataObject(iface);
1185 TRACE("(%p, %d)\n", iface, dwConnection);
1188 * If we don't have a data advise holder yet, it means that
1189 * we don't have any connections..
1191 if (!This->dataAdviseHolder)
1192 return OLE_E_NOCONNECTION;
1194 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1195 dwConnection);
1198 /************************************************************************
1199 * DefaultHandler_EnumDAdvise (IDataObject)
1201 * The default handler's implementation of this method simply
1202 * delegates to the DataAdviseHolder.
1204 * See Windows documentation for more details on IDataObject methods.
1206 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1207 IDataObject* iface,
1208 IEnumSTATDATA** ppenumAdvise)
1210 DefaultHandler *This = impl_from_IDataObject(iface);
1212 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1214 if (!ppenumAdvise)
1215 return E_POINTER;
1217 *ppenumAdvise = NULL;
1219 /* If we have a data advise holder object, delegate. */
1220 if (This->dataAdviseHolder)
1221 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1222 ppenumAdvise);
1224 return S_OK;
1227 /*********************************************************
1228 * Methods implementation for the IRunnableObject part
1229 * of the DefaultHandler class.
1232 /************************************************************************
1233 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1235 * See Windows documentation for more details on IUnknown methods.
1237 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1238 IRunnableObject* iface,
1239 REFIID riid,
1240 void** ppvObject)
1242 DefaultHandler *This = impl_from_IRunnableObject(iface);
1244 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1247 /************************************************************************
1248 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1250 * See Windows documentation for more details on IUnknown methods.
1252 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1253 IRunnableObject* iface)
1255 DefaultHandler *This = impl_from_IRunnableObject(iface);
1257 return IUnknown_AddRef(This->outerUnknown);
1260 /************************************************************************
1261 * DefaultHandler_IRunnableObject_Release (IUnknown)
1263 * See Windows documentation for more details on IUnknown methods.
1265 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1266 IRunnableObject* iface)
1268 DefaultHandler *This = impl_from_IRunnableObject(iface);
1270 return IUnknown_Release(This->outerUnknown);
1273 /************************************************************************
1274 * DefaultHandler_GetRunningClass (IRunnableObject)
1276 * See Windows documentation for more details on IRunnableObject methods.
1278 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1279 IRunnableObject* iface,
1280 LPCLSID lpClsid)
1282 FIXME("()\n");
1283 return S_OK;
1286 static HRESULT WINAPI DefaultHandler_Run(
1287 IRunnableObject* iface,
1288 IBindCtx* pbc)
1290 DefaultHandler *This = impl_from_IRunnableObject(iface);
1291 HRESULT hr;
1293 FIXME("(%p): semi-stub\n", pbc);
1295 /* already running? if so nothing to do */
1296 if (object_is_running(This))
1297 return S_OK;
1299 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1300 &IID_IOleObject, (void **)&This->pOleDelegate);
1301 if (FAILED(hr))
1302 return hr;
1304 hr = IOleObject_Advise(This->pOleDelegate,
1305 (IAdviseSink *)&This->lpvtblIAdviseSink,
1306 &This->dwAdvConn);
1308 if (SUCCEEDED(hr) && This->clientSite)
1309 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1311 if (SUCCEEDED(hr))
1313 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1314 (void **)&This->pPSDelegate);
1315 if (This->pPSDelegate)
1317 if(This->storage_state == storage_state_initialised)
1318 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1319 else if(This->storage_state == storage_state_loaded)
1320 hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1324 if (SUCCEEDED(hr) && This->containerApp)
1325 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1326 This->containerObj);
1328 /* FIXME: do more stuff here:
1329 * - IOleObject_GetMiscStatus
1330 * - IOleObject_GetMoniker
1331 * - IOleCache_OnRun
1334 if (SUCCEEDED(hr))
1335 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1336 (void **)&This->pDataDelegate);
1338 if (SUCCEEDED(hr) && This->dataAdviseHolder)
1339 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1341 if (FAILED(hr))
1342 DefaultHandler_Stop(This);
1344 return hr;
1347 /************************************************************************
1348 * DefaultHandler_IsRunning (IRunnableObject)
1350 * See Windows documentation for more details on IRunnableObject methods.
1352 static BOOL WINAPI DefaultHandler_IsRunning(
1353 IRunnableObject* iface)
1355 DefaultHandler *This = impl_from_IRunnableObject(iface);
1357 TRACE("()\n");
1359 if (This->pOleDelegate)
1360 return TRUE;
1361 else
1362 return FALSE;
1365 /************************************************************************
1366 * DefaultHandler_LockRunning (IRunnableObject)
1368 * See Windows documentation for more details on IRunnableObject methods.
1370 static HRESULT WINAPI DefaultHandler_LockRunning(
1371 IRunnableObject* iface,
1372 BOOL fLock,
1373 BOOL fLastUnlockCloses)
1375 FIXME("()\n");
1376 return S_OK;
1379 /************************************************************************
1380 * DefaultHandler_SetContainedObject (IRunnableObject)
1382 * See Windows documentation for more details on IRunnableObject methods.
1384 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1385 IRunnableObject* iface,
1386 BOOL fContained)
1388 FIXME("()\n");
1389 return S_OK;
1392 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1393 IAdviseSink *iface,
1394 REFIID riid,
1395 void **ppvObject)
1397 if (IsEqualIID(riid, &IID_IUnknown) ||
1398 IsEqualIID(riid, &IID_IAdviseSink))
1400 *ppvObject = iface;
1401 IAdviseSink_AddRef(iface);
1402 return S_OK;
1405 return E_NOINTERFACE;
1408 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1409 IAdviseSink *iface)
1411 DefaultHandler *This = impl_from_IAdviseSink(iface);
1413 return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1416 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1417 IAdviseSink *iface)
1419 DefaultHandler *This = impl_from_IAdviseSink(iface);
1421 return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1424 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1425 IAdviseSink *iface,
1426 FORMATETC *pFormatetc,
1427 STGMEDIUM *pStgmed)
1429 FIXME(": stub\n");
1432 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1433 IAdviseSink *iface,
1434 DWORD dwAspect,
1435 LONG lindex)
1437 FIXME(": stub\n");
1440 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1441 IAdviseSink *iface,
1442 IMoniker *pmk)
1444 DefaultHandler *This = impl_from_IAdviseSink(iface);
1446 TRACE("(%p)\n", pmk);
1448 if (This->oleAdviseHolder)
1449 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1452 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1453 IAdviseSink *iface)
1455 DefaultHandler *This = impl_from_IAdviseSink(iface);
1457 TRACE("()\n");
1459 if (This->oleAdviseHolder)
1460 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1463 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1464 IAdviseSink *iface)
1466 DefaultHandler *This = impl_from_IAdviseSink(iface);
1468 TRACE("()\n");
1470 if (This->oleAdviseHolder)
1471 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1473 DefaultHandler_Stop(This);
1477 /************************************************************************
1478 * DefaultHandler_IPersistStorage_QueryInterface
1481 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1482 IPersistStorage* iface,
1483 REFIID riid,
1484 void** ppvObject)
1486 DefaultHandler *This = impl_from_IPersistStorage(iface);
1488 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1491 /************************************************************************
1492 * DefaultHandler_IPersistStorage_AddRef
1495 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1496 IPersistStorage* iface)
1498 DefaultHandler *This = impl_from_IPersistStorage(iface);
1500 return IUnknown_AddRef(This->outerUnknown);
1503 /************************************************************************
1504 * DefaultHandler_IPersistStorage_Release
1507 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1508 IPersistStorage* iface)
1510 DefaultHandler *This = impl_from_IPersistStorage(iface);
1512 return IUnknown_Release(This->outerUnknown);
1515 /************************************************************************
1516 * DefaultHandler_IPersistStorage_GetClassID
1519 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1520 IPersistStorage* iface,
1521 CLSID* clsid)
1523 DefaultHandler *This = impl_from_IPersistStorage(iface);
1525 return IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1528 /************************************************************************
1529 * DefaultHandler_IPersistStorage_IsDirty
1532 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1533 IPersistStorage* iface)
1535 DefaultHandler *This = impl_from_IPersistStorage(iface);
1536 HRESULT hr;
1538 TRACE("(%p)\n", iface);
1540 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1541 if(hr != S_FALSE) return hr;
1543 if(object_is_running(This))
1544 hr = IPersistStorage_IsDirty(This->pPSDelegate);
1546 return hr;
1549 /***********************************************************************
1550 * init_ole_stream
1552 * Creates the '\1Ole' stream.
1553 * The format of this stream is as follows:
1555 * DWORD Version == 0x02000001
1556 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1557 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1558 * supplied by the app that creates the data structure. May be
1559 * ignored on processing].
1561 * DWORD Reserved == 0
1562 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1563 * CLSID clsid - class id of object capable of processing the moniker
1564 * BYTE data[] - moniker data for a link
1567 static const WCHAR OleStream[] = {1,'O','l','e',0};
1568 typedef struct
1570 DWORD version;
1571 DWORD flags;
1572 DWORD link_update_opt;
1573 DWORD res;
1574 DWORD moniker_size;
1575 } ole_stream_header_t;
1576 static const DWORD ole_stream_version = 0x02000001;
1578 static void init_ole_stream(IStorage *storage)
1580 HRESULT hr;
1581 IStream *stream;
1583 hr = IStorage_CreateStream(storage, OleStream, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream);
1584 if(SUCCEEDED(hr))
1586 DWORD written;
1587 ole_stream_header_t header;
1589 header.version = ole_stream_version;
1590 header.flags = 0;
1591 header.link_update_opt = 0;
1592 header.res = 0;
1593 header.moniker_size = 0;
1595 IStream_Write(stream, &header, sizeof(header), &written);
1596 IStream_Release(stream);
1598 return;
1601 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1603 IStream *stream;
1604 HRESULT hr;
1606 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1608 if(SUCCEEDED(hr))
1610 DWORD read;
1611 ole_stream_header_t header;
1613 hr = IStream_Read(stream, &header, sizeof(header), &read);
1614 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1616 if(header.flags & 1)
1618 /* FIXME: Read the moniker and deal with the link */
1619 FIXME("Linked objects are not supported yet\n");
1622 else
1624 WARN("Incorrect OleStream header\n");
1625 hr = DV_E_CLIPFORMAT;
1627 IStream_Release(stream);
1629 else
1631 init_ole_stream(storage);
1632 hr = S_OK;
1634 return hr;
1637 /************************************************************************
1638 * DefaultHandler_IPersistStorage_InitNew
1641 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1642 IPersistStorage* iface,
1643 IStorage* pStg)
1645 DefaultHandler *This = impl_from_IPersistStorage(iface);
1646 HRESULT hr;
1648 TRACE("(%p)->(%p)\n", iface, pStg);
1649 init_ole_stream(pStg);
1651 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1653 if(SUCCEEDED(hr) && object_is_running(This))
1654 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1656 if(SUCCEEDED(hr))
1658 IStorage_AddRef(pStg);
1659 This->storage = pStg;
1660 This->storage_state = storage_state_initialised;
1663 return hr;
1667 /************************************************************************
1668 * DefaultHandler_IPersistStorage_Load
1671 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1672 IPersistStorage* iface,
1673 IStorage* pStg)
1675 DefaultHandler *This = impl_from_IPersistStorage(iface);
1676 HRESULT hr;
1678 TRACE("(%p)->(%p)\n", iface, pStg);
1680 hr = load_ole_stream(This, pStg);
1682 if(SUCCEEDED(hr))
1683 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1685 if(SUCCEEDED(hr) && object_is_running(This))
1686 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1688 if(SUCCEEDED(hr))
1690 IStorage_AddRef(pStg);
1691 This->storage = pStg;
1692 This->storage_state = storage_state_loaded;
1694 return hr;
1698 /************************************************************************
1699 * DefaultHandler_IPersistStorage_Save
1702 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1703 IPersistStorage* iface,
1704 IStorage* pStgSave,
1705 BOOL fSameAsLoad)
1707 DefaultHandler *This = impl_from_IPersistStorage(iface);
1708 HRESULT hr;
1710 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1712 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1713 if(SUCCEEDED(hr) && object_is_running(This))
1714 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1716 return hr;
1720 /************************************************************************
1721 * DefaultHandler_IPersistStorage_SaveCompleted
1724 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1725 IPersistStorage* iface,
1726 IStorage* pStgNew)
1728 DefaultHandler *This = impl_from_IPersistStorage(iface);
1729 HRESULT hr;
1731 TRACE("(%p)->(%p)\n", iface, pStgNew);
1733 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1735 if(SUCCEEDED(hr) && object_is_running(This))
1736 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1738 if(pStgNew)
1740 IStorage_AddRef(pStgNew);
1741 if(This->storage) IStorage_Release(This->storage);
1742 This->storage = pStgNew;
1743 This->storage_state = storage_state_loaded;
1746 return hr;
1750 /************************************************************************
1751 * DefaultHandler_IPersistStorage_HandsOffStorage
1754 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1755 IPersistStorage* iface)
1757 DefaultHandler *This = impl_from_IPersistStorage(iface);
1758 HRESULT hr;
1760 TRACE("(%p)\n", iface);
1762 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1764 if(SUCCEEDED(hr) && object_is_running(This))
1765 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1767 if(This->storage) IStorage_Release(This->storage);
1768 This->storage = NULL;
1769 This->storage_state = storage_state_uninitialised;
1771 return hr;
1776 * Virtual function tables for the DefaultHandler class.
1778 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1780 DefaultHandler_QueryInterface,
1781 DefaultHandler_AddRef,
1782 DefaultHandler_Release,
1783 DefaultHandler_SetClientSite,
1784 DefaultHandler_GetClientSite,
1785 DefaultHandler_SetHostNames,
1786 DefaultHandler_Close,
1787 DefaultHandler_SetMoniker,
1788 DefaultHandler_GetMoniker,
1789 DefaultHandler_InitFromData,
1790 DefaultHandler_GetClipboardData,
1791 DefaultHandler_DoVerb,
1792 DefaultHandler_EnumVerbs,
1793 DefaultHandler_Update,
1794 DefaultHandler_IsUpToDate,
1795 DefaultHandler_GetUserClassID,
1796 DefaultHandler_GetUserType,
1797 DefaultHandler_SetExtent,
1798 DefaultHandler_GetExtent,
1799 DefaultHandler_Advise,
1800 DefaultHandler_Unadvise,
1801 DefaultHandler_EnumAdvise,
1802 DefaultHandler_GetMiscStatus,
1803 DefaultHandler_SetColorScheme
1806 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1808 DefaultHandler_NDIUnknown_QueryInterface,
1809 DefaultHandler_NDIUnknown_AddRef,
1810 DefaultHandler_NDIUnknown_Release,
1813 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1815 DefaultHandler_IDataObject_QueryInterface,
1816 DefaultHandler_IDataObject_AddRef,
1817 DefaultHandler_IDataObject_Release,
1818 DefaultHandler_GetData,
1819 DefaultHandler_GetDataHere,
1820 DefaultHandler_QueryGetData,
1821 DefaultHandler_GetCanonicalFormatEtc,
1822 DefaultHandler_SetData,
1823 DefaultHandler_EnumFormatEtc,
1824 DefaultHandler_DAdvise,
1825 DefaultHandler_DUnadvise,
1826 DefaultHandler_EnumDAdvise
1829 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1831 DefaultHandler_IRunnableObject_QueryInterface,
1832 DefaultHandler_IRunnableObject_AddRef,
1833 DefaultHandler_IRunnableObject_Release,
1834 DefaultHandler_GetRunningClass,
1835 DefaultHandler_Run,
1836 DefaultHandler_IsRunning,
1837 DefaultHandler_LockRunning,
1838 DefaultHandler_SetContainedObject
1841 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1843 DefaultHandler_IAdviseSink_QueryInterface,
1844 DefaultHandler_IAdviseSink_AddRef,
1845 DefaultHandler_IAdviseSink_Release,
1846 DefaultHandler_IAdviseSink_OnDataChange,
1847 DefaultHandler_IAdviseSink_OnViewChange,
1848 DefaultHandler_IAdviseSink_OnRename,
1849 DefaultHandler_IAdviseSink_OnSave,
1850 DefaultHandler_IAdviseSink_OnClose
1853 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
1855 DefaultHandler_IPersistStorage_QueryInterface,
1856 DefaultHandler_IPersistStorage_AddRef,
1857 DefaultHandler_IPersistStorage_Release,
1858 DefaultHandler_IPersistStorage_GetClassID,
1859 DefaultHandler_IPersistStorage_IsDirty,
1860 DefaultHandler_IPersistStorage_InitNew,
1861 DefaultHandler_IPersistStorage_Load,
1862 DefaultHandler_IPersistStorage_Save,
1863 DefaultHandler_IPersistStorage_SaveCompleted,
1864 DefaultHandler_IPersistStorage_HandsOffStorage
1867 /*********************************************************
1868 * Methods implementation for the DefaultHandler class.
1870 static DefaultHandler* DefaultHandler_Construct(
1871 REFCLSID clsid,
1872 LPUNKNOWN pUnkOuter)
1874 DefaultHandler* This = NULL;
1875 HRESULT hr;
1877 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1879 if (!This)
1880 return This;
1882 This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1883 This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1884 This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1885 This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1886 This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1887 This->lpvtblIPersistStorage = &DefaultHandler_IPersistStorage_VTable;
1890 * Start with one reference count. The caller of this function
1891 * must release the interface pointer when it is done.
1893 This->ref = 1;
1896 * Initialize the outer unknown
1897 * We don't keep a reference on the outer unknown since, the way
1898 * aggregation works, our lifetime is at least as large as its
1899 * lifetime.
1901 if (!pUnkOuter)
1902 pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1904 This->outerUnknown = pUnkOuter;
1907 * Create a datacache object.
1908 * We aggregate with the datacache. Make sure we pass our outer
1909 * unknown as the datacache's outer unknown.
1911 hr = CreateDataCache(This->outerUnknown,
1912 clsid,
1913 &IID_IUnknown,
1914 (void**)&This->dataCache);
1915 if(SUCCEEDED(hr))
1916 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
1917 if(FAILED(hr))
1918 ERR("Unexpected error creating data cache\n");
1920 This->clsid = *clsid;
1921 This->clientSite = NULL;
1922 This->oleAdviseHolder = NULL;
1923 This->dataAdviseHolder = NULL;
1924 This->containerApp = NULL;
1925 This->containerObj = NULL;
1926 This->pOleDelegate = NULL;
1927 This->pPSDelegate = NULL;
1928 This->pDataDelegate = NULL;
1930 This->dwAdvConn = 0;
1931 This->storage = NULL;
1932 This->storage_state = storage_state_uninitialised;
1934 return This;
1937 static void DefaultHandler_Destroy(
1938 DefaultHandler* This)
1940 /* release delegates */
1941 DefaultHandler_Stop(This);
1943 HeapFree( GetProcessHeap(), 0, This->containerApp );
1944 This->containerApp = NULL;
1945 HeapFree( GetProcessHeap(), 0, This->containerObj );
1946 This->containerObj = NULL;
1948 if (This->dataCache)
1950 IPersistStorage_Release(This->dataCache_PersistStg);
1951 IUnknown_Release(This->dataCache);
1952 This->dataCache_PersistStg = NULL;
1953 This->dataCache = NULL;
1956 if (This->clientSite)
1958 IOleClientSite_Release(This->clientSite);
1959 This->clientSite = NULL;
1962 if (This->oleAdviseHolder)
1964 IOleAdviseHolder_Release(This->oleAdviseHolder);
1965 This->oleAdviseHolder = NULL;
1968 if (This->dataAdviseHolder)
1970 IDataAdviseHolder_Release(This->dataAdviseHolder);
1971 This->dataAdviseHolder = NULL;
1974 if (This->storage)
1976 IStorage_Release(This->storage);
1977 This->storage = NULL;
1980 HeapFree(GetProcessHeap(), 0, This);
1983 /******************************************************************************
1984 * OleCreateDefaultHandler [OLE32.@]
1986 HRESULT WINAPI OleCreateDefaultHandler(
1987 REFCLSID clsid,
1988 LPUNKNOWN pUnkOuter,
1989 REFIID riid,
1990 LPVOID* ppvObj)
1992 DefaultHandler* newHandler = NULL;
1993 HRESULT hr = S_OK;
1995 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1997 if (!ppvObj)
1998 return E_POINTER;
2000 *ppvObj = NULL;
2003 * If This handler is constructed for aggregation, make sure
2004 * the caller is requesting the IUnknown interface.
2005 * This is necessary because it's the only time the non-delegating
2006 * IUnknown pointer can be returned to the outside.
2008 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2009 return CLASS_E_NOAGGREGATION;
2012 * Try to construct a new instance of the class.
2014 newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
2016 if (!newHandler)
2017 return E_OUTOFMEMORY;
2020 * Make sure it supports the interface required by the caller.
2022 hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
2025 * Release the reference obtained in the constructor. If
2026 * the QueryInterface was unsuccessful, it will free the class.
2028 IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
2030 return hr;