/*
 *	OLE 2 default object handler
 *
 *      Copyright 1999  Francis Beaudet
 *      Copyright 2000  Abey George
 *
 * 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
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * 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.
 *
 * - Some functions still return E_NOTIMPL they have to be
 *   implemented. Most of those are related to the running of the
 *   actual server.
 *
 * - All the methods related to notification and advise sinks are
 *   in place but no notifications are sent to the sinks yet.
 */
#include <assert.h>
#include <stdarg.h>
#include <string.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "ole2.h"

#include "compobj_private.h"
#include "storage32.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(ole);

enum storage_state
{
    storage_state_uninitialised,
    storage_state_initialised,
    storage_state_loaded
};

enum object_state
{
    object_state_not_running,
    object_state_running,
    object_state_deferred_close
};

/****************************************************************************
 * DefaultHandler
 *
 */
struct DefaultHandler
{
  IOleObject        IOleObject_iface;
  IUnknown          IUnknown_iface;
  IDataObject       IDataObject_iface;
  IRunnableObject   IRunnableObject_iface;
  IAdviseSink       IAdviseSink_iface;
  IPersistStorage   IPersistStorage_iface;

  /* Reference count of this object */
  LONG ref;

  /* IUnknown implementation of the outer object. */
  IUnknown* outerUnknown;

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

  /* IUnknown implementation of the datacache. */
  IUnknown* dataCache;
  /* IPersistStorage implementation of the datacache. */
  IPersistStorage* dataCache_PersistStg;

  /* Client site for the embedded object. */
  IOleClientSite* clientSite;

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

  /*
   * The IDataAdviseHolder maintains the data
   * connections on behalf of the default handler.
   */
  IDataAdviseHolder* dataAdviseHolder;

  /* Name of the container and object contained */
  LPWSTR containerApp;
  LPWSTR containerObj;

  /* IOleObject delegate */
  IOleObject *pOleDelegate;
  /* IPersistStorage delegate */
  IPersistStorage *pPSDelegate;
  /* IDataObject delegate */
  IDataObject *pDataDelegate;
  enum object_state object_state;
  ULONG in_call;

  /* connection cookie for the advise on the delegate OLE object */
  DWORD dwAdvConn;

  /* storage passed to Load or InitNew */
  IStorage *storage;
  enum storage_state storage_state;

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

typedef struct DefaultHandler DefaultHandler;

static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
{
    return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface);
}

static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface )
{
    return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface);
}

static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
{
    return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface);
}

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

static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
{
    return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface);
}

static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
{
    return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface);
}

static void DefaultHandler_Destroy(DefaultHandler* This);

static inline BOOL object_is_running(DefaultHandler *This)
{
    return IRunnableObject_IsRunning(&This->IRunnableObject_iface);
}

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 );
}

/*********************************************************
 * 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.
 *
 * This version of QueryInterface will not delegate its implementation
 * to the outer unknown.
 */
static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
            IUnknown*      iface,
            REFIID         riid,
            void**         ppvObject)
{
  DefaultHandler *This = impl_from_IUnknown(iface);

  if (!ppvObject)
    return E_INVALIDARG;

  *ppvObject = NULL;

  if (IsEqualIID(&IID_IUnknown, riid))
    *ppvObject = iface;
  else if (IsEqualIID(&IID_IOleObject, riid))
    *ppvObject = &This->IOleObject_iface;
  else if (IsEqualIID(&IID_IDataObject, riid))
    *ppvObject = &This->IDataObject_iface;
  else if (IsEqualIID(&IID_IRunnableObject, riid))
    *ppvObject = &This->IRunnableObject_iface;
  else if (IsEqualIID(&IID_IPersist, riid) ||
           IsEqualIID(&IID_IPersistStorage, riid))
    *ppvObject = &This->IPersistStorage_iface;
  else if (IsEqualIID(&IID_IViewObject, riid) ||
           IsEqualIID(&IID_IViewObject2, riid) ||
           IsEqualIID(&IID_IOleCache, riid) ||
           IsEqualIID(&IID_IOleCache2, riid))
  {
    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;
  }
  else if (This->inproc_server && This->pOleDelegate)
  {
    return IOleObject_QueryInterface(This->pOleDelegate, riid, ppvObject);
  }

  /* Check that we obtained an interface. */
  if (*ppvObject == NULL)
  {
    WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
  }

  /*
   * Query Interface always increases the reference count by one when it is
   * successful.
   */
  IUnknown_AddRef((IUnknown*)*ppvObject);

  return S_OK;
}

