iphlpapi: Clean up memory allocation.
[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   /* Sanity check. */
658   if (!pClsid)
659     return E_POINTER;
660
661   memcpy(pClsid, &This->clsid, sizeof(CLSID));
662
663   return S_OK;
664 }
665
666 /************************************************************************
667  * DefaultHandler_GetUserType (IOleObject)
668  *
669  * The default handler implementation of this method simply delegates
670  * to OleRegGetUserType
671  *
672  * See Windows documentation for more details on IOleObject methods.
673  */
674 static HRESULT WINAPI DefaultHandler_GetUserType(
675             IOleObject*        iface,
676             DWORD              dwFormOfType,
677             LPOLESTR*          pszUserType)
678 {
679   DefaultHandler *This = impl_from_IOleObject(iface);
680
681   TRACE("(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType);
682
683   return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
684 }
685
686 /************************************************************************
687  * DefaultHandler_SetExtent (IOleObject)
688  *
689  * This method is meaningless if the server is not running
690  *
691  * See Windows documentation for more details on IOleObject methods.
692  */
693 static HRESULT WINAPI DefaultHandler_SetExtent(
694             IOleObject*        iface,
695             DWORD              dwDrawAspect,
696             SIZEL*             psizel)
697 {
698   DefaultHandler *This = impl_from_IOleObject(iface);
699
700   TRACE("(%p, %lx, (%ld x %ld))\n", iface,
701         dwDrawAspect, psizel->cx, psizel->cy);
702
703   if (This->pOleDelegate)
704     IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
705
706   return OLE_E_NOTRUNNING;
707 }
708
709 /************************************************************************
710  * DefaultHandler_GetExtent (IOleObject)
711  *
712  * The default handler's implementation of this method returns uses
713  * the cache to locate the aspect and extract the extent from it.
714  *
715  * See Windows documentation for more details on IOleObject methods.
716  */
717 static HRESULT WINAPI DefaultHandler_GetExtent(
718             IOleObject*        iface,
719             DWORD              dwDrawAspect,
720             SIZEL*             psizel)
721 {
722   DVTARGETDEVICE* targetDevice;
723   IViewObject2*   cacheView = NULL;
724   HRESULT         hres;
725
726   DefaultHandler *This = impl_from_IOleObject(iface);
727
728   TRACE("(%p, %lx, %p)\n", iface, dwDrawAspect, psizel);
729
730   if (This->pOleDelegate)
731     return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
732
733   hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
734   if (FAILED(hres))
735     return E_UNEXPECTED;
736
737   /*
738    * Prepare the call to the cache's GetExtent method.
739    *
740    * Here we would build a valid DVTARGETDEVICE structure
741    * but, since we are calling into the data cache, we
742    * know it's implementation and we'll skip this
743    * extra work until later.
744    */
745   targetDevice = NULL;
746
747   hres = IViewObject2_GetExtent(cacheView,
748                                 dwDrawAspect,
749                                 -1,
750                                 targetDevice,
751                                 psizel);
752
753   /*
754    * Cleanup
755    */
756   IViewObject2_Release(cacheView);
757
758   return hres;
759 }
760
761 /************************************************************************
762  * DefaultHandler_Advise (IOleObject)
763  *
764  * The default handler's implementation of this method simply
765  * delegates to the OleAdviseHolder.
766  *
767  * See Windows documentation for more details on IOleObject methods.
768  */
769 static HRESULT WINAPI DefaultHandler_Advise(
770             IOleObject*        iface,
771             IAdviseSink*       pAdvSink,
772             DWORD*             pdwConnection)
773 {
774   HRESULT hres = S_OK;
775   DefaultHandler *This = impl_from_IOleObject(iface);
776
777   TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
778
779   /* Make sure we have an advise holder before we start. */
780   if (!This->oleAdviseHolder)
781     hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
782
783   if (SUCCEEDED(hres))
784     hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
785                                    pAdvSink,
786                                    pdwConnection);
787
788   return hres;
789 }
790
791 /************************************************************************
792  * DefaultHandler_Unadvise (IOleObject)
793  *
794  * The default handler's implementation of this method simply
795  * delegates to the OleAdviseHolder.
796  *
797  * See Windows documentation for more details on IOleObject methods.
798  */
799 static HRESULT WINAPI DefaultHandler_Unadvise(
800             IOleObject*        iface,
801             DWORD              dwConnection)
802 {
803   DefaultHandler *This = impl_from_IOleObject(iface);
804
805   TRACE("(%p, %ld)\n", iface, dwConnection);
806
807   /*
808    * If we don't have an advise holder yet, it means we don't have
809    * a connection.
810    */
811   if (!This->oleAdviseHolder)
812     return OLE_E_NOCONNECTION;
813
814   return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
815                                    dwConnection);
816 }
817
818 /************************************************************************
819  * DefaultHandler_EnumAdvise (IOleObject)
820  *
821  * The default handler's implementation of this method simply
822  * delegates to the OleAdviseHolder.
823  *
824  * See Windows documentation for more details on IOleObject methods.
825  */
826 static HRESULT WINAPI DefaultHandler_EnumAdvise(
827             IOleObject*        iface,
828             IEnumSTATDATA**    ppenumAdvise)
829 {
830   DefaultHandler *This = impl_from_IOleObject(iface);
831
832   TRACE("(%p, %p)\n", iface, ppenumAdvise);
833
834   /* Sanity check */
835   if (!ppenumAdvise)
836     return E_POINTER;
837
838   *ppenumAdvise = NULL;
839
840   if (!This->oleAdviseHolder)
841     return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder,
842                                        ppenumAdvise);
843
844   return S_OK;
845 }
846
847 /************************************************************************
848  * DefaultHandler_GetMiscStatus (IOleObject)
849  *
850  * The default handler's implementation of this method simply delegates
851  * to OleRegGetMiscStatus.
852  *
853  * See Windows documentation for more details on IOleObject methods.
854  */
855 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
856             IOleObject*        iface,
857             DWORD              dwAspect,
858             DWORD*             pdwStatus)
859 {
860   HRESULT hres;
861   DefaultHandler *This = impl_from_IOleObject(iface);
862
863   TRACE("(%p, %lx, %p)\n", iface, dwAspect, pdwStatus);
864
865   if (This->pOleDelegate)
866     return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
867
868   hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
869
870   if (FAILED(hres))
871     *pdwStatus = 0;
872
873   return S_OK;
874 }
875
876 /************************************************************************
877  * DefaultHandler_SetColorScheme (IOleObject)
878  *
879  * This method is meaningless if the server is not running
880  *
881  * See Windows documentation for more details on IOleObject methods.
882  */
883 static HRESULT WINAPI DefaultHandler_SetColorScheme(
884             IOleObject*           iface,
885             struct tagLOGPALETTE* pLogpal)
886 {
887   DefaultHandler *This = impl_from_IOleObject(iface);
888
889   TRACE("(%p, %p))\n", iface, pLogpal);
890
891   if (This->pOleDelegate)
892     return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
893
894   return OLE_E_NOTRUNNING;
895 }
896
897 /*********************************************************
898  * Methods implementation for the IDataObject part of
899  * the DefaultHandler class.
900  */
901
902 /************************************************************************
903  * DefaultHandler_IDataObject_QueryInterface (IUnknown)
904  *
905  * See Windows documentation for more details on IUnknown methods.
906  */
907 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
908             IDataObject*     iface,
909            REFIID           riid,
910             void**           ppvObject)
911 {
912   DefaultHandler *This = impl_from_IDataObject(iface);
913
914   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
915 }
916
917 /************************************************************************
918  * DefaultHandler_IDataObject_AddRef (IUnknown)
919  *
920  * See Windows documentation for more details on IUnknown methods.
921  */
922 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
923             IDataObject*     iface)
924 {
925   DefaultHandler *This = impl_from_IDataObject(iface);
926
927   return IUnknown_AddRef(This->outerUnknown);
928 }
929
930 /************************************************************************
931  * DefaultHandler_IDataObject_Release (IUnknown)
932  *
933  * See Windows documentation for more details on IUnknown methods.
934  */
935 static ULONG WINAPI DefaultHandler_IDataObject_Release(
936             IDataObject*     iface)
937 {
938   DefaultHandler *This = impl_from_IDataObject(iface);
939
940   return IUnknown_Release(This->outerUnknown);
941 }
942
943 /************************************************************************
944  * DefaultHandler_GetData
945  *
946  * Get Data from a source dataobject using format pformatetcIn->cfFormat
947  * See Windows documentation for more details on GetData.
948  * Default handler's implementation of this method delegates to the cache.
949  */
950 static HRESULT WINAPI DefaultHandler_GetData(
951             IDataObject*     iface,
952             LPFORMATETC      pformatetcIn,
953             STGMEDIUM*       pmedium)
954 {
955   IDataObject* cacheDataObject = NULL;
956   HRESULT      hres;
957
958   DefaultHandler *This = impl_from_IDataObject(iface);
959
960   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
961
962   hres = IUnknown_QueryInterface(This->dataCache,
963                                  &IID_IDataObject,
964                                  (void**)&cacheDataObject);
965
966   if (FAILED(hres))
967     return E_UNEXPECTED;
968
969   hres = IDataObject_GetData(cacheDataObject,
970                              pformatetcIn,
971                              pmedium);
972
973   IDataObject_Release(cacheDataObject);
974
975   return hres;
976 }
977
978 static HRESULT WINAPI DefaultHandler_GetDataHere(
979             IDataObject*     iface,
980             LPFORMATETC      pformatetc,
981             STGMEDIUM*       pmedium)
982 {
983   FIXME(": Stub\n");
984   return E_NOTIMPL;
985 }
986
987 /************************************************************************
988  * DefaultHandler_QueryGetData (IDataObject)
989  *
990  * The default handler's implementation of this method delegates to
991  * the cache.
992  *
993  * See Windows documentation for more details on IDataObject methods.
994  */
995 static HRESULT WINAPI DefaultHandler_QueryGetData(
996             IDataObject*     iface,
997             LPFORMATETC      pformatetc)
998 {
999   IDataObject* cacheDataObject = NULL;
1000   HRESULT      hres;
1001
1002   DefaultHandler *This = impl_from_IDataObject(iface);
1003
1004   TRACE("(%p, %p)\n", iface, pformatetc);
1005
1006   hres = IUnknown_QueryInterface(This->dataCache,
1007                                  &IID_IDataObject,
1008                                  (void**)&cacheDataObject);
1009
1010   if (FAILED(hres))
1011     return E_UNEXPECTED;
1012
1013   hres = IDataObject_QueryGetData(cacheDataObject,
1014                                   pformatetc);
1015
1016   IDataObject_Release(cacheDataObject);
1017
1018   return hres;
1019 }
1020
1021 /************************************************************************
1022  * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1023  *
1024  * This method is meaningless if the server is not running
1025  *
1026  * See Windows documentation for more details on IDataObject methods.
1027  */
1028 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1029             IDataObject*     iface,
1030             LPFORMATETC      pformatetcIn,
1031             LPFORMATETC      pformatetcOut)
1032 {
1033   DefaultHandler *This = impl_from_IDataObject(iface);
1034   IDataObject *pDataObject;
1035   HRESULT hr;
1036
1037   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1038
1039   if (!This->pOleDelegate)
1040     return OLE_E_NOTRUNNING;
1041
1042   hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&pDataObject);
1043   return IDataObject_GetCanonicalFormatEtc(pDataObject, pformatetcIn, pformatetcOut);
1044 }
1045
1046 /************************************************************************
1047  * DefaultHandler_SetData (IDataObject)
1048  *
1049  * The default handler's implementation of this method delegates to
1050  * the cache.
1051  *
1052  * See Windows documentation for more details on IDataObject methods.
1053  */
1054 static HRESULT WINAPI DefaultHandler_SetData(
1055             IDataObject*     iface,
1056             LPFORMATETC      pformatetc,
1057             STGMEDIUM*       pmedium,
1058             BOOL             fRelease)
1059 {
1060   DefaultHandler *This = impl_from_IDataObject(iface);
1061   IDataObject* cacheDataObject = NULL;
1062   HRESULT      hres;
1063
1064   TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1065
1066   hres = IUnknown_QueryInterface(This->dataCache,
1067                                  &IID_IDataObject,
1068                                  (void**)&cacheDataObject);
1069
1070   if (FAILED(hres))
1071     return E_UNEXPECTED;
1072
1073   hres = IDataObject_SetData(cacheDataObject,
1074                              pformatetc,
1075                              pmedium,
1076                              fRelease);
1077
1078   IDataObject_Release(cacheDataObject);
1079
1080   return hres;
1081 }
1082
1083 /************************************************************************
1084  * DefaultHandler_EnumFormatEtc (IDataObject)
1085  *
1086  * The default handler's implementation of This method simply delegates
1087  * to OleRegEnumFormatEtc.
1088  *
1089  * See Windows documentation for more details on IDataObject methods.
1090  */
1091 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1092             IDataObject*     iface,
1093             DWORD            dwDirection,
1094             IEnumFORMATETC** ppenumFormatEtc)
1095 {
1096   HRESULT hres;
1097   DefaultHandler *This = impl_from_IDataObject(iface);
1098
1099   TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
1100
1101   hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1102
1103   return hres;
1104 }
1105
1106 /************************************************************************
1107  * DefaultHandler_DAdvise (IDataObject)
1108  *
1109  * The default handler's implementation of this method simply
1110  * delegates to the DataAdviseHolder.
1111  *
1112  * See Windows documentation for more details on IDataObject methods.
1113  */
1114 static HRESULT WINAPI DefaultHandler_DAdvise(
1115             IDataObject*     iface,
1116             FORMATETC*       pformatetc,
1117             DWORD            advf,
1118             IAdviseSink*     pAdvSink,
1119             DWORD*           pdwConnection)
1120 {
1121   HRESULT hres = S_OK;
1122   DefaultHandler *This = impl_from_IDataObject(iface);
1123
1124   TRACE("(%p, %p, %ld, %p, %p)\n",
1125         iface, pformatetc, advf, pAdvSink, pdwConnection);
1126
1127   /* Make sure we have a data advise holder before we start. */
1128   if (!This->dataAdviseHolder)
1129     hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1130
1131   if (SUCCEEDED(hres))
1132     hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1133                                     iface,
1134                                     pformatetc,
1135                                     advf,
1136                                     pAdvSink,
1137                                     pdwConnection);
1138
1139   return hres;
1140 }
1141
1142 /************************************************************************
1143  * DefaultHandler_DUnadvise (IDataObject)
1144  *
1145  * The default handler's implementation of this method simply
1146  * delegates to the DataAdviseHolder.
1147  *
1148  * See Windows documentation for more details on IDataObject methods.
1149  */
1150 static HRESULT WINAPI DefaultHandler_DUnadvise(
1151             IDataObject*     iface,
1152             DWORD            dwConnection)
1153 {
1154   DefaultHandler *This = impl_from_IDataObject(iface);
1155
1156   TRACE("(%p, %ld)\n", iface, dwConnection);
1157
1158   /*
1159    * If we don't have a data advise holder yet, it means that
1160    * we don't have any connections..
1161    */
1162   if (!This->dataAdviseHolder)
1163     return OLE_E_NOCONNECTION;
1164
1165   return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1166                                     dwConnection);
1167 }
1168
1169 /************************************************************************
1170  * DefaultHandler_EnumDAdvise (IDataObject)
1171  *
1172  * The default handler's implementation of this method simply
1173  * delegates to the DataAdviseHolder.
1174  *
1175  * See Windows documentation for more details on IDataObject methods.
1176  */
1177 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1178             IDataObject*     iface,
1179             IEnumSTATDATA**  ppenumAdvise)
1180 {
1181   DefaultHandler *This = impl_from_IDataObject(iface);
1182
1183   TRACE("(%p, %p)\n", iface, ppenumAdvise);
1184
1185   /* Sanity check */
1186   if (!ppenumAdvise)
1187     return E_POINTER;
1188
1189   *ppenumAdvise = NULL;
1190
1191   /* If we have a data advise holder object, delegate. */
1192   if (This->dataAdviseHolder)
1193     return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1194                                         ppenumAdvise);
1195
1196   return S_OK;
1197 }
1198
1199 /*********************************************************
1200  * Methods implementation for the IRunnableObject part
1201  * of the DefaultHandler class.
1202  */
1203
1204 /************************************************************************
1205  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1206  *
1207  * See Windows documentation for more details on IUnknown methods.
1208  */
1209 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1210             IRunnableObject*     iface,
1211             REFIID               riid,
1212             void**               ppvObject)
1213 {
1214   DefaultHandler *This = impl_from_IRunnableObject(iface);
1215
1216   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1217 }
1218
1219 /************************************************************************
1220  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1221  *
1222  * See Windows documentation for more details on IUnknown methods.
1223  */
1224 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1225             IRunnableObject*     iface)
1226 {
1227   DefaultHandler *This = impl_from_IRunnableObject(iface);
1228
1229   return IUnknown_AddRef(This->outerUnknown);
1230 }
1231
1232 /************************************************************************
1233  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1234  *
1235  * See Windows documentation for more details on IUnknown methods.
1236  */
1237 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1238             IRunnableObject*     iface)
1239 {
1240   DefaultHandler *This = impl_from_IRunnableObject(iface);
1241
1242   return IUnknown_Release(This->outerUnknown);
1243 }
1244
1245 /************************************************************************
1246  * DefaultHandler_GetRunningClass (IRunnableObject)
1247  *
1248  * See Windows documentation for more details on IRunnableObject methods.
1249  */
1250 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1251             IRunnableObject*     iface,
1252             LPCLSID              lpClsid)
1253 {
1254   FIXME("()\n");
1255   return S_OK;
1256 }
1257
1258 static HRESULT WINAPI DefaultHandler_Run(
1259             IRunnableObject*     iface,
1260             IBindCtx*            pbc)
1261 {
1262   DefaultHandler *This = impl_from_IRunnableObject(iface);
1263   HRESULT hr;
1264
1265   FIXME("(%p): semi-stub\n", pbc);
1266
1267   /* already running? if so nothing to do */
1268   if (This->pOleDelegate)
1269     return S_OK;
1270
1271   hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1272                         &IID_IOleObject, (void **)&This->pOleDelegate);
1273   if (FAILED(hr))
1274     return hr;
1275
1276   hr = IOleObject_Advise(This->pOleDelegate,
1277                          (IAdviseSink *)&This->lpvtblIAdviseSink,
1278                          &This->dwAdvConn);
1279
1280   if (SUCCEEDED(hr) && This->clientSite)
1281     hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1282
1283   if (SUCCEEDED(hr))
1284   {
1285     IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1286                               (void **)&This->pPSDelegate);
1287     if (This->pPSDelegate)
1288       hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
1289   }
1290
1291   if (SUCCEEDED(hr) && This->containerApp)
1292     hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1293                                  This->containerObj);
1294
1295   /* FIXME: do more stuff here:
1296    * - IOleObject_GetMiscStatus
1297    * - IOleObject_GetMoniker
1298    * - IOleCache_OnRun
1299    */
1300
1301   if (SUCCEEDED(hr))
1302     hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1303                                    (void **)&This->pDataDelegate);
1304
1305   if (SUCCEEDED(hr) && This->dataAdviseHolder)
1306     hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1307
1308   if (FAILED(hr))
1309     DefaultHandler_Stop(This);
1310
1311   return hr;
1312 }
1313
1314 /************************************************************************
1315  * DefaultHandler_IsRunning (IRunnableObject)
1316  *
1317  * See Windows documentation for more details on IRunnableObject methods.
1318  */
1319 static BOOL    WINAPI DefaultHandler_IsRunning(
1320             IRunnableObject*     iface)
1321 {
1322   DefaultHandler *This = impl_from_IRunnableObject(iface);
1323
1324   TRACE("()\n");
1325
1326   if (This->pOleDelegate)
1327     return TRUE;
1328   else
1329     return FALSE;
1330 }
1331
1332 /************************************************************************
1333  * DefaultHandler_LockRunning (IRunnableObject)
1334  *
1335  * See Windows documentation for more details on IRunnableObject methods.
1336  */
1337 static HRESULT WINAPI DefaultHandler_LockRunning(
1338             IRunnableObject*     iface,
1339             BOOL                 fLock,
1340             BOOL                 fLastUnlockCloses)
1341 {
1342   FIXME("()\n");
1343   return S_OK;
1344 }
1345
1346 /************************************************************************
1347  * DefaultHandler_SetContainedObject (IRunnableObject)
1348  *
1349  * See Windows documentation for more details on IRunnableObject methods.
1350  */
1351 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1352             IRunnableObject*     iface,
1353             BOOL                 fContained)
1354 {
1355   FIXME("()\n");
1356   return S_OK;
1357 }
1358
1359 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1360     IAdviseSink *iface,
1361     REFIID riid,
1362     void **ppvObject)
1363 {
1364     if (IsEqualIID(riid, &IID_IUnknown) ||
1365         IsEqualIID(riid, &IID_IAdviseSink))
1366     {
1367         *ppvObject = iface;
1368         IAdviseSink_AddRef(iface);
1369         return S_OK;
1370     }
1371
1372     return E_NOINTERFACE;
1373 }
1374
1375 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1376     IAdviseSink *iface)
1377 {
1378     DefaultHandler *This = impl_from_IAdviseSink(iface);
1379
1380     return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1381 }
1382
1383 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1384             IAdviseSink *iface)
1385 {
1386     DefaultHandler *This = impl_from_IAdviseSink(iface);
1387
1388     return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1389 }
1390
1391 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1392     IAdviseSink *iface,
1393     FORMATETC *pFormatetc,
1394     STGMEDIUM *pStgmed)
1395 {
1396     FIXME(": stub\n");
1397 }
1398
1399 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1400     IAdviseSink *iface,
1401     DWORD dwAspect,
1402     LONG lindex)
1403 {
1404     FIXME(": stub\n");
1405 }
1406
1407 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1408     IAdviseSink *iface,
1409     IMoniker *pmk)
1410 {
1411     DefaultHandler *This = impl_from_IAdviseSink(iface);
1412
1413     TRACE("(%p)\n", pmk);
1414
1415     if (This->oleAdviseHolder)
1416         IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1417 }
1418
1419 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1420     IAdviseSink *iface)
1421 {
1422     DefaultHandler *This = impl_from_IAdviseSink(iface);
1423
1424     TRACE("()\n");
1425
1426     if (This->oleAdviseHolder)
1427         IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1428 }
1429
1430 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1431     IAdviseSink *iface)
1432 {
1433     DefaultHandler *This = impl_from_IAdviseSink(iface);
1434     
1435     TRACE("()\n");
1436
1437     if (This->oleAdviseHolder)
1438         IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1439
1440     DefaultHandler_Stop(This);
1441 }
1442
1443 /*
1444  * Virtual function tables for the DefaultHandler class.
1445  */
1446 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1447 {
1448   DefaultHandler_QueryInterface,
1449   DefaultHandler_AddRef,
1450   DefaultHandler_Release,
1451   DefaultHandler_SetClientSite,
1452   DefaultHandler_GetClientSite,
1453   DefaultHandler_SetHostNames,
1454   DefaultHandler_Close,
1455   DefaultHandler_SetMoniker,
1456   DefaultHandler_GetMoniker,
1457   DefaultHandler_InitFromData,
1458   DefaultHandler_GetClipboardData,
1459   DefaultHandler_DoVerb,
1460   DefaultHandler_EnumVerbs,
1461   DefaultHandler_Update,
1462   DefaultHandler_IsUpToDate,
1463   DefaultHandler_GetUserClassID,
1464   DefaultHandler_GetUserType,
1465   DefaultHandler_SetExtent,
1466   DefaultHandler_GetExtent,
1467   DefaultHandler_Advise,
1468   DefaultHandler_Unadvise,
1469   DefaultHandler_EnumAdvise,
1470   DefaultHandler_GetMiscStatus,
1471   DefaultHandler_SetColorScheme
1472 };
1473
1474 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1475 {
1476   DefaultHandler_NDIUnknown_QueryInterface,
1477   DefaultHandler_NDIUnknown_AddRef,
1478   DefaultHandler_NDIUnknown_Release,
1479 };
1480
1481 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1482 {
1483   DefaultHandler_IDataObject_QueryInterface,
1484   DefaultHandler_IDataObject_AddRef,
1485   DefaultHandler_IDataObject_Release,
1486   DefaultHandler_GetData,
1487   DefaultHandler_GetDataHere,
1488   DefaultHandler_QueryGetData,
1489   DefaultHandler_GetCanonicalFormatEtc,
1490   DefaultHandler_SetData,
1491   DefaultHandler_EnumFormatEtc,
1492   DefaultHandler_DAdvise,
1493   DefaultHandler_DUnadvise,
1494   DefaultHandler_EnumDAdvise
1495 };
1496
1497 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1498 {
1499   DefaultHandler_IRunnableObject_QueryInterface,
1500   DefaultHandler_IRunnableObject_AddRef,
1501   DefaultHandler_IRunnableObject_Release,
1502   DefaultHandler_GetRunningClass,
1503   DefaultHandler_Run,
1504   DefaultHandler_IsRunning,
1505   DefaultHandler_LockRunning,
1506   DefaultHandler_SetContainedObject
1507 };
1508
1509 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1510 {
1511   DefaultHandler_IAdviseSink_QueryInterface,
1512   DefaultHandler_IAdviseSink_AddRef,
1513   DefaultHandler_IAdviseSink_Release,
1514   DefaultHandler_IAdviseSink_OnDataChange,
1515   DefaultHandler_IAdviseSink_OnViewChange,
1516   DefaultHandler_IAdviseSink_OnRename,
1517   DefaultHandler_IAdviseSink_OnSave,
1518   DefaultHandler_IAdviseSink_OnClose
1519 };
1520
1521 /*********************************************************
1522  * Methods implementation for the DefaultHandler class.
1523  */
1524 static DefaultHandler* DefaultHandler_Construct(
1525   REFCLSID  clsid,
1526   LPUNKNOWN pUnkOuter)
1527 {
1528   DefaultHandler* This = NULL;
1529
1530   /*
1531    * Allocate space for the object.
1532    */
1533   This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1534
1535   if (!This)
1536     return This;
1537
1538   This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1539   This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1540   This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1541   This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1542   This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1543
1544   /*
1545    * Start with one reference count. The caller of this function
1546    * must release the interface pointer when it is done.
1547    */
1548   This->ref = 1;
1549
1550   /*
1551    * Initialize the outer unknown
1552    * We don't keep a reference on the outer unknown since, the way
1553    * aggregation works, our lifetime is at least as large as it's
1554    * lifetime.
1555    */
1556   if (!pUnkOuter)
1557     pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1558
1559   This->outerUnknown = pUnkOuter;
1560
1561   /*
1562    * Create a datacache object.
1563    * We aggregate with the datacache. Make sure we pass our outer
1564    * unknown as the datacache's outer unknown.
1565    */
1566   CreateDataCache(This->outerUnknown,
1567                   clsid,
1568                   &IID_IUnknown,
1569                   (void**)&This->dataCache);
1570
1571   /*
1572    * Initialize the other data members of the class.
1573    */
1574   memcpy(&This->clsid, clsid, sizeof(CLSID));
1575   This->clientSite = NULL;
1576   This->oleAdviseHolder = NULL;
1577   This->dataAdviseHolder = NULL;
1578   This->containerApp = NULL;
1579   This->containerObj = NULL;
1580   This->pOleDelegate = NULL;
1581   This->pPSDelegate = NULL;
1582   This->pDataDelegate = NULL;
1583
1584   This->dwAdvConn = 0;
1585
1586   return This;
1587 }
1588
1589 static void DefaultHandler_Destroy(
1590   DefaultHandler* This)
1591 {
1592   /* release delegates */
1593   DefaultHandler_Stop(This);
1594
1595   /* Free the strings idenfitying the object */
1596   HeapFree( GetProcessHeap(), 0, This->containerApp );
1597   This->containerApp = NULL;
1598   HeapFree( GetProcessHeap(), 0, This->containerObj );
1599   This->containerObj = NULL;
1600
1601   /* Release our reference to the data cache. */
1602   if (This->dataCache)
1603   {
1604     IUnknown_Release(This->dataCache);
1605     This->dataCache = NULL;
1606   }
1607
1608   /* Same thing for the client site. */
1609   if (This->clientSite)
1610   {
1611     IOleClientSite_Release(This->clientSite);
1612     This->clientSite = NULL;
1613   }
1614
1615   /* And the advise holder. */
1616   if (This->oleAdviseHolder)
1617   {
1618     IOleAdviseHolder_Release(This->oleAdviseHolder);
1619     This->oleAdviseHolder = NULL;
1620   }
1621
1622   /* And the data advise holder. */
1623   if (This->dataAdviseHolder)
1624   {
1625     IDataAdviseHolder_Release(This->dataAdviseHolder);
1626     This->dataAdviseHolder = NULL;
1627   }
1628
1629   /* Free the actual default handler structure. */
1630   HeapFree(GetProcessHeap(), 0, This);
1631 }
1632
1633 /******************************************************************************
1634  * OleCreateDefaultHandler [OLE32.@]
1635  */
1636 HRESULT WINAPI OleCreateDefaultHandler(
1637   REFCLSID  clsid,
1638   LPUNKNOWN pUnkOuter,
1639   REFIID    riid,
1640   LPVOID*   ppvObj)
1641 {
1642   DefaultHandler* newHandler = NULL;
1643   HRESULT         hr         = S_OK;
1644
1645   TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1646
1647   /*
1648    * Sanity check
1649    */
1650   if (!ppvObj)
1651     return E_POINTER;
1652
1653   *ppvObj = NULL;
1654
1655   /*
1656    * If This handler is constructed for aggregation, make sure
1657    * the caller is requesting the IUnknown interface.
1658    * This is necessary because it's the only time the non-delegating
1659    * IUnknown pointer can be returned to the outside.
1660    */
1661   if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
1662     return CLASS_E_NOAGGREGATION;
1663
1664   /*
1665    * Try to construct a new instance of the class.
1666    */
1667   newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1668
1669   if (!newHandler)
1670     return E_OUTOFMEMORY;
1671
1672   /*
1673    * Make sure it supports the interface required by the caller.
1674    */
1675   hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1676
1677   /*
1678    * Release the reference obtained in the constructor. If
1679    * the QueryInterface was unsuccessful, it will free the class.
1680    */
1681   IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
1682
1683   return hr;
1684 }