From eef94cb2a6e2067b3a958daf3065c7a20a5cf613 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 18 Mar 2019 15:20:24 -0700 Subject: [PATCH 01/11] First pass at adding winrt host entry-point. --- .../WindowsRuntime/ActivationFactoryLoader.cs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs new file mode 100644 index 000000000000..251392964934 --- /dev/null +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs @@ -0,0 +1,37 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Runtime.Loader; + +// +// Types in this file marked as 'public' are done so only to aid in +// testing of functionality and should not be considered publicly consumable. +// +namespace Internal.Runtime.InteropServices.WindowsRuntime +{ + public static class ActivationFactoryLoader + { + public static void GetActivationFactory( + [MarshalAs(UnmanagedType.HString)] string typeName, + [MarshalAs(UnmanagedType.Interface)] out IActivationFactory activationFactory) + { + activationFactory = null; + if (typeName is null) + { + throw new ArgumentNullException(nameof(typeName)); + } + + Type winRTType = System.StubHelpers.WinRTTypeNameConverter.GetTypeFromWinRTTypeName(typeName, out bool _); + + activationFactory = new ManagedActivationFactory(winRTType); + } + } +} From 7616f0529d44730a44e042adeae2c96713c4c486 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 18 Mar 2019 16:32:45 -0700 Subject: [PATCH 02/11] There's no way to specify HResult-swapping on a function called via hosted-interop so just return the HResult instead. --- .../WindowsRuntime/ActivationFactoryLoader.cs | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs index 251392964934..730fe99f051a 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs @@ -19,19 +19,27 @@ namespace Internal.Runtime.InteropServices.WindowsRuntime { public static class ActivationFactoryLoader { - public static void GetActivationFactory( + public static int GetActivationFactory( [MarshalAs(UnmanagedType.HString)] string typeName, [MarshalAs(UnmanagedType.Interface)] out IActivationFactory activationFactory) { activationFactory = null; - if (typeName is null) + try { - throw new ArgumentNullException(nameof(typeName)); - } - - Type winRTType = System.StubHelpers.WinRTTypeNameConverter.GetTypeFromWinRTTypeName(typeName, out bool _); + if (typeName is null) + { + throw new ArgumentNullException(nameof(typeName)); + } + + Type winRTType = System.StubHelpers.WinRTTypeNameConverter.GetTypeFromWinRTTypeName(typeName, out bool _); - activationFactory = new ManagedActivationFactory(winRTType); + activationFactory = new ManagedActivationFactory(winRTType); + } + catch (System.Exception ex) + { + return ex.HResult; + } + return 0; } } } From 0321896a6f504404bb5cf40b5f303b86eafeb10c Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 18 Mar 2019 16:56:19 -0700 Subject: [PATCH 03/11] Use the WindowsRuntimeMarshal class to create the activation factory and initialize it. --- src/System.Private.CoreLib/System.Private.CoreLib.csproj | 1 + .../InteropServices/WindowsRuntime/ActivationFactoryLoader.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/System.Private.CoreLib.csproj index b052272158d0..b4a1a717dabb 100644 --- a/src/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -293,6 +293,7 @@ + diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs index 730fe99f051a..2aa107449425 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs @@ -33,7 +33,7 @@ public static int GetActivationFactory( Type winRTType = System.StubHelpers.WinRTTypeNameConverter.GetTypeFromWinRTTypeName(typeName, out bool _); - activationFactory = new ManagedActivationFactory(winRTType); + activationFactory = WindowsRuntimeMarshal.GetManagedActivationFactory(winRTType); } catch (System.Exception ex) { From 92a345df63151d145b625c32abeb73db868d134d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 19 Mar 2019 16:12:12 -0700 Subject: [PATCH 04/11] Implement loading the dependent assemblies of a WinRT assembly into an isolated load context. --- .../WindowsRuntime/ActivationFactoryLoader.cs | 28 ++++++++++++++++++- .../src/System/RtType.cs | 7 +++-- .../Loader/AssemblyLoadContext.CoreCLR.cs | 21 ++++++++++++++ src/vm/appdomain.cpp | 3 ++ src/vm/assemblynative.cpp | 20 +++++++++++++ src/vm/assemblynative.hpp | 3 ++ src/vm/assemblyspec.cpp | 17 +++++++++-- src/vm/clrprivbinderwinrt.cpp | 3 +- src/vm/clrprivbinderwinrt.h | 11 ++++++++ src/vm/corhost.cpp | 2 +- src/vm/ecalllist.h | 3 ++ src/vm/interoputil.cpp | 8 +++--- src/vm/interoputil.h | 2 +- src/vm/runtimecallablewrapper.cpp | 4 +-- src/vm/runtimehandles.cpp | 3 ++ src/vm/runtimehandles.h | 4 ++- src/vm/stdinterfaces.cpp | 2 +- src/vm/stubhelpers.cpp | 8 +++++- src/vm/winrttypenameconverter.cpp | 16 +++++------ src/vm/winrttypenameconverter.h | 7 +++-- 20 files changed, 143 insertions(+), 29 deletions(-) diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs index 2aa107449425..da3649639463 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs @@ -19,7 +19,27 @@ namespace Internal.Runtime.InteropServices.WindowsRuntime { public static class ActivationFactoryLoader { + // Collection of all ALCs used for WinRT activation. + private static Dictionary s_AssemblyLoadContexts = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + + private static AssemblyLoadContext GetALC(string assemblyPath) + { + AssemblyLoadContext alc; + + lock (s_AssemblyLoadContexts) + { + if (!s_AssemblyLoadContexts.TryGetValue(assemblyPath, out alc)) + { + alc = new IsolatedComponentLoadContext(assemblyPath); + s_AssemblyLoadContexts.Add(assemblyPath, alc); + } + } + + return alc; + } + public static int GetActivationFactory( + IntPtr componentPath, [MarshalAs(UnmanagedType.HString)] string typeName, [MarshalAs(UnmanagedType.Interface)] out IActivationFactory activationFactory) { @@ -30,9 +50,15 @@ public static int GetActivationFactory( { throw new ArgumentNullException(nameof(typeName)); } + + AssemblyLoadContext context = GetALC(Marshal.PtrToStringUni(componentPath)); - Type winRTType = System.StubHelpers.WinRTTypeNameConverter.GetTypeFromWinRTTypeName(typeName, out bool _); + Type winRTType = context.LoadTypeForWinRTTypeNameInContext(typeName); + if (winRTType is null) + { + throw new TypeLoadException(typeName); + } activationFactory = WindowsRuntimeMarshal.GetManagedActivationFactory(winRTType); } catch (System.Exception ex) diff --git a/src/System.Private.CoreLib/src/System/RtType.cs b/src/System.Private.CoreLib/src/System/RtType.cs index 3d037712586b..c3e8d09066dd 100644 --- a/src/System.Private.CoreLib/src/System/RtType.cs +++ b/src/System.Private.CoreLib/src/System/RtType.cs @@ -3364,14 +3364,15 @@ public override Guid GUID #if FEATURE_COMINTEROP internal override bool IsWindowsRuntimeObjectImpl() => IsWindowsRuntimeObjectType(this); - internal override bool IsExportedToWindowsRuntimeImpl() => IsTypeExportedToWindowsRuntime(this); - [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool IsWindowsRuntimeObjectType(RuntimeType type); +#if FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION + internal override bool IsExportedToWindowsRuntimeImpl() => IsTypeExportedToWindowsRuntime(this); + [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool IsTypeExportedToWindowsRuntime(RuntimeType type); - +#endif // FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION #endif // FEATURE_COMINTEROP internal bool IsDelegate() => GetBaseType() == typeof(MulticastDelegate); diff --git a/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs index b36c382c38b7..7617df4b7164 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs @@ -217,6 +217,27 @@ private IntPtr GetResolvedUnmanagedDll(Assembly assembly, string unmanagedDllNam return IntPtr.Zero; } + + + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + private static extern void LoadTypeForWinRTTypeNameInContextInternal(IntPtr ptrNativeAssemblyLoadContext, string typeName, ObjectHandleOnStack loadedType); + + internal Type LoadTypeForWinRTTypeNameInContext(string typeName) + { + if (typeName is null) + { + throw new ArgumentNullException(typeName); + } + + lock (_unloadLock) + { + VerifyIsAlive(); + + Type type = null; + LoadTypeForWinRTTypeNameInContextInternal(_nativeAssemblyLoadContext, typeName, JitHelpers.GetObjectHandleOnStack(ref type)); + return type; + } + } [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] private static extern IntPtr GetLoadContextForAssembly(RuntimeAssembly assembly); diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index bcffb3b8aa92..85f778ea8a9f 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -5962,6 +5962,9 @@ PEAssembly * AppDomain::BindAssemblySpec( hr = BindAssemblySpecForHostedBinder(pSpec, pAssemblyName, m_pWinRtBinder, &pAssembly); if (FAILED(hr)) goto EndTry2; // Goto end of try block. + + PTR_CLRPrivAssemblyWinRT assem = dac_cast(pAssembly->GetHostAssembly()); + assem->SetFallbackBinder(pSpec->GetHostBinder()); EndTry2:; } // The combination of this conditional catch/ the following if statement which will throw reduces the count of exceptions diff --git a/src/vm/assemblynative.cpp b/src/vm/assemblynative.cpp index ed2ce660e7be..2383fdd1b549 100644 --- a/src/vm/assemblynative.cpp +++ b/src/vm/assemblynative.cpp @@ -412,6 +412,26 @@ void QCALLTYPE AssemblyNative::GetLocation(QCall::AssemblyHandle pAssembly, QCal END_QCALL; } + +#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION +void QCALLTYPE AssemblyNative::LoadTypeForWinRTTypeNameInContext(INT_PTR ptrAssemblyLoadContext, LPCWSTR pwzTypeName, QCall::ObjectHandleOnStack retType) +{ + QCALL_CONTRACT; + + BEGIN_QCALL; + + TypeHandle loadedType = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(pwzTypeName, nullptr, (ICLRPrivBinder*)ptrAssemblyLoadContext); + + if (!loadedType.IsNull()) + { + GCX_COOP(); + retType.Set(loadedType.GetManagedClassObject()); + } + + END_QCALL; +} +#endif + void QCALLTYPE AssemblyNative::GetType(QCall::AssemblyHandle pAssembly, LPCWSTR wszName, BOOL bThrowOnError, BOOL bIgnoreCase, QCall::ObjectHandleOnStack retType, QCall::ObjectHandleOnStack keepAlive) { CONTRACTL diff --git a/src/vm/assemblynative.hpp b/src/vm/assemblynative.hpp index 13db261359a5..0ce2fb232776 100644 --- a/src/vm/assemblynative.hpp +++ b/src/vm/assemblynative.hpp @@ -124,6 +124,9 @@ class AssemblyNative static void QCALLTYPE LoadFromInMemoryModule(INT_PTR ptrNativeAssemblyLoadContext, INT_PTR hModule, QCall::ObjectHandleOnStack retLoadedAssembly); #endif static Assembly* LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImage *pILImage, PEImage *pNIImage); +#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION + static void QCALLTYPE LoadTypeForWinRTTypeNameInContext(INT_PTR ptrAssemblyLoadContext, LPCWSTR pwzTypeName, QCall::ObjectHandleOnStack retType); +#endif static INT_PTR QCALLTYPE GetLoadContextForAssembly(QCall::AssemblyHandle pAssembly); static BOOL QCALLTYPE InternalTryGetRawMetadata(QCall::AssemblyHandle assembly, UINT8 **blobRef, INT32 *lengthRef); diff --git a/src/vm/assemblyspec.cpp b/src/vm/assemblyspec.cpp index a2323afe6b1b..de4d2c3b2c11 100644 --- a/src/vm/assemblyspec.cpp +++ b/src/vm/assemblyspec.cpp @@ -870,8 +870,21 @@ ICLRPrivBinder* AssemblySpec::GetBindingContextFromParentAssembly(AppDomain *pDo // types being referenced from Windows.Foundation.Winmd). // // If the AssemblySpec does not correspond to WinRT type but our parent assembly binder is a WinRT binder, - // then such an assembly will not be found by the binder. In such a case, we reset our binder reference. - pParentAssemblyBinder = NULL; + // then such an assembly will not be found by the binder. + // In such a case, the parent binder should be the fallback binder for the WinRT assembly if one exists. + ReleaseHolder assembly; + + if (SUCCEEDED(pParentAssemblyBinder->QueryInterface(&assembly))) + { + pParentAssemblyBinder = dac_cast(assembly.GetValue())->GetFallbackBinder(); + + // The fallback binder should not be a WinRT binder. + _ASSERTE(!AreSameBinderInstance(pWinRTBinder, pParentAssemblyBinder)); + } + else + { + pParentAssemblyBinder = NULL; + } } } #endif // defined(FEATURE_COMINTEROP) diff --git a/src/vm/clrprivbinderwinrt.cpp b/src/vm/clrprivbinderwinrt.cpp index 2441dae39996..83cdf88473f3 100644 --- a/src/vm/clrprivbinderwinrt.cpp +++ b/src/vm/clrprivbinderwinrt.cpp @@ -985,7 +985,8 @@ CLRPrivAssemblyWinRT::CLRPrivAssemblyWinRT( m_pIResourceNI(nullptr), m_pIBindResult(nullptr), m_fShareable(fShareable), - m_dwImageTypes(0) + m_dwImageTypes(0), + m_FallbackBinder(nullptr) { STANDARD_VM_CONTRACT; VALIDATE_ARG_THROW((pBinder != nullptr) && (pResourceIL != nullptr) && (pIBindResult != nullptr)); diff --git a/src/vm/clrprivbinderwinrt.h b/src/vm/clrprivbinderwinrt.h index e9cc1dfe9af9..da6f0d53f783 100644 --- a/src/vm/clrprivbinderwinrt.h +++ b/src/vm/clrprivbinderwinrt.h @@ -323,6 +323,16 @@ class CLRPrivAssemblyWinRT : DWORD dwImageType, DWORD * pdwImageType, ICLRPrivResource ** ppIResource); + + void SetFallbackBinder(ICLRPrivBinder* fallbackBinder) + { + m_FallbackBinder = clr::SafeAddRef(fallbackBinder); + } + + ICLRPrivBinder* GetFallbackBinder() + { + return m_FallbackBinder; + } private: //============================================================================================= @@ -336,4 +346,5 @@ class CLRPrivAssemblyWinRT : ReleaseHolder m_pIBindResult; BOOL m_fShareable; Volatile m_dwImageTypes; + ReleaseHolder m_FallbackBinder; }; // class CLRPrivAssemblyWinRT diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp index e02b514f5e30..7570ea1ca9e1 100644 --- a/src/vm/corhost.cpp +++ b/src/vm/corhost.cpp @@ -2407,7 +2407,7 @@ HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(LPCWSTR wszAssemblyName, GCX_COOP(); bool bIsPrimitive; - TypeHandle typeHandle = WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeName(wszTypeName, &bIsPrimitive); + TypeHandle typeHandle = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(wszTypeName, &bIsPrimitive); if (!bIsPrimitive && !typeHandle.IsNull() && !typeHandle.IsTypeDesc() && typeHandle.AsMethodTable()->IsExportedToWinRT()) { struct _gc { diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h index c1846332211d..e3ab28f5ce24 100644 --- a/src/vm/ecalllist.h +++ b/src/vm/ecalllist.h @@ -520,6 +520,9 @@ FCFuncStart(gAssemblyLoadContextFuncs) QCFuncElement("LoadFromPath", AssemblyNative::LoadFromPath) QCFuncElement("InternalLoadUnmanagedDllFromPath", AssemblyNative::InternalLoadUnmanagedDllFromPath) QCFuncElement("LoadFromStream", AssemblyNative::LoadFromStream) +#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION + QCFuncElement("LoadTypeForWinRTTypeNameInContextInternal", AssemblyNative::LoadTypeForWinRTTypeNameInContext) +#endif #ifndef FEATURE_PAL QCFuncElement("LoadFromInMemoryModuleInternal", AssemblyNative::LoadFromInMemoryModule) #endif diff --git a/src/vm/interoputil.cpp b/src/vm/interoputil.cpp index 5c000569d681..dc1cf90f82d3 100644 --- a/src/vm/interoputil.cpp +++ b/src/vm/interoputil.cpp @@ -5103,7 +5103,7 @@ void InitializeComInterop() } // Try to load a WinRT type. -TypeHandle GetWinRTType(SString* ssTypeName, BOOL bThrowIfNotFound) +TypeHandle LoadWinRTType(SString* ssTypeName, BOOL bThrowIfNotFound, ICLRPrivBinder* loadBinder /* =nullptr */) { CONTRACT (TypeHandle) { @@ -5116,8 +5116,8 @@ TypeHandle GetWinRTType(SString* ssTypeName, BOOL bThrowIfNotFound) TypeHandle typeHandle; SString ssAssemblyName(SString::Utf8Literal, "WindowsRuntimeAssemblyName, ContentType=WindowsRuntime"); - DomainAssembly *pAssembly = LoadDomainAssembly(&ssAssemblyName, NULL, - NULL, + DomainAssembly *pAssembly = LoadDomainAssembly(&ssAssemblyName, nullptr, + loadBinder, bThrowIfNotFound, ssTypeName); if (pAssembly != NULL) { @@ -6669,7 +6669,7 @@ TypeHandle GetClassFromIInspectable(IUnknown* pUnk, bool *pfSupportsIInspectable EX_TRY { LPCWSTR pszWinRTTypeName = (ssTmpClassName.IsEmpty() ? ssClassName : ssTmpClassName); - classTypeHandle = WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeName(pszWinRTTypeName, /*pbIsPrimitive = */ NULL); + classTypeHandle = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(pszWinRTTypeName, /*pbIsPrimitive = */ NULL); } EX_CATCH { diff --git a/src/vm/interoputil.h b/src/vm/interoputil.h index 872848b9df2e..311cedd102ff 100644 --- a/src/vm/interoputil.h +++ b/src/vm/interoputil.h @@ -443,7 +443,7 @@ MethodTable* GetClassFromIProvideClassInfo(IUnknown* pUnk); //-------------------------------------------------------------------------------- // Try to load a WinRT type. -TypeHandle GetWinRTType(SString* ssTypeName, BOOL bThrowIfNotFound); +TypeHandle LoadWinRTType(SString* ssTypeName, BOOL bThrowIfNotFound, ICLRPrivBinder* loadBinder = nullptr); //-------------------------------------------------------------------------------- // Try to get the class from IInspectable. diff --git a/src/vm/runtimecallablewrapper.cpp b/src/vm/runtimecallablewrapper.cpp index 48554086daca..540536ef5f5b 100644 --- a/src/vm/runtimecallablewrapper.cpp +++ b/src/vm/runtimecallablewrapper.cpp @@ -911,7 +911,7 @@ void WinRTClassFactory::Init() IfFailThrow(cap.GetNonNullString(&szFactoryInterfaceName, &cbFactoryInterfaceName)); StackSString strFactoryInterface(SString::Utf8, szFactoryInterfaceName, cbFactoryInterfaceName); - MethodTable *pMTFactoryInterface = GetWinRTType(&strFactoryInterface, /* bThrowIfNotFound = */ TRUE).GetMethodTable(); + MethodTable *pMTFactoryInterface = LoadWinRTType(&strFactoryInterface, /* bThrowIfNotFound = */ TRUE).GetMethodTable(); _ASSERTE(pMTFactoryInterface); m_factoryInterfaces.Append(pMTFactoryInterface); @@ -951,7 +951,7 @@ void WinRTClassFactory::Init() // copy the name to a temporary buffer and NULL terminate it StackSString ss(SString::Utf8, szName, cbName); - TypeHandle th = GetWinRTType(&ss, /* bThrowIfNotFound = */ TRUE); + TypeHandle th = LoadWinRTType(&ss, /* bThrowIfNotFound = */ TRUE); MethodTable *pMTStaticInterface = th.GetMethodTable(); m_staticInterfaces.Append(pMTStaticInterface); diff --git a/src/vm/runtimehandles.cpp b/src/vm/runtimehandles.cpp index c8782db7efed..7823ba63d9f2 100644 --- a/src/vm/runtimehandles.cpp +++ b/src/vm/runtimehandles.cpp @@ -29,6 +29,7 @@ #include "peimagelayout.inl" #include "eventtrace.h" #include "invokeutil.h" +#include "winrttypenameconverter.h" BOOL QCALLTYPE MdUtf8String::EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes) { @@ -384,6 +385,7 @@ FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClass } FCIMPLEND +#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsTypeExportedToWindowsRuntime, ReflectClassBaseObject *rtTypeUNSAFE) { FCALL_CONTRACT; @@ -401,6 +403,7 @@ FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsTypeExportedToWindowsRuntime, ReflectC FC_RETURN_BOOL(isExportedToWinRT); } FCIMPLEND +#endif #endif // FEATURE_COMINTEROP NOINLINE static MethodDesc * RestoreMethodHelper(MethodDesc * pMethod, LPVOID __me) diff --git a/src/vm/runtimehandles.h b/src/vm/runtimehandles.h index 66a27f4626b4..99ea03d37a23 100644 --- a/src/vm/runtimehandles.h +++ b/src/vm/runtimehandles.h @@ -160,8 +160,10 @@ class RuntimeTypeHandle { #ifdef FEATURE_COMINTEROP static FCDECL1(FC_BOOL_RET, IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE); +#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION static FCDECL1(FC_BOOL_RET, IsTypeExportedToWindowsRuntime, ReflectClassBaseObject *rtTypeUNSAFE); -#endif // FEATURE_COMINTEROP +#endif +#endif //FEATURE_COMINTEROP static void QCALLTYPE PrepareMemberInfoCache(EnregisteredTypeHandle pMemberInfoCache); diff --git a/src/vm/stdinterfaces.cpp b/src/vm/stdinterfaces.cpp index 1a9d0e2db132..15da1c8c2210 100644 --- a/src/vm/stdinterfaces.cpp +++ b/src/vm/stdinterfaces.cpp @@ -3121,7 +3121,7 @@ HRESULT __stdcall IStringable_ToString(IUnknown* pStringable, // Get the MethodTable for Windows.Foundation.IStringable. StackSString strIStringable(SString::Utf8, W("Windows.Foundation.IStringable")); - MethodTable *pMTIStringable = GetWinRTType(&strIStringable, /* bThrowIfNotFound = */ FALSE).GetMethodTable(); + MethodTable *pMTIStringable = LoadWinRTType(&strIStringable, /* bThrowIfNotFound = */ FALSE).GetMethodTable(); if (pMT != NULL && pMTIStringable != NULL && pMT->ImplementsInterface(pMTIStringable)) { diff --git a/src/vm/stubhelpers.cpp b/src/vm/stubhelpers.cpp index 72265b058496..6aa6165be627 100644 --- a/src/vm/stubhelpers.cpp +++ b/src/vm/stubhelpers.cpp @@ -705,6 +705,9 @@ FCIMPL4(IUnknown*, StubHelpers::InterfaceMarshaler__ConvertToNative, Object* pOb // This is only called in IL stubs which are in CER, so we don't need to worry about ThreadAbort HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_NO_THREAD_ABORT, pObj); + // We're going to be making some COM calls, better initialize COM. + EnsureComStarted(); + pIntf = MarshalObjectToInterface(&pObj, pItfMT, pClsMT, dwFlags); // No exception will be thrown here (including thread abort as it is delayed in IL stubs) @@ -725,6 +728,9 @@ FCIMPL4(Object*, StubHelpers::InterfaceMarshaler__ConvertToManaged, IUnknown **p OBJECTREF pObj = NULL; HELPER_METHOD_FRAME_BEGIN_RET_1(pObj); + + // We're going to be making some COM calls, better initialize COM. + EnsureComStarted(); UnmarshalObjectFromInterface(&pObj, ppUnk, pItfMT, pClsMT, dwFlags); @@ -893,7 +899,7 @@ FCIMPL2(ReflectClassBaseObject *, StubHelpers::WinRTTypeNameConverter__GetTypeFr HELPER_METHOD_FRAME_BEGIN_RET_2(refClass, refString); bool isPrimitive; - TypeHandle th = WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeName(refString->GetBuffer(), &isPrimitive); + TypeHandle th = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(refString->GetBuffer(), &isPrimitive); *pbIsPrimitive = isPrimitive; refClass = th.GetManagedClassObject(); diff --git a/src/vm/winrttypenameconverter.cpp b/src/vm/winrttypenameconverter.cpp index e30128b5df39..8f38fcefb946 100644 --- a/src/vm/winrttypenameconverter.cpp +++ b/src/vm/winrttypenameconverter.cpp @@ -828,7 +828,7 @@ bool WinRTTypeNameConverter::IsRedirectedWinRTSourceType(MethodTable *pMT) // Get TypeHandle from a WinRT type name // Parse the WinRT type name in the form of WinRTType=TypeName[] // -TypeHandle WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeName(LPCWSTR wszWinRTTypeName, bool *pbIsPrimitive) +TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(LPCWSTR wszWinRTTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder /* = nullptr */) { CONTRACTL { @@ -842,7 +842,7 @@ TypeHandle WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeName(LPCWSTR wszWi SString ssTypeName(SString::Literal, wszWinRTTypeName); - TypeHandle th = GetManagedTypeFromWinRTTypeNameInternal(&ssTypeName, pbIsPrimitive); + TypeHandle th = LoadManagedTypeForWinRTTypeNameInternal(&ssTypeName, pbIsPrimitive, loadBinder); if (th.IsNull()) { COMPlusThrowArgumentException(W("typeName"), NULL); @@ -900,7 +900,7 @@ extern "C" HRESULT WINAPI CrossgenRoParseTypeName(SString* typeName, DWORD *part // Return TypeHandle for the specified WinRT type name (supports generic type) // Updates wszWinRTTypeName pointer as it parse the string // -TypeHandle WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeNameInternal(SString *ssTypeName, bool *pbIsPrimitive) +TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeNameInternal(SString *ssTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder) { CONTRACTL { @@ -944,7 +944,7 @@ TypeHandle WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeNameInternal(SStri PCWSTR wszPart = WindowsGetStringRawBuffer(rhsPartNames[i], &cchPartLength); StackSString ssPartName(wszPart, cchPartLength); - rqPartTypes[i] = GetManagedTypeFromSimpleWinRTNameInternal(&ssPartName, NULL); + rqPartTypes[i] = GetManagedTypeFromSimpleWinRTNameInternal(&ssPartName, NULL, loadBinder); } #else //CROSSGEN_COMPILE @@ -963,7 +963,7 @@ TypeHandle WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeNameInternal(SStri // load the components for (DWORD i = 0; i < dwPartsCount; i++) { - rqPartTypes[i] = GetManagedTypeFromSimpleWinRTNameInternal(&rhsPartNames[i], NULL); + rqPartTypes[i] = GetManagedTypeFromSimpleWinRTNameInternal(&rhsPartNames[i], NULL, loadBinder); } delete[] rhsPartNames; @@ -980,7 +980,7 @@ TypeHandle WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeNameInternal(SStri } else { - return GetManagedTypeFromSimpleWinRTNameInternal(ssTypeName, pbIsPrimitive); + return GetManagedTypeFromSimpleWinRTNameInternal(ssTypeName, pbIsPrimitive, loadBinder); } } @@ -988,7 +988,7 @@ TypeHandle WinRTTypeNameConverter::GetManagedTypeFromWinRTTypeNameInternal(SStri // Return MethodTable* for the specified WinRT primitive type name (non-generic type) // Updates wszWinRTTypeName pointer as it parse the string // -TypeHandle WinRTTypeNameConverter::GetManagedTypeFromSimpleWinRTNameInternal(SString *ssTypeName, bool *pbIsPrimitive) +TypeHandle WinRTTypeNameConverter::GetManagedTypeFromSimpleWinRTNameInternal(SString *ssTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder) { CONTRACTL { @@ -1042,7 +1042,7 @@ TypeHandle WinRTTypeNameConverter::GetManagedTypeFromSimpleWinRTNameInternal(SSt // // A regular WinRT type // - return GetWinRTType(ssTypeName, TRUE); + return LoadWinRTType(ssTypeName, TRUE, loadBinder); } } diff --git a/src/vm/winrttypenameconverter.h b/src/vm/winrttypenameconverter.h index c3d139d87aa4..8776c4766670 100644 --- a/src/vm/winrttypenameconverter.h +++ b/src/vm/winrttypenameconverter.h @@ -17,6 +17,7 @@ #pragma once #include "..\md\winmd\inc\adapter.h" +#include "clrprivbinding.h" struct WinRTTypeNameInfo; @@ -90,7 +91,7 @@ public : // Get TypeHandle from a WinRT type name // Parse the WinRT type name in the form of WinRTType=TypeName[] // - static TypeHandle GetManagedTypeFromWinRTTypeName(LPCWSTR wszWinRTTypeName, bool *pbIsPrimitive); + static TypeHandle LoadManagedTypeForWinRTTypeName(LPCWSTR wszWinRTTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder = nullptr); private : @@ -108,13 +109,13 @@ private : // Return TypeHandle for the specified WinRT type name (supports generic type) // Updates wszWinRTTypeName pointer as it parse the string // - static TypeHandle GetManagedTypeFromWinRTTypeNameInternal(SString *ssTypeName, bool *pbIsPrimitive); + static TypeHandle LoadManagedTypeForWinRTTypeNameInternal(SString *ssTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder); // // Return MethodTable* for the specified WinRT primitive type name (non-generic type) // Updates wszWinRTTypeName pointer as it parse the string // - static TypeHandle GetManagedTypeFromSimpleWinRTNameInternal(SString *ssTypeName, bool *pbIsPrimitive); + static TypeHandle GetManagedTypeFromSimpleWinRTNameInternal(SString *ssTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder); static bool AppendWinRTTypeNameForManagedType( TypeHandle thManagedType, From 53336a0bc8780aa7202e95e51c7a4b409288d65e Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 26 Mar 2019 12:00:16 -0700 Subject: [PATCH 05/11] PR Feedback. --- .../WindowsRuntime/ActivationFactoryLoader.cs | 14 +++++++++++--- .../Runtime/Loader/AssemblyLoadContext.CoreCLR.cs | 2 +- src/vm/assemblyspec.cpp | 6 +----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs index da3649639463..04c9d6e37a13 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs @@ -20,6 +20,9 @@ namespace Internal.Runtime.InteropServices.WindowsRuntime public static class ActivationFactoryLoader { // Collection of all ALCs used for WinRT activation. + // Since each of the assemblies that act as the "key" here are WinRT assemblies + // we don't need to share this dictionary with the COM activation dictionary + // since there will be no overlap. private static Dictionary s_AssemblyLoadContexts = new Dictionary(StringComparer.InvariantCultureIgnoreCase); private static AssemblyLoadContext GetALC(string assemblyPath) @@ -38,8 +41,13 @@ private static AssemblyLoadContext GetALC(string assemblyPath) return alc; } - public static int GetActivationFactory( - IntPtr componentPath, + /// Get a WinRT activation factory for a given type name. + /// The path to the WinRT component that the type is expected (although not required) to be defined in. + /// The name of the component type to activate + /// The activation factory + [CLSCompliant(false)] + public unsafe static int GetActivationFactory( + char* componentPath, [MarshalAs(UnmanagedType.HString)] string typeName, [MarshalAs(UnmanagedType.Interface)] out IActivationFactory activationFactory) { @@ -51,7 +59,7 @@ public static int GetActivationFactory( throw new ArgumentNullException(nameof(typeName)); } - AssemblyLoadContext context = GetALC(Marshal.PtrToStringUni(componentPath)); + AssemblyLoadContext context = GetALC(Marshal.PtrToStringUni((IntPtr)componentPath)); Type winRTType = context.LoadTypeForWinRTTypeNameInContext(typeName); diff --git a/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs index 7617df4b7164..557ed1aefc4c 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs @@ -226,7 +226,7 @@ internal Type LoadTypeForWinRTTypeNameInContext(string typeName) { if (typeName is null) { - throw new ArgumentNullException(typeName); + throw new ArgumentNullException(nameof(typeName)); } lock (_unloadLock) diff --git a/src/vm/assemblyspec.cpp b/src/vm/assemblyspec.cpp index de4d2c3b2c11..10448f7e29eb 100644 --- a/src/vm/assemblyspec.cpp +++ b/src/vm/assemblyspec.cpp @@ -872,8 +872,8 @@ ICLRPrivBinder* AssemblySpec::GetBindingContextFromParentAssembly(AppDomain *pDo // If the AssemblySpec does not correspond to WinRT type but our parent assembly binder is a WinRT binder, // then such an assembly will not be found by the binder. // In such a case, the parent binder should be the fallback binder for the WinRT assembly if one exists. + pParentAssemblyBinder = NULL; ReleaseHolder assembly; - if (SUCCEEDED(pParentAssemblyBinder->QueryInterface(&assembly))) { pParentAssemblyBinder = dac_cast(assembly.GetValue())->GetFallbackBinder(); @@ -881,10 +881,6 @@ ICLRPrivBinder* AssemblySpec::GetBindingContextFromParentAssembly(AppDomain *pDo // The fallback binder should not be a WinRT binder. _ASSERTE(!AreSameBinderInstance(pWinRTBinder, pParentAssemblyBinder)); } - else - { - pParentAssemblyBinder = NULL; - } } } #endif // defined(FEATURE_COMINTEROP) From 2ba2ab8a6eeb9e951e62e5a036216488e7bb9e1a Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 26 Mar 2019 12:01:44 -0700 Subject: [PATCH 06/11] Fail to get the activation factory if the found type is not a managed type exported from a winmd. --- .../InteropServices/WindowsRuntime/ActivationFactoryLoader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs index 04c9d6e37a13..2714bf618a2d 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs @@ -42,7 +42,7 @@ private static AssemblyLoadContext GetALC(string assemblyPath) } /// Get a WinRT activation factory for a given type name. - /// The path to the WinRT component that the type is expected (although not required) to be defined in. + /// The path to the WinRT component that the type is expected to be defined in. /// The name of the component type to activate /// The activation factory [CLSCompliant(false)] @@ -63,7 +63,7 @@ public unsafe static int GetActivationFactory( Type winRTType = context.LoadTypeForWinRTTypeNameInContext(typeName); - if (winRTType is null) + if (winRTType is null || !winRTType.IsExportedToWindowsRuntime) { throw new TypeLoadException(typeName); } From d1e009b4a876702c19e160ba0ccb2edfb08c494a Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 26 Mar 2019 12:52:33 -0700 Subject: [PATCH 07/11] Rearrange parameters based on PR feedback. --- src/vm/assemblynative.cpp | 2 +- src/vm/corhost.cpp | 2 +- src/vm/interoputil.cpp | 2 +- src/vm/stubhelpers.cpp | 2 +- src/vm/winrttypenameconverter.cpp | 14 +++++++------- src/vm/winrttypenameconverter.h | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/vm/assemblynative.cpp b/src/vm/assemblynative.cpp index 2383fdd1b549..a0193ae488ac 100644 --- a/src/vm/assemblynative.cpp +++ b/src/vm/assemblynative.cpp @@ -420,7 +420,7 @@ void QCALLTYPE AssemblyNative::LoadTypeForWinRTTypeNameInContext(INT_PTR ptrAsse BEGIN_QCALL; - TypeHandle loadedType = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(pwzTypeName, nullptr, (ICLRPrivBinder*)ptrAssemblyLoadContext); + TypeHandle loadedType = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(pwzTypeName, (ICLRPrivBinder*)ptrAssemblyLoadContext, /* pbIsPrimitive */ nullptr); if (!loadedType.IsNull()) { diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp index 7570ea1ca9e1..e7f5f1d87ca1 100644 --- a/src/vm/corhost.cpp +++ b/src/vm/corhost.cpp @@ -2407,7 +2407,7 @@ HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(LPCWSTR wszAssemblyName, GCX_COOP(); bool bIsPrimitive; - TypeHandle typeHandle = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(wszTypeName, &bIsPrimitive); + TypeHandle typeHandle = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(wszTypeName, /* pLoadBinder */ nullptr, &bIsPrimitive); if (!bIsPrimitive && !typeHandle.IsNull() && !typeHandle.IsTypeDesc() && typeHandle.AsMethodTable()->IsExportedToWinRT()) { struct _gc { diff --git a/src/vm/interoputil.cpp b/src/vm/interoputil.cpp index dc1cf90f82d3..7cca714a1463 100644 --- a/src/vm/interoputil.cpp +++ b/src/vm/interoputil.cpp @@ -6669,7 +6669,7 @@ TypeHandle GetClassFromIInspectable(IUnknown* pUnk, bool *pfSupportsIInspectable EX_TRY { LPCWSTR pszWinRTTypeName = (ssTmpClassName.IsEmpty() ? ssClassName : ssTmpClassName); - classTypeHandle = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(pszWinRTTypeName, /*pbIsPrimitive = */ NULL); + classTypeHandle = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(pszWinRTTypeName, /* pLoadBinder */ nullptr, /*pbIsPrimitive = */ nullptr); } EX_CATCH { diff --git a/src/vm/stubhelpers.cpp b/src/vm/stubhelpers.cpp index 6aa6165be627..9cd2cf927cf8 100644 --- a/src/vm/stubhelpers.cpp +++ b/src/vm/stubhelpers.cpp @@ -899,7 +899,7 @@ FCIMPL2(ReflectClassBaseObject *, StubHelpers::WinRTTypeNameConverter__GetTypeFr HELPER_METHOD_FRAME_BEGIN_RET_2(refClass, refString); bool isPrimitive; - TypeHandle th = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(refString->GetBuffer(), &isPrimitive); + TypeHandle th = WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(refString->GetBuffer(), /* pLoadBinder */ nullptr, &isPrimitive); *pbIsPrimitive = isPrimitive; refClass = th.GetManagedClassObject(); diff --git a/src/vm/winrttypenameconverter.cpp b/src/vm/winrttypenameconverter.cpp index 8f38fcefb946..e9fd3c7ea058 100644 --- a/src/vm/winrttypenameconverter.cpp +++ b/src/vm/winrttypenameconverter.cpp @@ -828,7 +828,7 @@ bool WinRTTypeNameConverter::IsRedirectedWinRTSourceType(MethodTable *pMT) // Get TypeHandle from a WinRT type name // Parse the WinRT type name in the form of WinRTType=TypeName[] // -TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(LPCWSTR wszWinRTTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder /* = nullptr */) +TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(LPCWSTR wszWinRTTypeName, ICLRPrivBinder * loadBinder, bool *pbIsPrimitive) { CONTRACTL { @@ -842,7 +842,7 @@ TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeName(LPCWSTR wszWi SString ssTypeName(SString::Literal, wszWinRTTypeName); - TypeHandle th = LoadManagedTypeForWinRTTypeNameInternal(&ssTypeName, pbIsPrimitive, loadBinder); + TypeHandle th = LoadManagedTypeForWinRTTypeNameInternal(&ssTypeName, loadBinder, pbIsPrimitive); if (th.IsNull()) { COMPlusThrowArgumentException(W("typeName"), NULL); @@ -900,7 +900,7 @@ extern "C" HRESULT WINAPI CrossgenRoParseTypeName(SString* typeName, DWORD *part // Return TypeHandle for the specified WinRT type name (supports generic type) // Updates wszWinRTTypeName pointer as it parse the string // -TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeNameInternal(SString *ssTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder) +TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeNameInternal(SString *ssTypeName, ICLRPrivBinder* loadBinder, bool *pbIsPrimitive) { CONTRACTL { @@ -944,7 +944,7 @@ TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeNameInternal(SStri PCWSTR wszPart = WindowsGetStringRawBuffer(rhsPartNames[i], &cchPartLength); StackSString ssPartName(wszPart, cchPartLength); - rqPartTypes[i] = GetManagedTypeFromSimpleWinRTNameInternal(&ssPartName, NULL, loadBinder); + rqPartTypes[i] = GetManagedTypeFromSimpleWinRTNameInternal(&ssPartName, loadBinder, nullptr); } #else //CROSSGEN_COMPILE @@ -963,7 +963,7 @@ TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeNameInternal(SStri // load the components for (DWORD i = 0; i < dwPartsCount; i++) { - rqPartTypes[i] = GetManagedTypeFromSimpleWinRTNameInternal(&rhsPartNames[i], NULL, loadBinder); + rqPartTypes[i] = GetManagedTypeFromSimpleWinRTNameInternal(&rhsPartNames[i], loadBinder, NULL); } delete[] rhsPartNames; @@ -980,7 +980,7 @@ TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeNameInternal(SStri } else { - return GetManagedTypeFromSimpleWinRTNameInternal(ssTypeName, pbIsPrimitive, loadBinder); + return GetManagedTypeFromSimpleWinRTNameInternal(ssTypeName, loadBinder, pbIsPrimitive); } } @@ -988,7 +988,7 @@ TypeHandle WinRTTypeNameConverter::LoadManagedTypeForWinRTTypeNameInternal(SStri // Return MethodTable* for the specified WinRT primitive type name (non-generic type) // Updates wszWinRTTypeName pointer as it parse the string // -TypeHandle WinRTTypeNameConverter::GetManagedTypeFromSimpleWinRTNameInternal(SString *ssTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder) +TypeHandle WinRTTypeNameConverter::GetManagedTypeFromSimpleWinRTNameInternal(SString *ssTypeName, ICLRPrivBinder* loadBinder, bool *pbIsPrimitive) { CONTRACTL { diff --git a/src/vm/winrttypenameconverter.h b/src/vm/winrttypenameconverter.h index 8776c4766670..28dd3b6f7c06 100644 --- a/src/vm/winrttypenameconverter.h +++ b/src/vm/winrttypenameconverter.h @@ -91,7 +91,7 @@ public : // Get TypeHandle from a WinRT type name // Parse the WinRT type name in the form of WinRTType=TypeName[] // - static TypeHandle LoadManagedTypeForWinRTTypeName(LPCWSTR wszWinRTTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder = nullptr); + static TypeHandle LoadManagedTypeForWinRTTypeName(LPCWSTR wszWinRTTypeName, ICLRPrivBinder * loadBinder, bool *pbIsPrimitive); private : @@ -109,13 +109,13 @@ private : // Return TypeHandle for the specified WinRT type name (supports generic type) // Updates wszWinRTTypeName pointer as it parse the string // - static TypeHandle LoadManagedTypeForWinRTTypeNameInternal(SString *ssTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder); + static TypeHandle LoadManagedTypeForWinRTTypeNameInternal(SString *ssTypeName, ICLRPrivBinder* loadBinder, bool *pbIsPrimitive); // // Return MethodTable* for the specified WinRT primitive type name (non-generic type) // Updates wszWinRTTypeName pointer as it parse the string // - static TypeHandle GetManagedTypeFromSimpleWinRTNameInternal(SString *ssTypeName, bool *pbIsPrimitive, ICLRPrivBinder* loadBinder); + static TypeHandle GetManagedTypeFromSimpleWinRTNameInternal(SString *ssTypeName, ICLRPrivBinder* loadBinder, bool *pbIsPrimitive); static bool AppendWinRTTypeNameForManagedType( TypeHandle thManagedType, From 87cc7b911a558ee9466ea8fb07a63307f122c285 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 26 Mar 2019 12:54:03 -0700 Subject: [PATCH 08/11] Remove unneeded include. --- src/vm/runtimehandles.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vm/runtimehandles.cpp b/src/vm/runtimehandles.cpp index 7823ba63d9f2..f4e1e1d906b4 100644 --- a/src/vm/runtimehandles.cpp +++ b/src/vm/runtimehandles.cpp @@ -29,7 +29,6 @@ #include "peimagelayout.inl" #include "eventtrace.h" #include "invokeutil.h" -#include "winrttypenameconverter.h" BOOL QCALLTYPE MdUtf8String::EqualsCaseInsensitive(LPCUTF8 szLhs, LPCUTF8 szRhs, INT32 stringNumBytes) { From dbe5ded9dc81b8b56d8fe8f9ec7a716ff1e4ac6f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 26 Mar 2019 13:02:15 -0700 Subject: [PATCH 09/11] Make ActivationFactoryLoader internal. --- src/System.Private.CoreLib/ILLinkTrim.xml | 2 ++ .../WindowsRuntime/ActivationFactoryLoader.cs | 7 +------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/System.Private.CoreLib/ILLinkTrim.xml b/src/System.Private.CoreLib/ILLinkTrim.xml index e334c3703e53..5820e2be13b1 100644 --- a/src/System.Private.CoreLib/ILLinkTrim.xml +++ b/src/System.Private.CoreLib/ILLinkTrim.xml @@ -50,5 +50,7 @@ + + diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs index 2714bf618a2d..b0caad434667 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs @@ -11,13 +11,9 @@ using System.Runtime.InteropServices.WindowsRuntime; using System.Runtime.Loader; -// -// Types in this file marked as 'public' are done so only to aid in -// testing of functionality and should not be considered publicly consumable. -// namespace Internal.Runtime.InteropServices.WindowsRuntime { - public static class ActivationFactoryLoader + internal static class ActivationFactoryLoader { // Collection of all ALCs used for WinRT activation. // Since each of the assemblies that act as the "key" here are WinRT assemblies @@ -45,7 +41,6 @@ private static AssemblyLoadContext GetALC(string assemblyPath) /// The path to the WinRT component that the type is expected to be defined in. /// The name of the component type to activate /// The activation factory - [CLSCompliant(false)] public unsafe static int GetActivationFactory( char* componentPath, [MarshalAs(UnmanagedType.HString)] string typeName, From a484b3ee59cea36dc03625eeb3a6b10aa5babc55 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 2 Apr 2019 11:41:23 -0700 Subject: [PATCH 10/11] Fix null-ref in WinRT-dependent-assembly loading --- src/vm/assemblyspec.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vm/assemblyspec.cpp b/src/vm/assemblyspec.cpp index 10448f7e29eb..a044456ff994 100644 --- a/src/vm/assemblyspec.cpp +++ b/src/vm/assemblyspec.cpp @@ -872,9 +872,10 @@ ICLRPrivBinder* AssemblySpec::GetBindingContextFromParentAssembly(AppDomain *pDo // If the AssemblySpec does not correspond to WinRT type but our parent assembly binder is a WinRT binder, // then such an assembly will not be found by the binder. // In such a case, the parent binder should be the fallback binder for the WinRT assembly if one exists. + ICLRPrivBinder* pParentWinRTBinder = pParentAssemblyBinder; pParentAssemblyBinder = NULL; ReleaseHolder assembly; - if (SUCCEEDED(pParentAssemblyBinder->QueryInterface(&assembly))) + if (SUCCEEDED(pParentWinRTBinder->QueryInterface(&assembly))) { pParentAssemblyBinder = dac_cast(assembly.GetValue())->GetFallbackBinder(); From 795ed3ba77f343b2862a4180eae99863e85995f6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 2 Apr 2019 16:48:35 -0700 Subject: [PATCH 11/11] Remove extraneous "System." --- .../InteropServices/WindowsRuntime/ActivationFactoryLoader.cs | 2 +- .../src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs index b0caad434667..eb1c584b6c0d 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ActivationFactoryLoader.cs @@ -64,7 +64,7 @@ public unsafe static int GetActivationFactory( } activationFactory = WindowsRuntimeMarshal.GetManagedActivationFactory(winRTType); } - catch (System.Exception ex) + catch (Exception ex) { return ex.HResult; } diff --git a/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs index 996b052b6088..5cabe5158ea8 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs @@ -217,7 +217,6 @@ private IntPtr GetResolvedUnmanagedDll(Assembly assembly, string unmanagedDllNam return IntPtr.Zero; } - [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] private static extern void LoadTypeForWinRTTypeNameInContextInternal(IntPtr ptrNativeAssemblyLoadContext, string typeName, ObjectHandleOnStack loadedType);