/************************************************************************
 * DefaultHandler_NDIUnknown_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 *
 * This version of QueryInterface will not delegate its implementation
 * to the outer unknown.
 */
static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
            IUnknown*      iface)
{
  DefaultHandler *This = impl_from_IUnknown(iface);
  return InterlockedIncrement(&This->ref);
}

/************************************************************************
 * DefaultHandler_NDIUnknown_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 *
 * This version of QueryInterface will not delegate its implementation
 * to the outer unknown.
 */
static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
            IUnknown*      iface)
{
  DefaultHandler *This = impl_from_IUnknown(iface);
  ULONG ref;

  ref = InterlockedDecrement(&This->ref);

  if (!ref) DefaultHandler_Destroy(This);

  return ref;
}

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

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

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

  return IUnknown_AddRef(This->outerUnknown);
}

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

  return IUnknown_Release(This->outerUnknown);
}

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

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
    end_object_call( This );
  }

  /*
   * Make sure we release the previous client site if there
   * was one.
   */
  if (This->clientSite)
    IOleClientSite_Release(This->clientSite);

  This->clientSite = pClientSite;

  if (This->clientSite)
    IOleClientSite_AddRef(This->clientSite);

  return hr;
}

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

  if (!ppClientSite)
    return E_POINTER;

  *ppClientSite = This->clientSite;

  if (This->clientSite)
    IOleClientSite_AddRef(This->clientSite);

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

  TRACE("(%p, %s, %s)\n",
	iface,
	debugstr_w(szContainerApp),
	debugstr_w(szContainerObj));

  if (object_is_running(This))
  {
    start_object_call( This );
    IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
    end_object_call( This );
  }

  /* Be sure to cleanup before re-assigning the strings. */
  HeapFree( GetProcessHeap(), 0, This->containerApp );
  This->containerApp = NULL;
  HeapFree( GetProcessHeap(), 0, This->containerObj );
  This->containerObj = NULL;

  if (szContainerApp)
  {
      if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
                                           (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
          strcpyW( This->containerApp, szContainerApp );
  }

  if (szContainerObj)
  {
      if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
                                           (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
          strcpyW( This->containerObj, szContainerObj );
  }
  return S_OK;
}

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;
    }
}

/* undoes the work done by DefaultHandler_Run */
static void DefaultHandler_Stop(DefaultHandler *This)
{
  IOleCacheControl *cache_ctrl;
  HRESULT hr;

  if (This->object_state == object_state_not_running)
    return;

  hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
  if (SUCCEEDED(hr))
  {
    hr = IOleCacheControl_OnStop( cache_ctrl );
    IOleCacheControl_Release( cache_ctrl );
  }

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

  if (This->dataAdviseHolder)
    DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);

  This->object_state = object_state_not_running;
  release_delegates( This );
}

