defaulthandler.c 64.6 KB
Newer Older
1 2 3 4
/*
 *	OLE 2 default object handler
 *
 *      Copyright 1999  Francis Beaudet
5
 *      Copyright 2000  Abey George
6
 *
7 8 9 10 11 12 13 14 15 16 17 18
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * 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 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
 * NOTES:
 *    The OLE2 default object handler supports a whole whack of
 *    interfaces including:
 *       IOleObject, IDataObject, IPersistStorage, IViewObject2,
 *       IRunnableObject, IOleCache2, IOleCacheControl and much more.
 *
 *    All the implementation details are taken from: Inside OLE
 *    second edition by Kraig Brockschmidt,
 *
 * TODO
 * - This implementation of the default handler does not launch the
 *   server in the DoVerb, Update, GetData, GetDataHere and Run
 *   methods. When it is fixed to do so, all the methods will have
 *   to be  revisited to allow delegating to the running object
 *
 * - All methods in the class that use the class ID should be
 *   aware that it is possible for a class to be treated as
 *   another one and go into emulation mode. Nothing has been
 *   done in this area.
 *
41
 * - Some functions still return E_NOTIMPL they have to be
42
 *   implemented. Most of those are related to the running of the
43 44
 *   actual server.
 *
45
 * - All the methods related to notification and advise sinks are
46 47 48
 *   in place but no notifications are sent to the sinks yet.
 */
#include <assert.h>
49
#include <stdarg.h>
50
#include <string.h>
51

52 53
#define COBJMACROS

54
#include "windef.h"
55
#include "winbase.h"
56
#include "winuser.h"
57 58
#include "winerror.h"
#include "ole2.h"
59 60

#include "compobj_private.h"
61
#include "storage32.h"
62 63

#include "wine/unicode.h"
64
#include "wine/debug.h"
65

66
WINE_DEFAULT_DEBUG_CHANNEL(ole);
67

68 69 70 71 72 73 74
enum storage_state
{
    storage_state_uninitialised,
    storage_state_initialised,
    storage_state_loaded
};

75 76 77
enum object_state
{
    object_state_not_running,
78 79
    object_state_running,
    object_state_deferred_close
80 81
};

82 83 84 85 86 87
/****************************************************************************
 * DefaultHandler
 *
 */
struct DefaultHandler
{
88 89 90 91 92 93
  IOleObject        IOleObject_iface;
  IUnknown          IUnknown_iface;
  IDataObject       IDataObject_iface;
  IRunnableObject   IRunnableObject_iface;
  IAdviseSink       IAdviseSink_iface;
  IPersistStorage   IPersistStorage_iface;
94

95
  /* Reference count of this object */
96
  LONG ref;
97

98
  /* IUnknown implementation of the outer object. */
99 100
  IUnknown* outerUnknown;

101
  /* Class Id that this handler object represents. */
102 103
  CLSID clsid;

104
  /* IUnknown implementation of the datacache. */
105
  IUnknown* dataCache;
106 107
  /* IPersistStorage implementation of the datacache. */
  IPersistStorage* dataCache_PersistStg;
108

109
  /* Client site for the embedded object. */
110 111 112 113 114 115 116 117 118
  IOleClientSite* clientSite;

  /*
   * The IOleAdviseHolder maintains the connections
   * on behalf of the default handler.
   */
  IOleAdviseHolder* oleAdviseHolder;

  /*
119
   * The IDataAdviseHolder maintains the data
120 121 122 123
   * connections on behalf of the default handler.
   */
  IDataAdviseHolder* dataAdviseHolder;

124
  /* Name of the container and object contained */
125
  LPWSTR containerApp;
126
  LPWSTR containerObj;
127

128 129 130 131
  /* IOleObject delegate */
  IOleObject *pOleDelegate;
  /* IPersistStorage delegate */
  IPersistStorage *pPSDelegate;
132 133
  /* IDataObject delegate */
  IDataObject *pDataDelegate;
134
  enum object_state object_state;
135
  ULONG in_call;
136 137 138

  /* connection cookie for the advise on the delegate OLE object */
  DWORD dwAdvConn;
139 140 141 142

  /* storage passed to Load or InitNew */
  IStorage *storage;
  enum storage_state storage_state;
143 144 145 146 147

  /* optional class factory for object */
  IClassFactory *pCFObject;
  /* TRUE if acting as an inproc server instead of an inproc handler */
  BOOL inproc_server;
148 149 150 151
};

typedef struct DefaultHandler DefaultHandler;

152 153
static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
{
154
    return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface);
155 156
}

157
static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface )
158
{
159
    return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface);
160 161 162 163
}

static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
{
164
    return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface);
165 166 167 168
}

static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
{
169
    return CONTAINING_RECORD(iface, DefaultHandler, IRunnableObject_iface);
170 171
}

172 173
static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
{
174
    return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface);
175 176
}

177 178
static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
{
179
    return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface);
180 181
}

182
static void DefaultHandler_Destroy(DefaultHandler* This);
183

184 185
static inline BOOL object_is_running(DefaultHandler *This)
{
186
    return IRunnableObject_IsRunning(&This->IRunnableObject_iface);
187
}
188

189 190 191 192 193 194 195 196 197 198 199 200 201 202
static void DefaultHandler_Stop(DefaultHandler *This);

static inline void start_object_call(DefaultHandler *This)
{
    This->in_call++;
}

static inline void end_object_call(DefaultHandler *This)
{
    This->in_call--;
    if (This->in_call == 0 && This->object_state == object_state_deferred_close)
        DefaultHandler_Stop( This );
}

203 204 205 206 207 208 209 210 211 212
/*********************************************************
 * Method implementation for the  non delegating IUnknown
 * part of the DefaultHandler class.
 */

/************************************************************************
 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 *
Huw Davies's avatar
Huw Davies committed
213
 * This version of QueryInterface will not delegate its implementation
214 215 216 217 218 219 220
 * to the outer unknown.
 */
static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
            IUnknown*      iface,
            REFIID         riid,
            void**         ppvObject)
{
221
  DefaultHandler *This = impl_from_IUnknown(iface);
222

223
  if (!ppvObject)
224
    return E_INVALIDARG;
225

226
  *ppvObject = NULL;
227

228
  if (IsEqualIID(&IID_IUnknown, riid))
229
    *ppvObject = iface;
230
  else if (IsEqualIID(&IID_IOleObject, riid))
231
    *ppvObject = &This->IOleObject_iface;
232
  else if (IsEqualIID(&IID_IDataObject, riid))
233
    *ppvObject = &This->IDataObject_iface;
234
  else if (IsEqualIID(&IID_IRunnableObject, riid))
235
    *ppvObject = &This->IRunnableObject_iface;
236
  else if (IsEqualIID(&IID_IPersist, riid) ||
237
           IsEqualIID(&IID_IPersistStorage, riid))
238
    *ppvObject = &This->IPersistStorage_iface;
239
  else if (IsEqualIID(&IID_IViewObject, riid) ||
240 241 242
           IsEqualIID(&IID_IViewObject2, riid) ||
           IsEqualIID(&IID_IOleCache, riid) ||
           IsEqualIID(&IID_IOleCache2, riid))
243
  {
244 245 246
    HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
    if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
    return hr;
247
  }
248 249
  else if (This->inproc_server && This->pOleDelegate)
  {
250
    return IOleObject_QueryInterface(This->pOleDelegate, riid, ppvObject);
251
  }
252

253 254
  /* Check that we obtained an interface. */
  if (*ppvObject == NULL)
255
  {
Andrey Gusev's avatar
Andrey Gusev committed
256
    WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
257 258
    return E_NOINTERFACE;
  }
259

260 261
  /*
   * Query Interface always increases the reference count by one when it is
262
   * successful.
263 264 265
   */
  IUnknown_AddRef((IUnknown*)*ppvObject);

266
  return S_OK;
267 268 269 270 271 272 273
}

/************************************************************************
 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 *
Huw Davies's avatar
Huw Davies committed
274
 * This version of QueryInterface will not delegate its implementation
275 276
 * to the outer unknown.
 */
277
static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
278 279
            IUnknown*      iface)
{
280
  DefaultHandler *This = impl_from_IUnknown(iface);
281
  return InterlockedIncrement(&This->ref);
282 283 284 285 286 287 288
}

