diff options
author | Gaurav Khanna <gkhanna@microsoft.com> | 2016-05-13 09:55:19 -0700 |
---|---|---|
committer | Gaurav Khanna <gkhanna@microsoft.com> | 2016-05-15 10:53:25 -0700 |
commit | dd9317c7958f4fb65f45420433c587ea5e122ab2 (patch) | |
tree | 1dec7f6a88917f795d93526071b0d20cfabd8e0a /src/binder | |
parent | 48fa30ee5aa0b95a939934da40822f46b16ee807 (diff) | |
download | coreclr-dd9317c7958f4fb65f45420433c587ea5e122ab2.tar.gz coreclr-dd9317c7958f4fb65f45420433c587ea5e122ab2.tar.bz2 coreclr-dd9317c7958f4fb65f45420433c587ea5e122ab2.zip |
Enable overriding assemblies from TPA
Diffstat (limited to 'src/binder')
-rw-r--r-- | src/binder/assemblybinder.cpp | 10 | ||||
-rw-r--r-- | src/binder/clrprivbinderassemblyloadcontext.cpp | 58 | ||||
-rw-r--r-- | src/binder/clrprivbindercoreclr.cpp | 3 | ||||
-rw-r--r-- | src/binder/inc/assemblybinder.hpp | 1 |
4 files changed, 31 insertions, 41 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, |