2005-07-31 12:11:56 +00:00
|
|
|
/*
|
|
|
|
* 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
|
2007-04-20 12:23:52 +00:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2005-07-31 12:11:56 +00:00
|
|
|
*
|
|
|
|
* 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"
|
2005-12-12 23:53:06 +00:00
|
|
|
|
|
|
|
#include "compobj_private.h"
|
|
|
|
|
|
|
|
#include "wine/unicode.h"
|
2005-07-31 12:11:56 +00:00
|
|
|
#include "wine/debug.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
enum storage_state
|
|
|
|
{
|
|
|
|
storage_state_uninitialised,
|
|
|
|
storage_state_initialised,
|
|
|
|
storage_state_loaded
|
|
|
|
};
|
|
|
|
|
2009-01-15 17:52:35 +00:00
|
|
|
enum object_state
|
|
|
|
{
|
|
|
|
object_state_not_running,
|
|
|
|
object_state_running
|
|
|
|
};
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/****************************************************************************
|
|
|
|
* DefaultHandler
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
struct DefaultHandler
|
|
|
|
{
|
2005-09-05 21:56:14 +00:00
|
|
|
const IOleObjectVtbl* lpVtbl;
|
|
|
|
const IUnknownVtbl* lpvtblIUnknown;
|
|
|
|
const IDataObjectVtbl* lpvtblIDataObject;
|
|
|
|
const IRunnableObjectVtbl* lpvtblIRunnableObject;
|
2005-11-20 15:01:10 +00:00
|
|
|
const IAdviseSinkVtbl *lpvtblIAdviseSink;
|
2008-01-14 15:45:45 +00:00
|
|
|
const IPersistStorageVtbl *lpvtblIPersistStorage;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* Reference count of this object */
|
2005-08-12 17:19:46 +00:00
|
|
|
LONG ref;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* IUnknown implementation of the outer object. */
|
2005-07-31 12:11:56 +00:00
|
|
|
IUnknown* outerUnknown;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* Class Id that this handler object represents. */
|
2005-07-31 12:11:56 +00:00
|
|
|
CLSID clsid;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* IUnknown implementation of the datacache. */
|
2005-07-31 12:11:56 +00:00
|
|
|
IUnknown* dataCache;
|
2008-01-14 15:45:45 +00:00
|
|
|
/* IPersistStorage implementation of the datacache. */
|
|
|
|
IPersistStorage* dataCache_PersistStg;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* Client site for the embedded object. */
|
2005-07-31 12:11:56 +00:00
|
|
|
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;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* Name of the container and object contained */
|
2005-07-31 12:11:56 +00:00
|
|
|
LPWSTR containerApp;
|
|
|
|
LPWSTR containerObj;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* IOleObject delegate */
|
|
|
|
IOleObject *pOleDelegate;
|
|
|
|
/* IPersistStorage delegate */
|
|
|
|
IPersistStorage *pPSDelegate;
|
2005-12-12 23:53:06 +00:00
|
|
|
/* IDataObject delegate */
|
|
|
|
IDataObject *pDataDelegate;
|
2009-01-15 17:52:35 +00:00
|
|
|
enum object_state object_state;
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
/* connection cookie for the advise on the delegate OLE object */
|
|
|
|
DWORD dwAdvConn;
|
2008-11-07 11:00:30 +00:00
|
|
|
|
|
|
|
/* storage passed to Load or InitNew */
|
|
|
|
IStorage *storage;
|
|
|
|
enum storage_state storage_state;
|
2009-08-24 10:51:15 +00:00
|
|
|
|
|
|
|
/* optional class factory for object */
|
|
|
|
IClassFactory *pCFObject;
|
|
|
|
/* TRUE if acting as an inproc server instead of an inproc handler */
|
|
|
|
BOOL inproc_server;
|
2005-07-31 12:11:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct DefaultHandler DefaultHandler;
|
|
|
|
|
2005-09-05 21:56:14 +00:00
|
|
|
static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface )
|
|
|
|
{
|
|
|
|
return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpVtbl));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline DefaultHandler *impl_from_NDIUnknown( IUnknown *iface )
|
|
|
|
{
|
|
|
|
return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIUnknown));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface )
|
|
|
|
{
|
|
|
|
return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIDataObject));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface )
|
|
|
|
{
|
|
|
|
return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
|
|
|
|
}
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink));
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface )
|
|
|
|
{
|
|
|
|
return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIPersistStorage));
|
|
|
|
}
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
static void DefaultHandler_Destroy(DefaultHandler* This);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
static inline BOOL object_is_running(DefaultHandler *This)
|
|
|
|
{
|
|
|
|
return IRunnableObject_IsRunning((IRunnableObject*)&This->lpvtblIRunnableObject);
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/*********************************************************
|
|
|
|
* 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.
|
|
|
|
*
|
2008-01-14 15:45:45 +00:00
|
|
|
* This version of QueryInterface will not delegate its implementation
|
2005-07-31 12:11:56 +00:00
|
|
|
* to the outer unknown.
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
|
|
|
|
IUnknown* iface,
|
|
|
|
REFIID riid,
|
|
|
|
void** ppvObject)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_NDIUnknown(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (!ppvObject)
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
*ppvObject = NULL;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (IsEqualIID(&IID_IUnknown, riid))
|
2005-07-31 12:11:56 +00:00
|
|
|
*ppvObject = iface;
|
2005-11-20 15:01:10 +00:00
|
|
|
else if (IsEqualIID(&IID_IOleObject, riid))
|
2009-03-03 09:12:43 +00:00
|
|
|
*ppvObject = &This->lpVtbl;
|
2005-11-20 15:01:10 +00:00
|
|
|
else if (IsEqualIID(&IID_IDataObject, riid))
|
2009-03-03 09:12:43 +00:00
|
|
|
*ppvObject = &This->lpvtblIDataObject;
|
2005-11-20 15:01:10 +00:00
|
|
|
else if (IsEqualIID(&IID_IRunnableObject, riid))
|
2009-03-03 09:12:43 +00:00
|
|
|
*ppvObject = &This->lpvtblIRunnableObject;
|
2005-11-20 15:01:10 +00:00
|
|
|
else if (IsEqualIID(&IID_IPersist, riid) ||
|
2008-01-14 15:45:45 +00:00
|
|
|
IsEqualIID(&IID_IPersistStorage, riid))
|
|
|
|
*ppvObject = &This->lpvtblIPersistStorage;
|
|
|
|
else if (IsEqualIID(&IID_IViewObject, riid) ||
|
2005-11-20 15:01:10 +00:00
|
|
|
IsEqualIID(&IID_IViewObject2, riid) ||
|
|
|
|
IsEqualIID(&IID_IOleCache, riid) ||
|
|
|
|
IsEqualIID(&IID_IOleCache2, riid))
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
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;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
2009-08-24 10:51:15 +00:00
|
|
|
else if (This->inproc_server && This->pOleDelegate)
|
|
|
|
{
|
|
|
|
HRESULT hr = IUnknown_QueryInterface(This->pOleDelegate, riid, ppvObject);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
return hr;
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* Check that we obtained an interface. */
|
|
|
|
if (*ppvObject == NULL)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
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.
|
|
|
|
*
|
2008-01-14 15:45:45 +00:00
|
|
|
* This version of QueryInterface will not delegate its implementation
|
2005-07-31 12:11:56 +00:00
|
|
|
* to the outer unknown.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
|
|
|
|
IUnknown* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_NDIUnknown(iface);
|
|
|
|
return InterlockedIncrement(&This->ref);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_NDIUnknown_Release (IUnknown)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IUnknown methods.
|
|
|
|
*
|
2008-01-14 15:45:45 +00:00
|
|
|
* This version of QueryInterface will not delegate its implementation
|
2005-07-31 12:11:56 +00:00
|
|
|
* to the outer unknown.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
|
|
|
|
IUnknown* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_NDIUnknown(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
ULONG ref;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
ref = InterlockedDecrement(&This->ref);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (!ref) DefaultHandler_Destroy(This);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_AddRef (IUnknown)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IUnknown methods.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DefaultHandler_AddRef(
|
|
|
|
IOleObject* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_AddRef(This->outerUnknown);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_Release (IUnknown)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IUnknown methods.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DefaultHandler_Release(
|
|
|
|
IOleObject* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_Release(This->outerUnknown);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-12-12 23:53:06 +00:00
|
|
|
HRESULT hr = S_OK;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", iface, pClientSite);
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-12-12 23:53:06 +00:00
|
|
|
hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/*
|
|
|
|
* Make sure we release the previous client site if there
|
|
|
|
* was one.
|
|
|
|
*/
|
2005-11-20 15:01:10 +00:00
|
|
|
if (This->clientSite)
|
|
|
|
IOleClientSite_Release(This->clientSite);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
This->clientSite = pClientSite;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (This->clientSite)
|
|
|
|
IOleClientSite_AddRef(This->clientSite);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2010-05-29 11:34:57 +00:00
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (!ppClientSite)
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_POINTER;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
*ppClientSite = This->clientSite;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (This->clientSite)
|
|
|
|
IOleClientSite_AddRef(This->clientSite);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %s, %s)\n",
|
|
|
|
iface,
|
|
|
|
debugstr_w(szContainerApp),
|
|
|
|
debugstr_w(szContainerObj));
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-12-12 23:53:06 +00:00
|
|
|
IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
|
|
|
|
|
2008-07-10 09:14:19 +00:00
|
|
|
/* Be sure to cleanup before re-assigning the strings. */
|
2005-11-20 15:01:10 +00:00
|
|
|
HeapFree( GetProcessHeap(), 0, This->containerApp );
|
|
|
|
This->containerApp = NULL;
|
|
|
|
HeapFree( GetProcessHeap(), 0, This->containerObj );
|
|
|
|
This->containerObj = NULL;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (szContainerApp)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
|
2005-07-31 12:11:56 +00:00
|
|
|
(lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
|
2005-11-20 15:01:10 +00:00
|
|
|
strcpyW( This->containerApp, szContainerApp );
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (szContainerObj)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
|
2005-07-31 12:11:56 +00:00
|
|
|
(lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
|
2005-11-20 15:01:10 +00:00
|
|
|
strcpyW( This->containerObj, szContainerObj );
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2009-01-15 17:52:35 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
/* undoes the work done by DefaultHandler_Run */
|
|
|
|
static void DefaultHandler_Stop(DefaultHandler *This)
|
2005-11-20 15:01:10 +00:00
|
|
|
{
|
2008-01-14 15:45:45 +00:00
|
|
|
if (!object_is_running(This))
|
2005-11-20 15:01:10 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
|
|
|
|
|
|
|
|
/* FIXME: call IOleCache_OnStop */
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (This->dataAdviseHolder)
|
|
|
|
DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
|
2009-01-15 17:52:35 +00:00
|
|
|
|
|
|
|
This->object_state = object_state_not_running;
|
2005-11-20 15:01:10 +00:00
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
HRESULT hr;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%d)\n", dwSaveOption);
|
2005-11-20 15:01:10 +00:00
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (!object_is_running(This))
|
2005-11-20 15:01:10 +00:00
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
|
|
|
|
|
|
|
|
DefaultHandler_Stop(This);
|
2009-01-15 17:52:35 +00:00
|
|
|
release_delegates(This);
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2005-12-12 23:53:06 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %d, %p)\n",
|
2005-07-31 12:11:56 +00:00
|
|
|
iface,
|
|
|
|
dwWhichMoniker,
|
|
|
|
pmk);
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-12-12 23:53:06 +00:00
|
|
|
return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %d, %d, %p)\n",
|
2005-07-31 12:11:56 +00:00
|
|
|
iface, dwAssign, dwWhichMoniker, ppmk);
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-12-12 23:53:06 +00:00
|
|
|
return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
|
|
|
|
ppmk);
|
|
|
|
|
|
|
|
/* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
|
2005-11-20 15:01:10 +00:00
|
|
|
if (This->clientSite)
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
return IOleClientSite_GetMoniker(This->clientSite,
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-12-12 23:53:06 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %p, %d, %d)\n",
|
2005-07-31 12:11:56 +00:00
|
|
|
iface, pDataObject, fCreation, dwReserved);
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-12-12 23:53:06 +00:00
|
|
|
return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
|
|
|
|
dwReserved);
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-12-12 23:53:06 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %d, %p)\n",
|
2005-07-31 12:11:56 +00:00
|
|
|
iface, dwReserved, ppDataObject);
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-12-12 23:53:06 +00:00
|
|
|
return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
|
|
|
|
ppDataObject);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
return OLE_E_NOTRUNNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI DefaultHandler_DoVerb(
|
|
|
|
IOleObject* iface,
|
|
|
|
LONG iVerb,
|
|
|
|
struct tagMSG* lpmsg,
|
|
|
|
IOleClientSite* pActiveSite,
|
|
|
|
LONG lindex,
|
|
|
|
HWND hwndParent,
|
|
|
|
LPCRECT lprcPosRect)
|
|
|
|
{
|
2005-12-12 23:53:06 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
IRunnableObject *pRunnableObj = (IRunnableObject *)&This->lpvtblIRunnableObject;
|
|
|
|
HRESULT hr;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect));
|
2005-12-12 23:53:06 +00:00
|
|
|
|
|
|
|
hr = IRunnableObject_Run(pRunnableObj, NULL);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
|
|
|
|
return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
|
|
|
|
lindex, hwndParent, lprcPosRect);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
HRESULT hr = OLE_S_USEREG;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-11-20 15:01:10 +00:00
|
|
|
hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
|
|
|
|
|
|
|
|
if (hr == OLE_S_USEREG)
|
|
|
|
return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
|
|
|
|
else
|
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI DefaultHandler_Update(
|
|
|
|
IOleObject* iface)
|
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
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);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
TRACE("(%p)\n", iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
if (object_is_running(This))
|
|
|
|
return IOleObject_IsUpToDate(This->pOleDelegate);
|
|
|
|
|
|
|
|
return OLE_E_NOTRUNNING;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", iface, pClsid);
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-11-20 15:01:10 +00:00
|
|
|
return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
|
|
|
|
|
|
|
|
if (!pClsid)
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_POINTER;
|
|
|
|
|
2008-07-10 09:14:19 +00:00
|
|
|
*pClsid = This->clsid;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
|
2008-11-07 11:00:30 +00:00
|
|
|
if (object_is_running(This))
|
|
|
|
return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2005-12-12 23:53:06 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %x, (%d x %d))\n", iface,
|
2005-07-31 12:11:56 +00:00
|
|
|
dwDrawAspect, psizel->cx, psizel->cy);
|
2005-12-12 23:53:06 +00:00
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2008-09-13 18:49:51 +00:00
|
|
|
return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
|
2005-12-12 23:53:06 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
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;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-12-12 23:53:06 +00:00
|
|
|
return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-12-12 23:53:06 +00:00
|
|
|
hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
|
2005-07-31 12:11:56 +00:00
|
|
|
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
|
2008-01-14 15:45:45 +00:00
|
|
|
* know its implementation and we'll skip this
|
2005-07-31 12:11:56 +00:00
|
|
|
* 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;
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* Make sure we have an advise holder before we start. */
|
|
|
|
if (!This->oleAdviseHolder)
|
|
|
|
hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (SUCCEEDED(hres))
|
2005-11-20 15:01:10 +00:00
|
|
|
hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %d)\n", iface, dwConnection);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we don't have an advise holder yet, it means we don't have
|
|
|
|
* a connection.
|
|
|
|
*/
|
2005-11-20 15:01:10 +00:00
|
|
|
if (!This->oleAdviseHolder)
|
2005-07-31 12:11:56 +00:00
|
|
|
return OLE_E_NOCONNECTION;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", iface, ppenumAdvise);
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (!ppenumAdvise)
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppenumAdvise = NULL;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (!This->oleAdviseHolder)
|
2007-04-20 12:23:52 +00:00
|
|
|
return S_OK;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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;
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-11-20 15:01:10 +00:00
|
|
|
return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (FAILED(hres))
|
|
|
|
*pdwStatus = 0;
|
|
|
|
|
2009-01-18 19:23:59 +00:00
|
|
|
return hres;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
2005-12-12 23:53:06 +00:00
|
|
|
* DefaultHandler_SetColorScheme (IOleObject)
|
2005-07-31 12:11:56 +00:00
|
|
|
*
|
|
|
|
* 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)
|
|
|
|
{
|
2005-12-12 23:53:06 +00:00
|
|
|
DefaultHandler *This = impl_from_IOleObject(iface);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
TRACE("(%p, %p))\n", iface, pLogpal);
|
2005-12-12 23:53:06 +00:00
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-12-12 23:53:06 +00:00
|
|
|
return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IDataObject_AddRef (IUnknown)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IUnknown methods.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
|
|
|
|
IDataObject* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_AddRef(This->outerUnknown);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IDataObject_Release (IUnknown)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IUnknown methods.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DefaultHandler_IDataObject_Release(
|
|
|
|
IDataObject* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_Release(This->outerUnknown);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
hres = IUnknown_QueryInterface(This->dataCache,
|
2005-07-31 12:11:56 +00:00
|
|
|
&IID_IDataObject,
|
|
|
|
(void**)&cacheDataObject);
|
|
|
|
|
|
|
|
if (FAILED(hres))
|
|
|
|
return E_UNEXPECTED;
|
|
|
|
|
|
|
|
hres = IDataObject_GetData(cacheDataObject,
|
|
|
|
pformatetcIn,
|
|
|
|
pmedium);
|
|
|
|
|
|
|
|
IDataObject_Release(cacheDataObject);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (FAILED(hres) && This->pDataDelegate)
|
|
|
|
hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
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;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", iface, pformatetc);
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
hres = IUnknown_QueryInterface(This->dataCache,
|
2005-07-31 12:11:56 +00:00
|
|
|
&IID_IDataObject,
|
|
|
|
(void**)&cacheDataObject);
|
|
|
|
|
|
|
|
if (FAILED(hres))
|
|
|
|
return E_UNEXPECTED;
|
|
|
|
|
|
|
|
hres = IDataObject_QueryGetData(cacheDataObject,
|
|
|
|
pformatetc);
|
|
|
|
|
|
|
|
IDataObject_Release(cacheDataObject);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (FAILED(hres) && This->pDataDelegate)
|
|
|
|
hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
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,
|
2005-11-20 15:01:10 +00:00
|
|
|
LPFORMATETC pformatetcIn,
|
2005-07-31 12:11:56 +00:00
|
|
|
LPFORMATETC pformatetcOut)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
if (!This->pDataDelegate)
|
2005-11-20 15:01:10 +00:00
|
|
|
return OLE_E_NOTRUNNING;
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
IDataObject* cacheDataObject = NULL;
|
|
|
|
HRESULT hres;
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
hres = IUnknown_QueryInterface(This->dataCache,
|
2005-07-31 12:11:56 +00:00
|
|
|
&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)
|
|
|
|
*
|
2005-11-20 15:01:10 +00:00
|
|
|
* The default handler's implementation of This method simply delegates
|
2005-07-31 12:11:56 +00:00
|
|
|
* to OleRegEnumFormatEtc.
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IDataObject methods.
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
|
|
|
|
IDataObject* iface,
|
|
|
|
DWORD dwDirection,
|
|
|
|
IEnumFORMATETC** ppenumFormatEtc)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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;
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %p, %d, %p, %p)\n",
|
2005-07-31 12:11:56 +00:00
|
|
|
iface, pformatetc, advf, pAdvSink, pdwConnection);
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* Make sure we have a data advise holder before we start. */
|
|
|
|
if (!This->dataAdviseHolder)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
|
2007-04-20 12:23:52 +00:00
|
|
|
if (SUCCEEDED(hres) && This->pDataDelegate)
|
|
|
|
DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
if (SUCCEEDED(hres))
|
2005-11-20 15:01:10 +00:00
|
|
|
hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
TRACE("(%p, %d)\n", iface, dwConnection);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we don't have a data advise holder yet, it means that
|
|
|
|
* we don't have any connections..
|
|
|
|
*/
|
2005-11-20 15:01:10 +00:00
|
|
|
if (!This->dataAdviseHolder)
|
2005-07-31 12:11:56 +00:00
|
|
|
return OLE_E_NOCONNECTION;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IDataObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
TRACE("(%p, %p)\n", iface, ppenumAdvise);
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
if (!ppenumAdvise)
|
2005-07-31 12:11:56 +00:00
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppenumAdvise = NULL;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* If we have a data advise holder object, delegate. */
|
|
|
|
if (This->dataAdviseHolder)
|
|
|
|
return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
|
2005-07-31 12:11:56 +00:00
|
|
|
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)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IRunnableObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
2008-01-14 15:45:45 +00:00
|
|
|
* DefaultHandler_IRunnableObject_AddRef (IUnknown)
|
2005-07-31 12:11:56 +00:00
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IUnknown methods.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
|
|
|
|
IRunnableObject* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IRunnableObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_AddRef(This->outerUnknown);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
2008-01-14 15:45:45 +00:00
|
|
|
* DefaultHandler_IRunnableObject_Release (IUnknown)
|
2005-07-31 12:11:56 +00:00
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IUnknown methods.
|
|
|
|
*/
|
|
|
|
static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
|
|
|
|
IRunnableObject* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IRunnableObject(iface);
|
2005-07-31 12:11:56 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return IUnknown_Release(This->outerUnknown);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_GetRunningClass (IRunnableObject)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IRunnableObject methods.
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_GetRunningClass(
|
|
|
|
IRunnableObject* iface,
|
|
|
|
LPCLSID lpClsid)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
FIXME("()\n");
|
2005-07-31 12:11:56 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT WINAPI DefaultHandler_Run(
|
|
|
|
IRunnableObject* iface,
|
|
|
|
IBindCtx* pbc)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IRunnableObject(iface);
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
FIXME("(%p): semi-stub\n", pbc);
|
|
|
|
|
|
|
|
/* already running? if so nothing to do */
|
2008-01-14 15:45:45 +00:00
|
|
|
if (object_is_running(This))
|
2005-11-20 15:01:10 +00:00
|
|
|
return S_OK;
|
|
|
|
|
2009-01-15 17:52:35 +00:00
|
|
|
release_delegates(This);
|
|
|
|
|
2005-12-12 23:53:06 +00:00
|
|
|
hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER,
|
|
|
|
&IID_IOleObject, (void **)&This->pOleDelegate);
|
2005-11-20 15:01:10 +00:00
|
|
|
if (FAILED(hr))
|
|
|
|
return hr;
|
|
|
|
|
2009-01-15 17:52:35 +00:00
|
|
|
This->object_state = object_state_running;
|
|
|
|
|
2005-12-12 23:53:06 +00:00
|
|
|
hr = IOleObject_Advise(This->pOleDelegate,
|
|
|
|
(IAdviseSink *)&This->lpvtblIAdviseSink,
|
|
|
|
&This->dwAdvConn);
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
if (SUCCEEDED(hr) && This->clientSite)
|
|
|
|
hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2005-12-12 23:53:06 +00:00
|
|
|
IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
|
|
|
|
(void **)&This->pPSDelegate);
|
2005-11-20 15:01:10 +00:00
|
|
|
if (This->pPSDelegate)
|
2008-11-07 11:00:30 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2005-11-20 15:01:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr) && This->containerApp)
|
2005-12-12 23:53:06 +00:00
|
|
|
hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
|
|
|
|
This->containerObj);
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
/* FIXME: do more stuff here:
|
|
|
|
* - IOleObject_GetMiscStatus
|
|
|
|
* - IOleObject_GetMoniker
|
|
|
|
* - IOleCache_OnRun
|
|
|
|
*/
|
|
|
|
|
2005-12-12 23:53:06 +00:00
|
|
|
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))
|
2009-01-15 17:52:35 +00:00
|
|
|
{
|
2005-12-12 23:53:06 +00:00
|
|
|
DefaultHandler_Stop(This);
|
2009-01-15 17:52:35 +00:00
|
|
|
release_delegates(This);
|
|
|
|
}
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
return hr;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IsRunning (IRunnableObject)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IRunnableObject methods.
|
|
|
|
*/
|
|
|
|
static BOOL WINAPI DefaultHandler_IsRunning(
|
|
|
|
IRunnableObject* iface)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
DefaultHandler *This = impl_from_IRunnableObject(iface);
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
TRACE("()\n");
|
2005-11-20 15:01:10 +00:00
|
|
|
|
2009-01-15 17:52:35 +00:00
|
|
|
if (This->object_state == object_state_running)
|
2005-11-20 15:01:10 +00:00
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_LockRunning (IRunnableObject)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IRunnableObject methods.
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_LockRunning(
|
|
|
|
IRunnableObject* iface,
|
|
|
|
BOOL fLock,
|
|
|
|
BOOL fLastUnlockCloses)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
FIXME("()\n");
|
2005-07-31 12:11:56 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_SetContainedObject (IRunnableObject)
|
|
|
|
*
|
|
|
|
* See Windows documentation for more details on IRunnableObject methods.
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_SetContainedObject(
|
|
|
|
IRunnableObject* iface,
|
|
|
|
BOOL fContained)
|
|
|
|
{
|
2005-11-20 15:01:10 +00:00
|
|
|
FIXME("()\n");
|
2005-07-31 12:11:56 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
|
|
|
|
IAdviseSink *iface,
|
|
|
|
REFIID riid,
|
|
|
|
void **ppvObject)
|
|
|
|
{
|
|
|
|
if (IsEqualIID(riid, &IID_IUnknown) ||
|
|
|
|
IsEqualIID(riid, &IID_IAdviseSink))
|
|
|
|
{
|
|
|
|
*ppvObject = iface;
|
|
|
|
IAdviseSink_AddRef(iface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
|
|
|
|
IAdviseSink *iface)
|
|
|
|
{
|
|
|
|
DefaultHandler *This = impl_from_IAdviseSink(iface);
|
|
|
|
|
|
|
|
return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
|
|
|
|
IAdviseSink *iface)
|
|
|
|
{
|
|
|
|
DefaultHandler *This = impl_from_IAdviseSink(iface);
|
|
|
|
|
|
|
|
return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
|
|
|
|
IAdviseSink *iface,
|
|
|
|
FORMATETC *pFormatetc,
|
|
|
|
STGMEDIUM *pStgmed)
|
|
|
|
{
|
|
|
|
FIXME(": stub\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
|
|
|
|
IAdviseSink *iface,
|
|
|
|
DWORD dwAspect,
|
|
|
|
LONG lindex)
|
|
|
|
{
|
|
|
|
FIXME(": stub\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void WINAPI DefaultHandler_IAdviseSink_OnRename(
|
|
|
|
IAdviseSink *iface,
|
|
|
|
IMoniker *pmk)
|
|
|
|
{
|
|
|
|
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);
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
TRACE("()\n");
|
|
|
|
|
|
|
|
if (This->oleAdviseHolder)
|
|
|
|
IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
|
|
|
|
|
|
|
|
DefaultHandler_Stop(This);
|
|
|
|
}
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* 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)
|
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
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);
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
return hr;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IPersistStorage_IsDirty
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
|
|
|
|
IPersistStorage* iface)
|
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
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);
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
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;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IPersistStorage_InitNew
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
|
|
|
|
IPersistStorage* iface,
|
|
|
|
IStorage* pStg)
|
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
DefaultHandler *This = impl_from_IPersistStorage(iface);
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", iface, pStg);
|
|
|
|
init_ole_stream(pStg);
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
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;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IPersistStorage_Load
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
|
|
|
|
IPersistStorage* iface,
|
|
|
|
IStorage* pStg)
|
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
DefaultHandler *This = impl_from_IPersistStorage(iface);
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
|
|
TRACE("(%p)->(%p)\n", iface, pStg);
|
|
|
|
|
|
|
|
hr = load_ole_stream(This, pStg);
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
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;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IPersistStorage_Save
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
|
|
|
|
IPersistStorage* iface,
|
|
|
|
IStorage* pStgSave,
|
2008-11-07 11:00:30 +00:00
|
|
|
BOOL fSameAsLoad)
|
2008-01-14 15:45:45 +00:00
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
DefaultHandler *This = impl_from_IPersistStorage(iface);
|
|
|
|
HRESULT hr;
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
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;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IPersistStorage_SaveCompleted
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
|
|
|
|
IPersistStorage* iface,
|
|
|
|
IStorage* pStgNew)
|
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
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;
|
|
|
|
}
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
return hr;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* DefaultHandler_IPersistStorage_HandsOffStorage
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
|
|
|
|
IPersistStorage* iface)
|
|
|
|
{
|
2008-11-07 11:00:30 +00:00
|
|
|
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);
|
2008-01-14 15:45:45 +00:00
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
if(This->storage) IStorage_Release(This->storage);
|
|
|
|
This->storage = NULL;
|
|
|
|
This->storage_state = storage_state_uninitialised;
|
|
|
|
|
|
|
|
return hr;
|
2008-01-14 15:45:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
};
|
|
|
|
|
2008-01-14 15:45:45 +00:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/*********************************************************
|
|
|
|
* Methods implementation for the DefaultHandler class.
|
|
|
|
*/
|
|
|
|
static DefaultHandler* DefaultHandler_Construct(
|
|
|
|
REFCLSID clsid,
|
2009-08-24 10:51:15 +00:00
|
|
|
LPUNKNOWN pUnkOuter,
|
|
|
|
DWORD flags,
|
|
|
|
IClassFactory *pCF)
|
2005-11-20 15:01:10 +00:00
|
|
|
{
|
|
|
|
DefaultHandler* This = NULL;
|
2008-01-14 15:45:45 +00:00
|
|
|
HRESULT hr;
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
|
|
|
|
|
|
|
|
if (!This)
|
|
|
|
return This;
|
|
|
|
|
|
|
|
This->lpVtbl = &DefaultHandler_IOleObject_VTable;
|
|
|
|
This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
|
|
|
|
This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
|
|
|
|
This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
|
|
|
|
This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
|
2008-01-14 15:45:45 +00:00
|
|
|
This->lpvtblIPersistStorage = &DefaultHandler_IPersistStorage_VTable;
|
2005-11-20 15:01:10 +00:00
|
|
|
|
2009-08-24 10:51:15 +00:00
|
|
|
This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) ? TRUE : FALSE;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/*
|
|
|
|
* 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
|
2008-01-14 15:45:45 +00:00
|
|
|
* aggregation works, our lifetime is at least as large as its
|
2005-11-20 15:01:10 +00:00
|
|
|
* lifetime.
|
|
|
|
*/
|
|
|
|
if (!pUnkOuter)
|
|
|
|
pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
|
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
2008-01-14 15:45:45 +00:00
|
|
|
hr = CreateDataCache(This->outerUnknown,
|
|
|
|
clsid,
|
|
|
|
&IID_IUnknown,
|
|
|
|
(void**)&This->dataCache);
|
|
|
|
if(SUCCEEDED(hr))
|
2010-03-10 14:28:56 +00:00
|
|
|
{
|
2008-01-14 15:45:45 +00:00
|
|
|
hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg);
|
2010-03-10 14:28:56 +00:00
|
|
|
/* 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);
|
|
|
|
}
|
2008-01-14 15:45:45 +00:00
|
|
|
if(FAILED(hr))
|
2010-03-10 14:28:56 +00:00
|
|
|
{
|
2008-01-14 15:45:45 +00:00
|
|
|
ERR("Unexpected error creating data cache\n");
|
2010-03-10 14:28:56 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-11-07 11:00:30 +00:00
|
|
|
|
2008-07-10 09:14:19 +00:00
|
|
|
This->clsid = *clsid;
|
2005-11-20 15:01:10 +00:00
|
|
|
This->clientSite = NULL;
|
|
|
|
This->oleAdviseHolder = NULL;
|
|
|
|
This->dataAdviseHolder = NULL;
|
|
|
|
This->containerApp = NULL;
|
|
|
|
This->containerObj = NULL;
|
|
|
|
This->pOleDelegate = NULL;
|
|
|
|
This->pPSDelegate = NULL;
|
2005-12-12 23:53:06 +00:00
|
|
|
This->pDataDelegate = NULL;
|
2009-01-15 17:52:35 +00:00
|
|
|
This->object_state = object_state_not_running;
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
This->dwAdvConn = 0;
|
2008-11-07 11:00:30 +00:00
|
|
|
This->storage = NULL;
|
|
|
|
This->storage_state = storage_state_uninitialised;
|
2005-11-20 15:01:10 +00:00
|
|
|
|
2009-08-24 10:51:15 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
return This;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DefaultHandler_Destroy(
|
|
|
|
DefaultHandler* This)
|
|
|
|
{
|
2010-03-10 14:28:56 +00:00
|
|
|
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;
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
/* release delegates */
|
|
|
|
DefaultHandler_Stop(This);
|
2009-01-15 17:52:35 +00:00
|
|
|
release_delegates(This);
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
HeapFree( GetProcessHeap(), 0, This->containerApp );
|
|
|
|
This->containerApp = NULL;
|
|
|
|
HeapFree( GetProcessHeap(), 0, This->containerObj );
|
|
|
|
This->containerObj = NULL;
|
|
|
|
|
|
|
|
if (This->dataCache)
|
|
|
|
{
|
2010-03-10 14:28:56 +00:00
|
|
|
/* to balance out the release of dataCache_PersistStg which will result
|
|
|
|
* in a reference being released from the outer unknown */
|
|
|
|
IUnknown_AddRef(This->outerUnknown);
|
2008-01-14 15:45:45 +00:00
|
|
|
IPersistStorage_Release(This->dataCache_PersistStg);
|
2005-11-20 15:01:10 +00:00
|
|
|
IUnknown_Release(This->dataCache);
|
2008-01-14 15:45:45 +00:00
|
|
|
This->dataCache_PersistStg = NULL;
|
2005-11-20 15:01:10 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-11-07 11:00:30 +00:00
|
|
|
if (This->storage)
|
|
|
|
{
|
|
|
|
IStorage_Release(This->storage);
|
|
|
|
This->storage = NULL;
|
|
|
|
}
|
|
|
|
|
2009-08-24 10:51:15 +00:00
|
|
|
if (This->pCFObject)
|
|
|
|
{
|
|
|
|
IClassFactory_Release(This->pCFObject);
|
|
|
|
This->pCFObject = NULL;
|
|
|
|
}
|
|
|
|
|
2005-11-20 15:01:10 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
2009-08-24 10:51:15 +00:00
|
|
|
* OleCreateEmbeddingHelper [OLE32.@]
|
2005-11-20 15:01:10 +00:00
|
|
|
*/
|
2009-08-24 10:51:15 +00:00
|
|
|
HRESULT WINAPI OleCreateEmbeddingHelper(
|
2005-11-20 15:01:10 +00:00
|
|
|
REFCLSID clsid,
|
|
|
|
LPUNKNOWN pUnkOuter,
|
2009-08-24 10:51:15 +00:00
|
|
|
DWORD flags,
|
|
|
|
IClassFactory *pCF,
|
2005-11-20 15:01:10 +00:00
|
|
|
REFIID riid,
|
|
|
|
LPVOID* ppvObj)
|
|
|
|
{
|
|
|
|
DefaultHandler* newHandler = NULL;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
2009-08-24 10:51:15 +00:00
|
|
|
TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj);
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
2009-08-24 10:51:15 +00:00
|
|
|
newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF);
|
2005-11-20 15:01:10 +00:00
|
|
|
|
|
|
|
if (!newHandler)
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure it supports the interface required by the caller.
|
|
|
|
*/
|
|
|
|
hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Release the reference obtained in the constructor. If
|
|
|
|
* the QueryInterface was unsuccessful, it will free the class.
|
|
|
|
*/
|
|
|
|
IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
2009-08-24 10:51:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* 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);
|
|
|
|
}
|
2010-03-10 14:28:56 +00:00
|
|
|
|
|
|
|
typedef struct HandlerCF
|
|
|
|
{
|
|
|
|
const IClassFactoryVtbl *lpVtbl;
|
|
|
|
LONG refs;
|
|
|
|
CLSID clsid;
|
|
|
|
} HandlerCF;
|
|
|
|
|
|
|
|
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 = (HandlerCF *)iface;
|
|
|
|
return InterlockedIncrement(&This->refs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
|
|
|
|
{
|
|
|
|
HandlerCF *This = (HandlerCF *)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 = (HandlerCF *)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->lpVtbl = &HandlerClassFactoryVtbl;
|
|
|
|
This->refs = 0;
|
|
|
|
This->clsid = *rclsid;
|
|
|
|
|
|
|
|
hr = IUnknown_QueryInterface((IUnknown *)&This->lpVtbl, riid, ppv);
|
|
|
|
if (FAILED(hr))
|
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|