diff options
Diffstat (limited to 'src/vm/mngstdinterfaces.h')
-rw-r--r-- | src/vm/mngstdinterfaces.h | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/src/vm/mngstdinterfaces.h b/src/vm/mngstdinterfaces.h new file mode 100644 index 0000000000..2aaee9574d --- /dev/null +++ b/src/vm/mngstdinterfaces.h @@ -0,0 +1,398 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Header: MngStdInterfaceMap.h +** +** +** Purpose: Contains types and method signatures for the Com wrapper class +** +** + +===========================================================*/ + +#ifndef _MNGSTDINTERFACEMAP_H +#define _MNGSTDINTERFACEMAP_H + +#ifndef FEATURE_COMINTEROP +#error FEATURE_COMINTEROP is required for this file +#endif // FEATURE_COMINTEROP + +#include "vars.hpp" +#include "eehash.h" +#include "class.h" +#include "mlinfo.h" + +#ifndef DACCESS_COMPILE +// +// This class is used to establish a mapping between a managed standard interface and its +// unmanaged counterpart. +// + +class MngStdInterfaceMap +{ +public: + // This method retrieves the native IID of the interface that the specified + // managed type is a standard interface for. If the specified type is not + // a standard interface then GUIDNULL is returned. + inline static IID* GetNativeIIDForType(TypeHandle th) + { + CONTRACTL + { + THROWS; + GC_TRIGGERS; + INJECT_FAULT(COMPlusThrowOM()); + } + CONTRACTL_END + + // Only simple class types can have native IIDs + if (th.IsTypeDesc()) + return NULL; + + HashDatum Data; + + // Retrieve the name of the type. + LPCUTF8 ns, name; + LPUTF8 strTypeName; + name = th.GetMethodTable()->GetFullyQualifiedNameInfo(&ns); + MAKE_FULL_PATH_ON_STACK_UTF8(strTypeName, ns, name); + + if (m_pMngStdItfMap == NULL) { + MngStdInterfaceMap *tmp = new MngStdInterfaceMap; + if (FastInterlockCompareExchangePointer(&m_pMngStdItfMap, tmp, NULL) != NULL) { + tmp->m_TypeNameToNativeIIDMap.ClearHashTable(); + delete tmp; + } + } + if (m_pMngStdItfMap->m_TypeNameToNativeIIDMap.GetValue(strTypeName, &Data) && (*((GUID*)Data) != GUID_NULL)) + { + // The type is a standard interface. + return (IID*)Data; + } + else + { + // The type is not a standard interface. + return NULL; + } + } + +private: + // Disalow creation of this class by anybody outside of it. + MngStdInterfaceMap(); + + // The map of type names to native IID's. + EEUtf8StringHashTable m_TypeNameToNativeIIDMap; + + // The one and only instance of the managed std interface map. + static MngStdInterfaceMap *m_pMngStdItfMap; +}; + +#endif // DACCESS_COMPILE + +// +// Base class for all the classes that contain the ECall's for the managed standard interfaces. +// + +class MngStdItfBase +{ +protected: + static void InitHelper( + LPCUTF8 strMngItfTypeName, + LPCUTF8 strUComItfTypeName, + LPCUTF8 strCMTypeName, + LPCUTF8 strCookie, + LPCUTF8 strManagedViewName, + TypeHandle *pMngItfType, + TypeHandle *pUComItfType, + TypeHandle *pCustomMarshalerType, + TypeHandle *pManagedViewType, + OBJECTHANDLE *phndMarshaler); + + static LPVOID ForwardCallToManagedView( + OBJECTHANDLE hndMarshaler, + MethodDesc *pMngItfMD, + MethodDesc *pUComItfMD, + MethodDesc *pMarshalNativeToManagedMD, + MethodDesc *pMngViewMD, + IID *pMngItfIID, + IID *pNativeItfIID, + ARG_SLOT* pArgs); +}; + + +// +// Define the enum of methods on the managed standard interface. +// + +#define MNGSTDITF_BEGIN_INTERFACE(FriendlyName, strMngItfName, strUCOMMngItfName, strCustomMarshalerName, strCustomMarshalerCookie, strManagedViewName, NativeItfIID, bCanCastOnNativeItfQI) \ +\ +enum FriendlyName##Methods \ +{ \ + FriendlyName##Methods_Dummy = -1, + + +#define MNGSTDITF_DEFINE_METH_IMPL(FriendlyName, ECallMethName, MethName, MethSig, FcallDecl) \ + FriendlyName##Methods_##ECallMethName, + + +#define MNGSTDITF_END_INTERFACE(FriendlyName) \ + FriendlyName##Methods_LastMember \ +}; \ + + +#include "mngstditflist.h" + + +#undef MNGSTDITF_BEGIN_INTERFACE +#undef MNGSTDITF_DEFINE_METH_IMPL +#undef MNGSTDITF_END_INTERFACE + + +// +// Define the class that implements the ECall's for the managed standard interface. +// + +#define MNGSTDITF_BEGIN_INTERFACE(FriendlyName, strMngItfName, strUCOMMngItfName, strCustomMarshalerName, strCustomMarshalerCookie, strManagedViewName, NativeItfIID, bCanCastOnNativeItfQI) \ +\ +class FriendlyName : public MngStdItfBase \ +{ \ +public: \ + FriendlyName() \ + { \ + CONTRACTL \ + { \ + THROWS; \ + GC_TRIGGERS; \ + INJECT_FAULT(COMPlusThrowOM()); \ + } \ + CONTRACTL_END \ + InitHelper(strMngItfName, strUCOMMngItfName, strCustomMarshalerName, strCustomMarshalerCookie, strManagedViewName, &m_MngItfType, &m_UComItfType, &m_CustomMarshalerType, &m_ManagedViewType, &m_hndCustomMarshaler); \ + m_NativeItfIID = NativeItfIID; \ + m_UComItfType.GetMethodTable()->GetGuid(&m_MngItfIID, TRUE); \ + memset(m_apCustomMarshalerMD, 0, CustomMarshalerMethods_LastMember * sizeof(MethodDesc *)); \ + memset(m_apManagedViewMD, 0, FriendlyName##Methods_LastMember * sizeof(MethodDesc *)); \ + memset(m_apUComItfMD, 0, FriendlyName##Methods_LastMember * sizeof(MethodDesc *)); \ + memset(m_apMngItfMD, 0, FriendlyName##Methods_LastMember * sizeof(MethodDesc *)); \ + } \ +\ + OBJECTREF GetCustomMarshaler() \ + { \ + WRAPPER_NO_CONTRACT; \ + return ObjectFromHandle(m_hndCustomMarshaler); \ + } \ +\ + MethodDesc* GetCustomMarshalerMD(EnumCustomMarshalerMethods Method) \ + { \ + CONTRACTL \ + { \ + THROWS; \ + GC_TRIGGERS; \ + INJECT_FAULT(COMPlusThrowOM()); \ + } \ + CONTRACTL_END \ + MethodDesc *pMD = NULL; \ + \ + if (m_apCustomMarshalerMD[Method]) \ + return m_apCustomMarshalerMD[Method]; \ + \ + pMD = CustomMarshalerInfo::GetCustomMarshalerMD(Method, m_CustomMarshalerType); \ + _ASSERTE(pMD && "Unable to find specified method on the custom marshaler"); \ + MetaSig::EnsureSigValueTypesLoaded(pMD); \ + \ + m_apCustomMarshalerMD[Method] = pMD; \ + return pMD; \ + } \ +\ + MethodDesc* GetManagedViewMD(FriendlyName##Methods Method, LPCUTF8 strMethName, LPHARDCODEDMETASIG pSig) \ + { \ + CONTRACTL \ + { \ + THROWS; \ + GC_TRIGGERS; \ + INJECT_FAULT(COMPlusThrowOM()); \ + } \ + CONTRACTL_END \ + MethodDesc *pMD = NULL; \ + \ + if (m_apManagedViewMD[Method]) \ + return m_apManagedViewMD[Method]; \ + \ + pMD = MemberLoader::FindMethod(m_ManagedViewType.GetMethodTable(), strMethName, pSig); \ + _ASSERTE(pMD && "Unable to find specified method on the managed view"); \ + MetaSig::EnsureSigValueTypesLoaded(pMD); \ + \ + m_apManagedViewMD[Method] = pMD; \ + return pMD; \ + } \ +\ + MethodDesc* GetUComItfMD(FriendlyName##Methods Method, LPCUTF8 strMethName, LPHARDCODEDMETASIG pSig) \ + { \ + CONTRACTL \ + { \ + THROWS; \ + GC_TRIGGERS; \ + INJECT_FAULT(COMPlusThrowOM()); \ + } \ + CONTRACTL_END \ + MethodDesc *pMD = NULL; \ + \ + if (m_apUComItfMD[Method]) \ + return m_apUComItfMD[Method]; \ + \ + pMD = MemberLoader::FindMethod(m_UComItfType.GetMethodTable(), strMethName, pSig); \ + _ASSERTE(pMD && "Unable to find specified method in UCom interface"); \ + MetaSig::EnsureSigValueTypesLoaded(pMD); \ + \ + m_apUComItfMD[Method] = pMD; \ + return pMD; \ + } \ +\ + MethodDesc* GetMngItfMD(FriendlyName##Methods Method, LPCUTF8 strMethName, LPHARDCODEDMETASIG pSig) \ + { \ + CONTRACTL \ + { \ + THROWS; \ + GC_TRIGGERS; \ + INJECT_FAULT(COMPlusThrowOM()); \ + } \ + CONTRACTL_END \ + MethodDesc *pMD = NULL; \ + \ + if (m_apMngItfMD[Method]) \ + return m_apMngItfMD[Method]; \ + \ + pMD = MemberLoader::FindMethod(m_MngItfType.GetMethodTable(), strMethName, pSig); \ + _ASSERTE(pMD && "Unable to find specified method in UCom interface"); \ + MetaSig::EnsureSigValueTypesLoaded(pMD); \ + \ + m_apMngItfMD[Method] = pMD; \ + return pMD; \ + } \ +\ +private: \ + MethodDesc* m_apCustomMarshalerMD[CustomMarshalerMethods_LastMember]; \ + MethodDesc* m_apManagedViewMD[FriendlyName##Methods_LastMember]; \ + MethodDesc* m_apUComItfMD[FriendlyName##Methods_LastMember]; \ + MethodDesc* m_apMngItfMD[FriendlyName##Methods_LastMember]; \ + TypeHandle m_CustomMarshalerType; \ + TypeHandle m_ManagedViewType; \ + TypeHandle m_UComItfType; \ + TypeHandle m_MngItfType; \ + OBJECTHANDLE m_hndCustomMarshaler; \ + GUID m_MngItfIID; \ + GUID m_NativeItfIID; \ +\ + +#define MNGSTDITF_DEFINE_METH_IMPL(FriendlyName, ECallMethName, MethName, MethSig, FcallDecl) \ +\ +public: static LPVOID __stdcall ECallMethName##Worker(ARG_SLOT* pArgs); \ +public: static FcallDecl; \ +\ + +#define MNGSTDITF_END_INTERFACE(FriendlyName) \ +}; \ +\ + + +#include "mngstditflist.h" + + +#undef MNGSTDITF_BEGIN_INTERFACE +#undef MNGSTDITF_DEFINE_METH_IMPL +#undef MNGSTDITF_END_INTERFACE + + +// +// App domain level information on the managed standard interfaces . +// + +class MngStdInterfacesInfo +{ +public: + // Constructor and destructor. + MngStdInterfacesInfo() + { + STATIC_CONTRACT_THROWS; + STATIC_CONTRACT_FAULT; + +#define MNGSTDITF_BEGIN_INTERFACE(FriendlyName, strMngItfName, strUCOMMngItfName, strCustomMarshalerName, strCustomMarshalerCookie, strManagedViewName, NativeItfIID, bCanCastOnNativeItfQI) \ +\ + m_p##FriendlyName = 0; \ +\ + +#define MNGSTDITF_DEFINE_METH_IMPL(FriendlyName, ECallMethName, MethName, MethSig, FcallDecl) +#define MNGSTDITF_END_INTERFACE(FriendlyName) + + +#include "mngstditflist.h" + + +#undef MNGSTDITF_BEGIN_INTERFACE +#undef MNGSTDITF_DEFINE_METH_IMPL +#undef MNGSTDITF_END_INTERFACE + } + + ~MngStdInterfacesInfo() + { + WRAPPER_NO_CONTRACT; + +#define MNGSTDITF_BEGIN_INTERFACE(FriendlyName, strMngItfName, strUCOMMngItfName, strCustomMarshalerName, strCustomMarshalerCookie, strManagedViewName, NativeItfIID, bCanCastOnNativeItfQI) \ +\ + if (m_p##FriendlyName) \ + delete m_p##FriendlyName; \ +\ + +#define MNGSTDITF_DEFINE_METH_IMPL(FriendlyName, ECallMethName, MethName, MethSig, FcallDecl) +#define MNGSTDITF_END_INTERFACE(FriendlyName) + + +#include "mngstditflist.h" + + +#undef MNGSTDITF_BEGIN_INTERFACE +#undef MNGSTDITF_DEFINE_METH_IMPL +#undef MNGSTDITF_END_INTERFACE + } + + + // Accessors for each of the managed standard interfaces. +#define MNGSTDITF_BEGIN_INTERFACE(FriendlyName, strMngItfName, strUCOMMngItfName, strCustomMarshalerName, strCustomMarshalerCookie, strManagedViewName, NativeItfIID, bCanCastOnNativeItfQI) \ +\ +public: \ + FriendlyName *Get##FriendlyName() \ + { \ + CONTRACTL \ + { \ + THROWS; \ + GC_TRIGGERS; \ + INJECT_FAULT(COMPlusThrowOM()); \ + } \ + CONTRACTL_END \ + if (!m_p##FriendlyName) \ + { \ + NewHolder<FriendlyName> pFriendlyName = new FriendlyName(); \ + if (InterlockedCompareExchangeT(&m_p##FriendlyName, pFriendlyName.GetValue(), NULL) == NULL) \ + pFriendlyName.SuppressRelease(); \ + } \ + return m_p##FriendlyName; \ + } \ +\ +private: \ + FriendlyName *m_p##FriendlyName; \ +\ + +#define MNGSTDITF_DEFINE_METH_IMPL(FriendlyName, ECallMethName, MethName, MethSig, FcallDecl) +#define MNGSTDITF_END_INTERFACE(FriendlyName) + + +#include "mngstditflist.h" + + +#undef MNGSTDITF_BEGIN_INTERFACE +#undef MNGSTDITF_DEFINE_METH_IMPL +#undef MNGSTDITF_END_INTERFACE +}; + +#endif // _MNGSTDINTERFACEMAP_H |