/************************************************************************
 * 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(
	    IOleObject*        iface,
	    DWORD              dwSaveOption)
{
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr;

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

  if (!object_is_running(This))
    return S_OK;

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

  DefaultHandler_Stop(This);

  return hr;
}

/************************************************************************
 * 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(
	    IOleObject*        iface,
	    DWORD              dwWhichMoniker,
	    IMoniker*          pmk)
{
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr = S_OK;

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
    end_object_call( This );
  }

  return hr;
}

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

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
                               ppmk);
    end_object_call( This );
    return hr;
  }

  /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
  if (This->clientSite)
  {
    return IOleClientSite_GetMoniker(This->clientSite,
				     dwAssign,
				     dwWhichMoniker,
				     ppmk);

  }

  return E_FAIL;
}

/************************************************************************
 * DefaultHandler_InitFromData (IOleObject)
 *
 * This method is meaningless if the server is not running
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_InitFromData(
	    IOleObject*        iface,
	    IDataObject*       pDataObject,
	    BOOL               fCreation,
	    DWORD              dwReserved)
{
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr = OLE_E_NOTRUNNING;

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
		                   dwReserved);
    end_object_call( This );
  }

  return hr;
}

/************************************************************************
 * DefaultHandler_GetClipboardData (IOleObject)
 *
 * This method is meaningless if the server is not running
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetClipboardData(
	    IOleObject*        iface,
	    DWORD              dwReserved,
	    IDataObject**      ppDataObject)
{
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr = OLE_E_NOTRUNNING;

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
                                       ppDataObject);
    end_object_call( This );
  }

  return hr;
}

static HRESULT WINAPI DefaultHandler_DoVerb(
	    IOleObject*        iface,
	    LONG               iVerb,
	    struct tagMSG*     lpmsg,
	    IOleClientSite*    pActiveSite,
	    LONG               lindex,
	    HWND               hwndParent,
	    LPCRECT            lprcPosRect)
{
  DefaultHandler *This = impl_from_IOleObject(iface);
  IRunnableObject *pRunnableObj = &This->IRunnableObject_iface;
  HRESULT hr;

  TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));

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

  start_object_call( This );
  hr = IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
                           lindex, hwndParent, lprcPosRect);
  end_object_call( This );

  return hr;
}

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

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
    end_object_call( This );
  }

  if (hr == OLE_S_USEREG)
    return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
  else
    return hr;
}

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

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

    if (!object_is_running(This))
    {
        FIXME("Should run object\n");
        return E_NOTIMPL;
    }

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

    return hr;
}

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

    if (object_is_running(This))
    {
        start_object_call( This );
        hr = IOleObject_IsUpToDate(This->pOleDelegate);
        end_object_call( This );
    }

    return hr;
}

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

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
    end_object_call( This );
    return hr;
  }

  if (!pClsid)
    return E_POINTER;

  *pClsid = This->clsid;

  return S_OK;
}

/************************************************************************
 * DefaultHandler_GetUserType (IOleObject)
 *
 * The default handler implementation of this method simply delegates
 * to OleRegGetUserType
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetUserType(
	    IOleObject*        iface,
	    DWORD              dwFormOfType,
	    LPOLESTR*          pszUserType)
{
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr;

  TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
    end_object_call( This );
    return hr;
  }

  return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
}

/************************************************************************
 * 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(
	    IOleObject*        iface,
	    DWORD              dwDrawAspect,
	    SIZEL*             psizel)
{
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr = OLE_E_NOTRUNNING;

  TRACE("(%p, %x, (%d x %d))\n", iface,
        dwDrawAspect, psizel->cx, psizel->cy);

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
    end_object_call( This );
  }

  return hr;
}

/************************************************************************
 * 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(
	    IOleObject*        iface,
	    DWORD              dwDrawAspect,
	    SIZEL*             psizel)
{
  DVTARGETDEVICE* targetDevice;
  IViewObject2*   cacheView = NULL;
  HRESULT         hres;

  DefaultHandler *This = impl_from_IOleObject(iface);

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hres = IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
    end_object_call( This );
    return hres;
  }

  hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
  if (FAILED(hres))
    return E_UNEXPECTED;

  /*
   * Prepare the call to the cache's GetExtent method.
   *
   * Here we would build a valid DVTARGETDEVICE structure
   * but, since we are calling into the data cache, we
   * know its implementation and we'll skip this
   * 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(
	    IOleObject*        iface,
	    IAdviseSink*       pAdvSink,
	    DWORD*             pdwConnection)
{
  HRESULT hres = S_OK;
  DefaultHandler *This = impl_from_IOleObject(iface);

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

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

  if (SUCCEEDED(hres))
    hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
				   pAdvSink,
				   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(
	    IOleObject*        iface,
	    DWORD              dwConnection)
{
  DefaultHandler *This = impl_from_IOleObject(iface);

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

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

  return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
				   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(
	    IOleObject*        iface,
	    IEnumSTATDATA**    ppenumAdvise)
{
  DefaultHandler *This = impl_from_IOleObject(iface);

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

  if (!ppenumAdvise)
    return E_POINTER;

  *ppenumAdvise = NULL;

  if (!This->oleAdviseHolder)
      return S_OK;

  return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
}

/************************************************************************
 * 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(
	    IOleObject*        iface,
	    DWORD              dwAspect,
	    DWORD*             pdwStatus)
{
  HRESULT hres;
  DefaultHandler *This = impl_from_IOleObject(iface);

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hres = IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
    end_object_call( This );
    return hres;
  }

  hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);

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

  return hres;
}

/************************************************************************
 * DefaultHandler_SetColorScheme (IOleObject)
 *
 * This method is meaningless if the server is not running
 *
 * See Windows documentation for more details on IOleObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetColorScheme(
	    IOleObject*           iface,
	    struct tagLOGPALETTE* pLogpal)
{
  DefaultHandler *This = impl_from_IOleObject(iface);
  HRESULT hr = OLE_E_NOTRUNNING;

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

  if (object_is_running(This))
  {
    start_object_call( This );
    hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
    end_object_call( This );
  }

  return hr;
}

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

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

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

  return IUnknown_AddRef(This->outerUnknown);
}

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

  return IUnknown_Release(This->outerUnknown);
}

/************************************************************************
 * 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.
 */
