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

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

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

/*********************************************************
 * 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 IUnknown_QueryInterface(This->pOleDelegate, riid, ppvObject);
  }

  /* Check that we obtained an interface. */
  if (*ppvObject == NULL)
  {
    WARN( "() : asking for un supported 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))
    hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);

  /*
   * 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))
    IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);

  /* 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)
{
  if (!object_is_running(This))
    return;

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

  /* FIXME: call IOleCache_OnStop */

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

  This->object_state = object_state_not_running;
}

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

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

  DefaultHandler_Stop(This);
  release_delegates(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);

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

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

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

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

  if (object_is_running(This))
    return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
                                 ppmk);

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

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

  if (object_is_running(This))
    return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
		                   dwReserved);
  return OLE_E_NOTRUNNING;
}

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

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

  if (object_is_running(This))
    return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
                                       ppDataObject);

  return OLE_E_NOTRUNNING;
}

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;

  return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
                           lindex, hwndParent, lprcPosRect);
}

/************************************************************************
 * 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))
    hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);

  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);
    TRACE("(%p)\n", iface);

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

/************************************************************************
 * 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);
    TRACE("(%p)\n", iface);

    if (object_is_running(This))
        return IOleObject_IsUpToDate(This->pOleDelegate);

    return OLE_E_NOTRUNNING;
}

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

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

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

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

  TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
  if (object_is_running(This))
    return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);

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

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

  if (object_is_running(This))
    return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);

  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(
	    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))
    return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);

  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))
    return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);

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

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

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

  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(
            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 (FAILED(hres) && This->pDataDelegate)
    hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);

  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 (FAILED(hres) && This->pDataDelegate)
    hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);

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

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

  if (!This->pDataDelegate)
    return OLE_E_NOTRUNNING;

  return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
}

/************************************************************************
 * 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) && This->pDataDelegate)
      DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
  }

  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;

  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,
                        &IID_IOleObject, (void **)&This->pOleDelegate);
  if (FAILED(hr))
    return hr;

  This->object_state = object_state_running;

  hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);

  if (SUCCEEDED(hr) && This->clientSite)
    hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);

  if (SUCCEEDED(hr))
  {
    IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
                              (void **)&This->pPSDelegate);
    if (This->pPSDelegate)
    {
      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 (SUCCEEDED(hr) && This->containerApp)
    hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
                                 This->containerObj);

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

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

  if (FAILED(hr))
  {
    DefaultHandler_Stop(This);
    release_delegates(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);

    DefaultHandler_Stop(This);
}


/************************************************************************
 * 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))
        hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
    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))
        hr = IPersistStorage_IsDirty(This->pPSDelegate);

    return hr;
}

/***********************************************************************
 *   init_ole_stream
 *
 * Creates the '\1Ole' stream.
 * The format of this 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 void init_ole_stream(IStorage *storage)
{
    HRESULT hr;
    IStream *stream;

    hr = IStorage_CreateStream(storage, OleStream, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream);
    if(SUCCEEDED(hr))
    {
        DWORD written;
        ole_stream_header_t header;

        header.version         = ole_stream_version;
        header.flags           = 0;
        header.link_update_opt = 0;
        header.res             = 0;
        header.moniker_size    = 0;

        IStream_Write(stream, &header, sizeof(header), &written);
        IStream_Release(stream);
    }
    return;
}

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
    {
        init_ole_stream(storage);
        hr = S_OK;
    }
    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);
    init_ole_stream(pStg);

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

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

    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))
        hr = IPersistStorage_Load(This->pPSDelegate, pStg);

    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))
        hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);

    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))
        hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);

    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))
        hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);

    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) ? TRUE : FALSE;

  /*
   * 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->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);
  release_delegates(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 = IUnknown_QueryInterface((IUnknown *)&This->IClassFactory_iface, riid, ppv);
    if (FAILED(hr))
        HeapFree(GetProcessHeap(), 0, This);

    return hr;
}