/************************************************************************
 * DefaultHandler_NDIUnknown_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 *
Huw Davies's avatar
Huw Davies committed
289
 * This version of QueryInterface will not delegate its implementation
290 291
 * to the outer unknown.
 */
292
static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
293 294
            IUnknown*      iface)
{
295
  DefaultHandler *This = impl_from_IUnknown(iface);
296
  ULONG ref;
297

298
  ref = InterlockedDecrement(&This->ref);
299

300
  if (!ref) DefaultHandler_Destroy(This);
301

302
  return ref;
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
}

/*********************************************************
 * Methods implementation for the IOleObject part of
 * the DefaultHandler class.
 */

/************************************************************************
 * DefaultHandler_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static HRESULT WINAPI DefaultHandler_QueryInterface(
            IOleObject*      iface,
            REFIID           riid,
            void**           ppvObject)
{
320
  DefaultHandler *This = impl_from_IOleObject(iface);
321

322
  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
323 324 325 326 327 328 329
}

/************************************************************************
 * DefaultHandler_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
330
static ULONG WINAPI DefaultHandler_AddRef(
331 332
            IOleObject*        iface)
{
333
  DefaultHandler *This = impl_from_IOleObject(iface);
334

335
  return IUnknown_AddRef(This->outerUnknown);
336 337 338 339 340 341 342
}

/************************************************************************
 * DefaultHandler_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
343
static ULONG WINAPI DefaultHandler_Release(
344 345
            IOleObject*        iface)
{
346
  DefaultHandler *This = impl_from_IOleObject(iface);
347

348
  return IUnknown_Release(This->outerUnknown);
349 350 351 352 353 354 355 356 357 358 359 360 361 362
}

/************************************************************************
 * DefaultHandler_SetClientSite (IOleObject)
 *
 * The default handler's implementation of this method only keeps the
 * client site pointer for future reference.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetClientSite(
	    IOleObject*        iface,
	    IOleClientSite*    pClientSite)
{
363
  DefaultHandler *This = impl_from_IOleObject(iface);
364
  HRESULT hr = S_OK;
365

366
  TRACE("(%p, %p)\n", iface, pClientSite);
367

368
  if (object_is_running(This))
369 370
  {
    start_object_call( This );
371
    hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
372 373
    end_object_call( This );
  }
374

375 376 377 378
  /*
   * Make sure we release the previous client site if there
   * was one.
   */
379 380
  if (This->clientSite)
    IOleClientSite_Release(This->clientSite);
381

382
  This->clientSite = pClientSite;
383

384 385
  if (This->clientSite)
    IOleClientSite_AddRef(This->clientSite);
386

387
  return hr;
388 389 390 391 392 393 394 395 396 397 398 399 400 401
}

/************************************************************************
 * DefaultHandler_GetClientSite (IOleObject)
 *
 * The default handler's implementation of this method returns the
 * last pointer set in IOleObject_SetClientSite.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetClientSite(
	    IOleObject*        iface,
	    IOleClientSite**   ppClientSite)
{
402
  DefaultHandler *This = impl_from_IOleObject(iface);
403

404
  if (!ppClientSite)
405 406
    return E_POINTER;

407
  *ppClientSite = This->clientSite;
408

409 410
  if (This->clientSite)
    IOleClientSite_AddRef(This->clientSite);
411 412 413 414 415 416 417 418 419 420 421 422 423 424

  return S_OK;
}

/************************************************************************
 * DefaultHandler_SetHostNames (IOleObject)
 *
 * The default handler's implementation of this method just stores
 * the strings and returns S_OK.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetHostNames(
	    IOleObject*        iface,
425
	    LPCOLESTR          szContainerApp,
426 427
	    LPCOLESTR          szContainerObj)
{
428
  DefaultHandler *This = impl_from_IOleObject(iface);
429

430
  TRACE("(%p, %s, %s)\n",
431
	iface,
432
	debugstr_w(szContainerApp),
433 434
	debugstr_w(szContainerObj));

435
  if (object_is_running(This))
436 437
  {
    start_object_call( This );
438
    IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
439 440
    end_object_call( This );
  }
441

Austin English's avatar
Austin English committed
442
  /* Be sure to cleanup before re-assigning the strings. */
443 444 445 446
  HeapFree( GetProcessHeap(), 0, This->containerApp );
  This->containerApp = NULL;
  HeapFree( GetProcessHeap(), 0, This->containerObj );
  This->containerObj = NULL;
447

448
  if (szContainerApp)
