539 lines
12 KiB
C++
539 lines
12 KiB
C++
// MarshalableTI.cpp : Implementation of CMarshalableTI
|
|
#include "precomp.h"
|
|
#include "MarshalableTI.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMarshalableTI methods
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CMarshalableTI::FinalConstruct()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
m_bCreated = false;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IMarshalableTI methods
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CMarshalableTI::Create(REFIID clsid, REFIID iidLib, LCID lcid, WORD dwMajorVer, WORD dwMinorVer)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if( !m_bCreated )
|
|
{
|
|
m_guid = clsid;
|
|
m_libid = iidLib;
|
|
m_lcid = lcid;
|
|
|
|
m_TIHolder.m_pguid = &m_guid;
|
|
m_TIHolder.m_plibid = &m_libid;
|
|
m_TIHolder.m_wMajor = dwMajorVer;
|
|
m_TIHolder.m_wMinor = dwMinorVer;
|
|
m_TIHolder.m_pInfo = NULL;
|
|
m_TIHolder.m_dwRef = 0;
|
|
m_TIHolder.m_pMap = NULL;
|
|
m_TIHolder.m_nCount = 0;
|
|
}
|
|
else
|
|
{
|
|
ATLASSERT(0);
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IMarshal Methods
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CMarshalableTI::GetUnmarshalClass(
|
|
/* [in] */ REFIID riid,
|
|
/* [unique][in] */ void *pv,
|
|
/* [in] */ DWORD dwDestContext,
|
|
/* [unique][in] */ void *pvDestContext,
|
|
/* [in] */ DWORD mshlflags,
|
|
/* [out] */ CLSID *pCid)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
*pCid = CLSID_MarshalableTI;
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMarshalableTI::GetMarshalSizeMax(
|
|
/* [in] */ REFIID riid,
|
|
/* [unique][in] */ void *pv,
|
|
/* [in] */ DWORD dwDestContext,
|
|
/* [unique][in] */ void *pvDestContext,
|
|
/* [in] */ DWORD mshlflags,
|
|
/* [out] */ DWORD *pSize)
|
|
{
|
|
|
|
*pSize = (2 * sizeof(GUID) + 2 * sizeof(ULONG) + sizeof(LCID) );
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMarshalableTI::MarshalInterface(
|
|
/* [unique][in] */ IStream *pStm,
|
|
/* [in] */ REFIID riid,
|
|
/* [unique][in] */ void *pv,
|
|
/* [in] */ DWORD dwDestContext,
|
|
/* [unique][in] */ void *pvDestContext,
|
|
/* [in] */ DWORD mshlflags)
|
|
{
|
|
|
|
BYTE buf[(2 * sizeof(GUID) + 2 * sizeof(ULONG) + sizeof(LCID))];
|
|
BYTE * pByte = buf;
|
|
|
|
const GUID* pGuid = m_TIHolder.m_plibid;
|
|
DWORD dwVer = m_TIHolder.m_wMajor;
|
|
const DWORD* pDword = &dwVer;
|
|
|
|
// Ugly because it is yanked from tested, shipped system code
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
DWORD dword = pGuid->Data1;
|
|
*pByte++ = (BYTE)(dword);
|
|
*pByte++ = (BYTE)(dword >> 8);
|
|
*pByte++ = (BYTE)(dword >> 16);
|
|
*pByte++ = (BYTE)(dword >> 24);
|
|
|
|
WORD word = pGuid->Data2;
|
|
*pByte++ = (BYTE)(word);
|
|
*pByte++ = (BYTE)(word >> 8);
|
|
|
|
word = pGuid->Data3;
|
|
*pByte++ = (BYTE)(word);
|
|
*pByte++ = (BYTE)(word >> 8);
|
|
|
|
const BYTE* pData4 = pGuid->Data4;
|
|
for (int j = 0; j < 8; j++) {
|
|
*pByte++ = *pData4++;
|
|
}
|
|
|
|
dword = *pDword;
|
|
*pByte++ = (BYTE)(dword);
|
|
*pByte++ = (BYTE)(dword >> 8);
|
|
*pByte++ = (BYTE)(dword >> 16);
|
|
*pByte++ = (BYTE)(dword >> 24);
|
|
|
|
pGuid = m_TIHolder.m_pguid;
|
|
dwVer = m_TIHolder.m_wMinor;
|
|
}
|
|
|
|
*pByte++ = (BYTE)(m_lcid);
|
|
*pByte++ = (BYTE)(m_lcid >> 8);
|
|
*pByte++ = (BYTE)(m_lcid >> 16);
|
|
*pByte++ = (BYTE)(m_lcid >> 24);
|
|
|
|
HRESULT hr = pStm->Write(buf, sizeof(buf), NULL);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMarshalableTI::UnmarshalInterface(
|
|
/* [unique][in] */ IStream *pStm,
|
|
/* [in] */ REFIID riid,
|
|
/* [out] */ void **ppv)
|
|
{
|
|
|
|
|
|
// Since we don't know the endian-ness of the other side,
|
|
// we use a private wire format for custom marshaling here.
|
|
//
|
|
BYTE buf[(2 * sizeof(GUID) + 2 * sizeof(ULONG) + sizeof(LCID) )];
|
|
HRESULT hr = S_OK;
|
|
|
|
if( !m_bCreated )
|
|
{
|
|
|
|
*ppv = NULL;
|
|
|
|
hr = pStm->Read(buf, sizeof(buf), NULL);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
GUID guidTypeLib;
|
|
GUID guidTypeInfo;
|
|
LCID lcidTypeLib;
|
|
ULONG verMajor;
|
|
ULONG verMinor;
|
|
|
|
BYTE * pByte;
|
|
GUID * pGuid;
|
|
DWORD * pDword;
|
|
|
|
pByte = buf;
|
|
pGuid = &guidTypeLib;
|
|
pDword = &verMajor;
|
|
int i;
|
|
|
|
// Ugly because it is yanked from tested, shipped system code
|
|
for (i = 0; i < 2; i++) {
|
|
DWORD dword;
|
|
WORD word;
|
|
|
|
dword = (DWORD)(*pByte++);
|
|
dword += (DWORD)(*pByte++ << 8);
|
|
dword += (DWORD)(*pByte++ << 16);
|
|
dword += (DWORD)(*pByte++ << 24);
|
|
pGuid->Data1 = dword;
|
|
|
|
word = (WORD)(*pByte++);
|
|
word += (WORD)(*pByte++ << 8);
|
|
pGuid->Data2 = word;
|
|
|
|
word = (WORD)(*pByte++);
|
|
word += (WORD)(*pByte++ << 8);
|
|
pGuid->Data3 = word;
|
|
|
|
BYTE * pData4 = pGuid->Data4;
|
|
for (int j = 0; j < 8; j++) {
|
|
*pData4++ = *pByte++;
|
|
}
|
|
|
|
dword = (DWORD)(*pByte++);
|
|
dword += (DWORD)(*pByte++ << 8);
|
|
dword += (DWORD)(*pByte++ << 16);
|
|
dword += (DWORD)(*pByte++ << 24);
|
|
*pDword = dword;
|
|
|
|
pGuid = &guidTypeInfo;
|
|
pDword = &verMinor;
|
|
}
|
|
|
|
lcidTypeLib = (DWORD)(*pByte++);
|
|
lcidTypeLib += (DWORD)(*pByte++ << 8);
|
|
lcidTypeLib += (DWORD)(*pByte++ << 16);
|
|
lcidTypeLib += (DWORD)(*pByte++ << 24);
|
|
|
|
hr = Create(guidTypeInfo, guidTypeLib,lcidTypeLib, static_cast<WORD>(verMajor), static_cast<WORD>(verMinor));
|
|
}
|
|
}
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
hr = QueryInterface(riid, ppv);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMarshalableTI::ReleaseMarshalData(
|
|
/* [unique][in] */ IStream *pStm)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMarshalableTI::DisconnectObject(
|
|
/* [in] */ DWORD dwReserved)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// ITypeInfo Methods
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CMarshalableTI::GetTypeAttr(
|
|
TYPEATTR ** ppTypeAttr
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetTypeAttr(ppTypeAttr);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMarshalableTI:: GetTypeComp(
|
|
ITypeComp ** ppTComp
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetTypeComp(ppTComp);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMarshalableTI:: GetFuncDesc(
|
|
UINT index,
|
|
FUNCDESC ** ppFuncDesc
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetFuncDesc(index, ppFuncDesc);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMarshalableTI:: GetVarDesc(
|
|
UINT index,
|
|
VARDESC ** ppVarDesc
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetVarDesc(index, ppVarDesc);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMarshalableTI:: GetNames(
|
|
MEMBERID memid,
|
|
BSTR * rgBstrNames,
|
|
UINT cMaxNames,
|
|
UINT * pcNames
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetNames(memid, rgBstrNames, cMaxNames, pcNames);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: GetRefTypeOfImplType(
|
|
UINT index,
|
|
HREFTYPE * pRefType
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetRefTypeOfImplType(index, pRefType);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: GetImplTypeFlags(
|
|
UINT index,
|
|
INT * pImplTypeFlags
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetImplTypeFlags(index, pImplTypeFlags);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: GetIDsOfNames(
|
|
LPOLESTR * rgszNames,
|
|
UINT cNames,
|
|
MEMBERID * pMemId
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetIDsOfNames(rgszNames, cNames, pMemId);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: Invoke(
|
|
PVOID pvInstance,
|
|
MEMBERID memid,
|
|
WORD wFlags,
|
|
DISPPARAMS * pDispParams,
|
|
VARIANT * pVarResult,
|
|
EXCEPINFO * pExcepInfo,
|
|
UINT * puArgErr
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->Invoke(pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMarshalableTI:: GetDocumentation(
|
|
MEMBERID memid,
|
|
BSTR * pBstrName,
|
|
BSTR * pBstrDocString,
|
|
DWORD * pdwHelpContext,
|
|
BSTR * pBstrHelpFile
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetDocumentation(memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: GetDllEntry(
|
|
MEMBERID memid,
|
|
INVOKEKIND invKind,
|
|
BSTR * pBstrDllName,
|
|
BSTR * pBstrName,
|
|
WORD * pwOrdinal
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetDllEntry(memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: GetRefTypeInfo(
|
|
HREFTYPE hRefType,
|
|
ITypeInfo ** ppTInfo
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetRefTypeInfo(hRefType, ppTInfo);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: AddressOfMember(
|
|
MEMBERID memid,
|
|
INVOKEKIND invKind,
|
|
PVOID * ppv
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->AddressOfMember(memid, invKind, ppv);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
HRESULT CMarshalableTI:: CreateInstance(
|
|
IUnknown * pUnkOuter,
|
|
REFIID riid,
|
|
PVOID * ppvObj
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->CreateInstance(pUnkOuter, riid, ppvObj );
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: GetMops(
|
|
MEMBERID memid,
|
|
BSTR * pBstrMops
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetMops(memid, pBstrMops);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI:: GetContainingTypeLib(
|
|
ITypeLib ** ppTLib,
|
|
UINT * pIndex
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
hr = spTI->GetContainingTypeLib(ppTLib, pIndex);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
void CMarshalableTI::ReleaseTypeAttr(
|
|
TYPEATTR * pTypeAttr
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
spTI->ReleaseTypeAttr(pTypeAttr);
|
|
}
|
|
}
|
|
|
|
void CMarshalableTI::ReleaseFuncDesc(
|
|
FUNCDESC * pFuncDesc
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
spTI->ReleaseFuncDesc(pFuncDesc);
|
|
}
|
|
}
|
|
|
|
void CMarshalableTI::ReleaseVarDesc(
|
|
VARDESC * pVarDesc
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<ITypeInfo> spTI;
|
|
if( SUCCEEDED( hr = _GetClassInfo(&spTI) ) )
|
|
{
|
|
spTI->ReleaseVarDesc(pVarDesc);
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT CMarshalableTI::_GetClassInfo(ITypeInfo** ppTI)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = m_TIHolder.GetTI(m_lcid, ppTI);
|
|
|
|
return hr;
|
|
}
|