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