msvcrt: _filbuf should not lock any file.
[wine.git] / dlls / ole32 / defaulthandler.c
blob5e899770857353c54153edb1e0f49b2f13e478e3
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"
61 #include "storage32.h"
63 #include "wine/unicode.h"
64 #include "wine/debug.h"
66 WINE_DEFAULT_DEBUG_CHANNEL(ole);
68 enum storage_state
70 storage_state_uninitialised,
71 storage_state_initialised,
72 storage_state_loaded
75 enum object_state
77 object_state_not_running,
78 object_state_running
81 /****************************************************************************
82 * DefaultHandler
85 struct DefaultHandler
87 IOleObject IOleObject_iface;
88 IUnknown IUnknown_iface;
89 IDataObject IDataObject_iface;
90 IRunnableObject IRunnableObject_iface;
91 IAdviseSink IAdviseSink_iface;
92 IPersistStorage IPersistStorage_iface;
94 /* Reference count of this object */
95 LONG ref;
97 /* IUnknown implementation of the outer object. */
98 IUnknown* outerUnknown;
100 /* Class Id that this handler object represents. */
101 CLSID clsid;
103 /* IUnknown implementation of the datacache. */
104 IUnknown* dataCache;
105 /* IPersistStorage implementation of the datacache. */
106 IPersistStorage* dataCache_PersistStg;
108 /* Client site for the embedded object. */
109 IOleClientSite* clientSite;
112 * The IOleAdviseHolder maintains the connections
113 * on behalf of the default handler.
115 IOleAdviseHolder* oleAdviseHolder;
118 * The IDataAdviseHolder maintains the data
119 * connections on behalf of the default handler.
121 IDataAdviseHolder* dataAdviseHolder;
123 /* Name of the container and object contained */
124 LPWSTR containerApp;
125 LPWSTR containerObj;
127 /* IOleObject delegate */
128 IOleObject *pOleDelegate;
129 /* IPersistStorage delegate */
130 IPersistStorage *pPSDelegate;
131 /* IDataObject delegate */
132 IDataObject *pDataDelegate;
133 enum object_state object_state;
135 /* connection cookie for the advise on the delegate OLE object */
136 DWORD dwAdvConn;
138 /* storage passed to Load or InitNew */
139 IStorage *storage;
140 enum storage_state storage_state;
142 /* optional class factory for object */
143 IClassFactory *pCFObject;
144 /* TRUE if acting as an inproc server instead of an inproc handler */
145 BOOL inproc_server;
148 typedef struct DefaultHandler DefaultHandler;
150 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
152 return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface);
155 static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface )
157 return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface);
160 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
162 return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface);
165 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
167 return CONTAINING_RECORD(iface, DefaultHandler, IRunnableObject_iface);
170 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
172 return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface);
175 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
177 return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface);
180 static void DefaultHandler_Destroy(DefaultHandler* This);
182 static inline BOOL object_is_running(DefaultHandler *This)
184 return IRunnableObject_IsRunning(&This->IRunnableObject_iface);
187 /*********************************************************
188 * Method implementation for the non delegating IUnknown
189 * part of the DefaultHandler class.
192 /************************************************************************
193 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
195 * See Windows documentation for more details on IUnknown methods.
197 * This version of QueryInterface will not delegate its implementation
198 * to the outer unknown.
200 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
201 IUnknown* iface,
202 REFIID riid,
203 void** ppvObject)
205 DefaultHandler *This = impl_from_IUnknown(iface);
207 if (!ppvObject)
208 return E_INVALIDARG;
210 *ppvObject = NULL;
212 if (IsEqualIID(&IID_IUnknown, riid))
213 *ppvObject = iface;
214 else if (IsEqualIID(&IID_IOleObject, riid))
215 *ppvObject = &This->IOleObject_iface;
216 else if (IsEqualIID(&IID_IDataObject, riid))
217 *ppvObject = &This->IDataObject_iface;
218 else if (IsEqualIID(&IID_IRunnableObject, riid))
219 *ppvObject = &This->IRunnableObject_iface;
220 else if (IsEqualIID(&IID_IPersist, riid) ||
221 IsEqualIID(&IID_IPersistStorage, riid))
222 *ppvObject = &This->IPersistStorage_iface;
223 else if (IsEqualIID(&IID_IViewObject, riid) ||
224 IsEqualIID(&IID_IViewObject2, riid) ||
225 IsEqualIID(&IID_IOleCache, riid) ||
226 IsEqualIID(&IID_IOleCache2, riid))
228 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
229 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
230 return hr;
232 else if (This->inproc_server && This->pOleDelegate)
234 return IOleObject_QueryInterface(This->pOleDelegate, riid, ppvObject);
237 /* Check that we obtained an interface. */
238 if (*ppvObject == NULL)
240 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
241 return E_NOINTERFACE;
245 * Query Interface always increases the reference count by one when it is
246 * successful.
248 IUnknown_AddRef((IUnknown*)*ppvObject);
250 return S_OK;
253 /************************************************************************
254 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
256 * See Windows documentation for more details on IUnknown methods.
258 * This version of QueryInterface will not delegate its implementation
259 * to the outer unknown.
261 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
262 IUnknown* iface)
264 DefaultHandler *This = impl_from_IUnknown(iface);
265 return InterlockedIncrement(&This->ref);
268 /************************************************************************
269 * DefaultHandler_NDIUnknown_Release (IUnknown)
271 * See Windows documentation for more details on IUnknown methods.
273 * This version of QueryInterface will not delegate its implementation
274 * to the outer unknown.
276 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
277 IUnknown* iface)
279 DefaultHandler *This = impl_from_IUnknown(iface);
280 ULONG ref;
282 ref = InterlockedDecrement(&This->ref);
284 if (!ref) DefaultHandler_Destroy(This);
286 return ref;
289 /*********************************************************
290 * Methods implementation for the IOleObject part of
291 * the DefaultHandler class.
294 /************************************************************************
295 * DefaultHandler_QueryInterface (IUnknown)
297 * See Windows documentation for more details on IUnknown methods.
299 static HRESULT WINAPI DefaultHandler_QueryInterface(
300 IOleObject* iface,
301 REFIID riid,
302 void** ppvObject)
304 DefaultHandler *This = impl_from_IOleObject(iface);
306 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
309 /************************************************************************
310 * DefaultHandler_AddRef (IUnknown)
312 * See Windows documentation for more details on IUnknown methods.
314 static ULONG WINAPI DefaultHandler_AddRef(
315 IOleObject* iface)
317 DefaultHandler *This = impl_from_IOleObject(iface);
319 return IUnknown_AddRef(This->outerUnknown);
322 /************************************************************************
323 * DefaultHandler_Release (IUnknown)
325 * See Windows documentation for more details on IUnknown methods.
327 static ULONG WINAPI DefaultHandler_Release(
328 IOleObject* iface)
330 DefaultHandler *This = impl_from_IOleObject(iface);
332 return IUnknown_Release(This->outerUnknown);
335 /************************************************************************
336 * DefaultHandler_SetClientSite (IOleObject)
338 * The default handler's implementation of this method only keeps the
339 * client site pointer for future reference.
341 * See Windows documentation for more details on IOleObject methods.
343 static HRESULT WINAPI DefaultHandler_SetClientSite(
344 IOleObject* iface,
345 IOleClientSite* pClientSite)
347 DefaultHandler *This = impl_from_IOleObject(iface);
348 HRESULT hr = S_OK;
350 TRACE("(%p, %p)\n", iface, pClientSite);
352 if (object_is_running(This))
353 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
356 * Make sure we release the previous client site if there
357 * was one.
359 if (This->clientSite)
360 IOleClientSite_Release(This->clientSite);
362 This->clientSite = pClientSite;
364 if (This->clientSite)
365 IOleClientSite_AddRef(This->clientSite);
367 return hr;
370 /************************************************************************
371 * DefaultHandler_GetClientSite (IOleObject)
373 * The default handler's implementation of this method returns the
374 * last pointer set in IOleObject_SetClientSite.
376 * See Windows documentation for more details on IOleObject methods.
378 static HRESULT WINAPI DefaultHandler_GetClientSite(
379 IOleObject* iface,
380 IOleClientSite** ppClientSite)
382 DefaultHandler *This = impl_from_IOleObject(iface);
384 if (!ppClientSite)
385 return E_POINTER;
387 *ppClientSite = This->clientSite;
389 if (This->clientSite)
390 IOleClientSite_AddRef(This->clientSite);
392 return S_OK;
395 /************************************************************************
396 * DefaultHandler_SetHostNames (IOleObject)
398 * The default handler's implementation of this method just stores
399 * the strings and returns S_OK.
401 * See Windows documentation for more details on IOleObject methods.
403 static HRESULT WINAPI DefaultHandler_SetHostNames(
404 IOleObject* iface,
405 LPCOLESTR szContainerApp,
406 LPCOLESTR szContainerObj)
408 DefaultHandler *This = impl_from_IOleObject(iface);
410 TRACE("(%p, %s, %s)\n",
411 iface,
412 debugstr_w(szContainerApp),
413 debugstr_w(szContainerObj));
415 if (object_is_running(This))
416 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
418 /* Be sure to cleanup before re-assigning the strings. */
419 HeapFree( GetProcessHeap(), 0, This->containerApp );
420 This->containerApp = NULL;
421 HeapFree( GetProcessHeap(), 0, This->containerObj );
422 This->containerObj = NULL;
424 if (szContainerApp)
426 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
427 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
428 strcpyW( This->containerApp, szContainerApp );
431 if (szContainerObj)
433 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
434 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
435 strcpyW( This->containerObj, szContainerObj );
437 return S_OK;
440 static void release_delegates(DefaultHandler *This)
442 if (This->pDataDelegate)
444 IDataObject_Release(This->pDataDelegate);
445 This->pDataDelegate = NULL;
447 if (This->pPSDelegate)
449 IPersistStorage_Release(This->pPSDelegate);
450 This->pPSDelegate = NULL;
452 if (This->pOleDelegate)
454 IOleObject_Release(This->pOleDelegate);
455 This->pOleDelegate = NULL;
459 /* undoes the work done by DefaultHandler_Run */
460 static void DefaultHandler_Stop(DefaultHandler *This)
462 if (!object_is_running(This))
463 return;
465 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
467 /* FIXME: call IOleCache_OnStop */
469 if (This->dataAdviseHolder)
470 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
472 This->object_state = object_state_not_running;
475 /************************************************************************
476 * DefaultHandler_Close (IOleObject)
478 * The default handler's implementation of this method is meaningless
479 * without a running server so it does nothing.
481 * See Windows documentation for more details on IOleObject methods.
483 static HRESULT WINAPI DefaultHandler_Close(
484 IOleObject* iface,
485 DWORD dwSaveOption)
487 DefaultHandler *This = impl_from_IOleObject(iface);
488 HRESULT hr;
490 TRACE("(%d)\n", dwSaveOption);
492 if (!object_is_running(This))
493 return S_OK;
495 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
497 DefaultHandler_Stop(This);
498 release_delegates(This);
500 return hr;
503 /************************************************************************
504 * DefaultHandler_SetMoniker (IOleObject)
506 * The default handler's implementation of this method does nothing.
508 * See Windows documentation for more details on IOleObject methods.
510 static HRESULT WINAPI DefaultHandler_SetMoniker(
511 IOleObject* iface,
512 DWORD dwWhichMoniker,
513 IMoniker* pmk)
515 DefaultHandler *This = impl_from_IOleObject(iface);
517 TRACE("(%p, %d, %p)\n",
518 iface,
519 dwWhichMoniker,
520 pmk);
522 if (object_is_running(This))
523 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
525 return S_OK;
528 /************************************************************************
529 * DefaultHandler_GetMoniker (IOleObject)
531 * Delegate this request to the client site if we have one.
533 * See Windows documentation for more details on IOleObject methods.
535 static HRESULT WINAPI DefaultHandler_GetMoniker(
536 IOleObject* iface,
537 DWORD dwAssign,
538 DWORD dwWhichMoniker,
539 IMoniker** ppmk)
541 DefaultHandler *This = impl_from_IOleObject(iface);
543 TRACE("(%p, %d, %d, %p)\n",
544 iface, dwAssign, dwWhichMoniker, ppmk);
546 if (object_is_running(This))
547 return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
548 ppmk);
550 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
551 if (This->clientSite)
553 return IOleClientSite_GetMoniker(This->clientSite,
554 dwAssign,
555 dwWhichMoniker,
556 ppmk);
560 return E_FAIL;
563 /************************************************************************
564 * DefaultHandler_InitFromData (IOleObject)
566 * This method is meaningless if the server is not running
568 * See Windows documentation for more details on IOleObject methods.
570 static HRESULT WINAPI DefaultHandler_InitFromData(
571 IOleObject* iface,
572 IDataObject* pDataObject,
573 BOOL fCreation,
574 DWORD dwReserved)
576 DefaultHandler *This = impl_from_IOleObject(iface);
578 TRACE("(%p, %p, %d, %d)\n",
579 iface, pDataObject, fCreation, dwReserved);
581 if (object_is_running(This))
582 return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
583 dwReserved);
584 return OLE_E_NOTRUNNING;
587 /************************************************************************
588 * DefaultHandler_GetClipboardData (IOleObject)
590 * This method is meaningless if the server is not running
592 * See Windows documentation for more details on IOleObject methods.
594 static HRESULT WINAPI DefaultHandler_GetClipboardData(
595 IOleObject* iface,
596 DWORD dwReserved,
597 IDataObject** ppDataObject)
599 DefaultHandler *This = impl_from_IOleObject(iface);
601 TRACE("(%p, %d, %p)\n",
602 iface, dwReserved, ppDataObject);
604 if (object_is_running(This))
605 return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
606 ppDataObject);
608 return OLE_E_NOTRUNNING;
611 static HRESULT WINAPI DefaultHandler_DoVerb(
612 IOleObject* iface,
613 LONG iVerb,
614 struct tagMSG* lpmsg,
615 IOleClientSite* pActiveSite,
616 LONG lindex,
617 HWND hwndParent,
618 LPCRECT lprcPosRect)
620 DefaultHandler *This = impl_from_IOleObject(iface);
621 IRunnableObject *pRunnableObj = &This->IRunnableObject_iface;
622 HRESULT hr;
624 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
626 hr = IRunnableObject_Run(pRunnableObj, NULL);
627 if (FAILED(hr)) return hr;
629 return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
630 lindex, hwndParent, lprcPosRect);
633 /************************************************************************
634 * DefaultHandler_EnumVerbs (IOleObject)
636 * The default handler implementation of this method simply delegates
637 * to OleRegEnumVerbs
639 * See Windows documentation for more details on IOleObject methods.
641 static HRESULT WINAPI DefaultHandler_EnumVerbs(
642 IOleObject* iface,
643 IEnumOLEVERB** ppEnumOleVerb)
645 DefaultHandler *This = impl_from_IOleObject(iface);
646 HRESULT hr = OLE_S_USEREG;
648 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
650 if (object_is_running(This))
651 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
653 if (hr == OLE_S_USEREG)
654 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
655 else
656 return hr;
659 static HRESULT WINAPI DefaultHandler_Update(
660 IOleObject* iface)
662 DefaultHandler *This = impl_from_IOleObject(iface);
663 TRACE("(%p)\n", iface);
665 if (!object_is_running(This))
667 FIXME("Should run object\n");
668 return E_NOTIMPL;
670 return IOleObject_Update(This->pOleDelegate);
673 /************************************************************************
674 * DefaultHandler_IsUpToDate (IOleObject)
676 * This method is meaningless if the server is not running
678 * See Windows documentation for more details on IOleObject methods.
680 static HRESULT WINAPI DefaultHandler_IsUpToDate(
681 IOleObject* iface)
683 DefaultHandler *This = impl_from_IOleObject(iface);
684 TRACE("(%p)\n", iface);
686 if (object_is_running(This))
687 return IOleObject_IsUpToDate(This->pOleDelegate);
689 return OLE_E_NOTRUNNING;
692 /************************************************************************
693 * DefaultHandler_GetUserClassID (IOleObject)
695 * TODO: Map to a new class ID if emulation is active.
697 * See Windows documentation for more details on IOleObject methods.
699 static HRESULT WINAPI DefaultHandler_GetUserClassID(
700 IOleObject* iface,
701 CLSID* pClsid)
703 DefaultHandler *This = impl_from_IOleObject(iface);
705 TRACE("(%p, %p)\n", iface, pClsid);
707 if (object_is_running(This))
708 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
710 if (!pClsid)
711 return E_POINTER;
713 *pClsid = This->clsid;
715 return S_OK;
718 /************************************************************************
719 * DefaultHandler_GetUserType (IOleObject)
721 * The default handler implementation of this method simply delegates
722 * to OleRegGetUserType
724 * See Windows documentation for more details on IOleObject methods.
726 static HRESULT WINAPI DefaultHandler_GetUserType(
727 IOleObject* iface,
728 DWORD dwFormOfType,
729 LPOLESTR* pszUserType)
731 DefaultHandler *This = impl_from_IOleObject(iface);
733 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
734 if (object_is_running(This))
735 return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
737 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
740 /************************************************************************
741 * DefaultHandler_SetExtent (IOleObject)
743 * This method is meaningless if the server is not running
745 * See Windows documentation for more details on IOleObject methods.
747 static HRESULT WINAPI DefaultHandler_SetExtent(
748 IOleObject* iface,
749 DWORD dwDrawAspect,
750 SIZEL* psizel)
752 DefaultHandler *This = impl_from_IOleObject(iface);
754 TRACE("(%p, %x, (%d x %d))\n", iface,
755 dwDrawAspect, psizel->cx, psizel->cy);
757 if (object_is_running(This))
758 return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
760 return OLE_E_NOTRUNNING;
763 /************************************************************************
764 * DefaultHandler_GetExtent (IOleObject)
766 * The default handler's implementation of this method returns uses
767 * the cache to locate the aspect and extract the extent from it.
769 * See Windows documentation for more details on IOleObject methods.
771 static HRESULT WINAPI DefaultHandler_GetExtent(
772 IOleObject* iface,
773 DWORD dwDrawAspect,
774 SIZEL* psizel)
776 DVTARGETDEVICE* targetDevice;
777 IViewObject2* cacheView = NULL;
778 HRESULT hres;
780 DefaultHandler *This = impl_from_IOleObject(iface);
782 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
784 if (object_is_running(This))
785 return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
787 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
788 if (FAILED(hres))
789 return E_UNEXPECTED;
792 * Prepare the call to the cache's GetExtent method.
794 * Here we would build a valid DVTARGETDEVICE structure
795 * but, since we are calling into the data cache, we
796 * know its implementation and we'll skip this
797 * extra work until later.
799 targetDevice = NULL;
801 hres = IViewObject2_GetExtent(cacheView,
802 dwDrawAspect,
804 targetDevice,
805 psizel);
807 IViewObject2_Release(cacheView);
809 return hres;
812 /************************************************************************
813 * DefaultHandler_Advise (IOleObject)
815 * The default handler's implementation of this method simply
816 * delegates to the OleAdviseHolder.
818 * See Windows documentation for more details on IOleObject methods.
820 static HRESULT WINAPI DefaultHandler_Advise(
821 IOleObject* iface,
822 IAdviseSink* pAdvSink,
823 DWORD* pdwConnection)
825 HRESULT hres = S_OK;
826 DefaultHandler *This = impl_from_IOleObject(iface);
828 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
830 /* Make sure we have an advise holder before we start. */
831 if (!This->oleAdviseHolder)
832 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
834 if (SUCCEEDED(hres))
835 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
836 pAdvSink,
837 pdwConnection);
839 return hres;
842 /************************************************************************
843 * DefaultHandler_Unadvise (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_Unadvise(
851 IOleObject* iface,
852 DWORD dwConnection)
854 DefaultHandler *This = impl_from_IOleObject(iface);
856 TRACE("(%p, %d)\n", iface, dwConnection);
859 * If we don't have an advise holder yet, it means we don't have
860 * a connection.
862 if (!This->oleAdviseHolder)
863 return OLE_E_NOCONNECTION;
865 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
866 dwConnection);
869 /************************************************************************
870 * DefaultHandler_EnumAdvise (IOleObject)
872 * The default handler's implementation of this method simply
873 * delegates to the OleAdviseHolder.
875 * See Windows documentation for more details on IOleObject methods.
877 static HRESULT WINAPI DefaultHandler_EnumAdvise(
878 IOleObject* iface,
879 IEnumSTATDATA** ppenumAdvise)
881 DefaultHandler *This = impl_from_IOleObject(iface);
883 TRACE("(%p, %p)\n", iface, ppenumAdvise);
885 if (!ppenumAdvise)
886 return E_POINTER;
888 *ppenumAdvise = NULL;
890 if (!This->oleAdviseHolder)
891 return S_OK;
893 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
896 /************************************************************************
897 * DefaultHandler_GetMiscStatus (IOleObject)
899 * The default handler's implementation of this method simply delegates
900 * to OleRegGetMiscStatus.
902 * See Windows documentation for more details on IOleObject methods.
904 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
905 IOleObject* iface,
906 DWORD dwAspect,
907 DWORD* pdwStatus)
909 HRESULT hres;
910 DefaultHandler *This = impl_from_IOleObject(iface);
912 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
914 if (object_is_running(This))
915 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
917 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
919 if (FAILED(hres))
920 *pdwStatus = 0;
922 return hres;
925 /************************************************************************
926 * DefaultHandler_SetColorScheme (IOleObject)
928 * This method is meaningless if the server is not running
930 * See Windows documentation for more details on IOleObject methods.
932 static HRESULT WINAPI DefaultHandler_SetColorScheme(
933 IOleObject* iface,
934 struct tagLOGPALETTE* pLogpal)
936 DefaultHandler *This = impl_from_IOleObject(iface);
938 TRACE("(%p, %p))\n", iface, pLogpal);
940 if (object_is_running(This))
941 return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
943 return OLE_E_NOTRUNNING;
946 /*********************************************************
947 * Methods implementation for the IDataObject part of
948 * the DefaultHandler class.
951 /************************************************************************
952 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
954 * See Windows documentation for more details on IUnknown methods.
956 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
957 IDataObject* iface,
958 REFIID riid,
959 void** ppvObject)
961 DefaultHandler *This = impl_from_IDataObject(iface);
963 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
966 /************************************************************************
967 * DefaultHandler_IDataObject_AddRef (IUnknown)
969 * See Windows documentation for more details on IUnknown methods.
971 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
972 IDataObject* iface)
974 DefaultHandler *This = impl_from_IDataObject(iface);
976 return IUnknown_AddRef(This->outerUnknown);
979 /************************************************************************
980 * DefaultHandler_IDataObject_Release (IUnknown)
982 * See Windows documentation for more details on IUnknown methods.
984 static ULONG WINAPI DefaultHandler_IDataObject_Release(
985 IDataObject* iface)
987 DefaultHandler *This = impl_from_IDataObject(iface);
989 return IUnknown_Release(This->outerUnknown);
992 /************************************************************************
993 * DefaultHandler_GetData
995 * Get Data from a source dataobject using format pformatetcIn->cfFormat
996 * See Windows documentation for more details on GetData.
997 * Default handler's implementation of this method delegates to the cache.
999 static HRESULT WINAPI DefaultHandler_GetData(
1000 IDataObject* iface,
1001 LPFORMATETC pformatetcIn,
1002 STGMEDIUM* pmedium)
1004 IDataObject* cacheDataObject = NULL;
1005 HRESULT hres;
1007 DefaultHandler *This = impl_from_IDataObject(iface);
1009 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
1011 hres = IUnknown_QueryInterface(This->dataCache,
1012 &IID_IDataObject,
1013 (void**)&cacheDataObject);
1015 if (FAILED(hres))
1016 return E_UNEXPECTED;
1018 hres = IDataObject_GetData(cacheDataObject,
1019 pformatetcIn,
1020 pmedium);
1022 IDataObject_Release(cacheDataObject);
1024 if (FAILED(hres) && This->pDataDelegate)
1025 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1027 return hres;
1030 static HRESULT WINAPI DefaultHandler_GetDataHere(
1031 IDataObject* iface,
1032 LPFORMATETC pformatetc,
1033 STGMEDIUM* pmedium)
1035 FIXME(": Stub\n");
1036 return E_NOTIMPL;
1039 /************************************************************************
1040 * DefaultHandler_QueryGetData (IDataObject)
1042 * The default handler's implementation of this method delegates to
1043 * the cache.
1045 * See Windows documentation for more details on IDataObject methods.
1047 static HRESULT WINAPI DefaultHandler_QueryGetData(
1048 IDataObject* iface,
1049 LPFORMATETC pformatetc)
1051 IDataObject* cacheDataObject = NULL;
1052 HRESULT hres;
1054 DefaultHandler *This = impl_from_IDataObject(iface);
1056 TRACE("(%p, %p)\n", iface, pformatetc);
1058 hres = IUnknown_QueryInterface(This->dataCache,
1059 &IID_IDataObject,
1060 (void**)&cacheDataObject);
1062 if (FAILED(hres))
1063 return E_UNEXPECTED;
1065 hres = IDataObject_QueryGetData(cacheDataObject,
1066 pformatetc);
1068 IDataObject_Release(cacheDataObject);
1070 if (FAILED(hres) && This->pDataDelegate)
1071 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1073 return hres;
1076 /************************************************************************
1077 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1079 * This method is meaningless if the server is not running
1081 * See Windows documentation for more details on IDataObject methods.
1083 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1084 IDataObject* iface,
1085 LPFORMATETC pformatetcIn,
1086 LPFORMATETC pformatetcOut)
1088 DefaultHandler *This = impl_from_IDataObject(iface);
1090 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1092 if (!This->pDataDelegate)
1093 return OLE_E_NOTRUNNING;
1095 return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1098 /************************************************************************
1099 * DefaultHandler_SetData (IDataObject)
1101 * The default handler's implementation of this method delegates to
1102 * the cache.
1104 * See Windows documentation for more details on IDataObject methods.
1106 static HRESULT WINAPI DefaultHandler_SetData(
1107 IDataObject* iface,
1108 LPFORMATETC pformatetc,
1109 STGMEDIUM* pmedium,
1110 BOOL fRelease)
1112 DefaultHandler *This = impl_from_IDataObject(iface);
1113 IDataObject* cacheDataObject = NULL;
1114 HRESULT hres;
1116 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1118 hres = IUnknown_QueryInterface(This->dataCache,
1119 &IID_IDataObject,
1120 (void**)&cacheDataObject);
1122 if (FAILED(hres))
1123 return E_UNEXPECTED;
1125 hres = IDataObject_SetData(cacheDataObject,
1126 pformatetc,
1127 pmedium,
1128 fRelease);
1130 IDataObject_Release(cacheDataObject);
1132 return hres;
1135 /************************************************************************
1136 * DefaultHandler_EnumFormatEtc (IDataObject)
1138 * The default handler's implementation of This method simply delegates
1139 * to OleRegEnumFormatEtc.
1141 * See Windows documentation for more details on IDataObject methods.
1143 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1144 IDataObject* iface,
1145 DWORD dwDirection,
1146 IEnumFORMATETC** ppenumFormatEtc)
1148 DefaultHandler *This = impl_from_IDataObject(iface);
1150 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1152 return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1155 /************************************************************************
1156 * DefaultHandler_DAdvise (IDataObject)
1158 * The default handler's implementation of this method simply
1159 * delegates to the DataAdviseHolder.
1161 * See Windows documentation for more details on IDataObject methods.
1163 static HRESULT WINAPI DefaultHandler_DAdvise(
1164 IDataObject* iface,
1165 FORMATETC* pformatetc,
1166 DWORD advf,
1167 IAdviseSink* pAdvSink,
1168 DWORD* pdwConnection)
1170 HRESULT hres = S_OK;
1171 DefaultHandler *This = impl_from_IDataObject(iface);
1173 TRACE("(%p, %p, %d, %p, %p)\n",
1174 iface, pformatetc, advf, pAdvSink, pdwConnection);
1176 /* Make sure we have a data advise holder before we start. */
1177 if (!This->dataAdviseHolder)
1179 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1180 if (SUCCEEDED(hres) && This->pDataDelegate)
1181 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1184 if (SUCCEEDED(hres))
1185 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1186 iface,
1187 pformatetc,
1188 advf,
1189 pAdvSink,
1190 pdwConnection);
1192 return hres;
1195 /************************************************************************
1196 * DefaultHandler_DUnadvise (IDataObject)
1198 * The default handler's implementation of this method simply
1199 * delegates to the DataAdviseHolder.
1201 * See Windows documentation for more details on IDataObject methods.
1203 static HRESULT WINAPI DefaultHandler_DUnadvise(
1204 IDataObject* iface,
1205 DWORD dwConnection)
1207 DefaultHandler *This = impl_from_IDataObject(iface);
1209 TRACE("(%p, %d)\n", iface, dwConnection);
1212 * If we don't have a data advise holder yet, it means that
1213 * we don't have any connections..
1215 if (!This->dataAdviseHolder)
1216 return OLE_E_NOCONNECTION;
1218 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1219 dwConnection);
1222 /************************************************************************
1223 * DefaultHandler_EnumDAdvise (IDataObject)
1225 * The default handler's implementation of this method simply
1226 * delegates to the DataAdviseHolder.
1228 * See Windows documentation for more details on IDataObject methods.
1230 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1231 IDataObject* iface,
1232 IEnumSTATDATA** ppenumAdvise)
1234 DefaultHandler *This = impl_from_IDataObject(iface);
1236 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1238 if (!ppenumAdvise)
1239 return E_POINTER;
1241 *ppenumAdvise = NULL;
1243 /* If we have a data advise holder object, delegate. */
1244 if (This->dataAdviseHolder)
1245 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1246 ppenumAdvise);
1248 return S_OK;
1251 /*********************************************************
1252 * Methods implementation for the IRunnableObject part
1253 * of the DefaultHandler class.
1256 /************************************************************************
1257 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1259 * See Windows documentation for more details on IUnknown methods.
1261 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1262 IRunnableObject* iface,
1263 REFIID riid,
1264 void** ppvObject)
1266 DefaultHandler *This = impl_from_IRunnableObject(iface);
1268 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1271 /************************************************************************
1272 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1274 * See Windows documentation for more details on IUnknown methods.
1276 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1277 IRunnableObject* iface)
1279 DefaultHandler *This = impl_from_IRunnableObject(iface);
1281 return IUnknown_AddRef(This->outerUnknown);
1284 /************************************************************************
1285 * DefaultHandler_IRunnableObject_Release (IUnknown)
1287 * See Windows documentation for more details on IUnknown methods.
1289 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1290 IRunnableObject* iface)
1292 DefaultHandler *This = impl_from_IRunnableObject(iface);
1294 return IUnknown_Release(This->outerUnknown);
1297 /************************************************************************
1298 * DefaultHandler_GetRunningClass (IRunnableObject)
1300 * See Windows documentation for more details on IRunnableObject methods.
1302 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1303 IRunnableObject* iface,
1304 LPCLSID lpClsid)
1306 FIXME("()\n");
1307 return S_OK;
1310 static HRESULT WINAPI DefaultHandler_Run(
1311 IRunnableObject* iface,
1312 IBindCtx* pbc)
1314 DefaultHandler *This = impl_from_IRunnableObject(iface);
1315 HRESULT hr;
1317 FIXME("(%p): semi-stub\n", pbc);
1319 /* already running? if so nothing to do */
1320 if (object_is_running(This))
1321 return S_OK;
1323 release_delegates(This);
1325 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
1326 &IID_IOleObject, (void **)&This->pOleDelegate);
1327 if (FAILED(hr))
1328 return hr;
1330 This->object_state = object_state_running;
1332 hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
1334 if (SUCCEEDED(hr) && This->clientSite)
1335 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1337 if (SUCCEEDED(hr))
1339 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1340 (void **)&This->pPSDelegate);
1341 if (This->pPSDelegate)
1343 if(This->storage_state == storage_state_initialised)
1344 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1345 else if(This->storage_state == storage_state_loaded)
1346 hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1350 if (SUCCEEDED(hr) && This->containerApp)
1351 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1352 This->containerObj);
1354 /* FIXME: do more stuff here:
1355 * - IOleObject_GetMiscStatus
1356 * - IOleObject_GetMoniker
1357 * - IOleCache_OnRun
1360 if (SUCCEEDED(hr))
1361 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1362 (void **)&This->pDataDelegate);
1364 if (SUCCEEDED(hr) && This->dataAdviseHolder)
1365 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1367 if (FAILED(hr))
1369 DefaultHandler_Stop(This);
1370 release_delegates(This);
1373 return hr;
1376 /************************************************************************
1377 * DefaultHandler_IsRunning (IRunnableObject)
1379 * See Windows documentation for more details on IRunnableObject methods.
1381 static BOOL WINAPI DefaultHandler_IsRunning(
1382 IRunnableObject* iface)
1384 DefaultHandler *This = impl_from_IRunnableObject(iface);
1386 TRACE("()\n");
1388 if (This->object_state == object_state_running)
1389 return TRUE;
1390 else
1391 return FALSE;
1394 /************************************************************************
1395 * DefaultHandler_LockRunning (IRunnableObject)
1397 * See Windows documentation for more details on IRunnableObject methods.
1399 static HRESULT WINAPI DefaultHandler_LockRunning(
1400 IRunnableObject* iface,
1401 BOOL fLock,
1402 BOOL fLastUnlockCloses)
1404 FIXME("()\n");
1405 return S_OK;
1408 /************************************************************************
1409 * DefaultHandler_SetContainedObject (IRunnableObject)
1411 * See Windows documentation for more details on IRunnableObject methods.
1413 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1414 IRunnableObject* iface,
1415 BOOL fContained)
1417 FIXME("()\n");
1418 return S_OK;
1421 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1422 IAdviseSink *iface,
1423 REFIID riid,
1424 void **ppvObject)
1426 if (IsEqualIID(riid, &IID_IUnknown) ||
1427 IsEqualIID(riid, &IID_IAdviseSink))
1429 *ppvObject = iface;
1430 IAdviseSink_AddRef(iface);
1431 return S_OK;
1434 return E_NOINTERFACE;
1437 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1438 IAdviseSink *iface)
1440 DefaultHandler *This = impl_from_IAdviseSink(iface);
1442 return IUnknown_AddRef(&This->IUnknown_iface);
1445 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1446 IAdviseSink *iface)
1448 DefaultHandler *This = impl_from_IAdviseSink(iface);
1450 return IUnknown_Release(&This->IUnknown_iface);
1453 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1454 IAdviseSink *iface,
1455 FORMATETC *pFormatetc,
1456 STGMEDIUM *pStgmed)
1458 FIXME(": stub\n");
1461 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1462 IAdviseSink *iface,
1463 DWORD dwAspect,
1464 LONG lindex)
1466 FIXME(": stub\n");
1469 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1470 IAdviseSink *iface,
1471 IMoniker *pmk)
1473 DefaultHandler *This = impl_from_IAdviseSink(iface);
1475 TRACE("(%p)\n", pmk);
1477 if (This->oleAdviseHolder)
1478 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1481 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1482 IAdviseSink *iface)
1484 DefaultHandler *This = impl_from_IAdviseSink(iface);
1486 TRACE("()\n");
1488 if (This->oleAdviseHolder)
1489 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1492 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1493 IAdviseSink *iface)
1495 DefaultHandler *This = impl_from_IAdviseSink(iface);
1497 TRACE("()\n");
1499 if (This->oleAdviseHolder)
1500 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1502 DefaultHandler_Stop(This);
1506 /************************************************************************
1507 * DefaultHandler_IPersistStorage_QueryInterface
1510 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1511 IPersistStorage* iface,
1512 REFIID riid,
1513 void** ppvObject)
1515 DefaultHandler *This = impl_from_IPersistStorage(iface);
1517 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1520 /************************************************************************
1521 * DefaultHandler_IPersistStorage_AddRef
1524 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1525 IPersistStorage* iface)
1527 DefaultHandler *This = impl_from_IPersistStorage(iface);
1529 return IUnknown_AddRef(This->outerUnknown);
1532 /************************************************************************
1533 * DefaultHandler_IPersistStorage_Release
1536 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1537 IPersistStorage* iface)
1539 DefaultHandler *This = impl_from_IPersistStorage(iface);
1541 return IUnknown_Release(This->outerUnknown);
1544 /************************************************************************
1545 * DefaultHandler_IPersistStorage_GetClassID
1548 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1549 IPersistStorage* iface,
1550 CLSID* clsid)
1552 DefaultHandler *This = impl_from_IPersistStorage(iface);
1553 HRESULT hr;
1555 TRACE("(%p)->(%p)\n", iface, clsid);
1557 if(object_is_running(This))
1558 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1559 else
1560 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1562 return hr;
1565 /************************************************************************
1566 * DefaultHandler_IPersistStorage_IsDirty
1569 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1570 IPersistStorage* iface)
1572 DefaultHandler *This = impl_from_IPersistStorage(iface);
1573 HRESULT hr;
1575 TRACE("(%p)\n", iface);
1577 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1578 if(hr != S_FALSE) return hr;
1580 if(object_is_running(This))
1581 hr = IPersistStorage_IsDirty(This->pPSDelegate);
1583 return hr;
1586 /***********************************************************************
1588 * The format of '\1Ole' stream is as follows:
1590 * DWORD Version == 0x02000001
1591 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1592 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1593 * supplied by the app that creates the data structure. May be
1594 * ignored on processing].
1596 * DWORD Reserved == 0
1597 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1598 * CLSID clsid - class id of object capable of processing the moniker
1599 * BYTE data[] - moniker data for a link
1602 static const WCHAR OleStream[] = {1,'O','l','e',0};
1603 typedef struct
1605 DWORD version;
1606 DWORD flags;
1607 DWORD link_update_opt;
1608 DWORD res;
1609 DWORD moniker_size;
1610 } ole_stream_header_t;
1611 static const DWORD ole_stream_version = 0x02000001;
1613 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1615 IStream *stream;
1616 HRESULT hr;
1618 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1620 if(SUCCEEDED(hr))
1622 DWORD read;
1623 ole_stream_header_t header;
1625 hr = IStream_Read(stream, &header, sizeof(header), &read);
1626 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1628 if(header.flags & 1)
1630 /* FIXME: Read the moniker and deal with the link */
1631 FIXME("Linked objects are not supported yet\n");
1634 else
1636 WARN("Incorrect OleStream header\n");
1637 hr = DV_E_CLIPFORMAT;
1639 IStream_Release(stream);
1641 else
1642 hr = STORAGE_CreateOleStream(storage, 0);
1644 return hr;
1647 /************************************************************************
1648 * DefaultHandler_IPersistStorage_InitNew
1651 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1652 IPersistStorage* iface,
1653 IStorage* pStg)
1655 DefaultHandler *This = impl_from_IPersistStorage(iface);
1656 HRESULT hr;
1658 TRACE("(%p)->(%p)\n", iface, pStg);
1659 hr = STORAGE_CreateOleStream(pStg, 0);
1660 if (hr != S_OK) return hr;
1662 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1664 if(SUCCEEDED(hr) && object_is_running(This))
1665 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1667 if(SUCCEEDED(hr))
1669 IStorage_AddRef(pStg);
1670 This->storage = pStg;
1671 This->storage_state = storage_state_initialised;
1674 return hr;
1678 /************************************************************************
1679 * DefaultHandler_IPersistStorage_Load
1682 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1683 IPersistStorage* iface,
1684 IStorage* pStg)
1686 DefaultHandler *This = impl_from_IPersistStorage(iface);
1687 HRESULT hr;
1689 TRACE("(%p)->(%p)\n", iface, pStg);
1691 hr = load_ole_stream(This, pStg);
1693 if(SUCCEEDED(hr))
1694 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1696 if(SUCCEEDED(hr) && object_is_running(This))
1697 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1699 if(SUCCEEDED(hr))
1701 IStorage_AddRef(pStg);
1702 This->storage = pStg;
1703 This->storage_state = storage_state_loaded;
1705 return hr;
1709 /************************************************************************
1710 * DefaultHandler_IPersistStorage_Save
1713 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1714 IPersistStorage* iface,
1715 IStorage* pStgSave,
1716 BOOL fSameAsLoad)
1718 DefaultHandler *This = impl_from_IPersistStorage(iface);
1719 HRESULT hr;
1721 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1723 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1724 if(SUCCEEDED(hr) && object_is_running(This))
1725 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1727 return hr;
1731 /************************************************************************
1732 * DefaultHandler_IPersistStorage_SaveCompleted
1735 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1736 IPersistStorage* iface,
1737 IStorage* pStgNew)
1739 DefaultHandler *This = impl_from_IPersistStorage(iface);
1740 HRESULT hr;
1742 TRACE("(%p)->(%p)\n", iface, pStgNew);
1744 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1746 if(SUCCEEDED(hr) && object_is_running(This))
1747 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1749 if(pStgNew)
1751 IStorage_AddRef(pStgNew);
1752 if(This->storage) IStorage_Release(This->storage);
1753 This->storage = pStgNew;
1754 This->storage_state = storage_state_loaded;
1757 return hr;
1761 /************************************************************************
1762 * DefaultHandler_IPersistStorage_HandsOffStorage
1765 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1766 IPersistStorage* iface)
1768 DefaultHandler *This = impl_from_IPersistStorage(iface);
1769 HRESULT hr;
1771 TRACE("(%p)\n", iface);
1773 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1775 if(SUCCEEDED(hr) && object_is_running(This))
1776 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1778 if(This->storage) IStorage_Release(This->storage);
1779 This->storage = NULL;
1780 This->storage_state = storage_state_uninitialised;
1782 return hr;
1787 * Virtual function tables for the DefaultHandler class.
1789 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1791 DefaultHandler_QueryInterface,
1792 DefaultHandler_AddRef,
1793 DefaultHandler_Release,
1794 DefaultHandler_SetClientSite,
1795 DefaultHandler_GetClientSite,
1796 DefaultHandler_SetHostNames,
1797 DefaultHandler_Close,
1798 DefaultHandler_SetMoniker,
1799 DefaultHandler_GetMoniker,
1800 DefaultHandler_InitFromData,
1801 DefaultHandler_GetClipboardData,
1802 DefaultHandler_DoVerb,
1803 DefaultHandler_EnumVerbs,
1804 DefaultHandler_Update,
1805 DefaultHandler_IsUpToDate,
1806 DefaultHandler_GetUserClassID,
1807 DefaultHandler_GetUserType,
1808 DefaultHandler_SetExtent,
1809 DefaultHandler_GetExtent,
1810 DefaultHandler_Advise,
1811 DefaultHandler_Unadvise,
1812 DefaultHandler_EnumAdvise,
1813 DefaultHandler_GetMiscStatus,
1814 DefaultHandler_SetColorScheme
1817 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1819 DefaultHandler_NDIUnknown_QueryInterface,
1820 DefaultHandler_NDIUnknown_AddRef,
1821 DefaultHandler_NDIUnknown_Release,
1824 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1826 DefaultHandler_IDataObject_QueryInterface,
1827 DefaultHandler_IDataObject_AddRef,
1828 DefaultHandler_IDataObject_Release,
1829 DefaultHandler_GetData,
1830 DefaultHandler_GetDataHere,
1831 DefaultHandler_QueryGetData,
1832 DefaultHandler_GetCanonicalFormatEtc,
1833 DefaultHandler_SetData,
1834 DefaultHandler_EnumFormatEtc,
1835 DefaultHandler_DAdvise,
1836 DefaultHandler_DUnadvise,
1837 DefaultHandler_EnumDAdvise
1840 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1842 DefaultHandler_IRunnableObject_QueryInterface,
1843 DefaultHandler_IRunnableObject_AddRef,
1844 DefaultHandler_IRunnableObject_Release,
1845 DefaultHandler_GetRunningClass,
1846 DefaultHandler_Run,
1847 DefaultHandler_IsRunning,
1848 DefaultHandler_LockRunning,
1849 DefaultHandler_SetContainedObject
1852 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1854 DefaultHandler_IAdviseSink_QueryInterface,
1855 DefaultHandler_IAdviseSink_AddRef,
1856 DefaultHandler_IAdviseSink_Release,
1857 DefaultHandler_IAdviseSink_OnDataChange,
1858 DefaultHandler_IAdviseSink_OnViewChange,
1859 DefaultHandler_IAdviseSink_OnRename,
1860 DefaultHandler_IAdviseSink_OnSave,
1861 DefaultHandler_IAdviseSink_OnClose
1864 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
1866 DefaultHandler_IPersistStorage_QueryInterface,
1867 DefaultHandler_IPersistStorage_AddRef,
1868 DefaultHandler_IPersistStorage_Release,
1869 DefaultHandler_IPersistStorage_GetClassID,
1870 DefaultHandler_IPersistStorage_IsDirty,
1871 DefaultHandler_IPersistStorage_InitNew,
1872 DefaultHandler_IPersistStorage_Load,
1873 DefaultHandler_IPersistStorage_Save,
1874 DefaultHandler_IPersistStorage_SaveCompleted,
1875 DefaultHandler_IPersistStorage_HandsOffStorage
1878 /*********************************************************
1879 * Methods implementation for the DefaultHandler class.
1881 static DefaultHandler* DefaultHandler_Construct(
1882 REFCLSID clsid,
1883 LPUNKNOWN pUnkOuter,
1884 DWORD flags,
1885 IClassFactory *pCF)
1887 DefaultHandler* This = NULL;
1888 HRESULT hr;
1890 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1892 if (!This)
1893 return This;
1895 This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable;
1896 This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable;
1897 This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable;
1898 This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable;
1899 This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable;
1900 This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable;
1902 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) != 0;
1905 * Start with one reference count. The caller of this function
1906 * must release the interface pointer when it is done.
1908 This->ref = 1;
1911 * Initialize the outer unknown
1912 * We don't keep a reference on the outer unknown since, the way
1913 * aggregation works, our lifetime is at least as large as its
1914 * lifetime.
1916 if (!pUnkOuter)
1917 pUnkOuter = &This->IUnknown_iface;
1919 This->outerUnknown = pUnkOuter;
1922 * Create a datacache object.
1923 * We aggregate with the datacache. Make sure we pass our outer
1924 * unknown as the datacache's outer unknown.
1926 hr = CreateDataCache(This->outerUnknown,
1927 clsid,
1928 &IID_IUnknown,
1929 (void**)&This->dataCache);
1930 if(SUCCEEDED(hr))
1932 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
1933 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
1934 * reference on the outer object */
1935 if (SUCCEEDED(hr))
1936 IUnknown_Release(This->outerUnknown);
1937 else
1938 IUnknown_Release(This->dataCache);
1940 if(FAILED(hr))
1942 ERR("Unexpected error creating data cache\n");
1943 HeapFree(GetProcessHeap(), 0, This);
1944 return NULL;
1947 This->clsid = *clsid;
1948 This->clientSite = NULL;
1949 This->oleAdviseHolder = NULL;
1950 This->dataAdviseHolder = NULL;
1951 This->containerApp = NULL;
1952 This->containerObj = NULL;
1953 This->pOleDelegate = NULL;
1954 This->pPSDelegate = NULL;
1955 This->pDataDelegate = NULL;
1956 This->object_state = object_state_not_running;
1958 This->dwAdvConn = 0;
1959 This->storage = NULL;
1960 This->storage_state = storage_state_uninitialised;
1962 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
1964 HRESULT hr;
1965 This->pCFObject = NULL;
1966 if (pCF)
1967 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
1968 else
1969 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1970 &IID_IOleObject, (void **)&This->pOleDelegate);
1971 if (SUCCEEDED(hr))
1972 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
1973 if (SUCCEEDED(hr))
1974 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
1975 if (SUCCEEDED(hr))
1976 This->object_state = object_state_running;
1977 if (FAILED(hr))
1978 WARN("object creation failed with error %08x\n", hr);
1980 else
1982 This->pCFObject = pCF;
1983 if (pCF) IClassFactory_AddRef(pCF);
1986 return This;
1989 static void DefaultHandler_Destroy(
1990 DefaultHandler* This)
1992 TRACE("(%p)\n", This);
1994 /* AddRef/Release may be called on this object during destruction.
1995 * Prevent the object being destroyed recursively by artificially raising
1996 * the reference count. */
1997 This->ref = 10000;
1999 /* release delegates */
2000 DefaultHandler_Stop(This);
2001 release_delegates(This);
2003 HeapFree( GetProcessHeap(), 0, This->containerApp );
2004 This->containerApp = NULL;
2005 HeapFree( GetProcessHeap(), 0, This->containerObj );
2006 This->containerObj = NULL;
2008 if (This->dataCache)
2010 /* to balance out the release of dataCache_PersistStg which will result
2011 * in a reference being released from the outer unknown */
2012 IUnknown_AddRef(This->outerUnknown);
2013 IPersistStorage_Release(This->dataCache_PersistStg);
2014 IUnknown_Release(This->dataCache);
2015 This->dataCache_PersistStg = NULL;
2016 This->dataCache = NULL;
2019 if (This->clientSite)
2021 IOleClientSite_Release(This->clientSite);
2022 This->clientSite = NULL;
2025 if (This->oleAdviseHolder)
2027 IOleAdviseHolder_Release(This->oleAdviseHolder);
2028 This->oleAdviseHolder = NULL;
2031 if (This->dataAdviseHolder)
2033 IDataAdviseHolder_Release(This->dataAdviseHolder);
2034 This->dataAdviseHolder = NULL;
2037 if (This->storage)
2039 IStorage_Release(This->storage);
2040 This->storage = NULL;
2043 if (This->pCFObject)
2045 IClassFactory_Release(This->pCFObject);
2046 This->pCFObject = NULL;
2049 HeapFree(GetProcessHeap(), 0, This);
2052 /******************************************************************************
2053 * OleCreateEmbeddingHelper [OLE32.@]
2055 HRESULT WINAPI OleCreateEmbeddingHelper(
2056 REFCLSID clsid,
2057 LPUNKNOWN pUnkOuter,
2058 DWORD flags,
2059 IClassFactory *pCF,
2060 REFIID riid,
2061 LPVOID* ppvObj)
2063 DefaultHandler* newHandler = NULL;
2064 HRESULT hr = S_OK;
2066 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2068 if (!ppvObj)
2069 return E_POINTER;
2071 *ppvObj = NULL;
2074 * If This handler is constructed for aggregation, make sure
2075 * the caller is requesting the IUnknown interface.
2076 * This is necessary because it's the only time the non-delegating
2077 * IUnknown pointer can be returned to the outside.
2079 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2080 return CLASS_E_NOAGGREGATION;
2083 * Try to construct a new instance of the class.
2085 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2087 if (!newHandler)
2088 return E_OUTOFMEMORY;
2091 * Make sure it supports the interface required by the caller.
2093 hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj);
2096 * Release the reference obtained in the constructor. If
2097 * the QueryInterface was unsuccessful, it will free the class.
2099 IUnknown_Release(&newHandler->IUnknown_iface);
2101 return hr;
2105 /******************************************************************************
2106 * OleCreateDefaultHandler [OLE32.@]
2108 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
2109 REFIID riid, LPVOID* ppvObj)
2111 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
2112 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
2113 NULL, riid, ppvObj);
2116 typedef struct HandlerCF
2118 IClassFactory IClassFactory_iface;
2119 LONG refs;
2120 CLSID clsid;
2121 } HandlerCF;
2123 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
2125 return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
2128 static HRESULT WINAPI
2129 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
2131 *ppv = NULL;
2132 if (IsEqualIID(riid,&IID_IUnknown) ||
2133 IsEqualIID(riid,&IID_IClassFactory))
2135 *ppv = iface;
2136 IClassFactory_AddRef(iface);
2137 return S_OK;
2139 return E_NOINTERFACE;
2142 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
2144 HandlerCF *This = impl_from_IClassFactory(iface);
2145 return InterlockedIncrement(&This->refs);
2148 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
2150 HandlerCF *This = impl_from_IClassFactory(iface);
2151 ULONG refs = InterlockedDecrement(&This->refs);
2152 if (!refs)
2153 HeapFree(GetProcessHeap(), 0, This);
2154 return refs;
2157 static HRESULT WINAPI
2158 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
2159 REFIID riid, LPVOID *ppv)
2161 HandlerCF *This = impl_from_IClassFactory(iface);
2162 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
2165 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
2167 FIXME("(%d), stub!\n",fLock);
2168 return S_OK;
2171 static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
2172 HandlerCF_QueryInterface,
2173 HandlerCF_AddRef,
2174 HandlerCF_Release,
2175 HandlerCF_CreateInstance,
2176 HandlerCF_LockServer
2179 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
2181 HRESULT hr;
2182 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2183 if (!This) return E_OUTOFMEMORY;
2184 This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
2185 This->refs = 0;
2186 This->clsid = *rclsid;
2188 hr = IUnknown_QueryInterface((IUnknown *)&This->IClassFactory_iface, riid, ppv);
2189 if (FAILED(hr))
2190 HeapFree(GetProcessHeap(), 0, This);
2192 return hr;