static HRESULT WINAPI DefaultHandler_GetData(
	    IDataObject*     iface,
	    LPFORMATETC      pformatetcIn,
	    STGMEDIUM*       pmedium)
{
  IDataObject* cacheDataObject = NULL;
  HRESULT      hres;

  DefaultHandler *This = impl_from_IDataObject(iface);

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

  hres = IUnknown_QueryInterface(This->dataCache,
				 &IID_IDataObject,
				 (void**)&cacheDataObject);

  if (FAILED(hres))
    return E_UNEXPECTED;

  hres = IDataObject_GetData(cacheDataObject,
			     pformatetcIn,
			     pmedium);

  IDataObject_Release(cacheDataObject);

  if (hres == S_OK) return hres;

  if (object_is_running( This ))
  {
    start_object_call(This);
    hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
    end_object_call(This);
    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;

  return hres;
}

static HRESULT WINAPI DefaultHandler_GetDataHere(
	    IDataObject*     iface,
	    LPFORMATETC      pformatetc,
	    STGMEDIUM*       pmedium)
{
  FIXME(": Stub\n");
  return E_NOTIMPL;
}

/************************************************************************
 * DefaultHandler_QueryGetData (IDataObject)
 *
 * The default handler's implementation of this method delegates to
 * 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;

  DefaultHandler *This = impl_from_IDataObject(iface);

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

  hres = IUnknown_QueryInterface(This->dataCache,
				 &IID_IDataObject,
				 (void**)&cacheDataObject);

  if (FAILED(hres))
    return E_UNEXPECTED;

  hres = IDataObject_QueryGetData(cacheDataObject,
				  pformatetc);

  IDataObject_Release(cacheDataObject);

  if (hres == S_OK) return hres;

  if (object_is_running( This ))
  {
    start_object_call( This );
    hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
    end_object_call( This );
    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;

  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(
	    IDataObject*     iface,
	    LPFORMATETC      pformatetcIn,
	    LPFORMATETC      pformatetcOut)
{
  DefaultHandler *This = impl_from_IDataObject(iface);
  HRESULT hr;

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

  if (!object_is_running( This ))
    return OLE_E_NOTRUNNING;

  start_object_call( This );
  hr = IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
  end_object_call( This );

  return hr;
}

/************************************************************************
 * DefaultHandler_SetData (IDataObject)
 *
 * The default handler's implementation of this method delegates to
 * the cache.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetData(
	    IDataObject*     iface,
	    LPFORMATETC      pformatetc,
	    STGMEDIUM*       pmedium,
	    BOOL             fRelease)
{
  DefaultHandler *This = impl_from_IDataObject(iface);
  IDataObject* cacheDataObject = NULL;
  HRESULT      hres;

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

  hres = IUnknown_QueryInterface(This->dataCache,
				 &IID_IDataObject,
				 (void**)&cacheDataObject);

  if (FAILED(hres))
    return E_UNEXPECTED;

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

  IDataObject_Release(cacheDataObject);

  return hres;
}

/************************************************************************
 * DefaultHandler_EnumFormatEtc (IDataObject)
 *
 * The default handler's implementation of This method simply delegates
 * to OleRegEnumFormatEtc.
 *
 * See Windows documentation for more details on IDataObject methods.
 */
static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
	    IDataObject*     iface,
	    DWORD            dwDirection,
	    IEnumFORMATETC** ppenumFormatEtc)
{
  DefaultHandler *This = impl_from_IDataObject(iface);

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

  return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
}

