ole32: Avoid a warning for VT_FILETIME in PropVariantCopy.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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   if (This->dataAdviseHolder)
420     DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
421   if (This->pDataDelegate)
422   {
423      IDataObject_Release(This->pDataDelegate);
424      This->pDataDelegate = NULL;
425   }
426   if (This->pPSDelegate)
427   {
428      IPersistStorage_Release(This->pPSDelegate);
429      This->pPSDelegate = NULL;
430   }
431   IOleObject_Release(This->pOleDelegate);
432   This->pOleDelegate = NULL;
433 }
434
435 /************************************************************************
436  * DefaultHandler_Close (IOleObject)
437  *
438  * The default handler's implementation of this method is meaningless
439  * without a running server so it does nothing.
440  *
441  * See Windows documentation for more details on IOleObject methods.
442  */
443 static HRESULT WINAPI DefaultHandler_Close(
444             IOleObject*        iface,
445             DWORD              dwSaveOption)
446 {
447   DefaultHandler *This = impl_from_IOleObject(iface);
448   HRESULT hr;
449
450   TRACE("(%ld)\n", dwSaveOption);
451
452   if (!This->pOleDelegate)
453     return S_OK;
454
455   hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
456
457   DefaultHandler_Stop(This);
458
459   return hr;
460 }
461
462 /************************************************************************
463  * DefaultHandler_SetMoniker (IOleObject)
464  *
465  * The default handler's implementation of this method does nothing.
466  *
467  * See Windows documentation for more details on IOleObject methods.
468  */
469 static HRESULT WINAPI DefaultHandler_SetMoniker(
470             IOleObject*        iface,
471             DWORD              dwWhichMoniker,
472             IMoniker*          pmk)
473 {
474   DefaultHandler *This = impl_from_IOleObject(iface);
475
476   TRACE("(%p, %ld, %p)\n",
477         iface,
478         dwWhichMoniker,
479         pmk);
480
481   if (This->pOleDelegate)
482     return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
483
484   return S_OK;
485 }
486
487 /************************************************************************
488  * DefaultHandler_GetMoniker (IOleObject)
489  *
490  * Delegate this request to the client site if we have one.
491  *
492  * See Windows documentation for more details on IOleObject methods.
493  */
494 static HRESULT WINAPI DefaultHandler_GetMoniker(
495             IOleObject*        iface,
496             DWORD              dwAssign,
497             DWORD              dwWhichMoniker,
498             IMoniker**         ppmk)
499 {
500   DefaultHandler *This = impl_from_IOleObject(iface);
501
502   TRACE("(%p, %ld, %ld, %p)\n",
503         iface, dwAssign, dwWhichMoniker, ppmk);
504
505   if (This->pOleDelegate)
506     return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
507                                  ppmk);
508
509   /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
510   if (This->clientSite)
511   {
512     return IOleClientSite_GetMoniker(This->clientSite,
513                                      dwAssign,
514                                      dwWhichMoniker,
515                                      ppmk);
516
517   }
518
519   return E_FAIL;
520 }
521
522 /************************************************************************
523  * DefaultHandler_InitFromData (IOleObject)
524  *
525  * This method is meaningless if the server is not running
526  *
527  * See Windows documentation for more details on IOleObject methods.
528  */
529 static HRESULT WINAPI DefaultHandler_InitFromData(
530             IOleObject*        iface,
531             IDataObject*       pDataObject,
532             BOOL               fCreation,
533             DWORD              dwReserved)
534 {
535   DefaultHandler *This = impl_from_IOleObject(iface);
536
537   TRACE("(%p, %p, %d, %ld)\n",
538         iface, pDataObject, fCreation, dwReserved);
539
540   if (This->pOleDelegate)
541     return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
542                                    dwReserved);
543   return OLE_E_NOTRUNNING;
544 }
545
546 /************************************************************************
547  * DefaultHandler_GetClipboardData (IOleObject)
548  *
549  * This method is meaningless if the server is not running
550  *
551  * See Windows documentation for more details on IOleObject methods.
552  */
553 static HRESULT WINAPI DefaultHandler_GetClipboardData(
554             IOleObject*        iface,
555             DWORD              dwReserved,
556             IDataObject**      ppDataObject)
557 {
558   DefaultHandler *This = impl_from_IOleObject(iface);
559
560   TRACE("(%p, %ld, %p)\n",
561         iface, dwReserved, ppDataObject);
562
563   if (This->pOleDelegate)
564     return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
565                                        ppDataObject);
566
567   return OLE_E_NOTRUNNING;
568 }
569
570 static HRESULT WINAPI DefaultHandler_DoVerb(
571             IOleObject*        iface,
572             LONG               iVerb,
573             struct tagMSG*     lpmsg,
574             IOleClientSite*    pActiveSite,
575             LONG               lindex,
576             HWND               hwndParent,
577             LPCRECT            lprcPosRect)
578 {
579   DefaultHandler *This = impl_from_IOleObject(iface);
580   IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
581   HRESULT hr;
582
583   TRACE("(%ld, %p, %p, %ld, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
584
585   hr = IRunnableObject_Run(pRunnableObj, NULL);
586   if (FAILED(hr)) return hr;
587
588   return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
589                            lindex, hwndParent, lprcPosRect);
590 }
591
592 /************************************************************************
593  * DefaultHandler_EnumVerbs (IOleObject)
594  *
595  * The default handler implementation of this method simply delegates
596  * to OleRegEnumVerbs
597  *
598  * See Windows documentation for more details on IOleObject methods.
599  */
600 static HRESULT WINAPI DefaultHandler_EnumVerbs(
601             IOleObject*        iface,
602             IEnumOLEVERB**     ppEnumOleVerb)
603 {
604   DefaultHandler *This = impl_from_IOleObject(iface);
605   HRESULT hr = OLE_S_USEREG;
606
607   TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
608
609   if (This->pOleDelegate)
610     hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
611
612   if (hr == OLE_S_USEREG)
613     return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
614   else
615     return hr;
616 }
617
618 static HRESULT WINAPI DefaultHandler_Update(
619             IOleObject*        iface)
620 {
621   FIXME(": Stub\n");
622   return E_NOTIMPL;
623 }
624
625 /************************************************************************
626  * DefaultHandler_IsUpToDate (IOleObject)
627  *
628  * This method is meaningless if the server is not running
629  *
630  * See Windows documentation for more details on IOleObject methods.
631  */
632 static HRESULT WINAPI DefaultHandler_IsUpToDate(
633             IOleObject*        iface)
634 {
635   TRACE("(%p)\n", iface);
636
637   return OLE_E_NOTRUNNING;
638 }
639
640 /************************************************************************
641  * DefaultHandler_GetUserClassID (IOleObject)
642  *
643  * TODO: Map to a new class ID if emulation is active.
644  *
645  * See Windows documentation for more details on IOleObject methods.
646  */
647 static HRESULT WINAPI DefaultHandler_GetUserClassID(
648             IOleObject*        iface,
649             CLSID*             pClsid)
650 {
651   DefaultHandler *This = impl_from_IOleObject(iface);
652
653   TRACE("(%p, %p)\n", iface, pClsid);
654
655   if (This->pOleDelegate)
656     return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
657
658   /* Sanity check. */
659   if (!pClsid)
660     return E_POINTER;
661
662   memcpy(pClsid, &This->clsid, sizeof(CLSID));
663
664   return S_OK;
665 }
666
667 /************************************************************************
668  * DefaultHandler_GetUserType (IOleObject)
669  *
670  * The default handler implementation of this method simply delegates
671  * to OleRegGetUserType
672  *
673  * See Windows documentation for more details on IOleObject methods.
674  */
675 static HRESULT WINAPI DefaultHandler_GetUserType(
676             IOleObject*        iface,
677             DWORD              dwFormOfType,
678             LPOLESTR*          pszUserType)
679 {
680   DefaultHandler *This = impl_from_IOleObject(iface);
681
682   TRACE("(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType);
683
684   return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
685 }
686
687 /************************************************************************
688  * DefaultHandler_SetExtent (IOleObject)
689  *
690  * This method is meaningless if the server is not running
691  *
692  * See Windows documentation for more details on IOleObject methods.
693  */
694 static HRESULT WINAPI DefaultHandler_SetExtent(
695             IOleObject*        iface,
696             DWORD              dwDrawAspect,
697             SIZEL*             psizel)
698 {
699   DefaultHandler *This = impl_from_IOleObject(iface);
700
701   TRACE("(%p, %lx, (%ld x %ld))\n", iface,
702         dwDrawAspect, psizel->cx, psizel->cy);
703
704   if (This->pOleDelegate)
705     IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
706
707   return OLE_E_NOTRUNNING;
708 }
709
710 /************************************************************************
711  * DefaultHandler_GetExtent (IOleObject)
712  *
713  * The default handler's implementation of this method returns uses
714  * the cache to locate the aspect and extract the extent from it.
715  *
716  * See Windows documentation for more details on IOleObject methods.
717  */
718 static HRESULT WINAPI DefaultHandler_GetExtent(
719             IOleObject*        iface,
720             DWORD              dwDrawAspect,
721             SIZEL*             psizel)
722 {
723   DVTARGETDEVICE* targetDevice;
724   IViewObject2*   cacheView = NULL;
725   HRESULT         hres;
726
727   DefaultHandler *This = impl_from_IOleObject(iface);
728
729   TRACE("(%p, %lx, %p)\n", iface, dwDrawAspect, psizel);
730
731   if (This->pOleDelegate)
732     return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
733
734   hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
735   if (FAILED(hres))
736     return E_UNEXPECTED;
737
738   /*
739    * Prepare the call to the cache's GetExtent method.
740    *
741    * Here we would build a valid DVTARGETDEVICE structure
742    * but, since we are calling into the data cache, we
743    * know it's implementation and we'll skip this
744    * extra work until later.
745    */
746   targetDevice = NULL;
747
748   hres = IViewObject2_GetExtent(cacheView,
749                                 dwDrawAspect,
750                                 -1,
751                                 targetDevice,
752                                 psizel);
753
754   /*
755    * Cleanup
756    */
757   IViewObject2_Release(cacheView);
758
759   return hres;
760 }
761
762 /************************************************************************
763  * DefaultHandler_Advise (IOleObject)
764  *
765  * The default handler's implementation of this method simply
766  * delegates to the OleAdviseHolder.
767  *
768  * See Windows documentation for more details on IOleObject methods.
769  */
770 static HRESULT WINAPI DefaultHandler_Advise(
771             IOleObject*        iface,
772             IAdviseSink*       pAdvSink,
773             DWORD*             pdwConnection)
774 {
775   HRESULT hres = S_OK;
776   DefaultHandler *This = impl_from_IOleObject(iface);
777
778   TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
779
780   /* Make sure we have an advise holder before we start. */
781   if (!This->oleAdviseHolder)
782     hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
783
784   if (SUCCEEDED(hres))
785     hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
786                                    pAdvSink,
787                                    pdwConnection);
788
789   return hres;
790 }
791
792 /************************************************************************
793  * DefaultHandler_Unadvise (IOleObject)
794  *
795  * The default handler's implementation of this method simply
796  * delegates to the OleAdviseHolder.
797  *
798  * See Windows documentation for more details on IOleObject methods.
799  */
800 static HRESULT WINAPI DefaultHandler_Unadvise(
801             IOleObject*        iface,
802             DWORD              dwConnection)
803 {
804   DefaultHandler *This = impl_from_IOleObject(iface);
805
806   TRACE("(%p, %ld)\n", iface, dwConnection);
807
808   /*
809    * If we don't have an advise holder yet, it means we don't have
810    * a connection.
811    */
812   if (!This->oleAdviseHolder)
813     return OLE_E_NOCONNECTION;
814
815   return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
816                                    dwConnection);
817 }
818
819 /************************************************************************
820  * DefaultHandler_EnumAdvise (IOleObject)
821  *
822  * The default handler's implementation of this method simply
823  * delegates to the OleAdviseHolder.
824  *
825  * See Windows documentation for more details on IOleObject methods.
826  */
827 static HRESULT WINAPI DefaultHandler_EnumAdvise(
828             IOleObject*        iface,
829             IEnumSTATDATA**    ppenumAdvise)
830 {
831   DefaultHandler *This = impl_from_IOleObject(iface);
832
833   TRACE("(%p, %p)\n", iface, ppenumAdvise);
834
835   /* Sanity check */
836   if (!ppenumAdvise)
837     return E_POINTER;
838
839   *ppenumAdvise = NULL;
840
841   if (!This->oleAdviseHolder)
842       return S_OK;
843
844   return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
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
1035   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1036
1037   if (!This->pDataDelegate)
1038     return OLE_E_NOTRUNNING;
1039
1040   return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1041 }
1042
1043 /************************************************************************
1044  * DefaultHandler_SetData (IDataObject)
1045  *
1046  * The default handler's implementation of this method delegates to
1047  * the cache.
1048  *
1049  * See Windows documentation for more details on IDataObject methods.
1050  */
1051 static HRESULT WINAPI DefaultHandler_SetData(
1052             IDataObject*     iface,
1053             LPFORMATETC      pformatetc,
1054             STGMEDIUM*       pmedium,
1055             BOOL             fRelease)
1056 {
1057   DefaultHandler *This = impl_from_IDataObject(iface);
1058   IDataObject* cacheDataObject = NULL;
1059   HRESULT      hres;
1060
1061   TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1062
1063   hres = IUnknown_QueryInterface(This->dataCache,
1064                                  &IID_IDataObject,
1065                                  (void**)&cacheDataObject);
1066
1067   if (FAILED(hres))
1068     return E_UNEXPECTED;
1069
1070   hres = IDataObject_SetData(cacheDataObject,
1071                              pformatetc,
1072                              pmedium,
1073                              fRelease);
1074
1075   IDataObject_Release(cacheDataObject);
1076
1077   return hres;
1078 }
1079
1080 /************************************************************************
1081  * DefaultHandler_EnumFormatEtc (IDataObject)
1082  *
1083  * The default handler's implementation of This method simply delegates
1084  * to OleRegEnumFormatEtc.
1085  *
1086  * See Windows documentation for more details on IDataObject methods.
1087  */
1088 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1089             IDataObject*     iface,
1090             DWORD            dwDirection,
1091             IEnumFORMATETC** ppenumFormatEtc)
1092 {
1093   HRESULT hres;
1094   DefaultHandler *This = impl_from_IDataObject(iface);
1095
1096   TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
1097
1098   hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1099
1100   return hres;
1101 }
1102
1103 /************************************************************************
1104  * DefaultHandler_DAdvise (IDataObject)
1105  *
1106  * The default handler's implementation of this method simply
1107  * delegates to the DataAdviseHolder.
1108  *
1109  * See Windows documentation for more details on IDataObject methods.
1110  */
1111 static HRESULT WINAPI DefaultHandler_DAdvise(
1112             IDataObject*     iface,
1113             FORMATETC*       pformatetc,
1114             DWORD            advf,
1115             IAdviseSink*     pAdvSink,
1116             DWORD*           pdwConnection)
1117 {
1118   HRESULT hres = S_OK;
1119   DefaultHandler *This = impl_from_IDataObject(iface);
1120
1121   TRACE("(%p, %p, %ld, %p, %p)\n",
1122         iface, pformatetc, advf, pAdvSink, pdwConnection);
1123
1124   /* Make sure we have a data advise holder before we start. */
1125   if (!This->dataAdviseHolder)
1126   {
1127     hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1128     if (SUCCEEDED(hres) && This->pDataDelegate)
1129       DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1130   }
1131
1132   if (SUCCEEDED(hres))
1133     hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1134                                     iface,
1135                                     pformatetc,
1136                                     advf,
1137                                     pAdvSink,
1138                                     pdwConnection);
1139
1140   return hres;
1141 }
1142
1143 /************************************************************************
1144  * DefaultHandler_DUnadvise (IDataObject)
1145  *
1146  * The default handler's implementation of this method simply
1147  * delegates to the DataAdviseHolder.
1148  *
1149  * See Windows documentation for more details on IDataObject methods.
1150  */
1151 static HRESULT WINAPI DefaultHandler_DUnadvise(
1152             IDataObject*     iface,
1153             DWORD            dwConnection)
1154 {
1155   DefaultHandler *This = impl_from_IDataObject(iface);
1156
1157   TRACE("(%p, %ld)\n", iface, dwConnection);
1158
1159   /*
1160    * If we don't have a data advise holder yet, it means that
1161    * we don't have any connections..
1162    */
1163   if (!This->dataAdviseHolder)
1164     return OLE_E_NOCONNECTION;
1165
1166   return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1167                                     dwConnection);
1168 }
1169
1170 /************************************************************************
1171  * DefaultHandler_EnumDAdvise (IDataObject)
1172  *
1173  * The default handler's implementation of this method simply
1174  * delegates to the DataAdviseHolder.
1175  *
1176  * See Windows documentation for more details on IDataObject methods.
1177  */
1178 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1179             IDataObject*     iface,
1180             IEnumSTATDATA**  ppenumAdvise)
1181 {
1182   DefaultHandler *This = impl_from_IDataObject(iface);
1183
1184   TRACE("(%p, %p)\n", iface, ppenumAdvise);
1185
1186   /* Sanity check */
1187   if (!ppenumAdvise)
1188     return E_POINTER;
1189
1190   *ppenumAdvise = NULL;
1191
1192   /* If we have a data advise holder object, delegate. */
1193   if (This->dataAdviseHolder)
1194     return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1195                                         ppenumAdvise);
1196
1197   return S_OK;
1198 }
1199
1200 /*********************************************************
1201  * Methods implementation for the IRunnableObject part
1202  * of the DefaultHandler class.
1203  */
1204
1205 /************************************************************************
1206  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1207  *
1208  * See Windows documentation for more details on IUnknown methods.
1209  */
1210 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1211             IRunnableObject*     iface,
1212             REFIID               riid,
1213             void**               ppvObject)
1214 {
1215   DefaultHandler *This = impl_from_IRunnableObject(iface);
1216
1217   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1218 }
1219
1220 /************************************************************************
1221  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1222  *
1223  * See Windows documentation for more details on IUnknown methods.
1224  */
1225 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1226             IRunnableObject*     iface)
1227 {
1228   DefaultHandler *This = impl_from_IRunnableObject(iface);
1229
1230   return IUnknown_AddRef(This->outerUnknown);
1231 }
1232
1233 /************************************************************************
1234  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1235  *
1236  * See Windows documentation for more details on IUnknown methods.
1237  */
1238 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1239             IRunnableObject*     iface)
1240 {
1241   DefaultHandler *This = impl_from_IRunnableObject(iface);
1242
1243   return IUnknown_Release(This->outerUnknown);
1244 }
1245
1246 /************************************************************************
1247  * DefaultHandler_GetRunningClass (IRunnableObject)
1248  *
1249  * See Windows documentation for more details on IRunnableObject methods.
1250  */
1251 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1252             IRunnableObject*     iface,
1253             LPCLSID              lpClsid)
1254 {
1255   FIXME("()\n");
1256   return S_OK;
1257 }
1258
1259 static HRESULT WINAPI DefaultHandler_Run(
1260             IRunnableObject*     iface,
1261             IBindCtx*            pbc)
1262 {
1263   DefaultHandler *This = impl_from_IRunnableObject(iface);
1264   HRESULT hr;
1265
1266   FIXME("(%p): semi-stub\n", pbc);
1267
1268   /* already running? if so nothing to do */
1269   if (This->pOleDelegate)
1270     return S_OK;
1271
1272   hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1273                         &IID_IOleObject, (void **)&This->pOleDelegate);
1274   if (FAILED(hr))
1275     return hr;
1276
1277   hr = IOleObject_Advise(This->pOleDelegate,
1278                          (IAdviseSink *)&This->lpvtblIAdviseSink,
1279                          &This->dwAdvConn);
1280
1281   if (SUCCEEDED(hr) && This->clientSite)
1282     hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1283
1284   if (SUCCEEDED(hr))
1285   {
1286     IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1287                               (void **)&This->pPSDelegate);
1288     if (This->pPSDelegate)
1289       hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
1290   }
1291
1292   if (SUCCEEDED(hr) && This->containerApp)
1293     hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1294                                  This->containerObj);
1295
1296   /* FIXME: do more stuff here:
1297    * - IOleObject_GetMiscStatus
1298    * - IOleObject_GetMoniker
1299    * - IOleCache_OnRun
1300    */
1301
1302   if (SUCCEEDED(hr))
1303     hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1304                                    (void **)&This->pDataDelegate);
1305
1306   if (SUCCEEDED(hr) && This->dataAdviseHolder)
1307     hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1308
1309   if (FAILED(hr))
1310     DefaultHandler_Stop(This);
1311
1312   return hr;
1313 }
1314
1315 /************************************************************************
1316  * DefaultHandler_IsRunning (IRunnableObject)
1317  *
1318  * See Windows documentation for more details on IRunnableObject methods.
1319  */
1320 static BOOL    WINAPI DefaultHandler_IsRunning(
1321             IRunnableObject*     iface)
1322 {
1323   DefaultHandler *This = impl_from_IRunnableObject(iface);
1324
1325   TRACE("()\n");
1326
1327   if (This->pOleDelegate)
1328     return TRUE;
1329   else
1330     return FALSE;
1331 }
1332
1333 /************************************************************************
1334  * DefaultHandler_LockRunning (IRunnableObject)
1335  *
1336  * See Windows documentation for more details on IRunnableObject methods.
1337  */
1338 static HRESULT WINAPI DefaultHandler_LockRunning(
1339             IRunnableObject*     iface,
1340             BOOL                 fLock,
1341             BOOL                 fLastUnlockCloses)
1342 {
1343   FIXME("()\n");
1344   return S_OK;
1345 }
1346
1347 /************************************************************************
1348  * DefaultHandler_SetContainedObject (IRunnableObject)
1349  *
1350  * See Windows documentation for more details on IRunnableObject methods.
1351  */
1352 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1353             IRunnableObject*     iface,
1354             BOOL                 fContained)
1355 {
1356   FIXME("()\n");
1357   return S_OK;
1358 }
1359
1360 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1361     IAdviseSink *iface,
1362     REFIID riid,
1363     void **ppvObject)
1364 {
1365     if (IsEqualIID(riid, &IID_IUnknown) ||
1366         IsEqualIID(riid, &IID_IAdviseSink))
1367     {
1368         *ppvObject = iface;
1369         IAdviseSink_AddRef(iface);
1370         return S_OK;
1371     }
1372
1373     return E_NOINTERFACE;
1374 }
1375
1376 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1377     IAdviseSink *iface)
1378 {
1379     DefaultHandler *This = impl_from_IAdviseSink(iface);
1380
1381     return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1382 }
1383
1384 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1385             IAdviseSink *iface)
1386 {
1387     DefaultHandler *This = impl_from_IAdviseSink(iface);
1388
1389     return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1390 }
1391
1392 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1393     IAdviseSink *iface,
1394     FORMATETC *pFormatetc,
1395     STGMEDIUM *pStgmed)
1396 {
1397     FIXME(": stub\n");
1398 }
1399
1400 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1401     IAdviseSink *iface,
1402     DWORD dwAspect,
1403     LONG lindex)
1404 {
1405     FIXME(": stub\n");
1406 }
1407
1408 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1409     IAdviseSink *iface,
1410     IMoniker *pmk)
1411 {
1412     DefaultHandler *This = impl_from_IAdviseSink(iface);
1413
1414     TRACE("(%p)\n", pmk);
1415
1416     if (This->oleAdviseHolder)
1417         IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1418 }
1419
1420 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1421     IAdviseSink *iface)
1422 {
1423     DefaultHandler *This = impl_from_IAdviseSink(iface);
1424
1425     TRACE("()\n");
1426
1427     if (This->oleAdviseHolder)
1428         IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1429 }
1430
1431 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1432     IAdviseSink *iface)
1433 {
1434     DefaultHandler *This = impl_from_IAdviseSink(iface);
1435     
1436     TRACE("()\n");
1437
1438     if (This->oleAdviseHolder)
1439         IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1440
1441     DefaultHandler_Stop(This);
1442 }
1443
1444 /*
1445  * Virtual function tables for the DefaultHandler class.
1446  */
1447 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1448 {
1449   DefaultHandler_QueryInterface,
1450   DefaultHandler_AddRef,
1451   DefaultHandler_Release,
1452   DefaultHandler_SetClientSite,
1453   DefaultHandler_GetClientSite,
1454   DefaultHandler_SetHostNames,
1455   DefaultHandler_Close,
1456   DefaultHandler_SetMoniker,
1457   DefaultHandler_GetMoniker,
1458   DefaultHandler_InitFromData,
1459   DefaultHandler_GetClipboardData,
1460   DefaultHandler_DoVerb,
1461   DefaultHandler_EnumVerbs,
1462   DefaultHandler_Update,
1463   DefaultHandler_IsUpToDate,
1464   DefaultHandler_GetUserClassID,
1465   DefaultHandler_GetUserType,
1466   DefaultHandler_SetExtent,
1467   DefaultHandler_GetExtent,
1468   DefaultHandler_Advise,
1469   DefaultHandler_Unadvise,
1470   DefaultHandler_EnumAdvise,
1471   DefaultHandler_GetMiscStatus,
1472   DefaultHandler_SetColorScheme
1473 };
1474
1475 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1476 {
1477   DefaultHandler_NDIUnknown_QueryInterface,
1478   DefaultHandler_NDIUnknown_AddRef,
1479   DefaultHandler_NDIUnknown_Release,
1480 };
1481
1482 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1483 {
1484   DefaultHandler_IDataObject_QueryInterface,
1485   DefaultHandler_IDataObject_AddRef,
1486   DefaultHandler_IDataObject_Release,
1487   DefaultHandler_GetData,
1488   DefaultHandler_GetDataHere,
1489   DefaultHandler_QueryGetData,
1490   DefaultHandler_GetCanonicalFormatEtc,
1491   DefaultHandler_SetData,
1492   DefaultHandler_EnumFormatEtc,
1493   DefaultHandler_DAdvise,
1494   DefaultHandler_DUnadvise,
1495   DefaultHandler_EnumDAdvise
1496 };
1497
1498 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1499 {
1500   DefaultHandler_IRunnableObject_QueryInterface,
1501   DefaultHandler_IRunnableObject_AddRef,
1502   DefaultHandler_IRunnableObject_Release,
1503   DefaultHandler_GetRunningClass,
1504   DefaultHandler_Run,
1505   DefaultHandler_IsRunning,
1506   DefaultHandler_LockRunning,
1507   DefaultHandler_SetContainedObject
1508 };
1509
1510 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1511 {
1512   DefaultHandler_IAdviseSink_QueryInterface,
1513   DefaultHandler_IAdviseSink_AddRef,
1514   DefaultHandler_IAdviseSink_Release,
1515   DefaultHandler_IAdviseSink_OnDataChange,
1516   DefaultHandler_IAdviseSink_OnViewChange,
1517   DefaultHandler_IAdviseSink_OnRename,
1518   DefaultHandler_IAdviseSink_OnSave,
1519   DefaultHandler_IAdviseSink_OnClose
1520 };
1521
1522 /*********************************************************
1523  * Methods implementation for the DefaultHandler class.
1524  */
1525 static DefaultHandler* DefaultHandler_Construct(
1526   REFCLSID  clsid,
1527   LPUNKNOWN pUnkOuter)
1528 {
1529   DefaultHandler* This = NULL;
1530
1531   /*
1532    * Allocate space for the object.
1533    */
1534   This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1535
1536   if (!This)
1537     return This;
1538
1539   This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1540   This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1541   This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1542   This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1543   This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1544
1545   /*
1546    * Start with one reference count. The caller of this function
1547    * must release the interface pointer when it is done.
1548    */
1549   This->ref = 1;
1550
1551   /*
1552    * Initialize the outer unknown
1553    * We don't keep a reference on the outer unknown since, the way
1554    * aggregation works, our lifetime is at least as large as it's
1555    * lifetime.
1556    */
1557   if (!pUnkOuter)
1558     pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1559
1560   This->outerUnknown = pUnkOuter;
1561
1562   /*
1563    * Create a datacache object.
1564    * We aggregate with the datacache. Make sure we pass our outer
1565    * unknown as the datacache's outer unknown.
1566    */
1567   CreateDataCache(This->outerUnknown,
1568                   clsid,
1569                   &IID_IUnknown,
1570                   (void**)&This->dataCache);
1571
1572   /*
1573    * Initialize the other data members of the class.
1574    */
1575   memcpy(&This->clsid, clsid, sizeof(CLSID));
1576   This->clientSite = NULL;
1577   This->oleAdviseHolder = NULL;
1578   This->dataAdviseHolder = NULL;
1579   This->containerApp = NULL;
1580   This->containerObj = NULL;
1581   This->pOleDelegate = NULL;
1582   This->pPSDelegate = NULL;
1583   This->pDataDelegate = NULL;
1584
1585   This->dwAdvConn = 0;
1586
1587   return This;
1588 }
1589
1590 static void DefaultHandler_Destroy(
1591   DefaultHandler* This)
1592 {
1593   /* release delegates */
1594   DefaultHandler_Stop(This);
1595
1596   /* Free the strings idenfitying the object */
1597   HeapFree( GetProcessHeap(), 0, This->containerApp );
1598   This->containerApp = NULL;
1599   HeapFree( GetProcessHeap(), 0, This->containerObj );
1600   This->containerObj = NULL;
1601
1602   /* Release our reference to the data cache. */
1603   if (This->dataCache)
1604   {
1605     IUnknown_Release(This->dataCache);
1606     This->dataCache = NULL;
1607   }
1608
1609   /* Same thing for the client site. */
1610   if (This->clientSite)
1611   {
1612     IOleClientSite_Release(This->clientSite);
1613     This->clientSite = NULL;
1614   }
1615
1616   /* And the advise holder. */
1617   if (This->oleAdviseHolder)
1618   {
1619     IOleAdviseHolder_Release(This->oleAdviseHolder);
1620     This->oleAdviseHolder = NULL;
1621   }
1622
1623   /* And the data advise holder. */
1624   if (This->dataAdviseHolder)
1625   {
1626     IDataAdviseHolder_Release(This->dataAdviseHolder);
1627     This->dataAdviseHolder = NULL;
1628   }
1629
1630   /* Free the actual default handler structure. */
1631   HeapFree(GetProcessHeap(), 0, This);
1632 }
1633
1634 /******************************************************************************
1635  * OleCreateDefaultHandler [OLE32.@]
1636  */
1637 HRESULT WINAPI OleCreateDefaultHandler(
1638   REFCLSID  clsid,
1639   LPUNKNOWN pUnkOuter,
1640   REFIID    riid,
1641   LPVOID*   ppvObj)
1642 {
1643   DefaultHandler* newHandler = NULL;
1644   HRESULT         hr         = S_OK;
1645
1646   TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1647
1648   /*
1649    * Sanity check
1650    */
1651   if (!ppvObj)
1652     return E_POINTER;
1653
1654   *ppvObj = NULL;
1655
1656   /*
1657    * If This handler is constructed for aggregation, make sure
1658    * the caller is requesting the IUnknown interface.
1659    * This is necessary because it's the only time the non-delegating
1660    * IUnknown pointer can be returned to the outside.
1661    */
1662   if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
1663     return CLASS_E_NOAGGREGATION;
1664
1665   /*
1666    * Try to construct a new instance of the class.
1667    */
1668   newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1669
1670   if (!newHandler)
1671     return E_OUTOFMEMORY;
1672
1673   /*
1674    * Make sure it supports the interface required by the caller.
1675    */
1676   hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1677
1678   /*
1679    * Release the reference obtained in the constructor. If
1680    * the QueryInterface was unsuccessful, it will free the class.
1681    */
1682   IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
1683
1684   return hr;
1685 }