push cc8bc80451cc24f4d7cf75168b569f0ebfe19547
[wine/hacks.git] / dlls / ole32 / defaulthandler.c
blobb85002ad52b90b51080be3e73a124abb1342fdfd
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 enum object_state
76 object_state_not_running,
77 object_state_running
80 /****************************************************************************
81 * DefaultHandler
84 struct DefaultHandler
86 const IOleObjectVtbl* lpVtbl;
87 const IUnknownVtbl* lpvtblIUnknown;
88 const IDataObjectVtbl* lpvtblIDataObject;
89 const IRunnableObjectVtbl* lpvtblIRunnableObject;
90 const IAdviseSinkVtbl *lpvtblIAdviseSink;
91 const IPersistStorageVtbl *lpvtblIPersistStorage;
93 /* Reference count of this object */
94 LONG ref;
96 /* IUnknown implementation of the outer object. */
97 IUnknown* outerUnknown;
99 /* Class Id that this handler object represents. */
100 CLSID clsid;
102 /* IUnknown implementation of the datacache. */
103 IUnknown* dataCache;
104 /* IPersistStorage implementation of the datacache. */
105 IPersistStorage* dataCache_PersistStg;
107 /* Client site for the embedded object. */
108 IOleClientSite* clientSite;
111 * The IOleAdviseHolder maintains the connections
112 * on behalf of the default handler.
114 IOleAdviseHolder* oleAdviseHolder;
117 * The IDataAdviseHolder maintains the data
118 * connections on behalf of the default handler.
120 IDataAdviseHolder* dataAdviseHolder;
122 /* Name of the container and object contained */
123 LPWSTR containerApp;
124 LPWSTR containerObj;
126 /* IOleObject delegate */
127 IOleObject *pOleDelegate;
128 /* IPersistStorage delegate */
129 IPersistStorage *pPSDelegate;
130 /* IDataObject delegate */
131 IDataObject *pDataDelegate;
132 enum object_state object_state;
134 /* connection cookie for the advise on the delegate OLE object */
135 DWORD dwAdvConn;
137 /* storage passed to Load or InitNew */
138 IStorage *storage;
139 enum storage_state storage_state;
142 typedef struct DefaultHandler DefaultHandler;
144 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
146 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpVtbl));
149 static inline DefaultHandler *impl_from_NDIUnknown( IUnknown *iface )
151 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIUnknown));
154 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
156 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIDataObject));
159 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
161 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
164 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
166 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink));
169 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
171 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIPersistStorage));
174 static void DefaultHandler_Destroy(DefaultHandler* This);
176 static inline BOOL object_is_running(DefaultHandler *This)
178 return IRunnableObject_IsRunning((IRunnableObject*)&This->lpvtblIRunnableObject);
181 /*********************************************************
182 * Method implementation for the non delegating IUnknown
183 * part of the DefaultHandler class.
186 /************************************************************************
187 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
189 * See Windows documentation for more details on IUnknown methods.
191 * This version of QueryInterface will not delegate its implementation
192 * to the outer unknown.
194 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
195 IUnknown* iface,
196 REFIID riid,
197 void** ppvObject)
199 DefaultHandler *This = impl_from_NDIUnknown(iface);
201 if (!ppvObject)
202 return E_INVALIDARG;
204 *ppvObject = NULL;
206 if (IsEqualIID(&IID_IUnknown, riid))
207 *ppvObject = iface;
208 else if (IsEqualIID(&IID_IOleObject, riid))
209 *ppvObject = &This->lpVtbl;
210 else if (IsEqualIID(&IID_IDataObject, riid))
211 *ppvObject = &This->lpvtblIDataObject;
212 else if (IsEqualIID(&IID_IRunnableObject, riid))
213 *ppvObject = &This->lpvtblIRunnableObject;
214 else if (IsEqualIID(&IID_IPersist, riid) ||
215 IsEqualIID(&IID_IPersistStorage, riid))
216 *ppvObject = &This->lpvtblIPersistStorage;
217 else if (IsEqualIID(&IID_IViewObject, riid) ||
218 IsEqualIID(&IID_IViewObject2, riid) ||
219 IsEqualIID(&IID_IOleCache, riid) ||
220 IsEqualIID(&IID_IOleCache2, riid))
222 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
223 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
224 return hr;
227 /* Check that we obtained an interface. */
228 if (*ppvObject == NULL)
230 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
231 return E_NOINTERFACE;
235 * Query Interface always increases the reference count by one when it is
236 * successful.
238 IUnknown_AddRef((IUnknown*)*ppvObject);
240 return S_OK;
243 /************************************************************************
244 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
246 * See Windows documentation for more details on IUnknown methods.
248 * This version of QueryInterface will not delegate its implementation
249 * to the outer unknown.
251 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
252 IUnknown* iface)
254 DefaultHandler *This = impl_from_NDIUnknown(iface);
255 return InterlockedIncrement(&This->ref);
258 /************************************************************************
259 * DefaultHandler_NDIUnknown_Release (IUnknown)
261 * See Windows documentation for more details on IUnknown methods.
263 * This version of QueryInterface will not delegate its implementation
264 * to the outer unknown.
266 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
267 IUnknown* iface)
269 DefaultHandler *This = impl_from_NDIUnknown(iface);
270 ULONG ref;
272 ref = InterlockedDecrement(&This->ref);
274 if (!ref) DefaultHandler_Destroy(This);
276 return ref;
279 /*********************************************************
280 * Methods implementation for the IOleObject part of
281 * the DefaultHandler class.
284 /************************************************************************
285 * DefaultHandler_QueryInterface (IUnknown)
287 * See Windows documentation for more details on IUnknown methods.
289 static HRESULT WINAPI DefaultHandler_QueryInterface(
290 IOleObject* iface,
291 REFIID riid,
292 void** ppvObject)
294 DefaultHandler *This = impl_from_IOleObject(iface);
296 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
299 /************************************************************************
300 * DefaultHandler_AddRef (IUnknown)
302 * See Windows documentation for more details on IUnknown methods.
304 static ULONG WINAPI DefaultHandler_AddRef(
305 IOleObject* iface)
307 DefaultHandler *This = impl_from_IOleObject(iface);
309 return IUnknown_AddRef(This->outerUnknown);
312 /************************************************************************
313 * DefaultHandler_Release (IUnknown)
315 * See Windows documentation for more details on IUnknown methods.
317 static ULONG WINAPI DefaultHandler_Release(
318 IOleObject* iface)
320 DefaultHandler *This = impl_from_IOleObject(iface);
322 return IUnknown_Release(This->outerUnknown);
325 /************************************************************************
326 * DefaultHandler_SetClientSite (IOleObject)
328 * The default handler's implementation of this method only keeps the
329 * client site pointer for future reference.
331 * See Windows documentation for more details on IOleObject methods.
333 static HRESULT WINAPI DefaultHandler_SetClientSite(
334 IOleObject* iface,
335 IOleClientSite* pClientSite)
337 DefaultHandler *This = impl_from_IOleObject(iface);
338 HRESULT hr = S_OK;
340 TRACE("(%p, %p)\n", iface, pClientSite);
342 if (object_is_running(This))
343 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
346 * Make sure we release the previous client site if there
347 * was one.
349 if (This->clientSite)
350 IOleClientSite_Release(This->clientSite);
352 This->clientSite = pClientSite;
354 if (This->clientSite)
355 IOleClientSite_AddRef(This->clientSite);
357 return S_OK;
360 /************************************************************************
361 * DefaultHandler_GetClientSite (IOleObject)
363 * The default handler's implementation of this method returns the
364 * last pointer set in IOleObject_SetClientSite.
366 * See Windows documentation for more details on IOleObject methods.
368 static HRESULT WINAPI DefaultHandler_GetClientSite(
369 IOleObject* iface,
370 IOleClientSite** ppClientSite)
372 DefaultHandler *This = impl_from_IOleObject(iface);
374 if (!ppClientSite)
375 return E_POINTER;
377 *ppClientSite = This->clientSite;
379 if (This->clientSite)
380 IOleClientSite_AddRef(This->clientSite);
382 return S_OK;
385 /************************************************************************
386 * DefaultHandler_SetHostNames (IOleObject)
388 * The default handler's implementation of this method just stores
389 * the strings and returns S_OK.
391 * See Windows documentation for more details on IOleObject methods.
393 static HRESULT WINAPI DefaultHandler_SetHostNames(
394 IOleObject* iface,
395 LPCOLESTR szContainerApp,
396 LPCOLESTR szContainerObj)
398 DefaultHandler *This = impl_from_IOleObject(iface);
400 TRACE("(%p, %s, %s)\n",
401 iface,
402 debugstr_w(szContainerApp),
403 debugstr_w(szContainerObj));
405 if (object_is_running(This))
406 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
408 /* Be sure to cleanup before re-assigning the strings. */
409 HeapFree( GetProcessHeap(), 0, This->containerApp );
410 This->containerApp = NULL;
411 HeapFree( GetProcessHeap(), 0, This->containerObj );
412 This->containerObj = NULL;
414 if (szContainerApp)
416 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
417 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
418 strcpyW( This->containerApp, szContainerApp );
421 if (szContainerObj)
423 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
424 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
425 strcpyW( This->containerObj, szContainerObj );
427 return S_OK;
430 static void release_delegates(DefaultHandler *This)
432 if (This->pDataDelegate)
434 IDataObject_Release(This->pDataDelegate);
435 This->pDataDelegate = NULL;
437 if (This->pPSDelegate)
439 IPersistStorage_Release(This->pPSDelegate);
440 This->pPSDelegate = NULL;
442 if (This->pOleDelegate)
444 IOleObject_Release(This->pOleDelegate);
445 This->pOleDelegate = NULL;
449 /* undoes the work done by DefaultHandler_Run */
450 static void DefaultHandler_Stop(DefaultHandler *This)
452 if (!object_is_running(This))
453 return;
455 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
457 /* FIXME: call IOleCache_OnStop */
459 if (This->dataAdviseHolder)
460 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
462 This->object_state = object_state_not_running;
465 /************************************************************************
466 * DefaultHandler_Close (IOleObject)
468 * The default handler's implementation of this method is meaningless
469 * without a running server so it does nothing.
471 * See Windows documentation for more details on IOleObject methods.
473 static HRESULT WINAPI DefaultHandler_Close(
474 IOleObject* iface,
475 DWORD dwSaveOption)
477 DefaultHandler *This = impl_from_IOleObject(iface);
478 HRESULT hr;
480 TRACE("(%d)\n", dwSaveOption);
482 if (!object_is_running(This))
483 return S_OK;
485 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
487 DefaultHandler_Stop(This);
488 release_delegates(This);
490 return hr;
493 /************************************************************************
494 * DefaultHandler_SetMoniker (IOleObject)
496 * The default handler's implementation of this method does nothing.
498 * See Windows documentation for more details on IOleObject methods.
500 static HRESULT WINAPI DefaultHandler_SetMoniker(
501 IOleObject* iface,
502 DWORD dwWhichMoniker,
503 IMoniker* pmk)
505 DefaultHandler *This = impl_from_IOleObject(iface);
507 TRACE("(%p, %d, %p)\n",
508 iface,
509 dwWhichMoniker,
510 pmk);
512 if (object_is_running(This))
513 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
515 return S_OK;
518 /************************************************************************
519 * DefaultHandler_GetMoniker (IOleObject)
521 * Delegate this request to the client site if we have one.
523 * See Windows documentation for more details on IOleObject methods.
525 static HRESULT WINAPI DefaultHandler_GetMoniker(
526 IOleObject* iface,
527 DWORD dwAssign,
528 DWORD dwWhichMoniker,
529 IMoniker** ppmk)
531 DefaultHandler *This = impl_from_IOleObject(iface);
533 TRACE("(%p, %d, %d, %p)\n",
534 iface, dwAssign, dwWhichMoniker, ppmk);
536 if (object_is_running(This))
537 return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
538 ppmk);
540 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
541 if (This->clientSite)
543 return IOleClientSite_GetMoniker(This->clientSite,
544 dwAssign,
545 dwWhichMoniker,
546 ppmk);
550 return E_FAIL;
553 /************************************************************************
554 * DefaultHandler_InitFromData (IOleObject)
556 * This method is meaningless if the server is not running
558 * See Windows documentation for more details on IOleObject methods.
560 static HRESULT WINAPI DefaultHandler_InitFromData(
561 IOleObject* iface,
562 IDataObject* pDataObject,
563 BOOL fCreation,
564 DWORD dwReserved)
566 DefaultHandler *This = impl_from_IOleObject(iface);
568 TRACE("(%p, %p, %d, %d)\n",
569 iface, pDataObject, fCreation, dwReserved);
571 if (object_is_running(This))
572 return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
573 dwReserved);
574 return OLE_E_NOTRUNNING;
577 /************************************************************************
578 * DefaultHandler_GetClipboardData (IOleObject)
580 * This method is meaningless if the server is not running
582 * See Windows documentation for more details on IOleObject methods.
584 static HRESULT WINAPI DefaultHandler_GetClipboardData(
585 IOleObject* iface,
586 DWORD dwReserved,
587 IDataObject** ppDataObject)
589 DefaultHandler *This = impl_from_IOleObject(iface);
591 TRACE("(%p, %d, %p)\n",
592 iface, dwReserved, ppDataObject);
594 if (object_is_running(This))
595 return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
596 ppDataObject);
598 return OLE_E_NOTRUNNING;
601 static HRESULT WINAPI DefaultHandler_DoVerb(
602 IOleObject* iface,
603 LONG iVerb,
604 struct tagMSG* lpmsg,
605 IOleClientSite* pActiveSite,
606 LONG lindex,
607 HWND hwndParent,
608 LPCRECT lprcPosRect)
610 DefaultHandler *This = impl_from_IOleObject(iface);
611 IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
612 HRESULT hr;
614 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
616 hr = IRunnableObject_Run(pRunnableObj, NULL);
617 if (FAILED(hr)) return hr;
619 return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
620 lindex, hwndParent, lprcPosRect);
623 /************************************************************************
624 * DefaultHandler_EnumVerbs (IOleObject)
626 * The default handler implementation of this method simply delegates
627 * to OleRegEnumVerbs
629 * See Windows documentation for more details on IOleObject methods.
631 static HRESULT WINAPI DefaultHandler_EnumVerbs(
632 IOleObject* iface,
633 IEnumOLEVERB** ppEnumOleVerb)
635 DefaultHandler *This = impl_from_IOleObject(iface);
636 HRESULT hr = OLE_S_USEREG;
638 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
640 if (object_is_running(This))
641 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
643 if (hr == OLE_S_USEREG)
644 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
645 else
646 return hr;
649 static HRESULT WINAPI DefaultHandler_Update(
650 IOleObject* iface)
652 DefaultHandler *This = impl_from_IOleObject(iface);
653 TRACE("(%p)\n", iface);
655 if (!object_is_running(This))
657 FIXME("Should run object\n");
658 return E_NOTIMPL;
660 return IOleObject_Update(This->pOleDelegate);
663 /************************************************************************
664 * DefaultHandler_IsUpToDate (IOleObject)
666 * This method is meaningless if the server is not running
668 * See Windows documentation for more details on IOleObject methods.
670 static HRESULT WINAPI DefaultHandler_IsUpToDate(
671 IOleObject* iface)
673 DefaultHandler *This = impl_from_IOleObject(iface);
674 TRACE("(%p)\n", iface);
676 if (object_is_running(This))
677 return IOleObject_IsUpToDate(This->pOleDelegate);
679 return OLE_E_NOTRUNNING;
682 /************************************************************************
683 * DefaultHandler_GetUserClassID (IOleObject)
685 * TODO: Map to a new class ID if emulation is active.
687 * See Windows documentation for more details on IOleObject methods.
689 static HRESULT WINAPI DefaultHandler_GetUserClassID(
690 IOleObject* iface,
691 CLSID* pClsid)
693 DefaultHandler *This = impl_from_IOleObject(iface);
695 TRACE("(%p, %p)\n", iface, pClsid);
697 if (object_is_running(This))
698 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
700 if (!pClsid)
701 return E_POINTER;
703 *pClsid = This->clsid;
705 return S_OK;
708 /************************************************************************
709 * DefaultHandler_GetUserType (IOleObject)
711 * The default handler implementation of this method simply delegates
712 * to OleRegGetUserType
714 * See Windows documentation for more details on IOleObject methods.
716 static HRESULT WINAPI DefaultHandler_GetUserType(
717 IOleObject* iface,
718 DWORD dwFormOfType,
719 LPOLESTR* pszUserType)
721 DefaultHandler *This = impl_from_IOleObject(iface);
723 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
724 if (object_is_running(This))
725 return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
727 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
730 /************************************************************************
731 * DefaultHandler_SetExtent (IOleObject)
733 * This method is meaningless if the server is not running
735 * See Windows documentation for more details on IOleObject methods.
737 static HRESULT WINAPI DefaultHandler_SetExtent(
738 IOleObject* iface,
739 DWORD dwDrawAspect,
740 SIZEL* psizel)
742 DefaultHandler *This = impl_from_IOleObject(iface);
744 TRACE("(%p, %x, (%d x %d))\n", iface,
745 dwDrawAspect, psizel->cx, psizel->cy);
747 if (object_is_running(This))
748 return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
750 return OLE_E_NOTRUNNING;
753 /************************************************************************
754 * DefaultHandler_GetExtent (IOleObject)
756 * The default handler's implementation of this method returns uses
757 * the cache to locate the aspect and extract the extent from it.
759 * See Windows documentation for more details on IOleObject methods.
761 static HRESULT WINAPI DefaultHandler_GetExtent(
762 IOleObject* iface,
763 DWORD dwDrawAspect,
764 SIZEL* psizel)
766 DVTARGETDEVICE* targetDevice;
767 IViewObject2* cacheView = NULL;
768 HRESULT hres;
770 DefaultHandler *This = impl_from_IOleObject(iface);
772 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
774 if (object_is_running(This))
775 return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
777 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
778 if (FAILED(hres))
779 return E_UNEXPECTED;
782 * Prepare the call to the cache's GetExtent method.
784 * Here we would build a valid DVTARGETDEVICE structure
785 * but, since we are calling into the data cache, we
786 * know its implementation and we'll skip this
787 * extra work until later.
789 targetDevice = NULL;
791 hres = IViewObject2_GetExtent(cacheView,
792 dwDrawAspect,
794 targetDevice,
795 psizel);
797 IViewObject2_Release(cacheView);
799 return hres;
802 /************************************************************************
803 * DefaultHandler_Advise (IOleObject)
805 * The default handler's implementation of this method simply
806 * delegates to the OleAdviseHolder.
808 * See Windows documentation for more details on IOleObject methods.
810 static HRESULT WINAPI DefaultHandler_Advise(
811 IOleObject* iface,
812 IAdviseSink* pAdvSink,
813 DWORD* pdwConnection)
815 HRESULT hres = S_OK;
816 DefaultHandler *This = impl_from_IOleObject(iface);
818 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
820 /* Make sure we have an advise holder before we start. */
821 if (!This->oleAdviseHolder)
822 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
824 if (SUCCEEDED(hres))
825 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
826 pAdvSink,
827 pdwConnection);
829 return hres;
832 /************************************************************************
833 * DefaultHandler_Unadvise (IOleObject)
835 * The default handler's implementation of this method simply
836 * delegates to the OleAdviseHolder.
838 * See Windows documentation for more details on IOleObject methods.
840 static HRESULT WINAPI DefaultHandler_Unadvise(
841 IOleObject* iface,
842 DWORD dwConnection)
844 DefaultHandler *This = impl_from_IOleObject(iface);
846 TRACE("(%p, %d)\n", iface, dwConnection);
849 * If we don't have an advise holder yet, it means we don't have
850 * a connection.
852 if (!This->oleAdviseHolder)
853 return OLE_E_NOCONNECTION;
855 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
856 dwConnection);
859 /************************************************************************
860 * DefaultHandler_EnumAdvise (IOleObject)
862 * The default handler's implementation of this method simply
863 * delegates to the OleAdviseHolder.
865 * See Windows documentation for more details on IOleObject methods.
867 static HRESULT WINAPI DefaultHandler_EnumAdvise(
868 IOleObject* iface,
869 IEnumSTATDATA** ppenumAdvise)
871 DefaultHandler *This = impl_from_IOleObject(iface);
873 TRACE("(%p, %p)\n", iface, ppenumAdvise);
875 if (!ppenumAdvise)
876 return E_POINTER;
878 *ppenumAdvise = NULL;
880 if (!This->oleAdviseHolder)
881 return S_OK;
883 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
886 /************************************************************************
887 * DefaultHandler_GetMiscStatus (IOleObject)
889 * The default handler's implementation of this method simply delegates
890 * to OleRegGetMiscStatus.
892 * See Windows documentation for more details on IOleObject methods.
894 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
895 IOleObject* iface,
896 DWORD dwAspect,
897 DWORD* pdwStatus)
899 HRESULT hres;
900 DefaultHandler *This = impl_from_IOleObject(iface);
902 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
904 if (object_is_running(This))
905 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
907 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
909 if (FAILED(hres))
910 *pdwStatus = 0;
912 return hres;
915 /************************************************************************
916 * DefaultHandler_SetColorScheme (IOleObject)
918 * This method is meaningless if the server is not running
920 * See Windows documentation for more details on IOleObject methods.
922 static HRESULT WINAPI DefaultHandler_SetColorScheme(
923 IOleObject* iface,
924 struct tagLOGPALETTE* pLogpal)
926 DefaultHandler *This = impl_from_IOleObject(iface);
928 TRACE("(%p, %p))\n", iface, pLogpal);
930 if (object_is_running(This))
931 return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
933 return OLE_E_NOTRUNNING;
936 /*********************************************************
937 * Methods implementation for the IDataObject part of
938 * the DefaultHandler class.
941 /************************************************************************
942 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
944 * See Windows documentation for more details on IUnknown methods.
946 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
947 IDataObject* iface,
948 REFIID riid,
949 void** ppvObject)
951 DefaultHandler *This = impl_from_IDataObject(iface);
953 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
956 /************************************************************************
957 * DefaultHandler_IDataObject_AddRef (IUnknown)
959 * See Windows documentation for more details on IUnknown methods.
961 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
962 IDataObject* iface)
964 DefaultHandler *This = impl_from_IDataObject(iface);
966 return IUnknown_AddRef(This->outerUnknown);
969 /************************************************************************
970 * DefaultHandler_IDataObject_Release (IUnknown)
972 * See Windows documentation for more details on IUnknown methods.
974 static ULONG WINAPI DefaultHandler_IDataObject_Release(
975 IDataObject* iface)
977 DefaultHandler *This = impl_from_IDataObject(iface);
979 return IUnknown_Release(This->outerUnknown);
982 /************************************************************************
983 * DefaultHandler_GetData
985 * Get Data from a source dataobject using format pformatetcIn->cfFormat
986 * See Windows documentation for more details on GetData.
987 * Default handler's implementation of this method delegates to the cache.
989 static HRESULT WINAPI DefaultHandler_GetData(
990 IDataObject* iface,
991 LPFORMATETC pformatetcIn,
992 STGMEDIUM* pmedium)
994 IDataObject* cacheDataObject = NULL;
995 HRESULT hres;
997 DefaultHandler *This = impl_from_IDataObject(iface);
999 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
1001 hres = IUnknown_QueryInterface(This->dataCache,
1002 &IID_IDataObject,
1003 (void**)&cacheDataObject);
1005 if (FAILED(hres))
1006 return E_UNEXPECTED;
1008 hres = IDataObject_GetData(cacheDataObject,
1009 pformatetcIn,
1010 pmedium);
1012 IDataObject_Release(cacheDataObject);
1014 if (FAILED(hres) && This->pDataDelegate)
1015 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1017 return hres;
1020 static HRESULT WINAPI DefaultHandler_GetDataHere(
1021 IDataObject* iface,
1022 LPFORMATETC pformatetc,
1023 STGMEDIUM* pmedium)
1025 FIXME(": Stub\n");
1026 return E_NOTIMPL;
1029 /************************************************************************
1030 * DefaultHandler_QueryGetData (IDataObject)
1032 * The default handler's implementation of this method delegates to
1033 * the cache.
1035 * See Windows documentation for more details on IDataObject methods.
1037 static HRESULT WINAPI DefaultHandler_QueryGetData(
1038 IDataObject* iface,
1039 LPFORMATETC pformatetc)
1041 IDataObject* cacheDataObject = NULL;
1042 HRESULT hres;
1044 DefaultHandler *This = impl_from_IDataObject(iface);
1046 TRACE("(%p, %p)\n", iface, pformatetc);
1048 hres = IUnknown_QueryInterface(This->dataCache,
1049 &IID_IDataObject,
1050 (void**)&cacheDataObject);
1052 if (FAILED(hres))
1053 return E_UNEXPECTED;
1055 hres = IDataObject_QueryGetData(cacheDataObject,
1056 pformatetc);
1058 IDataObject_Release(cacheDataObject);
1060 if (FAILED(hres) && This->pDataDelegate)
1061 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1063 return hres;
1066 /************************************************************************
1067 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1069 * This method is meaningless if the server is not running
1071 * See Windows documentation for more details on IDataObject methods.
1073 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1074 IDataObject* iface,
1075 LPFORMATETC pformatetcIn,
1076 LPFORMATETC pformatetcOut)
1078 DefaultHandler *This = impl_from_IDataObject(iface);
1080 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1082 if (!This->pDataDelegate)
1083 return OLE_E_NOTRUNNING;
1085 return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1088 /************************************************************************
1089 * DefaultHandler_SetData (IDataObject)
1091 * The default handler's implementation of this method delegates to
1092 * the cache.
1094 * See Windows documentation for more details on IDataObject methods.
1096 static HRESULT WINAPI DefaultHandler_SetData(
1097 IDataObject* iface,
1098 LPFORMATETC pformatetc,
1099 STGMEDIUM* pmedium,
1100 BOOL fRelease)
1102 DefaultHandler *This = impl_from_IDataObject(iface);
1103 IDataObject* cacheDataObject = NULL;
1104 HRESULT hres;
1106 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1108 hres = IUnknown_QueryInterface(This->dataCache,
1109 &IID_IDataObject,
1110 (void**)&cacheDataObject);
1112 if (FAILED(hres))
1113 return E_UNEXPECTED;
1115 hres = IDataObject_SetData(cacheDataObject,
1116 pformatetc,
1117 pmedium,
1118 fRelease);
1120 IDataObject_Release(cacheDataObject);
1122 return hres;
1125 /************************************************************************
1126 * DefaultHandler_EnumFormatEtc (IDataObject)
1128 * The default handler's implementation of This method simply delegates
1129 * to OleRegEnumFormatEtc.
1131 * See Windows documentation for more details on IDataObject methods.
1133 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1134 IDataObject* iface,
1135 DWORD dwDirection,
1136 IEnumFORMATETC** ppenumFormatEtc)
1138 HRESULT hres;
1139 DefaultHandler *This = impl_from_IDataObject(iface);
1141 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1143 hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1145 return hres;
1148 /************************************************************************
1149 * DefaultHandler_DAdvise (IDataObject)
1151 * The default handler's implementation of this method simply
1152 * delegates to the DataAdviseHolder.
1154 * See Windows documentation for more details on IDataObject methods.
1156 static HRESULT WINAPI DefaultHandler_DAdvise(
1157 IDataObject* iface,
1158 FORMATETC* pformatetc,
1159 DWORD advf,
1160 IAdviseSink* pAdvSink,
1161 DWORD* pdwConnection)
1163 HRESULT hres = S_OK;
1164 DefaultHandler *This = impl_from_IDataObject(iface);
1166 TRACE("(%p, %p, %d, %p, %p)\n",
1167 iface, pformatetc, advf, pAdvSink, pdwConnection);
1169 /* Make sure we have a data advise holder before we start. */
1170 if (!This->dataAdviseHolder)
1172 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1173 if (SUCCEEDED(hres) && This->pDataDelegate)
1174 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1177 if (SUCCEEDED(hres))
1178 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1179 iface,
1180 pformatetc,
1181 advf,
1182 pAdvSink,
1183 pdwConnection);
1185 return hres;
1188 /************************************************************************
1189 * DefaultHandler_DUnadvise (IDataObject)
1191 * The default handler's implementation of this method simply
1192 * delegates to the DataAdviseHolder.
1194 * See Windows documentation for more details on IDataObject methods.
1196 static HRESULT WINAPI DefaultHandler_DUnadvise(
1197 IDataObject* iface,
1198 DWORD dwConnection)
1200 DefaultHandler *This = impl_from_IDataObject(iface);
1202 TRACE("(%p, %d)\n", iface, dwConnection);
1205 * If we don't have a data advise holder yet, it means that
1206 * we don't have any connections..
1208 if (!This->dataAdviseHolder)
1209 return OLE_E_NOCONNECTION;
1211 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1212 dwConnection);
1215 /************************************************************************
1216 * DefaultHandler_EnumDAdvise (IDataObject)
1218 * The default handler's implementation of this method simply
1219 * delegates to the DataAdviseHolder.
1221 * See Windows documentation for more details on IDataObject methods.
1223 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1224 IDataObject* iface,
1225 IEnumSTATDATA** ppenumAdvise)
1227 DefaultHandler *This = impl_from_IDataObject(iface);
1229 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1231 if (!ppenumAdvise)
1232 return E_POINTER;
1234 *ppenumAdvise = NULL;
1236 /* If we have a data advise holder object, delegate. */
1237 if (This->dataAdviseHolder)
1238 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1239 ppenumAdvise);
1241 return S_OK;
1244 /*********************************************************
1245 * Methods implementation for the IRunnableObject part
1246 * of the DefaultHandler class.
1249 /************************************************************************
1250 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1252 * See Windows documentation for more details on IUnknown methods.
1254 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1255 IRunnableObject* iface,
1256 REFIID riid,
1257 void** ppvObject)
1259 DefaultHandler *This = impl_from_IRunnableObject(iface);
1261 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1264 /************************************************************************
1265 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1267 * See Windows documentation for more details on IUnknown methods.
1269 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1270 IRunnableObject* iface)
1272 DefaultHandler *This = impl_from_IRunnableObject(iface);
1274 return IUnknown_AddRef(This->outerUnknown);
1277 /************************************************************************
1278 * DefaultHandler_IRunnableObject_Release (IUnknown)
1280 * See Windows documentation for more details on IUnknown methods.
1282 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1283 IRunnableObject* iface)
1285 DefaultHandler *This = impl_from_IRunnableObject(iface);
1287 return IUnknown_Release(This->outerUnknown);
1290 /************************************************************************
1291 * DefaultHandler_GetRunningClass (IRunnableObject)
1293 * See Windows documentation for more details on IRunnableObject methods.
1295 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1296 IRunnableObject* iface,
1297 LPCLSID lpClsid)
1299 FIXME("()\n");
1300 return S_OK;
1303 static HRESULT WINAPI DefaultHandler_Run(
1304 IRunnableObject* iface,
1305 IBindCtx* pbc)
1307 DefaultHandler *This = impl_from_IRunnableObject(iface);
1308 HRESULT hr;
1310 FIXME("(%p): semi-stub\n", pbc);
1312 /* already running? if so nothing to do */
1313 if (object_is_running(This))
1314 return S_OK;
1316 release_delegates(This);
1318 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1319 &IID_IOleObject, (void **)&This->pOleDelegate);
1320 if (FAILED(hr))
1321 return hr;
1323 This->object_state = object_state_running;
1325 hr = IOleObject_Advise(This->pOleDelegate,
1326 (IAdviseSink *)&This->lpvtblIAdviseSink,
1327 &This->dwAdvConn);
1329 if (SUCCEEDED(hr) && This->clientSite)
1330 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1332 if (SUCCEEDED(hr))
1334 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1335 (void **)&This->pPSDelegate);
1336 if (This->pPSDelegate)
1338 if(This->storage_state == storage_state_initialised)
1339 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1340 else if(This->storage_state == storage_state_loaded)
1341 hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1345 if (SUCCEEDED(hr) && This->containerApp)
1346 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1347 This->containerObj);
1349 /* FIXME: do more stuff here:
1350 * - IOleObject_GetMiscStatus
1351 * - IOleObject_GetMoniker
1352 * - IOleCache_OnRun
1355 if (SUCCEEDED(hr))
1356 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1357 (void **)&This->pDataDelegate);
1359 if (SUCCEEDED(hr) && This->dataAdviseHolder)
1360 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1362 if (FAILED(hr))
1364 DefaultHandler_Stop(This);
1365 release_delegates(This);
1368 return hr;
1371 /************************************************************************
1372 * DefaultHandler_IsRunning (IRunnableObject)
1374 * See Windows documentation for more details on IRunnableObject methods.
1376 static BOOL WINAPI DefaultHandler_IsRunning(
1377 IRunnableObject* iface)
1379 DefaultHandler *This = impl_from_IRunnableObject(iface);
1381 TRACE("()\n");
1383 if (This->object_state == object_state_running)
1384 return TRUE;
1385 else
1386 return FALSE;
1389 /************************************************************************
1390 * DefaultHandler_LockRunning (IRunnableObject)
1392 * See Windows documentation for more details on IRunnableObject methods.
1394 static HRESULT WINAPI DefaultHandler_LockRunning(
1395 IRunnableObject* iface,
1396 BOOL fLock,
1397 BOOL fLastUnlockCloses)
1399 FIXME("()\n");
1400 return S_OK;
1403 /************************************************************************
1404 * DefaultHandler_SetContainedObject (IRunnableObject)
1406 * See Windows documentation for more details on IRunnableObject methods.
1408 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1409 IRunnableObject* iface,
1410 BOOL fContained)
1412 FIXME("()\n");
1413 return S_OK;
1416 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1417 IAdviseSink *iface,
1418 REFIID riid,
1419 void **ppvObject)
1421 if (IsEqualIID(riid, &IID_IUnknown) ||
1422 IsEqualIID(riid, &IID_IAdviseSink))
1424 *ppvObject = iface;
1425 IAdviseSink_AddRef(iface);
1426 return S_OK;
1429 return E_NOINTERFACE;
1432 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1433 IAdviseSink *iface)
1435 DefaultHandler *This = impl_from_IAdviseSink(iface);
1437 return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1440 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1441 IAdviseSink *iface)
1443 DefaultHandler *This = impl_from_IAdviseSink(iface);
1445 return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1448 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1449 IAdviseSink *iface,
1450 FORMATETC *pFormatetc,
1451 STGMEDIUM *pStgmed)
1453 FIXME(": stub\n");
1456 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1457 IAdviseSink *iface,
1458 DWORD dwAspect,
1459 LONG lindex)
1461 FIXME(": stub\n");
1464 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1465 IAdviseSink *iface,
1466 IMoniker *pmk)
1468 DefaultHandler *This = impl_from_IAdviseSink(iface);
1470 TRACE("(%p)\n", pmk);
1472 if (This->oleAdviseHolder)
1473 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1476 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1477 IAdviseSink *iface)
1479 DefaultHandler *This = impl_from_IAdviseSink(iface);
1481 TRACE("()\n");
1483 if (This->oleAdviseHolder)
1484 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1487 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1488 IAdviseSink *iface)
1490 DefaultHandler *This = impl_from_IAdviseSink(iface);
1492 TRACE("()\n");
1494 if (This->oleAdviseHolder)
1495 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1497 DefaultHandler_Stop(This);
1501 /************************************************************************
1502 * DefaultHandler_IPersistStorage_QueryInterface
1505 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1506 IPersistStorage* iface,
1507 REFIID riid,
1508 void** ppvObject)
1510 DefaultHandler *This = impl_from_IPersistStorage(iface);
1512 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1515 /************************************************************************
1516 * DefaultHandler_IPersistStorage_AddRef
1519 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1520 IPersistStorage* iface)
1522 DefaultHandler *This = impl_from_IPersistStorage(iface);
1524 return IUnknown_AddRef(This->outerUnknown);
1527 /************************************************************************
1528 * DefaultHandler_IPersistStorage_Release
1531 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1532 IPersistStorage* iface)
1534 DefaultHandler *This = impl_from_IPersistStorage(iface);
1536 return IUnknown_Release(This->outerUnknown);
1539 /************************************************************************
1540 * DefaultHandler_IPersistStorage_GetClassID
1543 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1544 IPersistStorage* iface,
1545 CLSID* clsid)
1547 DefaultHandler *This = impl_from_IPersistStorage(iface);
1548 HRESULT hr;
1550 TRACE("(%p)->(%p)\n", iface, clsid);
1552 if(object_is_running(This))
1553 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1554 else
1555 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1557 return hr;
1560 /************************************************************************
1561 * DefaultHandler_IPersistStorage_IsDirty
1564 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1565 IPersistStorage* iface)
1567 DefaultHandler *This = impl_from_IPersistStorage(iface);
1568 HRESULT hr;
1570 TRACE("(%p)\n", iface);
1572 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1573 if(hr != S_FALSE) return hr;
1575 if(object_is_running(This))
1576 hr = IPersistStorage_IsDirty(This->pPSDelegate);
1578 return hr;
1581 /***********************************************************************
1582 * init_ole_stream
1584 * Creates the '\1Ole' stream.
1585 * The format of this stream is as follows:
1587 * DWORD Version == 0x02000001
1588 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1589 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1590 * supplied by the app that creates the data structure. May be
1591 * ignored on processing].
1593 * DWORD Reserved == 0
1594 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1595 * CLSID clsid - class id of object capable of processing the moniker
1596 * BYTE data[] - moniker data for a link
1599 static const WCHAR OleStream[] = {1,'O','l','e',0};
1600 typedef struct
1602 DWORD version;
1603 DWORD flags;
1604 DWORD link_update_opt;
1605 DWORD res;
1606 DWORD moniker_size;
1607 } ole_stream_header_t;
1608 static const DWORD ole_stream_version = 0x02000001;
1610 static void init_ole_stream(IStorage *storage)
1612 HRESULT hr;
1613 IStream *stream;
1615 hr = IStorage_CreateStream(storage, OleStream, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream);
1616 if(SUCCEEDED(hr))
1618 DWORD written;
1619 ole_stream_header_t header;
1621 header.version = ole_stream_version;
1622 header.flags = 0;
1623 header.link_update_opt = 0;
1624 header.res = 0;
1625 header.moniker_size = 0;
1627 IStream_Write(stream, &header, sizeof(header), &written);
1628 IStream_Release(stream);
1630 return;
1633 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1635 IStream *stream;
1636 HRESULT hr;
1638 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1640 if(SUCCEEDED(hr))
1642 DWORD read;
1643 ole_stream_header_t header;
1645 hr = IStream_Read(stream, &header, sizeof(header), &read);
1646 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1648 if(header.flags & 1)
1650 /* FIXME: Read the moniker and deal with the link */
1651 FIXME("Linked objects are not supported yet\n");
1654 else
1656 WARN("Incorrect OleStream header\n");
1657 hr = DV_E_CLIPFORMAT;
1659 IStream_Release(stream);
1661 else
1663 init_ole_stream(storage);
1664 hr = S_OK;
1666 return hr;
1669 /************************************************************************
1670 * DefaultHandler_IPersistStorage_InitNew
1673 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1674 IPersistStorage* iface,
1675 IStorage* pStg)
1677 DefaultHandler *This = impl_from_IPersistStorage(iface);
1678 HRESULT hr;
1680 TRACE("(%p)->(%p)\n", iface, pStg);
1681 init_ole_stream(pStg);
1683 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1685 if(SUCCEEDED(hr) && object_is_running(This))
1686 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1688 if(SUCCEEDED(hr))
1690 IStorage_AddRef(pStg);
1691 This->storage = pStg;
1692 This->storage_state = storage_state_initialised;
1695 return hr;
1699 /************************************************************************
1700 * DefaultHandler_IPersistStorage_Load
1703 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1704 IPersistStorage* iface,
1705 IStorage* pStg)
1707 DefaultHandler *This = impl_from_IPersistStorage(iface);
1708 HRESULT hr;
1710 TRACE("(%p)->(%p)\n", iface, pStg);
1712 hr = load_ole_stream(This, pStg);
1714 if(SUCCEEDED(hr))
1715 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1717 if(SUCCEEDED(hr) && object_is_running(This))
1718 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1720 if(SUCCEEDED(hr))
1722 IStorage_AddRef(pStg);
1723 This->storage = pStg;
1724 This->storage_state = storage_state_loaded;
1726 return hr;
1730 /************************************************************************
1731 * DefaultHandler_IPersistStorage_Save
1734 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1735 IPersistStorage* iface,
1736 IStorage* pStgSave,
1737 BOOL fSameAsLoad)
1739 DefaultHandler *This = impl_from_IPersistStorage(iface);
1740 HRESULT hr;
1742 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1744 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1745 if(SUCCEEDED(hr) && object_is_running(This))
1746 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1748 return hr;
1752 /************************************************************************
1753 * DefaultHandler_IPersistStorage_SaveCompleted
1756 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1757 IPersistStorage* iface,
1758 IStorage* pStgNew)
1760 DefaultHandler *This = impl_from_IPersistStorage(iface);
1761 HRESULT hr;
1763 TRACE("(%p)->(%p)\n", iface, pStgNew);
1765 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1767 if(SUCCEEDED(hr) && object_is_running(This))
1768 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1770 if(pStgNew)
1772 IStorage_AddRef(pStgNew);
1773 if(This->storage) IStorage_Release(This->storage);
1774 This->storage = pStgNew;
1775 This->storage_state = storage_state_loaded;
1778 return hr;
1782 /************************************************************************
1783 * DefaultHandler_IPersistStorage_HandsOffStorage
1786 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1787 IPersistStorage* iface)
1789 DefaultHandler *This = impl_from_IPersistStorage(iface);
1790 HRESULT hr;
1792 TRACE("(%p)\n", iface);
1794 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1796 if(SUCCEEDED(hr) && object_is_running(This))
1797 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1799 if(This->storage) IStorage_Release(This->storage);
1800 This->storage = NULL;
1801 This->storage_state = storage_state_uninitialised;
1803 return hr;
1808 * Virtual function tables for the DefaultHandler class.
1810 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1812 DefaultHandler_QueryInterface,
1813 DefaultHandler_AddRef,
1814 DefaultHandler_Release,
1815 DefaultHandler_SetClientSite,
1816 DefaultHandler_GetClientSite,
1817 DefaultHandler_SetHostNames,
1818 DefaultHandler_Close,
1819 DefaultHandler_SetMoniker,
1820 DefaultHandler_GetMoniker,
1821 DefaultHandler_InitFromData,
1822 DefaultHandler_GetClipboardData,
1823 DefaultHandler_DoVerb,
1824 DefaultHandler_EnumVerbs,
1825 DefaultHandler_Update,
1826 DefaultHandler_IsUpToDate,
1827 DefaultHandler_GetUserClassID,
1828 DefaultHandler_GetUserType,
1829 DefaultHandler_SetExtent,
1830 DefaultHandler_GetExtent,
1831 DefaultHandler_Advise,
1832 DefaultHandler_Unadvise,
1833 DefaultHandler_EnumAdvise,
1834 DefaultHandler_GetMiscStatus,
1835 DefaultHandler_SetColorScheme
1838 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1840 DefaultHandler_NDIUnknown_QueryInterface,
1841 DefaultHandler_NDIUnknown_AddRef,
1842 DefaultHandler_NDIUnknown_Release,
1845 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1847 DefaultHandler_IDataObject_QueryInterface,
1848 DefaultHandler_IDataObject_AddRef,
1849 DefaultHandler_IDataObject_Release,
1850 DefaultHandler_GetData,
1851 DefaultHandler_GetDataHere,
1852 DefaultHandler_QueryGetData,
1853 DefaultHandler_GetCanonicalFormatEtc,
1854 DefaultHandler_SetData,
1855 DefaultHandler_EnumFormatEtc,
1856 DefaultHandler_DAdvise,
1857 DefaultHandler_DUnadvise,
1858 DefaultHandler_EnumDAdvise
1861 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1863 DefaultHandler_IRunnableObject_QueryInterface,
1864 DefaultHandler_IRunnableObject_AddRef,
1865 DefaultHandler_IRunnableObject_Release,
1866 DefaultHandler_GetRunningClass,
1867 DefaultHandler_Run,
1868 DefaultHandler_IsRunning,
1869 DefaultHandler_LockRunning,
1870 DefaultHandler_SetContainedObject
1873 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1875 DefaultHandler_IAdviseSink_QueryInterface,
1876 DefaultHandler_IAdviseSink_AddRef,
1877 DefaultHandler_IAdviseSink_Release,
1878 DefaultHandler_IAdviseSink_OnDataChange,
1879 DefaultHandler_IAdviseSink_OnViewChange,
1880 DefaultHandler_IAdviseSink_OnRename,
1881 DefaultHandler_IAdviseSink_OnSave,
1882 DefaultHandler_IAdviseSink_OnClose
1885 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
1887 DefaultHandler_IPersistStorage_QueryInterface,
1888 DefaultHandler_IPersistStorage_AddRef,
1889 DefaultHandler_IPersistStorage_Release,
1890 DefaultHandler_IPersistStorage_GetClassID,
1891 DefaultHandler_IPersistStorage_IsDirty,
1892 DefaultHandler_IPersistStorage_InitNew,
1893 DefaultHandler_IPersistStorage_Load,
1894 DefaultHandler_IPersistStorage_Save,
1895 DefaultHandler_IPersistStorage_SaveCompleted,
1896 DefaultHandler_IPersistStorage_HandsOffStorage
1899 /*********************************************************
1900 * Methods implementation for the DefaultHandler class.
1902 static DefaultHandler* DefaultHandler_Construct(
1903 REFCLSID clsid,
1904 LPUNKNOWN pUnkOuter)
1906 DefaultHandler* This = NULL;
1907 HRESULT hr;
1909 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1911 if (!This)
1912 return This;
1914 This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1915 This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1916 This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1917 This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1918 This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1919 This->lpvtblIPersistStorage = &DefaultHandler_IPersistStorage_VTable;
1922 * Start with one reference count. The caller of this function
1923 * must release the interface pointer when it is done.
1925 This->ref = 1;
1928 * Initialize the outer unknown
1929 * We don't keep a reference on the outer unknown since, the way
1930 * aggregation works, our lifetime is at least as large as its
1931 * lifetime.
1933 if (!pUnkOuter)
1934 pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1936 This->outerUnknown = pUnkOuter;
1939 * Create a datacache object.
1940 * We aggregate with the datacache. Make sure we pass our outer
1941 * unknown as the datacache's outer unknown.
1943 hr = CreateDataCache(This->outerUnknown,
1944 clsid,
1945 &IID_IUnknown,
1946 (void**)&This->dataCache);
1947 if(SUCCEEDED(hr))
1948 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
1949 if(FAILED(hr))
1950 ERR("Unexpected error creating data cache\n");
1952 This->clsid = *clsid;
1953 This->clientSite = NULL;
1954 This->oleAdviseHolder = NULL;
1955 This->dataAdviseHolder = NULL;
1956 This->containerApp = NULL;
1957 This->containerObj = NULL;
1958 This->pOleDelegate = NULL;
1959 This->pPSDelegate = NULL;
1960 This->pDataDelegate = NULL;
1961 This->object_state = object_state_not_running;
1963 This->dwAdvConn = 0;
1964 This->storage = NULL;
1965 This->storage_state = storage_state_uninitialised;
1967 return This;
1970 static void DefaultHandler_Destroy(
1971 DefaultHandler* This)
1973 /* release delegates */
1974 DefaultHandler_Stop(This);
1975 release_delegates(This);
1977 HeapFree( GetProcessHeap(), 0, This->containerApp );
1978 This->containerApp = NULL;
1979 HeapFree( GetProcessHeap(), 0, This->containerObj );
1980 This->containerObj = NULL;
1982 if (This->dataCache)
1984 IPersistStorage_Release(This->dataCache_PersistStg);
1985 IUnknown_Release(This->dataCache);
1986 This->dataCache_PersistStg = NULL;
1987 This->dataCache = NULL;
1990 if (This->clientSite)
1992 IOleClientSite_Release(This->clientSite);
1993 This->clientSite = NULL;
1996 if (This->oleAdviseHolder)
1998 IOleAdviseHolder_Release(This->oleAdviseHolder);
1999 This->oleAdviseHolder = NULL;
2002 if (This->dataAdviseHolder)
2004 IDataAdviseHolder_Release(This->dataAdviseHolder);
2005 This->dataAdviseHolder = NULL;
2008 if (This->storage)
2010 IStorage_Release(This->storage);
2011 This->storage = NULL;
2014 HeapFree(GetProcessHeap(), 0, This);
2017 /******************************************************************************
2018 * OleCreateDefaultHandler [OLE32.@]
2020 HRESULT WINAPI OleCreateDefaultHandler(
2021 REFCLSID clsid,
2022 LPUNKNOWN pUnkOuter,
2023 REFIID riid,
2024 LPVOID* ppvObj)
2026 DefaultHandler* newHandler = NULL;
2027 HRESULT hr = S_OK;
2029 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
2031 if (!ppvObj)
2032 return E_POINTER;
2034 *ppvObj = NULL;
2037 * If This handler is constructed for aggregation, make sure
2038 * the caller is requesting the IUnknown interface.
2039 * This is necessary because it's the only time the non-delegating
2040 * IUnknown pointer can be returned to the outside.
2042 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2043 return CLASS_E_NOAGGREGATION;
2046 * Try to construct a new instance of the class.
2048 newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
2050 if (!newHandler)
2051 return E_OUTOFMEMORY;
2054 * Make sure it supports the interface required by the caller.
2056 hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
2059 * Release the reference obtained in the constructor. If
2060 * the QueryInterface was unsuccessful, it will free the class.
2062 IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
2064 return hr;