449
  {
450
      if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
451
                                           (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
452
          strcpyW( This->containerApp, szContainerApp );
453
  }
454

455
  if (szContainerObj)
456
  {
457
      if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
458
                                           (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
459
          strcpyW( This->containerObj, szContainerObj );
460
  }
461 462 463
  return S_OK;
}

464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
static void release_delegates(DefaultHandler *This)
{
    if (This->pDataDelegate)
    {
        IDataObject_Release(This->pDataDelegate);
        This->pDataDelegate = NULL;
    }
    if (This->pPSDelegate)
    {
        IPersistStorage_Release(This->pPSDelegate);
        This->pPSDelegate = NULL;
    }
    if (This->pOleDelegate)
    {
        IOleObject_Release(This->pOleDelegate);
        This->pOleDelegate = NULL;
    }
}

483 484
/* undoes the work done by DefaultHandler_Run */
static void DefaultHandler_Stop(DefaultHandler *This)
485
{
486 487 488
  IOleCacheControl *cache_ctrl;
  HRESULT hr;

489
  if (This->object_state == object_state_not_running)
490 491
    return;

492 493 494 495 496 497
  hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
  if (SUCCEEDED(hr))
  {
    hr = IOleCacheControl_OnStop( cache_ctrl );
    IOleCacheControl_Release( cache_ctrl );
  }
498

499
  IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
500

501 502
  if (This->dataAdviseHolder)
    DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
503

504
  This->object_state = object_state_not_running;
505
  release_delegates( This );
506 507
}

508 509 510 511 512 513 514 515 516
/************************************************************************
 * DefaultHandler_Close (IOleObject)
 *
 * The default handler's implementation of this method is meaningless
 * without a running server so it does nothing.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_Close(
517
	    IOleObject*        iface,
518 519
	    DWORD              dwSaveOption)
{
520 521 522
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr;

523
  TRACE("(%d)\n", dwSaveOption);
524

525
  if (!object_is_running(This))
526 527
    return S_OK;

528
  start_object_call( This );
529
  hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
530
  end_object_call( This );
531 532 533 534

  DefaultHandler_Stop(This);

  return hr;
535 536 537 538 539 540 541 542 543 544
}

/************************************************************************
 * DefaultHandler_SetMoniker (IOleObject)
 *
 * The default handler's implementation of this method does nothing.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetMoniker(
545
	    IOleObject*        iface,
546 547 548
	    DWORD              dwWhichMoniker,
	    IMoniker*          pmk)
{
549
  DefaultHandler *This = impl_from_IOleObject(iface);
550
  HRESULT hr = S_OK;
551

552
  TRACE("(%p, %d, %p)\n", iface, dwWhichMoniker, pmk);
553

554
  if (object_is_running(This))
555 556 557 558 559
  {
    start_object_call( This );
    hr = IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
    end_object_call( This );
  }
560

561
  return hr;
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
}

/************************************************************************
 * DefaultHandler_GetMoniker (IOleObject)
 *
 * Delegate this request to the client site if we have one.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetMoniker(
	    IOleObject*        iface,
	    DWORD              dwAssign,
	    DWORD              dwWhichMoniker,
	    IMoniker**         ppmk)
{
577
  DefaultHandler *This = impl_from_IOleObject(iface);
578
  HRESULT hr;
579

580
  TRACE("(%p, %d, %d, %p)\n",
581 582
	iface, dwAssign, dwWhichMoniker, ppmk);

583
  if (object_is_running(This))
584 585 586 587 588 589 590
  {
    start_object_call( This );
    hr = IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
                               ppmk);
    end_object_call( This );
    return hr;
  }
591 592

  /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
593
  if (This->clientSite)
594
  {
595
    return IOleClientSite_GetMoniker(This->clientSite,
596 597 598
				     dwAssign,
				     dwWhichMoniker,
				     ppmk);
599

600 601
  }

602
  return E_FAIL;
603 604 605 606 607 608
}

/************************************************************************
 * DefaultHandler_InitFromData (IOleObject)
 *
 * This method is meaningless if the server is not running
609
 *
610 611 612
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_InitFromData(
613 614
	    IOleObject*        iface,
	    IDataObject*       pDataObject,
615 616 617
	    BOOL               fCreation,
	    DWORD              dwReserved)
{
618
  DefaultHandler *This = impl_from_IOleObject(iface);
619
  HRESULT hr = OLE_E_NOTRUNNING;
620

621
  TRACE("(%p, %p, %d, %d)\n",
622 623
	iface, pDataObject, fCreation, dwReserved);

624
  if (object_is_running(This))
625 626 627
  {
    start_object_call( This );
    hr = IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
628
		                   dwReserved);
629 630 631 632
    end_object_call( This );
  }

  return hr;
633 634 635 636 637 638
}

/************************************************************************
 * DefaultHandler_GetClipboardData (IOleObject)
 *
 * This method is meaningless if the server is not running
639
 *
640 641 642
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetClipboardData(
643 644
	    IOleObject*        iface,
	    DWORD              dwReserved,
645 646
	    IDataObject**      ppDataObject)
{
647
  DefaultHandler *This = impl_from_IOleObject(iface);
648
  HRESULT hr = OLE_E_NOTRUNNING;
649

650
  TRACE("(%p, %d, %p)\n",
651 652
	iface, dwReserved, ppDataObject);

653
  if (object_is_running(This))
654 655 656
  {
    start_object_call( This );
    hr = IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
657
                                       ppDataObject);
658 659
    end_object_call( This );
  }
660

661
  return hr;
662 663 664
}

static HRESULT WINAPI DefaultHandler_DoVerb(
665 666 667 668 669 670
	    IOleObject*        iface,
	    LONG               iVerb,
	    struct tagMSG*     lpmsg,
	    IOleClientSite*    pActiveSite,
	    LONG               lindex,
	    HWND               hwndParent,
671 672
	    LPCRECT            lprcPosRect)
{
673
  DefaultHandler *This = impl_from_IOleObject(iface);
674
  IRunnableObject *pRunnableObj = &This->IRunnableObject_iface;
675 676
  HRESULT hr;

677
  TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
678 679 680 681

  hr = IRunnableObject_Run(pRunnableObj, NULL);
  if (FAILED(hr)) return hr;

682 683
  start_object_call( This );
  hr = IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
684
                           lindex, hwndParent, lprcPosRect);
685 686 687
  end_object_call( This );

  return hr;
688 689 690 691 692 693 694
}

/************************************************************************
 * DefaultHandler_EnumVerbs (IOleObject)
 *
 * The default handler implementation of this method simply delegates
 * to OleRegEnumVerbs
695
 *
696 697 698
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_EnumVerbs(
699
	    IOleObject*        iface,
700 701
	    IEnumOLEVERB**     ppEnumOleVerb)
{
702
  DefaultHandler *This = impl_from_IOleObject(iface);
703
  HRESULT hr = OLE_S_USEREG;
704

705
  TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
706

707
  if (object_is_running(This))
708 709
  {
    start_object_call( This );
710
    hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
711 712
    end_object_call( This );
  }
713 714 715 716 717

  if (hr == OLE_S_USEREG)
    return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
  else
    return hr;
718 719 720 721 722
}

static HRESULT WINAPI DefaultHandler_Update(
	    IOleObject*        iface)
{
723
    DefaultHandler *This = impl_from_IOleObject(iface);
724 725
    HRESULT hr;

726 727 728 729 730 731 732
    TRACE("(%p)\n", iface);

    if (!object_is_running(This))
    {
        FIXME("Should run object\n");
        return E_NOTIMPL;
    }
733 734 735 736 737 738

    start_object_call( This );
    hr = IOleObject_Update(This->pOleDelegate);
    end_object_call( This );

    return hr;
739 740 741 742 743 744
}

/************************************************************************
 * DefaultHandler_IsUpToDate (IOleObject)
 *
 * This method is meaningless if the server is not running
745
 *
746 747 748 749 750
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_IsUpToDate(
	    IOleObject*        iface)
{
751
    DefaultHandler *This = impl_from_IOleObject(iface);
752
    HRESULT hr = OLE_E_NOTRUNNING;
753
    TRACE("(%p)\n", iface);
754

755
    if (object_is_running(This))
756 757 758 759 760
    {
        start_object_call( This );
        hr = IOleObject_IsUpToDate(This->pOleDelegate);
        end_object_call( This );
    }
761

762
    return hr;
763 764 765 766 767 768
}

/************************************************************************
 * DefaultHandler_GetUserClassID (IOleObject)
 *
 * TODO: Map to a new class ID if emulation is active.
769
 *
770 771 772
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetUserClassID(
773
	    IOleObject*        iface,
774 775
	    CLSID*             pClsid)
{
776
  DefaultHandler *This = impl_from_IOleObject(iface);
777
  HRESULT hr;
778

779
  TRACE("(%p, %p)\n", iface, pClsid);
780

781
  if (object_is_running(This))
782 783 784 785 786 787
  {
    start_object_call( This );
    hr = IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
    end_object_call( This );
    return hr;
  }
788

789
  if (!pClsid)
790 791
    return E_POINTER;

792
  *pClsid = This->clsid;
793 794 795 796 797 798 799 800 801

  return S_OK;
}

/************************************************************************
 * DefaultHandler_GetUserType (IOleObject)
 *
 * The default handler implementation of this method simply delegates
 * to OleRegGetUserType
802
 *
803 804 805
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetUserType(
806 807
	    IOleObject*        iface,
	    DWORD              dwFormOfType,
808 809
	    LPOLESTR*          pszUserType)
{
810
  DefaultHandler *This = impl_from_IOleObject(iface);
811
  HRESULT hr;
812

813
  TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
814
  if (object_is_running(This))
815 816 817 818 819 820
  {
    start_object_call( This );
    hr = IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
    end_object_call( This );
    return hr;
  }
821

822
  return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
823 824 825 826 827 828 829 830 831 832
}

/************************************************************************
 * DefaultHandler_SetExtent (IOleObject)
 *
 * This method is meaningless if the server is not running
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetExtent(
833 834
	    IOleObject*        iface,
	    DWORD              dwDrawAspect,
835 836
	    SIZEL*             psizel)
{
837
  DefaultHandler *This = impl_from_IOleObject(iface);
838
  HRESULT hr = OLE_E_NOTRUNNING;
839

840
  TRACE("(%p, %x, (%d x %d))\n", iface,
Gerald Pfeifer's avatar
Gerald Pfeifer committed
841
        dwDrawAspect, psizel->cx, psizel->cy);
842

843
  if (object_is_running(This))
844 845 846 847 848
  {
    start_object_call( This );
    hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
    end_object_call( This );
  }
849

850
  return hr;
851 852 853 854 855 856 857 858 859 860 861
}

/************************************************************************
 * DefaultHandler_GetExtent (IOleObject)
 *
 * The default handler's implementation of this method returns uses
 * the cache to locate the aspect and extract the extent from it.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetExtent(
862 863
	    IOleObject*        iface,
	    DWORD              dwDrawAspect,
864 865 866 867 868 869
	    SIZEL*             psizel)
{
  DVTARGETDEVICE* targetDevice;
  IViewObject2*   cacheView = NULL;
  HRESULT         hres;

870
  DefaultHandler *This = impl_from_IOleObject(iface);
871

872
  TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
873

874
  if (object_is_running(This))
875 876 877 878 879 880
  {
    start_object_call( This );
    hres = IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
    end_object_call( This );
    return hres;
  }
881

882
  hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
883 884 885 886 887 888 889
  if (FAILED(hres))
    return E_UNEXPECTED;

  /*
   * Prepare the call to the cache's GetExtent method.
   *
   * Here we would build a valid DVTARGETDEVICE structure
890
   * but, since we are calling into the data cache, we
Huw Davies's avatar
Huw Davies committed
891
   * know its implementation and we'll skip this
892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915
   * extra work until later.
   */
  targetDevice = NULL;

  hres = IViewObject2_GetExtent(cacheView,
				dwDrawAspect,
				-1,
				targetDevice,
				psizel);

  IViewObject2_Release(cacheView);

  return hres;
}

