dinput: Implement GetObjectInfo[A|W] in base device class.
[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("(%d)\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, %d, %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, %d, %d, %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, %d)\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, %d, %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("(%d, %p, %p, %d, %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, %d, %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, %x, (%d x %d))\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, %x, %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, %d)\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, %x, %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   if (FAILED(hres) && This->pDataDelegate)
976     hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
977
978   return hres;
979 }
980
981 static HRESULT WINAPI DefaultHandler_GetDataHere(
982             IDataObject*     iface,
983             LPFORMATETC      pformatetc,
984             STGMEDIUM*       pmedium)
985 {
986   FIXME(": Stub\n");
987   return E_NOTIMPL;
988 }
989
990 /************************************************************************
991  * DefaultHandler_QueryGetData (IDataObject)
992  *
993  * The default handler's implementation of this method delegates to
994  * the cache.
995  *
996  * See Windows documentation for more details on IDataObject methods.
997  */
998 static HRESULT WINAPI DefaultHandler_QueryGetData(
999             IDataObject*     iface,
1000             LPFORMATETC      pformatetc)
1001 {
1002   IDataObject* cacheDataObject = NULL;
1003   HRESULT      hres;
1004
1005   DefaultHandler *This = impl_from_IDataObject(iface);
1006
1007   TRACE("(%p, %p)\n", iface, pformatetc);
1008
1009   hres = IUnknown_QueryInterface(This->dataCache,
1010                                  &IID_IDataObject,
1011                                  (void**)&cacheDataObject);
1012
1013   if (FAILED(hres))
1014     return E_UNEXPECTED;
1015
1016   hres = IDataObject_QueryGetData(cacheDataObject,
1017                                   pformatetc);
1018
1019   IDataObject_Release(cacheDataObject);
1020
1021   if (FAILED(hres) && This->pDataDelegate)
1022     hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1023
1024   return hres;
1025 }
1026
1027 /************************************************************************
1028  * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1029  *
1030  * This method is meaningless if the server is not running
1031  *
1032  * See Windows documentation for more details on IDataObject methods.
1033  */
1034 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1035             IDataObject*     iface,
1036             LPFORMATETC      pformatetcIn,
1037             LPFORMATETC      pformatetcOut)
1038 {
1039   DefaultHandler *This = impl_from_IDataObject(iface);
1040
1041   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1042
1043   if (!This->pDataDelegate)
1044     return OLE_E_NOTRUNNING;
1045
1046   return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1047 }
1048
1049 /************************************************************************
1050  * DefaultHandler_SetData (IDataObject)
1051  *
1052  * The default handler's implementation of this method delegates to
1053  * the cache.
1054  *
1055  * See Windows documentation for more details on IDataObject methods.
1056  */
1057 static HRESULT WINAPI DefaultHandler_SetData(
1058             IDataObject*     iface,
1059             LPFORMATETC      pformatetc,
1060             STGMEDIUM*       pmedium,
1061             BOOL             fRelease)
1062 {
1063   DefaultHandler *This = impl_from_IDataObject(iface);
1064   IDataObject* cacheDataObject = NULL;
1065   HRESULT      hres;
1066
1067   TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1068
1069   hres = IUnknown_QueryInterface(This->dataCache,
1070                                  &IID_IDataObject,
1071                                  (void**)&cacheDataObject);
1072
1073   if (FAILED(hres))
1074     return E_UNEXPECTED;
1075
1076   hres = IDataObject_SetData(cacheDataObject,
1077                              pformatetc,
1078                              pmedium,
1079                              fRelease);
1080
1081   IDataObject_Release(cacheDataObject);
1082
1083   return hres;
1084 }
1085
1086 /************************************************************************
1087  * DefaultHandler_EnumFormatEtc (IDataObject)
1088  *
1089  * The default handler's implementation of This method simply delegates
1090  * to OleRegEnumFormatEtc.
1091  *
1092  * See Windows documentation for more details on IDataObject methods.
1093  */
1094 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1095             IDataObject*     iface,
1096             DWORD            dwDirection,
1097             IEnumFORMATETC** ppenumFormatEtc)
1098 {
1099   HRESULT hres;
1100   DefaultHandler *This = impl_from_IDataObject(iface);
1101
1102   TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1103
1104   hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1105
1106   return hres;
1107 }
1108
1109 /************************************************************************
1110  * DefaultHandler_DAdvise (IDataObject)
1111  *
1112  * The default handler's implementation of this method simply
1113  * delegates to the DataAdviseHolder.
1114  *
1115  * See Windows documentation for more details on IDataObject methods.
1116  */
1117 static HRESULT WINAPI DefaultHandler_DAdvise(
1118             IDataObject*     iface,
1119             FORMATETC*       pformatetc,
1120             DWORD            advf,
1121             IAdviseSink*     pAdvSink,
1122             DWORD*           pdwConnection)
1123 {
1124   HRESULT hres = S_OK;
1125   DefaultHandler *This = impl_from_IDataObject(iface);
1126
1127   TRACE("(%p, %p, %d, %p, %p)\n",
1128         iface, pformatetc, advf, pAdvSink, pdwConnection);
1129
1130   /* Make sure we have a data advise holder before we start. */
1131   if (!This->dataAdviseHolder)
1132   {
1133     hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1134     if (SUCCEEDED(hres) && This->pDataDelegate)
1135       DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1136   }
1137
1138   if (SUCCEEDED(hres))
1139     hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1140                                     iface,
1141                                     pformatetc,
1142                                     advf,
1143                                     pAdvSink,
1144                                     pdwConnection);
1145
1146   return hres;
1147 }
1148
1149 /************************************************************************
1150  * DefaultHandler_DUnadvise (IDataObject)
1151  *
1152  * The default handler's implementation of this method simply
1153  * delegates to the DataAdviseHolder.
1154  *
1155  * See Windows documentation for more details on IDataObject methods.
1156  */
1157 static HRESULT WINAPI DefaultHandler_DUnadvise(
1158             IDataObject*     iface,
1159             DWORD            dwConnection)
1160 {
1161   DefaultHandler *This = impl_from_IDataObject(iface);
1162
1163   TRACE("(%p, %d)\n", iface, dwConnection);
1164
1165   /*
1166    * If we don't have a data advise holder yet, it means that
1167    * we don't have any connections..
1168    */
1169   if (!This->dataAdviseHolder)
1170     return OLE_E_NOCONNECTION;
1171
1172   return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1173                                     dwConnection);
1174 }
1175
1176 /************************************************************************
1177  * DefaultHandler_EnumDAdvise (IDataObject)
1178  *
1179  * The default handler's implementation of this method simply
1180  * delegates to the DataAdviseHolder.
1181  *
1182  * See Windows documentation for more details on IDataObject methods.
1183  */
1184 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1185             IDataObject*     iface,
1186             IEnumSTATDATA**  ppenumAdvise)
1187 {
1188   DefaultHandler *This = impl_from_IDataObject(iface);
1189
1190   TRACE("(%p, %p)\n", iface, ppenumAdvise);
1191
1192   /* Sanity check */
1193   if (!ppenumAdvise)
1194     return E_POINTER;
1195
1196   *ppenumAdvise = NULL;
1197
1198   /* If we have a data advise holder object, delegate. */
1199   if (This->dataAdviseHolder)
1200     return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1201                                         ppenumAdvise);
1202
1203   return S_OK;
1204 }
1205
1206 /*********************************************************
1207  * Methods implementation for the IRunnableObject part
1208  * of the DefaultHandler class.
1209  */
1210
1211 /************************************************************************
1212  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1213  *
1214  * See Windows documentation for more details on IUnknown methods.
1215  */
1216 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1217             IRunnableObject*     iface,
1218             REFIID               riid,
1219             void**               ppvObject)
1220 {
1221   DefaultHandler *This = impl_from_IRunnableObject(iface);
1222
1223   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1224 }
1225
1226 /************************************************************************
1227  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1228  *
1229  * See Windows documentation for more details on IUnknown methods.
1230  */
1231 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1232             IRunnableObject*     iface)
1233 {
1234   DefaultHandler *This = impl_from_IRunnableObject(iface);
1235
1236   return IUnknown_AddRef(This->outerUnknown);
1237 }
1238
1239 /************************************************************************
1240  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1241  *
1242  * See Windows documentation for more details on IUnknown methods.
1243  */
1244 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1245             IRunnableObject*     iface)
1246 {
1247   DefaultHandler *This = impl_from_IRunnableObject(iface);
1248
1249   return IUnknown_Release(This->outerUnknown);
1250 }
1251
1252 /************************************************************************
1253  * DefaultHandler_GetRunningClass (IRunnableObject)
1254  *
1255  * See Windows documentation for more details on IRunnableObject methods.
1256  */
1257 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1258             IRunnableObject*     iface,
1259             LPCLSID              lpClsid)
1260 {
1261   FIXME("()\n");
1262   return S_OK;
1263 }
1264
1265 static HRESULT WINAPI DefaultHandler_Run(
1266             IRunnableObject*     iface,
1267             IBindCtx*            pbc)
1268 {
1269   DefaultHandler *This = impl_from_IRunnableObject(iface);
1270   HRESULT hr;
1271
1272   FIXME("(%p): semi-stub\n", pbc);
1273
1274   /* already running? if so nothing to do */
1275   if (This->pOleDelegate)
1276     return S_OK;
1277
1278   hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1279                         &IID_IOleObject, (void **)&This->pOleDelegate);
1280   if (FAILED(hr))
1281     return hr;
1282
1283   hr = IOleObject_Advise(This->pOleDelegate,
1284                          (IAdviseSink *)&This->lpvtblIAdviseSink,
1285                          &This->dwAdvConn);
1286
1287   if (SUCCEEDED(hr) && This->clientSite)
1288     hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1289
1290   if (SUCCEEDED(hr))
1291   {
1292     IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1293                               (void **)&This->pPSDelegate);
1294     if (This->pPSDelegate)
1295       hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
1296   }
1297
1298   if (SUCCEEDED(hr) && This->containerApp)
1299     hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1300                                  This->containerObj);
1301
1302   /* FIXME: do more stuff here:
1303    * - IOleObject_GetMiscStatus
1304    * - IOleObject_GetMoniker
1305    * - IOleCache_OnRun
1306    */
1307
1308   if (SUCCEEDED(hr))
1309     hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1310                                    (void **)&This->pDataDelegate);
1311
1312   if (SUCCEEDED(hr) && This->dataAdviseHolder)
1313     hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1314
1315   if (FAILED(hr))
1316     DefaultHandler_Stop(This);
1317
1318   return hr;
1319 }
1320
1321 /************************************************************************
1322  * DefaultHandler_IsRunning (IRunnableObject)
1323  *
1324  * See Windows documentation for more details on IRunnableObject methods.
1325  */
1326 static BOOL    WINAPI DefaultHandler_IsRunning(
1327             IRunnableObject*     iface)
1328 {
1329   DefaultHandler *This = impl_from_IRunnableObject(iface);
1330
1331   TRACE("()\n");
1332
1333   if (This->pOleDelegate)
1334     return TRUE;
1335   else
1336     return FALSE;
1337 }
1338
1339 /************************************************************************
1340  * DefaultHandler_LockRunning (IRunnableObject)
1341  *
1342  * See Windows documentation for more details on IRunnableObject methods.
1343  */
1344 static HRESULT WINAPI DefaultHandler_LockRunning(
1345             IRunnableObject*     iface,
1346             BOOL                 fLock,
1347             BOOL                 fLastUnlockCloses)
1348 {
1349   FIXME("()\n");
1350   return S_OK;
1351 }
1352
1353 /************************************************************************
1354  * DefaultHandler_SetContainedObject (IRunnableObject)
1355  *
1356  * See Windows documentation for more details on IRunnableObject methods.
1357  */
1358 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1359             IRunnableObject*     iface,
1360             BOOL                 fContained)
1361 {
1362   FIXME("()\n");
1363   return S_OK;
1364 }
1365
1366 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1367     IAdviseSink *iface,
1368     REFIID riid,
1369     void **ppvObject)
1370 {
1371     if (IsEqualIID(riid, &IID_IUnknown) ||
1372         IsEqualIID(riid, &IID_IAdviseSink))
1373     {
1374         *ppvObject = iface;
1375         IAdviseSink_AddRef(iface);
1376         return S_OK;
1377     }
1378
1379     return E_NOINTERFACE;
1380 }
1381
1382 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1383     IAdviseSink *iface)
1384 {
1385     DefaultHandler *This = impl_from_IAdviseSink(iface);
1386
1387     return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
1388 }
1389
1390 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1391             IAdviseSink *iface)
1392 {
1393     DefaultHandler *This = impl_from_IAdviseSink(iface);
1394
1395     return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
1396 }
1397
1398 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1399     IAdviseSink *iface,
1400     FORMATETC *pFormatetc,
1401     STGMEDIUM *pStgmed)
1402 {
1403     FIXME(": stub\n");
1404 }
1405
1406 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1407     IAdviseSink *iface,
1408     DWORD dwAspect,
1409     LONG lindex)
1410 {
1411     FIXME(": stub\n");
1412 }
1413
1414 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1415     IAdviseSink *iface,
1416     IMoniker *pmk)
1417 {
1418     DefaultHandler *This = impl_from_IAdviseSink(iface);
1419
1420     TRACE("(%p)\n", pmk);
1421
1422     if (This->oleAdviseHolder)
1423         IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1424 }
1425
1426 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1427     IAdviseSink *iface)
1428 {
1429     DefaultHandler *This = impl_from_IAdviseSink(iface);
1430
1431     TRACE("()\n");
1432
1433     if (This->oleAdviseHolder)
1434         IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1435 }
1436
1437 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1438     IAdviseSink *iface)
1439 {
1440     DefaultHandler *This = impl_from_IAdviseSink(iface);
1441     
1442     TRACE("()\n");
1443
1444     if (This->oleAdviseHolder)
1445         IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1446
1447     DefaultHandler_Stop(This);
1448 }
1449
1450 /*
1451  * Virtual function tables for the DefaultHandler class.
1452  */
1453 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1454 {
1455   DefaultHandler_QueryInterface,
1456   DefaultHandler_AddRef,
1457   DefaultHandler_Release,
1458   DefaultHandler_SetClientSite,
1459   DefaultHandler_GetClientSite,
1460   DefaultHandler_SetHostNames,
1461   DefaultHandler_Close,
1462   DefaultHandler_SetMoniker,
1463   DefaultHandler_GetMoniker,
1464   DefaultHandler_InitFromData,
1465   DefaultHandler_GetClipboardData,
1466   DefaultHandler_DoVerb,
1467   DefaultHandler_EnumVerbs,
1468   DefaultHandler_Update,
1469   DefaultHandler_IsUpToDate,
1470   DefaultHandler_GetUserClassID,
1471   DefaultHandler_GetUserType,
1472   DefaultHandler_SetExtent,
1473   DefaultHandler_GetExtent,
1474   DefaultHandler_Advise,
1475   DefaultHandler_Unadvise,
1476   DefaultHandler_EnumAdvise,
1477   DefaultHandler_GetMiscStatus,
1478   DefaultHandler_SetColorScheme
1479 };
1480
1481 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1482 {
1483   DefaultHandler_NDIUnknown_QueryInterface,
1484   DefaultHandler_NDIUnknown_AddRef,
1485   DefaultHandler_NDIUnknown_Release,
1486 };
1487
1488 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1489 {
1490   DefaultHandler_IDataObject_QueryInterface,
1491   DefaultHandler_IDataObject_AddRef,
1492   DefaultHandler_IDataObject_Release,
1493   DefaultHandler_GetData,
1494   DefaultHandler_GetDataHere,
1495   DefaultHandler_QueryGetData,
1496   DefaultHandler_GetCanonicalFormatEtc,
1497   DefaultHandler_SetData,
1498   DefaultHandler_EnumFormatEtc,
1499   DefaultHandler_DAdvise,
1500   DefaultHandler_DUnadvise,
1501   DefaultHandler_EnumDAdvise
1502 };
1503
1504 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1505 {
1506   DefaultHandler_IRunnableObject_QueryInterface,
1507   DefaultHandler_IRunnableObject_AddRef,
1508   DefaultHandler_IRunnableObject_Release,
1509   DefaultHandler_GetRunningClass,
1510   DefaultHandler_Run,
1511   DefaultHandler_IsRunning,
1512   DefaultHandler_LockRunning,
1513   DefaultHandler_SetContainedObject
1514 };
1515
1516 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1517 {
1518   DefaultHandler_IAdviseSink_QueryInterface,
1519   DefaultHandler_IAdviseSink_AddRef,
1520   DefaultHandler_IAdviseSink_Release,
1521   DefaultHandler_IAdviseSink_OnDataChange,
1522   DefaultHandler_IAdviseSink_OnViewChange,
1523   DefaultHandler_IAdviseSink_OnRename,
1524   DefaultHandler_IAdviseSink_OnSave,
1525   DefaultHandler_IAdviseSink_OnClose
1526 };
1527
1528 /*********************************************************
1529  * Methods implementation for the DefaultHandler class.
1530  */
1531 static DefaultHandler* DefaultHandler_Construct(
1532   REFCLSID  clsid,
1533   LPUNKNOWN pUnkOuter)
1534 {
1535   DefaultHandler* This = NULL;
1536
1537   /*
1538    * Allocate space for the object.
1539    */
1540   This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1541
1542   if (!This)
1543     return This;
1544
1545   This->lpVtbl = &DefaultHandler_IOleObject_VTable;
1546   This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
1547   This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
1548   This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1549   This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1550
1551   /*
1552    * Start with one reference count. The caller of this function
1553    * must release the interface pointer when it is done.
1554    */
1555   This->ref = 1;
1556
1557   /*
1558    * Initialize the outer unknown
1559    * We don't keep a reference on the outer unknown since, the way
1560    * aggregation works, our lifetime is at least as large as it's
1561    * lifetime.
1562    */
1563   if (!pUnkOuter)
1564     pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1565
1566   This->outerUnknown = pUnkOuter;
1567
1568   /*
1569    * Create a datacache object.
1570    * We aggregate with the datacache. Make sure we pass our outer
1571    * unknown as the datacache's outer unknown.
1572    */
1573   CreateDataCache(This->outerUnknown,
1574                   clsid,
1575                   &IID_IUnknown,
1576                   (void**)&This->dataCache);
1577
1578   /*
1579    * Initialize the other data members of the class.
1580    */
1581   memcpy(&This->clsid, clsid, sizeof(CLSID));
1582   This->clientSite = NULL;
1583   This->oleAdviseHolder = NULL;
1584   This->dataAdviseHolder = NULL;
1585   This->containerApp = NULL;
1586   This->containerObj = NULL;
1587   This->pOleDelegate = NULL;
1588   This->pPSDelegate = NULL;
1589   This->pDataDelegate = NULL;
1590
1591   This->dwAdvConn = 0;
1592
1593   return This;
1594 }
1595
1596 static void DefaultHandler_Destroy(
1597   DefaultHandler* This)
1598 {
1599   /* release delegates */
1600   DefaultHandler_Stop(This);
1601
1602   /* Free the strings idenfitying the object */
1603   HeapFree( GetProcessHeap(), 0, This->containerApp );
1604   This->containerApp = NULL;
1605   HeapFree( GetProcessHeap(), 0, This->containerObj );
1606   This->containerObj = NULL;
1607
1608   /* Release our reference to the data cache. */
1609   if (This->dataCache)
1610   {
1611     IUnknown_Release(This->dataCache);
1612     This->dataCache = NULL;
1613   }
1614
1615   /* Same thing for the client site. */
1616   if (This->clientSite)
1617   {
1618     IOleClientSite_Release(This->clientSite);
1619     This->clientSite = NULL;
1620   }
1621
1622   /* And the advise holder. */
1623   if (This->oleAdviseHolder)
1624   {
1625     IOleAdviseHolder_Release(This->oleAdviseHolder);
1626     This->oleAdviseHolder = NULL;
1627   }
1628
1629   /* And the data advise holder. */
1630   if (This->dataAdviseHolder)
1631   {
1632     IDataAdviseHolder_Release(This->dataAdviseHolder);
1633     This->dataAdviseHolder = NULL;
1634   }
1635
1636   /* Free the actual default handler structure. */
1637   HeapFree(GetProcessHeap(), 0, This);
1638 }
1639
1640 /******************************************************************************
1641  * OleCreateDefaultHandler [OLE32.@]
1642  */
1643 HRESULT WINAPI OleCreateDefaultHandler(
1644   REFCLSID  clsid,
1645   LPUNKNOWN pUnkOuter,
1646   REFIID    riid,
1647   LPVOID*   ppvObj)
1648 {
1649   DefaultHandler* newHandler = NULL;
1650   HRESULT         hr         = S_OK;
1651
1652   TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
1653
1654   /*
1655    * Sanity check
1656    */
1657   if (!ppvObj)
1658     return E_POINTER;
1659
1660   *ppvObj = NULL;
1661
1662   /*
1663    * If This handler is constructed for aggregation, make sure
1664    * the caller is requesting the IUnknown interface.
1665    * This is necessary because it's the only time the non-delegating
1666    * IUnknown pointer can be returned to the outside.
1667    */
1668   if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
1669     return CLASS_E_NOAGGREGATION;
1670
1671   /*
1672    * Try to construct a new instance of the class.
1673    */
1674   newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1675
1676   if (!newHandler)
1677     return E_OUTOFMEMORY;
1678
1679   /*
1680    * Make sure it supports the interface required by the caller.
1681    */
1682   hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1683
1684   /*
1685    * Release the reference obtained in the constructor. If
1686    * the QueryInterface was unsuccessful, it will free the class.
1687    */
1688   IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
1689
1690   return hr;
1691 }