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