summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs312
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs9
-rw-r--r--src/vm/appdomain.cpp42
-rw-r--r--src/vm/appdomain.hpp5
-rw-r--r--src/vm/metasig.h11
-rw-r--r--src/vm/mscorlib.h6
-rw-r--r--src/vm/namespace.h1
-rw-r--r--src/vm/runtimecallablewrapper.cpp206
-rw-r--r--tests/src/Interop/COM/NETClients/Licensing/Program.cs7
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)
{