windows-nt/Source/XPSP1/NT/com/ole32/actprops/propifs.cxx
2020-09-26 16:20:57 +08:00

1531 lines
44 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: propifs.cxx
//
// Contents: Activation Functions used by object servers.
//
// Functions: Implements classes in propifs.hxx
//
// History: 24-Jan-98 Vinaykr Created
//
///--------------------------------------------------------------------------
#include <ole2int.h>
#include <context.hxx>
#include <actprops.hxx>
#include <serial.hxx>
#include <hash.hxx>
//---------------------------------------------------------------------------
// This file contains implementations of serializable
// interfaces
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Methods for InstantiationInfo
//---------------------------------------------------------------------------
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP InstantiationInfo::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP InstantiationInfo::SerializableQueryInterface( REFIID riid, LPVOID* ppvObj)
{
//Use IID_InstantiationInfo to return the real object right now
if (IsEqualIID(riid, IID_IInstantiationInfo))
{
*ppvObj = (InstantiationInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IInstantiationInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG InstantiationInfo::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG InstantiationInfo::Release(void)
{
if (_parent)
return _parent->Release();
return 0;
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP InstantiationInfo::Serialize(void *pv)
{
HRESULT hr;
Serializer *pSer = (Serializer*) pv;
handle_t handle;
hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
InstantiationInfoData_Encode(handle, &_instantiationInfoData);
return S_OK;
}
STDMETHODIMP InstantiationInfo::UnSerialize(void *pv)
{
Serializer *pSer = (Serializer*) pv;
if (!_unSerialized)
{
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
_instantiationInfoData.pIID = 0;
InstantiationInfoData_Decode(handle, &_instantiationInfoData);
_unSerialized = TRUE;
}
return S_OK;
}
STDMETHODIMP InstantiationInfo::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
Serializer *pSer = (Serializer*) pv;
if (!IsInproc(pSer))
{
handle_t handle;
HRESULT hr = pSer->GetSizingHandle((void*) &handle);
if (FAILED(hr))
return hr;
*pdwSize = InstantiationInfoData_AlignSize(handle,
&_instantiationInfoData);
MesHandleFree(handle);
_instantiationInfoData.thisSize = *pdwSize;
}
else
*pdwSize = 0;
return S_OK;
}
STDMETHODIMP InstantiationInfo::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_IInstantiationInfo;
return S_OK;
}
//---------------------------------------------------------------------------
// Methods for ServerLocationInfo
//---------------------------------------------------------------------------
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP ServerLocationInfo::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP ServerLocationInfo::SerializableQueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (IsEqualIID(riid, IID_IServerLocationInfo) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IServerLocationInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG ServerLocationInfo::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG ServerLocationInfo::Release(void)
{
if (_parent)
return _parent->Release();
return 0;
}
//-----------------------------------------------------------------------
// Constructor/destructor
//-----------------------------------------------------------------------
ServerLocationInfo::ServerLocationInfo()
{
ZeroMemory(&_locationInfoData, sizeof(LocationInfoData));
_pObjectContext = NULL;
_pISSP = NULL;
}
ServerLocationInfo::~ServerLocationInfo()
{
if (_locationInfoData.machineName)
ActMemFree(_locationInfoData.machineName);
if (_pObjectContext)
_pObjectContext->InternalRelease();
// do not release _pISSP
}
//-----------------------------------------------------------------------
// Methods
//-----------------------------------------------------------------------
STDMETHODIMP ServerLocationInfo::SetRemoteServerName(IN WCHAR *pwszMachineName)
{
HRESULT hr;
if (_locationInfoData.machineName)
{
ActMemFree(_locationInfoData.machineName);
_locationInfoData.machineName = NULL;
}
Win4Assert(_locationInfoData.machineName == NULL);
if (pwszMachineName)
{
//
// Some apps may unnecessarily put slashes before their
// server names. We'll allow this and strip them off.
//
if (pwszMachineName[0] == L'\\' &&
pwszMachineName[1] == L'\\' )
pwszMachineName += 2;
if ( 0 == *pwszMachineName)
return CO_E_BAD_SERVER_NAME;
BOOL fIsSelf;
_locationInfoData.machineName =
makeWStringCopy(pwszMachineName);
if (_locationInfoData.machineName == NULL)
return E_OUTOFMEMORY;
}
return S_OK;
}
STDMETHODIMP ServerLocationInfo::SetProcess(IN DWORD processId, OUT DWORD dwPRT)
{
HRESULT hr;
ISpecialSystemProperties* pISSP = NULL;
// This is necessary since we didn't want to break the wire-format
// after RC2. If it wasn't for that, we could have put the storage for
// dwPRT right into _locationInfoData.
// Note: calling this method before this object is aggregated into the
// actpropsin object means that this QI will fail (see
// ServerLocationInfo::QueryInterface up above, _pParent will still be NULL)
hr = this->QueryInterface(IID_ISpecialSystemProperties, (void**)&pISSP);
if (SUCCEEDED(hr))
{
hr = pISSP->SetProcessRequestType(dwPRT);
if (SUCCEEDED(hr))
{
_locationInfoData.processId = processId;
}
pISSP->Release();
}
return hr;
}
STDMETHODIMP ServerLocationInfo::GetProcess(OUT DWORD *pProcessId, OUT DWORD* pdwPRT)
{
HRESULT hr;
ISpecialSystemProperties* pISSP = NULL;
// This is necessary since we didn't want to break the wire-format
// after RC2. If it wasn't for that, we could have put the storage for
// dwPRT right into _locationInfoData.
// Note: calling this method before this object is aggregated into the
// actpropsin object means that this QI will fail (see
// ServerLocationInfo::QueryInterface up above, _pParent will still be NULL)
hr = this->QueryInterface(IID_ISpecialSystemProperties, (void**)&pISSP);
if (SUCCEEDED(hr))
{
hr = pISSP->GetProcessRequestType(pdwPRT);
if (SUCCEEDED(hr))
{
*pProcessId = _locationInfoData.processId;
}
pISSP->Release();
}
return hr;
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP ServerLocationInfo::Serialize(void *pv)
{
Serializer *pSer = (Serializer*) pv;
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
LocationInfoData_Encode(handle, &_locationInfoData);
return S_OK;
}
STDMETHODIMP ServerLocationInfo::UnSerialize(void *pv)
{
Serializer *pSer = (Serializer*) pv;
if (!_unSerialized)
{
_locationInfoData.machineName=0;
handle_t handle;
pSer->GetSerializationHandle((void*) &handle);
LocationInfoData_Decode(handle, &_locationInfoData);
_unSerialized = TRUE;
}
return S_OK;
}
STDMETHODIMP ServerLocationInfo::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
Serializer *pSer = (Serializer*) pv;
if (!IsInproc(pSer))
{
handle_t handle;
HRESULT hr = pSer->GetSizingHandle((void*) &handle);
if (FAILED(hr))
return hr;
*pdwSize = LocationInfoData_AlignSize(handle, &_locationInfoData);
MesHandleFree(handle);
}
else
*pdwSize = 0;
return S_OK;
}
STDMETHODIMP ServerLocationInfo::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_IServerLocationInfo;
return S_OK;
}
//---------------------------------------------------------------------------
// Methods for SecurityInfo
//---------------------------------------------------------------------------
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP SecurityInfo::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP SecurityInfo::SerializableQueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (IsEqualIID(riid, IID_IActivationSecurityInfo) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IActivationSecurityInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ILegacyInfo))
{
*ppvObj = (ILegacyInfo*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG SecurityInfo::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG SecurityInfo::Release(void)
{
if (_parent)
return _parent->Release();
return 0;
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP SecurityInfo::Serialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
SecurityInfoData_Encode(handle, &_securityInfoData);
return S_OK;
}
STDMETHODIMP SecurityInfo::UnSerialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
if (!_unSerialized)
{
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
_securityInfoData.pServerInfo = 0;
_securityInfoData.pAuthIdentityInfo = 0;
SecurityInfoData_Decode(handle, &_securityInfoData);
_unSerialized = TRUE;
}
return S_OK;
}
STDMETHODIMP SecurityInfo::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
Serializer *pSer = (Serializer*) pv;
if (!IsInproc(pSer))
{
handle_t handle;
HRESULT hr = pSer->GetSizingHandle((void*) &handle);
if (FAILED(hr))
return hr;
*pdwSize = SecurityInfoData_AlignSize(handle, &_securityInfoData);
MesHandleFree(handle);
}
else
*pdwSize = 0;
return S_OK;
}
STDMETHODIMP SecurityInfo::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_IActivationSecurityInfo;
return S_OK;
}
//---------------------------------------------------------------------------
// Methods for ScmRequestInfo
//---------------------------------------------------------------------------
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP ScmRequestInfo::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP ScmRequestInfo::SerializableQueryInterface( REFIID riid, LPVOID*
ppvObj)
{
if (IsEqualIID(riid, IID_IScmRequestInfo) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IScmRequestInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG ScmRequestInfo::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG ScmRequestInfo::Release(void)
{
if (_parent)
return _parent->Release();
#if 0 //Always allocate on stack
ULONG count;
if ((count=InterlockedDecrement(&_cRefs)) == 0)
{
delete this;
return 0;
}
return count;
#else
return 0;
#endif
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP ScmRequestInfo::Serialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
ScmRequestInfoData_Encode(handle, &_scmRequestInfoData);
return S_OK;
}
STDMETHODIMP ScmRequestInfo::UnSerialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
if (!_unSerialized)
{
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
_scmRequestInfoData.pScmInfo = 0;
_scmRequestInfoData.remoteRequest = 0;
ScmRequestInfoData_Decode(handle, &_scmRequestInfoData);
_unSerialized = TRUE;
}
return S_OK;
}
STDMETHODIMP ScmRequestInfo::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
Serializer *pSer = (Serializer*) pv;
if (!IsInproc(pSer))
{
handle_t handle;
HRESULT hr = pSer->GetSizingHandle((void*) &handle);
if (FAILED(hr))
return hr;
*pdwSize = ScmRequestInfoData_AlignSize(handle, &_scmRequestInfoData);
MesHandleFree(handle);
}
else
*pdwSize = 0;
return S_OK;
}
STDMETHODIMP ScmRequestInfo::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_IScmRequestInfo;
return S_OK;
}
//---------------------------------------------------------------------------
// Methods for ScmReplyInfo
//---------------------------------------------------------------------------
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP ScmReplyInfo::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP ScmReplyInfo::SerializableQueryInterface( REFIID riid, LPVOID*
ppvObj)
{
if (IsEqualIID(riid, IID_IScmReplyInfo) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IScmReplyInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG ScmReplyInfo::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG ScmReplyInfo::Release(void)
{
if (_parent)
return _parent->Release();
#if 0 //Always allocate on stack
ULONG count;
if ((count=InterlockedDecrement(&_cRefs)) == 0)
{
delete this;
return 0;
}
return count;
#else
return 0;
#endif
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP ScmReplyInfo::Serialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
ScmReplyInfoData_Encode(handle, &_scmReplyInfoData);
return S_OK;
}
STDMETHODIMP ScmReplyInfo::UnSerialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
if (!_unSerialized)
{
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
_scmReplyInfoData.remoteReply = 0;
_scmReplyInfoData.pResolverInfo = 0;
ScmReplyInfoData_Decode(handle, &_scmReplyInfoData);
_unSerialized = TRUE;
}
return S_OK;
}
STDMETHODIMP ScmReplyInfo::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
Serializer *pSer = (Serializer*) pv;
handle_t handle;
HRESULT hr = pSer->GetSizingHandle((void*) &handle);
if (FAILED(hr))
return hr;
*pdwSize = ScmReplyInfoData_AlignSize(handle, &_scmReplyInfoData);
MesHandleFree(handle);
return S_OK;
}
STDMETHODIMP ScmReplyInfo::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_IScmReplyInfo;
return S_OK;
}
//---------------------------------------------------------------------------
// Methods for ContextInfo
//---------------------------------------------------------------------------
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP ContextInfo::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP ContextInfo::SerializableQueryInterface(REFIID riid,
LPVOID* ppvObj)
{
if (IsEqualIID(riid, IID_IPrivActivationContextInfo))
{
*ppvObj = (IPrivActivationContextInfo*) this;
AddRef();
return S_OK;
}
else if (IsEqualIID(riid, IID_IActivationContextInfo)
|| IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IActivationContextInfo*) this;
AddRef();
return S_OK;
}
else if (IsEqualIID(riid, IID_IOverrideTargetContext))
{
*ppvObj = (IOverrideTargetContext*) this;
AddRef();
return S_OK;
}
else if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG ContextInfo::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG ContextInfo::Release(void)
{
if (_parent)
return _parent->Release();
return 0;
}
HRESULT ContextInfo::GetClientContext(OUT IContext **ppCtx)
{
CObjectContext *pCtx;
HRESULT hr = GetInternalClientContext(&pCtx);
if (SUCCEEDED(hr) && pCtx)
{
pCtx->AddRef();
pCtx->InternalRelease();
*ppCtx = (IContext*)pCtx;
}
return hr;
}
HRESULT ContextInfo::GetInternalClientContext(OUT CObjectContext **ppCtx)
{
HRESULT hr = S_OK;
InitMarshalling();
if ((_unSerialized) &&
(_pClientCtx==NULL) &&
(_contextInfoData.pIFDClientCtx != NULL))
{
if (pfnCoUnmarshalInterface)
{
ActivationStream stream((InterfaceData*)_contextInfoData.pIFDClientCtx);
hr = pfnCoUnmarshalInterface(&stream,
IID_IStdObjectContext,
(void**)&_pClientCtx);
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
}
if (SUCCEEDED(hr))
{
// Unmarshaling the context gives a user reference. We want
// an internal ref, so we take one and release the user ref.
_pClientCtx->InternalAddRef();
_pClientCtx->Release();
}
ActMemFree(_contextInfoData.pIFDClientCtx);
_contextInfoData.pIFDClientCtx = NULL;
}
if (_pClientCtx)
_pClientCtx->InternalAddRef();
else
SetClientContextNotOK();
*ppCtx = _pClientCtx;
return hr;
}
STDMETHODIMP ContextInfo::GetPrototypeContext(OUT IContext **ppCtx)
{
CObjectContext *pCtx;
HRESULT hr = GetInternalPrototypeContext(&pCtx);
if (SUCCEEDED(hr))
{
pCtx->AddRef();
pCtx->InternalRelease();
*ppCtx = (IContext*)pCtx;
}
return hr;
}
HRESULT ContextInfo::GetInternalPrototypeContext(OUT CObjectContext **ppCtx)
{
extern HRESULT CObjectContextCF_CreateInstance(IUnknown *pUnkOuter,
REFIID riid,
void** ppv);
InitMarshalling();
HRESULT hr = S_OK;
if ((_unSerialized) &&
(_pPrototypeCtx==NULL) &&
(_contextInfoData.pIFDPrototypeCtx != NULL))
{
if (pfnCoUnmarshalInterface)
{
ActivationStream stream((InterfaceData*)_contextInfoData.pIFDPrototypeCtx);
hr = pfnCoUnmarshalInterface(&stream,
IID_IStdObjectContext,
(void**)&_pPrototypeCtx);
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
}
if (SUCCEEDED(hr))
{
// Unmarshaling the context gives a user reference. We want
// an internal ref, so we take one and release the user ref.
_pPrototypeCtx->InternalAddRef();
_pPrototypeCtx->Release();
}
ActMemFree(_contextInfoData.pIFDPrototypeCtx);
_contextInfoData.pIFDPrototypeCtx = NULL;
}
else
if (!_pPrototypeCtx)
{
hr = CObjectContextCF_CreateInstance(NULL,
IID_IStdObjectContext,
(void**) &_pPrototypeCtx);
if (SUCCEEDED(hr))
{
// Creating the context gives a user reference. We want
// an internal ref, so we take one and release the user ref.
_pPrototypeCtx->InternalAddRef();
_pPrototypeCtx->Release();
}
}
if (SUCCEEDED(hr))
_pPrototypeCtx->InternalAddRef();
*ppCtx = _pPrototypeCtx;
return hr;
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP ContextInfo::Serialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
//-------------------------------------------------------------------
// Encode header
//-------------------------------------------------------------------
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
ActivationContextInfoData_Encode(handle, &_contextInfoData);
_unSerialized = FALSE;
return S_OK;
}
STDMETHODIMP ContextInfo::UnSerialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
if (!_unSerialized)
{
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
_pClientCtx = 0;
_pPrototypeCtx = 0;
ActivationContextInfoData_Decode(handle, &_contextInfoData);
_unSerialized = TRUE;
}
return S_OK;
}
STDMETHODIMP ContextInfo::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
Serializer *pSer = (Serializer*) pv;
HRESULT rethr=S_OK;
//--------------------------------------------------------------------
// If Is an inproc path, no need to marshal context
//--------------------------------------------------------------------
if (IsInproc(pSer))
{
*pdwSize = 0;
return S_OK;
}
_toReleaseIFD = FALSE;
if (_pClientCtx)
{
rethr = GetIFDFromInterface((IUnknown*)(IObjContext*) _pClientCtx,
IID_IContext,
MSHCTX_DIFFERENTMACHINE,
MSHLFLAGS_NORMAL,
&_contextInfoData.pIFDClientCtx);
if (FAILED(rethr))
{
_contextInfoData.pIFDClientCtx = NULL;
return rethr;
}
}
if (_pPrototypeCtx)
{
rethr = GetIFDFromInterface((IUnknown*)(IObjContext*) _pPrototypeCtx,
IID_IContext,
MSHCTX_DIFFERENTMACHINE,
MSHLFLAGS_NORMAL,
&_contextInfoData.pIFDPrototypeCtx);
if (FAILED(rethr))
{
_contextInfoData.pIFDPrototypeCtx = NULL;
return rethr;
}
}
handle_t handle;
rethr = pSer->GetSizingHandle((void*) &handle);
if (SUCCEEDED(rethr))
{
*pdwSize = ActivationContextInfoData_AlignSize(handle,
&_contextInfoData);
MesHandleFree(handle);
}
return rethr;
}
STDMETHODIMP ContextInfo::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_IActivationContextInfo;
return S_OK;
}
//---------------------------------------------------------------------------
// Methods for InstanceInfo
//---------------------------------------------------------------------------
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP InstanceInfo::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP InstanceInfo::SerializableQueryInterface( REFIID riid, LPVOID*
ppvObj)
{
if (IsEqualIID(riid, IID_IInstanceInfo) ||
IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IInstanceInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG InstanceInfo::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG InstanceInfo::Release(void)
{
if (_parent)
return _parent->Release();
#if 0 //Always allocate on stack
ULONG count;
if ((count=InterlockedDecrement(&_cRefs)) == 0)
{
delete this;
return 0;
}
return count;
#else
return 0;
#endif
}
//-----------------------------------------------------------------------
// Methods from IInstanceInfo
//-----------------------------------------------------------------------
STDMETHODIMP InstanceInfo::SetStorage(IN IStorage *pstg)
{
_pstg = pstg;
if (_pstg)
_pstg->AddRef();
return S_OK;
}
STDMETHODIMP InstanceInfo::GetStorage(OUT IStorage **ppstg)
{
HRESULT hr = S_OK;
InitMarshalling();
if ((_pstg==NULL) &&
(_instanceInfoData.ifdStg != NULL))
{
if (pfnCoUnmarshalInterface)
{
ActivationStream stream((InterfaceData*)_instanceInfoData.ifdStg);
hr = pfnCoUnmarshalInterface(&stream, IID_IStorage, (void**)&_pstg);
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
}
}
if (_pstg)
_pstg->AddRef();
*ppstg = _pstg;
return hr;
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP InstanceInfo::Serialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
InstanceInfoData_Encode(handle, &_instanceInfoData);
_unSerialized = FALSE;
return hr;
}
STDMETHODIMP InstanceInfo::UnSerialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
HRESULT hr = S_OK;
if (!_unSerialized)
{
handle_t handle;
hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
InstanceInfoData_Decode(handle, &_instanceInfoData);
_unSerialized = TRUE;
}
return hr;
}
//-----------------------------------------------------------------------
// NOTE: This function should only get called if a storage pointer is
// present during inproc/crossctx marshalling
//-----------------------------------------------------------------------
STDMETHODIMP InstanceInfo::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
Serializer *pSer = (Serializer*) pv;
HRESULT rethr=S_OK;
DWORD dwCurrDestCtx;
pSer->GetCurrDestCtx(&dwCurrDestCtx);
//-------------------------------------------------------------------
//Need to marshal interface first to compute size
//-------------------------------------------------------------------
if (_pstg)
{
//----------------------------------------------------------------
// Need to free previously marshalled data
//----------------------------------------------------------------
if (_instanceInfoData.ifdStg)
ActMemFree(_instanceInfoData.ifdStg);
if (dwCurrDestCtx == MSHCTX_LOCAL)
dwCurrDestCtx = MSHCTX_DIFFERENTMACHINE;
rethr = GetIFDFromInterface((IUnknown*) _pstg,
IID_IStorage,
dwCurrDestCtx,
MSHLFLAGS_NORMAL,
&_instanceInfoData.ifdStg);
if (FAILED(rethr))
{
_instanceInfoData.ifdStg = NULL;
return rethr;
}
_pstg->Release();
_pstg = NULL;
}
if (IsInproc(pSer))
{
*pdwSize = 0;
}
else
{
//-------------------------------------------------------------------
// Encode header
//-------------------------------------------------------------------
handle_t handle;
rethr = pSer->GetSizingHandle((void*) &handle);
if (SUCCEEDED(rethr))
{
*pdwSize = InstanceInfoData_AlignSize(handle,
&_instanceInfoData);
MesHandleFree(handle);
}
}
return rethr;
}
STDMETHODIMP InstanceInfo::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_IInstanceInfo;
return S_OK;
}
//-----------------------------------------------------------------------
// Methods from IOpaqueDataInfo
//-----------------------------------------------------------------------
STDMETHODIMP OpaqueDataInfo::AddOpaqueData (OpaqueData *pData)
{
HRESULT hr;
if (_cOpaqueData == _dwCollSize)
{
OpaqueData *pNew = (OpaqueData*)
ActMemAlloc(sizeof(OpaqueData) *(_dwCollSize+20));
if (pNew == NULL)
{
return E_OUTOFMEMORY;
}
_dwCollSize += 20;
CopyOpaqueData(pNew, _pOpaqueData,
_cOpaqueData, FALSE);
ActMemFree(_pOpaqueData);
_pOpaqueData = pNew;
}
hr = CopyOpaqueData(&_pOpaqueData[_cOpaqueData], pData,
1, TRUE);
if (FAILED(hr))
return hr;
_cOpaqueData++;
return S_OK;
}
STDMETHODIMP OpaqueDataInfo::GetOpaqueData (REFGUID guid,
OpaqueData **pData)
{
for (DWORD i=0; i < _cOpaqueData ; i++)
{
if (_pOpaqueData[i].guid == guid)
{
*pData = &_pOpaqueData[i];
return S_OK;
}
}
return E_FAIL;
}
STDMETHODIMP OpaqueDataInfo::DeleteOpaqueData (REFGUID guid)
{
BOOL found = FALSE;
for (DWORD i=0; i < _cOpaqueData ; i++)
{
if (_pOpaqueData[i].guid == guid)
{
found = TRUE;
break;
}
}
if (!found)
return E_FAIL;
ActMemFree(_pOpaqueData[i].data);
for (i=i+1; i < _cOpaqueData ; i++)
{
CopyOpaqueData(&_pOpaqueData[i-1],
&_pOpaqueData[i],
1, FALSE);
}
_cOpaqueData--;
return S_OK;
}
STDMETHODIMP OpaqueDataInfo::GetOpaqueDataCount (ULONG *pulCount)
{
*pulCount = _cOpaqueData;
return S_OK;
}
STDMETHODIMP OpaqueDataInfo::GetAllOpaqueData (OpaqueData **prgData)
{
*prgData = _pOpaqueData;
return S_OK;
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP OpaqueDataInfo::Serialize(IN void *pv)
{
_unSerialized = FALSE;
return S_OK;
}
STDMETHODIMP OpaqueDataInfo::UnSerialize(IN void *pv)
{
if (!_parent)
return E_INVALIDARG;
HRESULT hr = S_OK;
if (!_unSerialized)
{
hr = ((ActivationProperties*)_pAct)->GetOpaqueDataInfo(&_cOpaqueData, &_pOpaqueData);
_unSerialized = TRUE;
}
return hr;
}
STDMETHODIMP OpaqueDataInfo::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
if (!_parent)
return E_INVALIDARG;
*pdwSize = 0;
Serializer *pSer = (Serializer*) pv;
if ((!IsInproc(pSer)) && _cOpaqueData)
{
((ActivationProperties*)_pAct)->SetOpaqueDataInfo(_cOpaqueData,
_pOpaqueData);
_cOpaqueData = 0;
_pOpaqueData = NULL;
}
return S_OK;
}
STDMETHODIMP OpaqueDataInfo::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_IOpaqueDataInfo;
return S_OK;
}
STDMETHODIMP OpaqueDataInfo::SetParent(ISerializableParent *pParent)
{
_parent = pParent;
if (pParent)
return pParent->QueryInterface(CLSID_ActivationProperties,
&_pAct);
return S_OK;
}
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP OpaqueDataInfo::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP OpaqueDataInfo::SerializableQueryInterface( REFIID riid, LPVOID* ppvObj)
{
//Use IID_OpaqueDataInfo to return the real object right now
if (IsEqualIID(riid, IID_IOpaqueDataInfo))
{
*ppvObj = (OpaqueDataInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IOpaqueDataInfo*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG OpaqueDataInfo::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG OpaqueDataInfo::Release(void)
{
if (_parent)
return _parent->Release();
return 0;
}
//-----------------------------------------------------------------------
// Methods from IUnknown
//-----------------------------------------------------------------------
STDMETHODIMP SpecialProperties::QueryInterface( REFIID riid, LPVOID* ppvObj)
{
if (_parent)
return _parent->QueryInterface(riid, ppvObj);
else
return SerializableQueryInterface(riid, ppvObj);
}
STDMETHODIMP SpecialProperties::SerializableQueryInterface( REFIID riid, LPVOID
* ppvObj)
{
//Use IID_ISpecialSystemProperties to return the real object right now
if (IsEqualIID(riid, IID_ISpecialSystemProperties))
{
*ppvObj = (SpecialProperties*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (ISpecialSystemProperties*) this;
AddRef();
return S_OK;
}
else
if (IsEqualIID(riid, IID_ISerializable))
{
*ppvObj = (ISerializable*) this;
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
ULONG SpecialProperties::AddRef(void)
{
if (_parent)
return _parent->AddRef();
return 1;
}
ULONG SpecialProperties::Release(void)
{
if (_parent)
return _parent->Release();
return 0;
}
//-----------------------------------------------------------------------
// Methods from ISerializable
//-----------------------------------------------------------------------
STDMETHODIMP SpecialProperties::Serialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
SpecialPropertiesData_Encode(handle, &_data);
return S_OK;
}
STDMETHODIMP SpecialProperties::UnSerialize(IN void *pv)
{
Serializer *pSer = (Serializer*) pv;
if (!_unSerialized)
{
handle_t handle;
HRESULT hr = pSer->GetSerializationHandle((void*) &handle);
Win4Assert(hr==S_OK);
SpecialPropertiesData_Decode(handle, &_data);
_unSerialized = TRUE;
}
return S_OK;
}
STDMETHODIMP SpecialProperties::GetSize(IN void *pv, OUT DWORD *pdwSize)
{
Serializer *pSer = (Serializer*) pv;
if (!IsInproc(pSer))
{
handle_t handle;
HRESULT hr = pSer->GetSizingHandle((void*) &handle);
if (FAILED(hr))
return hr;
*pdwSize = SpecialPropertiesData_AlignSize(handle, &_data);
MesHandleFree(handle);
}
else
*pdwSize = 0;
return S_OK;
}
STDMETHODIMP SpecialProperties::GetCLSID(OUT CLSID *pclsid)
{
*pclsid = IID_ISpecialSystemProperties;
return S_OK;
}