/************************************************************************
 * 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(
	    IDataObject*     iface,
	    FORMATETC*       pformatetc,
	    DWORD            advf,
	    IAdviseSink*     pAdvSink,
	    DWORD*           pdwConnection)
{
  HRESULT hres = S_OK;
  DefaultHandler *This = impl_from_IDataObject(iface);

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

  /* Make sure we have a data advise holder before we start. */
  if (!This->dataAdviseHolder)
  {
    hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
    if (SUCCEEDED(hres) && object_is_running( This ))
    {
      start_object_call( This );
      DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
      end_object_call( This );
    }
  }

  if (SUCCEEDED(hres))
    hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
				    iface,
				    pformatetc,
				    advf,
				    pAdvSink,
				    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)
{
  DefaultHandler *This = impl_from_IDataObject(iface);

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

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

  return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
				    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)
{
  DefaultHandler *This = impl_from_IDataObject(iface);

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

  if (!ppenumAdvise)
    return E_POINTER;

  *ppenumAdvise = NULL;

  /* If we have a data advise holder object, delegate. */
  if (This->dataAdviseHolder)
    return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
					ppenumAdvise);

  return S_OK;
}

/*********************************************************
 * Methods implementation for the IRunnableObject part
 * 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)
{
  DefaultHandler *This = impl_from_IRunnableObject(iface);

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

/************************************************************************
 * DefaultHandler_IRunnableObject_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
            IRunnableObject*     iface)
{
  DefaultHandler *This = impl_from_IRunnableObject(iface);

  return IUnknown_AddRef(This->outerUnknown);
}

/************************************************************************
 * DefaultHandler_IRunnableObject_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
            IRunnableObject*     iface)
{
  DefaultHandler *This = impl_from_IRunnableObject(iface);

  return IUnknown_Release(This->outerUnknown);
}

/************************************************************************
 * DefaultHandler_GetRunningClass (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
static HRESULT WINAPI DefaultHandler_GetRunningClass(
            IRunnableObject*     iface,
	    LPCLSID              lpClsid)
{
  FIXME("()\n");
  return S_OK;
}

static HRESULT WINAPI DefaultHandler_Run(
            IRunnableObject*     iface,
	    IBindCtx*            pbc)
{
  DefaultHandler *This = impl_from_IRunnableObject(iface);
  HRESULT hr;
  IOleCacheControl *cache_ctrl;

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

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

  release_delegates(This);

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

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

  if (This->clientSite)
  {
    hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
    if (FAILED(hr)) goto fail;
  }

  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)
  {
    hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
                                 This->containerObj);
    if (FAILED(hr)) goto fail;
  }

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

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

  This->object_state = object_state_running;

  if (This->dataAdviseHolder)
  {
    hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
    if (FAILED(hr)) goto fail;
  }

  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;

  return hr;

fail:
  DefaultHandler_Stop(This);
  return hr;
}

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

  TRACE("()\n");

  if (This->object_state == object_state_running)
    return TRUE;
  else
    return FALSE;
}

/************************************************************************
 * DefaultHandler_LockRunning (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
static HRESULT WINAPI DefaultHandler_LockRunning(
            IRunnableObject*     iface,
	    BOOL                 fLock,
	    BOOL                 fLastUnlockCloses)
{
  FIXME("()\n");
  return S_OK;
}

/************************************************************************
 * DefaultHandler_SetContainedObject (IRunnableObject)
 *
 * See Windows documentation for more details on IRunnableObject methods.
 */
