diff options
-rw-r--r-- | src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs | 312 | ||||
-rw-r--r-- | src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs | 9 | ||||
-rw-r--r-- | src/vm/appdomain.cpp | 42 | ||||
-rw-r--r-- | src/vm/appdomain.hpp | 5 | ||||
-rw-r--r-- | src/vm/metasig.h | 11 | ||||
-rw-r--r-- | src/vm/mscorlib.h | 6 | ||||
-rw-r--r-- | src/vm/namespace.h | 1 | ||||
-rw-r--r-- | src/vm/runtimecallablewrapper.cpp | 206 | ||||
-rw-r--r-- | tests/src/Interop/COM/NETClients/Licensing/Program.cs | 7 |
9 files changed, 288 insertions, 311 deletions
diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs index d8689e429b..608d1579fa 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs @@ -409,165 +409,217 @@ $@"{nameof(GetClassFactoryForTypeInternal)} arguments: } } } + } - // This is a helper class that supports the CLR's IClassFactory2 marshaling - // support. - // - // When a managed object is exposed to COM, the CLR invokes - // AllocateAndValidateLicense() to set up the appropriate - // license context and instantiate the object. - private class LicenseInteropProxy + // This is a helper class that supports the CLR's IClassFactory2 marshaling + // support. + // + // When a managed object is exposed to COM, the CLR invokes + // AllocateAndValidateLicense() to set up the appropriate + // license context and instantiate the object. + internal sealed class LicenseInteropProxy + { + private static readonly Type s_licenseAttrType; + private static readonly Type s_licenseExceptionType; + + // LicenseManager + private MethodInfo _createWithContext; + + // LicenseInteropHelper + private MethodInfo _validateTypeAndReturnDetails; + private MethodInfo _getCurrentContextInfo; + + // CLRLicenseContext + private MethodInfo _createDesignContext; + private MethodInfo _createRuntimeContext; + + // LicenseContext + private MethodInfo _setSavedLicenseKey; + + private Type _licInfoHelper; + private MethodInfo _licInfoHelperContains; + + // RCW Activation + private object _licContext; + private Type _targetRcwType; + + static LicenseInteropProxy() { - private static readonly Type s_licenseAttrType; - private static readonly Type s_licenseExceptionType; + s_licenseAttrType = Type.GetType("System.ComponentModel.LicenseProviderAttribute, System.ComponentModel.TypeConverter", throwOnError: false); + s_licenseExceptionType = Type.GetType("System.ComponentModel.LicenseException, System.ComponentModel.TypeConverter", throwOnError: false); + } - private MethodInfo _createWithContext; - private MethodInfo _validateTypeAndReturnDetails; - private MethodInfo _createDesignContext; - private MethodInfo _createRuntimeContext; + public LicenseInteropProxy() + { + Type licManager = Type.GetType("System.ComponentModel.LicenseManager, System.ComponentModel.TypeConverter", throwOnError: true); - private Type _licInfoHelper; - private MethodInfo _licInfoHelperContains; + Type licContext = Type.GetType("System.ComponentModel.LicenseContext, System.ComponentModel.TypeConverter", throwOnError: true); + _setSavedLicenseKey = licContext.GetMethod("SetSavedLicenseKey", BindingFlags.Instance | BindingFlags.Public); + _createWithContext = licManager.GetMethod("CreateWithContext", new[] { typeof(Type), licContext }); - static LicenseInteropProxy() - { - s_licenseAttrType = Type.GetType("System.ComponentModel.LicenseProviderAttribute, System.ComponentModel.TypeConverter", throwOnError: false); - s_licenseExceptionType = Type.GetType("System.ComponentModel.LicenseException, System.ComponentModel.TypeConverter", throwOnError: false); - } + Type interopHelper = licManager.GetNestedType("LicenseInteropHelper", BindingFlags.NonPublic); + _validateTypeAndReturnDetails = interopHelper.GetMethod("ValidateAndRetrieveLicenseDetails", BindingFlags.Static | BindingFlags.Public); + _getCurrentContextInfo = interopHelper.GetMethod("GetCurrentContextInfo", BindingFlags.Static | BindingFlags.Public); - public LicenseInteropProxy() - { - Type licManager = Type.GetType("System.ComponentModel.LicenseManager, System.ComponentModel.TypeConverter", throwOnError: true); + Type clrLicContext = licManager.GetNestedType("CLRLicenseContext", BindingFlags.NonPublic); + _createDesignContext = clrLicContext.GetMethod("CreateDesignContext", BindingFlags.Static | BindingFlags.Public); + _createRuntimeContext = clrLicContext.GetMethod("CreateRuntimeContext", BindingFlags.Static | BindingFlags.Public); - Type licContext = Type.GetType("System.ComponentModel.LicenseContext, System.ComponentModel.TypeConverter", throwOnError: true); - _createWithContext = licManager.GetMethod("CreateWithContext", new[] { typeof(Type), licContext }); + _licInfoHelper = licManager.GetNestedType("LicInfoHelperLicenseContext", BindingFlags.NonPublic); + _licInfoHelperContains = _licInfoHelper.GetMethod("Contains", BindingFlags.Instance | BindingFlags.Public); + } + + // Helper function to create an object from the native side + public static object Create() + { + return new LicenseInteropProxy(); + } - Type interopHelper = licManager.GetNestedType("LicenseInteropHelper", BindingFlags.NonPublic); - _validateTypeAndReturnDetails = interopHelper.GetMethod("ValidateAndRetrieveLicenseDetails", BindingFlags.Static | BindingFlags.Public); + // Determine if the type supports licensing + public static bool HasLicense(Type type) + { + // If the attribute type can't be found, then the type + // definitely doesn't support licensing. + if (s_licenseAttrType == null) + { + return false; + } - Type clrLicContext = licManager.GetNestedType("CLRLicenseContext", BindingFlags.NonPublic); - _createDesignContext = clrLicContext.GetMethod("CreateDesignContext", BindingFlags.Static | BindingFlags.Public); - _createRuntimeContext = clrLicContext.GetMethod("CreateRuntimeContext", BindingFlags.Static | BindingFlags.Public); + return type.IsDefined(s_licenseAttrType, inherit: true); + } - _licInfoHelper = licManager.GetNestedType("LicInfoHelperLicenseContext", BindingFlags.NonPublic); - _licInfoHelperContains = _licInfoHelper.GetMethod("Contains", BindingFlags.Instance | BindingFlags.Public); + // The CLR invokes this whenever a COM client invokes + // IClassFactory2::GetLicInfo on a managed class. + // + // COM normally doesn't expect this function to fail so this method + // should only throw in the case of a catastrophic error (stack, memory, etc.) + public void GetLicInfo(Type type, out bool runtimeKeyAvail, out bool licVerified) + { + runtimeKeyAvail = false; + licVerified = false; + + // Types are as follows: + // LicenseContext, Type, out License, out string + object licContext = Activator.CreateInstance(_licInfoHelper); + var parameters = new object[] { licContext, type, /* out */ null, /* out */ null }; + bool isValid = (bool)_validateTypeAndReturnDetails.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); + if (!isValid) + { + return; } - // Determine if the type supports licensing - public static bool HasLicense(Type type) + var license = (IDisposable)parameters[2]; + if (license != null) { - // If the attribute type can't be found, then the type - // definitely doesn't support licensing. - if (s_licenseAttrType == null) - { - return false; - } + license.Dispose(); + licVerified = true; + } - return type.IsDefined(s_licenseAttrType, inherit: true); + parameters = new object[] { type.AssemblyQualifiedName }; + runtimeKeyAvail = (bool)_licInfoHelperContains.Invoke(licContext, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); + } + + // The CLR invokes this whenever a COM client invokes + // IClassFactory2::RequestLicKey on a managed class. + public string RequestLicKey(Type type) + { + // License will be null, since we passed no instance, + // however we can still retrieve the "first" license + // key from the file. This really will only + // work for simple COM-compatible license providers + // like LicFileLicenseProvider that don't require the + // instance to grant a key. + + // Types are as follows: + // LicenseContext, Type, out License, out string + var parameters = new object[] { /* use global LicenseContext */ null, type, /* out */ null, /* out */ null }; + bool isValid = (bool)_validateTypeAndReturnDetails.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); + if (!isValid) + { + throw new COMException(); //E_FAIL } - // The CLR invokes this whenever a COM client invokes - // IClassFactory2::GetLicInfo on a managed class. - // - // COM normally doesn't expect this function to fail so this method - // should only throw in the case of a catastrophic error (stack, memory, etc.) - public void GetLicInfo(Type type, out bool runtimeKeyAvail, out bool licVerified) + var license = (IDisposable)parameters[2]; + if (license != null) { - runtimeKeyAvail = false; - licVerified = false; + license.Dispose(); + } - // Types are as follows: - // LicenseContext, Type, out License, out string - object licContext = Activator.CreateInstance(_licInfoHelper); - var parameters = new object[] { licContext, type, /* out */ null, /* out */ null }; - bool isValid = (bool)_validateTypeAndReturnDetails.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); - if (!isValid) - { - return; - } + string licenseKey = (string)parameters[3]; + if (licenseKey == null) + { + throw new COMException(); //E_FAIL + } - var license = (IDisposable)parameters[2]; - if (license != null) - { - license.Dispose(); - licVerified = true; - } + return licenseKey; + } - parameters = new object[] { type.AssemblyQualifiedName }; - runtimeKeyAvail = (bool)_licInfoHelperContains.Invoke(licContext, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); + // The CLR invokes this whenever a COM client invokes + // IClassFactory::CreateInstance() or IClassFactory2::CreateInstanceLic() + // on a managed that has a LicenseProvider custom attribute. + // + // If we are being entered because of a call to ICF::CreateInstance(), + // "isDesignTime" will be "true". + // + // If we are being entered because of a call to ICF::CreateInstanceLic(), + // "isDesignTime" will be "false" and "key" will point to a non-null + // license key. + public object AllocateAndValidateLicense(Type type, string key, bool isDesignTime) + { + object[] parameters; + object licContext; + if (isDesignTime) + { + parameters = new object[] { type }; + licContext = _createDesignContext.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); } - - // The CLR invokes this whenever a COM client invokes - // IClassFactory2::RequestLicKey on a managed class. - public string RequestLicKey(Type type) + else { - // License will be null, since we passed no instance, - // however we can still retrieve the "first" license - // key from the file. This really will only - // work for simple COM-compatible license providers - // like LicFileLicenseProvider that don't require the - // instance to grant a key. + parameters = new object[] { type, key }; + licContext = _createRuntimeContext.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); + } - // Types are as follows: - // LicenseContext, Type, out License, out string - var parameters = new object[] { /* use global LicenseContext */ null, type, /* out */ null, /* out */ null }; - bool isValid = (bool)_validateTypeAndReturnDetails.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); - if (!isValid) - { - throw new COMException(); //E_FAIL - } + try + { + parameters = new object[] { type, licContext }; + return _createWithContext.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); + } + catch (Exception exception) when (exception.GetType() == s_licenseExceptionType) + { + const int CLASS_E_NOTLICENSED = unchecked((int)0x80040112); + throw new COMException(exception.Message, CLASS_E_NOTLICENSED); + } + } - var license = (IDisposable)parameters[2]; - if (license != null) - { - license.Dispose(); - } + // See usage in native RCW code + public void GetCurrentContextInfo(RuntimeTypeHandle rth, out bool isDesignTime, out IntPtr bstrKey) + { + Type targetRcwTypeMaybe = Type.GetTypeFromHandle(rth); - string licenseKey = (string)parameters[3]; - if (licenseKey == null) - { - throw new COMException(); //E_FAIL - } + // Types are as follows: + // Type, out bool, out string -> LicenseContext + var parameters = new object[] { targetRcwTypeMaybe, /* out */ null, /* out */ null }; + _licContext = _getCurrentContextInfo.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); - return licenseKey; - } + _targetRcwType = targetRcwTypeMaybe; + isDesignTime = (bool)parameters[1]; + bstrKey = Marshal.StringToBSTR((string)parameters[2]); + } - // The CLR invokes this whenever a COM client invokes - // IClassFactory::CreateInstance() or IClassFactory2::CreateInstanceLic() - // on a managed that has a LicenseProvider custom attribute. - // - // If we are being entered because of a call to ICF::CreateInstance(), - // "isDesignTime" will be "true". - // - // If we are being entered because of a call to ICF::CreateInstanceLic(), - // "isDesignTime" will be "false" and "key" will point to a non-null - // license key. - public object AllocateAndValidateLicense(Type type, string key, bool isDesignTime) + // The CLR invokes this when instantiating a licensed COM + // object inside a designtime license context. + // It's purpose is to save away the license key that the CLR + // retrieved using RequestLicKey(). + public void SaveKeyInCurrentContext(IntPtr bstrKey) + { + if (bstrKey == IntPtr.Zero) { - object[] parameters; - object licContext; - if (isDesignTime) - { - parameters = new object[] { type }; - licContext = _createDesignContext.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); - } - else - { - parameters = new object[] { type, key }; - licContext = _createRuntimeContext.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); - } - - try - { - parameters = new object[] { type, licContext }; - return _createWithContext.Invoke(null, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); - } - catch (Exception exception) when (exception.GetType() == s_licenseExceptionType) - { - const int CLASS_E_NOTLICENSED = unchecked((int)0x80040112); - throw new COMException(exception.Message, CLASS_E_NOTLICENSED); - } + return; } + + string key = Marshal.PtrToStringBSTR(bstrKey); + var parameters = new object[] { _targetRcwType, key }; + _setSavedLicenseKey.Invoke(_licContext, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null); } } } diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 28c4ec223a..4cdf838fb1 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs @@ -741,15 +741,6 @@ namespace System.Runtime.InteropServices [DllImport(Interop.Libraries.Ole32, PreserveSig = false)] private static extern void BindMoniker(IMoniker pmk, uint grfOpt, ref Guid iidResult, [MarshalAs(UnmanagedType.Interface)] out object ppvResult); - /// <summary> - /// Private method called from EE upon use of license/ICF2 marshaling. - /// </summary> - private static IntPtr LoadLicenseManager() - { - Type t = Type.GetType("System.ComponentModel.LicenseManager, System", throwOnError: true); - return t.TypeHandle.Value; - } - [MethodImpl(MethodImplOptions.InternalCall)] public static extern void ChangeWrapperHandleStrength(object otp, bool fIsWeak); diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index 21161763ef..563de46075 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -1828,47 +1828,6 @@ void BaseDomain::InitLargeHeapHandleTable() #endif } -#ifdef FEATURE_COMINTEROP -MethodTable* AppDomain::GetLicenseInteropHelperMethodTable() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - } - CONTRACTL_END; - - if(m_pLicenseInteropHelperMT == NULL) - { - // Do this work outside of the lock so we don't have an unbreakable lock condition - - TypeHandle licenseMgrTypeHnd; - MethodDescCallSite loadLM(METHOD__MARSHAL__LOAD_LICENSE_MANAGER); - - licenseMgrTypeHnd = (MethodTable*) loadLM.Call_RetLPVOID((ARG_SLOT*)NULL); - - // - // Look up this method by name, because the type is actually declared in System.dll. <TODO>@todo: why?</TODO> - // - - MethodDesc *pGetLIHMD = MemberLoader::FindMethod(licenseMgrTypeHnd.AsMethodTable(), - "GetLicenseInteropHelperType", &gsig_SM_Void_RetIntPtr); - _ASSERTE(pGetLIHMD); - - TypeHandle lihTypeHnd; - - MethodDescCallSite getLIH(pGetLIHMD); - lihTypeHnd = (MethodTable*) getLIH.Call_RetLPVOID((ARG_SLOT*)NULL); - - BaseDomain::LockHolder lh(this); - - if(m_pLicenseInteropHelperMT == NULL) - m_pLicenseInteropHelperMT = lihTypeHnd.AsMethodTable(); - } - return m_pLicenseInteropHelperMT; -} -#endif // FEATURE_COMINTEROP - #endif // CROSSGEN_COMPILE //***************************************************************************** @@ -3489,7 +3448,6 @@ AppDomain::AppDomain() #ifdef FEATURE_COMINTEROP m_pRCWCache = NULL; m_pRCWRefCache = NULL; - m_pLicenseInteropHelperMT = NULL; memset(m_rpCLRTypes, 0, sizeof(m_rpCLRTypes)); #endif // FEATURE_COMINTEROP diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp index e6655246eb..7fdf912327 100644 --- a/src/vm/appdomain.hpp +++ b/src/vm/appdomain.hpp @@ -2448,8 +2448,6 @@ public: } RCWRefCache *GetRCWRefCache(); - - MethodTable* GetLicenseInteropHelperMethodTable(); #endif // FEATURE_COMINTEROP //**************************************************************************************** @@ -2995,9 +2993,6 @@ private: // this cache stores the RCW -> CCW references in this domain RCWRefCache *m_pRCWRefCache; - - // The method table used for LicenseInteropHelper - MethodTable* m_pLicenseInteropHelperMT; #endif // FEATURE_COMINTEROP // The index of this app domain among existing app domains (starting from 1) diff --git a/src/vm/metasig.h b/src/vm/metasig.h index 7700c0a5b4..5321fd3ee3 100644 --- a/src/vm/metasig.h +++ b/src/vm/metasig.h @@ -347,6 +347,8 @@ DEFINE_METASIG_T(SM(Str_PtrHStringHeader_RetIntPtr, s P(g(HSTRING_HEADER_MANAGED DEFINE_METASIG_T(SM(RefDateTimeOffset_RefDateTimeNative_RetVoid, r(g(DATE_TIME_OFFSET)) r(g(DATETIMENATIVE)), v)) +DEFINE_METASIG_T(IM(RuntimeTypeHandle_RefBool_RefIntPtr_RetVoid, g(RT_TYPE_HANDLE) r(F) r(I), v)) + #endif @@ -363,9 +365,6 @@ DEFINE_METASIG(SM(ArrByte_Bool_RetObj, a(b) F, j)) DEFINE_METASIG(SM(ArrByte_ArrByte_RefObj_RetObj, a(b) a(b) r(j), j)) DEFINE_METASIG_T(SM(PtrSByt_Int_Int_Encoding_RetStr, P(B) i i C(ENCODING), s)) -DEFINE_METASIG_T(SM(Void_RetRuntimeTypeHandle, _, g(RT_TYPE_HANDLE))) -DEFINE_METASIG(SM(Void_RetIntPtr, _, I)) - DEFINE_METASIG_T(SM(UInt_UInt_PtrNativeOverlapped_RetVoid, K K P(g(NATIVEOVERLAPPED)), v)) DEFINE_METASIG(IM(Long_RetVoid, l, v)) @@ -381,6 +380,7 @@ DEFINE_METASIG_T(IM(Str_ArrB_ArrB_Ver_CI_AHA_AVC_Str_ANF_SNKP_RetV, DEFINE_METASIG_T(IM(PEK_IFM_RetV, g(PORTABLE_EXECUTABLE_KINDS) g(IMAGE_FILE_MACHINE), v)) DEFINE_METASIG(IM(RetObj, _, j)) +DEFINE_METASIG(SM(RetObj, _, j)) DEFINE_METASIG_T(IM(RetIEnumerator, _, C(IENUMERATOR))) DEFINE_METASIG(IM(RetStr, _, s)) DEFINE_METASIG(IM(RetLong, _, l)) @@ -532,11 +532,6 @@ DEFINE_METASIG_T(IM(RuntimeType_RetVoid, C(CLASS) , v)) DEFINE_METASIG_T(SM(ArrException_PtrInt_RetVoid, a(C(EXCEPTION)) P(i), v)) DEFINE_METASIG_T(IM(RuntimeArgumentHandle_PtrVoid_RetVoid, g(ARGUMENT_HANDLE) P(v), v)) -DEFINE_METASIG_T(IM(LicenseInteropHelper_GetCurrentContextInfo, r(i) r(I) g(RT_TYPE_HANDLE), v)) -DEFINE_METASIG(IM(LicenseInteropHelper_SaveKeyInCurrentContext, I, v)) -DEFINE_METASIG_T(SM(LicenseInteropHelper_AllocateAndValidateLicense, g(RT_TYPE_HANDLE) I i, j)) -DEFINE_METASIG_T(SM(LicenseInteropHelper_RequestLicKey, g(RT_TYPE_HANDLE) r(I), i)) -DEFINE_METASIG_T(IM(LicenseInteropHelper_GetLicInfo, g(RT_TYPE_HANDLE) r(i) r(i), v)) DEFINE_METASIG_T(SM(Assembly_RetVoid, C(ASSEMBLY), v)) DEFINE_METASIG_T(SM(Assembly_Str_RetArrAssembly, C(ASSEMBLY) s, a(C(ASSEMBLY)))) diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h index b78684da62..aea2197f9a 100644 --- a/src/vm/mscorlib.h +++ b/src/vm/mscorlib.h @@ -195,6 +195,11 @@ DEFINE_CLASS(COM_OBJECT, System, __ComObject) DEFINE_METHOD(COM_OBJECT, RELEASE_ALL_DATA, ReleaseAllData, IM_RetVoid) DEFINE_METHOD(COM_OBJECT, GET_EVENT_PROVIDER, GetEventProvider, IM_Class_RetObj) +DEFINE_CLASS(LICENSE_INTEROP_PROXY, InternalInteropServices, LicenseInteropProxy) +DEFINE_METHOD(LICENSE_INTEROP_PROXY, CREATE, Create, SM_RetObj) +DEFINE_METHOD(LICENSE_INTEROP_PROXY, GETCURRENTCONTEXTINFO, GetCurrentContextInfo, IM_RuntimeTypeHandle_RefBool_RefIntPtr_RetVoid) +DEFINE_METHOD(LICENSE_INTEROP_PROXY, SAVEKEYINCURRENTCONTEXT, SaveKeyInCurrentContext, IM_IntPtr_RetVoid) + DEFINE_CLASS(RUNTIME_CLASS, WinRT, RuntimeClass) #endif // FEATURE_COMINTEROP @@ -483,7 +488,6 @@ DEFINE_CLASS(LCID_CONVERSION_TYPE, Interop, LCIDConversionAttrib DEFINE_CLASS(MARSHAL, Interop, Marshal) #ifdef FEATURE_COMINTEROP -DEFINE_METHOD(MARSHAL, LOAD_LICENSE_MANAGER, LoadLicenseManager, SM_Void_RetIntPtr) DEFINE_METHOD(MARSHAL, INITIALIZE_WRAPPER_FOR_WINRT, InitializeWrapperForWinRT, SM_Obj_RefIntPtr_RetVoid) DEFINE_METHOD(MARSHAL, GET_HR_FOR_EXCEPTION, GetHRForException, SM_Exception_RetInt) DEFINE_METHOD(MARSHAL, GET_HR_FOR_EXCEPTION_WINRT, GetHRForException_WinRT, SM_Exception_RetInt) diff --git a/src/vm/namespace.h b/src/vm/namespace.h index 7275584c03..ce40247f43 100644 --- a/src/vm/namespace.h +++ b/src/vm/namespace.h @@ -28,6 +28,7 @@ #define g_CollectionsGenericNS g_SystemNS ".Collections.Generic" #define g_InteropServicesNS g_SystemNS ".Runtime.InteropServices" +#define g_InternalInteropServicesNS "Internal.Runtime.InteropServices" #define g_ReflectionNS g_SystemNS ".Reflection" #define g_ReflectionEmitNS g_ReflectionNS ".Emit" diff --git a/src/vm/runtimecallablewrapper.cpp b/src/vm/runtimecallablewrapper.cpp index 83f246e6ca..51c2ee016f 100644 --- a/src/vm/runtimecallablewrapper.cpp +++ b/src/vm/runtimecallablewrapper.cpp @@ -104,18 +104,16 @@ IUnknown *ComClassFactory::CreateInstanceFromClassFactory(IClassFactory *pClassF } CONTRACT_END; - HRESULT hr = S_OK; - SafeComHolder<IClassFactory2> pClassFact2 = NULL; - SafeComHolder<IUnknown> pUnk = NULL; - BSTRHolder bstrKey = NULL; - - Thread *pThread = GetThread(); + HRESULT hr = S_OK; + SafeComHolder<IClassFactory2> pClassFact2 = NULL; + SafeComHolder<IUnknown> pUnk = NULL; + BSTRHolder bstrKey = NULL; - // Does this support licensing? - if (FAILED(SafeQueryInterface(pClassFact, IID_IClassFactory2, (IUnknown**)&pClassFact2))) + // If the class doesn't support licensing or if it is missing a managed + // type to use for querying a license, just use IClassFactory. + if (FAILED(SafeQueryInterface(pClassFact, IID_IClassFactory2, (IUnknown**)&pClassFact2)) + || m_pClassMT == NULL) { - // not a licensed class - just createinstance the usual way. - // Create an instance of the object. FrameWithCookie<DebuggerExitFrame> __def; { GCX_PREEMP(); @@ -131,127 +129,109 @@ IUnknown *ComClassFactory::CreateInstanceFromClassFactory(IClassFactory *pClassF } else { - if (m_pClassMT == NULL) + _ASSERTE(m_pClassMT != NULL); + + // Get the type to query for licensing. + TypeHandle rth = TypeHandle(m_pClassMT); + + struct { - // Create an instance of the object. - FrameWithCookie<DebuggerExitFrame> __def; + OBJECTREF pProxy; + OBJECTREF pType; + } gc; + gc.pProxy = NULL; // LicenseInteropProxy + gc.pType = NULL; + + GCPROTECT_BEGIN(gc); + + // Create an instance of the object + MethodDescCallSite createObj(METHOD__LICENSE_INTEROP_PROXY__CREATE); + gc.pProxy = createObj.Call_RetOBJECTREF(NULL); + gc.pType = rth.GetManagedClassObject(); + + // Query the current licensing context + MethodDescCallSite getCurrentContextInfo(METHOD__LICENSE_INTEROP_PROXY__GETCURRENTCONTEXTINFO, &gc.pProxy); + CLR_BOOL fDesignTime = FALSE; + ARG_SLOT args[4]; + args[0] = ObjToArgSlot(gc.pProxy); + args[1] = ObjToArgSlot(gc.pType); + args[2] = (ARG_SLOT)&fDesignTime; + args[3] = (ARG_SLOT)(BSTR*)&bstrKey; + + getCurrentContextInfo.Call(args); + + if (fDesignTime) + { + // If designtime, we're supposed to obtain the runtime license key + // from the component and save it away in the license context. + // (the design tool can then grab it and embedded it into the + // app it is creating) + if (bstrKey != NULL) { - GCX_PREEMP(); - hr = pClassFact->CreateInstance(punkOuter, IID_IUnknown, (void **)&pUnk); - if (FAILED(hr) && punkOuter) - { - hr = pClassFact->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk); - if (pfDidContainment) - *pfDidContainment = TRUE; - } + // It's illegal for our helper to return a non-null bstrKey + // when the context is design-time. But we'll try to do the + // right thing anyway. + _ASSERTE(!"We're not supposed to get here, but we'll try to cope anyway."); + SysFreeString(bstrKey); + bstrKey = NULL; } - __def.Pop(); - } - else - { - MethodTable *pHelperMT = pThread->GetDomain()->GetLicenseInteropHelperMethodTable(); - MethodDesc *pMD = MemberLoader::FindMethod(pHelperMT, "GetCurrentContextInfo", &gsig_IM_LicenseInteropHelper_GetCurrentContextInfo); - MethodDescCallSite getCurrentContextInfo(pMD); - - TypeHandle rth = TypeHandle(m_pClassMT); - - struct _gc { - OBJECTREF pHelper; - OBJECTREF pType; - } gc; - gc.pHelper = NULL; // LicenseInteropHelper - gc.pType = NULL; - - GCPROTECT_BEGIN(gc); - - gc.pHelper = pHelperMT->Allocate(); - gc.pType = rth.GetManagedClassObject(); - // First, crack open the current licensing context. - INT32 fDesignTime = 0; - ARG_SLOT args[4]; - args[0] = ObjToArgSlot(gc.pHelper); - args[1] = (ARG_SLOT)&fDesignTime; - args[2] = (ARG_SLOT)(BSTR*)&bstrKey; - args[3] = ObjToArgSlot(gc.pType); - - getCurrentContextInfo.Call(args); - - if (fDesignTime) { - // If designtime, we're supposed to obtain the runtime license key - // from the component and save it away in the license context - // (the design tool can then grab it and embedded it into the - // app it's creating.) - - if (bstrKey != NULL) - { - // It's illegal for our helper to return a non-null bstrKey - // when the context is design-time. But we'll try to do the - // right thing anyway. - _ASSERTE(!"We're not supposed to get here, but we'll try to cope anyway."); - SysFreeString(bstrKey); - bstrKey = NULL; - } + GCX_PREEMP(); + hr = pClassFact2->RequestLicKey(0, &bstrKey); + } - { - GCX_PREEMP(); - hr = pClassFact2->RequestLicKey(0, &bstrKey); - } - - // E_NOTIMPL is not a true failure. It simply indicates that - // the component doesn't support a runtime license key. - if (hr == E_NOTIMPL) - hr = S_OK; + // E_NOTIMPL is not a true failure. It simply indicates that + // the component doesn't support a runtime license key. + if (hr == E_NOTIMPL) + hr = S_OK; - if (SUCCEEDED(hr)) - { - MethodDesc *pMDSaveKey = MemberLoader::FindMethod(pHelperMT, "SaveKeyInCurrentContext", &gsig_IM_LicenseInteropHelper_SaveKeyInCurrentContext); - MethodDescCallSite saveKeyInCurrentContext(pMDSaveKey); + // Store the requested license key + if (SUCCEEDED(hr)) + { + MethodDescCallSite saveKeyInCurrentContext(METHOD__LICENSE_INTEROP_PROXY__SAVEKEYINCURRENTCONTEXT, &gc.pProxy); - args[0] = ObjToArgSlot(gc.pHelper); - args[1] = (ARG_SLOT)(BSTR)bstrKey; - saveKeyInCurrentContext.Call(args); - } + args[0] = ObjToArgSlot(gc.pProxy); + args[1] = (ARG_SLOT)(BSTR)bstrKey; + saveKeyInCurrentContext.Call(args); } - - if (SUCCEEDED(hr)) + } + + // Create the instance + if (SUCCEEDED(hr)) + { + FrameWithCookie<DebuggerExitFrame> __def; { - FrameWithCookie<DebuggerExitFrame> __def; + GCX_PREEMP(); + if (fDesignTime || bstrKey == NULL) { - GCX_PREEMP(); - - if (fDesignTime || bstrKey == NULL) + // Either it's design time, or the current context doesn't + // supply a runtime license key. + hr = pClassFact->CreateInstance(punkOuter, IID_IUnknown, (void **)&pUnk); + if (FAILED(hr) && punkOuter) { - // Either it's design time, or the current context doesn't - // supply a runtime license key. - hr = pClassFact->CreateInstance(punkOuter, IID_IUnknown, (void **)&pUnk); - if (FAILED(hr) && punkOuter) - { - hr = pClassFact->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk); - if (pfDidContainment) - *pfDidContainment = TRUE; - } + hr = pClassFact->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk); + if (pfDidContainment) + *pfDidContainment = TRUE; } - else + } + else + { + // It is runtime and we have a license key. + _ASSERTE(bstrKey != NULL); + hr = pClassFact2->CreateInstanceLic(punkOuter, NULL, IID_IUnknown, bstrKey, (void**)&pUnk); + if (FAILED(hr) && punkOuter) { - // It's runtime, and we do have a non-null license key. - _ASSERTE(bstrKey != NULL); - hr = pClassFact2->CreateInstanceLic(punkOuter, NULL, IID_IUnknown, bstrKey, (void**)&pUnk); - if (FAILED(hr) && punkOuter) - { - hr = pClassFact2->CreateInstanceLic(NULL, NULL, IID_IUnknown, bstrKey, (void**)&pUnk); - if (pfDidContainment) - *pfDidContainment = TRUE; - } - + hr = pClassFact2->CreateInstanceLic(NULL, NULL, IID_IUnknown, bstrKey, (void**)&pUnk); + if (pfDidContainment) + *pfDidContainment = TRUE; } } - __def.Pop(); } - - GCPROTECT_END(); + __def.Pop(); } + + GCPROTECT_END(); } if (FAILED(hr)) diff --git a/tests/src/Interop/COM/NETClients/Licensing/Program.cs b/tests/src/Interop/COM/NETClients/Licensing/Program.cs index 68ac88184d..794411830f 100644 --- a/tests/src/Interop/COM/NETClients/Licensing/Program.cs +++ b/tests/src/Interop/COM/NETClients/Licensing/Program.cs @@ -131,9 +131,10 @@ namespace NetClient try { - ActivateLicensedObject(); - ActivateUnderDesigntimeContext(); - ActivateUnderRuntimeContext(); + // Uncomment once https://github.com/dotnet/corefx/pull/35767 is in sync with coreclr repo + //ActivateLicensedObject(); + //ActivateUnderDesigntimeContext(); + //ActivateUnderRuntimeContext(); } catch (Exception e) { |