/************************************************************************
 * DefaultHandler_Advise (IOleObject)
 *
 * The default handler's implementation of this method simply
 * delegates to the OleAdviseHolder.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_Advise(
916 917
	    IOleObject*        iface,
	    IAdviseSink*       pAdvSink,
918 919 920
	    DWORD*             pdwConnection)
{
  HRESULT hres = S_OK;
921
  DefaultHandler *This = impl_from_IOleObject(iface);
922

923
  TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
924

925 926 927
  /* Make sure we have an advise holder before we start. */
  if (!This->oleAdviseHolder)
    hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
928 929

  if (SUCCEEDED(hres))
930
    hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
931
				   pAdvSink,
932 933 934 935 936 937 938 939 940 941 942 943 944 945
				   pdwConnection);

  return hres;
}

/************************************************************************
 * DefaultHandler_Unadvise (IOleObject)
 *
 * The default handler's implementation of this method simply
 * delegates to the OleAdviseHolder.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_Unadvise(
946
	    IOleObject*        iface,
947 948
	    DWORD              dwConnection)
{
949
  DefaultHandler *This = impl_from_IOleObject(iface);
950

951
  TRACE("(%p, %d)\n", iface, dwConnection);
952 953 954 955 956

  /*
   * If we don't have an advise holder yet, it means we don't have
   * a connection.
   */
957
  if (!This->oleAdviseHolder)
958 959
    return OLE_E_NOCONNECTION;

960
  return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
961 962 963 964 965 966 967 968 969 970 971 972
				   dwConnection);
}

/************************************************************************
 * DefaultHandler_EnumAdvise (IOleObject)
 *
 * The default handler's implementation of this method simply
 * delegates to the OleAdviseHolder.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_EnumAdvise(
973
	    IOleObject*        iface,
974 975
	    IEnumSTATDATA**    ppenumAdvise)
{
976
  DefaultHandler *This = impl_from_IOleObject(iface);
977

978
  TRACE("(%p, %p)\n", iface, ppenumAdvise);
979

980
  if (!ppenumAdvise)
981 982 983 984
    return E_POINTER;

  *ppenumAdvise = NULL;

985
  if (!This->oleAdviseHolder)
986
      return S_OK;
987

988
  return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
989 990 991 992 993 994 995 996 997 998 999
}

/************************************************************************
 * DefaultHandler_GetMiscStatus (IOleObject)
 *
 * The default handler's implementation of this method simply delegates
 * to OleRegGetMiscStatus.
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetMiscStatus(
1000 1001
	    IOleObject*        iface,
	    DWORD              dwAspect,
1002 1003 1004
	    DWORD*             pdwStatus)
{
  HRESULT hres;
1005
  DefaultHandler *This = impl_from_IOleObject(iface);
1006

1007
  TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
1008

1009
  if (object_is_running(This))
1010 1011 1012 1013 1014 1015
  {
    start_object_call( This );
    hres = IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
    end_object_call( This );
    return hres;
  }
1016

1017
  hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
1018 1019 1020 1021

  if (FAILED(hres))
    *pdwStatus = 0;

1022
  return hres;
1023 1024 1025
}

/************************************************************************
1026
 * DefaultHandler_SetColorScheme (IOleObject)
1027 1028 1029 1030 1031 1032
 *
 * This method is meaningless if the server is not running
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetColorScheme(
1033 1034
	    IOleObject*           iface,
	    struct tagLOGPALETTE* pLogpal)
1035
{
1036
  DefaultHandler *This = impl_from_IOleObject(iface);
1037
  HRESULT hr = OLE_E_NOTRUNNING;
1038

1039
  TRACE("(%p, %p))\n", iface, pLogpal);
1040

1041
  if (object_is_running(This))
1042 1043 1044 1045 1046
  {
    start_object_call( This );
    hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
    end_object_call( This );
  }
1047

1048
  return hr;
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
}

/*********************************************************
 * Methods implementation for the IDataObject part of
 * the DefaultHandler class.
 */

/************************************************************************
 * DefaultHandler_IDataObject_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
1062
            IDataObject*     iface,
1063 1064 1065
           REFIID           riid,
            void**           ppvObject)
{
1066
  DefaultHandler *This = impl_from_IDataObject(iface);
1067

1068
  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1069 1070 1071 1072 1073 1074 1075
}

/************************************************************************
 * DefaultHandler_IDataObject_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
1076
static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
1077 1078
            IDataObject*     iface)
{
1079
  DefaultHandler *This = impl_from_IDataObject(iface);
1080

1081
  return IUnknown_AddRef(This->outerUnknown);
1082 1083 1084 1085 1086 1087 1088
}

/************************************************************************
 * DefaultHandler_IDataObject_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
1089
static ULONG WINAPI DefaultHandler_IDataObject_Release(
1090 1091
            IDataObject*     iface)
{
1092
  DefaultHandler *This = impl_from_IDataObject(iface);
1093

1094
  return IUnknown_Release(This->outerUnknown);
1095 1096
}

1097 1098 1099 1100 1101 1102 1103
/************************************************************************
 * DefaultHandler_GetData
 *
 * Get Data from a source dataobject using format pformatetcIn->cfFormat
 * See Windows documentation for more details on GetData.
 * Default handler's implementation of this method delegates to the cache.
 */
1104 1105
static HRESULT WINAPI DefaultHandler_GetData(
	    IDataObject*     iface,
1106
	    LPFORMATETC      pformatetcIn,
1107 1108
	    STGMEDIUM*       pmedium)
{
1109 1110 1111
  IDataObject* cacheDataObject = NULL;
  HRESULT      hres;

1112
  DefaultHandler *This = impl_from_IDataObject(iface);
1113 1114 1115

  TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);

1116
  hres = IUnknown_QueryInterface(This->dataCache,
1117
				 &IID_IDataObject,
1118
				 (void**)&cacheDataObject);
1119 1120 1121 1122 1123 1124 1125

  if (FAILED(hres))
    return E_UNEXPECTED;

  hres = IDataObject_GetData(cacheDataObject,
			     pformatetcIn,
			     pmedium);
1126

1127
  IDataObject_Release(cacheDataObject);
1128

1129 1130 1131 1132
  if (hres == S_OK) return hres;

  if (object_is_running( This ))
  {
1133
    start_object_call(This);
1134
    hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
1135
    end_object_call(This);
1136 1137 1138 1139 1140 1141
    if (hres == S_OK) return hres;
  }

  /* Query running state again, as the object may have closed during _GetData call */
  if (!object_is_running( This ))
    hres = OLE_E_NOTRUNNING;
1142

1143
  return hres;
1144 1145 1146
}

static HRESULT WINAPI DefaultHandler_GetDataHere(
1147
	    IDataObject*     iface,
1148 1149 1150
	    LPFORMATETC      pformatetc,
	    STGMEDIUM*       pmedium)
{
1151
  FIXME(": Stub\n");
1152 1153 1154 1155 1156 1157
  return E_NOTIMPL;
}

/************************************************************************
 * DefaultHandler_QueryGetData (IDataObject)
 *
1158
 * The default handler's implementation of this method delegates to
1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
 * the cache.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_QueryGetData(
	    IDataObject*     iface,
	    LPFORMATETC      pformatetc)
{
  IDataObject* cacheDataObject = NULL;
  HRESULT      hres;

1170
  DefaultHandler *This = impl_from_IDataObject(iface);
1171

1172
  TRACE("(%p, %p)\n", iface, pformatetc);
1173

1174
  hres = IUnknown_QueryInterface(This->dataCache,
1175
				 &IID_IDataObject,
1176
				 (void**)&cacheDataObject);
1177 1178 1179 1180 1181 1182 1183 1184

  if (FAILED(hres))
    return E_UNEXPECTED;

  hres = IDataObject_QueryGetData(cacheDataObject,
				  pformatetc);

  IDataObject_Release(cacheDataObject);
1185

1186 1187 1188 1189
  if (hres == S_OK) return hres;

  if (object_is_running( This ))
  {
1190
    start_object_call( This );
1191
    hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
1192
    end_object_call( This );
1193 1194 1195 1196 1197 1198
    if (hres == S_OK) return hres;
  }

  /* Query running state again, as the object may have closed during _QueryGetData call */
  if (!object_is_running( This ))
    hres = OLE_E_NOTRUNNING;
