defaulthandler.c 52 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 61 62

#include "compobj_private.h"

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

65
WINE_DEFAULT_DEBUG_CHANNEL(ole);
66 67 68 69 70 71 72

/****************************************************************************
 * DefaultHandler
 *
 */
struct DefaultHandler
{
73 74 75 76
  const IOleObjectVtbl*      lpVtbl;
  const IUnknownVtbl*        lpvtblIUnknown;
  const IDataObjectVtbl*     lpvtblIDataObject;
  const IRunnableObjectVtbl* lpvtblIRunnableObject;
77
  const IAdviseSinkVtbl     *lpvtblIAdviseSink;
78
  const IPersistStorageVtbl *lpvtblIPersistStorage;
79

80
  /* Reference count of this object */
81
  LONG ref;
82

83
  /* IUnknown implementation of the outer object. */
84 85
  IUnknown* outerUnknown;

86
  /* Class Id that this handler object represents. */
87 88
  CLSID clsid;

89
  /* IUnknown implementation of the datacache. */
90
  IUnknown* dataCache;
91 92
  /* IPersistStorage implementation of the datacache. */
  IPersistStorage* dataCache_PersistStg;
93

94
  /* Client site for the embedded object. */
95 96 97 98 99 100 101 102 103
  IOleClientSite* clientSite;

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

  /*
104
   * The IDataAdviseHolder maintains the data
105 106 107 108
   * connections on behalf of the default handler.
   */
  IDataAdviseHolder* dataAdviseHolder;

109
  /* Name of the container and object contained */
110
  LPWSTR containerApp;
111
  LPWSTR containerObj;
112

113 114 115 116
  /* IOleObject delegate */
  IOleObject *pOleDelegate;
  /* IPersistStorage delegate */
  IPersistStorage *pPSDelegate;
117 118
  /* IDataObject delegate */
  IDataObject *pDataDelegate;
119 120 121

  /* connection cookie for the advise on the delegate OLE object */
  DWORD dwAdvConn;
122 123 124 125 126
};

typedef struct DefaultHandler DefaultHandler;

/*
127
 * Here, I define utility functions to help with the casting of the
128
 * "This" parameter.
129
 * There is a version to accommodate all of the VTables implemented
130 131
 * by this object.
 */
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
{
    return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpVtbl));
}

static inline DefaultHandler *impl_from_NDIUnknown( IUnknown *iface )
{
    return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIUnknown));
}

static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
{
    return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIDataObject));
}

static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
{
    return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
}

152 153 154 155 156
static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
{
    return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink));
}

157 158 159 160 161
static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
{
    return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIPersistStorage));
}

162
static void DefaultHandler_Destroy(DefaultHandler* This);
163

164 165 166 167
static inline BOOL object_is_running(DefaultHandler *This)
{
    return IRunnableObject_IsRunning((IRunnableObject*)&This->lpvtblIRunnableObject);
}
168 169 170 171 172 173 174 175 176 177 178

/*********************************************************
 * 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
179
 * This version of QueryInterface will not delegate its implementation
180 181 182 183 184 185 186
 * to the outer unknown.
 */
static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
            IUnknown*      iface,
            REFIID         riid,
            void**         ppvObject)
{
187
  DefaultHandler *This = impl_from_NDIUnknown(iface);
188

189 190
  /* Perform a sanity check on the parameters. */
  if (!ppvObject)
191
    return E_INVALIDARG;
192

193
  *ppvObject = NULL;
194

195
  if (IsEqualIID(&IID_IUnknown, riid))
196
    *ppvObject = iface;
197 198 199 200 201 202
  else if (IsEqualIID(&IID_IOleObject, riid))
    *ppvObject = (IOleObject*)&This->lpVtbl;
  else if (IsEqualIID(&IID_IDataObject, riid))
    *ppvObject = (IDataObject*)&This->lpvtblIDataObject;
  else if (IsEqualIID(&IID_IRunnableObject, riid))
    *ppvObject = (IRunnableObject*)&This->lpvtblIRunnableObject;
203
  else if (IsEqualIID(&IID_IPersist, riid) ||
204 205 206
           IsEqualIID(&IID_IPersistStorage, riid))
    *ppvObject = &This->lpvtblIPersistStorage;
  else if (IsEqualIID(&IID_IViewObject, riid) ||
207 208 209
           IsEqualIID(&IID_IViewObject2, riid) ||
           IsEqualIID(&IID_IOleCache, riid) ||
           IsEqualIID(&IID_IOleCache2, riid))
210
  {
211 212 213
    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;
214
  }
215

216 217
  /* Check that we obtained an interface. */
  if (*ppvObject == NULL)
218
  {
219
    WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
220 221
    return E_NOINTERFACE;
  }
222

223 224
  /*
   * Query Interface always increases the reference count by one when it is
225
   * successful.
226 227 228
   */
  IUnknown_AddRef((IUnknown*)*ppvObject);

229
  return S_OK;
230 231 232 233 234 235 236
}