static HRESULT WINAPI DefaultHandler_SetContainedObject(
            IRunnableObject*     iface,
	    BOOL                 fContained)
{
  FIXME("()\n");
  return S_OK;
}

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(&This->IUnknown_iface);
}

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

    return IUnknown_Release(&This->IUnknown_iface);
}

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

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

    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
}

static void WINAPI DefaultHandler_IAdviseSink_OnSave(
    IAdviseSink *iface)
{
    DefaultHandler *This = impl_from_IAdviseSink(iface);

    TRACE("()\n");

    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
}

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

    if (This->oleAdviseHolder)
        IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);

    if(!This->in_call)
        DefaultHandler_Stop(This);
    else
    {
        TRACE("OnClose during call.  Deferring shutdown\n");
        This->object_state = object_state_deferred_close;
    }
}

/************************************************************************
 * 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);
    HRESULT hr;

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

    if(object_is_running(This))
    {
        start_object_call( This );
        hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
        end_object_call( This );
    }
    else
        hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);

    return hr;
}

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

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

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

    if(object_is_running(This))
    {
        start_object_call( This );
        hr = IPersistStorage_IsDirty(This->pPSDelegate);
        end_object_call( This );
    }

    return hr;
}

/***********************************************************************
 *
 * The format of '\1Ole' stream is as follows:
 *
 * 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;

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
        hr = STORAGE_CreateOleStream(storage, 0);

    return hr;
}

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

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

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

    if(SUCCEEDED(hr) && object_is_running(This))
    {
        start_object_call( This );
        hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
        end_object_call( This );
    }

    if(SUCCEEDED(hr))
    {
        IStorage_AddRef(pStg);
        This->storage = pStg;
        This->storage_state = storage_state_initialised;
    }

    return hr;
}


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

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

    hr = load_ole_stream(This, pStg);

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

    if(SUCCEEDED(hr) && object_is_running(This))
    {
        start_object_call( This );
        hr = IPersistStorage_Load(This->pPSDelegate, pStg);
        end_object_call( This );
    }

    if(SUCCEEDED(hr))
    {
        IStorage_AddRef(pStg);
        This->storage = pStg;
        This->storage_state = storage_state_loaded;
    }
    return hr;
}


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

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

    hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
    if(SUCCEEDED(hr) && object_is_running(This))
    {
        start_object_call( This );
        hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
        end_object_call( This );
    }

    return hr;
}


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

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

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

    if(SUCCEEDED(hr) && object_is_running(This))
    {
        start_object_call( This );
        hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
        end_object_call( This );
    }

    if(pStgNew)
    {
        IStorage_AddRef(pStgNew);
        if(This->storage) IStorage_Release(This->storage);
        This->storage = pStgNew;
        This->storage_state = storage_state_loaded;
    }

    return hr;
}


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

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

    hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);

    if(SUCCEEDED(hr) && object_is_running(This))
    {
        start_object_call( This );
        hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
        end_object_call( This );
    }

    if(This->storage) IStorage_Release(This->storage);
    This->storage = NULL;
    This->storage_state = storage_state_uninitialised;

    return hr;
}


/*
 * 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
};

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
};

static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable =
{
  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
};

/*********************************************************
 * Methods implementation for the DefaultHandler class.
 */