1199

1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210
  return hres;
}

/************************************************************************
 * DefaultHandler_GetCanonicalFormatEtc (IDataObject)
 *
 * This method is meaningless if the server is not running
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
1211
	    IDataObject*     iface,
1212
	    LPFORMATETC      pformatetcIn,
1213 1214
	    LPFORMATETC      pformatetcOut)
{
1215
  DefaultHandler *This = impl_from_IDataObject(iface);
1216
  HRESULT hr;
1217

1218 1219
  TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);

1220
  if (!object_is_running( This ))
1221 1222
    return OLE_E_NOTRUNNING;

1223 1224 1225 1226 1227
  start_object_call( This );
  hr = IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
  end_object_call( This );

  return hr;
1228 1229 1230 1231 1232
}

/************************************************************************
 * DefaultHandler_SetData (IDataObject)
 *
1233
 * The default handler's implementation of this method delegates to
1234 1235 1236 1237 1238 1239
 * the cache.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetData(
	    IDataObject*     iface,
1240 1241
	    LPFORMATETC      pformatetc,
	    STGMEDIUM*       pmedium,
1242 1243
	    BOOL             fRelease)
{
1244
  DefaultHandler *This = impl_from_IDataObject(iface);
1245 1246 1247
  IDataObject* cacheDataObject = NULL;
  HRESULT      hres;

1248
  TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1249

1250
  hres = IUnknown_QueryInterface(This->dataCache,
1251
				 &IID_IDataObject,
1252
				 (void**)&cacheDataObject);
1253 1254 1255 1256 1257 1258 1259 1260

  if (FAILED(hres))
    return E_UNEXPECTED;

  hres = IDataObject_SetData(cacheDataObject,
			     pformatetc,
			     pmedium,
			     fRelease);
1261

1262
  IDataObject_Release(cacheDataObject);
1263

1264 1265 1266 1267 1268 1269
  return hres;
}

/************************************************************************
 * DefaultHandler_EnumFormatEtc (IDataObject)
 *
1270
 * The default handler's implementation of This method simply delegates
1271 1272 1273 1274 1275
 * to OleRegEnumFormatEtc.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1276
	    IDataObject*     iface,
1277 1278 1279
	    DWORD            dwDirection,
	    IEnumFORMATETC** ppenumFormatEtc)
{
1280
  DefaultHandler *This = impl_from_IDataObject(iface);
1281

1282
  TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1283

1284
  return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295
}

/************************************************************************
 * DefaultHandler_DAdvise (IDataObject)
 *
 * The default handler's implementation of this method simply
 * delegates to the DataAdviseHolder.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_DAdvise(
1296 1297 1298 1299
	    IDataObject*     iface,
	    FORMATETC*       pformatetc,
	    DWORD            advf,
	    IAdviseSink*     pAdvSink,
1300 1301 1302
	    DWORD*           pdwConnection)
{
  HRESULT hres = S_OK;
1303
  DefaultHandler *This = impl_from_IDataObject(iface);
1304

1305
  TRACE("(%p, %p, %d, %p, %p)\n",
1306 1307
	iface, pformatetc, advf, pAdvSink, pdwConnection);

1308 1309
  /* Make sure we have a data advise holder before we start. */
  if (!This->dataAdviseHolder)
1310
  {
1311
    hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1312
    if (SUCCEEDED(hres) && object_is_running( This ))
1313 1314
    {
      start_object_call( This );
1315
      DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
1316 1317
      end_object_call( This );
    }
1318
  }
1319 1320

  if (SUCCEEDED(hres))
1321
    hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1322
				    iface,
1323 1324 1325
				    pformatetc,
				    advf,
				    pAdvSink,
1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342
				    pdwConnection);

  return hres;
}

/************************************************************************
 * DefaultHandler_DUnadvise (IDataObject)
 *
 * The default handler's implementation of this method simply
 * delegates to the DataAdviseHolder.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_DUnadvise(
	    IDataObject*     iface,
	    DWORD            dwConnection)
{
1343
  DefaultHandler *This = impl_from_IDataObject(iface);
1344

1345
  TRACE("(%p, %d)\n", iface, dwConnection);
1346 1347 1348 1349 1350

  /*
   * If we don't have a data advise holder yet, it means that
   * we don't have any connections..
   */
1351
  if (!This->dataAdviseHolder)
1352 1353
    return OLE_E_NOCONNECTION;

1354
  return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369
				    dwConnection);
}

/************************************************************************
 * DefaultHandler_EnumDAdvise (IDataObject)
 *
 * The default handler's implementation of this method simply
 * delegates to the DataAdviseHolder.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_EnumDAdvise(
	    IDataObject*     iface,
	    IEnumSTATDATA**  ppenumAdvise)
{
1370
  DefaultHandler *This = impl_from_IDataObject(iface);
1371

1372
  TRACE("(%p, %p)\n", iface, ppenumAdvise);
1373

1374
  if (!ppenumAdvise)
1375 1376 1377 1378
    return E_POINTER;

  *ppenumAdvise = NULL;

1379 1380 1381
  /* If we have a data advise holder object, delegate. */
  if (This->dataAdviseHolder)
    return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1382 1383 1384 1385 1386 1387
					ppenumAdvise);

  return S_OK;
}

/*********************************************************
1388
 * Methods implementation for the IRunnableObject part
1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
 * of the DefaultHandler class.
 */

/************************************************************************
 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
            IRunnableObject*     iface,
            REFIID               riid,
            void**               ppvObject)
{
1402
  DefaultHandler *This = impl_from_IRunnableObject(iface);
1403

1404
  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1405 1406 1407
}

/************************************************************************
Huw Davies's avatar
Huw Davies committed
1408
 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1409 1410 1411
 *
 * See Windows documentation for more details on IUnknown methods.
 */
1412
static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1413 1414
            IRunnableObject*     iface)
{
1415
  DefaultHandler *This = impl_from_IRunnableObject(iface);
1416

1417
  return IUnknown_AddRef(This->outerUnknown);
1418 1419 1420
}

/************************************************************************
Huw Davies's avatar
Huw Davies committed
1421
 * DefaultHandler_IRunnableObject_Release (IUnknown)
1422 1423 1424
 *
 * See Windows documentation for more details on IUnknown methods.
 */
1425
static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1426 1427
            IRunnableObject*     iface)
{
1428
  DefaultHandler *This = impl_from_IRunnableObject(iface);
1429

1430
  return IUnknown_Release(This->outerUnknown);
1431 1432 1433 1434 1435 1436 1437
}

/************************************************************************
 * DefaultHandler_GetRunningClass (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
1438 1439
static HRESULT WINAPI DefaultHandler_GetRunningClass(
            IRunnableObject*     iface,
1440 1441
	    LPCLSID              lpClsid)
{
1442
  FIXME("()\n");
1443 1444 1445
  return S_OK;
}

1446
static HRESULT WINAPI DefaultHandler_Run(
1447 1448 1449
            IRunnableObject*     iface,
	    IBindCtx*            pbc)
{
1450 1451
  DefaultHandler *This = impl_from_IRunnableObject(iface);
  HRESULT hr;
1452
  IOleCacheControl *cache_ctrl;
1453 1454 1455 1456

  FIXME("(%p): semi-stub\n", pbc);

  /* already running? if so nothing to do */
1457
  if (object_is_running(This))
1458 1459
    return S_OK;

1460 1461
  release_delegates(This);

1462
  hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,
1463
                        &IID_IOleObject, (void **)&This->pOleDelegate);
1464 1465 1466
  if (FAILED(hr))
    return hr;

1467
  hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
1468
  if (FAILED(hr)) goto fail;
1469

1470
  if (This->clientSite)
1471
  {
1472 1473
    hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
    if (FAILED(hr)) goto fail;
1474 1475
  }

1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487
  hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
                                 (void **)&This->pPSDelegate);
  if (FAILED(hr)) goto fail;

  if (This->storage_state == storage_state_initialised)
      hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
  else if (This->storage_state == storage_state_loaded)
      hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
  if (FAILED(hr)) goto fail;

  if (This->containerApp)
  {
1488 1489
    hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
                                 This->containerObj);
1490 1491
    if (FAILED(hr)) goto fail;
  }
