summaryrefslogtreecommitdiff
path: root/src/binder/clrprivbinderassemblyloadcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/binder/clrprivbinderassemblyloadcontext.cpp')
-rw-r--r--src/binder/clrprivbinderassemblyloadcontext.cpp58
1 files changed, 37 insertions, 21 deletions
diff --git a/src/binder/clrprivbinderassemblyloadcontext.cpp b/src/binder/clrprivbinderassemblyloadcontext.cpp
index 8f3a3eef49..57f4ee72c4 100644
--- a/src/binder/clrprivbinderassemblyloadcontext.cpp
+++ b/src/binder/clrprivbinderassemblyloadcontext.cpp
@@ -61,19 +61,14 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindAssemblyByName(IAssemblyName *
SAFE_NEW(pAssemblyName, AssemblyName);
IF_FAIL_GO(pAssemblyName->Init(pIAssemblyName));
- // 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.
-
+ // 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))
{
- // Step 1 - Try to find the assembly within the LoadContext.
+ // 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.
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))
@@ -87,8 +82,7 @@ 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, m_pTPABinder, &pCoreCLRFoundAssembly);
+ hr = AssemblyBinder::BindUsingHostAssemblyResolver(GetManagedAssemblyLoadContext(), pAssemblyName, pIAssemblyName, &pCoreCLRFoundAssembly);
if (SUCCEEDED(hr))
{
// We maybe returned an assembly that was bound to a different AssemblyLoadContext instance.
@@ -148,19 +142,41 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindUsingPEImage( /* in */ PEImage *pP
IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_BAD_FORMAT));
}
- // 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).
+ // Ensure we are not being asked to bind to a TPA assembly
+ //
+ // Easy out for mscorlib
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)
{
- _ASSERTE(pCoreCLRFoundAssembly != NULL);
- pCoreCLRFoundAssembly->SetBinder(this);
- *ppAssembly = pCoreCLRFoundAssembly.Extract();
+ 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();
+ }
}
Exit:;
}