summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaurav Khanna <gkhanna@microsoft.com>2016-05-15 20:55:02 -0700
committerGaurav Khanna <gkhanna@microsoft.com>2016-05-15 20:55:02 -0700
commit71fe847d72f7b6a4d019c3bd2715ceba3bc1b33b (patch)
tree001332b1c9052e6b5c8d783c627872b6a6d503eb
parent06e38c02a88c6d0f290bacf7900eab1a523a0ccb (diff)
parentdd9317c7958f4fb65f45420433c587ea5e122ab2 (diff)
downloadcoreclr-71fe847d72f7b6a4d019c3bd2715ceba3bc1b33b.tar.gz
coreclr-71fe847d72f7b6a4d019c3bd2715ceba3bc1b33b.tar.bz2
coreclr-71fe847d72f7b6a4d019c3bd2715ceba3bc1b33b.zip
Merge pull request #4969 from gkhanna79/RelaxALC
Enable overriding assemblies from TPA
-rw-r--r--src/binder/assemblybinder.cpp10
-rw-r--r--src/binder/clrprivbinderassemblyloadcontext.cpp58
-rw-r--r--src/binder/clrprivbindercoreclr.cpp3
-rw-r--r--src/binder/inc/assemblybinder.hpp1
-rw-r--r--src/mscorlib/model.CoreLib.xml1
-rw-r--r--src/mscorlib/model.xml1
-rw-r--r--src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs85
-rw-r--r--src/vm/appdomain.cpp91
-rw-r--r--src/vm/mscorlib.h1
9 files changed, 169 insertions, 82 deletions
diff --git a/src/binder/assemblybinder.cpp b/src/binder/assemblybinder.cpp
index 55d0147b07..70f698f10f 100644
--- a/src/binder/assemblybinder.cpp
+++ b/src/binder/assemblybinder.cpp
@@ -50,7 +50,9 @@ BOOL IsCompilationProcess();
#include "clrprivbindercoreclr.h"
#include "clrprivbinderassemblyloadcontext.h"
// Helper function in the VM, invoked by the Binder, to invoke the host assembly resolver
-extern HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToBindWithin, IAssemblyName *pIAssemblyName, ICLRPrivAssembly **ppLoadedAssembly);
+extern HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToBindWithin,
+ IAssemblyName *pIAssemblyName, CLRPrivBinderCoreCLR *pTPABinder,
+ BINDER_SPACE::AssemblyName *pAssemblyName, ICLRPrivAssembly **ppLoadedAssembly);
// Helper to check if we have a host assembly resolver set
extern BOOL RuntimeCanUseAppPathAssemblyResolver(DWORD adid);
@@ -1814,6 +1816,7 @@ namespace BINDER_SPACE
HRESULT AssemblyBinder::BindUsingHostAssemblyResolver (/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin,
/* in */ AssemblyName *pAssemblyName,
/* in */ IAssemblyName *pIAssemblyName,
+ /* in */ CLRPrivBinderCoreCLR *pTPABinder,
/* out */ Assembly **ppAssembly)
{
HRESULT hr = E_FAIL;
@@ -1821,9 +1824,10 @@ HRESULT AssemblyBinder::BindUsingHostAssemblyResolver (/* in */ INT_PTR pManaged
_ASSERTE(pManagedAssemblyLoadContextToBindWithin != NULL);
- // Call into the VM to use the HostAssemblyResolver and load the assembly
+ // RuntimeInvokeHostAssemblyResolver will perform steps 2-4 of CLRPrivBinderAssemblyLoadContext::BindAssemblyByName.
ICLRPrivAssembly *pLoadedAssembly = NULL;
- hr = RuntimeInvokeHostAssemblyResolver(pManagedAssemblyLoadContextToBindWithin, pIAssemblyName, &pLoadedAssembly);
+ hr = RuntimeInvokeHostAssemblyResolver(pManagedAssemblyLoadContextToBindWithin, pIAssemblyName,
+ pTPABinder, pAssemblyName, &pLoadedAssembly);
if (SUCCEEDED(hr))
{
_ASSERTE(pLoadedAssembly != NULL);
diff --git a/src/binder/clrprivbinderassemblyloadcontext.cpp b/src/binder/clrprivbinderassemblyloadcontext.cpp
index 57f4ee72c4..8f3a3eef49 100644
--- a/src/binder/clrprivbinderassemblyloadcontext.cpp
+++ b/src/binder/clrprivbinderassemblyloadcontext.cpp
@@ -61,14 +61,19 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindAssemblyByName(IAssemblyName *
SAFE_NEW(pAssemblyName, AssemblyName);
IF_FAIL_GO(pAssemblyName->Init(pIAssemblyName));
- // Check if the assembly is in the TPA list or not. Don't search app paths when using the TPA binder because the actual
- // binder is using a host assembly resolver.
- hr = m_pTPABinder->BindAssemblyByNameWorker(pAssemblyName, &pCoreCLRFoundAssembly, true /* excludeAppPaths */);
- if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
+ // When LoadContext needs to resolve an assembly reference, it will go through the following lookup order:
+ //
+ // 1) Lookup the assembly within the LoadContext itself. If assembly is found, use it.
+ // 2) Invoke the LoadContext's Load method implementation. If assembly is found, use it.
+ // 3) Lookup the assembly within TPABinder. If assembly is found, use it.
+ // 4) Invoke the LoadContext's Resolving event. If assembly is found, use it.
+ // 5) Raise exception.
+ //
+ // This approach enables a LoadContext to override assemblies that have been loaded in TPA context by loading
+ // a different (or even the same!) version.
+
{
- // If we could not find the assembly in the TPA list,
- // then bind to it in the context of the current binder.
- // If we find it already loaded, we will return the reference.
+ // Step 1 - Try to find the assembly within the LoadContext.
hr = BindAssemblyByNameWorker(pAssemblyName, &pCoreCLRFoundAssembly);
if ((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
(hr == FUSION_E_APP_DOMAIN_LOCKED) || (hr == FUSION_E_REF_DEF_MISMATCH))
@@ -82,7 +87,8 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindAssemblyByName(IAssemblyName *
// Thus, if default binder has been overridden, then invoke it in an attempt to perform the binding for it make the call
// of what to do next. The host-overridden binder can either fail the bind or return reference to an existing assembly
// that has been loaded.
- hr = AssemblyBinder::BindUsingHostAssemblyResolver(GetManagedAssemblyLoadContext(), pAssemblyName, pIAssemblyName, &pCoreCLRFoundAssembly);
+ //
+ hr = AssemblyBinder::BindUsingHostAssemblyResolver(GetManagedAssemblyLoadContext(), pAssemblyName, pIAssemblyName, m_pTPABinder, &pCoreCLRFoundAssembly);
if (SUCCEEDED(hr))
{
// We maybe returned an assembly that was bound to a different AssemblyLoadContext instance.
@@ -142,41 +148,19 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindUsingPEImage( /* in */ PEImage *pP
IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_BAD_FORMAT));
}
- // Ensure we are not being asked to bind to a TPA assembly
- //
- // Easy out for mscorlib
+ // Disallow attempt to bind to the core library. Aside from that,
+ // the LoadContext can load any assembly (even if it was in a different LoadContext like TPA).
if (pAssemblyName->IsMscorlib())
{
IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
}
+ hr = AssemblyBinder::BindUsingPEImage(&m_appContext, pAssemblyName, pPEImage, PeKind, pIMetaDataAssemblyImport, &pCoreCLRFoundAssembly);
+ if (hr == S_OK)
{
- SString& simpleName = pAssemblyName->GetSimpleName();
- ApplicationContext *pTPAApplicationContext = m_pTPABinder->GetAppContext();
- SimpleNameToFileNameMap * tpaMap = pTPAApplicationContext->GetTpaList();
- if (tpaMap->LookupPtr(simpleName.GetUnicode()) != NULL)
- {
- // The simple name of the assembly being requested to be bound was found in the TPA list.
- // Now, perform the actual bind to see if the assembly was really in the TPA assembly or not.
- // Don't search app paths when using the TPA binder because the actual binder is using a host assembly resolver.
- hr = m_pTPABinder->BindAssemblyByNameWorker(pAssemblyName, &pCoreCLRFoundAssembly, true /* excludeAppPaths */);
- if (SUCCEEDED(hr))
- {
- if (pCoreCLRFoundAssembly->GetIsInGAC())
- {
- // If we were able to bind to a TPA assembly, then fail the load
- IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
- }
- }
- }
-
- hr = AssemblyBinder::BindUsingPEImage(&m_appContext, pAssemblyName, pPEImage, PeKind, pIMetaDataAssemblyImport, &pCoreCLRFoundAssembly);
- if (hr == S_OK)
- {
- _ASSERTE(pCoreCLRFoundAssembly != NULL);
- pCoreCLRFoundAssembly->SetBinder(this);
- *ppAssembly = pCoreCLRFoundAssembly.Extract();
- }
+ _ASSERTE(pCoreCLRFoundAssembly != NULL);
+ pCoreCLRFoundAssembly->SetBinder(this);
+ *ppAssembly = pCoreCLRFoundAssembly.Extract();
}
Exit:;
}
diff --git a/src/binder/clrprivbindercoreclr.cpp b/src/binder/clrprivbindercoreclr.cpp
index a2fb1c8237..d62af867ef 100644
--- a/src/binder/clrprivbindercoreclr.cpp
+++ b/src/binder/clrprivbindercoreclr.cpp
@@ -80,7 +80,8 @@ HRESULT CLRPrivBinderCoreCLR::BindAssemblyByName(IAssemblyName *pIAssemblyNa
INT_PTR pManagedAssemblyLoadContext = GetManagedAssemblyLoadContext();
if (pManagedAssemblyLoadContext != NULL)
{
- hr = AssemblyBinder::BindUsingHostAssemblyResolver(pManagedAssemblyLoadContext, pAssemblyName, pIAssemblyName, &pCoreCLRFoundAssembly);
+ hr = AssemblyBinder::BindUsingHostAssemblyResolver(pManagedAssemblyLoadContext, pAssemblyName, pIAssemblyName,
+ NULL, &pCoreCLRFoundAssembly);
if (SUCCEEDED(hr))
{
// We maybe returned an assembly that was bound to a different AssemblyLoadContext instance.
diff --git a/src/binder/inc/assemblybinder.hpp b/src/binder/inc/assemblybinder.hpp
index 87d6491a92..3a1f1e45fd 100644
--- a/src/binder/inc/assemblybinder.hpp
+++ b/src/binder/inc/assemblybinder.hpp
@@ -78,6 +78,7 @@ namespace BINDER_SPACE
static HRESULT BindUsingHostAssemblyResolver (/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin,
/* in */ AssemblyName *pAssemblyName,
/* in */ IAssemblyName *pIAssemblyName,
+ /* in */ CLRPrivBinderCoreCLR *pTPABinder,
/* out */ Assembly **ppAssembly);
static HRESULT BindUsingPEImage(/* in */ ApplicationContext *pApplicationContext,
diff --git a/src/mscorlib/model.CoreLib.xml b/src/mscorlib/model.CoreLib.xml
index 1f1408d446..7b5214b2f8 100644
--- a/src/mscorlib/model.CoreLib.xml
+++ b/src/mscorlib/model.CoreLib.xml
@@ -951,6 +951,7 @@
<Member Name="LoadFromStream(System.IO.Stream)" />
<Member Name="LoadFromStream(System.IO.Stream,System.IO.Stream)" />
<Member Name="Resolve(System.IntPtr,System.Reflection.AssemblyName)" />
+ <Member Name="ResolveUsingResolvingEvent(System.IntPtr,System.Reflection.AssemblyName)" />
<Member Name="ResolveUnmanagedDll(System.String,System.IntPtr)" />
<Member Name="LoadUnmanagedDll(System.String)" />
<Member Name="LoadUnmanagedDllFromPath(System.String)" />
diff --git a/src/mscorlib/model.xml b/src/mscorlib/model.xml
index 225249f83c..ef2774a9f3 100644
--- a/src/mscorlib/model.xml
+++ b/src/mscorlib/model.xml
@@ -951,6 +951,7 @@
<Member Name="LoadFromStream(System.IO.Stream)" />
<Member Name="LoadFromStream(System.IO.Stream,System.IO.Stream)" />
<Member Name="Resolve(System.IntPtr,System.Reflection.AssemblyName)" />
+ <Member Name="ResolveUsingResolvingEvent(System.IntPtr,System.Reflection.AssemblyName)" />
<Member Name="ResolveUnmanagedDll(System.String,System.IntPtr)" />
<Member Name="LoadUnmanagedDll(System.String)" />
<Member Name="LoadUnmanagedDllFromPath(System.String)" />
diff --git a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
index 6b53ba3b64..527fbe4d6c 100644
--- a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
+++ b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
@@ -111,13 +111,6 @@ namespace System.Runtime.Loader
throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), "nativeImagePath");
}
- // Check if the nativeImagePath has ".ni.dll" or ".ni.exe" extension
- if (!(nativeImagePath.EndsWith(".ni.dll", StringComparison.InvariantCultureIgnoreCase) ||
- nativeImagePath.EndsWith(".ni.exe", StringComparison.InvariantCultureIgnoreCase)))
- {
- throw new ArgumentException("nativeImagePath");
- }
-
if (assemblyPath != null && Path.IsRelative(assemblyPath))
{
throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), "assemblyPath");
@@ -184,7 +177,17 @@ namespace System.Runtime.Loader
{
AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target);
- return context.LoadFromAssemblyName(assemblyName);
+ return context.ResolveUsingLoad(assemblyName);
+ }
+
+ // This method is invoked by the VM to resolve an assembly reference using the Resolving event
+ // after trying assembly resolution via Load override and TPA load context without success.
+ private static Assembly ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
+ {
+ AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target);
+
+ // Invoke the AssemblyResolve event callbacks if wired up
+ return context.ResolveUsingEvent(assemblyName);
}
private Assembly GetFirstResolvedAssembly(AssemblyName assemblyName)
@@ -210,23 +213,8 @@ namespace System.Runtime.Loader
return resolvedAssembly;
}
- public Assembly LoadFromAssemblyName(AssemblyName assemblyName)
+ private Assembly ValidateAssemblyNameWithSimpleName(Assembly assembly, string requestedSimpleName)
{
- // AssemblyName is mutable. Cache the expected name before anybody gets a chance to modify it.
- string requestedSimpleName = assemblyName.Name;
-
- Assembly assembly = Load(assemblyName);
- if (assembly == null)
- {
- // Invoke the AssemblyResolve event callbacks if wired up
- assembly = GetFirstResolvedAssembly(assemblyName);
- }
-
- if (assembly == null)
- {
- throw new FileNotFoundException(Environment.GetResourceString("IO.FileLoad"), requestedSimpleName);
- }
-
// Get the name of the loaded assembly
string loadedSimpleName = null;
@@ -244,7 +232,56 @@ namespace System.Runtime.Loader
throw new InvalidOperationException(Environment.GetResourceString("Argument_CustomAssemblyLoadContextRequestedNameMismatch"));
return assembly;
+
+ }
+
+ private Assembly ResolveUsingLoad(AssemblyName assemblyName)
+ {
+ string simpleName = assemblyName.Name;
+ Assembly assembly = Load(assemblyName);
+
+ if (assembly != null)
+ {
+ assembly = ValidateAssemblyNameWithSimpleName(assembly, simpleName);
+ }
+
+ return assembly;
+ }
+
+ private Assembly ResolveUsingEvent(AssemblyName assemblyName)
+ {
+ string simpleName = assemblyName.Name;
+
+ // Invoke the AssemblyResolve event callbacks if wired up
+ Assembly assembly = GetFirstResolvedAssembly(assemblyName);
+ if (assembly != null)
+ {
+ assembly = ValidateAssemblyNameWithSimpleName(assembly, simpleName);
+ }
+
+ // Since attempt to resolve the assembly via Resolving event is the last option,
+ // throw an exception if we do not find any assembly.
+ if (assembly == null)
+ {
+ throw new FileNotFoundException(Environment.GetResourceString("IO.FileLoad"), simpleName);
+ }
+
+ return assembly;
+ }
+
+ public Assembly LoadFromAssemblyName(AssemblyName assemblyName)
+ {
+ // AssemblyName is mutable. Cache the expected name before anybody gets a chance to modify it.
+ string requestedSimpleName = assemblyName.Name;
+
+ Assembly assembly = ResolveUsingLoad(assemblyName);
+ if (assembly == null)
+ {
+ // Invoke the AssemblyResolve event callbacks if wired up
+ assembly = ResolveUsingEvent(assemblyName);
+ }
+ return assembly;
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp
index 3827d9b0ac..53c68776d3 100644
--- a/src/vm/appdomain.cpp
+++ b/src/vm/appdomain.cpp
@@ -14214,7 +14214,7 @@ BOOL RuntimeCanUseAppPathAssemblyResolver(DWORD adid)
}
// Returns S_OK if the assembly was successfully loaded
-HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToBindWithin, IAssemblyName *pIAssemblyName, ICLRPrivAssembly **ppLoadedAssembly)
+HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToBindWithin, IAssemblyName *pIAssemblyName, CLRPrivBinderCoreCLR *pTPABinder, BINDER_SPACE::AssemblyName *pAssemblyName, ICLRPrivAssembly **ppLoadedAssembly)
{
CONTRACTL
{
@@ -14243,6 +14243,8 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB
GCPROTECT_BEGIN(_gcRefs);
+ ICLRPrivAssembly *pAssemblyBindingContext = NULL;
+
// Prepare to invoke System.Runtime.Loader.AssemblyLoadContext.Resolve method.
//
// First, initialize an assembly spec for the requested assembly
@@ -14251,7 +14253,9 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB
hr = spec.Init(pIAssemblyName);
if (SUCCEEDED(hr))
{
- // Next, allocate an AssemblyName managed object
+ // Step 2 (of CLRPrivBinderAssemblyLoadContext::BindUsingAssemblyName) - Invoke Load method
+ //
+ // Allocate an AssemblyName managed object
_gcRefs.oRefAssemblyName = (ASSEMBLYNAMEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME));
// Initialize the AssemblyName object from the AssemblySpec
@@ -14268,10 +14272,63 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB
ObjToArgSlot(_gcRefs.oRefAssemblyName), // AssemblyName instance
};
+ bool fResolvedAssembly = true;
+ bool fResolvedAssemblyViaTPALoadContext = false;
+
// Make the call
_gcRefs.oRefLoadedAssembly = (ASSEMBLYREF) methLoadAssembly.Call_RetOBJECTREF(args);
- if (_gcRefs.oRefLoadedAssembly != NULL)
+ if (_gcRefs.oRefLoadedAssembly == NULL)
+ {
+ fResolvedAssembly = false;
+ }
+
+ if (!fResolvedAssembly)
+ {
+ // Step 3 (of CLRPrivBinderAssemblyLoadContext::BindUsingAssemblyName)
+ //
+ // If we could not resolve the assembly using Load method, then bind using TPA binder if present in its
+ // load context.
+ if (pTPABinder != NULL)
+ {
+ // Switch to pre-emp mode before calling into the binder
+ GCX_PREEMP();
+ BINDER_SPACE::Assembly *pCoreCLRFoundAssembly = NULL;
+ hr = pTPABinder->BindAssemblyByNameWorker(pAssemblyName, &pCoreCLRFoundAssembly, true /* excludeAppPaths */);
+ if (SUCCEEDED(hr))
+ {
+ pAssemblyBindingContext = pCoreCLRFoundAssembly;
+ fResolvedAssembly = true;
+ fResolvedAssemblyViaTPALoadContext = true;
+ }
+ }
+ }
+
+ if (!fResolvedAssembly)
+ {
+ // Step 4 (of CLRPrivBinderAssemblyLoadContext::BindUsingAssemblyName)
+ //
+ // If we couldnt resolve the assembly using TPA LoadContext as well, then
+ // attempt to resolve it using the Resolving event.
+ // Finally, setup arguments for invocation
+ BinderMethodID idHAR_ResolveUsingEvent = METHOD__ASSEMBLYLOADCONTEXT__RESOLVEUSINGEVENT;
+ MethodDescCallSite methLoadAssembly(idHAR_ResolveUsingEvent);
+
+ // Setup the arguments for the call
+ ARG_SLOT args[2] =
+ {
+ PtrToArgSlot(pManagedAssemblyLoadContextToBindWithin), // IntPtr for managed assembly load context instance
+ ObjToArgSlot(_gcRefs.oRefAssemblyName), // AssemblyName instance
+ };
+
+ // Make the call
+ _gcRefs.oRefLoadedAssembly = (ASSEMBLYREF) methLoadAssembly.Call_RetOBJECTREF(args);
+ }
+
+ if (fResolvedAssembly && !fResolvedAssemblyViaTPALoadContext)
{
+ // If we are here, assembly was successfully resolved via Load or Resolving events.
+ _ASSERTE(_gcRefs.oRefLoadedAssembly != NULL);
+
// We were able to get the assembly loaded. Now, get its name since the host could have
// performed the resolution using an assembly with different name.
DomainAssembly *pDomainAssembly = _gcRefs.oRefLoadedAssembly->GetDomainAssembly();
@@ -14302,23 +14359,23 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB
// Is the assembly already bound using a binding context that will be incompatible?
// An example is attempting to consume an assembly bound to WinRT binder.
- ICLRPrivAssembly *pAssemblyBindingContext = pLoadedPEAssembly->GetHostAssembly();
-
+ pAssemblyBindingContext = pLoadedPEAssembly->GetHostAssembly();
+ }
+
#ifdef FEATURE_COMINTEROP
- if (AreSameBinderInstance(pAssemblyBindingContext, GetAppDomain()->GetWinRtBinder()))
- {
- // It is invalid to return an assembly bound to an incompatible binder
- *ppLoadedAssembly = NULL;
- SString name;
- spec.GetFileOrDisplayName(0, name);
- COMPlusThrowHR(COR_E_INVALIDOPERATION, IDS_HOST_ASSEMBLY_RESOLVER_INCOMPATIBLE_BINDING_CONTEXT, name);
- }
+ if (AreSameBinderInstance(pAssemblyBindingContext, GetAppDomain()->GetWinRtBinder()))
+ {
+ // It is invalid to return an assembly bound to an incompatible binder
+ *ppLoadedAssembly = NULL;
+ SString name;
+ spec.GetFileOrDisplayName(0, name);
+ COMPlusThrowHR(COR_E_INVALIDOPERATION, IDS_HOST_ASSEMBLY_RESOLVER_INCOMPATIBLE_BINDING_CONTEXT, name);
+ }
#endif // FEATURE_COMINTEROP
- // Get the ICLRPrivAssembly reference to return back to.
- *ppLoadedAssembly = clr::SafeAddRef(pLoadedPEAssembly->GetHostAssembly());
- hr = S_OK;
- }
+ // Get the ICLRPrivAssembly reference to return back to.
+ *ppLoadedAssembly = clr::SafeAddRef(pAssemblyBindingContext);
+ hr = S_OK;
}
GCPROTECT_END();
diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h
index 9620627bea..4c27965248 100644
--- a/src/vm/mscorlib.h
+++ b/src/vm/mscorlib.h
@@ -1674,6 +1674,7 @@ DEFINE_METHOD(FIRSTCHANCE_EVENTARGS, CTOR, .ctor,
DEFINE_CLASS(ASSEMBLYLOADCONTEXT, Loader, AssemblyLoadContext)
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVE, Resolve, SM_IntPtr_AssemblyName_RetAssemblyBase)
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVEUNMANAGEDDLL, ResolveUnmanagedDll, SM_Str_IntPtr_RetIntPtr)
+DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVEUSINGEVENT, ResolveUsingResolvingEvent, SM_IntPtr_AssemblyName_RetAssemblyBase)
#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)