/************************************************************************
 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 *
Huw Davies's avatar
Huw Davies committed
237
 * This version of QueryInterface will not delegate its implementation
238 239
 * to the outer unknown.
 */
240
static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
241 242
            IUnknown*      iface)
{
243 244
  DefaultHandler *This = impl_from_NDIUnknown(iface);
  return InterlockedIncrement(&This->ref);
245 246 247 248 249 250 251
}

/************************************************************************
 * DefaultHandler_NDIUnknown_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 *
Huw Davies's avatar
Huw Davies committed
252
 * This version of QueryInterface will not delegate its implementation
253 254
 * to the outer unknown.
 */
255
static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
256 257
            IUnknown*      iface)
{
258
  DefaultHandler *This = impl_from_NDIUnknown(iface);
259
  ULONG ref;
260

261 262
  /* Decrease the reference count on this object. */
  ref = InterlockedDecrement(&This->ref);
263

264
  if (!ref) DefaultHandler_Destroy(This);
265

266
  return ref;
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
}

/*********************************************************
 * 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)
{
284
  DefaultHandler *This = impl_from_IOleObject(iface);
285

286
  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
287 288 289 290 291 292 293
}

/************************************************************************
 * DefaultHandler_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
294
static ULONG WINAPI DefaultHandler_AddRef(
295 296
            IOleObject*        iface)
{
297
  DefaultHandler *This = impl_from_IOleObject(iface);
298

299
  return IUnknown_AddRef(This->outerUnknown);
300 301 302 303 304 305 306
}

/************************************************************************
 * DefaultHandler_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
307
static ULONG WINAPI DefaultHandler_Release(
308 309
            IOleObject*        iface)
{
310
  DefaultHandler *This = impl_from_IOleObject(iface);
311

312
  return IUnknown_Release(This->outerUnknown);
313 314 315 316 317 318 319 320 321 322 323 324 325 326
}

/************************************************************************
 * 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)
{
327
  DefaultHandler *This = impl_from_IOleObject(iface);
328
  HRESULT hr = S_OK;
329

330
  TRACE("(%p, %p)\n", iface, pClientSite);
331

332
  if (object_is_running(This))
333 334
    hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);

335 336 337 338
  /*
   * Make sure we release the previous client site if there
   * was one.
   */
339 340
  if (This->clientSite)
    IOleClientSite_Release(This->clientSite);
341

342
  This->clientSite = pClientSite;
343

344 345
  if (This->clientSite)
    IOleClientSite_AddRef(This->clientSite);
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361

  return S_OK;
}

/************************************************************************
 * 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)
{
362
  DefaultHandler *This = impl_from_IOleObject(iface);
363

364 365
  /* Sanity check. */
  if (!ppClientSite)
366 367
    return E_POINTER;

368
  *ppClientSite = This->clientSite;
369

370 371
  if (This->clientSite)
    IOleClientSite_AddRef(This->clientSite);
372 373 374 375 376 377 378 379 380 381 382 383 384 385

  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,
386
	    LPCOLESTR          szContainerApp,
387 388
	    LPCOLESTR          szContainerObj)
{
389
  DefaultHandler *This = impl_from_IOleObject(iface);
390

391
  TRACE("(%p, %s, %s)\n",
392
	iface,
393
	debugstr_w(szContainerApp),
394 395
	debugstr_w(szContainerObj));

396
  if (object_is_running(This))
397 398
    IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);

399 400 401 402 403
  /* Be sure to cleanup before re-assinging the strings. */
  HeapFree( GetProcessHeap(), 0, This->containerApp );
  This->containerApp = NULL;
  HeapFree( GetProcessHeap(), 0, This->containerObj );
  This->containerObj = NULL;
404

405 406
  /* Copy the string supplied. */
  if (szContainerApp)
