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