static DefaultHandler* DefaultHandler_Construct(
  REFCLSID  clsid,
  LPUNKNOWN pUnkOuter,
  DWORD flags,
  IClassFactory *pCF)
{
  DefaultHandler* This = NULL;
  HRESULT hr;

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

  if (!This)
    return This;

  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;

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

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

  /*
   * Initialize the outer unknown
   * We don't keep a reference on the outer unknown since, the way
   * aggregation works, our lifetime is at least as large as its
   * lifetime.
   */
  if (!pUnkOuter)
    pUnkOuter = &This->IUnknown_iface;

  This->outerUnknown = pUnkOuter;

  /*
   * Create a datacache object.
   * We aggregate with the datacache. Make sure we pass our outer
   * unknown as the datacache's outer unknown.
   */
  hr = CreateDataCache(This->outerUnknown,
                       clsid,
                       &IID_IUnknown,
                       (void**)&This->dataCache);
  if(SUCCEEDED(hr))
  {
    hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
    /* 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);
  }
  if(FAILED(hr))
  {
    ERR("Unexpected error creating data cache\n");
    HeapFree(GetProcessHeap(), 0, This);
    return NULL;
  }

  This->clsid = *clsid;
  This->clientSite = NULL;
  This->oleAdviseHolder = NULL;
  This->dataAdviseHolder = NULL;
  This->containerApp = NULL;
  This->containerObj = NULL;
  This->pOleDelegate = NULL;
  This->pPSDelegate = NULL;
  This->pDataDelegate = NULL;
  This->object_state = object_state_not_running;
  This->in_call = 0;

  This->dwAdvConn = 0;
  This->storage = NULL;
  This->storage_state = storage_state_uninitialised;

  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);
  }

  return This;
}

static void DefaultHandler_Destroy(
  DefaultHandler* This)
{
  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;

  /* release delegates */
  DefaultHandler_Stop(This);

  HeapFree( GetProcessHeap(), 0, This->containerApp );
  This->containerApp = NULL;
  HeapFree( GetProcessHeap(), 0, This->containerObj );
  This->containerObj = NULL;

  if (This->dataCache)
  {
    /* to balance out the release of dataCache_PersistStg which will result
     * in a reference being released from the outer unknown */
    IUnknown_AddRef(This->outerUnknown);
    IPersistStorage_Release(This->dataCache_PersistStg);
    IUnknown_Release(This->dataCache);
    This->dataCache_PersistStg = NULL;
    This->dataCache = NULL;
  }

  if (This->clientSite)
  {
    IOleClientSite_Release(This->clientSite);
    This->clientSite = NULL;
  }

  if (This->oleAdviseHolder)
  {
    IOleAdviseHolder_Release(This->oleAdviseHolder);
    This->oleAdviseHolder = NULL;
  }

  if (This->dataAdviseHolder)
  {
    IDataAdviseHolder_Release(This->dataAdviseHolder);
    This->dataAdviseHolder = NULL;
  }

  if (This->storage)
  {
    IStorage_Release(This->storage);
    This->storage = NULL;
  }

  if (This->pCFObject)
  {
    IClassFactory_Release(This->pCFObject);
    This->pCFObject = NULL;
  }

  HeapFree(GetProcessHeap(), 0, This);
}

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

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

  if (!ppvObj)
    return E_POINTER;

  *ppvObj = NULL;

  /*
   * If This handler is constructed for aggregation, make sure
   * 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.
   */
  if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
    return CLASS_E_NOAGGREGATION;

  /*
   * Try to construct a new instance of the class.
   */
  newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);

  if (!newHandler)
    return E_OUTOFMEMORY;

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

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

  return hr;
}


/******************************************************************************
 * 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);
}

typedef struct HandlerCF
{
    IClassFactory IClassFactory_iface;
    LONG refs;
    CLSID clsid;
} HandlerCF;

static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface)
{
    return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface);
}

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)
{
    HandlerCF *This = impl_from_IClassFactory(iface);
    return InterlockedIncrement(&This->refs);
}

static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
{
    HandlerCF *This = impl_from_IClassFactory(iface);
    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)
{
    HandlerCF *This = impl_from_IClassFactory(iface);
    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;
    This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl;
    This->refs = 0;
    This->clsid = *rclsid;

    hr = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv);
    if (FAILED(hr))
        HeapFree(GetProcessHeap(), 0, This);

    return hr;
}
