Implement IOleObject_DoVerb function by running the object and then
[wine] / dlls / ole32 / defaulthandler.c
1 /*
2  *      OLE 2 default object handler
3  *
4  *      Copyright 1999  Francis Beaudet
5  *      Copyright 2000  Abey George
6  *
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.
11  *
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.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
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.
26  *
27  *    All the implementation details are taken from: Inside OLE
28  *    second edition by Kraig Brockschmidt,
29  *
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
35  *
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.
40  *
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.
44  *
45  * - All the methods related to notification and advise sinks are
46  *   in place but no notifications are sent to the sinks yet.
47  */
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <string.h>
51
52 #define COBJMACROS
53
54 #include "windef.h"
55 #include "winbase.h"
56 #include "winuser.h"
57 #include "winerror.h"
58 #include "ole2.h"
59
60 #include "compobj_private.h"
61
62 #include "wine/unicode.h"
63 #include "wine/debug.h"
64
65 WINE_DEFAULT_DEBUG_CHANNEL(ole);
66
67 /****************************************************************************
68  * DefaultHandler
69  *
70  */
71 struct DefaultHandler
72 {
73   const IOleObjectVtbl*      lpVtbl;
74   const IUnknownVtbl*        lpvtblIUnknown;
75   const IDataObjectVtbl*     lpvtblIDataObject;
76   const IRunnableObjectVtbl* lpvtblIRunnableObject;
77   const IAdviseSinkVtbl     *lpvtblIAdviseSink;
78
79   /* Reference count of this object */
80   LONG ref;
81
82   /* IUnknown implementation of the outer object. */
83   IUnknown* outerUnknown;
84
85   /* Class Id that this handler object represents. */
86   CLSID clsid;
87
88   /* IUnknown implementation of the datacache. */
89   IUnknown* dataCache;
90
91   /* Client site for the embedded object. */
92   IOleClientSite* clientSite;
93
94   /*
95    * The IOleAdviseHolder maintains the connections
96    * on behalf of the default handler.
97    */
98   IOleAdviseHolder* oleAdviseHolder;
99
100   /*
101    * The IDataAdviseHolder maintains the data
102    * connections on behalf of the default handler.
103    */
104   IDataAdviseHolder* dataAdviseHolder;
105
106   /* Name of the container and object contained */
107   LPWSTR containerApp;
108   LPWSTR containerObj;
109
110   /* IOleObject delegate */
111   IOleObject *pOleDelegate;
112   /* IPersistStorage delegate */
113   IPersistStorage *pPSDelegate;
114   /* IDataObject delegate */
115   IDataObject *pDataDelegate;
116
117   /* connection cookie for the advise on the delegate OLE object */
118   DWORD dwAdvConn;
119 };
120
121 typedef struct DefaultHandler DefaultHandler;
122
123 /*
124  * Here, I define utility functions to help with the casting of the
125  * "This" parameter.
126  * There is a version to accommodate all of the VTables implemented
127  * by this object.
128  */
129 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
130 {
131     return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpVtbl));
132 }
133
134 static inline DefaultHandler *impl_from_NDIUnknown( IUnknown *iface )
135 {
136     return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIUnknown));
137 }
138
139 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
140 {
141     return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIDataObject));
142 }
143
144 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
145 {
146     return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
147 }
148
149 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
150 {
151     return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink));
152 }
153
154 static void DefaultHandler_Destroy(DefaultHandler* This);
155
156
157 /*********************************************************
158  * Method implementation for the  non delegating IUnknown
159  * part of the DefaultHandler class.
160  */
161
162 /************************************************************************
163  * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
164  *
165  * See Windows documentation for more details on IUnknown methods.
166  *
167  * This version of QueryInterface will not delegate it's implementation
168  * to the outer unknown.
169  */
170 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
171             IUnknown*      iface,
172             REFIID         riid,
173             void**         ppvObject)
174 {
175   DefaultHandler *This = impl_from_NDIUnknown(iface);
176
177   /* Perform a sanity check on the parameters. */
178   if (!ppvObject)
179     return E_INVALIDARG;
180
181   *ppvObject = NULL;
182
183   if (IsEqualIID(&IID_IUnknown, riid))
184     *ppvObject = iface;
185   else if (IsEqualIID(&IID_IOleObject, riid))
186     *ppvObject = (IOleObject*)&This->lpVtbl;
187   else if (IsEqualIID(&IID_IDataObject, riid))
188     *ppvObject = (IDataObject*)&This->lpvtblIDataObject;
189   else if (IsEqualIID(&IID_IRunnableObject, riid))
190     *ppvObject = (IRunnableObject*)&This->lpvtblIRunnableObject;
191   else if (IsEqualIID(&IID_IPersist, riid) ||
192            IsEqualIID(&IID_IPersistStorage, riid) ||
193            IsEqualIID(&IID_IViewObject, riid) ||
194            IsEqualIID(&IID_IViewObject2, riid) ||
195            IsEqualIID(&IID_IOleCache, riid) ||
196            IsEqualIID(&IID_IOleCache2, riid))
197   {
198     HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
199     if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
200     return hr;
201   }
202
203   /* Check that we obtained an interface. */
204   if (*ppvObject == NULL)
205   {
206     WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
207     return E_NOINTERFACE;
208   }
209
210   /*
211    * Query Interface always increases the reference count by one when it is
212    * successful.
213    */
214   IUnknown_AddRef((IUnknown*)*ppvObject);
215
216   return S_OK;
217 }
218
219 /************************************************************************
220  * DefaultHandler_NDIUnknown_AddRef (IUnknown)
221  *
222  * See Windows documentation for more details on IUnknown methods.
223  *
224  * This version of QueryInterface will not delegate it's implementation
225  * to the outer unknown.
226  */
227 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
228             IUnknown*      iface)
229 {
230   DefaultHandler *This = impl_from_NDIUnknown(iface);
231   return InterlockedIncrement(&This->ref);
232 }
233
234 /************************************************************************
235  * DefaultHandler_NDIUnknown_Release (IUnknown)
236  *
237  * See Windows documentation for more details on IUnknown methods.
238  *
239  * This version of QueryInterface will not delegate it's implementation
240  * to the outer unknown.
241  */
242 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
243             IUnknown*      iface)
244 {
245   DefaultHandler *This = impl_from_NDIUnknown(iface);
246   ULONG ref;
247
248   /* Decrease the reference count on this object. */
249   ref = InterlockedDecrement(&This->ref);
250
251   if (!ref) DefaultHandler_Destroy(This);
252
253   return ref;
254 }
255
256 /*********************************************************
257  * Methods implementation for the IOleObject part of
258  * the DefaultHandler class.
259  */
260
261 /************************************************************************
262  * DefaultHandler_QueryInterface (IUnknown)
263  *
264  * See Windows documentation for more details on IUnknown methods.
265  */
266 static HRESULT WINAPI DefaultHandler_QueryInterface(
267             IOleObject*      iface,
268             REFIID           riid,
269             void**           ppvObject)
270 {
271   DefaultHandler *This = impl_from_IOleObject(iface);
272
273   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
274 }
275
276 /************************************************************************
277  * DefaultHandler_AddRef (IUnknown)
278  *
279  * See Windows documentation for more details on IUnknown methods.
280  */
281 static ULONG WINAPI DefaultHandler_AddRef(
282             IOleObject*        iface)
283 {
284   DefaultHandler *This = impl_from_IOleObject(iface);
285
286   return IUnknown_AddRef(This->outerUnknown);
287 }
288
289 /************************************************************************
290  * DefaultHandler_Release (IUnknown)
291  *
292  * See Windows documentation for more details on IUnknown methods.
293  */
294 static ULONG WINAPI DefaultHandler_Release(
295             IOleObject*        iface)
296 {
297   DefaultHandler *This = impl_from_IOleObject(iface);
298
299   return IUnknown_Release(This->outerUnknown);
300 }
301
302 /************************************************************************
303  * DefaultHandler_SetClientSite (IOleObject)
304  *
305  * The default handler's implementation of this method only keeps the
306  * client site pointer for future reference.
307  *
308  * See Windows documentation for more details on IOleObject methods.
309  */
310 static HRESULT WINAPI DefaultHandler_SetClientSite(
311             IOleObject*        iface,
312             IOleClientSite*    pClientSite)
313 {
314   DefaultHandler *This = impl_from_IOleObject(iface);
315   HRESULT hr = S_OK;
316
317   TRACE("(%p, %p)\n", iface, pClientSite);
318
319   if (This->pOleDelegate)
320     hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
321
322   /*
323    * Make sure we release the previous client site if there
324    * was one.
325    */
326   if (This->clientSite)
327     IOleClientSite_Release(This->clientSite);
328
329   This->clientSite = pClientSite;
330
331   if (This->clientSite)
332     IOleClientSite_AddRef(This->clientSite);
333
334   return S_OK;
335 }
336
337 /************************************************************************
338  * DefaultHandler_GetClientSite (IOleObject)
339  *
340  * The default handler's implementation of this method returns the
341  * last pointer set in IOleObject_SetClientSite.
342  *
343  * See Windows documentation for more details on IOleObject methods.
344  */
345 static HRESULT WINAPI DefaultHandler_GetClientSite(
346             IOleObject*        iface,
347             IOleClientSite**   ppClientSite)
348 {
349   DefaultHandler *This = impl_from_IOleObject(iface);
350
351   /* Sanity check. */
352   if (!ppClientSite)
353     return E_POINTER;
354
355   *ppClientSite = This->clientSite;
356
357   if (This->clientSite)
358     IOleClientSite_AddRef(This->clientSite);
359
360   return S_OK;
361 }
362
363 /************************************************************************
364  * DefaultHandler_SetHostNames (IOleObject)
365  *
366  * The default handler's implementation of this method just stores
367  * the strings and returns S_OK.
368  *
369  * See Windows documentation for more details on IOleObject methods.
370  */
371 static HRESULT WINAPI DefaultHandler_SetHostNames(
372             IOleObject*        iface,
373             LPCOLESTR          szContainerApp,
374             LPCOLESTR          szContainerObj)
375 {
376   DefaultHandler *This = impl_from_IOleObject(iface);
377
378   TRACE("(%p, %s, %s)\n",
379         iface,
380         debugstr_w(szContainerApp),
381         debugstr_w(szContainerObj));
382
383   if (This->pOleDelegate)
384     IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
385
386   /* Be sure to cleanup before re-assinging the strings. */
387   HeapFree( GetProcessHeap(), 0, This->containerApp );
388   This->containerApp = NULL;
389   HeapFree( GetProcessHeap(), 0, This->containerObj );
390   This->containerObj = NULL;
391
392   /* Copy the string supplied. */
393   if (szContainerApp)
394   {
395       if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
396                                            (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
397           strcpyW( This->containerApp, szContainerApp );
398   }
399
400   if (szContainerObj)
401   {
402       if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
403                                            (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
404           strcpyW( This->containerObj, szContainerObj );
405   }
406   return S_OK;
407 }
408
409 /* undos the work done by DefaultHandler_Run */
410 static void WINAPI DefaultHandler_Stop(DefaultHandler *This)
411 {
412   if (!This->pOleDelegate)
413     return;
414
415   IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
416
417   /* FIXME: call IOleCache_OnStop */
418
419   DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
420   if (This->pDataDelegate)
421   {
422      IDataObject_Release(This->pDataDelegate);
423      This->pDataDelegate = NULL;
424   }
425   if (This->pPSDelegate)
426   {
427      IPersistStorage_Release(This->pPSDelegate);
428      This->pPSDelegate = NULL;
429   }
430   IOleObject_Release(This->pOleDelegate);
431   This->pOleDelegate = NULL;
432 }
433
434 /************************************************************************
435  * DefaultHandler_Close (IOleObject)
436  *
437  * The default handler's implementation of this method is meaningless
438  * without a running server so it does nothing.
439  *
440  * See Windows documentation for more details on IOleObject methods.
441  */
442 static HRESULT WINAPI DefaultHandler_Close(
443             IOleObject*        iface,
444             DWORD              dwSaveOption)
445 {
446   DefaultHandler *This = impl_from_IOleObject(iface);
447   HRESULT hr;
448
449   TRACE("(%ld)\n", dwSaveOption);
450
451   if (!This->pOleDelegate)
452     return S_OK;
453
454   hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
455
456   DefaultHandler_Stop(This);
457
458   return hr;
459 }
460
461 /************************************************************************
462  * DefaultHandler_SetMoniker (IOleObject)
463  *
464  * The default handler's implementation of this method does nothing.
465  *
466  * See Windows documentation for more details on IOleObject methods.
467  */
468 static HRESULT WINAPI DefaultHandler_SetMoniker(
469             IOleObject*        iface,
470             DWORD              dwWhichMoniker,
471             IMoniker*          pmk)
472 {
473   DefaultHandler *This = impl_from_IOleObject(iface);
474
475   TRACE("(%p, %ld, %p)\n",
476         iface,
477         dwWhichMoniker,
478         pmk);
479
480   if (This->pOleDelegate)
481     return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
482
483   return S_OK;
484 }
485
486 /************************************************************************
487  * DefaultHandler_GetMoniker (IOleObject)
488  *
489  * Delegate this request to the client site if we have one.
490  *
491  * See Windows documentation for more details on IOleObject methods.
492  */
493 static HRESULT WINAPI DefaultHandler_GetMoniker(
494             IOleObject*        iface,
495             DWORD              dwAssign,
496             DWORD              dwWhichMoniker,
497             IMoniker**         ppmk)
498 {
499   DefaultHandler *This = impl_from_IOleObject(iface);
500
501   TRACE("(%p, %ld, %ld, %p)\n",
502         iface, dwAssign, dwWhichMoniker, ppmk);
503
504   if (This->pOleDelegate)
505     return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
506                                  ppmk);
507
508   /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
509   if (This->clientSite)
510   {
511     return IOleClientSite_GetMoniker(This->clientSite,
512                                      dwAssign,
513                                      dwWhichMoniker,
514                                      ppmk);
515
516   }
517
518   return E_FAIL;
519 }
520
521 /************************************************************************
522  * DefaultHandler_InitFromData (IOleObject)
523  *
524  * This method is meaningless if the server is not running
525  *
526  * See Windows documentation for more details on IOleObject methods.
527  */
528 static HRESULT WINAPI DefaultHandler_InitFromData(
529             IOleObject*        iface,
530             IDataObject*       pDataObject,
531             BOOL               fCreation,
532             DWORD              dwReserved)
533 {
534   DefaultHandler *This = impl_from_IOleObject(iface);
535
536   TRACE("(%p, %p, %d, %ld)\n",
537         iface, pDataObject, fCreation, dwReserved);
538
539   if (This->pOleDelegate)
540     return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
541                                    dwReserved);
542   return OLE_E_NOTRUNNING;
543 }
544
545 /************************************************************************
546  * DefaultHandler_GetClipboardData (IOleObject)
547  *
548  * This method is meaningless if the server is not running
549  *
550  * See Windows documentation for more details on IOleObject methods.
551  */
552 static HRESULT WINAPI DefaultHandler_GetClipboardData(
553             IOleObject*        iface,
554             DWORD              dwReserved,
555             IDataObject**      ppDataObject)
556 {
557   DefaultHandler *This = impl_from_IOleObject(iface);
558
559   TRACE("(%p, %ld, %p)\n",
560         iface, dwReserved, ppDataObject);
561
562   if (This->pOleDelegate)
563     return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
564                                        ppDataObject);
565
566   return OLE_E_NOTRUNNING;
567 }
568
569 static HRESULT WINAPI DefaultHandler_DoVerb(
570             IOleObject*        iface,
571             LONG               iVerb,
572             struct tagMSG*     lpmsg,
573             IOleClientSite*    pActiveSite,
574             LONG               lindex,
575             HWND               hwndParent,
576             LPCRECT            lprcPosRect)
577 {
578   DefaultHandler *This = impl_from_IOleObject(iface);
579   IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
580   HRESULT hr;
581
582   TRACE("(%ld, %p, %p, %ld, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
583
584   hr = IRunnableObject_Run(pRunnableObj, NULL);
585   if (FAILED(hr)) return hr;
586
587   return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
588                            lindex, hwndParent, lprcPosRect);
589 }
590
591 /************************************************************************
592  * DefaultHandler_EnumVerbs (IOleObject)
593  *
594  * The default handler implementation of this method simply delegates
595  * to OleRegEnumVerbs
596  *
597  * See Windows documentation for more details on IOleObject methods.
598  */
599 static HRESULT WINAPI DefaultHandler_EnumVerbs(
600             IOleObject*        iface,
601             IEnumOLEVERB**     ppEnumOleVerb)
602 {
603   DefaultHandler *This = impl_from_IOleObject(iface);
604   HRESULT hr = OLE_S_USEREG;
605
606   TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
607
608   if (This->pOleDelegate)
609     hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
610
611   if (hr == OLE_S_USEREG)
612     return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
613   else
614     return hr;
615 }
616
617 static HRESULT WINAPI DefaultHandler_Update(
618             IOleObject*        iface)
619 {
620   FIXME(": Stub\n");
621   return E_NOTIMPL;
622 }
623
624 /************************************************************************
625  * DefaultHandler_IsUpToDate (IOleObject)
626  *
627  * This method is meaningless if the server is not running
628  *
629  * See Windows documentation for more details on IOleObject methods.
630  */
631 static HRESULT WINAPI DefaultHandler_IsUpToDate(
632             IOleObject*        iface)
633 {
634   TRACE("(%p)\n", iface);
635
636   return OLE_E_NOTRUNNING;
637 }
638
639 /************************************************************************
640  * DefaultHandler_GetUserClassID (IOleObject)
641  *
642  * TODO: Map to a new class ID if emulation is active.
643  *
644  * See Windows documentation for more details on IOleObject methods.
645  */
646 static HRESULT WINAPI DefaultHandler_GetUserClassID(
647             IOleObject*        iface,
648             CLSID*             pClsid)
649 {
650   DefaultHandler *This = impl_from_IOleObject(iface);
651
652   TRACE("(%p, %p)\n", iface, pClsid);
653
654   if (This->pOleDelegate)
655     return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
656
657   if (This->pOleDelegate)
658     return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
659
660   /* Sanity check. */
661   if (!pClsid)
662     return E_POINTER;
663
664   memcpy(pClsid, &This->clsid, sizeof(CLSID));
665
666   return S_OK;
667 }
668
669 /************************************************************************
670  * DefaultHandler_GetUserType (IOleObject)
671  *
672  * The default handler implementation of this method simply delegates
673  * to OleRegGetUserType
674  *
675  * See Windows documentation for more details on IOleObject methods.
676  */
677 static HRESULT WINAPI DefaultHandler_GetUserType(
678             IOleObject*        iface,
679             DWORD              dwFormOfType,
680             LPOLESTR*          pszUserType)
681 {
682   DefaultHandler *This = impl_from_IOleObject(iface);
683
684   TRACE("(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType);
685
686   return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
687 }
688
689 /************************************************************************
690  * DefaultHandler_SetExtent (IOleObject)
691  *
692  * This method is meaningless if the server is not running
693  *
694  * See Windows documentation for more details on IOleObject methods.
695  */
696 static HRESULT WINAPI DefaultHandler_SetExtent(
697             IOleObject*        iface,
698             DWORD              dwDrawAspect,
699             SIZEL*             psizel)
700 {
701   DefaultHandler *This = impl_from_IOleObject(iface);
702
703   TRACE("(%p, %lx, (%ld x %ld))\n", iface,
704         dwDrawAspect, psizel->cx, psizel->cy);
705
706   if (This->pOleDelegate)
707     IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
708
709   return OLE_E_NOTRUNNING;
710 }
711
712 /************************************************************************
713  * DefaultHandler_GetExtent (IOleObject)
714  *
715  * The default handler's implementation of this method returns uses
716  * the cache to locate the aspect and extract the extent from it.
717  *
718  * See Windows documentation for more details on IOleObject methods.
719  */
720 static HRESULT WINAPI DefaultHandler_GetExtent(
721             IOleObject*        iface,
722             DWORD              dwDrawAspect,
723             SIZEL*             psizel)
724 {
725   DVTARGETDEVICE* targetDevice;
726   IViewObject2*   cacheView = NULL;
727   HRESULT         hres;
728
729   DefaultHandler *This = impl_from_IOleObject(iface);
730
731   TRACE("(%p, %lx, %p)\n", iface, dwDrawAspect, psizel);
732
733   if (This->pOleDelegate)
734     return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
735
736   hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
737   if (FAILED(hres))
738     return E_UNEXPECTED;
739
740   /*
741    * Prepare the call to the cache's GetExtent method.
742    *
743    * Here we would build a valid DVTARGETDEVICE structure
744    * but, since we are calling into the data cache, we
745    * know it's implementation and we'll skip this
746    * extra work until later.
747    */
748   targetDevice = NULL;
749
750   hres = IViewObject2_GetExtent(cacheView,
751                                 dwDrawAspect,
752                                 -1,
753                                 targetDevice,
754                                 psizel);
755
756   /*
757    * Cleanup
758    */
759   IViewObject2_Release(cacheView);
760
761   return hres;
762 }
763
764 /************************************************************************
765  * DefaultHandler_Advise (IOleObject)
766  *
767  * The default handler's implementation of this method simply
768  * delegates to the OleAdviseHolder.
769  *
770  * See Windows documentation for more details on IOleObject methods.
771  */
772 static HRESULT WINAPI DefaultHandler_Advise(
773             IOleObject*        iface,
774             IAdviseSink*       pAdvSink,
775             DWORD*             pdwConnection)
776 {
777   HRESULT hres = S_OK;
778   DefaultHandler *This = impl_from_IOleObject(iface);
779
780   TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
781
782   /* Make sure we have an advise holder before we start. */
783   if (!This->oleAdviseHolder)
784     hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
785
786   if (SUCCEEDED(hres))
787     hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
788                                    pAdvSink,
789                                    pdwConnection);
790
791   return hres;
792 }
793
794 /************************************************************************
795  * DefaultHandler_Unadvise (IOleObject)
796  *
797  * The default handler's implementation of this method simply
798  * delegates to the OleAdviseHolder.
799  *
800  * See Windows documentation for more details on IOleObject methods.
801  */
802 static HRESULT WINAPI DefaultHandler_Unadvise(
803             IOleObject*        iface,
804             DWORD              dwConnection)
805 {
806   DefaultHandler *This = impl_from_IOleObject(iface);
807
808   TRACE("(%p, %ld)\n", iface, dwConnection);
809
810   /*
811    * If we don't have an advise holder yet, it means we don't have
812    * a connection.
813    */
814   if (!This->oleAdviseHolder)
815     return OLE_E_NOCONNECTION;
816
817   return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
818                                    dwConnection);
819 }
820
821 /************************************************************************
822  * DefaultHandler_EnumAdvise (IOleObject)
823  *
824  * The default handler's implementation of this method simply
825  * delegates to the OleAdviseHolder.
826  *
827  * See Windows documentation for more details on IOleObject methods.
828  */
829 static HRESULT WINAPI DefaultHandler_EnumAdvise(
830             IOleObject*        iface,
831             IEnumSTATDATA**    ppenumAdvise)
832 {
833   DefaultHandler *This = impl_from_IOleObject(iface);
834
835   TRACE("(%p, %p)\n", iface, ppenumAdvise);
836
837   /* Sanity check */
838   if (!ppenumAdvise)
839     return E_POINTER;
840
841   *ppenumAdvise = NULL;
842
843   if (!This->oleAdviseHolder)
844     return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder,
845                                        ppenumAdvise);
846
847   return S_OK;
848 }
849
850 /************************************************************************
851  * DefaultHandler_GetMiscStatus (IOleObject)
852  *
853  * The default handler's implementation of this method simply delegates
854  * to OleRegGetMiscStatus.
855  *
856  * See Windows documentation for more details on IOleObject methods.
857  */
858 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
859             IOleObject*        iface,
860             DWORD              dwAspect,
861             DWORD*             pdwStatus)
862 {
863   HRESULT hres;
864   DefaultHandler *This = impl_from_IOleObject(iface);
865
866   TRACE("(%p, %lx, %p)\n", iface, dwAspect, pdwStatus);
867
868   if (This->pOleDelegate)
869     return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
870
871   if (This->pOleDelegate)
872     return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
873
874   hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
875
876   if (FAILED(hres))
877     *pdwStatus = 0;
878
879   return S_OK;
880 }
881
882 /************************************************************************
883  * DefaultHandler_SetColorScheme (IOleObject)
884  *
885  * This method is meaningless if the server is not running
886  *
887  * See Windows documentation for more details on IOleObject methods.
888  */
889 static HRESULT WINAPI DefaultHandler_SetColorScheme(
890             IOleObject*           iface,
891             struct tagLOGPALETTE* pLogpal)
892 {
893   DefaultHandler *This = impl_from_IOleObject(iface);
894
895   TRACE("(%p, %p))\n", iface, pLogpal);
896
897   if (This->pOleDelegate)
898     return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
899
900   return OLE_E_NOTRUNNING;
901 }
902
903 /*********************************************************
904  * Methods implementation for the IDataObject part of
905  * the DefaultHandler class.
906  */
907
908 /************************************************************************
909  * DefaultHandler_IDataObject_QueryInterface (IUnknown)
910  *
911  * See Windows documentation for more details on IUnknown methods.
912  */
913 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
914             IDataObject*     iface,
915            REFIID           riid,
916             void**           ppvObject)
917 {
918   DefaultHandler *This = impl_from_IDataObject(iface);
919
920   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
921 }
922
923 /************************************************************************
924  * DefaultHandler_IDataObject_AddRef (IUnknown)
925  *
926  * See Windows documentation for more details on IUnknown methods.
927  */
928 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
929             IDataObject*     iface)
930 {
931   DefaultHandler *This = impl_from_IDataObject(iface);
932
933   return IUnknown_AddRef(This->outerUnknown);
934 }
935
936 /************************************************************************
937  * DefaultHandler_IDataObject_Release (IUnknown)
938  *
939  * See Windows documentation for more details on IUnknown methods.
940  */
941 static ULONG WINAPI DefaultHandler_IDataObject_Release(
942             IDataObject*     iface)
943 {
944   DefaultHandler *This = impl_from_IDataObject(iface);
945
946   return IUnknown_Release(This->outerUnknown);
947 }
948
949 /************************************************************************
950  * DefaultHandler_GetData
951  *
952  * Get Data from a source dataobject using format pformatetcIn->cfFormat
953  * See Windows documentation for more details on GetData.
954  * Default handler's implementation of this method delegates to the cache.
955  */
956 static HRESULT WINAPI DefaultHandler_GetData(
957             IDataObject*     iface,
958             LPFORMATETC      pformatetcIn,
959             STGMEDIUM*       pmedium)
960 {
961   IDataObject* cacheDataObject = NULL;
962   HRESULT      hres;
963
964   DefaultHandler *This = impl_from_IDataObject(iface);
965
966   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
967
968   hres = IUnknown_QueryInterface(This->dataCache,
969                                  &IID_IDataObject,
970                                  (void**)&cacheDataObject);
971
972   if (FAILED(hres))
973     return E_UNEXPECTED;
974
975   hres = IDataObject_GetData(cacheDataObject,
976                              pformatetcIn,
977                              pmedium);
978
979   IDataObject_Release(cacheDataObject);
980
981   return hres;
982 }
983
984 static HRESULT WINAPI DefaultHandler_GetDataHere(
985             IDataObject*     iface,
986             LPFORMATETC      pformatetc,
987             STGMEDIUM*       pmedium)
988 {
989   FIXME(": Stub\n");
990   return E_NOTIMPL;
991 }
992
993 /************************************************************************
994  * DefaultHandler_QueryGetData (IDataObject)
995  *
996  * The default handler's implementation of this method delegates to
997  * the cache.
998  *
999  * See Windows documentation for more details on IDataObject methods.
1000  */
1001 static HRESULT WINAPI DefaultHandler_QueryGetData(
1002             IDataObject*     iface,
1003             LPFORMATETC      pformatetc)
1004 {
1005   IDataObject* cacheDataObject = NULL;
1006   HRESULT      hres;
1007
1008   DefaultHandler *This = impl_from_IDataObject(iface);
1009
1010   TRACE("(%p, %p)\n", iface, pformatetc);
1011
1012   hres = IUnknown_QueryInterface(This->dataCache,
1013                                  &IID_IDataObject,
1014                                  (void**)&cacheDataObject);
1015
1016   if (FAILED(hres))
1017     return E_UNEXPECTED;
1018
1019   hres = IDataObject_QueryGetData(cacheDataObject,
1020                                   pformatetc);
1021
1022   IDataObject_Release(cacheDataObject);
1023
1024   return hres;
1025 }
1026
1027 /************************************************************************
1028  * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1029  *
1030  * This method is meaningless if the server is not running
1031  *
1032  * See Windows documentation for more details on IDataObject methods.
1033  */
1034 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1035             IDataObject*     iface,
1036             LPFORMATETC      pformatetcIn,
1037             LPFORMATETC      pformatetcOut)
1038 {
1039   DefaultHandler *This = impl_from_IDataObject(iface);
1040   IDataObject *pDataObject;
1041   HRESULT hr;
1042
1043   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1044
1045   if (!This->pOleDelegate)
1046     return OLE_E_NOTRUNNING;
1047
1048   hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&pDataObject);
1049   return IDataObject_GetCanonicalFormatEtc(pDataObject, pformatetcIn, pformatetcOut);
1050 }
1051
1052 /************************************************************************
1053  * DefaultHandler_SetData (IDataObject)
1054  *
1055  * The default handler's implementation of this method delegates to
1056  * the cache.
1057  *
1058  * See Windows documentation for more details on IDataObject methods.
1059  */
1060 static HRESULT WINAPI DefaultHandler_SetData(
1061             IDataObject*     iface,
1062             LPFORMATETC      pformatetc,
1063             STGMEDIUM*       pmedium,
1064             BOOL             fRelease)
1065 {
1066   DefaultHandler *This = impl_from_IDataObject(iface);
1067   IDataObject* cacheDataObject = NULL;
1068   HRESULT      hres;
1069
1070   TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1071
1072   hres = IUnknown_QueryInterface(This->dataCache,
1073                                  &IID_IDataObject,
1074                                  (void**)&cacheDataObject);
1075
1076   if (FAILED(hres))
1077     return E_UNEXPECTED;
1078
1079   hres = IDataObject_SetData(cacheDataObject,
1080                              pformatetc,
1081                              pmedium,
1082                              fRelease);
1083
1084   IDataObject_Release(cacheDataObject);
1085
1086   return hres;
1087 }
1088
1089 /************************************************************************
1090  * DefaultHandler_EnumFormatEtc (IDataObject)
1091  *
1092  * The default handler's implementation of This method simply delegates
1093  * to OleRegEnumFormatEtc.
1094  *
1095  * See Windows documentation for more details on IDataObject methods.
1096  */
1097 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1098             IDataObject*     iface,
1099             DWORD            dwDirection,
1100             IEnumFORMATETC** ppenumFormatEtc)
1101 {
1102   HRESULT hres;
1103   DefaultHandler *This = impl_from_IDataObject(iface);
1104
1105   TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
1106
1107   hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1108
1109   return hres;
1110 }
1111
1112 /************************************************************************
1113  * DefaultHandler_DAdvise (IDataObject)
1114  *
1115  * The default handler's implementation of this method simply
1116  * delegates to the DataAdviseHolder.
1117  *
1118  * See Windows documentation for more details on IDataObject methods.
1119  */
1120 static HRESULT WINAPI DefaultHandler_DAdvise(
1121             IDataObject*     iface,
1122             FORMATETC*       pformatetc,
1123             DWORD            advf,
1124             IAdviseSink*     pAdvSink,
1125             DWORD*           pdwConnection)
1126 {
1127   HRESULT hres = S_OK;
1128   DefaultHandler *This = impl_from_IDataObject(iface);
1129
1130   TRACE("(%p, %p, %ld, %p, %p)\n",
1131         iface, pformatetc, advf, pAdvSink, pdwConnection);
1132
1133   /* Make sure we have a data advise holder before we start. */
1134   if (!This->dataAdviseHolder)
1135     hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1136
1137   if (SUCCEEDED(hres))
1138     hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1139                                     iface,
1140                                     pformatetc,
1141                                     advf,
1142                                     pAdvSink,
1143                                     pdwConnection);
1144
1145   return hres;
1146 }
1147
1148 /************************************************************************
1149  * DefaultHandler_DUnadvise (IDataObject)
1150  *
1151  * The default handler's implementation of this method simply
1152  * delegates to the DataAdviseHolder.
1153  *
1154  * See Windows documentation for more details on IDataObject methods.
1155  */
1156 static HRESULT WINAPI DefaultHandler_DUnadvise(
1157             IDataObject*     iface,
1158             DWORD            dwConnection)
1159 {
1160   DefaultHandler *This = impl_from_IDataObject(iface);
1161
1162   TRACE("(%p, %ld)\n", iface, dwConnection);
1163
1164   /*
1165    * If we don't have a data advise holder yet, it means that
1166    * we don't have any connections..
1167    */
1168   if (!This->dataAdviseHolder)
1169     return OLE_E_NOCONNECTION;
1170
1171   return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1172                                     dwConnection);
1173 }
1174
1175 /************************************************************************
1176  * DefaultHandler_EnumDAdvise (IDataObject)
1177  *
1178  * The default handler's implementation of this method simply
1179  * delegates to the DataAdviseHolder.
1180  *
1181  * See Windows documentation for more details on IDataObject methods.
1182  */
1183 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1184             IDataObject*     iface,
1185             IEnumSTATDATA**  ppenumAdvise)
1186 {
1187   DefaultHandler *This = impl_from_IDataObject(iface);
1188
1189   TRACE("(%p, %p)\n", iface, ppenumAdvise);
1190
1191   /* Sanity check */
1192   if (!ppenumAdvise)
1193     return E_POINTER;
1194
1195   *ppenumAdvise = NULL;
1196
1197   /* If we have a data advise holder object, delegate. */
1198   if (This->dataAdviseHolder)
1199     return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1200                                         ppenumAdvise);
1201
1202   return S_OK;
1203 }
1204
1205 /*********************************************************
1206  * Methods implementation for the IRunnableObject part
1207  * of the DefaultHandler class.
1208  */
1209
1210 /************************************************************************
1211  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1212  *
1213  * See Windows documentation for more details on IUnknown methods.
1214  */
1215 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1216             IRunnableObject*     iface,
1217             REFIID               riid,
1218             void**               ppvObject)
1219 {
1220   DefaultHandler *This = impl_from_IRunnableObject(iface);
1221
1222   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1223 }
1224
1225 /************************************************************************
1226  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1227  *
1228  * See Windows documentation for more details on IUnknown methods.
1229  */
1230 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1231             IRunnableObject*     iface)
1232 {
1233   DefaultHandler *This = impl_from_IRunnableObject(iface);
1234
1235   return IUnknown_AddRef(This->outerUnknown);
1236 }
1237
1238 /************************************************************************
1239  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1240  *
1241  * See Windows documentation for more details on IUnknown methods.
1242  */
1243 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1244             IRunnableObject*     iface)
1245 {
1246   DefaultHandler *This = impl_from_IRunnableObject(iface);
1247
1248   return IUnknown_Release(This->outerUnknown);
1249 }
1250
1251 /************************************************************************
1252  * DefaultHandler_GetRunningClass (IRunnableObject)
1253  *
1254  * See Windows documentation for more details on IRunnableObject methods.
1255  */
1256 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1257             IRunnableObject*     iface,
1258             LPCLSID              lpClsid)
1259 {
1260   FIXME("()\n");
1261   return S_OK;
1262 }
1263
1264 static HRESULT WINAPI DefaultHandler_Run(
1265             IRunnableObject*     iface,
1266             IBindCtx*            pbc)
1267 {
1268   DefaultHandler *This = impl_from_IRunnableObject(iface);
1269   HRESULT hr;
1270
1271   FIXME("(%p): semi-stub\n", pbc);
1272
1273   /* already running? if so nothing to do */
1274   if (This->pOleDelegate)
1275     return S_OK;
1276
1277   hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1278                         &IID_IOleObject, (void **)&This->pOleDelegate);
1279   if (FAILED(hr))
1280     return hr;
1281
1282   hr = IOleObject_Advise(This->pOleDelegate,
1283                          (IAdviseSink *)&This->lpvtblIAdviseSink,
1284                          &This->dwAdvConn);
1285
1286   if (SUCCEEDED(hr) && This->clientSite)
1287     hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1288
1289   if (SUCCEEDED(hr))
1290   {
1291     IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1292                               (void **)&This->pPSDelegate);
1293     if (This->pPSDelegate)
1294       hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
1295   }
1296
1297   if (SUCCEEDED(hr) && This->containerApp)
1298     hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1299                                  This->containerObj);
1300
1301   /* FIXME: do more stuff here:
1302    * - IOleObject_GetMiscStatus
1303    * - IOleObject_GetMoniker
1304    * - IOleCache_OnRun
1305    */
1306
1307   if (SUCCEEDED(hr))
1308     hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1309                                    (void **)&This->pDataDelegate);
1310
1311   if (SUCCEEDED(hr) && This->dataAdviseHolder)
1312     hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1313
1314   if (FAILED(hr))
1315     DefaultHandler_Stop(This);
1316
1317   return hr;
1318 }
1319
1320 /************************************************************************
1321  * DefaultHandler_IsRunning (IRunnableObject)
1322  *
1323  * See Windows documentation for more details on IRunnableObject methods.
1324  */
1325 static BOOL    WINAPI DefaultHandler_IsRunning(
1326             IRunnableObject*     iface)
1327 {
1328   DefaultHandler *This = impl_from_IRunnableObject(iface);
1329
1330   TRACE("()\n");
1331
1332   if (This->pOleDelegate)
1333     return TRUE;
1334   else
1335     return FALSE;
1336 }
1337
1338 /************************************************************************
1339  * DefaultHandler_LockRunning (IRunnableObject)
1340  *
1341  * See Windows documentation for more details on IRunnableObject methods.
1342  */
1343 static HRESULT WINAPI DefaultHandler_LockRunning(
1344             IRunnableObject*     iface,
1345             BOOL                 fLock,
1346             BOOL                 fLastUnlockCloses)
1347 {
1348   FIXME("()\n");
1349   return S_OK;
1350 }
1351
1352 /************************************************************************
1353  * DefaultHandler_SetContainedObject (IRunnableObject)
1354  *
1355  * See Windows documentation for more details on IRunnableObject methods.
1356  */
1357 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1358             IRunnableObject*     iface,
1359             BOOL                 fContained)
1360 {
1361   FIXME("()\n");
1362   return S_OK;
1363 }
1364
1365 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1366     IAdviseSink *iface,
1367     REFIID riid,
1368     void **ppvObject)
1369 {
1370     if (IsEqualIID(riid, &IID_IUnknown) ||
1371         IsEqualIID(riid, &IID_IAdviseSink))
1372     {
1373         *ppvObject = iface;
1374         IAdviseSink_AddRef(iface);
1375         return S_OK;
1376     }
1377
1378     return E_NOINTERFACE;
1379 }
1380
1381 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1382     IAdviseSink *iface)
1383 {
1384     DefaultHandler *This = impl_from_IAdviseSink(iface);
1385
1386     return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1387 }
1388
1389 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1390             IAdviseSink *iface)
1391 {
1392     DefaultHandler *This = impl_from_IAdviseSink(iface);
1393
1394     return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1395 }
1396
1397 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1398     IAdviseSink *iface,
1399     FORMATETC *pFormatetc,
1400     STGMEDIUM *pStgmed)
1401 {
1402     FIXME(": stub\n");
1403 }
1404
1405 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1406     IAdviseSink *iface,
1407     DWORD dwAspect,
1408     LONG lindex)
1409 {
1410     FIXME(": stub\n");
1411 }
1412
1413 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1414     IAdviseSink *iface,
1415     IMoniker *pmk)
1416 {
1417     DefaultHandler *This = impl_from_IAdviseSink(iface);
1418
1419     TRACE("(%p)\n", pmk);
1420
1421     if (This->oleAdviseHolder)
1422         IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1423 }
1424
1425 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1426     IAdviseSink *iface)
1427 {
1428     DefaultHandler *This = impl_from_IAdviseSink(iface);
1429
1430     TRACE("()\n");
1431
1432     if (This->oleAdviseHolder)
1433         IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1434 }
1435
1436 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1437     IAdviseSink *iface)
1438 {
1439     DefaultHandler *This = impl_from_IAdviseSink(iface);
1440     
1441     TRACE("()\n");
1442
1443     if (This->oleAdviseHolder)
1444         IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1445
1446     DefaultHandler_Stop(This);
1447 }
1448
1449 /*
1450  * Virtual function tables for the DefaultHandler class.
1451  */
1452 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1453 {
1454   DefaultHandler_QueryInterface,
1455   DefaultHandler_AddRef,
1456   DefaultHandler_Release,
1457   DefaultHandler_SetClientSite,
1458   DefaultHandler_GetClientSite,
1459   DefaultHandler_SetHostNames,
1460   DefaultHandler_Close,
1461   DefaultHandler_SetMoniker,
1462   DefaultHandler_GetMoniker,
1463   DefaultHandler_InitFromData,
1464   DefaultHandler_GetClipboardData,
1465   DefaultHandler_DoVerb,
1466   DefaultHandler_EnumVerbs,
1467   DefaultHandler_Update,
1468   DefaultHandler_IsUpToDate,
1469   DefaultHandler_GetUserClassID,
1470   DefaultHandler_GetUserType,
1471   DefaultHandler_SetExtent,
1472   DefaultHandler_GetExtent,
1473   DefaultHandler_Advise,
1474   DefaultHandler_Unadvise,
1475   DefaultHandler_EnumAdvise,
1476   DefaultHandler_GetMiscStatus,
1477   DefaultHandler_SetColorScheme
1478 };
1479
1480 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1481 {
1482   DefaultHandler_NDIUnknown_QueryInterface,
1483   DefaultHandler_NDIUnknown_AddRef,
1484   DefaultHandler_NDIUnknown_Release,
1485 };
1486
1487 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1488 {
1489   DefaultHandler_IDataObject_QueryInterface,
1490   DefaultHandler_IDataObject_AddRef,
1491   DefaultHandler_IDataObject_Release,
1492   DefaultHandler_GetData,
1493   DefaultHandler_GetDataHere,
1494   DefaultHandler_QueryGetData,
1495   DefaultHandler_GetCanonicalFormatEtc,
1496   DefaultHandler_SetData,
1497   DefaultHandler_EnumFormatEtc,
1498   DefaultHandler_DAdvise,
1499   DefaultHandler_DUnadvise,
1500   DefaultHandler_EnumDAdvise
1501 };
1502
1503 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1504 {
1505   DefaultHandler_IRunnableObject_QueryInterface,
1506   DefaultHandler_IRunnableObject_AddRef,
1507   DefaultHandler_IRunnableObject_Release,
1508   DefaultHandler_GetRunningClass,
1509   DefaultHandler_Run,
1510   DefaultHandler_IsRunning,
1511   DefaultHandler_LockRunning,
1512   DefaultHandler_SetContainedObject
1513 };
1514
1515 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1516 {
1517   DefaultHandler_IAdviseSink_QueryInterface,
1518   DefaultHandler_IAdviseSink_AddRef,
1519   DefaultHandler_IAdviseSink_Release,
1520   DefaultHandler_IAdviseSink_OnDataChange,
1521   DefaultHandler_IAdviseSink_OnViewChange,
1522   DefaultHandler_IAdviseSink_OnRename,
1523   DefaultHandler_IAdviseSink_OnSave,
1524   DefaultHandler_IAdviseSink_OnClose
1525 };
1526
1527 /*********************************************************
1528  * Methods implementation for the DefaultHandler class.
1529  */
1530 static DefaultHandler* DefaultHandler_Construct(
1531   REFCLSID  clsid,
1532   LPUNKNOWN pUnkOuter)
1533 {
1534   DefaultHandler* This = NULL;
1535
1536   /*
1537    * Allocate space for the object.
1538    */
1539   This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1540
1541   if (!This)
1542     return This;
1543
1544   This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1545   This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1546   This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1547   This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1548   This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1549
1550   /*
1551    * Start with one reference count. The caller of this function
1552    * must release the interface pointer when it is done.
1553    */
1554   This->ref = 1;
1555
1556   /*
1557    * Initialize the outer unknown
1558    * We don't keep a reference on the outer unknown since, the way
1559    * aggregation works, our lifetime is at least as large as it's
1560    * lifetime.
1561    */
1562   if (!pUnkOuter)
1563     pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1564
1565   This->outerUnknown = pUnkOuter;
1566
1567   /*
1568    * Create a datacache object.
1569    * We aggregate with the datacache. Make sure we pass our outer
1570    * unknown as the datacache's outer unknown.
1571    */
1572   CreateDataCache(This->outerUnknown,
1573                   clsid,
1574                   &IID_IUnknown,
1575                   (void**)&This->dataCache);
1576
1577   /*
1578    * Initialize the other data members of the class.
1579    */
1580   memcpy(&This->clsid, clsid, sizeof(CLSID));
1581   This->clientSite = NULL;
1582   This->oleAdviseHolder = NULL;
1583   This->dataAdviseHolder = NULL;
1584   This->containerApp = NULL;
1585   This->containerObj = NULL;
1586   This->pOleDelegate = NULL;
1587   This->pPSDelegate = NULL;
1588   This->pDataDelegate = NULL;
1589
1590   This->dwAdvConn = 0;
1591
1592   return This;
1593 }
1594
1595 static void DefaultHandler_Destroy(
1596   DefaultHandler* This)
1597 {
1598   /* release delegates */
1599   DefaultHandler_Stop(This);
1600
1601   /* Free the strings idenfitying the object */
1602   HeapFree( GetProcessHeap(), 0, This->containerApp );
1603   This->containerApp = NULL;
1604   HeapFree( GetProcessHeap(), 0, This->containerObj );
1605   This->containerObj = NULL;
1606
1607   /* Release our reference to the data cache. */
1608   if (This->dataCache)
1609   {
1610     IUnknown_Release(This->dataCache);
1611     This->dataCache = NULL;
1612   }
1613
1614   /* Same thing for the client site. */
1615   if (This->clientSite)
1616   {
1617     IOleClientSite_Release(This->clientSite);
1618     This->clientSite = NULL;
1619   }
1620
1621   /* And the advise holder. */
1622   if (This->oleAdviseHolder)
1623   {
1624     IOleAdviseHolder_Release(This->oleAdviseHolder);
1625     This->oleAdviseHolder = NULL;
1626   }
1627
1628   /* And the data advise holder. */
1629   if (This->dataAdviseHolder)
1630   {
1631     IDataAdviseHolder_Release(This->dataAdviseHolder);
1632     This->dataAdviseHolder = NULL;
1633   }
1634
1635   /* Free the actual default handler structure. */
1636   HeapFree(GetProcessHeap(), 0, This);
1637 }
1638
1639 /******************************************************************************
1640  * OleCreateDefaultHandler [OLE32.@]
1641  */
1642 HRESULT WINAPI OleCreateDefaultHandler(
1643   REFCLSID  clsid,
1644   LPUNKNOWN pUnkOuter,
1645   REFIID    riid,
1646   LPVOID*   ppvObj)
1647 {
1648   DefaultHandler* newHandler = NULL;
1649   HRESULT         hr         = S_OK;
1650
1651   TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1652
1653   /*
1654    * Sanity check
1655    */
1656   if (!ppvObj)
1657     return E_POINTER;
1658
1659   *ppvObj = NULL;
1660
1661   /*
1662    * If This handler is constructed for aggregation, make sure
1663    * the caller is requesting the IUnknown interface.
1664    * This is necessary because it's the only time the non-delegating
1665    * IUnknown pointer can be returned to the outside.
1666    */
1667   if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
1668     return CLASS_E_NOAGGREGATION;
1669
1670   /*
1671    * Try to construct a new instance of the class.
1672    */
1673   newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1674
1675   if (!newHandler)
1676     return E_OUTOFMEMORY;
1677
1678   /*
1679    * Make sure it supports the interface required by the caller.
1680    */
1681   hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1682
1683   /*
1684    * Release the reference obtained in the constructor. If
1685    * the QueryInterface was unsuccessful, it will free the class.
1686    */
1687   IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
1688
1689   return hr;
1690 }