1492 1493 1494 1495 1496 1497

  /* FIXME: do more stuff here:
   * - IOleObject_GetMiscStatus
   * - IOleObject_GetMoniker
   */

1498 1499 1500
  hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
                                 (void **)&This->pDataDelegate);
  if (FAILED(hr)) goto fail;
1501

1502 1503
  This->object_state = object_state_running;

1504
  if (This->dataAdviseHolder)
1505
  {
1506 1507
    hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
    if (FAILED(hr)) goto fail;
1508
  }
1509

1510 1511 1512 1513 1514 1515
  hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
  if (FAILED(hr)) goto fail;
  hr = IOleCacheControl_OnRun( cache_ctrl, This->pDataDelegate );
  IOleCacheControl_Release( cache_ctrl );
  if (FAILED(hr)) goto fail;

1516
  return hr;
1517 1518 1519 1520

fail:
  DefaultHandler_Stop(This);
  return hr;
1521 1522 1523 1524 1525 1526 1527
}

/************************************************************************
 * DefaultHandler_IsRunning (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
1528
static BOOL    WINAPI DefaultHandler_IsRunning(
1529 1530
            IRunnableObject*     iface)
{
1531 1532
  DefaultHandler *This = impl_from_IRunnableObject(iface);

1533
  TRACE("()\n");
1534

1535
  if (This->object_state == object_state_running)
1536 1537 1538
    return TRUE;
  else
    return FALSE;
1539 1540 1541 1542 1543 1544 1545
}

/************************************************************************
 * DefaultHandler_LockRunning (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
1546 1547 1548
static HRESULT WINAPI DefaultHandler_LockRunning(
            IRunnableObject*     iface,
	    BOOL                 fLock,
1549 1550
	    BOOL                 fLastUnlockCloses)
{
1551
  FIXME("()\n");
1552 1553 1554 1555 1556 1557 1558 1559
  return S_OK;
}

/************************************************************************
 * DefaultHandler_SetContainedObject (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
1560 1561
static HRESULT WINAPI DefaultHandler_SetContainedObject(
            IRunnableObject*     iface,
1562 1563
	    BOOL                 fContained)
{
1564
  FIXME("()\n");
1565 1566
  return S_OK;
}
1567

1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588
static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
    IAdviseSink *iface,
    REFIID riid,
    void **ppvObject)
{
    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IAdviseSink))
    {
        *ppvObject = iface;
        IAdviseSink_AddRef(iface);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
    IAdviseSink *iface)
{
    DefaultHandler *This = impl_from_IAdviseSink(iface);

1589
    return IUnknown_AddRef(&This->IUnknown_iface);
1590 1591 1592 1593 1594 1595 1596
}

static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
            IAdviseSink *iface)
{
    DefaultHandler *This = impl_from_IAdviseSink(iface);

1597
    return IUnknown_Release(&This->IUnknown_iface);
1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619
}

static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
    IAdviseSink *iface,
    FORMATETC *pFormatetc,
    STGMEDIUM *pStgmed)
{
    FIXME(": stub\n");
}

static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
    IAdviseSink *iface,
    DWORD dwAspect,
    LONG lindex)
{
    FIXME(": stub\n");
}

static void WINAPI DefaultHandler_IAdviseSink_OnRename(
    IAdviseSink *iface,
    IMoniker *pmk)
{
1620 1621 1622 1623 1624 1625
    DefaultHandler *This = impl_from_IAdviseSink(iface);

    TRACE("(%p)\n", pmk);

    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1626 1627 1628 1629 1630
}

static void WINAPI DefaultHandler_IAdviseSink_OnSave(
    IAdviseSink *iface)
{
1631 1632 1633 1634 1635 1636
    DefaultHandler *This = impl_from_IAdviseSink(iface);

    TRACE("()\n");

    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1637 1638 1639 1640 1641
}

static void WINAPI DefaultHandler_IAdviseSink_OnClose(
    IAdviseSink *iface)
{
1642 1643 1644 1645
    DefaultHandler *This = impl_from_IAdviseSink(iface);
    
    TRACE("()\n");

1646 1647
    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1648

1649 1650 1651 1652 1653 1654 1655
    if(!This->in_call)
        DefaultHandler_Stop(This);
    else
    {
        TRACE("OnClose during call.  Deferring shutdown\n");
        This->object_state = object_state_deferred_close;
    }
1656 1657
}

1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703
/************************************************************************
 * DefaultHandler_IPersistStorage_QueryInterface
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface(
            IPersistStorage*     iface,
            REFIID               riid,
            void**               ppvObject)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
}

/************************************************************************
 * DefaultHandler_IPersistStorage_AddRef
 *
 */
static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef(
            IPersistStorage*     iface)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IUnknown_AddRef(This->outerUnknown);
}

/************************************************************************
 * DefaultHandler_IPersistStorage_Release
 *
 */
static ULONG WINAPI DefaultHandler_IPersistStorage_Release(
            IPersistStorage*     iface)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IUnknown_Release(This->outerUnknown);
}

/************************************************************************
 * DefaultHandler_IPersistStorage_GetClassID
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
            IPersistStorage*     iface,
            CLSID*               clsid)
{
1704 1705 1706 1707
    DefaultHandler *This = impl_from_IPersistStorage(iface);
    HRESULT hr;

    TRACE("(%p)->(%p)\n", iface, clsid);
1708

1709
    if(object_is_running(This))
1710 1711
    {
        start_object_call( This );
1712
        hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
1713 1714
        end_object_call( This );
    }
1715 1716 1717 1718
    else
        hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);

    return hr;
1719 1720 1721 1722 1723 1724 1725 1726 1727
}

/************************************************************************
 * DefaultHandler_IPersistStorage_IsDirty
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
            IPersistStorage*     iface)
{
1728 1729 1730 1731 1732 1733 1734
    DefaultHandler *This = impl_from_IPersistStorage(iface);
    HRESULT hr;

    TRACE("(%p)\n", iface);

    hr = IPersistStorage_IsDirty(This->dataCache_PersistStg);
    if(hr != S_FALSE) return hr;
1735

1736
    if(object_is_running(This))
1737 1738
    {
        start_object_call( This );
1739
        hr = IPersistStorage_IsDirty(This->pPSDelegate);
1740 1741
        end_object_call( This );
    }
1742 1743

    return hr;
1744 1745
}

1746 1747
/***********************************************************************
 *
1748
 * The format of '\1Ole' stream is as follows:
1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772
 *
 * DWORD Version == 0x02000001
 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded.
 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint
 *                           supplied by the app that creates the data structure.  May be
 *                           ignored on processing].
 *
 * DWORD Reserved == 0
 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data).
 * CLSID clsid - class id of object capable of processing the moniker
 * BYTE  data[] - moniker data for a link
 */

static const WCHAR OleStream[] = {1,'O','l','e',0};
typedef struct
{
    DWORD version;
    DWORD flags;
    DWORD link_update_opt;
    DWORD res;
    DWORD moniker_size;
} ole_stream_header_t;
static const DWORD ole_stream_version = 0x02000001;

1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801
static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage)
{
    IStream *stream;
    HRESULT hr;

    hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream);

    if(SUCCEEDED(hr))
    {
        DWORD read;
        ole_stream_header_t header;

        hr = IStream_Read(stream, &header, sizeof(header), &read);
        if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version)
        {
            if(header.flags & 1)
            {
                /* FIXME: Read the moniker and deal with the link */
                FIXME("Linked objects are not supported yet\n");
            }
        }
        else
        {
            WARN("Incorrect OleStream header\n");
            hr = DV_E_CLIPFORMAT;
        }
        IStream_Release(stream);
    }
    else
1802 1803
        hr = STORAGE_CreateOleStream(storage, 0);

1804 1805 1806
    return hr;
}

