~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ole32/defaulthandler.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  *      OLE 2 default object handler
  3  *
  4  *      Copyright 1999  Francis Beaudet
  5  *      Copyright 2000  Abey George
  6  *
  7  * This library is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU Lesser General Public
  9  * License as published by the Free Software Foundation; either
 10  * version 2.1 of the License, or (at your option) any later version.
 11  *
 12  * This library is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  * Lesser General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Lesser General Public
 18  * License along with this library; if not, write to the Free Software
 19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  *
 21  * NOTES:
 22  *    The OLE2 default object handler supports a whole whack of
 23  *    interfaces including:
 24  *       IOleObject, IDataObject, IPersistStorage, IViewObject2,
 25  *       IRunnableObject, IOleCache2, IOleCacheControl and much more.
 26  *
 27  *    All the implementation details are taken from: Inside OLE
 28  *    second edition by Kraig Brockschmidt,
 29  *
 30  * TODO
 31  * - This implementation of the default handler does not launch the
 32  *   server in the DoVerb, Update, GetData, GetDataHere and Run
 33  *   methods. When it is fixed to do so, all the methods will have
 34  *   to be  revisited to allow delegating to the running object
 35  *
 36  * - All methods in the class that use the class ID should be
 37  *   aware that it is possible for a class to be treated as
 38  *   another one and go into emulation mode. Nothing has been
 39  *   done in this area.
 40  *
 41  * - Some functions still return E_NOTIMPL they have to be
 42  *   implemented. Most of those are related to the running of the
 43  *   actual server.
 44  *
 45  * - All the methods related to notification and advise sinks are
 46  *   in place but no notifications are sent to the sinks yet.
 47  */
 48 #include <assert.h>
 49 #include <stdarg.h>
 50 #include <string.h>
 51 
 52 #define COBJMACROS
 53 
 54 #include "windef.h"
 55 #include "winbase.h"
 56 #include "winuser.h"
 57 #include "winerror.h"
 58 #include "ole2.h"
 59 
 60 #include "compobj_private.h"
 61 
 62 #include "wine/unicode.h"
 63 #include "wine/debug.h"
 64 
 65 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 66 
 67 enum storage_state
 68 {
 69     storage_state_uninitialised,
 70     storage_state_initialised,
 71     storage_state_loaded
 72 };
 73 
 74 enum object_state
 75 {
 76     object_state_not_running,
 77     object_state_running
 78 };
 79 
 80 /****************************************************************************
 81  * DefaultHandler
 82  *
 83  */
 84 struct DefaultHandler
 85 {
 86   IOleObject        IOleObject_iface;
 87   IUnknown          IUnknown_iface;
 88   IDataObject       IDataObject_iface;
 89   IRunnableObject   IRunnableObject_iface;
 90   IAdviseSink       IAdviseSink_iface;
 91   IPersistStorage   IPersistStorage_iface;
 92 
 93   /* Reference count of this object */
 94   LONG ref;
 95 
 96   /* IUnknown implementation of the outer object. */
 97   IUnknown* outerUnknown;
 98 
 99   /* Class Id that this handler object represents. */
100   CLSID clsid;
101 
102   /* IUnknown implementation of the datacache. */
103   IUnknown* dataCache;
104   /* IPersistStorage implementation of the datacache. */
105   IPersistStorage* dataCache_PersistStg;
106 
107   /* Client site for the embedded object. */
108   IOleClientSite* clientSite;
109 
110   /*
111    * The IOleAdviseHolder maintains the connections
112    * on behalf of the default handler.
113    */
114   IOleAdviseHolder* oleAdviseHolder;
115 
116   /*
117    * The IDataAdviseHolder maintains the data
118    * connections on behalf of the default handler.
119    */
120   IDataAdviseHolder* dataAdviseHolder;
121 
122   /* Name of the container and object contained */
123   LPWSTR containerApp;
124   LPWSTR containerObj;
125 
126   /* IOleObject delegate */
127   IOleObject *pOleDelegate;
128   /* IPersistStorage delegate */
129   IPersistStorage *pPSDelegate;
130   /* IDataObject delegate */
131   IDataObject *pDataDelegate;
132   enum object_state object_state;
133 
134   /* connection cookie for the advise on the delegate OLE object */
135   DWORD dwAdvConn;
136 
137   /* storage passed to Load or InitNew */
138   IStorage *storage;
139   enum storage_state storage_state;
140 
141   /* optional class factory for object */
142   IClassFactory *pCFObject;
143   /* TRUE if acting as an inproc server instead of an inproc handler */
144   BOOL inproc_server;
145 };
146 
147 typedef struct DefaultHandler DefaultHandler;
148 
149 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
150 {
151     return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface);
152 }
153 
154 static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface )
155 {
156     return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface);
157 }
158 
159 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
160 {
161     return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface);
162 }
163 
164 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
165 {
166     return CONTAINING_RECORD(iface, DefaultHandler, IRunnableObject_iface);
167 }
168 
169 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
170 {
171     return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface);
172 }
173 
174 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
175 {
176     return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface);
177 }
178 
179 static void DefaultHandler_Destroy(DefaultHandler* This);
180 
181 static inline BOOL object_is_running(DefaultHandler *This)
182 {
183     return IRunnableObject_IsRunning(&This->IRunnableObject_iface);
184 }
185 
186 /*********************************************************
187  * Method implementation for the  non delegating IUnknown
188  * part of the DefaultHandler class.
189  */
190 
191 /************************************************************************
192  * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
193  *
194  * See Windows documentation for more details on IUnknown methods.
195  *
196  * This version of QueryInterface will not delegate its implementation
197  * to the outer unknown.
198  */
199 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
200             IUnknown*      iface,
201             REFIID         riid,
202             void**         ppvObject)
203 {
204   DefaultHandler *This = impl_from_IUnknown(iface);
205 
206   if (!ppvObject)
207     return E_INVALIDARG;
208 
209   *ppvObject = NULL;
210 
211   if (IsEqualIID(&IID_IUnknown, riid))
212     *ppvObject = iface;
213   else if (IsEqualIID(&IID_IOleObject, riid))
214     *ppvObject = &This->IOleObject_iface;
215   else if (IsEqualIID(&IID_IDataObject, riid))
216     *ppvObject = &This->IDataObject_iface;
217   else if (IsEqualIID(&IID_IRunnableObject, riid))
218     *ppvObject = &This->IRunnableObject_iface;
219   else if (IsEqualIID(&IID_IPersist, riid) ||
220            IsEqualIID(&IID_IPersistStorage, riid))
221     *ppvObject = &This->IPersistStorage_iface;
222   else if (IsEqualIID(&IID_IViewObject, riid) ||
223            IsEqualIID(&IID_IViewObject2, riid) ||
224            IsEqualIID(&IID_IOleCache, riid) ||
225            IsEqualIID(&IID_IOleCache2, riid))
226   {
227     HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
228     if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
229     return hr;
230   }
231   else if (This->inproc_server && This->pOleDelegate)
232   {
233     return IUnknown_QueryInterface(This->pOleDelegate, riid, ppvObject);
234   }
235 
236   /* Check that we obtained an interface. */
237   if (*ppvObject == NULL)
238   {
239     WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
240     return E_NOINTERFACE;
241   }
242 
243   /*
244    * Query Interface always increases the reference count by one when it is
245    * successful.
246    */
247   IUnknown_AddRef((IUnknown*)*ppvObject);
248 
249   return S_OK;
250 }
251 
252 /************************************************************************
253  * DefaultHandler_NDIUnknown_AddRef (IUnknown)
254  *
255  * See Windows documentation for more details on IUnknown methods.
256  *
257  * This version of QueryInterface will not delegate its implementation
258  * to the outer unknown.
259  */
260 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
261             IUnknown*      iface)
262 {
263   DefaultHandler *This = impl_from_IUnknown(iface);
264   return InterlockedIncrement(&This->ref);
265 }
266 
267 /************************************************************************
268  * DefaultHandler_NDIUnknown_Release (IUnknown)
269  *
270  * See Windows documentation for more details on IUnknown methods.
271  *
272  * This version of QueryInterface will not delegate its implementation
273  * to the outer unknown.
274  */
275 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
276             IUnknown*      iface)
277 {
278   DefaultHandler *This = impl_from_IUnknown(iface);
279   ULONG ref;
280 
281   ref = InterlockedDecrement(&This->ref);
282 
283   if (!ref) DefaultHandler_Destroy(This);
284 
285   return ref;
286 }
287 
288 /*********************************************************
289  * Methods implementation for the IOleObject part of
290  * the DefaultHandler class.
291  */
292 
293 /************************************************************************
294  * DefaultHandler_QueryInterface (IUnknown)
295  *
296  * See Windows documentation for more details on IUnknown methods.
297  */
298 static HRESULT WINAPI DefaultHandler_QueryInterface(
299             IOleObject*      iface,
300             REFIID           riid,
301             void**           ppvObject)
302 {
303   DefaultHandler *This = impl_from_IOleObject(iface);
304 
305   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
306 }
307 
308 /************************************************************************
309  * DefaultHandler_AddRef (IUnknown)
310  *
311  * See Windows documentation for more details on IUnknown methods.
312  */
313 static ULONG WINAPI DefaultHandler_AddRef(
314             IOleObject*        iface)
315 {
316   DefaultHandler *This = impl_from_IOleObject(iface);
317 
318   return IUnknown_AddRef(This->outerUnknown);
319 }
320 
321 /************************************************************************
322  * DefaultHandler_Release (IUnknown)
323  *
324  * See Windows documentation for more details on IUnknown methods.
325  */
326 static ULONG WINAPI DefaultHandler_Release(
327             IOleObject*        iface)
328 {
329   DefaultHandler *This = impl_from_IOleObject(iface);
330 
331   return IUnknown_Release(This->outerUnknown);
332 }
333 
334 /************************************************************************
335  * DefaultHandler_SetClientSite (IOleObject)
336  *
337  * The default handler's implementation of this method only keeps the
338  * client site pointer for future reference.
339  *
340  * See Windows documentation for more details on IOleObject methods.
341  */
342 static HRESULT WINAPI DefaultHandler_SetClientSite(
343             IOleObject*        iface,
344             IOleClientSite*    pClientSite)
345 {
346   DefaultHandler *This = impl_from_IOleObject(iface);
347   HRESULT hr = S_OK;
348 
349   TRACE("(%p, %p)\n", iface, pClientSite);
350 
351   if (object_is_running(This))
352     hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
353 
354   /*
355    * Make sure we release the previous client site if there
356    * was one.
357    */
358   if (This->clientSite)
359     IOleClientSite_Release(This->clientSite);
360 
361   This->clientSite = pClientSite;
362 
363   if (This->clientSite)
364     IOleClientSite_AddRef(This->clientSite);
365 
366   return hr;
367 }
368 
369 /************************************************************************
370  * DefaultHandler_GetClientSite (IOleObject)
371  *
372  * The default handler's implementation of this method returns the
373  * last pointer set in IOleObject_SetClientSite.
374  *
375  * See Windows documentation for more details on IOleObject methods.
376  */
377 static HRESULT WINAPI DefaultHandler_GetClientSite(
378             IOleObject*        iface,
379             IOleClientSite**   ppClientSite)
380 {
381   DefaultHandler *This = impl_from_IOleObject(iface);
382 
383   if (!ppClientSite)
384     return E_POINTER;
385 
386   *ppClientSite = This->clientSite;
387 
388   if (This->clientSite)
389     IOleClientSite_AddRef(This->clientSite);
390 
391   return S_OK;
392 }
393 
394 /************************************************************************
395  * DefaultHandler_SetHostNames (IOleObject)
396  *
397  * The default handler's implementation of this method just stores
398  * the strings and returns S_OK.
399  *
400  * See Windows documentation for more details on IOleObject methods.
401  */
402 static HRESULT WINAPI DefaultHandler_SetHostNames(
403             IOleObject*        iface,
404             LPCOLESTR          szContainerApp,
405             LPCOLESTR          szContainerObj)
406 {
407   DefaultHandler *This = impl_from_IOleObject(iface);
408 
409   TRACE("(%p, %s, %s)\n",
410         iface,
411         debugstr_w(szContainerApp),
412         debugstr_w(szContainerObj));
413 
414   if (object_is_running(This))
415     IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
416 
417   /* Be sure to cleanup before re-assigning the strings. */
418   HeapFree( GetProcessHeap(), 0, This->containerApp );
419   This->containerApp = NULL;
420   HeapFree( GetProcessHeap(), 0, This->containerObj );
421   This->containerObj = NULL;
422 
423   if (szContainerApp)
424   {
425       if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
426                                            (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
427           strcpyW( This->containerApp, szContainerApp );
428   }
429 
430   if (szContainerObj)
431   {
432       if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
433                                            (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
434           strcpyW( This->containerObj, szContainerObj );
435   }
436   return S_OK;
437 }
438 
439 static void release_delegates(DefaultHandler *This)
440 {
441     if (This->pDataDelegate)
442     {
443         IDataObject_Release(This->pDataDelegate);
444         This->pDataDelegate = NULL;
445     }
446     if (This->pPSDelegate)
447     {
448         IPersistStorage_Release(This->pPSDelegate);
449         This->pPSDelegate = NULL;
450     }
451     if (This->pOleDelegate)
452     {
453         IOleObject_Release(This->pOleDelegate);
454         This->pOleDelegate = NULL;
455     }
456 }
457 
458 /* undoes the work done by DefaultHandler_Run */
459 static void DefaultHandler_Stop(DefaultHandler *This)
460 {
461   if (!object_is_running(This))
462     return;
463 
464   IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
465 
466   /* FIXME: call IOleCache_OnStop */
467 
468   if (This->dataAdviseHolder)
469     DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
470 
471   This->object_state = object_state_not_running;
472 }
473 
474 /************************************************************************
475  * DefaultHandler_Close (IOleObject)
476  *
477  * The default handler's implementation of this method is meaningless
478  * without a running server so it does nothing.
479  *
480  * See Windows documentation for more details on IOleObject methods.
481  */
482 static HRESULT WINAPI DefaultHandler_Close(
483             IOleObject*        iface,
484             DWORD              dwSaveOption)
485 {
486   DefaultHandler *This = impl_from_IOleObject(iface);
487   HRESULT hr;
488 
489   TRACE("(%d)\n", dwSaveOption);
490 
491   if (!object_is_running(This))
492     return S_OK;
493 
494   hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
495 
496   DefaultHandler_Stop(This);
497   release_delegates(This);
498 
499   return hr;
500 }
501 
502 /************************************************************************
503  * DefaultHandler_SetMoniker (IOleObject)
504  *
505  * The default handler's implementation of this method does nothing.
506  *
507  * See Windows documentation for more details on IOleObject methods.
508  */
509 static HRESULT WINAPI DefaultHandler_SetMoniker(
510             IOleObject*        iface,
511             DWORD              dwWhichMoniker,
512             IMoniker*          pmk)
513 {
514   DefaultHandler *This = impl_from_IOleObject(iface);
515 
516   TRACE("(%p, %d, %p)\n",
517         iface,
518         dwWhichMoniker,
519         pmk);
520 
521   if (object_is_running(This))
522     return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
523 
524   return S_OK;
525 }
526 
527 /************************************************************************
528  * DefaultHandler_GetMoniker (IOleObject)
529  *
530  * Delegate this request to the client site if we have one.
531  *
532  * See Windows documentation for more details on IOleObject methods.
533  */
534 static HRESULT WINAPI DefaultHandler_GetMoniker(
535             IOleObject*        iface,
536             DWORD              dwAssign,
537             DWORD              dwWhichMoniker,
538             IMoniker**         ppmk)
539 {
540   DefaultHandler *This = impl_from_IOleObject(iface);
541 
542   TRACE("(%p, %d, %d, %p)\n",
543         iface, dwAssign, dwWhichMoniker, ppmk);
544 
545   if (object_is_running(This))
546     return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
547                                  ppmk);
548 
549   /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
550   if (This->clientSite)
551   {
552     return IOleClientSite_GetMoniker(This->clientSite,
553                                      dwAssign,
554                                      dwWhichMoniker,
555                                      ppmk);
556 
557   }
558 
559   return E_FAIL;
560 }
561 
562 /************************************************************************
563  * DefaultHandler_InitFromData (IOleObject)
564  *
565  * This method is meaningless if the server is not running
566  *
567  * See Windows documentation for more details on IOleObject methods.
568  */
569 static HRESULT WINAPI DefaultHandler_InitFromData(
570             IOleObject*        iface,
571             IDataObject*       pDataObject,
572             BOOL               fCreation,
573             DWORD              dwReserved)
574 {
575   DefaultHandler *This = impl_from_IOleObject(iface);
576 
577   TRACE("(%p, %p, %d, %d)\n",
578         iface, pDataObject, fCreation, dwReserved);
579 
580   if (object_is_running(This))
581     return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
582                                    dwReserved);
583   return OLE_E_NOTRUNNING;
584 }
585 
586 /************************************************************************
587  * DefaultHandler_GetClipboardData (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_GetClipboardData(
594             IOleObject*        iface,
595             DWORD              dwReserved,
596             IDataObject**      ppDataObject)
597 {
598   DefaultHandler *This = impl_from_IOleObject(iface);
599 
600   TRACE("(%p, %d, %p)\n",
601         iface, dwReserved, ppDataObject);
602 
603   if (object_is_running(This))
604     return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
605                                        ppDataObject);
606 
607   return OLE_E_NOTRUNNING;
608 }
609 
610 static HRESULT WINAPI DefaultHandler_DoVerb(
611             IOleObject*        iface,
612             LONG               iVerb,
613             struct tagMSG*     lpmsg,
614             IOleClientSite*    pActiveSite,
615             LONG               lindex,
616             HWND               hwndParent,
617             LPCRECT            lprcPosRect)
618 {
619   DefaultHandler *This = impl_from_IOleObject(iface);
620   IRunnableObject *pRunnableObj = &This->IRunnableObject_iface;
621   HRESULT hr;
622 
623   TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
624 
625   hr = IRunnableObject_Run(pRunnableObj, NULL);
626   if (FAILED(hr)) return hr;
627 
628   return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
629                            lindex, hwndParent, lprcPosRect);
630 }
631 
632 /************************************************************************
633  * DefaultHandler_EnumVerbs (IOleObject)
634  *
635  * The default handler implementation of this method simply delegates
636  * to OleRegEnumVerbs
637  *
638  * See Windows documentation for more details on IOleObject methods.
639  */
640 static HRESULT WINAPI DefaultHandler_EnumVerbs(
641             IOleObject*        iface,
642             IEnumOLEVERB**     ppEnumOleVerb)
643 {
644   DefaultHandler *This = impl_from_IOleObject(iface);
645   HRESULT hr = OLE_S_USEREG;
646 
647   TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
648 
649   if (object_is_running(This))
650     hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
651 
652   if (hr == OLE_S_USEREG)
653     return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
654   else
655     return hr;
656 }
657 
658 static HRESULT WINAPI DefaultHandler_Update(
659             IOleObject*        iface)
660 {
661     DefaultHandler *This = impl_from_IOleObject(iface);
662     TRACE("(%p)\n", iface);
663 
664     if (!object_is_running(This))
665     {
666         FIXME("Should run object\n");
667         return E_NOTIMPL;
668     }
669     return IOleObject_Update(This->pOleDelegate);
670 }
671 
672 /************************************************************************
673  * DefaultHandler_IsUpToDate (IOleObject)
674  *
675  * This method is meaningless if the server is not running
676  *
677  * See Windows documentation for more details on IOleObject methods.
678  */
679 static HRESULT WINAPI DefaultHandler_IsUpToDate(
680             IOleObject*        iface)
681 {
682     DefaultHandler *This = impl_from_IOleObject(iface);
683     TRACE("(%p)\n", iface);
684 
685     if (object_is_running(This))
686         return IOleObject_IsUpToDate(This->pOleDelegate);
687 
688     return OLE_E_NOTRUNNING;
689 }
690 
691 /************************************************************************
692  * DefaultHandler_GetUserClassID (IOleObject)
693  *
694  * TODO: Map to a new class ID if emulation is active.
695  *
696  * See Windows documentation for more details on IOleObject methods.
697  */
698 static HRESULT WINAPI DefaultHandler_GetUserClassID(
699             IOleObject*        iface,
700             CLSID*             pClsid)
701 {
702   DefaultHandler *This = impl_from_IOleObject(iface);
703 
704   TRACE("(%p, %p)\n", iface, pClsid);
705 
706   if (object_is_running(This))
707     return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
708 
709   if (!pClsid)
710     return E_POINTER;
711 
712   *pClsid = This->clsid;
713 
714   return S_OK;
715 }
716 
717 /************************************************************************
718  * DefaultHandler_GetUserType (IOleObject)
719  *
720  * The default handler implementation of this method simply delegates
721  * to OleRegGetUserType
722  *
723  * See Windows documentation for more details on IOleObject methods.
724  */
725 static HRESULT WINAPI DefaultHandler_GetUserType(
726             IOleObject*        iface,
727             DWORD              dwFormOfType,
728             LPOLESTR*          pszUserType)
729 {
730   DefaultHandler *This = impl_from_IOleObject(iface);
731 
732   TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
733   if (object_is_running(This))
734     return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
735 
736   return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
737 }
738 
739 /************************************************************************
740  * DefaultHandler_SetExtent (IOleObject)
741  *
742  * This method is meaningless if the server is not running
743  *
744  * See Windows documentation for more details on IOleObject methods.
745  */
746 static HRESULT WINAPI DefaultHandler_SetExtent(
747             IOleObject*        iface,
748             DWORD              dwDrawAspect,
749             SIZEL*             psizel)
750 {
751   DefaultHandler *This = impl_from_IOleObject(iface);
752 
753   TRACE("(%p, %x, (%d x %d))\n", iface,
754         dwDrawAspect, psizel->cx, psizel->cy);
755 
756   if (object_is_running(This))
757     return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
758 
759   return OLE_E_NOTRUNNING;
760 }
761 
762 /************************************************************************
763  * DefaultHandler_GetExtent (IOleObject)
764  *
765  * The default handler's implementation of this method returns uses
766  * the cache to locate the aspect and extract the extent from it.
767  *
768  * See Windows documentation for more details on IOleObject methods.
769  */
770 static HRESULT WINAPI DefaultHandler_GetExtent(
771             IOleObject*        iface,
772             DWORD              dwDrawAspect,
773             SIZEL*             psizel)
774 {
775   DVTARGETDEVICE* targetDevice;
776   IViewObject2*   cacheView = NULL;
777   HRESULT         hres;
778 
779   DefaultHandler *This = impl_from_IOleObject(iface);
780 
781   TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
782 
783   if (object_is_running(This))
784     return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
785 
786   hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
787   if (FAILED(hres))
788     return E_UNEXPECTED;
789 
790   /*
791    * Prepare the call to the cache's GetExtent method.
792    *
793    * Here we would build a valid DVTARGETDEVICE structure
794    * but, since we are calling into the data cache, we
795    * know its implementation and we'll skip this
796    * extra work until later.
797    */
798   targetDevice = NULL;
799 
800   hres = IViewObject2_GetExtent(cacheView,
801                                 dwDrawAspect,
802                                 -1,
803                                 targetDevice,
804                                 psizel);
805 
806   IViewObject2_Release(cacheView);
807 
808   return hres;
809 }
810 
811 /************************************************************************
812  * DefaultHandler_Advise (IOleObject)
813  *
814  * The default handler's implementation of this method simply
815  * delegates to the OleAdviseHolder.
816  *
817  * See Windows documentation for more details on IOleObject methods.
818  */
819 static HRESULT WINAPI DefaultHandler_Advise(
820             IOleObject*        iface,
821             IAdviseSink*       pAdvSink,
822             DWORD*             pdwConnection)
823 {
824   HRESULT hres = S_OK;
825   DefaultHandler *This = impl_from_IOleObject(iface);
826 
827   TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
828 
829   /* Make sure we have an advise holder before we start. */
830   if (!This->oleAdviseHolder)
831     hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
832 
833   if (SUCCEEDED(hres))
834     hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
835                                    pAdvSink,
836                                    pdwConnection);
837 
838   return hres;
839 }
840 
841 /************************************************************************
842  * DefaultHandler_Unadvise (IOleObject)
843  *
844  * The default handler's implementation of this method simply
845  * delegates to the OleAdviseHolder.
846  *
847  * See Windows documentation for more details on IOleObject methods.
848  */
849 static HRESULT WINAPI DefaultHandler_Unadvise(
850             IOleObject*        iface,
851             DWORD              dwConnection)
852 {
853   DefaultHandler *This = impl_from_IOleObject(iface);
854 
855   TRACE("(%p, %d)\n", iface, dwConnection);
856 
857   /*
858    * If we don't have an advise holder yet, it means we don't have
859    * a connection.
860    */
861   if (!This->oleAdviseHolder)
862     return OLE_E_NOCONNECTION;
863 
864   return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
865                                    dwConnection);
866 }
867 
868 /************************************************************************
869  * DefaultHandler_EnumAdvise (IOleObject)
870  *
871  * The default handler's implementation of this method simply
872  * delegates to the OleAdviseHolder.
873  *
874  * See Windows documentation for more details on IOleObject methods.
875  */
876 static HRESULT WINAPI DefaultHandler_EnumAdvise(
877             IOleObject*        iface,
878             IEnumSTATDATA**    ppenumAdvise)
879 {
880   DefaultHandler *This = impl_from_IOleObject(iface);
881 
882   TRACE("(%p, %p)\n", iface, ppenumAdvise);
883 
884   if (!ppenumAdvise)
885     return E_POINTER;
886 
887   *ppenumAdvise = NULL;
888 
889   if (!This->oleAdviseHolder)
890       return S_OK;
891 
892   return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
893 }
894 
895 /************************************************************************
896  * DefaultHandler_GetMiscStatus (IOleObject)
897  *
898  * The default handler's implementation of this method simply delegates
899  * to OleRegGetMiscStatus.
900  *
901  * See Windows documentation for more details on IOleObject methods.
902  */
903 static HRESULT WINAPI DefaultHandler_GetMiscStatus(
904             IOleObject*        iface,
905             DWORD              dwAspect,
906             DWORD*             pdwStatus)
907 {
908   HRESULT hres;
909   DefaultHandler *This = impl_from_IOleObject(iface);
910 
911   TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
912 
913   if (object_is_running(This))
914     return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
915 
916   hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
917 
918   if (FAILED(hres))
919     *pdwStatus = 0;
920 
921   return hres;
922 }
923 
924 /************************************************************************
925  * DefaultHandler_SetColorScheme (IOleObject)
926  *
927  * This method is meaningless if the server is not running
928  *
929  * See Windows documentation for more details on IOleObject methods.
930  */
931 static HRESULT WINAPI DefaultHandler_SetColorScheme(
932             IOleObject*           iface,
933             struct tagLOGPALETTE* pLogpal)
934 {
935   DefaultHandler *This = impl_from_IOleObject(iface);
936 
937   TRACE("(%p, %p))\n", iface, pLogpal);
938 
939   if (object_is_running(This))
940     return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
941 
942   return OLE_E_NOTRUNNING;
943 }
944 
945 /*********************************************************
946  * Methods implementation for the IDataObject part of
947  * the DefaultHandler class.
948  */
949 
950 /************************************************************************
951  * DefaultHandler_IDataObject_QueryInterface (IUnknown)
952  *
953  * See Windows documentation for more details on IUnknown methods.
954  */
955 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
956             IDataObject*     iface,
957            REFIID           riid,
958             void**           ppvObject)
959 {
960   DefaultHandler *This = impl_from_IDataObject(iface);
961 
962   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
963 }
964 
965 /************************************************************************
966  * DefaultHandler_IDataObject_AddRef (IUnknown)
967  *
968  * See Windows documentation for more details on IUnknown methods.
969  */
970 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
971             IDataObject*     iface)
972 {
973   DefaultHandler *This = impl_from_IDataObject(iface);
974 
975   return IUnknown_AddRef(This->outerUnknown);
976 }
977 
978 /************************************************************************
979  * DefaultHandler_IDataObject_Release (IUnknown)
980  *
981  * See Windows documentation for more details on IUnknown methods.
982  */
983 static ULONG WINAPI DefaultHandler_IDataObject_Release(
984             IDataObject*     iface)
985 {
986   DefaultHandler *This = impl_from_IDataObject(iface);
987 
988   return IUnknown_Release(This->outerUnknown);
989 }
990 
991 /************************************************************************
992  * DefaultHandler_GetData
993  *
994  * Get Data from a source dataobject using format pformatetcIn->cfFormat
995  * See Windows documentation for more details on GetData.
996  * Default handler's implementation of this method delegates to the cache.
997  */
998 static HRESULT WINAPI DefaultHandler_GetData(
999             IDataObject*     iface,
1000             LPFORMATETC      pformatetcIn,
1001             STGMEDIUM*       pmedium)
1002 {
1003   IDataObject* cacheDataObject = NULL;
1004   HRESULT      hres;
1005 
1006   DefaultHandler *This = impl_from_IDataObject(iface);
1007 
1008   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
1009 
1010   hres = IUnknown_QueryInterface(This->dataCache,
1011                                  &IID_IDataObject,
1012                                  (void**)&cacheDataObject);
1013 
1014   if (FAILED(hres))
1015     return E_UNEXPECTED;
1016 
1017   hres = IDataObject_GetData(cacheDataObject,
1018                              pformatetcIn,
1019                              pmedium);
1020 
1021   IDataObject_Release(cacheDataObject);
1022 
1023   if (FAILED(hres) && This->pDataDelegate)
1024     hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1025 
1026   return hres;
1027 }
1028 
1029 static HRESULT WINAPI DefaultHandler_GetDataHere(
1030             IDataObject*     iface,
1031             LPFORMATETC      pformatetc,
1032             STGMEDIUM*       pmedium)
1033 {
1034   FIXME(": Stub\n");
1035   return E_NOTIMPL;
1036 }
1037 
1038 /************************************************************************
1039  * DefaultHandler_QueryGetData (IDataObject)
1040  *
1041  * The default handler's implementation of this method delegates to
1042  * the cache.
1043  *
1044  * See Windows documentation for more details on IDataObject methods.
1045  */
1046 static HRESULT WINAPI DefaultHandler_QueryGetData(
1047             IDataObject*     iface,
1048             LPFORMATETC      pformatetc)
1049 {
1050   IDataObject* cacheDataObject = NULL;
1051   HRESULT      hres;
1052 
1053   DefaultHandler *This = impl_from_IDataObject(iface);
1054 
1055   TRACE("(%p, %p)\n", iface, pformatetc);
1056 
1057   hres = IUnknown_QueryInterface(This->dataCache,
1058                                  &IID_IDataObject,
1059                                  (void**)&cacheDataObject);
1060 
1061   if (FAILED(hres))
1062     return E_UNEXPECTED;
1063 
1064   hres = IDataObject_QueryGetData(cacheDataObject,
1065                                   pformatetc);
1066 
1067   IDataObject_Release(cacheDataObject);
1068 
1069   if (FAILED(hres) && This->pDataDelegate)
1070     hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1071 
1072   return hres;
1073 }
1074 
1075 /************************************************************************
1076  * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
1077  *
1078  * This method is meaningless if the server is not running
1079  *
1080  * See Windows documentation for more details on IDataObject methods.
1081  */
1082 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1083             IDataObject*     iface,
1084             LPFORMATETC      pformatetcIn,
1085             LPFORMATETC      pformatetcOut)
1086 {
1087   DefaultHandler *This = impl_from_IDataObject(iface);
1088 
1089   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
1090 
1091   if (!This->pDataDelegate)
1092     return OLE_E_NOTRUNNING;
1093 
1094   return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1095 }
1096 
1097 /************************************************************************
1098  * DefaultHandler_SetData (IDataObject)
1099  *
1100  * The default handler's implementation of this method delegates to
1101  * the cache.
1102  *
1103  * See Windows documentation for more details on IDataObject methods.
1104  */
1105 static HRESULT WINAPI DefaultHandler_SetData(
1106             IDataObject*     iface,
1107             LPFORMATETC      pformatetc,
1108             STGMEDIUM*       pmedium,
1109             BOOL             fRelease)
1110 {
1111   DefaultHandler *This = impl_from_IDataObject(iface);
1112   IDataObject* cacheDataObject = NULL;
1113   HRESULT      hres;
1114 
1115   TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1116 
1117   hres = IUnknown_QueryInterface(This->dataCache,
1118                                  &IID_IDataObject,
1119                                  (void**)&cacheDataObject);
1120 
1121   if (FAILED(hres))
1122     return E_UNEXPECTED;
1123 
1124   hres = IDataObject_SetData(cacheDataObject,
1125                              pformatetc,
1126                              pmedium,
1127                              fRelease);
1128 
1129   IDataObject_Release(cacheDataObject);
1130 
1131   return hres;
1132 }
1133 
1134 /************************************************************************
1135  * DefaultHandler_EnumFormatEtc (IDataObject)
1136  *
1137  * The default handler's implementation of This method simply delegates
1138  * to OleRegEnumFormatEtc.
1139  *
1140  * See Windows documentation for more details on IDataObject methods.
1141  */
1142 static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1143             IDataObject*     iface,
1144             DWORD            dwDirection,
1145             IEnumFORMATETC** ppenumFormatEtc)
1146 {
1147   DefaultHandler *This = impl_from_IDataObject(iface);
1148 
1149   TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1150 
1151   return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1152 }
1153 
1154 /************************************************************************
1155  * DefaultHandler_DAdvise (IDataObject)
1156  *
1157  * The default handler's implementation of this method simply
1158  * delegates to the DataAdviseHolder.
1159  *
1160  * See Windows documentation for more details on IDataObject methods.
1161  */
1162 static HRESULT WINAPI DefaultHandler_DAdvise(
1163             IDataObject*     iface,
1164             FORMATETC*       pformatetc,
1165             DWORD            advf,
1166             IAdviseSink*     pAdvSink,
1167             DWORD*           pdwConnection)
1168 {
1169   HRESULT hres = S_OK;
1170   DefaultHandler *This = impl_from_IDataObject(iface);
1171 
1172   TRACE("(%p, %p, %d, %p, %p)\n",
1173         iface, pformatetc, advf, pAdvSink, pdwConnection);
1174 
1175   /* Make sure we have a data advise holder before we start. */
1176   if (!This->dataAdviseHolder)
1177   {
1178     hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1179     if (SUCCEEDED(hres) && This->pDataDelegate)
1180       DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1181   }
1182 
1183   if (SUCCEEDED(hres))
1184     hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1185                                     iface,
1186                                     pformatetc,
1187                                     advf,
1188                                     pAdvSink,
1189                                     pdwConnection);
1190 
1191   return hres;
1192 }
1193 
1194 /************************************************************************
1195  * DefaultHandler_DUnadvise (IDataObject)
1196  *
1197  * The default handler's implementation of this method simply
1198  * delegates to the DataAdviseHolder.
1199  *
1200  * See Windows documentation for more details on IDataObject methods.
1201  */
1202 static HRESULT WINAPI DefaultHandler_DUnadvise(
1203             IDataObject*     iface,
1204             DWORD            dwConnection)
1205 {
1206   DefaultHandler *This = impl_from_IDataObject(iface);
1207 
1208   TRACE("(%p, %d)\n", iface, dwConnection);
1209 
1210   /*
1211    * If we don't have a data advise holder yet, it means that
1212    * we don't have any connections..
1213    */
1214   if (!This->dataAdviseHolder)
1215     return OLE_E_NOCONNECTION;
1216 
1217   return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1218                                     dwConnection);
1219 }
1220 
1221 /************************************************************************
1222  * DefaultHandler_EnumDAdvise (IDataObject)
1223  *
1224  * The default handler's implementation of this method simply
1225  * delegates to the DataAdviseHolder.
1226  *
1227  * See Windows documentation for more details on IDataObject methods.
1228  */
1229 static HRESULT WINAPI DefaultHandler_EnumDAdvise(
1230             IDataObject*     iface,
1231             IEnumSTATDATA**  ppenumAdvise)
1232 {
1233   DefaultHandler *This = impl_from_IDataObject(iface);
1234 
1235   TRACE("(%p, %p)\n", iface, ppenumAdvise);
1236 
1237   if (!ppenumAdvise)
1238     return E_POINTER;
1239 
1240   *ppenumAdvise = NULL;
1241 
1242   /* If we have a data advise holder object, delegate. */
1243   if (This->dataAdviseHolder)
1244     return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1245                                         ppenumAdvise);
1246 
1247   return S_OK;
1248 }
1249 
1250 /*********************************************************
1251  * Methods implementation for the IRunnableObject part
1252  * of the DefaultHandler class.
1253  */
1254 
1255 /************************************************************************
1256  * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
1257  *
1258  * See Windows documentation for more details on IUnknown methods.
1259  */
1260 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
1261             IRunnableObject*     iface,
1262             REFIID               riid,
1263             void**               ppvObject)
1264 {
1265   DefaultHandler *This = impl_from_IRunnableObject(iface);
1266 
1267   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1268 }
1269 
1270 /************************************************************************
1271  * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1272  *
1273  * See Windows documentation for more details on IUnknown methods.
1274  */
1275 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1276             IRunnableObject*     iface)
1277 {
1278   DefaultHandler *This = impl_from_IRunnableObject(iface);
1279 
1280   return IUnknown_AddRef(This->outerUnknown);
1281 }
1282 
1283 /************************************************************************
1284  * DefaultHandler_IRunnableObject_Release (IUnknown)
1285  *
1286  * See Windows documentation for more details on IUnknown methods.
1287  */
1288 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1289             IRunnableObject*     iface)
1290 {
1291   DefaultHandler *This = impl_from_IRunnableObject(iface);
1292 
1293   return IUnknown_Release(This->outerUnknown);
1294 }
1295 
1296 /************************************************************************
1297  * DefaultHandler_GetRunningClass (IRunnableObject)
1298  *
1299  * See Windows documentation for more details on IRunnableObject methods.
1300  */
1301 static HRESULT WINAPI DefaultHandler_GetRunningClass(
1302             IRunnableObject*     iface,
1303             LPCLSID              lpClsid)
1304 {
1305   FIXME("()\n");
1306   return S_OK;
1307 }
1308 
1309 static HRESULT WINAPI DefaultHandler_Run(
1310             IRunnableObject*     iface,
1311             IBindCtx*            pbc)
1312 {
1313   DefaultHandler *This = impl_from_IRunnableObject(iface);
1314   HRESULT hr;
1315 
1316   FIXME("(%p): semi-stub\n", pbc);
1317 
1318   /* already running? if so nothing to do */
1319   if (object_is_running(This))
1320     return S_OK;
1321 
1322   release_delegates(This);
1323 
1324   hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
1325                         &IID_IOleObject, (void **)&This->pOleDelegate);
1326   if (FAILED(hr))
1327     return hr;
1328 
1329   This->object_state = object_state_running;
1330 
1331   hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
1332 
1333   if (SUCCEEDED(hr) && This->clientSite)
1334     hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
1335 
1336   if (SUCCEEDED(hr))
1337   {
1338     IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
1339                               (void **)&This->pPSDelegate);
1340     if (This->pPSDelegate)
1341     {
1342       if(This->storage_state == storage_state_initialised)
1343         hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
1344       else if(This->storage_state == storage_state_loaded)
1345         hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
1346     }
1347   }
1348 
1349   if (SUCCEEDED(hr) && This->containerApp)
1350     hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
1351                                  This->containerObj);
1352 
1353   /* FIXME: do more stuff here:
1354    * - IOleObject_GetMiscStatus
1355    * - IOleObject_GetMoniker
1356    * - IOleCache_OnRun
1357    */
1358 
1359   if (SUCCEEDED(hr))
1360     hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
1361                                    (void **)&This->pDataDelegate);
1362 
1363   if (SUCCEEDED(hr) && This->dataAdviseHolder)
1364     hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1365 
1366   if (FAILED(hr))
1367   {
1368     DefaultHandler_Stop(This);
1369     release_delegates(This);
1370   }
1371 
1372   return hr;
1373 }
1374 
1375 /************************************************************************
1376  * DefaultHandler_IsRunning (IRunnableObject)
1377  *
1378  * See Windows documentation for more details on IRunnableObject methods.
1379  */
1380 static BOOL    WINAPI DefaultHandler_IsRunning(
1381             IRunnableObject*     iface)
1382 {
1383   DefaultHandler *This = impl_from_IRunnableObject(iface);
1384 
1385   TRACE("()\n");
1386 
1387   if (This->object_state == object_state_running)
1388     return TRUE;
1389   else
1390     return FALSE;
1391 }
1392 
1393 /************************************************************************
1394  * DefaultHandler_LockRunning (IRunnableObject)
1395  *
1396  * See Windows documentation for more details on IRunnableObject methods.
1397  */
1398 static HRESULT WINAPI DefaultHandler_LockRunning(
1399             IRunnableObject*     iface,
1400             BOOL                 fLock,
1401             BOOL                 fLastUnlockCloses)
1402 {
1403   FIXME("()\n");
1404   return S_OK;
1405 }
1406 
1407 /************************************************************************
1408  * DefaultHandler_SetContainedObject (IRunnableObject)
1409  *
1410  * See Windows documentation for more details on IRunnableObject methods.
1411  */
1412 static HRESULT WINAPI DefaultHandler_SetContainedObject(
1413             IRunnableObject*     iface,
1414             BOOL                 fContained)
1415 {
1416   FIXME("()\n");
1417   return S_OK;
1418 }
1419 
1420 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
1421     IAdviseSink *iface,
1422     REFIID riid,
1423     void **ppvObject)
1424 {
1425     if (IsEqualIID(riid, &IID_IUnknown) ||
1426         IsEqualIID(riid, &IID_IAdviseSink))
1427     {
1428         *ppvObject = iface;
1429         IAdviseSink_AddRef(iface);
1430         return S_OK;
1431     }
1432 
1433     return E_NOINTERFACE;
1434 }
1435 
1436 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
1437     IAdviseSink *iface)
1438 {
1439     DefaultHandler *This = impl_from_IAdviseSink(iface);
1440 
1441     return IUnknown_AddRef(&This->IUnknown_iface);
1442 }
1443 
1444 static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
1445             IAdviseSink *iface)
1446 {
1447     DefaultHandler *This = impl_from_IAdviseSink(iface);
1448 
1449     return IUnknown_Release(&This->IUnknown_iface);
1450 }
1451 
1452 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
1453     IAdviseSink *iface,
1454     FORMATETC *pFormatetc,
1455     STGMEDIUM *pStgmed)
1456 {
1457     FIXME(": stub\n");
1458 }
1459 
1460 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
1461     IAdviseSink *iface,
1462     DWORD dwAspect,
1463     LONG lindex)
1464 {
1465     FIXME(": stub\n");
1466 }
1467 
1468 static void WINAPI DefaultHandler_IAdviseSink_OnRename(
1469     IAdviseSink *iface,
1470     IMoniker *pmk)
1471 {
1472     DefaultHandler *This = impl_from_IAdviseSink(iface);
1473 
1474     TRACE("(%p)\n", pmk);
1475 
1476     if (This->oleAdviseHolder)
1477         IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1478 }
1479 
1480 static void WINAPI DefaultHandler_IAdviseSink_OnSave(
1481     IAdviseSink *iface)
1482 {
1483     DefaultHandler *This = impl_from_IAdviseSink(iface);
1484 
1485     TRACE("()\n");
1486 
1487     if (This->oleAdviseHolder)
1488         IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1489 }
1490 
1491 static void WINAPI DefaultHandler_IAdviseSink_OnClose(
1492     IAdviseSink *iface)
1493 {
1494     DefaultHandler *This = impl_from_IAdviseSink(iface);
1495     
1496     TRACE("()\n");
1497 
1498     if (This->oleAdviseHolder)
1499         IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1500 
1501     DefaultHandler_Stop(This);
1502 }
1503 
1504 
1505 /************************************************************************
1506  * DefaultHandler_IPersistStorage_QueryInterface
1507  *
1508  */
1509 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
1510             IPersistStorage*     iface,
1511             REFIID               riid,
1512             void**               ppvObject)
1513 {
1514   DefaultHandler *This = impl_from_IPersistStorage(iface);
1515 
1516   return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1517 }
1518 
1519 /************************************************************************
1520  * DefaultHandler_IPersistStorage_AddRef
1521  *
1522  */
1523 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
1524             IPersistStorage*     iface)
1525 {
1526   DefaultHandler *This = impl_from_IPersistStorage(iface);
1527 
1528   return IUnknown_AddRef(This->outerUnknown);
1529 }
1530 
1531 /************************************************************************
1532  * DefaultHandler_IPersistStorage_Release
1533  *
1534  */
1535 static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
1536             IPersistStorage*     iface)
1537 {
1538   DefaultHandler *This = impl_from_IPersistStorage(iface);
1539 
1540   return IUnknown_Release(This->outerUnknown);
1541 }
1542 
1543 /************************************************************************
1544  * DefaultHandler_IPersistStorage_GetClassID
1545  *
1546  */
1547 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
1548             IPersistStorage*     iface,
1549             CLSID*               clsid)
1550 {
1551     DefaultHandler *This = impl_from_IPersistStorage(iface);
1552     HRESULT hr;
1553 
1554     TRACE("(%p)->(%p)\n", iface, clsid);
1555 
1556     if(object_is_running(This))
1557         hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1558     else
1559         hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
1560 
1561     return hr;
1562 }
1563 
1564 /************************************************************************
1565  * DefaultHandler_IPersistStorage_IsDirty
1566  *
1567  */
1568 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
1569             IPersistStorage*     iface)
1570 {
1571     DefaultHandler *This = impl_from_IPersistStorage(iface);
1572     HRESULT hr;
1573 
1574     TRACE("(%p)\n", iface);
1575 
1576     hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
1577     if(hr != S_FALSE) return hr;
1578 
1579     if(object_is_running(This))
1580         hr = IPersistStorage_IsDirty(This->pPSDelegate);
1581 
1582     return hr;
1583 }
1584 
1585 /***********************************************************************
1586  *   init_ole_stream
1587  *
1588  * Creates the '\1Ole' stream.
1589  * The format of this stream is as follows:
1590  *
1591  * DWORD Version == 0x02000001
1592  * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
1593  * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
1594  *                           supplied by the app that creates the data structure.  May be
1595  *                           ignored on processing].
1596  *
1597  * DWORD Reserved == 0
1598  * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
1599  * CLSID clsid - class id of object capable of processing the moniker
1600  * BYTE  data[] - moniker data for a link
1601  */
1602 
1603 static const WCHAR OleStream[] = {1,'O','l','e',0};
1604 typedef struct
1605 {
1606     DWORD version;
1607     DWORD flags;
1608     DWORD link_update_opt;
1609     DWORD res;
1610     DWORD moniker_size;
1611 } ole_stream_header_t;
1612 static const DWORD ole_stream_version = 0x02000001;
1613 
1614 static void init_ole_stream(IStorage *storage)
1615 {
1616     HRESULT hr;
1617     IStream *stream;
1618 
1619     hr = IStorage_CreateStream(storage, OleStream, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream);
1620     if(SUCCEEDED(hr))
1621     {
1622         DWORD written;
1623         ole_stream_header_t header;
1624 
1625         header.version         = ole_stream_version;
1626         header.flags           = 0;
1627         header.link_update_opt = 0;
1628         header.res             = 0;
1629         header.moniker_size    = 0;
1630 
1631         IStream_Write(stream, &header, sizeof(header), &written);
1632         IStream_Release(stream);
1633     }
1634     return;
1635 }
1636 
1637 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
1638 {
1639     IStream *stream;
1640     HRESULT hr;
1641 
1642     hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);
1643 
1644     if(SUCCEEDED(hr))
1645     {
1646         DWORD read;
1647         ole_stream_header_t header;
1648 
1649         hr = IStream_Read(stream, &header, sizeof(header), &read);
1650         if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
1651         {
1652             if(header.flags & 1)
1653             {
1654                 /* FIXME: Read the moniker and deal with the link */
1655                 FIXME("Linked objects are not supported yet\n");
1656             }
1657         }
1658         else
1659         {
1660             WARN("Incorrect OleStream header\n");
1661             hr = DV_E_CLIPFORMAT;
1662         }
1663         IStream_Release(stream);
1664     }
1665     else
1666     {
1667         init_ole_stream(storage);
1668         hr = S_OK;
1669     }
1670     return hr;
1671 }
1672 
1673 /************************************************************************
1674  * DefaultHandler_IPersistStorage_InitNew
1675  *
1676  */
1677 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
1678            IPersistStorage*     iface,
1679            IStorage*            pStg)
1680 {
1681     DefaultHandler *This = impl_from_IPersistStorage(iface);
1682     HRESULT hr;
1683 
1684     TRACE("(%p)->(%p)\n", iface, pStg);
1685     init_ole_stream(pStg);
1686 
1687     hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
1688 
1689     if(SUCCEEDED(hr) && object_is_running(This))
1690         hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1691 
1692     if(SUCCEEDED(hr))
1693     {
1694         IStorage_AddRef(pStg);
1695         This->storage = pStg;
1696         This->storage_state = storage_state_initialised;
1697     }
1698 
1699     return hr;
1700 }
1701 
1702 
1703 /************************************************************************
1704  * DefaultHandler_IPersistStorage_Load
1705  *
1706  */
1707 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
1708            IPersistStorage*     iface,
1709            IStorage*            pStg)
1710 {
1711     DefaultHandler *This = impl_from_IPersistStorage(iface);
1712     HRESULT hr;
1713 
1714     TRACE("(%p)->(%p)\n", iface, pStg);
1715 
1716     hr = load_ole_stream(This, pStg);
1717 
1718     if(SUCCEEDED(hr))
1719         hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1720 
1721     if(SUCCEEDED(hr) && object_is_running(This))
1722         hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1723 
1724     if(SUCCEEDED(hr))
1725     {
1726         IStorage_AddRef(pStg);
1727         This->storage = pStg;
1728         This->storage_state = storage_state_loaded;
1729     }
1730     return hr;
1731 }
1732 
1733 
1734 /************************************************************************
1735  * DefaultHandler_IPersistStorage_Save
1736  *
1737  */
1738 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
1739            IPersistStorage*     iface,
1740            IStorage*            pStgSave,
1741            BOOL                 fSameAsLoad)
1742 {
1743     DefaultHandler *This = impl_from_IPersistStorage(iface);
1744     HRESULT hr;
1745 
1746     TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1747 
1748     hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
1749     if(SUCCEEDED(hr) && object_is_running(This))
1750         hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1751 
1752     return hr;
1753 }
1754 
1755 
1756 /************************************************************************
1757  * DefaultHandler_IPersistStorage_SaveCompleted
1758  *
1759  */
1760 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
1761            IPersistStorage*     iface,
1762            IStorage*            pStgNew)
1763 {
1764     DefaultHandler *This = impl_from_IPersistStorage(iface);
1765     HRESULT hr;
1766 
1767     TRACE("(%p)->(%p)\n", iface, pStgNew);
1768 
1769     hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
1770 
1771     if(SUCCEEDED(hr) && object_is_running(This))
1772         hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1773 
1774     if(pStgNew)
1775     {
1776         IStorage_AddRef(pStgNew);
1777         if(This->storage) IStorage_Release(This->storage);
1778         This->storage = pStgNew;
1779         This->storage_state = storage_state_loaded;
1780     }
1781 
1782     return hr;
1783 }
1784 
1785 
1786 /************************************************************************
1787  * DefaultHandler_IPersistStorage_HandsOffStorage
1788  *
1789  */
1790 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
1791             IPersistStorage*     iface)
1792 {
1793     DefaultHandler *This = impl_from_IPersistStorage(iface);
1794     HRESULT hr;
1795 
1796     TRACE("(%p)\n", iface);
1797 
1798     hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
1799 
1800     if(SUCCEEDED(hr) && object_is_running(This))
1801         hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1802 
1803     if(This->storage) IStorage_Release(This->storage);
1804     This->storage = NULL;
1805     This->storage_state = storage_state_uninitialised;
1806 
1807     return hr;
1808 }
1809 
1810 
1811 /*
1812  * Virtual function tables for the DefaultHandler class.
1813  */
1814 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
1815 {
1816   DefaultHandler_QueryInterface,
1817   DefaultHandler_AddRef,
1818   DefaultHandler_Release,
1819   DefaultHandler_SetClientSite,
1820   DefaultHandler_GetClientSite,
1821   DefaultHandler_SetHostNames,
1822   DefaultHandler_Close,
1823   DefaultHandler_SetMoniker,
1824   DefaultHandler_GetMoniker,
1825   DefaultHandler_InitFromData,
1826   DefaultHandler_GetClipboardData,
1827   DefaultHandler_DoVerb,
1828   DefaultHandler_EnumVerbs,
1829   DefaultHandler_Update,
1830   DefaultHandler_IsUpToDate,
1831   DefaultHandler_GetUserClassID,
1832   DefaultHandler_GetUserType,
1833   DefaultHandler_SetExtent,
1834   DefaultHandler_GetExtent,
1835   DefaultHandler_Advise,
1836   DefaultHandler_Unadvise,
1837   DefaultHandler_EnumAdvise,
1838   DefaultHandler_GetMiscStatus,
1839   DefaultHandler_SetColorScheme
1840 };
1841 
1842 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
1843 {
1844   DefaultHandler_NDIUnknown_QueryInterface,
1845   DefaultHandler_NDIUnknown_AddRef,
1846   DefaultHandler_NDIUnknown_Release,
1847 };
1848 
1849 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
1850 {
1851   DefaultHandler_IDataObject_QueryInterface,
1852   DefaultHandler_IDataObject_AddRef,
1853   DefaultHandler_IDataObject_Release,
1854   DefaultHandler_GetData,
1855   DefaultHandler_GetDataHere,
1856   DefaultHandler_QueryGetData,
1857   DefaultHandler_GetCanonicalFormatEtc,
1858   DefaultHandler_SetData,
1859   DefaultHandler_EnumFormatEtc,
1860   DefaultHandler_DAdvise,
1861   DefaultHandler_DUnadvise,
1862   DefaultHandler_EnumDAdvise
1863 };
1864 
1865 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
1866 {
1867   DefaultHandler_IRunnableObject_QueryInterface,
1868   DefaultHandler_IRunnableObject_AddRef,
1869   DefaultHandler_IRunnableObject_Release,
1870   DefaultHandler_GetRunningClass,
1871   DefaultHandler_Run,
1872   DefaultHandler_IsRunning,
1873   DefaultHandler_LockRunning,
1874   DefaultHandler_SetContainedObject
1875 };
1876 
1877 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
1878 {
1879   DefaultHandler_IAdviseSink_QueryInterface,
1880   DefaultHandler_IAdviseSink_AddRef,
1881   DefaultHandler_IAdviseSink_Release,
1882   DefaultHandler_IAdviseSink_OnDataChange,
1883   DefaultHandler_IAdviseSink_OnViewChange,
1884   DefaultHandler_IAdviseSink_OnRename,
1885   DefaultHandler_IAdviseSink_OnSave,
1886   DefaultHandler_IAdviseSink_OnClose
1887 };
1888 
1889 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
1890 {
1891   DefaultHandler_IPersistStorage_QueryInterface,
1892   DefaultHandler_IPersistStorage_AddRef,
1893   DefaultHandler_IPersistStorage_Release,
1894   DefaultHandler_IPersistStorage_GetClassID,
1895   DefaultHandler_IPersistStorage_IsDirty,
1896   DefaultHandler_IPersistStorage_InitNew,
1897   DefaultHandler_IPersistStorage_Load,
1898   DefaultHandler_IPersistStorage_Save,
1899   DefaultHandler_IPersistStorage_SaveCompleted,
1900   DefaultHandler_IPersistStorage_HandsOffStorage
1901 };
1902 
1903 /*********************************************************
1904  * Methods implementation for the DefaultHandler class.
1905  */
1906 static DefaultHandler* DefaultHandler_Construct(
1907   REFCLSID  clsid,
1908   LPUNKNOWN pUnkOuter,
1909   DWORD flags,
1910   IClassFactory *pCF)
1911 {
1912   DefaultHandler* This = NULL;
1913   HRESULT hr;
1914 
1915   This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1916 
1917   if (!This)
1918     return This;
1919 
1920   This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable;
1921   This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable;
1922   This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable;
1923   This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable;
1924   This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable;
1925   This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable;
1926 
1927   This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) ? TRUE : FALSE;
1928 
1929   /*
1930    * Start with one reference count. The caller of this function
1931    * must release the interface pointer when it is done.
1932    */
1933   This->ref = 1;
1934 
1935   /*
1936    * Initialize the outer unknown
1937    * We don't keep a reference on the outer unknown since, the way
1938    * aggregation works, our lifetime is at least as large as its
1939    * lifetime.
1940    */
1941   if (!pUnkOuter)
1942     pUnkOuter = &This->IUnknown_iface;
1943 
1944   This->outerUnknown = pUnkOuter;
1945 
1946   /*
1947    * Create a datacache object.
1948    * We aggregate with the datacache. Make sure we pass our outer
1949    * unknown as the datacache's outer unknown.
1950    */
1951   hr = CreateDataCache(This->outerUnknown,
1952                        clsid,
1953                        &IID_IUnknown,
1954                        (void**)&This->dataCache);
1955   if(SUCCEEDED(hr))
1956   {
1957     hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
1958     /* keeping a reference to This->dataCache_PersistStg causes us to keep a
1959      * reference on the outer object */
1960     if (SUCCEEDED(hr))
1961         IUnknown_Release(This->outerUnknown);
1962     else
1963         IUnknown_Release(This->dataCache);
1964   }
1965   if(FAILED(hr))
1966   {
1967     ERR("Unexpected error creating data cache\n");
1968     HeapFree(GetProcessHeap(), 0, This);
1969     return NULL;
1970   }
1971 
1972   This->clsid = *clsid;
1973   This->clientSite = NULL;
1974   This->oleAdviseHolder = NULL;
1975   This->dataAdviseHolder = NULL;
1976   This->containerApp = NULL;
1977   This->containerObj = NULL;
1978   This->pOleDelegate = NULL;
1979   This->pPSDelegate = NULL;
1980   This->pDataDelegate = NULL;
1981   This->object_state = object_state_not_running;
1982 
1983   This->dwAdvConn = 0;
1984   This->storage = NULL;
1985   This->storage_state = storage_state_uninitialised;
1986 
1987   if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
1988   {
1989     HRESULT hr;
1990     This->pCFObject = NULL;
1991     if (pCF)
1992       hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
1993     else
1994       hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
1995                             &IID_IOleObject, (void **)&This->pOleDelegate);
1996     if (SUCCEEDED(hr))
1997       hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
1998     if (SUCCEEDED(hr))
1999       hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
2000     if (SUCCEEDED(hr))
2001       This->object_state = object_state_running;
2002     if (FAILED(hr))
2003       WARN("object creation failed with error %08x\n", hr);
2004   }
2005   else
2006   {
2007     This->pCFObject = pCF;
2008     if (pCF) IClassFactory_AddRef(pCF);
2009   }
2010 
2011   return This;
2012 }
2013 
2014 static void DefaultHandler_Destroy(
2015   DefaultHandler* This)
2016 {
2017   TRACE("(%p)\n", This);
2018 
2019   /* AddRef/Release may be called on this object during destruction.
2020    * Prevent the object being destroyed recursively by artificially raising
2021    * the reference count. */
2022   This->ref = 10000;
2023 
2024   /* release delegates */
2025   DefaultHandler_Stop(This);
2026   release_delegates(This);
2027 
2028   HeapFree( GetProcessHeap(), 0, This->containerApp );
2029   This->containerApp = NULL;
2030   HeapFree( GetProcessHeap(), 0, This->containerObj );
2031   This->containerObj = NULL;
2032 
2033   if (This->dataCache)
2034   {
2035     /* to balance out the release of dataCache_PersistStg which will result
2036      * in a reference being released from the outer unknown */
2037     IUnknown_AddRef(This->outerUnknown);
2038     IPersistStorage_Release(This->dataCache_PersistStg);
2039     IUnknown_Release(This->dataCache);
2040     This->dataCache_PersistStg = NULL;
2041     This->dataCache = NULL;
2042   }
2043 
2044   if (This->clientSite)
2045   {
2046     IOleClientSite_Release(This->clientSite);
2047     This->clientSite = NULL;
2048   }
2049 
2050   if (This->oleAdviseHolder)
2051   {
2052     IOleAdviseHolder_Release(This->oleAdviseHolder);
2053     This->oleAdviseHolder = NULL;
2054   }
2055 
2056   if (This->dataAdviseHolder)
2057   {
2058     IDataAdviseHolder_Release(This->dataAdviseHolder);
2059     This->dataAdviseHolder = NULL;
2060   }
2061 
2062   if (This->storage)
2063   {
2064     IStorage_Release(This->storage);
2065     This->storage = NULL;
2066   }
2067 
2068   if (This->pCFObject)
2069   {
2070     IClassFactory_Release(This->pCFObject);
2071     This->pCFObject = NULL;
2072   }
2073 
2074   HeapFree(GetProcessHeap(), 0, This);
2075 }
2076 
2077 /******************************************************************************
2078  * OleCreateEmbeddingHelper [OLE32.@]
2079  */
2080 HRESULT WINAPI OleCreateEmbeddingHelper(
2081   REFCLSID  clsid,
2082   LPUNKNOWN pUnkOuter,
2083   DWORD     flags,
2084   IClassFactory *pCF,
2085   REFIID    riid,
2086   LPVOID*   ppvObj)
2087 {
2088   DefaultHandler* newHandler = NULL;
2089   HRESULT         hr         = S_OK;
2090 
2091   TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2092 
2093   if (!ppvObj)
2094     return E_POINTER;
2095 
2096   *ppvObj = NULL;
2097 
2098   /*
2099    * If This handler is constructed for aggregation, make sure
2100    * the caller is requesting the IUnknown interface.
2101    * This is necessary because it's the only time the non-delegating
2102    * IUnknown pointer can be returned to the outside.
2103    */
2104   if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2105     return CLASS_E_NOAGGREGATION;
2106 
2107   /*
2108    * Try to construct a new instance of the class.
2109    */
2110   newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2111 
2112   if (!newHandler)
2113     return E_OUTOFMEMORY;
2114 
2115   /*
2116    * Make sure it supports the interface required by the caller.
2117    */
2118   hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj);
2119 
2120   /*
2121    * Release the reference obtained in the constructor. If
2122    * the QueryInterface was unsuccessful, it will free the class.
2123    */
2124   IUnknown_Release(&newHandler->IUnknown_iface);
2125 
2126   return hr;
2127 }
2128 
2129 
2130 /******************************************************************************
2131  * OleCreateDefaultHandler [OLE32.@]
2132  */
2133 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
2134                                        REFIID riid, LPVOID* ppvObj)
2135 {
2136     TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
2137     return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
2138                                     NULL, riid, ppvObj);
2139 }
2140 
2141 typedef struct HandlerCF
2142 {
2143     IClassFactory IClassFactory_iface;
2144     LONG refs;
2145     CLSID clsid;
2146 } HandlerCF;
2147 
2148 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
2149 {
2150     return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
2151 }
2152 
2153 static HRESULT WINAPI
2154 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
2155 {
2156     *ppv = NULL;
2157     if (IsEqualIID(riid,&IID_IUnknown) ||
2158         IsEqualIID(riid,&IID_IClassFactory))
2159     {
2160         *ppv = iface;
2161         IClassFactory_AddRef(iface);
2162         return S_OK;
2163     }
2164     return E_NOINTERFACE;
2165 }
2166 
2167 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
2168 {
2169     HandlerCF *This = impl_from_IClassFactory(iface);
2170     return InterlockedIncrement(&This->refs);
2171 }
2172 
2173 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
2174 {
2175     HandlerCF *This = impl_from_IClassFactory(iface);
2176     ULONG refs = InterlockedDecrement(&This->refs);
2177     if (!refs)
2178         HeapFree(GetProcessHeap(), 0, This);
2179     return refs;
2180 }
2181 
2182 static HRESULT WINAPI
2183 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
2184                          REFIID riid, LPVOID *ppv)
2185 {
2186     HandlerCF *This = impl_from_IClassFactory(iface);
2187     return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
2188 }
2189 
2190 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
2191 {
2192     FIXME("(%d), stub!\n",fLock);
2193     return S_OK;
2194 }
2195 
2196 static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
2197     HandlerCF_QueryInterface,
2198     HandlerCF_AddRef,
2199     HandlerCF_Release,
2200     HandlerCF_CreateInstance,
2201     HandlerCF_LockServer
2202 };
2203 
2204 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
2205 {
2206     HRESULT hr;
2207     HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
2208     if (!This) return E_OUTOFMEMORY;
2209     This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
2210     This->refs = 0;
2211     This->clsid = *rclsid;
2212 
2213     hr = IUnknown_QueryInterface((IUnknown *)&This->IClassFactory_iface, riid, ppv);
2214     if (FAILED(hr))
2215         HeapFree(GetProcessHeap(), 0, This);
2216 
2217     return hr;
2218 }
2219 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.