407
  {
408
      if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
409
                                           (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
410
          strcpyW( This->containerApp, szContainerApp );
411
  }
412

413
  if (szContainerObj)
414
  {
415
      if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
416
                                           (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
417
          strcpyW( This->containerObj, szContainerObj );
418
  }
419 420 421
  return S_OK;
}

422 423 424
/* undos the work done by DefaultHandler_Run */
static void WINAPI DefaultHandler_Stop(DefaultHandler *This)
{
425
  if (!object_is_running(This))
426 427 428 429 430 431
    return;

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

  /* FIXME: call IOleCache_OnStop */

432 433
  if (This->dataAdviseHolder)
    DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
434 435 436 437 438
  if (This->pDataDelegate)
  {
     IDataObject_Release(This->pDataDelegate);
     This->pDataDelegate = NULL;
  }
439 440 441 442 443 444 445 446 447
  if (This->pPSDelegate)
  {
     IPersistStorage_Release(This->pPSDelegate);
     This->pPSDelegate = NULL;
  }
  IOleObject_Release(This->pOleDelegate);
  This->pOleDelegate = NULL;
}

448 449 450 451 452 453 454 455 456
/************************************************************************
 * 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(
457
	    IOleObject*        iface,
458 459
	    DWORD              dwSaveOption)
{
460 461 462
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr;

463
  TRACE("(%d)\n", dwSaveOption);
464

465
  if (!object_is_running(This))
466 467 468 469 470 471 472
    return S_OK;

  hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);

  DefaultHandler_Stop(This);

  return hr;
473 474 475 476 477 478 479 480 481 482
}

/************************************************************************
 * 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(
483
	    IOleObject*        iface,
484 485 486
	    DWORD              dwWhichMoniker,
	    IMoniker*          pmk)
{
487 488
  DefaultHandler *This = impl_from_IOleObject(iface);

489
  TRACE("(%p, %d, %p)\n",
490 491
	iface,
	dwWhichMoniker,
492 493
	pmk);

494
  if (object_is_running(This))
495 496
    return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);

497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
  return S_OK;
}

/************************************************************************
 * 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)
{
513
  DefaultHandler *This = impl_from_IOleObject(iface);
514

515
  TRACE("(%p, %d, %d, %p)\n",
516 517
	iface, dwAssign, dwWhichMoniker, ppmk);

518
  if (object_is_running(This))
519 520 521 522
    return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
                                 ppmk);

  /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
523
  if (This->clientSite)
524
  {
525
    return IOleClientSite_GetMoniker(This->clientSite,
526 527 528
				     dwAssign,
				     dwWhichMoniker,
				     ppmk);
529

530 531
  }

532
  return E_FAIL;
533 534 535 536 537 538
}

/************************************************************************
 * DefaultHandler_InitFromData (IOleObject)
 *
 * This method is meaningless if the server is not running
539
 *
540 541 542
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_InitFromData(
543 544
	    IOleObject*        iface,
	    IDataObject*       pDataObject,
545 546 547
	    BOOL               fCreation,
	    DWORD              dwReserved)
{
548 549
  DefaultHandler *This = impl_from_IOleObject(iface);

550
  TRACE("(%p, %p, %d, %d)\n",
551 552
	iface, pDataObject, fCreation, dwReserved);

553
  if (object_is_running(This))
554 555
    return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
		                   dwReserved);
556 557 558 559 560 561 562
  return OLE_E_NOTRUNNING;
}

/************************************************************************
 * DefaultHandler_GetClipboardData (IOleObject)
 *
 * This method is meaningless if the server is not running
563
 *
564 565 566
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetClipboardData(
567 568
	    IOleObject*        iface,
	    DWORD              dwReserved,
569 570
	    IDataObject**      ppDataObject)
{
571 572
  DefaultHandler *This = impl_from_IOleObject(iface);

573
  TRACE("(%p, %d, %p)\n",
574 575
	iface, dwReserved, ppDataObject);

576
  if (object_is_running(This))
577 578 579
    return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
                                       ppDataObject);

580 581 582 583
  return OLE_E_NOTRUNNING;
}

static HRESULT WINAPI DefaultHandler_DoVerb(
584 585 586 587 588 589
	    IOleObject*        iface,
	    LONG               iVerb,
	    struct tagMSG*     lpmsg,
	    IOleClientSite*    pActiveSite,
	    LONG               lindex,
	    HWND               hwndParent,
590 591
	    LPCRECT            lprcPosRect)
{
592 593 594 595
  DefaultHandler *This = impl_from_IOleObject(iface);
  IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
  HRESULT hr;

596
  TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
597 598 599 600 601 602

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

  return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
                           lindex, hwndParent, lprcPosRect);
603 604 605 606 607 608 609
}

/************************************************************************
 * DefaultHandler_EnumVerbs (IOleObject)
 *
 * The default handler implementation of this method simply delegates
 * to OleRegEnumVerbs
610
 *
611 612 613
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_EnumVerbs(
614
	    IOleObject*        iface,
615 616
	    IEnumOLEVERB**     ppEnumOleVerb)
{
617
  DefaultHandler *This = impl_from_IOleObject(iface);
618
  HRESULT hr = OLE_S_USEREG;
619

620
  TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
621

622
  if (object_is_running(This))
623 624 625 626 627 628
    hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);

  if (hr == OLE_S_USEREG)
    return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
  else
    return hr;
629 630 631 632 633
}

static HRESULT WINAPI DefaultHandler_Update(
	    IOleObject*        iface)
{
634
  FIXME(": Stub\n");
635 636 637 638 639 640 641
  return E_NOTIMPL;
}

/************************************************************************
 * DefaultHandler_IsUpToDate (IOleObject)
 *
 * This method is meaningless if the server is not running
642
 *
643 644 645 646 647
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_IsUpToDate(
	    IOleObject*        iface)
{
648
  TRACE("(%p)\n", iface);
649 650 651 652 653 654 655 656

  return OLE_E_NOTRUNNING;
}

/************************************************************************
 * DefaultHandler_GetUserClassID (IOleObject)
 *
 * TODO: Map to a new class ID if emulation is active.
657
 *
658 659 660
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetUserClassID(
661
	    IOleObject*        iface,
662 663
	    CLSID*             pClsid)
{
664
  DefaultHandler *This = impl_from_IOleObject(iface);
665

666
  TRACE("(%p, %p)\n", iface, pClsid);
667

668
  if (object_is_running(This))
669 670
    return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);

671 672
  /* Sanity check. */
  if (!pClsid)
673 674
    return E_POINTER;

675
  memcpy(pClsid, &This->clsid, sizeof(CLSID));
676 677 678 679 680 681 682 683 684

  return S_OK;
}