1807 1808 1809 1810 1811 1812 1813 1814
/************************************************************************
 * DefaultHandler_IPersistStorage_InitNew
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
           IPersistStorage*     iface,
           IStorage*            pStg)
{
1815 1816 1817 1818
    DefaultHandler *This = impl_from_IPersistStorage(iface);
    HRESULT hr;

    TRACE("(%p)->(%p)\n", iface, pStg);
1819 1820
    hr = STORAGE_CreateOleStream(pStg, 0);
    if (hr != S_OK) return hr;
1821

1822 1823 1824
    hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);

    if(SUCCEEDED(hr) && object_is_running(This))
1825 1826
    {
        start_object_call( This );
1827
        hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
1828 1829
        end_object_call( This );
    }
1830

1831 1832 1833 1834 1835 1836 1837
    if(SUCCEEDED(hr))
    {
        IStorage_AddRef(pStg);
        This->storage = pStg;
        This->storage_state = storage_state_initialised;
    }

1838
    return hr;
1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849
}


/************************************************************************
 * DefaultHandler_IPersistStorage_Load
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
           IPersistStorage*     iface,
           IStorage*            pStg)
{
1850 1851 1852 1853 1854
    DefaultHandler *This = impl_from_IPersistStorage(iface);
    HRESULT hr;

    TRACE("(%p)->(%p)\n", iface, pStg);

1855 1856 1857 1858
    hr = load_ole_stream(This, pStg);

    if(SUCCEEDED(hr))
        hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
1859

1860
    if(SUCCEEDED(hr) && object_is_running(This))
1861 1862
    {
        start_object_call( This );
1863
        hr = IPersistStorage_Load(This->pPSDelegate, pStg);
1864 1865
        end_object_call( This );
    }
1866

1867 1868 1869 1870 1871 1872
    if(SUCCEEDED(hr))
    {
        IStorage_AddRef(pStg);
        This->storage = pStg;
        This->storage_state = storage_state_loaded;
    }
1873
    return hr;
1874 1875 1876 1877 1878 1879 1880 1881 1882 1883
}


/************************************************************************
 * DefaultHandler_IPersistStorage_Save
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
           IPersistStorage*     iface,
           IStorage*            pStgSave,
1884
           BOOL                 fSameAsLoad)
1885
{
1886 1887 1888 1889
    DefaultHandler *This = impl_from_IPersistStorage(iface);
    HRESULT hr;

    TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad);
1890

1891 1892
    hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
    if(SUCCEEDED(hr) && object_is_running(This))
1893 1894
    {
        start_object_call( This );
1895
        hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
1896 1897
        end_object_call( This );
    }
1898 1899

    return hr;
1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910
}


/************************************************************************
 * DefaultHandler_IPersistStorage_SaveCompleted
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
           IPersistStorage*     iface,
           IStorage*            pStgNew)
{
1911 1912 1913 1914
    DefaultHandler *This = impl_from_IPersistStorage(iface);
    HRESULT hr;

    TRACE("(%p)->(%p)\n", iface, pStgNew);
1915

1916 1917 1918
    hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);

    if(SUCCEEDED(hr) && object_is_running(This))
1919 1920
    {
        start_object_call( This );
1921
        hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
1922 1923
        end_object_call( This );
    }
1924

1925 1926 1927 1928 1929 1930 1931 1932
    if(pStgNew)
    {
        IStorage_AddRef(pStgNew);
        if(This->storage) IStorage_Release(This->storage);
        This->storage = pStgNew;
        This->storage_state = storage_state_loaded;
    }

1933
    return hr;
1934 1935 1936 1937 1938 1939 1940 1941 1942 1943
}


/************************************************************************
 * DefaultHandler_IPersistStorage_HandsOffStorage
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
            IPersistStorage*     iface)
{
1944 1945 1946 1947
    DefaultHandler *This = impl_from_IPersistStorage(iface);
    HRESULT hr;

    TRACE("(%p)\n", iface);
1948

1949 1950 1951
    hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);

    if(SUCCEEDED(hr) && object_is_running(This))
1952 1953
    {
        start_object_call( This );
1954
        hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
1955 1956
        end_object_call( This );
    }
1957

1958 1959 1960 1961
    if(This->storage) IStorage_Release(This->storage);
    This->storage = NULL;
    This->storage_state = storage_state_uninitialised;

1962
    return hr;
1963 1964 1965
}


1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
/*
 * Virtual function tables for the DefaultHandler class.
 */
static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
{
  DefaultHandler_QueryInterface,
  DefaultHandler_AddRef,
  DefaultHandler_Release,
  DefaultHandler_SetClientSite,
  DefaultHandler_GetClientSite,
  DefaultHandler_SetHostNames,
  DefaultHandler_Close,
  DefaultHandler_SetMoniker,
  DefaultHandler_GetMoniker,
  DefaultHandler_InitFromData,
  DefaultHandler_GetClipboardData,
  DefaultHandler_DoVerb,
  DefaultHandler_EnumVerbs,
  DefaultHandler_Update,
  DefaultHandler_IsUpToDate,
  DefaultHandler_GetUserClassID,
  DefaultHandler_GetUserType,
  DefaultHandler_SetExtent,
  DefaultHandler_GetExtent,
  DefaultHandler_Advise,
  DefaultHandler_Unadvise,
  DefaultHandler_EnumAdvise,
  DefaultHandler_GetMiscStatus,
  DefaultHandler_SetColorScheme
};

static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
{
  DefaultHandler_NDIUnknown_QueryInterface,
  DefaultHandler_NDIUnknown_AddRef,
  DefaultHandler_NDIUnknown_Release,
};

static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
{
  DefaultHandler_IDataObject_QueryInterface,
  DefaultHandler_IDataObject_AddRef,
  DefaultHandler_IDataObject_Release,
  DefaultHandler_GetData,
  DefaultHandler_GetDataHere,
  DefaultHandler_QueryGetData,
  DefaultHandler_GetCanonicalFormatEtc,
  DefaultHandler_SetData,
  DefaultHandler_EnumFormatEtc,
  DefaultHandler_DAdvise,
  DefaultHandler_DUnadvise,
  DefaultHandler_EnumDAdvise
};

static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
{
  DefaultHandler_IRunnableObject_QueryInterface,
  DefaultHandler_IRunnableObject_AddRef,
  DefaultHandler_IRunnableObject_Release,
  DefaultHandler_GetRunningClass,
  DefaultHandler_Run,
  DefaultHandler_IsRunning,
  DefaultHandler_LockRunning,
  DefaultHandler_SetContainedObject
};

2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043
static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
{
  DefaultHandler_IAdviseSink_QueryInterface,
  DefaultHandler_IAdviseSink_AddRef,
  DefaultHandler_IAdviseSink_Release,
  DefaultHandler_IAdviseSink_OnDataChange,
  DefaultHandler_IAdviseSink_OnViewChange,
  DefaultHandler_IAdviseSink_OnRename,
  DefaultHandler_IAdviseSink_OnSave,
  DefaultHandler_IAdviseSink_OnClose
};

2044
static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057
{
  DefaultHandler_IPersistStorage_QueryInterface,
  DefaultHandler_IPersistStorage_AddRef,
  DefaultHandler_IPersistStorage_Release,
  DefaultHandler_IPersistStorage_GetClassID,
  DefaultHandler_IPersistStorage_IsDirty,
  DefaultHandler_IPersistStorage_InitNew,
  DefaultHandler_IPersistStorage_Load,
  DefaultHandler_IPersistStorage_Save,
  DefaultHandler_IPersistStorage_SaveCompleted,
  DefaultHandler_IPersistStorage_HandsOffStorage
};

2058 2059 2060 2061 2062
/*********************************************************
 * Methods implementation for the DefaultHandler class.
 */
static DefaultHandler* DefaultHandler_Construct(
  REFCLSID  clsid,
2063 2064 2065
  LPUNKNOWN pUnkOuter,
  DWORD flags,
  IClassFactory *pCF)
2066
{
2067
  DefaultHandler* This = NULL;
2068
  HRESULT hr;
2069

2070
  This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
2071

2072 2073
  if (!This)
    return This;
2074

2075 2076 2077 2078 2079 2080
  This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable;
  This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable;
  This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable;
  This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable;
  This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable;
  This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable;
2081

2082
  This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) != 0;
2083

2084 2085 2086 2087
  /*
   * Start with one reference count. The caller of this function
   * must release the interface pointer when it is done.
   */
2088
  This->ref = 1;
2089 2090 2091 2092

  /*
   * Initialize the outer unknown
   * We don't keep a reference on the outer unknown since, the way
Huw Davies's avatar
Huw Davies committed
2093
   * aggregation works, our lifetime is at least as large as its
2094 2095
   * lifetime.
   */
