push 38a8c0aff9170390b5a3ded41e7cf5b02f3a73d8
[wine/hacks.git] / dlls / ole32 / defaulthandler.c
blob5130513d57f0c5f3fe5197a601d8d6bbbe2647f0
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;
141 /* optional class factory for object */
142 IClassFactory *pCFObject;
143 /* TRUE if acting as an inproc server instead of an inproc handler */
144 BOOL inproc_server;
147 typedef struct DefaultHandler DefaultHandler;
149 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
151 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpVtbl));
154 static inline DefaultHandler *impl_from_NDIUnknown( IUnknown *iface )
156 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIUnknown));
159 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
161 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIDataObject));
164 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
166 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
169 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
171 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink));
174 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
176 return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIPersistStorage));
179 static void DefaultHandler_Destroy(DefaultHandler* This);
181 static inline BOOL object_is_running(DefaultHandler *This)
183 return IRunnableObject_IsRunning((IRunnableObject*)&This->lpvtblIRunnableObject);
186 /*********************************************************
187 * Method implementation for the non delegating IUnknown
188 * part of the DefaultHandler class.
191 /************************************************************************
192 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
194 * See Windows documentation for more details on IUnknown methods.
196 * This version of QueryInterface will not delegate its implementation
197 * to the outer unknown.
199 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
200 IUnknown* iface,
201 REFIID riid,
202 void** ppvObject)
204 DefaultHandler *This = impl_from_NDIUnknown(iface);
206 if (!ppvObject)
207 return E_INVALIDARG;
209 *ppvObject = NULL;
211 if (IsEqualIID(&IID_IUnknown, riid))
212 *ppvObject = iface;
213 else if (IsEqualIID(&IID_IOleObject, riid))
214 *ppvObject = &This->lpVtbl;
215 else if (IsEqualIID(&IID_IDataObject, riid))
216 *ppvObject = &This->lpvtblIDataObject;
217 else if (IsEqualIID(&IID_IRunnableObject, riid))
218 *ppvObject = &This->lpvtblIRunnableObject;
219 else if (IsEqualIID(&IID_IPersist, riid) ||
220 IsEqualIID(&IID_IPersistStorage, riid))
221 *ppvObject = &This->lpvtblIPersistStorage;
222 else if (IsEqualIID(&IID_IViewObject, riid) ||
223 IsEqualIID(&IID_IViewObject2, riid) ||
224 IsEqualIID(&IID_IOleCache, riid) ||
225 IsEqualIID(&IID_IOleCache2, riid))
227 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
228 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
229 return hr;
231 else if (This->inproc_server && This->pOleDelegate)
233 HRESULT hr = IUnknown_QueryInterface(This->pOleDelegate, riid, ppvObject);
234 if (SUCCEEDED(hr))
235 return hr;
238 /* Check that we obtained an interface. */
239 if (*ppvObject == NULL)
241 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
242 return E_NOINTERFACE;
246 * Query Interface always increases the reference count by one when it is
247 * successful.
249 IUnknown_AddRef((IUnknown*)*ppvObject);
251 return S_OK;
254 /************************************************************************
255 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
257 * See Windows documentation for more details on IUnknown methods.
259 * This version of QueryInterface will not delegate its implementation
260 * to the outer unknown.
262 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
263 IUnknown* iface)
265 DefaultHandler *This = impl_from_NDIUnknown(iface);
266 return InterlockedIncrement(&This->ref);
269 /************************************************************************
270 * DefaultHandler_NDIUnknown_Release (IUnknown)
272 * See Windows documentation for more details on IUnknown methods.
274 * This version of QueryInterface will not delegate its implementation
275 * to the outer unknown.
277 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
278 IUnknown* iface)
280 DefaultHandler *This = impl_from_NDIUnknown(iface);
281 ULONG ref;
283 ref = InterlockedDecrement(&This->ref);
285 if (!ref) DefaultHandler_Destroy(This);
287 return ref;
290 /*********************************************************
291 * Methods implementation for the IOleObject part of
292 * the DefaultHandler class.
295 /************************************************************************
296 * DefaultHandler_QueryInterface (IUnknown)
298 * See Windows documentation for more details on IUnknown methods.
300 static HRESULT WINAPI DefaultHandler_QueryInterface(
301 IOleObject* iface,
302 REFIID riid,
303 void** ppvObject)
305 DefaultHandler *This = impl_from_IOleObject(iface);
307 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
310 /************************************************************************
311 * DefaultHandler_AddRef (IUnknown)
313 * See Windows documentation for more details on IUnknown methods.
315 static ULONG WINAPI DefaultHandler_AddRef(
316 IOleObject* iface)
318 DefaultHandler *This = impl_from_IOleObject(iface);
320 return IUnknown_AddRef(This->outerUnknown);
323 /************************************************************************
324 * DefaultHandler_Release (IUnknown)
326 * See Windows documentation for more details on IUnknown methods.
328 static ULONG WINAPI DefaultHandler_Release(
329 IOleObject* iface)
331 DefaultHandler *This = impl_from_IOleObject(iface);
333 return IUnknown_Release(This->outerUnknown);
336 /************************************************************************
337 * DefaultHandler_SetClientSite (IOleObject)
339 * The default handler's implementation of this method only keeps the
340 * client site pointer for future reference.
342 * See Windows documentation for more details on IOleObject methods.
344 static HRESULT WINAPI DefaultHandler_SetClientSite(
345 IOleObject* iface,
346 IOleClientSite* pClientSite)
348 DefaultHandler *This = impl_from_IOleObject(iface);
349 HRESULT hr = S_OK;
351 TRACE("(%p, %p)\n", iface, pClientSite);
353 if (object_is_running(This))
354 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
357 * Make sure we release the previous client site if there
358 * was one.
360 if (This->clientSite)
361 IOleClientSite_Release(This->clientSite);
363 This->clientSite = pClientSite;
365 if (This->clientSite)
366 IOleClientSite_AddRef(This->clientSite);
368 return S_OK;
371 /************************************************************************
372 * DefaultHandler_GetClientSite (IOleObject)
374 * The default handler's implementation of this method returns the
375 * last pointer set in IOleObject_SetClientSite.
377 * See Windows documentation for more details on IOleObject methods.
379 static HRESULT WINAPI DefaultHandler_GetClientSite(
380 IOleObject* iface,
381 IOleClientSite** ppClientSite)
383 DefaultHandler *This = impl_from_IOleObject(iface);
385 if (!ppClientSite)
386 return E_POINTER;
388 *ppClientSite = This->clientSite;
390 if (This->clientSite)
391 IOleClientSite_AddRef(This->clientSite);
393 return S_OK;
396 /************************************************************************
397 * DefaultHandler_SetHostNames (IOleObject)
399 * The default handler's implementation of this method just stores
400 * the strings and returns S_OK.
402 * See Windows documentation for more details on IOleObject methods.
404 static HRESULT WINAPI DefaultHandler_SetHostNames(
405 IOleObject* iface,
406 LPCOLESTR szContainerApp,
407 LPCOLESTR szContainerObj)
409 DefaultHandler *This = impl_from_IOleObject(iface);
411 TRACE("(%p, %s, %s)\n",
412 iface,
413 debugstr_w(szContainerApp),
414 debugstr_w(szContainerObj));
416 if (object_is_running(This))
417 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
419 /* Be sure to cleanup before re-assigning the strings. */
420 HeapFree( GetProcessHeap(), 0, This->containerApp );
421 This->containerApp = NULL;
422 HeapFree( GetProcessHeap(), 0, This->containerObj );
423 This->containerObj = NULL;
425 if (szContainerApp)
427 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
428 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
429 strcpyW( This->containerApp, szContainerApp );
432 if (szContainerObj)
434 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
435 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
436 strcpyW( This->containerObj, szContainerObj );
438 return S_OK;
441 static void release_delegates(DefaultHandler *This)
443 if (This->pDataDelegate)
445 IDataObject_Release(This->pDataDelegate);
446 This->pDataDelegate = NULL;
448 if (This->pPSDelegate)
450 IPersistStorage_Release(This->pPSDelegate);
451 This->pPSDelegate = NULL;
453 if (This->pOleDelegate)
455 IOleObject_Release(This->pOleDelegate);
456 This->pOleDelegate = NULL;
460 /* undoes the work done by DefaultHandler_Run */
461 static void DefaultHandler_Stop(DefaultHandler *This)
463 if (!object_is_running(This))
464 return;
466 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
468 /* FIXME: call IOleCache_OnStop */
470 if (This->dataAdviseHolder)
471 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
473 This->object_state = object_state_not_running;
476 /************************************************************************
477 * DefaultHandler_Close (IOleObject)
479 * The default handler's implementation of this method is meaningless
480 * without a running server so it does nothing.
482 * See Windows documentation for more details on IOleObject methods.
484 static HRESULT WINAPI DefaultHandler_Close(
485 IOleObject* iface,
486 DWORD dwSaveOption)
488 DefaultHandler *This = impl_from_IOleObject(iface);
489 HRESULT hr;
491 TRACE("(%d)\n", dwSaveOption);
493 if (!object_is_running(This))
494 return S_OK;
496 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
498 DefaultHandler_Stop(This);
499 release_delegates(This);
501 return hr;
504 /************************************************************************
505 * DefaultHandler_SetMoniker (IOleObject)
507 * The default handler's implementation of this method does nothing.
509 * See Windows documentation for more details on IOleObject methods.
511 static HRESULT WINAPI DefaultHandler_SetMoniker(
512 IOleObject* iface,
513 DWORD dwWhichMoniker,
514 IMoniker* pmk)
516 DefaultHandler *This = impl_from_IOleObject(iface);
518 TRACE("(%p, %d, %p)\n",
519 iface,
520 dwWhichMoniker,
521 pmk);
523 if (object_is_running(This))
524 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
526 return S_OK;
529 /************************************************************************
530 * DefaultHandler_GetMoniker (IOleObject)
532 * Delegate this request to the client site if we have one.
534 * See Windows documentation for more details on IOleObject methods.
536 static HRESULT WINAPI DefaultHandler_GetMoniker(
537 IOleObject* iface,
538 DWORD dwAssign,
539 DWORD dwWhichMoniker,
540 IMoniker** ppmk)
542 DefaultHandler *This = impl_from_IOleObject(iface);
544 TRACE("(%p, %d, %d, %p)\n",
545 iface, dwAssign, dwWhichMoniker, ppmk);
547 if (object_is_running(This))
548 return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
549 ppmk);
551 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
552 if (This->clientSite)
554 return IOleClientSite_GetMoniker(This->clientSite,
555 dwAssign,
556 dwWhichMoniker,
557 ppmk);
561 return E_FAIL;
564 /************************************************************************
565 * DefaultHandler_InitFromData (IOleObject)
567 * This method is meaningless if the server is not running
569 * See Windows documentation for more details on IOleObject methods.
571 static HRESULT WINAPI DefaultHandler_InitFromData(
572 IOleObject* iface,
573 IDataObject* pDataObject,
574 BOOL fCreation,
575 DWORD dwReserved)
577 DefaultHandler *This = impl_from_IOleObject(iface);
579 TRACE("(%p, %p, %d, %d)\n",
580 iface, pDataObject, fCreation, dwReserved);
582 if (object_is_running(This))
583 return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
584 dwReserved);
585 return OLE_E_NOTRUNNING;
588 /************************************************************************
589 * DefaultHandler_GetClipboardData (IOleObject)
591 * This method is meaningless if the server is not running
593 * See Windows documentation for more details on IOleObject methods.
595 static HRESULT WINAPI DefaultHandler_GetClipboardData(
596 IOleObject* iface,
597 DWORD dwReserved,
598 IDataObject** ppDataObject)
600 DefaultHandler *This = impl_from_IOleObject(iface);
602 TRACE("(%p, %d, %p)\n",
603 iface, dwReserved, ppDataObject);
605 if (object_is_running(This))
606 return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
607 ppDataObject);
609 return OLE_E_NOTRUNNING;
612 static HRESULT WINAPI DefaultHandler_DoVerb(
613 IOleObject* iface,
614 LONG iVerb,
615 struct tagMSG* lpmsg,
616 IOleClientSite* pActiveSite,
617 LONG lindex,
618 HWND hwndParent,
619 LPCRECT lprcPosRect)
621 DefaultHandler *This = impl_from_IOleObject(iface);
622 IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
623 HRESULT hr;
625 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
627 hr = IRunnableObject_Run(pRunnableObj, NULL);
628 if (FAILED(hr)) return hr;
630 return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
631 lindex, hwndParent, lprcPosRect);
634 /************************************************************************
635 * DefaultHandler_EnumVerbs (IOleObject)
637 * The default handler implementation of this method simply delegates
638 * to OleRegEnumVerbs
640 * See Windows documentation for more details on IOleObject methods.
642 static HRESULT WINAPI DefaultHandler_EnumVerbs(
643 IOleObject* iface,
644 IEnumOLEVERB** ppEnumOleVerb)
646 DefaultHandler *This = impl_from_IOleObject(iface);
647 HRESULT hr = OLE_S_USEREG;
649 TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
651 if (object_is_running(This))
652 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
654 if (hr == OLE_S_USEREG)
655 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
656 else
657 return hr;
660 static HRESULT WINAPI DefaultHandler_Update(
661 IOleObject* iface)
663 DefaultHandler *This = impl_from_IOleObject(iface);
664 TRACE("(%p)\n", iface);
666 if (!object_is_running(This))
668 FIXME("Should run object\n");
669 return E_NOTIMPL;
671 return IOleObject_Update(This->pOleDelegate);
674 /************************************************************************
675 * DefaultHandler_IsUpToDate (IOleObject)
677 * This method is meaningless if the server is not running
679 * See Windows documentation for more details on IOleObject methods.
681 static HRESULT WINAPI DefaultHandler_IsUpToDate(
682 IOleObject* iface)
684 DefaultHandler *This = impl_from_IOleObject(iface);
685 TRACE("(%p)\n", iface);
687 if (object_is_running(This))
688 return IOleObject_IsUpToDate(This->pOleDelegate);
690 return OLE_E_NOTRUNNING;
693 /************************************************************************
694 * DefaultHandler_GetUserClassID (IOleObject)
696 * TODO: Map to a new class ID if emulation is active.
698 * See Windows documentation for more details on IOleObject methods.
700 static HRESULT WINAPI DefaultHandler_GetUserClassID(
701 IOleObject* iface,
702 CLSID* pClsid)
704 DefaultHandler *This = impl_from_IOleObject(iface);
706 TRACE("(%p, %p)\n", iface, pClsid);
708 if (object_is_running(This))
709 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
711 if (!pClsid)
712 return E_POINTER;
714 *pClsid = This->clsid;
716 return S_OK;
719 /************************************************************************
720 * DefaultHandler_GetUserType (IOleObject)
722 * The default handler implementation of this method simply delegates
723 * to OleRegGetUserType
725 * See Windows documentation for more details on IOleObject methods.
727 static HRESULT WINAPI DefaultHandler_GetUserType(
728 IOleObject* iface,
729 DWORD dwFormOfType,
730 LPOLESTR* pszUserType)
732 DefaultHandler *This = impl_from_IOleObject(iface);
734 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
735 if (object_is_running(This))
736 return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
738 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
741 /************************************************************************
742 * DefaultHandler_SetExtent (IOleObject)
744 * This method is meaningless if the server is not running
746 * See Windows documentation for more details on IOleObject methods.
748 static HRESULT WINAPI DefaultHandler_SetExtent(
749 IOleObject* iface,
750 DWORD dwDrawAspect,
751 SIZEL* psizel)
753 DefaultHandler *This = impl_from_IOleObject(iface);
755 TRACE("(%p, %x, (%d x %d))\n", iface,
756 dwDrawAspect, psizel->cx, psizel->cy);
758 if (object_is_running(This))
759 return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
761 return OLE_E_NOTRUNNING;
764 /************************************************************************
765 * DefaultHandler_GetExtent (IOleObject)
767 * The default handler's implementation of this method returns uses
768 * the cache to locate the aspect and extract the extent from it.
770 * See Windows documentation for more details on IOleObject methods.
772 static HRESULT WINAPI DefaultHandler_GetExtent(
773 IOleObject* iface,
774 DWORD dwDrawAspect,
775 SIZEL* psizel)
777 DVTARGETDEVICE* targetDevice;
778 IViewObject2* cacheView = NULL;
779 HRESULT hres;
781 DefaultHandler *This = impl_from_IOleObject(iface);
783 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
785 if (object_is_running(This))
786 return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
788 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
789 if (FAILED(hres))
790 return E_UNEXPECTED;
793 * Prepare the call to the cache's GetExtent method.
795 * Here we would build a valid DVTARGETDEVICE structure
796 * but, since we are calling into the data cache, we
797 * know its implementation and we'll skip this
798 * extra work until later.
800 targetDevice = NULL;
802 hres = IViewObject2_GetExtent(cacheView,
803 dwDrawAspect,
805 targetDevice,
806 psizel);
808 IViewObject2_Release(cacheView);
810 return hres;
813 /************************************************************************
814 * DefaultHandler_Advise (IOleObject)
816 * The default handler's implementation of this method simply
817 * delegates to the OleAdviseHolder.
819 * See Windows documentation for more details on IOleObject methods.
821 static HRESULT WINAPI DefaultHandler_Advise(
822 IOleObject* iface,
823 IAdviseSink* pAdvSink,
824 DWORD* pdwConnection)
826 HRESULT hres = S_OK;
827 DefaultHandler *This = impl_from_IOleObject(iface);
829 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
831 /* Make sure we have an advise holder before we start. */
832 if (!This->oleAdviseHolder)
833 hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
835 if (SUCCEEDED(hres))
836 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
837 pAdvSink,
838 pdwConnection);
840 return hres;
843 /************************************************************************
844 * DefaultHandler_Unadvise (IOleObject)
846 * The default handler's implementation of this method simply
847 * delegates to the OleAdviseHolder.
849 * See Windows documentation for more details on IOleObject methods.
851 static HRESULT WINAPI DefaultHandler_Unadvise(
852 IOleObject* iface,
853 DWORD dwConnection)
855 DefaultHandler *This = impl_from_IOleObject(iface);
857 TRACE("(%p, %d)\n", iface, dwConnection);
860 * If we don't have an advise holder yet, it means we don't have
861 * a connection.
863 if (!This->oleAdviseHolder)
864 return OLE_E_NOCONNECTION;
866 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
867 dwConnection);
870 /************************************************************************
871 * DefaultHandler_EnumAdvise (IOleObject)
873 * The default handler's implementation of this method simply
874 * delegates to the OleAdviseHolder.
876 * See Windows documentation for more details on IOleObject methods.
878 static HRESULT WINAPI DefaultHandler_EnumAdvise(
879 IOleObject* iface,
880 IEnumSTATDATA** ppenumAdvise)
882 DefaultHandler *This = impl_from_IOleObject(iface);
884 TRACE("(%p, %p)\n", iface, ppenumAdvise);
886 if (!ppenumAdvise)
887 return E_POINTER;
889 *ppenumAdvise = NULL;
891 if (!This->oleAdviseHolder)
892 return S_OK;
894 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
897 /************************************************************************
898 * DefaultHandler_GetMiscStatus (IOleObject)
900 * The default handler's implementation of this method simply delegates
901 * to OleRegGetMiscStatus.
903 * See Windows documentation for more details on IOleObject methods.
905 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
906 IOleObject* iface,
907 DWORD dwAspect,
908 DWORD* pdwStatus)
910 HRESULT hres;
911 DefaultHandler *This = impl_from_IOleObject(iface);
913 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
915 if (object_is_running(This))
916 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
918 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
920 if (FAILED(hres))
921 *pdwStatus = 0;
923 return hres;
926 /************************************************************************
927 * DefaultHandler_SetColorScheme (IOleObject)
929 * This method is meaningless if the server is not running
931 * See Windows documentation for more details on IOleObject methods.
933 static HRESULT WINAPI DefaultHandler_SetColorScheme(
934 IOleObject* iface,
935 struct tagLOGPALETTE* pLogpal)
937 DefaultHandler *This = impl_from_IOleObject(iface);
939 TRACE("(%p, %p))\n", iface, pLogpal);
941 if (object_is_running(This))
942 return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
944 return OLE_E_NOTRUNNING;
947 /*********************************************************
948 * Methods implementation for the IDataObject part of
949 * the DefaultHandler class.
952 /************************************************************************
953 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
955 * See Windows documentation for more details on IUnknown methods.
957 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
958 IDataObject* iface,
959 REFIID riid,
960 void** ppvObject)
962 DefaultHandler *This = impl_from_IDataObject(iface);
964 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
967 /************************************************************************
968 * DefaultHandler_IDataObject_AddRef (IUnknown)
970 * See Windows documentation for more details on IUnknown methods.
972 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
973 IDataObject* iface)
975 DefaultHandler *This = impl_from_IDataObject(iface);
977 return IUnknown_AddRef(This->outerUnknown);
980 /************************************************************************
981 * DefaultHandler_IDataObject_Release (IUnknown)
983 * See Windows documentation for more details on IUnknown methods.
985 static ULONG WINAPI DefaultHandler_IDataObject_Release(
986 IDataObject* iface)
988 DefaultHandler *This = impl_from_IDataObject(iface);
990 return IUnknown_Release(This->outerUnknown);
993 /************************************************************************
994 * DefaultHandler_GetData
996 * Get Data from a source dataobject using format pformatetcIn->cfFormat
997 * See Windows documentation for more details on GetData.
998 * Default handler's implementation of this method delegates to the cache.
1000 static HRESULT WINAPI DefaultHandler_GetData(
1001 IDataObject* iface,
1002 LPFORMATETC pformatetcIn,
1003 STGMEDIUM* pmedium)
1005 IDataObject* cacheDataObject = NULL;
1006 HRESULT hres;
1008 DefaultHandler *This = impl_from_IDataObject(iface);
1010 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
1012 hres = IUnknown_QueryInterface(This->dataCache,
1013 &IID_IDataObject,
1014 (void**)&cacheDataObject);
1016 if (FAILED(hres))
1017 return E_UNEXPECTED;
1019 hres = IDataObject_GetData(cacheDataObject,
1020 pformatetcIn,
1021 pmedium);
1023 IDataObject_Release(cacheDataObject);
1025 if (FAILED(hres) && This->pDataDelegate)
1026 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1028 return hres;
1031 static HRESULT WINAPI DefaultHandler_GetDataHere(
1032 IDataObject* iface,
1033 LPFORMATETC pformatetc,
1034 STGMEDIUM* pmedium)
1036 FIXME(": Stub\n");
1037 return E_NOTIMPL;
1040 /************************************************************************
1041 * DefaultHandler_QueryGetData (IDataObject)
1043 * The default handler's implementation of this method delegates to
1044 * the cache.
1046 * See Windows documentation for more details on IDataObject methods.
1048 static HRESULT WINAPI DefaultHandler_QueryGetData(
1049 IDataObject* iface,
1050 LPFORMATETC pformatetc)
1052 IDataObject* cacheDataObject = NULL;
1053 HRESULT hres;
1055 DefaultHandler *This = impl_from_IDataObject(iface);
1057 TRACE("(%p, %p)\n", iface, pformatetc);
1059 hres = IUnknown_QueryInterface(This->dataCache,
1060 &IID_IDataObject,
1061 (void**)&cacheDataObject);
1063 if (FAILED(hres))
1064 return E_UNEXPECTED;
1066 hres = IDataObject_QueryGetData(cacheDataObject,
1067 pformatetc);
1069 IDataObject_Release(cacheDataObject);
1071 if (FAILED(hres) && This->pDataDelegate)
1072 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1074 return hres;
1077 /************************************************************************
1078 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1080 * This method is meaningless if the server is not running
1082 * See Windows documentation for more details on IDataObject methods.
1084 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1085 IDataObject* iface,
1086 LPFORMATETC pformatetcIn,
1087 LPFORMATETC pformatetcOut)
1089 DefaultHandler *This = impl_from_IDataObject(iface);
1091 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1093 if (!This->pDataDelegate)
1094 return OLE_E_NOTRUNNING;
1096 return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1099 /************************************************************************
1100 * DefaultHandler_SetData (IDataObject)
1102 * The default handler's implementation of this method delegates to
1103 * the cache.
1105 * See Windows documentation for more details on IDataObject methods.
1107 static HRESULT WINAPI DefaultHandler_SetData(
1108 IDataObject* iface,
1109 LPFORMATETC pformatetc,
1110 STGMEDIUM* pmedium,
1111 BOOL fRelease)
1113 DefaultHandler *This = impl_from_IDataObject(iface);
1114 IDataObject* cacheDataObject = NULL;
1115 HRESULT hres;
1117 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1119 hres = IUnknown_QueryInterface(This->dataCache,
1120 &IID_IDataObject,
1121 (void**)&cacheDataObject);
1123 if (FAILED(hres))
1124 return E_UNEXPECTED;
1126 hres = IDataObject_SetData(cacheDataObject,
1127 pformatetc,
1128 pmedium,
1129 fRelease);
1131 IDataObject_Release(cacheDataObject);
1133 return hres;
1136 /************************************************************************
1137 * DefaultHandler_EnumFormatEtc (IDataObject)
1139 * The default handler's implementation of This method simply delegates
1140 * to OleRegEnumFormatEtc.
1142 * See Windows documentation for more details on IDataObject methods.
1144 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1145 IDataObject* iface,
1146 DWORD dwDirection,
1147 IEnumFORMATETC** ppenumFormatEtc)
1149 HRESULT hres;
1150 DefaultHandler *This = impl_from_IDataObject(iface);
1152 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1154 hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1156 return hres;
1159 /************************************************************************
1160 * DefaultHandler_DAdvise (IDataObject)
1162 * The default handler's implementation of this method simply
1163 * delegates to the DataAdviseHolder.
1165 * See Windows documentation for more details on IDataObject methods.
1167 static HRESULT WINAPI DefaultHandler_DAdvise(
1168 IDataObject* iface,
1169 FORMATETC* pformatetc,
1170 DWORD advf,
1171 IAdviseSink* pAdvSink,
1172 DWORD* pdwConnection)
1174 HRESULT hres = S_OK;
1175 DefaultHandler *This = impl_from_IDataObject(iface);
1177 TRACE("(%p, %p, %d, %p, %p)\n",
1178 iface, pformatetc, advf, pAdvSink, pdwConnection);
1180 /* Make sure we have a data advise holder before we start. */
1181 if (!This->dataAdviseHolder)
1183 hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1184 if (SUCCEEDED(hres) && This->pDataDelegate)
1185 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1188 if (SUCCEEDED(hres))
1189 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1190 iface,
1191 pformatetc,
1192 advf,
1193 pAdvSink,
1194 pdwConnection);
1196 return hres;
1199 /************************************************************************
1200 * DefaultHandler_DUnadvise (IDataObject)
1202 * The default handler's implementation of this method simply
1203 * delegates to the DataAdviseHolder.
1205 * See Windows documentation for more details on IDataObject methods.
1207 static HRESULT WINAPI DefaultHandler_DUnadvise(
1208 IDataObject* iface,
1209 DWORD dwConnection)
1211 DefaultHandler *This = impl_from_IDataObject(iface);
1213 TRACE("(%p, %d)\n", iface, dwConnection);
1216 * If we don't have a data advise holder yet, it means that
1217 * we don't have any connections..
1219 if (!This->dataAdviseHolder)
1220 return OLE_E_NOCONNECTION;
1222 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1223 dwConnection);
1226 /************************************************************************
1227 * DefaultHandler_EnumDAdvise (IDataObject)
1229 * The default handler's implementation of this method simply
1230 * delegates to the DataAdviseHolder.
1232 * See Windows documentation for more details on IDataObject methods.
1234 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1235 IDataObject* iface,
1236 IEnumSTATDATA** ppenumAdvise)
1238 DefaultHandler *This = impl_from_IDataObject(iface);
1240 TRACE("(%p, %p)\n", iface, ppenumAdvise);
1242 if (!ppenumAdvise)
1243 return E_POINTER;
1245 *ppenumAdvise = NULL;
1247 /* If we have a data advise holder object, delegate. */
1248 if (This->dataAdviseHolder)
1249 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1250 ppenumAdvise);
1252 return S_OK;
1255 /*********************************************************
1256 * Methods implementation for the IRunnableObject part
1257 * of the DefaultHandler class.
1260 /************************************************************************
1261 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1263 * See Windows documentation for more details on IUnknown methods.
1265 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1266 IRunnableObject* iface,
1267 REFIID riid,
1268 void** ppvObject)
1270 DefaultHandler *This = impl_from_IRunnableObject(iface);
1272 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1275 /************************************************************************
1276 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1278 * See Windows documentation for more details on IUnknown methods.
1280 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1281 IRunnableObject* iface)
1283 DefaultHandler *This = impl_from_IRunnableObject(iface);
1285 return IUnknown_AddRef(This->outerUnknown);
1288 /************************************************************************
1289 * DefaultHandler_IRunnableObject_Release (IUnknown)
1291 * See Windows documentation for more details on IUnknown methods.
1293 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1294 IRunnableObject* iface)
1296 DefaultHandler *This = impl_from_IRunnableObject(iface);
1298 return IUnknown_Release(This->outerUnknown);
1301 /************************************************************************
1302 * DefaultHandler_GetRunningClass (IRunnableObject)
1304 * See Windows documentation for more details on IRunnableObject methods.
1306 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1307 IRunnableObject* iface,
1308 LPCLSID lpClsid)
1310 FIXME("()\n");
1311 return S_OK;
1314 static HRESULT WINAPI DefaultHandler_Run(
1315 IRunnableObject* iface,
1316 IBindCtx* pbc)
1318 DefaultHandler *This = impl_from_IRunnableObject(iface);
1319 HRESULT hr;
1321 FIXME("(%p): semi-stub\n", pbc);
1323 /* already running? if so nothing to do */
1324 if (object_is_running(This))
1325 return S_OK;
1327 release_delegates(This);
1329 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1330 &IID_IOleObject, (void **)&This->pOleDelegate);
1331 if (FAILED(hr))
1332 return hr;
1334 This->object_state = object_state_running;
1336 hr = IOleObject_Advise(This->pOleDelegate,
1337 (IAdviseSink *)&This->lpvtblIAdviseSink,
1338 &This->dwAdvConn);
1340 if (SUCCEEDED(hr) && This->clientSite)
1341 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1343 if (SUCCEEDED(hr))
1345 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1346 (void **)&This->pPSDelegate);
1347 if (This->pPSDelegate)
1349 if(This->storage_state == storage_state_initialised)
1350 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1351 else if(This->storage_state == storage_state_loaded)
1352 hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1356 if (SUCCEEDED(hr) && This->containerApp)
1357 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1358 This->containerObj);
1360 /* FIXME: do more stuff here:
1361 * - IOleObject_GetMiscStatus
1362 * - IOleObject_GetMoniker
1363 * - IOleCache_OnRun
1366 if (SUCCEEDED(hr))
1367 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1368 (void **)&This->pDataDelegate);
1370 if (SUCCEEDED(hr) && This->dataAdviseHolder)
1371 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1373 if (FAILED(hr))
1375 DefaultHandler_Stop(This);
1376 release_delegates(This);
1379 return hr;
1382 /************************************************************************
1383 * DefaultHandler_IsRunning (IRunnableObject)
1385 * See Windows documentation for more details on IRunnableObject methods.
1387 static BOOL WINAPI DefaultHandler_IsRunning(
1388 IRunnableObject* iface)
1390 DefaultHandler *This = impl_from_IRunnableObject(iface);
1392 TRACE("()\n");
1394 if (This->object_state == object_state_running)
1395 return TRUE;
1396 else
1397 return FALSE;
1400 /************************************************************************
1401 * DefaultHandler_LockRunning (IRunnableObject)
1403 * See Windows documentation for more details on IRunnableObject methods.
1405 static HRESULT WINAPI DefaultHandler_LockRunning(
1406 IRunnableObject* iface,
1407 BOOL fLock,
1408 BOOL fLastUnlockCloses)
1410 FIXME("()\n");
1411 return S_OK;
1414 /************************************************************************
1415 * DefaultHandler_SetContainedObject (IRunnableObject)
1417 * See Windows documentation for more details on IRunnableObject methods.
1419 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1420 IRunnableObject* iface,
1421 BOOL fContained)
1423 FIXME("()\n");
1424 return S_OK;
1427 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1428 IAdviseSink *iface,
1429 REFIID riid,
1430 void **ppvObject)
1432 if (IsEqualIID(riid, &IID_IUnknown) ||
1433 IsEqualIID(riid, &IID_IAdviseSink))
1435 *ppvObject = iface;
1436 IAdviseSink_AddRef(iface);
1437 return S_OK;
1440 return E_NOINTERFACE;
1443 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1444 IAdviseSink *iface)
1446 DefaultHandler *This = impl_from_IAdviseSink(iface);
1448 return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1451 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1452 IAdviseSink *iface)
1454 DefaultHandler *This = impl_from_IAdviseSink(iface);
1456 return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1459 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1460 IAdviseSink *iface,
1461 FORMATETC *pFormatetc,
1462 STGMEDIUM *pStgmed)
1464 FIXME(": stub\n");
1467 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1468 IAdviseSink *iface,
1469 DWORD dwAspect,
1470 LONG lindex)
1472 FIXME(": stub\n");
1475 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1476 IAdviseSink *iface,
1477 IMoniker *pmk)
1479 DefaultHandler *This = impl_from_IAdviseSink(iface);
1481 TRACE("(%p)\n", pmk);
1483 if (This->oleAdviseHolder)
1484 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1487 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1488 IAdviseSink *iface)
1490 DefaultHandler *This = impl_from_IAdviseSink(iface);
1492 TRACE("()\n");
1494 if (This->oleAdviseHolder)
1495 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1498 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1499 IAdviseSink *iface)
1501 DefaultHandler *This = impl_from_IAdviseSink(iface);
1503 TRACE("()\n");
1505 if (This->oleAdviseHolder)
1506 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1508 DefaultHandler_Stop(This);
1512 /************************************************************************
1513 * DefaultHandler_IPersistStorage_QueryInterface
1516 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1517 IPersistStorage* iface,
1518 REFIID riid,
1519 void** ppvObject)
1521 DefaultHandler *This = impl_from_IPersistStorage(iface);
1523 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1526 /************************************************************************
1527 * DefaultHandler_IPersistStorage_AddRef
1530 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1531 IPersistStorage* iface)
1533 DefaultHandler *This = impl_from_IPersistStorage(iface);
1535 return IUnknown_AddRef(This->outerUnknown);
1538 /************************************************************************
1539 * DefaultHandler_IPersistStorage_Release
1542 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1543 IPersistStorage* iface)
1545 DefaultHandler *This = impl_from_IPersistStorage(iface);
1547 return IUnknown_Release(This->outerUnknown);
1550 /************************************************************************
1551 * DefaultHandler_IPersistStorage_GetClassID
1554 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1555 IPersistStorage* iface,
1556 CLSID* clsid)
1558 DefaultHandler *This = impl_from_IPersistStorage(iface);
1559 HRESULT hr;
1561 TRACE("(%p)->(%p)\n", iface, clsid);
1563 if(object_is_running(This))
1564 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1565 else
1566 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1568 return hr;
1571 /************************************************************************
1572 * DefaultHandler_IPersistStorage_IsDirty
1575 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1576 IPersistStorage* iface)
1578 DefaultHandler *This = impl_from_IPersistStorage(iface);
1579 HRESULT hr;
1581 TRACE("(%p)\n", iface);
1583 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1584 if(hr != S_FALSE) return hr;
1586 if(object_is_running(This))
1587 hr = IPersistStorage_IsDirty(This->pPSDelegate);
1589 return hr;
1592 /***********************************************************************
1593 * init_ole_stream
1595 * Creates the '\1Ole' stream.
1596 * The format of this stream is as follows:
1598 * DWORD Version == 0x02000001
1599 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1600 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1601 * supplied by the app that creates the data structure. May be
1602 * ignored on processing].
1604 * DWORD Reserved == 0
1605 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1606 * CLSID clsid - class id of object capable of processing the moniker
1607 * BYTE data[] - moniker data for a link
1610 static const WCHAR OleStream[] = {1,'O','l','e',0};
1611 typedef struct
1613 DWORD version;
1614 DWORD flags;
1615 DWORD link_update_opt;
1616 DWORD res;
1617 DWORD moniker_size;
1618 } ole_stream_header_t;
1619 static const DWORD ole_stream_version = 0x02000001;
1621 static void init_ole_stream(IStorage *storage)
1623 HRESULT hr;
1624 IStream *stream;
1626 hr = IStorage_CreateStream(storage, OleStream, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream);
1627 if(SUCCEEDED(hr))
1629 DWORD written;
1630 ole_stream_header_t header;
1632 header.version = ole_stream_version;
1633 header.flags = 0;
1634 header.link_update_opt = 0;
1635 header.res = 0;
1636 header.moniker_size = 0;
1638 IStream_Write(stream, &header, sizeof(header), &written);
1639 IStream_Release(stream);
1641 return;
1644 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1646 IStream *stream;
1647 HRESULT hr;
1649 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1651 if(SUCCEEDED(hr))
1653 DWORD read;
1654 ole_stream_header_t header;
1656 hr = IStream_Read(stream, &header, sizeof(header), &read);
1657 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1659 if(header.flags & 1)
1661 /* FIXME: Read the moniker and deal with the link */
1662 FIXME("Linked objects are not supported yet\n");
1665 else
1667 WARN("Incorrect OleStream header\n");
1668 hr = DV_E_CLIPFORMAT;
1670 IStream_Release(stream);
1672 else
1674 init_ole_stream(storage);
1675 hr = S_OK;
1677 return hr;
1680 /************************************************************************
1681 * DefaultHandler_IPersistStorage_InitNew
1684 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1685 IPersistStorage* iface,
1686 IStorage* pStg)
1688 DefaultHandler *This = impl_from_IPersistStorage(iface);
1689 HRESULT hr;
1691 TRACE("(%p)->(%p)\n", iface, pStg);
1692 init_ole_stream(pStg);
1694 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1696 if(SUCCEEDED(hr) && object_is_running(This))
1697 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1699 if(SUCCEEDED(hr))
1701 IStorage_AddRef(pStg);
1702 This->storage = pStg;
1703 This->storage_state = storage_state_initialised;
1706 return hr;
1710 /************************************************************************
1711 * DefaultHandler_IPersistStorage_Load
1714 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1715 IPersistStorage* iface,
1716 IStorage* pStg)
1718 DefaultHandler *This = impl_from_IPersistStorage(iface);
1719 HRESULT hr;
1721 TRACE("(%p)->(%p)\n", iface, pStg);
1723 hr = load_ole_stream(This, pStg);
1725 if(SUCCEEDED(hr))
1726 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1728 if(SUCCEEDED(hr) && object_is_running(This))
1729 hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1731 if(SUCCEEDED(hr))
1733 IStorage_AddRef(pStg);
1734 This->storage = pStg;
1735 This->storage_state = storage_state_loaded;
1737 return hr;
1741 /************************************************************************
1742 * DefaultHandler_IPersistStorage_Save
1745 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1746 IPersistStorage* iface,
1747 IStorage* pStgSave,
1748 BOOL fSameAsLoad)
1750 DefaultHandler *This = impl_from_IPersistStorage(iface);
1751 HRESULT hr;
1753 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1755 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1756 if(SUCCEEDED(hr) && object_is_running(This))
1757 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1759 return hr;
1763 /************************************************************************
1764 * DefaultHandler_IPersistStorage_SaveCompleted
1767 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1768 IPersistStorage* iface,
1769 IStorage* pStgNew)
1771 DefaultHandler *This = impl_from_IPersistStorage(iface);
1772 HRESULT hr;
1774 TRACE("(%p)->(%p)\n", iface, pStgNew);
1776 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1778 if(SUCCEEDED(hr) && object_is_running(This))
1779 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1781 if(pStgNew)
1783 IStorage_AddRef(pStgNew);
1784 if(This->storage) IStorage_Release(This->storage);
1785 This->storage = pStgNew;
1786 This->storage_state = storage_state_loaded;
1789 return hr;
1793 /************************************************************************
1794 * DefaultHandler_IPersistStorage_HandsOffStorage
1797 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1798 IPersistStorage* iface)
1800 DefaultHandler *This = impl_from_IPersistStorage(iface);
1801 HRESULT hr;
1803 TRACE("(%p)\n", iface);
1805 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1807 if(SUCCEEDED(hr) && object_is_running(This))
1808 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1810 if(This->storage) IStorage_Release(This->storage);
1811 This->storage = NULL;
1812 This->storage_state = storage_state_uninitialised;
1814 return hr;
1819 * Virtual function tables for the DefaultHandler class.
1821 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1823 DefaultHandler_QueryInterface,
1824 DefaultHandler_AddRef,
1825 DefaultHandler_Release,
1826 DefaultHandler_SetClientSite,
1827 DefaultHandler_GetClientSite,
1828 DefaultHandler_SetHostNames,
1829 DefaultHandler_Close,
1830 DefaultHandler_SetMoniker,
1831 DefaultHandler_GetMoniker,
1832 DefaultHandler_InitFromData,
1833 DefaultHandler_GetClipboardData,
1834 DefaultHandler_DoVerb,
1835 DefaultHandler_EnumVerbs,
1836 DefaultHandler_Update,
1837 DefaultHandler_IsUpToDate,
1838 DefaultHandler_GetUserClassID,
1839 DefaultHandler_GetUserType,
1840 DefaultHandler_SetExtent,
1841 DefaultHandler_GetExtent,
1842 DefaultHandler_Advise,
1843 DefaultHandler_Unadvise,
1844 DefaultHandler_EnumAdvise,
1845 DefaultHandler_GetMiscStatus,
1846 DefaultHandler_SetColorScheme
1849 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1851 DefaultHandler_NDIUnknown_QueryInterface,
1852 DefaultHandler_NDIUnknown_AddRef,
1853 DefaultHandler_NDIUnknown_Release,
1856 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1858 DefaultHandler_IDataObject_QueryInterface,
1859 DefaultHandler_IDataObject_AddRef,
1860 DefaultHandler_IDataObject_Release,
1861 DefaultHandler_GetData,
1862 DefaultHandler_GetDataHere,
1863 DefaultHandler_QueryGetData,
1864 DefaultHandler_GetCanonicalFormatEtc,
1865 DefaultHandler_SetData,
1866 DefaultHandler_EnumFormatEtc,
1867 DefaultHandler_DAdvise,
1868 DefaultHandler_DUnadvise,
1869 DefaultHandler_EnumDAdvise
1872 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1874 DefaultHandler_IRunnableObject_QueryInterface,
1875 DefaultHandler_IRunnableObject_AddRef,
1876 DefaultHandler_IRunnableObject_Release,
1877 DefaultHandler_GetRunningClass,
1878 DefaultHandler_Run,
1879 DefaultHandler_IsRunning,
1880 DefaultHandler_LockRunning,
1881 DefaultHandler_SetContainedObject
1884 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1886 DefaultHandler_IAdviseSink_QueryInterface,
1887 DefaultHandler_IAdviseSink_AddRef,
1888 DefaultHandler_IAdviseSink_Release,
1889 DefaultHandler_IAdviseSink_OnDataChange,
1890 DefaultHandler_IAdviseSink_OnViewChange,
1891 DefaultHandler_IAdviseSink_OnRename,
1892 DefaultHandler_IAdviseSink_OnSave,
1893 DefaultHandler_IAdviseSink_OnClose
1896 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
1898 DefaultHandler_IPersistStorage_QueryInterface,
1899 DefaultHandler_IPersistStorage_AddRef,
1900 DefaultHandler_IPersistStorage_Release,
1901 DefaultHandler_IPersistStorage_GetClassID,
1902 DefaultHandler_IPersistStorage_IsDirty,
1903 DefaultHandler_IPersistStorage_InitNew,
1904 DefaultHandler_IPersistStorage_Load,
1905 DefaultHandler_IPersistStorage_Save,
1906 DefaultHandler_IPersistStorage_SaveCompleted,
1907 DefaultHandler_IPersistStorage_HandsOffStorage
1910 /*********************************************************
1911 * Methods implementation for the DefaultHandler class.
1913 static DefaultHandler* DefaultHandler_Construct(
1914 REFCLSID clsid,
1915 LPUNKNOWN pUnkOuter,
1916 DWORD flags,
1917 IClassFactory *pCF)
1919 DefaultHandler* This = NULL;
1920 HRESULT hr;
1922 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1924 if (!This)
1925 return This;
1927 This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1928 This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1929 This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1930 This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1931 This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1932 This->lpvtblIPersistStorage = &DefaultHandler_IPersistStorage_VTable;
1934 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) ? TRUE : FALSE;
1937 * Start with one reference count. The caller of this function
1938 * must release the interface pointer when it is done.
1940 This->ref = 1;
1943 * Initialize the outer unknown
1944 * We don't keep a reference on the outer unknown since, the way
1945 * aggregation works, our lifetime is at least as large as its
1946 * lifetime.
1948 if (!pUnkOuter)
1949 pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1951 This->outerUnknown = pUnkOuter;
1954 * Create a datacache object.
1955 * We aggregate with the datacache. Make sure we pass our outer
1956 * unknown as the datacache's outer unknown.
1958 hr = CreateDataCache(This->outerUnknown,
1959 clsid,
1960 &IID_IUnknown,
1961 (void**)&This->dataCache);
1962 if(SUCCEEDED(hr))
1964 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
1965 /* keeping a reference to This->dataCache_PersistStg causes us to keep a
1966 * reference on the outer object */
1967 if (SUCCEEDED(hr))
1968 IUnknown_Release(This->outerUnknown);
1969 else
1970 IUnknown_Release(This->dataCache);
1972 if(FAILED(hr))
1974 ERR("Unexpected error creating data cache\n");
1975 HeapFree(GetProcessHeap(), 0, This);
1976 return NULL;
1979 This->clsid = *clsid;
1980 This->clientSite = NULL;
1981 This->oleAdviseHolder = NULL;
1982 This->dataAdviseHolder = NULL;
1983 This->containerApp = NULL;
1984 This->containerObj = NULL;
1985 This->pOleDelegate = NULL;
1986 This->pPSDelegate = NULL;
1987 This->pDataDelegate = NULL;
1988 This->object_state = object_state_not_running;
1990 This->dwAdvConn = 0;
1991 This->storage = NULL;
1992 This->storage_state = storage_state_uninitialised;
1994 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
1996 HRESULT hr;
1997 This->pCFObject = NULL;
1998 if (pCF)
1999 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
2000 else
2001 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
2002 &IID_IOleObject, (void **)&This->pOleDelegate);
2003 if (SUCCEEDED(hr))
2004 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
2005 if (SUCCEEDED(hr))
2006 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
2007 if (SUCCEEDED(hr))
2008 This->object_state = object_state_running;
2009 if (FAILED(hr))
2010 WARN("object creation failed with error %08x\n", hr);
2012 else
2014 This->pCFObject = pCF;
2015 if (pCF) IClassFactory_AddRef(pCF);
2018 return This;
2021 static void DefaultHandler_Destroy(
2022 DefaultHandler* This)
2024 TRACE("(%p)\n", This);
2026 /* AddRef/Release may be called on this object during destruction.
2027 * Prevent the object being destroyed recursively by artificially raising
2028 * the reference count. */
2029 This->ref = 10000;
2031 /* release delegates */
2032 DefaultHandler_Stop(This);
2033 release_delegates(This);
2035 HeapFree( GetProcessHeap(), 0, This->containerApp );
2036 This->containerApp = NULL;
2037 HeapFree( GetProcessHeap(), 0, This->containerObj );
2038 This->containerObj = NULL;
2040 if (This->dataCache)
2042 /* to balance out the release of dataCache_PersistStg which will result
2043 * in a reference being released from the outer unknown */
2044 IUnknown_AddRef(This->outerUnknown);
2045 IPersistStorage_Release(This->dataCache_PersistStg);
2046 IUnknown_Release(This->dataCache);
2047 This->dataCache_PersistStg = NULL;
2048 This->dataCache = NULL;
2051 if (This->clientSite)
2053 IOleClientSite_Release(This->clientSite);
2054 This->clientSite = NULL;
2057 if (This->oleAdviseHolder)
2059 IOleAdviseHolder_Release(This->oleAdviseHolder);
2060 This->oleAdviseHolder = NULL;
2063 if (This->dataAdviseHolder)
2065 IDataAdviseHolder_Release(This->dataAdviseHolder);
2066 This->dataAdviseHolder = NULL;
2069 if (This->storage)
2071 IStorage_Release(This->storage);
2072 This->storage = NULL;
2075 if (This->pCFObject)
2077 IClassFactory_Release(This->pCFObject);
2078 This->pCFObject = NULL;
2081 HeapFree(GetProcessHeap(), 0, This);
2084 /******************************************************************************
2085 * OleCreateEmbeddingHelper [OLE32.@]
2087 HRESULT WINAPI OleCreateEmbeddingHelper(
2088 REFCLSID clsid,
2089 LPUNKNOWN pUnkOuter,
2090 DWORD flags,
2091 IClassFactory *pCF,
2092 REFIID riid,
2093 LPVOID* ppvObj)
2095 DefaultHandler* newHandler = NULL;
2096 HRESULT hr = S_OK;
2098 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2100 if (!ppvObj)
2101 return E_POINTER;
2103 *ppvObj = NULL;
2106 * If This handler is constructed for aggregation, make sure
2107 * the caller is requesting the IUnknown interface.
2108 * This is necessary because it's the only time the non-delegating
2109 * IUnknown pointer can be returned to the outside.
2111 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2112 return CLASS_E_NOAGGREGATION;
2115 * Try to construct a new instance of the class.
2117 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2119 if (!newHandler)
2120 return E_OUTOFMEMORY;
2123 * Make sure it supports the interface required by the caller.
2125 hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
2128 * Release the reference obtained in the constructor. If
2129 * the QueryInterface was unsuccessful, it will free the class.
2131 IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
2133 return hr;
2137 /******************************************************************************
2138 * OleCreateDefaultHandler [OLE32.@]
2140 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
2141 REFIID riid, LPVOID* ppvObj)
2143 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
2144 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
2145 NULL, riid, ppvObj);
2148 typedef struct HandlerCF
2150 const IClassFactoryVtbl *lpVtbl;
2151 LONG refs;
2152 CLSID clsid;
2153 } HandlerCF;
2155 static HRESULT WINAPI
2156 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
2158 *ppv = NULL;
2159 if (IsEqualIID(riid,&IID_IUnknown) ||
2160 IsEqualIID(riid,&IID_IClassFactory))
2162 *ppv = iface;
2163 IClassFactory_AddRef(iface);
2164 return S_OK;
2166 return E_NOINTERFACE;
2169 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
2171 HandlerCF *This = (HandlerCF *)iface;
2172 return InterlockedIncrement(&This->refs);
2175 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
2177 HandlerCF *This = (HandlerCF *)iface;
2178 ULONG refs = InterlockedDecrement(&This->refs);
2179 if (!refs)
2180 HeapFree(GetProcessHeap(), 0, This);
2181 return refs;
2184 static HRESULT WINAPI
2185 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
2186 REFIID riid, LPVOID *ppv)
2188 HandlerCF *This = (HandlerCF *)iface;
2189 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
2192 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
2194 FIXME("(%d), stub!\n",fLock);
2195 return S_OK;
2198 static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
2199 HandlerCF_QueryInterface,
2200 HandlerCF_AddRef,
2201 HandlerCF_Release,
2202 HandlerCF_CreateInstance,
2203 HandlerCF_LockServer
2206 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
2208 HRESULT hr;
2209 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2210 if (!This) return E_OUTOFMEMORY;
2211 This->lpVtbl = &HandlerClassFactoryVtbl;
2212 This->refs = 0;
2213 This->clsid = *rclsid;
2215 hr = IUnknown_QueryInterface((IUnknown *)&This->lpVtbl, riid, ppv);
2216 if (FAILED(hr))
2217 HeapFree(GetProcessHeap(), 0, This);
2219 return hr;