/************************************************************************
 * DefaultHandler_GetUserType (IOleObject)
 *
 * The default handler implementation of this method simply delegates
 * to OleRegGetUserType
685
 *
686 687 688
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetUserType(
689 690
	    IOleObject*        iface,
	    DWORD              dwFormOfType,
691 692
	    LPOLESTR*          pszUserType)
{
693
  DefaultHandler *This = impl_from_IOleObject(iface);
694

695
  TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
696

697
  return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
698 699 700 701 702 703 704 705 706 707
}

/************************************************************************
 * 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(
708 709
	    IOleObject*        iface,
	    DWORD              dwDrawAspect,
710 711
	    SIZEL*             psizel)
{
712 713
  DefaultHandler *This = impl_from_IOleObject(iface);

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

717
  if (object_is_running(This))
718 719
    IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);

720 721 722 723 724 725 726 727 728 729 730 731
  return OLE_E_NOTRUNNING;
}

/************************************************************************
 * 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(
732 733
	    IOleObject*        iface,
	    DWORD              dwDrawAspect,
734 735 736 737 738 739
	    SIZEL*             psizel)
{
  DVTARGETDEVICE* targetDevice;
  IViewObject2*   cacheView = NULL;
  HRESULT         hres;

740
  DefaultHandler *This = impl_from_IOleObject(iface);
741

742
  TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
743

744
  if (object_is_running(This))
745
    return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
746

747
  hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
748 749 750 751 752 753 754
  if (FAILED(hres))
    return E_UNEXPECTED;

  /*
   * Prepare the call to the cache's GetExtent method.
   *
   * Here we would build a valid DVTARGETDEVICE structure
755
   * but, since we are calling into the data cache, we
Huw Davies's avatar
Huw Davies committed
756
   * know its implementation and we'll skip this
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
   * extra work until later.
   */
  targetDevice = NULL;

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

  /*
   * Cleanup
   */
  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(
784 785
	    IOleObject*        iface,
	    IAdviseSink*       pAdvSink,
786 787 788
	    DWORD*             pdwConnection)
{
  HRESULT hres = S_OK;
789
  DefaultHandler *This = impl_from_IOleObject(iface);
790

791
  TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
792

793 794 795
  /* Make sure we have an advise holder before we start. */
  if (!This->oleAdviseHolder)
    hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
796 797

  if (SUCCEEDED(hres))
798
    hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
799
				   pAdvSink,
800 801 802 803 804 805 806 807 808 809 810 811 812 813
				   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(
814
	    IOleObject*        iface,
815 816
	    DWORD              dwConnection)
{
817
  DefaultHandler *This = impl_from_IOleObject(iface);
818

819
  TRACE("(%p, %d)\n", iface, dwConnection);
820 821 822 823 824

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

828
  return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
829 830 831 832 833 834 835 836 837 838 839 840
				   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(
841
	    IOleObject*        iface,
842 843
	    IEnumSTATDATA**    ppenumAdvise)
{
844
  DefaultHandler *This = impl_from_IOleObject(iface);
845

846
  TRACE("(%p, %p)\n", iface, ppenumAdvise);
847

848 849
  /* Sanity check */
  if (!ppenumAdvise)
850 851 852 853
    return E_POINTER;

  *ppenumAdvise = NULL;

854
  if (!This->oleAdviseHolder)
855
      return S_OK;
856

857
  return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
858 859 860 861 862 863 864 865 866 867 868
}

/************************************************************************
 * 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(
869 870
	    IOleObject*        iface,
	    DWORD              dwAspect,
871 872 873
	    DWORD*             pdwStatus)
{
  HRESULT hres;
874
  DefaultHandler *This = impl_from_IOleObject(iface);
875

876
  TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
877

878
  if (object_is_running(This))
879 880
    return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);

881
  hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
882 883 884 885 886 887 888 889

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

  return S_OK;
}

/************************************************************************
890
 * DefaultHandler_SetColorScheme (IOleObject)
891 892 893 894 895 896
 *
 * This method is meaningless if the server is not running
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetColorScheme(
897 898
	    IOleObject*           iface,
	    struct tagLOGPALETTE* pLogpal)
899
{
900 901
  DefaultHandler *This = impl_from_IOleObject(iface);

902
  TRACE("(%p, %p))\n", iface, pLogpal);
903

904
  if (object_is_running(This))
905 906
    return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);

907 908 909 910 911 912 913 914 915 916 917 918 919 920
  return OLE_E_NOTRUNNING;
}

/*********************************************************
 * 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(
921
            IDataObject*     iface,
922 923 924
           REFIID           riid,
            void**           ppvObject)
{
925
  DefaultHandler *This = impl_from_IDataObject(iface);
926

927
  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
928 929 930 931 932 933 934
}

/************************************************************************
 * DefaultHandler_IDataObject_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
935
static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
936 937
            IDataObject*     iface)
{
938
  DefaultHandler *This = impl_from_IDataObject(iface);
939

940
  return IUnknown_AddRef(This->outerUnknown);
941 942 943 944 945 946 947
}

/************************************************************************
 * DefaultHandler_IDataObject_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
948
static ULONG WINAPI DefaultHandler_IDataObject_Release(
949 950
            IDataObject*     iface)
{
951
  DefaultHandler *This = impl_from_IDataObject(iface);
952

953
  return IUnknown_Release(This->outerUnknown);
954 955
}

956 957 958 959 960 961 962
/************************************************************************
 * 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.
 */
963 964
static HRESULT WINAPI DefaultHandler_GetData(
	    IDataObject*     iface,
965
	    LPFORMATETC      pformatetcIn,
966 967
	    STGMEDIUM*       pmedium)
{
968 969 970
  IDataObject* cacheDataObject = NULL;
  HRESULT      hres;

971
  DefaultHandler *This = impl_from_IDataObject(iface);
972 973 974

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

975
  hres = IUnknown_QueryInterface(This->dataCache,
976
				 &IID_IDataObject,
977
				 (void**)&cacheDataObject);
978 979 980 981 982 983 984

  if (FAILED(hres))
    return E_UNEXPECTED;

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

986
  IDataObject_Release(cacheDataObject);
987

988 989 990
  if (FAILED(hres) && This->pDataDelegate)
    hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);

991
  return hres;
992 993 994
}

static HRESULT WINAPI DefaultHandler_GetDataHere(
995
	    IDataObject*     iface,
996 997 998
	    LPFORMATETC      pformatetc,
	    STGMEDIUM*       pmedium)
{
999
  FIXME(": Stub\n");
1000 1001 1002 1003 1004 1005
  return E_NOTIMPL;
}

/************************************************************************
 * DefaultHandler_QueryGetData (IDataObject)
 *
1006
 * The default handler's implementation of this method delegates to
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
 * 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;

1018
  DefaultHandler *This = impl_from_IDataObject(iface);
1019

1020
  TRACE("(%p, %p)\n", iface, pformatetc);
1021

1022
  hres = IUnknown_QueryInterface(This->dataCache,
1023
				 &IID_IDataObject,
1024
				 (void**)&cacheDataObject);
1025 1026 1027 1028 1029 1030 1031 1032

  if (FAILED(hres))
    return E_UNEXPECTED;

  hres = IDataObject_QueryGetData(cacheDataObject,
				  pformatetc);

  IDataObject_Release(cacheDataObject);
1033

1034 1035 1036
  if (FAILED(hres) && This->pDataDelegate)
    hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);

1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
  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(
1048
	    IDataObject*     iface,
1049
	    LPFORMATETC      pformatetcIn,
1050 1051
	    LPFORMATETC      pformatetcOut)
{
1052
  DefaultHandler *This = impl_from_IDataObject(iface);
1053

1054 1055
  TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);

1056
  if (!This->pDataDelegate)
1057 1058
    return OLE_E_NOTRUNNING;

1059
  return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
1060 1061 1062 1063 1064
}

/************************************************************************
 * DefaultHandler_SetData (IDataObject)
 *
1065
 * The default handler's implementation of this method delegates to
1066 1067 1068 1069 1070 1071
 * the cache.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetData(
	    IDataObject*     iface,
1072 1073
	    LPFORMATETC      pformatetc,
	    STGMEDIUM*       pmedium,
1074 1075
	    BOOL             fRelease)
{
1076
  DefaultHandler *This = impl_from_IDataObject(iface);
1077 1078 1079
  IDataObject* cacheDataObject = NULL;
  HRESULT      hres;

1080
  TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1081

1082
  hres = IUnknown_QueryInterface(This->dataCache,
1083
				 &IID_IDataObject,
1084
				 (void**)&cacheDataObject);
1085 1086 1087 1088 1089 1090 1091 1092

  if (FAILED(hres))
    return E_UNEXPECTED;

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

1094
  IDataObject_Release(cacheDataObject);
1095

1096 1097 1098 1099 1100 1101
  return hres;
}

/************************************************************************
 * DefaultHandler_EnumFormatEtc (IDataObject)
 *
1102
 * The default handler's implementation of This method simply delegates
1103 1104 1105 1106 1107
 * to OleRegEnumFormatEtc.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
1108
	    IDataObject*     iface,
1109 1110 1111 1112
	    DWORD            dwDirection,
	    IEnumFORMATETC** ppenumFormatEtc)
{
  HRESULT hres;
1113
  DefaultHandler *This = impl_from_IDataObject(iface);
1114

1115
  TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
1116

1117
  hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130

  return hres;
}

/************************************************************************
 * 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(
1131 1132 1133 1134
	    IDataObject*     iface,
	    FORMATETC*       pformatetc,
	    DWORD            advf,
	    IAdviseSink*     pAdvSink,
1135 1136 1137
	    DWORD*           pdwConnection)
{
  HRESULT hres = S_OK;
1138
  DefaultHandler *This = impl_from_IDataObject(iface);
1139

1140
  TRACE("(%p, %p, %d, %p, %p)\n",
1141 1142
	iface, pformatetc, advf, pAdvSink, pdwConnection);

1143 1144
  /* Make sure we have a data advise holder before we start. */
  if (!This->dataAdviseHolder)
1145
  {
1146
    hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
1147 1148 1149
    if (SUCCEEDED(hres) && This->pDataDelegate)
      DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
  }
1150 1151

  if (SUCCEEDED(hres))
1152
    hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
1153
				    iface,
1154 1155 1156
				    pformatetc,
				    advf,
				    pAdvSink,
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
				    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)
{
1174
  DefaultHandler *This = impl_from_IDataObject(iface);
1175

1176
  TRACE("(%p, %d)\n", iface, dwConnection);
1177 1178 1179 1180 1181

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

1185
  return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
				    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)
{
1201
  DefaultHandler *This = impl_from_IDataObject(iface);
1202

1203
  TRACE("(%p, %p)\n", iface, ppenumAdvise);
1204

1205 1206
  /* Sanity check */
  if (!ppenumAdvise)
1207 1208 1209 1210
    return E_POINTER;

  *ppenumAdvise = NULL;

1211 1212 1213
  /* If we have a data advise holder object, delegate. */
  if (This->dataAdviseHolder)
    return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
1214 1215 1216 1217 1218 1219
					ppenumAdvise);

  return S_OK;
}

