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