2096
  if (!pUnkOuter)
2097
    pUnkOuter = &This->IUnknown_iface;
2098

2099
  This->outerUnknown = pUnkOuter;
2100 2101 2102 2103 2104 2105

  /*
   * Create a datacache object.
   * We aggregate with the datacache. Make sure we pass our outer
   * unknown as the datacache's outer unknown.
   */
2106 2107 2108 2109 2110
  hr = CreateDataCache(This->outerUnknown,
                       clsid,
                       &IID_IUnknown,
                       (void**)&This->dataCache);
  if(SUCCEEDED(hr))
2111
  {
2112
    hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
2113 2114 2115 2116 2117 2118 2119
    /* keeping a reference to This->dataCache_PersistStg causes us to keep a
     * reference on the outer object */
    if (SUCCEEDED(hr))
        IUnknown_Release(This->outerUnknown);
    else
        IUnknown_Release(This->dataCache);
  }
2120
  if(FAILED(hr))
2121
  {
2122
    ERR("Unexpected error creating data cache\n");
2123 2124 2125
    HeapFree(GetProcessHeap(), 0, This);
    return NULL;
  }
2126

2127
  This->clsid = *clsid;
2128 2129 2130 2131 2132
  This->clientSite = NULL;
  This->oleAdviseHolder = NULL;
  This->dataAdviseHolder = NULL;
  This->containerApp = NULL;
  This->containerObj = NULL;
2133 2134
  This->pOleDelegate = NULL;
  This->pPSDelegate = NULL;
2135
  This->pDataDelegate = NULL;
2136
  This->object_state = object_state_not_running;
2137
  This->in_call = 0;
2138

2139
  This->dwAdvConn = 0;
2140 2141
  This->storage = NULL;
  This->storage_state = storage_state_uninitialised;
2142

2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166
  if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE))
  {
    HRESULT hr;
    This->pCFObject = NULL;
    if (pCF)
      hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate);
    else
      hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
                            &IID_IOleObject, (void **)&This->pOleDelegate);
    if (SUCCEEDED(hr))
      hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
    if (SUCCEEDED(hr))
      hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate);
    if (SUCCEEDED(hr))
      This->object_state = object_state_running;
    if (FAILED(hr))
      WARN("object creation failed with error %08x\n", hr);
  }
  else
  {
    This->pCFObject = pCF;
    if (pCF) IClassFactory_AddRef(pCF);
  }

2167
  return This;
2168 2169 2170
}

static void DefaultHandler_Destroy(
2171
  DefaultHandler* This)
2172
{
2173 2174 2175 2176 2177 2178 2179
  TRACE("(%p)\n", This);

  /* AddRef/Release may be called on this object during destruction.
   * Prevent the object being destroyed recursively by artificially raising
   * the reference count. */
  This->ref = 10000;

2180 2181
  /* release delegates */
  DefaultHandler_Stop(This);
2182

2183 2184 2185 2186 2187 2188
  HeapFree( GetProcessHeap(), 0, This->containerApp );
  This->containerApp = NULL;
  HeapFree( GetProcessHeap(), 0, This->containerObj );
  This->containerObj = NULL;

  if (This->dataCache)
2189
  {
2190 2191 2192
    /* to balance out the release of dataCache_PersistStg which will result
     * in a reference being released from the outer unknown */
    IUnknown_AddRef(This->outerUnknown);
2193
    IPersistStorage_Release(This->dataCache_PersistStg);
2194
    IUnknown_Release(This->dataCache);
2195
    This->dataCache_PersistStg = NULL;
2196
    This->dataCache = NULL;
2197 2198
  }

2199
  if (This->clientSite)
2200
  {
2201 2202
    IOleClientSite_Release(This->clientSite);
    This->clientSite = NULL;
2203 2204
  }

2205
  if (This->oleAdviseHolder)
2206
  {
2207 2208
    IOleAdviseHolder_Release(This->oleAdviseHolder);
    This->oleAdviseHolder = NULL;
2209 2210
  }

2211
  if (This->dataAdviseHolder)
2212
  {
2213 2214
    IDataAdviseHolder_Release(This->dataAdviseHolder);
    This->dataAdviseHolder = NULL;
2215 2216
  }

2217 2218 2219 2220 2221 2222
  if (This->storage)
  {
    IStorage_Release(This->storage);
    This->storage = NULL;
  }

2223 2224 2225 2226 2227 2228
  if (This->pCFObject)
  {
    IClassFactory_Release(This->pCFObject);
    This->pCFObject = NULL;
  }

2229
  HeapFree(GetProcessHeap(), 0, This);
2230 2231 2232
}

/******************************************************************************
2233
 * OleCreateEmbeddingHelper [OLE32.@]
2234
 */
2235
HRESULT WINAPI OleCreateEmbeddingHelper(
2236 2237
  REFCLSID  clsid,
  LPUNKNOWN pUnkOuter,
2238 2239
  DWORD     flags,
  IClassFactory *pCF,
2240 2241 2242 2243 2244 2245
  REFIID    riid,
  LPVOID*   ppvObj)
{
  DefaultHandler* newHandler = NULL;
  HRESULT         hr         = S_OK;

2246
  TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
2247 2248 2249 2250 2251 2252 2253

  if (!ppvObj)
    return E_POINTER;

  *ppvObj = NULL;

  /*
2254
   * If This handler is constructed for aggregation, make sure
2255 2256 2257 2258
   * the caller is requesting the IUnknown interface.
   * This is necessary because it's the only time the non-delegating
   * IUnknown pointer can be returned to the outside.
   */
2259
  if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
2260 2261 2262 2263 2264
    return CLASS_E_NOAGGREGATION;

  /*
   * Try to construct a new instance of the class.
   */
2265
  newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
2266 2267 2268 2269 2270 2271 2272

  if (!newHandler)
    return E_OUTOFMEMORY;

  /*
   * Make sure it supports the interface required by the caller.
   */
2273
  hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj);
2274 2275 2276 2277 2278

  /*
   * Release the reference obtained in the constructor. If
   * the QueryInterface was unsuccessful, it will free the class.
   */
2279
  IUnknown_Release(&newHandler->IUnknown_iface);
2280 2281 2282

  return hr;
}
2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294


/******************************************************************************
 * OleCreateDefaultHandler [OLE32.@]
 */
HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
                                       REFIID riid, LPVOID* ppvObj)
{
    TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj);
    return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
                                    NULL, riid, ppvObj);
}
2295 2296 2297

typedef struct HandlerCF
{
2298
    IClassFactory IClassFactory_iface;
2299 2300 2301 2302
    LONG refs;
    CLSID clsid;
} HandlerCF;

2303 2304 2305 2306 2307
static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
{
    return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
}

2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323
static HRESULT WINAPI
HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
{
    *ppv = NULL;
    if (IsEqualIID(riid,&IID_IUnknown) ||
        IsEqualIID(riid,&IID_IClassFactory))
    {
        *ppv = iface;
        IClassFactory_AddRef(iface);
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
{
2324
    HandlerCF *This = impl_from_IClassFactory(iface);
2325 2326 2327 2328 2329
    return InterlockedIncrement(&This->refs);
}

static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
{
2330
    HandlerCF *This = impl_from_IClassFactory(iface);
2331 2332 2333 2334 2335 2336 2337 2338 2339 2340
    ULONG refs = InterlockedDecrement(&This->refs);
    if (!refs)
        HeapFree(GetProcessHeap(), 0, This);
    return refs;
}

static HRESULT WINAPI
HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
                         REFIID riid, LPVOID *ppv)
{
2341
    HandlerCF *This = impl_from_IClassFactory(iface);
2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363
    return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
}

static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
    FIXME("(%d), stub!\n",fLock);
    return S_OK;
}

static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
    HandlerCF_QueryInterface,
    HandlerCF_AddRef,
    HandlerCF_Release,
    HandlerCF_CreateInstance,
    HandlerCF_LockServer
};

HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
    HRESULT hr;
    HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This) return E_OUTOFMEMORY;
2364
    This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
2365 2366 2367
    This->refs = 0;
    This->clsid = *rclsid;

2368
    hr = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv);
2369 2370 2371 2372 2373
    if (FAILED(hr))
        HeapFree(GetProcessHeap(), 0, This);

    return hr;
}