/*********************************************************
1220
 * Methods implementation for the IRunnableObject part
1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
 * 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)
{
1234
  DefaultHandler *This = impl_from_IRunnableObject(iface);
1235

1236
  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
1237 1238 1239
}

/************************************************************************
Huw Davies's avatar
Huw Davies committed
1240
 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
1241 1242 1243
 *
 * See Windows documentation for more details on IUnknown methods.
 */
1244
static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
1245 1246
            IRunnableObject*     iface)
{
1247
  DefaultHandler *This = impl_from_IRunnableObject(iface);
1248

1249
  return IUnknown_AddRef(This->outerUnknown);
1250 1251 1252
}

/************************************************************************
Huw Davies's avatar
Huw Davies committed
1253
 * DefaultHandler_IRunnableObject_Release (IUnknown)
1254 1255 1256
 *
 * See Windows documentation for more details on IUnknown methods.
 */
1257
static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
1258 1259
            IRunnableObject*     iface)
{
1260
  DefaultHandler *This = impl_from_IRunnableObject(iface);
1261

1262
  return IUnknown_Release(This->outerUnknown);
1263 1264 1265 1266 1267 1268 1269
}

/************************************************************************
 * DefaultHandler_GetRunningClass (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
1270 1271
static HRESULT WINAPI DefaultHandler_GetRunningClass(
            IRunnableObject*     iface,
1272 1273
	    LPCLSID              lpClsid)
{
1274
  FIXME("()\n");
1275 1276 1277
  return S_OK;
}

1278
static HRESULT WINAPI DefaultHandler_Run(
1279 1280 1281
            IRunnableObject*     iface,
	    IBindCtx*            pbc)
{
1282 1283 1284 1285 1286 1287
  DefaultHandler *This = impl_from_IRunnableObject(iface);
  HRESULT hr;

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

  /* already running? if so nothing to do */
1288
  if (object_is_running(This))
1289 1290
    return S_OK;

1291 1292
  hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
                        &IID_IOleObject, (void **)&This->pOleDelegate);
1293 1294 1295
  if (FAILED(hr))
    return hr;

1296 1297 1298
  hr = IOleObject_Advise(This->pOleDelegate,
                         (IAdviseSink *)&This->lpvtblIAdviseSink,
                         &This->dwAdvConn);
1299 1300

  if (SUCCEEDED(hr) && This->clientSite)
1301 1302 1303 1304
    hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);

  if (SUCCEEDED(hr))
  {
1305 1306
    IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
                              (void **)&This->pPSDelegate);
1307 1308 1309 1310 1311
    if (This->pPSDelegate)
      hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
  }

  if (SUCCEEDED(hr) && This->containerApp)
1312 1313
    hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
                                 This->containerObj);
1314 1315 1316 1317

  /* FIXME: do more stuff here:
   * - IOleObject_GetMiscStatus
   * - IOleObject_GetMoniker
1318
   * - IOleCache_OnRun
1319 1320
   */

1321 1322 1323 1324 1325 1326 1327
  if (SUCCEEDED(hr))
    hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
                                   (void **)&This->pDataDelegate);

  if (SUCCEEDED(hr) && This->dataAdviseHolder)
    hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);

1328 1329
  if (FAILED(hr))
    DefaultHandler_Stop(This);
1330 1331

  return hr;
1332 1333 1334 1335 1336 1337 1338
}

/************************************************************************
 * DefaultHandler_IsRunning (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
1339
static BOOL    WINAPI DefaultHandler_IsRunning(
1340 1341
            IRunnableObject*     iface)
{
1342 1343
  DefaultHandler *This = impl_from_IRunnableObject(iface);

1344
  TRACE("()\n");
1345 1346 1347 1348 1349

  if (This->pOleDelegate)
    return TRUE;
  else
    return FALSE;
1350 1351 1352 1353 1354 1355 1356
}

/************************************************************************
 * DefaultHandler_LockRunning (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
1357 1358 1359
static HRESULT WINAPI DefaultHandler_LockRunning(
            IRunnableObject*     iface,
	    BOOL                 fLock,
1360 1361
	    BOOL                 fLastUnlockCloses)
{
1362
  FIXME("()\n");
1363 1364 1365 1366 1367 1368 1369 1370
  return S_OK;
}

/************************************************************************
 * DefaultHandler_SetContainedObject (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
1371 1372
static HRESULT WINAPI DefaultHandler_SetContainedObject(
            IRunnableObject*     iface,
1373 1374
	    BOOL                 fContained)
{
1375
  FIXME("()\n");
1376 1377
  return S_OK;
}
1378

1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430
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);

    return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
}

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

    return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
}

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)
{
1431 1432 1433 1434 1435 1436
    DefaultHandler *This = impl_from_IAdviseSink(iface);

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

    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
1437 1438 1439 1440 1441
}

static void WINAPI DefaultHandler_IAdviseSink_OnSave(
    IAdviseSink *iface)
{
1442 1443 1444 1445 1446 1447
    DefaultHandler *This = impl_from_IAdviseSink(iface);

    TRACE("()\n");

    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
1448 1449 1450 1451 1452
}

static void WINAPI DefaultHandler_IAdviseSink_OnClose(
    IAdviseSink *iface)
{
1453 1454 1455 1456
    DefaultHandler *This = impl_from_IAdviseSink(iface);
    
    TRACE("()\n");

1457 1458
    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
1459 1460

    DefaultHandler_Stop(This);
1461 1462
}

1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596

/************************************************************************
 * 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)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
}

/************************************************************************
 * DefaultHandler_IPersistStorage_IsDirty
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
            IPersistStorage*     iface)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IPersistStorage_IsDirty(This->dataCache_PersistStg);
}

/************************************************************************
 * DefaultHandler_IPersistStorage_InitNew
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
           IPersistStorage*     iface,
           IStorage*            pStg)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
}


/************************************************************************
 * DefaultHandler_IPersistStorage_Load
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
           IPersistStorage*     iface,
           IStorage*            pStg)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IPersistStorage_Load(This->dataCache_PersistStg, pStg);
}


/************************************************************************
 * DefaultHandler_IPersistStorage_Save
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
           IPersistStorage*     iface,
           IStorage*            pStgSave,
           BOOL                 fSaveAsLoad)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSaveAsLoad);
}


/************************************************************************
 * DefaultHandler_IPersistStorage_SaveCompleted
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
           IPersistStorage*     iface,
           IStorage*            pStgNew)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
}


/************************************************************************
 * DefaultHandler_IPersistStorage_HandsOffStorage
 *
 */
static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
            IPersistStorage*     iface)
{
  DefaultHandler *This = impl_from_IPersistStorage(iface);

  return IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
}


1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662
/*
 * 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
};

1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674
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
};

1675
static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688
{
  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
};

1689 1690 1691 1692 1693 1694 1695
/*********************************************************
 * Methods implementation for the DefaultHandler class.
 */
static DefaultHandler* DefaultHandler_Construct(
  REFCLSID  clsid,
  LPUNKNOWN pUnkOuter)
{
1696
  DefaultHandler* This = NULL;
1697
  HRESULT hr;
1698 1699 1700 1701

  /*
   * Allocate space for the object.
   */
1702
  This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
1703

1704 1705
  if (!This)
    return This;
1706

1707 1708 1709 1710
  This->lpVtbl = &DefaultHandler_IOleObject_VTable;
  This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
  This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
  This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
1711
  This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
1712
  This->lpvtblIPersistStorage = &DefaultHandler_IPersistStorage_VTable;
1713 1714 1715 1716 1717

  /*
   * Start with one reference count. The caller of this function
   * must release the interface pointer when it is done.
   */
1718
  This->ref = 1;
1719 1720 1721 1722

  /*
   * Initialize the outer unknown
   * We don't keep a reference on the outer unknown since, the way
Huw Davies's avatar
Huw Davies committed
1723
   * aggregation works, our lifetime is at least as large as its
1724 1725
   * lifetime.
   */
1726 1727
  if (!pUnkOuter)
    pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
1728

1729
  This->outerUnknown = pUnkOuter;
1730 1731 1732 1733 1734 1735

  /*
   * Create a datacache object.
   * We aggregate with the datacache. Make sure we pass our outer
   * unknown as the datacache's outer unknown.
   */
1736 1737 1738 1739 1740 1741 1742 1743
  hr = CreateDataCache(This->outerUnknown,
                       clsid,
                       &IID_IUnknown,
                       (void**)&This->dataCache);
  if(SUCCEEDED(hr))
    hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
  if(FAILED(hr))
    ERR("Unexpected error creating data cache\n");
1744 1745 1746
  /*
   * Initialize the other data members of the class.
   */
1747 1748 1749 1750 1751 1752
  memcpy(&This->clsid, clsid, sizeof(CLSID));
  This->clientSite = NULL;
  This->oleAdviseHolder = NULL;
  This->dataAdviseHolder = NULL;
  This->containerApp = NULL;
  This->containerObj = NULL;
1753 1754
  This->pOleDelegate = NULL;
  This->pPSDelegate = NULL;
1755
  This->pDataDelegate = NULL;
1756

1757 1758
  This->dwAdvConn = 0;

1759
  return This;
1760 1761 1762
}

static void DefaultHandler_Destroy(
1763
  DefaultHandler* This)
1764
{
1765 1766
  /* release delegates */
  DefaultHandler_Stop(This);
1767

1768 1769 1770 1771 1772 1773 1774 1775
  /* Free the strings idenfitying the object */
  HeapFree( GetProcessHeap(), 0, This->containerApp );
  This->containerApp = NULL;
  HeapFree( GetProcessHeap(), 0, This->containerObj );
  This->containerObj = NULL;

  /* Release our reference to the data cache. */
  if (This->dataCache)
1776
  {
1777
    IPersistStorage_Release(This->dataCache_PersistStg);
1778
    IUnknown_Release(This->dataCache);
1779
    This->dataCache_PersistStg = NULL;
1780
    This->dataCache = NULL;
1781 1782
  }

1783 1784
  /* Same thing for the client site. */
  if (This->clientSite)
1785
  {
1786 1787
    IOleClientSite_Release(This->clientSite);
    This->clientSite = NULL;
1788 1789
  }

1790 1791
  /* And the advise holder. */
  if (This->oleAdviseHolder)
1792
  {
1793 1794
    IOleAdviseHolder_Release(This->oleAdviseHolder);
    This->oleAdviseHolder = NULL;
1795 1796
  }

1797 1798
  /* And the data advise holder. */
  if (This->dataAdviseHolder)
1799
  {
1800 1801
    IDataAdviseHolder_Release(This->dataAdviseHolder);
    This->dataAdviseHolder = NULL;
1802 1803
  }

1804 1805
  /* Free the actual default handler structure. */
  HeapFree(GetProcessHeap(), 0, This);
1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830
}

/******************************************************************************
 * OleCreateDefaultHandler [OLE32.@]
 */
HRESULT WINAPI OleCreateDefaultHandler(
  REFCLSID  clsid,
  LPUNKNOWN pUnkOuter,
  REFIID    riid,
  LPVOID*   ppvObj)
{
  DefaultHandler* newHandler = NULL;
  HRESULT         hr         = S_OK;

  TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);

  /*
   * Sanity check
   */
  if (!ppvObj)
    return E_POINTER;

  *ppvObj = NULL;

  /*
1831
   * If This handler is constructed for aggregation, make sure
1832 1833 1834 1835
   * 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.
   */
1836
  if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
1837 1838 1839 1840 1841
    return CLASS_E_NOAGGREGATION;

  /*
   * Try to construct a new instance of the class.
   */
1842
  newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
1843 1844 1845 1846 1847 1848 1849

  if (!newHandler)
    return E_OUTOFMEMORY;

  /*
   * Make sure it supports the interface required by the caller.
   */
1850
  hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
1851 1852 1853 1854 1855

  /*
   * Release the reference obtained in the constructor. If
   * the QueryInterface was unsuccessful, it will free the class.
   */
1856
  IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
1857 1858 1859

  return hr;
}