/** probably should be exposed on an instance (of something) method rather that magically calling GetAppDomain() **/
ICLRPrivAssembly* RaiseAssemblyResolveEvent(IAssemblyName *pAssemblyName, ICLRPrivAssembly* pRequestingAssembly);
- /** PLACEHOLDER - CLRPRivBinderFusion::BindAssemblyByName throws, despite being an HRESULT function,
- most presumably because returning HRESULT is too lossy **/
-
/** Ultimately, only the binder can do ref-def matching, and it should be opaque to CLR.
This is not trivial to do, however, since we cannot do data conversion as the function is nofault **/
BOOL CompareHostBinderSpecs(AssemblySpec* a1, AssemblySpec* a2);
+++ /dev/null
-// 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.
-
-
-
-#include "common.h" // precompiled header
-
-#ifndef DACCESS_COMPILE
-
-//=====================================================================================================================
-#include "assemblyspec.hpp"
-#include "corhdr.h"
-#include "domainfile.h"
-#include "fusion.h"
-#include "policy.h"
-#include "sstring.h"
-#include "stackingallocator.h"
-#include "threads.h"
-#include "clrprivbinderfusion.h"
-#include "clrprivbinderutil.h"
-#include "fusionlogging.h"
-
-using namespace CLRPrivBinderUtil;
-
-//=================================================================================================
-#define STDMETHOD_NOTIMPL(...) \
- STDMETHOD(__VA_ARGS__) \
- { \
- WRAPPER_NO_CONTRACT; \
- _ASSERTE_MSG(false, "Method not implemented."); \
- return E_NOTIMPL; \
- }
-
-//=================================================================================================
-static HRESULT PropagateOutStringArgument(
- __in LPCSTR pszValue,
- __out_ecount_opt(*pcchArg) LPWSTR pwzArg,
- __in DWORD cchArg,
- __out DWORD * pcchArg)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_PTR_RET(pszValue);
- VALIDATE_CONDITION((pwzArg == nullptr || cchArg > 0), return E_INVALIDARG);
-
- HRESULT hr = S_OK;
-
- if (pwzArg != nullptr)
- {
- DWORD cchWritten = WszMultiByteToWideChar(
- CP_UTF8, 0 /*flags*/, pszValue, -1, pwzArg, cchArg);
-
- if (cchWritten == 0)
- {
- hr = HRESULT_FROM_GetLastError();
- }
- else if (pcchArg != nullptr)
- {
- *pcchArg = cchWritten;
- }
- }
-
- if (pcchArg != nullptr && (pwzArg == nullptr || hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)))
- {
- *pcchArg = WszMultiByteToWideChar(
- CP_UTF8, 0 /*flags*/, pszValue, -1, nullptr, 0);
-
- if (*pcchArg == 0)
- {
- hr = HRESULT_FROM_GetLastError();
- }
- }
-
- return hr;
-}
-
-//=================================================================================================
-// This is needed to allow calls to IsAnyFrameworkAssembly in GC_NOTRIGGER/NO_FAULT regions (i.e.,
-// GC stack walking). CAssemblyName (which implements IAssemblyName in most other uses) allocates
-// during construction and so cannot be used in this scenario.
-
-class AssemblySpecAsIAssemblyName
- : public IAssemblyName
-{
-public:
- AssemblySpecAsIAssemblyName(
- AssemblySpec * pSpec)
- : m_pSpec(pSpec)
- { LIMITED_METHOD_CONTRACT; }
-
- //=============================================================================================
- // IUnknown methods
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_(ULONG, AddRef())
- {
- WRAPPER_NO_CONTRACT;
- _ASSERTE_MSG(false, "Method not implemented.");
- return E_NOTIMPL;
- }
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_(ULONG, Release())
- {
- WRAPPER_NO_CONTRACT;
- _ASSERTE_MSG(false, "Method not implemented.");
- return E_NOTIMPL;
- }
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_NOTIMPL(QueryInterface(
- REFIID riid,
- void **ppvObject));
-
- //=============================================================================================
- // IAssemblyName methods
-
- STDMETHOD_NOTIMPL(SetProperty(
- DWORD PropertyId,
- void const * pvProperty,
- DWORD cbProperty));
-
-#define ASSURE_SUFFICIENT_BUFFER(SRCSIZE) \
- do { \
- if ((pvProperty == nullptr) || (*pcbProperty < SRCSIZE)) { \
- *pcbProperty = SRCSIZE; \
- return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); \
- } \
- } while (false)
-
- STDMETHOD(GetProperty)(
- DWORD PropertyId,
- LPVOID pvProperty,
- LPDWORD pcbProperty)
- {
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_PTR_RET(pcbProperty);
- VALIDATE_CONDITION((pvProperty == nullptr) == (*pcbProperty == 0), return E_INVALIDARG);
-
- HRESULT hr = S_OK;
-
- switch (PropertyId)
- {
- case ASM_NAME_NAME:
- return PropagateOutStringArgument(m_pSpec->GetName(), (LPWSTR) pvProperty,
- *pcbProperty / sizeof(WCHAR), pcbProperty);
-
- case ASM_NAME_MAJOR_VERSION:
- ASSURE_SUFFICIENT_BUFFER(sizeof(USHORT));
- *reinterpret_cast<USHORT*>(pvProperty) = m_pSpec->GetContext()->usMajorVersion;
- *pcbProperty = sizeof(USHORT);
- return S_OK;
-
- case ASM_NAME_MINOR_VERSION:
- ASSURE_SUFFICIENT_BUFFER(sizeof(USHORT));
- *reinterpret_cast<USHORT*>(pvProperty) = m_pSpec->GetContext()->usMinorVersion;
- *pcbProperty = sizeof(USHORT);
- return S_OK;
-
- case ASM_NAME_BUILD_NUMBER:
- ASSURE_SUFFICIENT_BUFFER(sizeof(USHORT));
- *reinterpret_cast<USHORT*>(pvProperty) = m_pSpec->GetContext()->usBuildNumber;
- *pcbProperty = sizeof(USHORT);
- return S_OK;
-
- case ASM_NAME_REVISION_NUMBER:
- ASSURE_SUFFICIENT_BUFFER(sizeof(USHORT));
- *reinterpret_cast<USHORT*>(pvProperty) = m_pSpec->GetContext()->usRevisionNumber;
- *pcbProperty = sizeof(USHORT);
- return S_OK;
-
- case ASM_NAME_CULTURE:
- if (m_pSpec->GetContext()->szLocale == nullptr)
- {
- return FUSION_E_INVALID_NAME;
- }
- return PropagateOutStringArgument(m_pSpec->GetContext()->szLocale, (LPWSTR) pvProperty,
- *pcbProperty / sizeof(WCHAR), pcbProperty);
-
- case ASM_NAME_PUBLIC_KEY_TOKEN:
- {
- if (!m_pSpec->HasPublicKeyToken())
- {
- return FUSION_E_INVALID_NAME;
- }
-
- PBYTE pbSN;
- DWORD cbSN;
- m_pSpec->GetPublicKeyToken(&pbSN, &cbSN);
- ASSURE_SUFFICIENT_BUFFER(cbSN);
- memcpy_s(pvProperty, *pcbProperty, pbSN, cbSN);
- *pcbProperty = cbSN;
- }
- return S_OK;
-
- case ASM_NAME_RETARGET:
- ASSURE_SUFFICIENT_BUFFER(sizeof(BOOL));
- *reinterpret_cast<BOOL*>(pvProperty) = m_pSpec->IsRetargetable();
- *pcbProperty = sizeof(BOOL);
- return S_OK;
-
- default:
- _ASSERTE_MSG(false, "Unexpected property requested.");
- return E_INVALIDARG;
- }
- }
-
-#undef ASSURE_SUFFICIENT_BUFFER
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_NOTIMPL(Finalize());
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_NOTIMPL(GetDisplayName(
- __out_ecount_opt(*pccDisplayName) LPOLESTR szDisplayName,
- __inout LPDWORD pccDisplayName,
- DWORD dwDisplayFlags));
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_NOTIMPL(Reserved(
- REFIID refIID,
- IUnknown *pUnkReserved1,
- IUnknown *pUnkReserved2,
- LPCOLESTR szReserved,
- LONGLONG llReserved,
- LPVOID pvReserved,
- DWORD cbReserved,
- LPVOID *ppReserved));
-
-
- STDMETHOD(GetName)(
- __inout LPDWORD lpcwBuffer,
- __out_ecount_opt(*lpcwBuffer) WCHAR *pwzName)
- {
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_PTR_RET(lpcwBuffer);
- return PropagateOutStringArgument(
- m_pSpec->GetName(), pwzName, *lpcwBuffer, lpcwBuffer);
- }
-
- STDMETHOD(GetVersion)(
- LPDWORD pdwVersionHi,
- LPDWORD pdwVersionLow)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_PTR_RET(pdwVersionHi);
- VALIDATE_PTR_RET(pdwVersionLow);
-
- AssemblyMetaDataInternal * pAMDI = m_pSpec->GetContext();
-
- *pdwVersionHi = MAKELONG(pAMDI->usMinorVersion, pAMDI->usMajorVersion);
- *pdwVersionLow = MAKELONG(pAMDI->usRevisionNumber, pAMDI->usBuildNumber);
-
- return S_OK;
- }
-
-
- // Exists exclusively to support fusion's IsSystem helper, which compares against 'mscorlib'.
- STDMETHOD(IsEqual)(
- IAssemblyName *pName,
- DWORD dwCmpFlags)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_PTR_RET(pName);
-
- // This function is here just to support checks against the name 'mscorlib'.
- if ((dwCmpFlags & ASM_CMPF_NAME) != ASM_CMPF_NAME)
- {
- return E_NOTIMPL;
- }
-
- DWORD cchName1 = 0;
- WCHAR wzName1[_MAX_PATH];
- IfFailRet(pName->GetName(&cchName1, wzName1));
- _ASSERTE(SString::_wcsicmp(wzName1, W("mscorlib")) == 0);
-
- WCHAR wzName2[_MAX_PATH];
- DWORD cchName2 = WszMultiByteToWideChar(
- CP_UTF8, 0 /*flags*/, m_pSpec->GetName(), -1, wzName2, (int) (sizeof(wzName2) / sizeof(wzName2[0])));
-
- if (0 == cchName2)
- {
- _ASSERTE(HRESULT_FROM_GetLastError() != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
- return HRESULT_FROM_GetLastError();
- }
-
- if (cchName1 != cchName2)
- {
- return S_FALSE;
- }
-
- return SString::_wcsnicmp(wzName1, wzName2, cchName1) == 0
- ? S_OK
- : S_FALSE;
- }
-
- STDMETHOD_NOTIMPL(Clone(
- IAssemblyName **pName));
-
-private:
- AssemblySpec * m_pSpec;
-};
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderFusion::FindFusionAssemblyBySpec(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- BindingScope kBindingScope,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
-{
- LIMITED_METHOD_CONTRACT;;
- HRESULT hr = S_OK;
-
- AppDomain* pAppDomain = reinterpret_cast<AppDomain*>(pvAppDomain);
- AssemblySpec* pAssemblySpec = reinterpret_cast<AssemblySpec*>(pvAssemblySpec);
- VALIDATE_PTR_RET(pAppDomain);
- VALIDATE_PTR_RET(pAssemblySpec);
- VALIDATE_PTR_RET(pResult);
- VALIDATE_PTR_RET(ppAssembly);
-
- if (pAssemblySpec->IsContentType_WindowsRuntime())
- {
- return CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT;
- }
-
- BOOL fIsSupportedInAppX;
- {
- AssemblySpecAsIAssemblyName asName(pAssemblySpec);
-
- if (Fusion::Util::IsAnyFrameworkAssembly(&asName, &fIsSupportedInAppX) != S_OK)
- { // Not a framework assembly identity.
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
- }
-
- if (kBindingScope == kBindingScope_FrameworkSubset)
- { // We should allow only some framework assemblies to load
-
- // DevMode has to allow all FX assemblies, not just a subset - see code:PreBind for more info
- {
- // Disabling for now, as it causes too many violations.
- //CONTRACT_VIOLATION(GCViolation | FaultViolation | ModeViolation);
- //_ASSERTE(!AppX::IsAppXDesignMode());
- }
-
- if (!fIsSupportedInAppX)
- { // Assembly is blocked for AppX, fail the load
- *pResult = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- *ppAssembly = nullptr;
- return S_OK;
- }
- }
-
- return FindAssemblyBySpec(pvAppDomain, pvAssemblySpec, pResult, ppAssembly);
-}
-
-//=====================================================================================================================
-static
-PEAssembly * FindCachedFile(AppDomain * pDomain, AssemblySpec * pSpec)
-{
- // Look for cached bind result. Prefer a cached DomainAssembly, as it takes priority over a
- // cached PEAssembly (which can be different from the one associated with the DomainAssembly).
- DomainAssembly * pDomainAssembly = pDomain->FindCachedAssembly(pSpec, FALSE);
- return (pDomainAssembly != nullptr)
- ? (pDomainAssembly->GetFile())
- : (pDomain->FindCachedFile(pSpec, FALSE));
-}
-
-//=====================================================================================================================
-// There is no need to create a separate binding record, since we can always just look in the AppDomain's
-// AssemblySpecBindingCache for an answer (which is precisely what this function does).
-
-HRESULT CLRPrivBinderFusion::FindAssemblyBySpec(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
-{
- LIMITED_METHOD_CONTRACT;;
- HRESULT hr = S_OK;
-
- AppDomain* pAppDomain = reinterpret_cast<AppDomain*>(pvAppDomain);
- AssemblySpec* pAssemblySpec = reinterpret_cast<AssemblySpec*>(pvAssemblySpec);
- VALIDATE_PTR_RET(pAppDomain);
- VALIDATE_PTR_RET(pAssemblySpec);
- VALIDATE_PTR_RET(pResult);
- VALIDATE_PTR_RET(ppAssembly);
-
- // For the Architecture property, canonicalize peMSIL to peNone (which are considered equivalent),
- // to ensure consistent lookups in the AssemblySpecBindingCache for the CLRPrivBinderFusion binder.
- if (pAssemblySpec->GetPEKIND() == peMSIL)
- {
- pAssemblySpec->SetPEKIND(peNone);
- }
-
- PEAssembly * pPEAssembly = FindCachedFile(pAppDomain, pAssemblySpec);
- if (pPEAssembly == nullptr)
- {
- return E_FAIL;
- }
-
- // Could be racing with another thread that has just added the PEAssembly to the binding cache
- // but not yet allocated and assigned a host assembly.
- if (!pPEAssembly->HasHostAssembly())
- {
- return E_FAIL;
- }
-
- *pResult = S_OK;
- *ppAssembly = clr::SafeAddRef(pPEAssembly->GetHostAssembly());
-
- return S_OK;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderFusion::BindAssemblyByNameWorker(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- STANDARD_VM_CONTRACT;
- PRECONDITION(CheckPointer(pAssemblyName));
- PRECONDITION(CheckPointer(ppAssembly));
-
- HRESULT hr = S_OK;
-
- AppDomain * pCurDomain = AppDomain::GetCurrentDomain();
- if (pCurDomain == nullptr)
- ThrowHR(E_UNEXPECTED);
-
- AssemblySpec prePolicySpec;
- AssemblySpec postPolicySpec;
-
- prePolicySpec.InitializeSpec(pAssemblyName);
-
- // For the Architecture property, canonicalize peMSIL to peNone (which are considered equivalent),
- // to ensure consistent lookups in the AssemblySpecBindingCache for the CLRPrivBinderFusion binder.
- if (prePolicySpec.GetPEKIND() == peMSIL)
- {
- prePolicySpec.SetPEKIND(peNone);
- }
-
- AssemblySpec * pBindSpec = &prePolicySpec;
- PEAssemblyHolder pPEAssembly = clr::SafeAddRef(FindCachedFile(pCurDomain, pBindSpec));
-
- if (pPEAssembly == nullptr)
- {
- // Early on in domain setup there may not be a fusion context, so skip ApplyPolicy then.
- _ASSERTE(pCurDomain->GetFusionContext() != nullptr || prePolicySpec.IsMscorlib());
- if (pCurDomain->GetFusionContext() != nullptr)
- {
- ReleaseHolder<IAssemblyName> pPolicyAssemblyName;
- DWORD dwPolicyApplied = 0;
- ApplyPolicy(pAssemblyName, pCurDomain->GetFusionContext(), nullptr, &pPolicyAssemblyName, nullptr, nullptr, &dwPolicyApplied);
-
- if (dwPolicyApplied != 0)
- {
- postPolicySpec.InitializeSpec(pPolicyAssemblyName);
- pBindSpec = &postPolicySpec;
- pPEAssembly = clr::SafeAddRef(FindCachedFile(pCurDomain, pBindSpec));
- }
- }
-
- if (pPEAssembly == nullptr)
- {
- // Trigger a load.
- pPEAssembly = pCurDomain->BindAssemblySpec(
- pBindSpec, // AssemblySpec
- TRUE, // ThrowOnFileNotFound
- FALSE, // RaisePrebindEvents
- nullptr, // CallerStackMark
- nullptr, // AssemblyLoadSecurity
- FALSE); // fUseHostBinderIfAvailable - to avoid infinite recursion
- _ASSERTE(FindCachedFile(pCurDomain, pBindSpec) == pPEAssembly || pBindSpec->IsMscorlib());
- }
-
- // If a post-policy spec was used, add the pre-policy spec to the binding cache
- // so that it can be found by FindAssemblyBySpec.
- if (&prePolicySpec != pBindSpec)
- {
- // Failure to add simply means someone else beat us to it. In that case
- // the FindCachedFile call below (after catch block) will update result
- // to the cached value.
- INDEBUG(BOOL fRes =) pCurDomain->AddFileToCache(&prePolicySpec, pPEAssembly, TRUE /* fAllowFailure */);
- _ASSERTE(!fRes || prePolicySpec.IsMscorlib() || FindCachedFile(pCurDomain, &prePolicySpec) == pPEAssembly);
- }
-
- // Ensure that the assembly is discoverable through a consistent assembly name (the assembly def name of the assembly)
- AssemblySpec specAssemblyDef;
- specAssemblyDef.InitializeSpec(pPEAssembly);
-
- // It is expected that all assemlbies found here will be unified assemblies, and therefore have a public key.
- _ASSERTE(specAssemblyDef.IsStrongNamed());
-
- // Convert public key into the format that matches the garaunteed cache in the AssemblySpecBindingCache ... see the extended logic
- // in Module::GetAssemblyIfLoaded.
- if (specAssemblyDef.IsStrongNamed() && specAssemblyDef.HasPublicKey())
- {
- specAssemblyDef.ConvertPublicKeyToToken();
- }
- pCurDomain->AddFileToCache(&specAssemblyDef, pPEAssembly, TRUE);
- }
-
- if (!pPEAssembly->HasHostAssembly())
- {
- // This can happen if we just loaded the PEAssembly with BindAssemblySpec above, or if the PEAssembly
- // Was not loaded through this binder. (NGEN Case)
-
- // Note: There can be multiple PEAssembly objects for the same file, however we have to create unique
- // CLRPrivAssemblyFusion object, otherwise code:AppDomain::FindAssembly will not recognize the duplicates which
- // will lead to creation of multiple code:DomainAssembly objects for the same file in the same AppDomain.
-
- InlineSString<128> ssPEAssemblyName;
- FusionBind::GetAssemblyNameDisplayName(pPEAssembly->GetFusionAssemblyName(), ssPEAssemblyName, ASM_DISPLAYF_FULL);
- NewHolder<CLRPrivAssemblyFusion> pAssemblyObj = new CLRPrivAssemblyFusion(ssPEAssemblyName.GetUnicode(), this);
-
- {
- CrstHolder lock(&m_SetHostAssemblyLock);
- if (!pPEAssembly->HasHostAssembly())
- {
- // Add the host assembly to the PEAssembly.
- pPEAssembly->SetHostAssembly(pAssemblyObj.Extract());
- }
- }
- }
-
- // Trigger a load so that a DomainAssembly is associated with the ICLRPrivAssembly created above.
- pPEAssembly = clr::SafeAddRef(pCurDomain->LoadDomainAssembly(pBindSpec, pPEAssembly, FILE_LOADED)->GetFile());
-
- _ASSERTE(pPEAssembly != nullptr);
- _ASSERTE(pPEAssembly->HasHostAssembly());
- _ASSERTE(pCurDomain->FindAssembly(pPEAssembly->GetHostAssembly()) != nullptr);
-
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FOUND, pPEAssembly->GetPath().GetUnicode());
-
- *ppAssembly = clr::SafeAddRef(pPEAssembly->GetHostAssembly());
-
- return hr;
-}
-
-//=====================================================================================================================
-void CLRPrivBinderFusion::BindMscorlib(
- PEAssembly * pPEAssembly)
-{
- STANDARD_VM_CONTRACT;
-
-#ifdef _DEBUG
- NewArrayHolder<WCHAR> dbg_wszAssemblySimpleName;
- _ASSERTE(SUCCEEDED(fusion::util::GetProperty(pPEAssembly->GetFusionAssemblyName(), ASM_NAME_NAME, &dbg_wszAssemblySimpleName)));
-
- _ASSERTE(wcscmp(dbg_wszAssemblySimpleName, W("mscorlib")) == 0);
-#endif //_DEBUG
-
- NewHolder<CLRPrivAssemblyFusion> pPrivAssembly = new CLRPrivAssemblyFusion(W("mscorlib"), this);
-
- pPEAssembly->SetHostAssembly(pPrivAssembly.Extract());
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderFusion::BindFusionAssemblyByName(
- IAssemblyName * pAssemblyName,
- BindingScope kBindingScope,
- ICLRPrivAssembly ** ppAssembly)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_FRAMEWORK, &hr);
-
- DWORD dwContentType = AssemblyContentType_Default;
- IfFailRet(fusion::util::GetProperty(pAssemblyName, ASM_NAME_CONTENT_TYPE, &dwContentType));
- if ((hr == S_OK) && (dwContentType != AssemblyContentType_Default))
- { // Not a NetFX content type.
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
-
- BOOL fIsSupportedInAppX;
- if (Fusion::Util::IsAnyFrameworkAssembly(pAssemblyName, &fIsSupportedInAppX) != S_OK)
- { // Not a framework assembly identity.
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
- if (kBindingScope == kBindingScope_FrameworkSubset)
- { // We should allow only some framework assemblies to load
-
- // DevMode has to allow all FX assemblies, not just a subset - see code:PreBind for more info
- _ASSERTE(!AppX::IsAppXDesignMode());
-
- if (!fIsSupportedInAppX)
- { // Assembly is blocked for AppX, fail the load
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FX_ASSEMBLY_BLOCKED);
-
- IfFailRet(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
- }
- }
-
- return (hr = BindAssemblyByNameWorker(pAssemblyName, ppAssembly));
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::BindAssemblyByName
-HRESULT CLRPrivBinderFusion::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return BindAssemblyByNameWorker(
- pAssemblyName,
- ppAssembly);
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::GetBinderID
-HRESULT CLRPrivBinderFusion::GetBinderID(
- UINT_PTR *pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
-
- *pBinderId = (UINT_PTR)this;
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:IBindContext::PreBind
-HRESULT CLRPrivBinderFusion::PreBind(
- IAssemblyName * pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult ** ppIBindResult)
-{
- STANDARD_BIND_CONTRACT;
- PRECONDITION(CheckPointer(pIAssemblyName));
- PRECONDITION(CheckPointer(ppIBindResult));
-
- HRESULT hr = S_OK;
-
- BOOL fIsSupportedInAppX;
- if (Fusion::Util::IsAnyFrameworkAssembly(pIAssemblyName, &fIsSupportedInAppX) != S_OK)
- { // Not a framework assembly identity.
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- EX_TRY
- {
- // Create new IL binding scope.
- fusion::logging::BindingScope defaultScope(pIAssemblyName, FUSION_BIND_LOG_CATEGORY_DEFAULT);
-
- // Ideally the caller would give us arg kBindingContext like in code:BindFusionAssemblyByName, so we can give the same answer.
- // That is not easy, so we will make the decision here:
- // - DevMode will allow all FX assemblies (that covers designer binding context scenario for designers that need to
- // load WPF with ngen images for perf reasons).
- // We know that the real bind via code:BindFusionAssemblyByName will succeed for the assemblies (because we are in DevMode).
- // - Normal mode (non-DevMode) we will allow only subset of FX assemblies.
- // It implies that designer binding context (used by debuggers) will not use ngen images for blocked FX assemblies
- // (transitively). That is acceptable performance trade-off.
- if (!AppX::IsAppXDesignMode())
- { // We should allow only some framework assemblies to load
- if (!fIsSupportedInAppX)
- { // Assembly is blocked for AppX, fail the load
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FX_ASSEMBLY_BLOCKED);
-
- hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
- }
-
- if (SUCCEEDED(hr))
- {
- AppDomain * pDomain = AppDomain::GetCurrentDomain();
- ReleaseHolder<IBindContext> pIBindContext;
- if (SUCCEEDED(hr = GetBindContextFromApplicationContext(pDomain->CreateFusionContext(), &pIBindContext)))
- {
- hr = pIBindContext->PreBind(pIAssemblyName, dwPreBindFlags, ppIBindResult);
- }
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderFusion::PreBindFusionAssemblyByName(
- IAssemblyName *pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult **ppIBindResult)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- DWORD dwContentType = AssemblyContentType_Default;
- IfFailRet(fusion::util::GetProperty(pIAssemblyName, ASM_NAME_CONTENT_TYPE, &dwContentType));
- if ((hr == S_OK) && (dwContentType != AssemblyContentType_Default))
- { // Not a NetFX content type.
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
-
- IfFailRet(PreBind(pIAssemblyName, dwPreBindFlags, ppIBindResult));
- _ASSERTE(*ppIBindResult != nullptr);
-
- if (*ppIBindResult == nullptr)
- IfFailRet(E_UNEXPECTED);
-
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:IBindContext::IsDefaultContext
-HRESULT CLRPrivBinderFusion::IsDefaultContext()
-{
- STANDARD_BIND_CONTRACT;
- return S_OK;
-}
-
-//=====================================================================================================================
-CLRPrivBinderFusion::~CLRPrivBinderFusion()
-{
- WRAPPER_NO_CONTRACT;
-}
-
-//=====================================================================================================================
-CLRPrivAssemblyFusion::CLRPrivAssemblyFusion(
- LPCWSTR wszName,
- CLRPrivBinderFusion * pBinder)
- : m_pBinder(clr::SafeAddRef(pBinder)),
- m_wszName(DuplicateStringThrowing(wszName))
-{
- STANDARD_VM_CONTRACT;
-}
-
-//=====================================================================================================================
-LPCWSTR CLRPrivAssemblyFusion::GetName() const
-{
- LIMITED_METHOD_CONTRACT;
-
- return m_wszName;
-}
-
-//=====================================================================================================================
-// Implements code:IUnknown::Release
-ULONG CLRPrivAssemblyFusion::Release()
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
- _ASSERTE(m_cRef > 0);
-
- ULONG cRef = InterlockedDecrement(&m_cRef);
-
- if (cRef == 0)
- {
- delete this;
- }
-
- return cRef;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::BindAssemblyByName
-HRESULT CLRPrivAssemblyFusion::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return m_pBinder->BindAssemblyByName(
- pAssemblyName,
- ppAssembly);
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::GetBinderID
-HRESULT CLRPrivAssemblyFusion::GetBinderID(
- UINT_PTR *pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
-
- *pBinderId = reinterpret_cast<UINT_PTR>(m_pBinder.GetValue());
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::IsShareable
-HRESULT CLRPrivAssemblyFusion::IsShareable(
- BOOL * pbIsShareable)
-{
- LIMITED_METHOD_CONTRACT;
- *pbIsShareable = TRUE; // These things are only used in the AppX scenario, where all fusion assemblies are unified, shareable assemblies.
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::GetAvailableImageTypes
-HRESULT CLRPrivAssemblyFusion::GetAvailableImageTypes(
- LPDWORD pdwImageTypes)
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(!"CLRPrivAssemblyFusion::GetAvailableImageTypes");
- return E_NOTIMPL;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::GetImageResource
-HRESULT CLRPrivAssemblyFusion::GetImageResource(
- DWORD dwImageType,
- DWORD *pdwImageType,
- ICLRPrivResource ** ppIResource)
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(!"CLRPrivAssemblyFusion::GetImageResource");
- return E_NOTIMPL;
-}
-
-#endif // !DACCESS_COMPILE
-
+++ /dev/null
-// 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.
-
-
-
-#pragma once
-
-#include "holder.h"
-#include "internalunknownimpl.h"
-#include "shash.h"
-#include "clrprivbinding.h"
-#include "clrprivruntimebinders.h"
-
-//=====================================================================================================================
-// Forward declarations
-class CLRPrivBinderFusion;
-class CLRPrivAssemblyFusion;
-
-class PEAssembly;
-class DomainAssembly;
-struct IMDInternalImport;
-
-//=====================================================================================================================
-class CLRPrivBinderFusion :
- public IUnknownCommon<ICLRPrivBinder, IBindContext>
-{
- friend class CLRPrivAssemblyFusion;
-
-public:
- // Scope for the bind operation
- enum BindingScope
- {
- // Binds only to subset of framework that is not on the black list (non-FX assemblies bindings are rejected)
- kBindingScope_FrameworkSubset,
- // Binds to all framework assemblies (incl. those on the black list) (non-FX assemblies bindings are rejected)
- // Used by designer binding context and in DevMode
- kBindingScope_FrameworkAll
- };
-
-public:
- //=============================================================================================
- // ICLRPrivBinder methods
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::BindAssemblyByName
- STDMETHOD(BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly));
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::VerifyBind
- STDMETHOD(VerifyBind)(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo)
- {
- LIMITED_METHOD_CONTRACT;
- if (pAssemblyName == nullptr || pAssembly == nullptr || pAssemblyInfo == nullptr)
- return E_INVALIDARG;
- return S_OK;
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- LIMITED_METHOD_CONTRACT;
- *pBinderFlags = BINDER_FINDASSEMBLYBYSPEC_REQUIRES_EXACT_MATCH;
- return S_OK;
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::GetBinderID
- STDMETHOD(GetBinderID)(
- UINT_PTR *pBinderId);
-
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly);
-
- //=============================================================================================
- // IBindContext methods
-
- // Implements code:IBindContext::PreBind
- STDMETHOD(PreBind)(
- IAssemblyName *pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult **ppIBindResult);
-
- // Implements code:IBindContext::IsDefaultContext
- STDMETHOD(IsDefaultContext)();
-
- //=============================================================================================
- // Class methods
-
- //---------------------------------------------------------------------------------------------
- CLRPrivBinderFusion()
- : m_SetHostAssemblyLock(CrstLeafLock)
- { STANDARD_VM_CONTRACT; }
-
- //---------------------------------------------------------------------------------------------
- ~CLRPrivBinderFusion();
-
- //---------------------------------------------------------------------------------------------
- HRESULT FindFusionAssemblyBySpec(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- BindingScope kBindingScope,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly);
-
- //---------------------------------------------------------------------------------------------
- HRESULT BindFusionAssemblyByName(
- IAssemblyName * pAssemblyName,
- BindingScope kBindingScope,
- ICLRPrivAssembly ** ppAssembly);
-
- //---------------------------------------------------------------------------------------------
- HRESULT PreBindFusionAssemblyByName(
- IAssemblyName * pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult ** ppIBindResult);
-
- //---------------------------------------------------------------------------------------------
- // Binds mscorlib.dll
- void BindMscorlib(
- PEAssembly * pPEAssembly);
-
-private:
- //---------------------------------------------------------------------------------------------
- HRESULT BindAssemblyByNameWorker(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly);
-
-private:
- //---------------------------------------------------------------------------------------------
- // This lock is used to serialize assigning ICLRPrivAssembly instances to PEAssembly objects.
- Crst m_SetHostAssemblyLock;
-
-}; // class CLRPrivBinderFusion
-
-//=====================================================================================================================
-class CLRPrivAssemblyFusion :
- public IUnknownCommon<ICLRPrivAssembly>
-{
-public:
- //---------------------------------------------------------------------------------------------
- CLRPrivAssemblyFusion(
- LPCWSTR wszName,
- CLRPrivBinderFusion * pBinder);
-
- //---------------------------------------------------------------------------------------------
- LPCWSTR GetName() const;
-
- //---------------------------------------------------------------------------------------------
- // Implements code:IUnknown::Release
- STDMETHOD_(ULONG, Release)();
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::BindAssemblyByName
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivAssembly::IsShareable
- STDMETHOD(IsShareable)(
- BOOL * pbIsShareable);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivAssembly::GetAvailableImageTypes
- STDMETHOD(GetAvailableImageTypes)(
- LPDWORD pdwImageTypes);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivAssembly::GetImageResource
- STDMETHOD(GetImageResource)(
- DWORD dwImageType,
- DWORD *pdwImageType,
- ICLRPrivResource ** ppIResource);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::VerifyBind
- STDMETHOD(VerifyBind)(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo)
- {
- WRAPPER_NO_CONTRACT;
- return m_pBinder->VerifyBind(pAssemblyName, pAssembly, pAssemblyInfo);
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pBinder->GetBinderFlags(pBinderFlags);
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::GetBinderID
- STDMETHOD(GetBinderID)(
- UINT_PTR *pBinderId);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::FindAssemblyBySpec
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
- { STATIC_CONTRACT_WRAPPER; return m_pBinder->FindAssemblyBySpec(pvAppDomain, pvAssemblySpec, pResult, ppAssembly); }
-
-protected:
- //---------------------------------------------------------------------------------------------
- // The fusion binder. Need to keep it around as long as this object is around.
- ReleaseHolder<CLRPrivBinderFusion> m_pBinder;
-
- // Full display name of the assembly - used to avoid duplicate CLRPrivAssemblyFusion objects
- NewArrayHolder<WCHAR> m_wszName;
-
-}; // class CLRPrivAssemblyFusion
+++ /dev/null
-// 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.
-//
-
-//
-// Contains the types that implement code:ICLRPrivBinder and code:ICLRPrivAssembly for WinRT ReflectionOnly (aka introspection) binding.
-//
-//=====================================================================================================================
-
-#include "common.h" // precompiled header
-
-#ifndef DACCESS_COMPILE
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-
-//=====================================================================================================================
-#include "sstring.h"
-#include "policy.h"
-#include "clrprivbinderreflectiononlywinrt.h"
-#include "appxutil.h"
-#include "clrprivbinderutil.h"
-#include "imprthelpers.h" // in fusion/inc
-
-#include <winstring.h>
-#include <typeresolution.h>
-
-using namespace CLRPrivBinderUtil;
-
-//=====================================================================================================================
-
-//=====================================================================================================================
-CLRPrivBinderReflectionOnlyWinRT::CLRPrivBinderReflectionOnlyWinRT(
- CLRPrivTypeCacheReflectionOnlyWinRT * pTypeCache)
- : m_MapsLock(CrstLeafLock, CRST_REENTRANCY) // Reentracy is needed for code:CLRPrivAssemblyReflectionOnlyWinRT::Release
-{
- STANDARD_VM_CONTRACT;
-
- // This binder is not supported in AppX scenario.
- _ASSERTE(!AppX::IsAppXProcess());
-
- _ASSERTE(pTypeCache != nullptr);
- m_pTypeCache = clr::SafeAddRef(pTypeCache);
-}
-
-//=====================================================================================================================
-CLRPrivBinderReflectionOnlyWinRT::~CLRPrivBinderReflectionOnlyWinRT()
-{
- WRAPPER_NO_CONTRACT;
-
- if (m_pTypeCache != nullptr)
- {
- m_pTypeCache->Release();
- }
-}
-
-//=====================================================================================================================
-HRESULT
-CLRPrivBinderReflectionOnlyWinRT::BindWinRtType_Internal(
- LPCSTR szTypeNamespace,
- LPCSTR szTypeClassName,
- DomainAssembly * pParentAssembly,
- CLRPrivAssemblyReflectionOnlyWinRT ** ppAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(ppAssembly != nullptr);
-
- CLRPrivBinderUtil::WStringList * pFileNameList = nullptr;
-
- StackSString ssTypeNamespace(SString::Utf8, szTypeNamespace);
-
- GetFileNameListForNamespace(ssTypeNamespace.GetUnicode(), pParentAssembly, &pFileNameList);
-
- if (pFileNameList == nullptr)
- { // There are no files associated with the namespace
- return CLR_E_BIND_TYPE_NOT_FOUND;
- }
-
- StackSString ssTypeName(ssTypeNamespace);
- ssTypeName.Append(W('.'));
- ssTypeName.AppendUTF8(szTypeClassName);
-
- CLRPrivBinderUtil::WStringListElem * pFileNameElem = pFileNameList->GetHead();
- while (pFileNameElem != nullptr)
- {
- const WCHAR * wszFileName = pFileNameElem->GetValue();
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> pAssembly = FindOrCreateAssemblyByFileName(wszFileName);
- _ASSERTE(pAssembly != NULL);
-
- IfFailRet(hr = m_pTypeCache->ContainsType(pAssembly, ssTypeName.GetUnicode()));
- if (hr == S_OK)
- { // The type we are looking for has been found in this assembly
- *ppAssembly = pAssembly.Extract();
- return S_OK;
- }
- _ASSERTE(hr == S_FALSE);
-
- // Try next file name for this namespace
- pFileNameElem = CLRPrivBinderUtil::WStringList::GetNext(pFileNameElem);
- }
-
- // The type has not been found in any of the files from the type's namespace
- return CLR_E_BIND_TYPE_NOT_FOUND;
-} // CLRPrivBinderReflectionOnlyWinRT::BindWinRtType_Internal
-
-//=====================================================================================================================
-HRESULT
-CLRPrivBinderReflectionOnlyWinRT::BindWinRtType(
- LPCSTR szTypeNamespace,
- LPCSTR szTypeClassName,
- DomainAssembly * pParentAssembly,
- ICLRPrivAssembly ** ppPrivAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> pWinRTAssembly;
- IfFailRet(BindWinRtType_Internal(szTypeNamespace, szTypeClassName, pParentAssembly, &pWinRTAssembly));
- IfFailRet(pWinRTAssembly->QueryInterface(__uuidof(ICLRPrivAssembly), (LPVOID *)ppPrivAssembly));
-
- return hr;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivBinder::BindAssemblyByName.
-//
-HRESULT CLRPrivBinderReflectionOnlyWinRT::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- LIMITED_METHOD_CONTRACT;
-
- _ASSERTE_MSG(false, "Unexpected call to CLRPrivBinderReflectionOnlyWinRT::BindAssemblyByName");
- return E_UNEXPECTED;
-}
-
-//=====================================================================================================================
-ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT>
-CLRPrivBinderReflectionOnlyWinRT::FindAssemblyByFileName(
- LPCWSTR wszFileName)
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
-
- CrstHolder lock(&m_MapsLock);
- const FileNameToAssemblyMapEntry * pEntry = m_FileNameToAssemblyMap.LookupPtr(wszFileName);
- return (pEntry == nullptr) ? nullptr : clr::SafeAddRef(pEntry->m_pAssembly);
-}
-
-//=====================================================================================================================
-// Add FileName -> CLRPrivAssemblyReflectionOnlyWinRT * mapping to the map (multi-thread safe).
-ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT>
-CLRPrivBinderReflectionOnlyWinRT::AddFileNameToAssemblyMapping(
- LPCWSTR wszFileName,
- CLRPrivAssemblyReflectionOnlyWinRT * pAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(pAssembly != nullptr);
-
- CrstHolder lock(&m_MapsLock);
-
- const FileNameToAssemblyMapEntry * pEntry = m_FileNameToAssemblyMap.LookupPtr(wszFileName);
- CLRPrivAssemblyReflectionOnlyWinRT * pResultAssembly = nullptr;
- if (pEntry != nullptr)
- {
- pResultAssembly = pEntry->m_pAssembly;
- }
- else
- {
- FileNameToAssemblyMapEntry e;
- e.m_wszFileName = wszFileName;
- e.m_pAssembly = pAssembly;
- m_FileNameToAssemblyMap.Add(e);
-
- pResultAssembly = pAssembly;
- }
- return clr::SafeAddRef(pResultAssembly);
-}
-
-//=====================================================================================================================
-void
-CLRPrivBinderReflectionOnlyWinRT::RemoveFileNameToAssemblyMapping(
- LPCWSTR wszFileName)
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
-
- CrstHolder lock(&m_MapsLock);
- m_FileNameToAssemblyMap.Remove(wszFileName);
-}
-
-//=====================================================================================================================
-ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT>
-CLRPrivBinderReflectionOnlyWinRT::FindOrCreateAssemblyByFileName(
- LPCWSTR wszFileName)
-{
- STANDARD_VM_CONTRACT;
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> pAssembly = FindAssemblyByFileName(wszFileName);
-
- if (pAssembly == nullptr)
- {
- NewHolder<CLRPrivResourcePathImpl> pResource(
- new CLRPrivResourcePathImpl(wszFileName));
-
- NewHolder<CLRPrivAssemblyReflectionOnlyWinRT> pNewAssembly(
- new CLRPrivAssemblyReflectionOnlyWinRT(wszFileName, this, pResource));
-
- // pNewAssembly holds reference to this now
- pResource.SuppressRelease();
-
- // Add the assembly into cache (multi-thread aware)
- pAssembly = AddFileNameToAssemblyMapping(pResource->GetPath(), pNewAssembly);
-
- if (pAssembly == pNewAssembly)
- { // We did not find an existing assembly in the cache and are using the newly created pNewAssembly.
- // Stop it from being deleted when we go out of scope.
- pNewAssembly.SuppressRelease();
- }
- }
- return pAssembly.Extract();
-}
-
-//=====================================================================================================================
-// Returns list of file names from code:m_NamespaceToFileNameListMap for the namespace.
-//
-void
-CLRPrivBinderReflectionOnlyWinRT::GetFileNameListForNamespace(
- LPCWSTR wszNamespace,
- DomainAssembly * pParentAssembly,
- CLRPrivBinderUtil::WStringList ** ppFileNameList)
-{
- STANDARD_VM_CONTRACT;
-
- CLRPrivBinderUtil::WStringList * pFileNameList = nullptr;
- {
- CrstHolder lock(&m_MapsLock);
-
- const NamespaceToFileNameListMapEntry * pEntry = m_NamespaceToFileNameListMap.LookupPtr(wszNamespace);
- if (pEntry != nullptr)
- {
- // Entries from the map are never removed, so we do not have to protect the file name list with a lock
- pFileNameList = pEntry->m_pFileNameList;
- }
- }
-
- if (pFileNameList != nullptr)
- {
- *ppFileNameList = pFileNameList;
- }
- else
- {
- CLRPrivBinderUtil::WStringListHolder hFileNameList;
-
- EX_TRY
- {
- m_pTypeCache->RaiseNamespaceResolveEvent(wszNamespace, pParentAssembly, &hFileNameList);
- }
- EX_CATCH
- {
- Exception * ex = GET_EXCEPTION();
- if (!ex->IsTransient())
- { // Exception was caused by user code
- // Cache empty file name list for this namespace
- (void)AddFileNameListForNamespace(wszNamespace, nullptr, ppFileNameList);
- }
- EX_RETHROW;
- }
- EX_END_CATCH_UNREACHABLE
-
- if (AddFileNameListForNamespace(wszNamespace, hFileNameList.GetValue(), ppFileNameList))
- { // The file name list was added to the cache - do not delete it
- _ASSERTE(*ppFileNameList == hFileNameList.GetValue());
- (void)hFileNameList.Extract();
- }
- }
-} // CLRPrivBinderReflectionOnlyWinRT::GetFileNameListForNamespace
-
-//=====================================================================================================================
-// Adds (thread-safe) list of file names to code:m_NamespaceToFileNameListMap for the namespace - returns the cached value.
-// Returns TRUE, if pFileNameList was added to the cache and caller should NOT delete it.
-// Returns FALSE, if pFileNameList was not added to the cache and caller should delete it.
-//
-BOOL
-CLRPrivBinderReflectionOnlyWinRT::AddFileNameListForNamespace(
- LPCWSTR wszNamespace,
- CLRPrivBinderUtil::WStringList * pFileNameList,
- CLRPrivBinderUtil::WStringList ** ppFileNameList)
-{
- STANDARD_VM_CONTRACT;
-
- NewArrayHolder<WCHAR> wszEntryNamespace = DuplicateStringThrowing(wszNamespace);
-
- NamespaceToFileNameListMapEntry entry;
- entry.m_wszNamespace = wszEntryNamespace;
- entry.m_pFileNameList = pFileNameList;
-
- {
- CrstHolder lock(&m_MapsLock);
-
- const NamespaceToFileNameListMapEntry * pEntry = m_NamespaceToFileNameListMap.LookupPtr(wszEntryNamespace);
- if (pEntry == nullptr)
- {
- m_NamespaceToFileNameListMap.Add(entry);
-
- // These values are now owned by the hash table element
- wszEntryNamespace.SuppressRelease();
- *ppFileNameList = pFileNameList;
- return TRUE;
- }
- else
- { // Another thread beat us adding this entry to the hash table
- *ppFileNameList = pEntry->m_pFileNameList;
- return FALSE;
- }
- }
-} // CLRPrivBinderReflectionOnlyWinRT::AddFileNameListForNamespace
-
-//=====================================================================================================================
-HRESULT
-CLRPrivBinderReflectionOnlyWinRT::BindAssemblyExplicit(
- const WCHAR * wszFileName,
- ICLRPrivAssembly ** ppAssembly)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr;
-
- GCX_PREEMP();
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> pAssembly = FindOrCreateAssemblyByFileName(wszFileName);
- _ASSERTE(pAssembly != NULL);
-
- IfFailRet(pAssembly->QueryInterface(__uuidof(ICLRPrivAssembly), (LPVOID *)ppAssembly));
-
- return S_OK;
-}
-
-//=====================================================================================================================
-CLRPrivAssemblyReflectionOnlyWinRT::CLRPrivAssemblyReflectionOnlyWinRT(
- LPCWSTR wzSimpleName,
- CLRPrivBinderReflectionOnlyWinRT * pBinder,
- CLRPrivResourcePathImpl * pResourceIL)
-{
- STANDARD_VM_CONTRACT;
- VALIDATE_ARG_THROW((wzSimpleName != nullptr) && (pBinder != nullptr) && (pResourceIL != nullptr));
-
- m_pBinder = clr::SafeAddRef(pBinder);
- m_pResourceIL = clr::SafeAddRef(pResourceIL);
-}
-
-//=====================================================================================================================
-ULONG CLRPrivAssemblyReflectionOnlyWinRT::Release()
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
- _ASSERTE(m_cRef > 0);
-
- ULONG cRef;
-
- {
- // To achieve proper lifetime semantics, the name to assembly map elements' CLRPrivAssemblyReflectionOnlyWinRT
- // instances are not ref counted. We cannot allow discovery of the object via m_FileNameToAssemblyMap
- // when the ref count is 0 (to prevent another thread to AddRef and Release it back to 0 in parallel).
- // All uses of the map are guarded by the map lock, so we have to decrease the ref count under that
- // lock (to avoid the chance that 2 threads are running Release to ref count 0 at once).
- CrstHolder lock(&m_pBinder->m_MapsLock);
-
- cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- {
- m_pBinder->RemoveFileNameToAssemblyMapping(m_pResourceIL->GetPath());
- }
- }
-
- if (cRef == 0)
- {
- delete this;
- }
- return cRef;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivAssembly::IsShareable.
-//
-HRESULT CLRPrivAssemblyReflectionOnlyWinRT::IsShareable(
- BOOL * pbIsShareable)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_ARG_RET(pbIsShareable != nullptr);
-
- *pbIsShareable = FALSE;
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivAssembly::GetAvailableImageTypes.
-//
-HRESULT CLRPrivAssemblyReflectionOnlyWinRT::GetAvailableImageTypes(
- LPDWORD pdwImageTypes)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_ARG_RET(pdwImageTypes != nullptr);
-
- *pdwImageTypes = 0;
-
- if (m_pResourceIL != nullptr)
- *pdwImageTypes |= ASSEMBLY_IMAGE_TYPE_IL;
-
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivAssembly::GetImageResource.
-//
-HRESULT CLRPrivAssemblyReflectionOnlyWinRT::GetImageResource(
- DWORD dwImageType,
- DWORD * pdwImageType,
- ICLRPrivResource ** ppIResource)
-{
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(ppIResource != nullptr);
-
- EX_TRY
- {
- DWORD _dwImageType;
- if (pdwImageType == nullptr)
- {
- pdwImageType = &_dwImageType;
- }
-
- if ((dwImageType & ASSEMBLY_IMAGE_TYPE_IL) == ASSEMBLY_IMAGE_TYPE_IL)
- {
- *ppIResource = clr::SafeAddRef(m_pResourceIL);
- *pdwImageType = ASSEMBLY_IMAGE_TYPE_IL;
- }
- else
- { // Native image is not supported by this binder
- hr = CLR_E_BIND_IMAGE_UNAVAILABLE;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivBinder::VerifyBind.
-//
-HRESULT CLRPrivBinderReflectionOnlyWinRT::VerifyBind(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly * pAssembly,
- ICLRPrivAssemblyInfo * pAssemblyInfo)
-{
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- UINT_PTR binderID;
- IfFailRet(pAssembly->GetBinderID(&binderID));
- if (binderID != reinterpret_cast<UINT_PTR>(this))
- {
- return pAssembly->VerifyBind(pAssemblyName, pAssembly, pAssemblyInfo);
- }
-
- // Since WinRT types are bound by type name and not assembly name, assembly-level version validation
- // does not make sense here. Just return S_OK.
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivBinder::GetBinderID.
-//
-HRESULT CLRPrivBinderReflectionOnlyWinRT::GetBinderID(
- UINT_PTR * pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
-
- *pBinderId = reinterpret_cast<UINT_PTR>(this);
- return S_OK;
-}
-
-#endif //FEATURE_REFLECTION_ONLY_LOAD
-#endif //!DACCESS_COMPILE
+++ /dev/null
-// 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.
-//
-
-//
-// Contains the types that implement code:ICLRPrivBinder and code:ICLRPrivAssembly for WinRT ReflectionOnly (aka introspection) binding.
-//
-//=====================================================================================================================
-
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-
-#pragma once
-
-#include "holder.h"
-#include "internalunknownimpl.h"
-#include "clrprivbinding.h"
-#include "clrprivruntimebinders.h"
-#include "clrprivbinderutil.h"
-#include "clr_std/utility"
-
-//=====================================================================================================================
-// Forward declarations
-class CLRPrivBinderReflectionOnlyWinRT;
-class CLRPrivAssemblyReflectionOnlyWinRT;
-class CLRPrivTypeCacheReflectionOnlyWinRT;
-class DomainAssembly;
-
-//=====================================================================================================================
-//=====================================================================================================================
-//=====================================================================================================================
-class CLRPrivBinderReflectionOnlyWinRT :
- public IUnknownCommon<ICLRPrivBinder>
-{
- friend class CLRPrivAssemblyReflectionOnlyWinRT;
-
-private:
- //=============================================================================================
- // Data structures for Namespace -> FileNameList hash (as returned by RoResolveNamespace API)
-
- // Entry in SHash table that maps namespace to list of files
- struct NamespaceToFileNameListMapEntry
- {
- PWSTR m_wszNamespace;
- CLRPrivBinderUtil::WStringList * m_pFileNameList;
- };
-
- // SHash traits for Namespace -> FileNameList hash
- class NamespaceToFileNameListMapTraits : public NoRemoveSHashTraits< DefaultSHashTraits< NamespaceToFileNameListMapEntry > >
- {
- public:
- typedef PCWSTR key_t;
- static const NamespaceToFileNameListMapEntry Null() { NamespaceToFileNameListMapEntry e; e.m_wszNamespace = nullptr; return e; }
- static bool IsNull(const NamespaceToFileNameListMapEntry & e) { return e.m_wszNamespace == nullptr; }
- static PCWSTR GetKey(const NamespaceToFileNameListMapEntry & e) { return e.m_wszNamespace; }
- static count_t Hash(PCWSTR str) { return HashString(str); }
- static BOOL Equals(PCWSTR lhs, PCWSTR rhs) { LIMITED_METHOD_CONTRACT; return (wcscmp(lhs, rhs) == 0); }
-
- void OnDestructPerEntryCleanupAction(const NamespaceToFileNameListMapEntry & e)
- {
- delete [] e.m_wszNamespace;
- CLRPrivBinderUtil::WStringList_Delete(e.m_pFileNameList);
- }
- static const bool s_DestructPerEntryCleanupAction = true;
- };
-
- typedef SHash<NamespaceToFileNameListMapTraits> NamespaceToFileNameListMap;
-
- //=============================================================================================
- // Data structure for FileName -> CLRPrivAssemblyReflectionOnlyWinRT * map
-
- struct FileNameToAssemblyMapEntry
- {
- PCWSTR m_wszFileName; // File name (owned by m_pAssembly)
- CLRPrivAssemblyReflectionOnlyWinRT * m_pAssembly;
- };
-
- class FileNameToAssemblyMapTraits : public DefaultSHashTraits<FileNameToAssemblyMapEntry>
- {
- public:
- typedef PCWSTR key_t;
- static const FileNameToAssemblyMapEntry Null() { FileNameToAssemblyMapEntry e; e.m_wszFileName = NULL; return e; }
- static bool IsNull(const FileNameToAssemblyMapEntry &e) { return e.m_wszFileName == NULL; }
- static const FileNameToAssemblyMapEntry Deleted() { FileNameToAssemblyMapEntry e; e.m_wszFileName = (PCWSTR)-1; return e; }
- static bool IsDeleted(const FileNameToAssemblyMapEntry & e) { return e.m_wszFileName == (PCWSTR)-1; }
- static PCWSTR GetKey(const FileNameToAssemblyMapEntry & e) { return e.m_wszFileName; }
- static count_t Hash(PCWSTR str) { return HashString(str); }
- static BOOL Equals(PCWSTR lhs, PCWSTR rhs) { LIMITED_METHOD_CONTRACT; return (wcscmp(lhs, rhs) == 0); }
- };
-
- typedef SHash<FileNameToAssemblyMapTraits> FileNameToAssemblyMap;
-
-public:
- //=============================================================================================
- // ICLRPrivBinder interface methods
-
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly);
-
- // Implements interface method code:ICLRPrivBinder::VerifyBind.
- STDMETHOD(VerifyBind)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly * pAssembly,
- ICLRPrivAssemblyInfo * pAssemblyInfo);
-
- // Implements interface method code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- LIMITED_METHOD_CONTRACT;
- *pBinderFlags = BINDER_NONE;
- return S_OK;
- }
-
- // Implements interface method code:ICLRPrivBinder::GetBinderID.
- STDMETHOD(GetBinderID)(
- UINT_PTR * pBinderId);
-
- // FindAssemblyBySpec is not supported by this binder.
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
- { STATIC_CONTRACT_WRAPPER; return E_FAIL; }
-
- //=============================================================================================
- // Class methods
-
- CLRPrivBinderReflectionOnlyWinRT(
- CLRPrivTypeCacheReflectionOnlyWinRT * pTypeCache);
-
- ~CLRPrivBinderReflectionOnlyWinRT();
-
- HRESULT BindAssemblyExplicit(
- const WCHAR * wszFileName,
- ICLRPrivAssembly ** ppAssembly);
-
- HRESULT BindWinRtType(
- LPCSTR szTypeNamespace,
- LPCSTR szTypeClassName,
- DomainAssembly * pParentAssembly,
- ICLRPrivAssembly ** ppPrivAssembly);
-
-private:
- //=============================================================================================
- // Accessors for FileName -> CLRPrivAssemblyReflectionOnlyWinRT * map
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> FindAssemblyByFileName(
- LPCWSTR wzsFileName);
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> AddFileNameToAssemblyMapping(
- LPCWSTR wszFileName,
- CLRPrivAssemblyReflectionOnlyWinRT * pAssembly);
-
- void RemoveFileNameToAssemblyMapping(
- LPCWSTR wszFileName);
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> FindOrCreateAssemblyByFileName(
- LPCWSTR wzsFileName);
-
- //=============================================================================================
- // Internal methods
-
- // Returns list of file names from code:m_NamespaceToFileNameListMap for the namespace.
- void GetFileNameListForNamespace(
- LPCWSTR wszNamespace,
- DomainAssembly * pParentAssembly,
- CLRPrivBinderUtil::WStringList ** ppFileNameList);
-
- // Adds (thread-safe) list of file names to code:m_NamespaceToFileNameListMap for the namespace - returns the cached value.
- BOOL AddFileNameListForNamespace(
- LPCWSTR wszNamespace,
- CLRPrivBinderUtil::WStringList * pFileNameList,
- CLRPrivBinderUtil::WStringList ** ppFileNameList);
-
- HRESULT BindWinRtType_Internal(
- LPCSTR szTypeNamespace,
- LPCSTR szTypeClassName,
- DomainAssembly * pParentAssembly,
- CLRPrivAssemblyReflectionOnlyWinRT ** ppAssembly);
-
-private:
- //=============================================================================================
-
- // Namespace -> FileName list map ... items are never removed
- NamespaceToFileNameListMap m_NamespaceToFileNameListMap;
- // FileName -> CLRPrivAssemblyReflectionOnlyWinRT * map ... items can be removed when CLRPrivAssemblyReflectionOnlyWinRT dies
- FileNameToAssemblyMap m_FileNameToAssemblyMap;
-
- // Lock for the above maps
- Crst m_MapsLock;
-
- //=============================================================================================
- CLRPrivTypeCacheReflectionOnlyWinRT * m_pTypeCache;
-
-}; // class CLRPrivBinderReflectionOnlyWinRT
-
-
-//=====================================================================================================================
-//=====================================================================================================================
-//=====================================================================================================================
-class CLRPrivAssemblyReflectionOnlyWinRT :
- public IUnknownCommon<ICLRPrivAssembly>
-{
- friend class CLRPrivBinderReflectionOnlyWinRT;
-
-public:
- //=============================================================================================
- // Class methods
-
- CLRPrivAssemblyReflectionOnlyWinRT(
- LPCWSTR wzFullTypeName,
- CLRPrivBinderReflectionOnlyWinRT * pBinder,
- CLRPrivBinderUtil::CLRPrivResourcePathImpl * pResourceIL);
-
- //=============================================================================================
- // IUnknown interface methods
-
- // Overridden to implement self-removal from assembly map code:CLRPrivBinderReflectionOnlyWinRT::m_FileNameToAssemblyMap.
- STDMETHOD_(ULONG, Release)();
-
- //=============================================================================================
- // ICLRPrivBinder interface methods
-
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
- {
- STATIC_CONTRACT_WRAPPER;
- return m_pBinder->BindAssemblyByName(pAssemblyName, ppAssembly);
- }
-
- // Implements interface method code:ICLRPrivBinder::VerifyBind.
- STDMETHOD(VerifyBind)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly * pAssembly,
- ICLRPrivAssemblyInfo * pAssemblyInfo)
- {
- STATIC_CONTRACT_WRAPPER;
- return m_pBinder->VerifyBind(pAssemblyName, pAssembly, pAssemblyInfo);
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements interface method code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- STATIC_CONTRACT_WRAPPER;
- return m_pBinder->GetBinderFlags(pBinderFlags);
- }
-
- // Implements interface method code:ICLRPrivBinder::GetBinderID.
- STDMETHOD(GetBinderID)(
- UINT_PTR * pBinderId)
- {
- STATIC_CONTRACT_WRAPPER;
- return m_pBinder->GetBinderID(pBinderId);
- }
-
- //=============================================================================================
- // ICLRPrivAssembly interface methods
-
- // Implements interface method code:ICLRPrivAssembly::IsShareable.
- STDMETHOD(IsShareable)(
- BOOL * pbIsShareable);
-
- // Implements interface method code:ICLRPrivAssembly::GetAvailableImageTypes.
- STDMETHOD(GetAvailableImageTypes)(
- LPDWORD pdwImageTypes);
-
- // Implements interface method code:ICLRPrivAssembly::GetImageResource.
- STDMETHOD(GetImageResource)(
- DWORD dwImageType,
- DWORD * pdwImageType,
- ICLRPrivResource ** ppIResource);
-
- // Implements code:ICLRPrivBinder::FindAssemblyBySpec
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
- { STATIC_CONTRACT_WRAPPER; return m_pBinder->FindAssemblyBySpec(pvAppDomain, pvAssemblySpec, pResult, ppAssembly); }
-
-private:
- //=============================================================================================
-
- ReleaseHolder<CLRPrivBinderReflectionOnlyWinRT> m_pBinder;
- ReleaseHolder<CLRPrivBinderUtil::CLRPrivResourcePathImpl> m_pResourceIL;
-
-}; // class CLRPrivAssemblyReflectionOnlyWinRT
-
-#endif //FEATURE_REFLECTION_ONLY_LOAD
+++ /dev/null
-// 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.
-//
-
-//
-// Contains VM implementation of WinRT type cache for code:CLRPrivBinderReflectionOnlyWinRT binder.
-//
-//=====================================================================================================================
-
-#include "common.h" // precompiled header
-
-#ifndef DACCESS_COMPILE
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-
-#include "clrprivtypecachereflectiononlywinrt.h"
-#include <typeresolution.h>
-
-//=====================================================================================================================
-// S_OK - pAssembly contains type wszTypeName
-// S_FALSE - pAssembly does not contain type wszTypeName
-//
-HRESULT
-CLRPrivTypeCacheReflectionOnlyWinRT::ContainsType(
- ICLRPrivAssembly * pPrivAssembly,
- LPCWSTR wszTypeName)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- AppDomain * pAppDomain = AppDomain::GetCurrentDomain();
-
- ReleaseHolder<PEAssembly> pPEAssembly;
- IfFailGo(pAppDomain->BindHostedPrivAssembly(nullptr, pPrivAssembly, nullptr, &pPEAssembly, TRUE));
- _ASSERTE(pPEAssembly != nullptr);
-
- {
- // Find DomainAssembly * (can be cached if this is too slow to call always)
- DomainAssembly * pDomainAssembly = pAppDomain->LoadDomainAssembly(
- nullptr, // pIdentity
- pPEAssembly,
- FILE_LOADED,
- nullptr); // pLoadSecurity
-
- // Convert the type name into namespace and type names in UTF8
- StackSString ssTypeNameWCHAR(wszTypeName);
-
- StackSString ssTypeName;
- ssTypeNameWCHAR.ConvertToUTF8(ssTypeName);
- LPUTF8 szTypeName = (LPUTF8)ssTypeName.GetUTF8NoConvert();
-
- LPCUTF8 szNamespace;
- LPCUTF8 szClassName;
- ns::SplitInline(szTypeName, szNamespace, szClassName);
-
- NameHandle typeName(szNamespace, szClassName);
-
- // Find the type in the assembly (use existing hash of all type names defined in the assembly)
- TypeHandle thType;
- mdToken tkType;
- Module * pTypeModule;
- mdToken tkExportedType;
- if (pDomainAssembly->GetAssembly()->GetLoader()->FindClassModuleThrowing(
- &typeName,
- &thType,
- &tkType,
- &pTypeModule,
- &tkExportedType,
- nullptr, // ppClassHashEntry
- nullptr, // pLookInThisModuleOnly
- Loader::DontLoad))
- { // The type is present in the assembly
- hr = S_OK;
- }
- else
- { // The type is not present in the assembly
- hr = S_FALSE;
- }
- }
-
-ErrExit:
- return hr;
-} // CLRPrivTypeCacheReflectionOnlyWinRT::ContainsType
-
-//=====================================================================================================================
-// Raises user event NamespaceResolveEvent to get a list of files for this namespace.
-//
-void
-CLRPrivTypeCacheReflectionOnlyWinRT::RaiseNamespaceResolveEvent(
- LPCWSTR wszNamespace,
- DomainAssembly * pParentAssembly,
- CLRPrivBinderUtil::WStringListHolder * pFileNameList)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(pFileNameList != nullptr);
-
- AppDomain * pAppDomain = AppDomain::GetCurrentDomain();
-
- GCX_COOP();
-
- struct _gc {
- OBJECTREF AppDomainRef;
- OBJECTREF AssemblyRef;
- STRINGREF str;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- if ((gc.AppDomainRef = pAppDomain->GetRawExposedObject()) != NULL)
- {
- if (pParentAssembly != nullptr)
- {
- gc.AssemblyRef = pParentAssembly->GetExposedAssemblyObject();
- }
-
- MethodDescCallSite onNamespaceResolve(METHOD__APP_DOMAIN__ON_REFLECTION_ONLY_NAMESPACE_RESOLVE, &gc.AppDomainRef);
- gc.str = StringObject::NewString(wszNamespace);
- ARG_SLOT args[3] =
- {
- ObjToArgSlot(gc.AppDomainRef),
- ObjToArgSlot(gc.AssemblyRef),
- ObjToArgSlot(gc.str)
- };
- PTRARRAYREF ResultingAssemblyArrayRef = (PTRARRAYREF) onNamespaceResolve.Call_RetOBJECTREF(args);
- if (ResultingAssemblyArrayRef != NULL)
- {
- for (DWORD i = 0; i < ResultingAssemblyArrayRef->GetNumComponents(); i++)
- {
- ASSEMBLYREF ResultingAssemblyRef = (ASSEMBLYREF) ResultingAssemblyArrayRef->GetAt(i);
- Assembly * pAssembly = ResultingAssemblyRef->GetAssembly();
-
- if (pAssembly->IsCollectible())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_CollectibleAssemblyResolve"));
- }
-
- PEAssembly * pPEAssembly = pAssembly->GetManifestFile();
-
- ICLRPrivAssembly * pPrivAssembly = pPEAssembly->GetHostAssembly();
- if ((pPrivAssembly == NULL) || !IsAfContentType_WindowsRuntime(pPEAssembly->GetFlags()))
- {
- COMPlusThrow(kNotSupportedException, IDS_EE_REFLECTIONONLY_WINRT_INVALIDASSEMBLY);
- }
-
- pFileNameList->InsertTail(pPEAssembly->GetILimage()->GetPath());
- }
- }
- }
- GCPROTECT_END();
-} // CLRPrivTypeCacheReflectionOnlyWinRT::RaiseNamespaceResolveEvent
-
-//=====================================================================================================================
-// Implementation of QCall System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata.nResolveNamespace
-// It's basically a PInvoke wrapper into Win8 API RoResolveNamespace
-//
-void
-QCALLTYPE
-CLRPrivTypeCacheReflectionOnlyWinRT::ResolveNamespace(
- LPCWSTR wszNamespace,
- LPCWSTR wszWindowsSdkPath,
- LPCWSTR * rgPackageGraphPaths,
- INT32 cPackageGraphPaths,
- QCall::ObjectHandleOnStack retFileNames)
-{
- QCALL_CONTRACT;
-
- _ASSERTE(wszNamespace != nullptr);
-
- BEGIN_QCALL;
-
- CoTaskMemHSTRINGArrayHolder hFileNames;
-
- if (!WinRTSupported())
- {
- IfFailThrow(COR_E_PLATFORMNOTSUPPORTED);
- }
-
- {
- CLRPrivBinderUtil::HSTRINGArrayHolder rgPackageGraph;
- rgPackageGraph.Allocate(cPackageGraphPaths);
-
- LPCWSTR wszNamespaceRoResolve = wszNamespace;
-
- for (INT32 i = 0; i < cPackageGraphPaths; i++)
- {
- _ASSERTE(rgPackageGraph.GetRawArray()[i] == nullptr);
- WinRtString hsPackageGraphPath;
- IfFailThrow(hsPackageGraphPath.Initialize(rgPackageGraphPaths[i]));
- hsPackageGraphPath.Detach(&rgPackageGraph.GetRawArray()[i]);
- }
-
- UINT32 cchNamespace, cchWindowsSdkPath;
- IfFailThrow(StringCchLength(wszNamespace, &cchNamespace));
- IfFailThrow(StringCchLength(wszWindowsSdkPath, &cchWindowsSdkPath));
-
- DWORD cFileNames = 0;
- HSTRING * rgFileNames = nullptr;
- HRESULT hr = RoResolveNamespace(
- WinRtStringRef(wszNamespace, cchNamespace),
- WinRtStringRef(wszWindowsSdkPath, cchWindowsSdkPath),
- rgPackageGraph.GetCount(),
- rgPackageGraph.GetRawArray(),
- &cFileNames,
- &rgFileNames,
- nullptr, // pcDirectNamespaceChildren
- nullptr); // rgDirectNamespaceChildren
- hFileNames.Init(rgFileNames, cFileNames);
-
- if (hr == HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE))
- { // User tried to resolve 3rd party namespace without passing package graph - throw InvalidOperationException with custom message
- _ASSERTE(cPackageGraphPaths == 0);
- COMPlusThrow(kInvalidOperationException, IDS_EE_REFLECTIONONLY_WINRT_LOADFAILURE_THIRDPARTY);
- }
- IfFailThrow(hr);
- if (hr != S_OK)
- {
- IfFailThrow(E_UNEXPECTED);
- }
- }
-
- {
- GCX_COOP();
-
- PTRARRAYREF orFileNames = NULL;
- GCPROTECT_BEGIN(orFileNames);
-
- orFileNames = (PTRARRAYREF) AllocateObjectArray(hFileNames.GetCount(), g_pStringClass);
-
- for (DWORD i = 0; i < hFileNames.GetCount(); i++)
- {
- UINT32 cchFileName = 0;
-
- HSTRING hsFileName = hFileNames.GetAt(i);
- LPCWSTR wszFileName;
-
- if (hsFileName != nullptr)
- {
- wszFileName = WindowsGetStringRawBuffer(
- hsFileName,
- &cchFileName);
-
- STRINGREF str = StringObject::NewString(wszFileName);
- orFileNames->SetAt(i, str);
- }
- }
-
- retFileNames.Set(orFileNames);
-
- GCPROTECT_END();
- }
-
- END_QCALL;
-} // CLRPrivTypeCacheReflectionOnlyWinRT::ResolveNamespace
-
-//=====================================================================================================================
-
-#endif //FEATURE_REFLECTION_ONLY_LOAD
-#endif //!DACCESS_COMPILE
+++ /dev/null
-// 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.
-//
-
-//
-// Contains VM implementation of code:ICLRPrivTypeCacheReflectionOnlyWinRT for code:CLRPrivBinderReflectionOnlyWinRT binder.
-//
-//=====================================================================================================================
-
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-
-#pragma once
-
-#include "internalunknownimpl.h"
-#include "clrprivbinding.h"
-
-//=====================================================================================================================
-// Forward declarations
-class DomainAssembly;
-
-//=====================================================================================================================
-class CLRPrivTypeCacheReflectionOnlyWinRT :
- public IUnknownCommon<IUnknown>
-{
-public:
- //=============================================================================================
- // Class methods
-
- // S_OK - pAssembly contains type wszTypeName
- // S_FALSE - pAssembly does not contain type wszTypeName
- STDMETHOD(ContainsType)(
- ICLRPrivAssembly * pAssembly,
- LPCWSTR wszTypeName);
-
-#ifndef DACCESS_COMPILE
-
- // Raises user event NamespaceResolveEvent to get a list of files for this namespace.
- void RaiseNamespaceResolveEvent(
- LPCWSTR wszNamespace,
- DomainAssembly * pParentAssembly,
- CLRPrivBinderUtil::WStringListHolder * pFileNameList);
-
-#endif //!DACCESS_COMPILE
-
- // Implementation of QCall System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata.nResolveNamespace
- // It's basically a PInvoke wrapper into Win8 API RoResolveNamespace
- static
- void QCALLTYPE ResolveNamespace(
- LPCWSTR wszNamespace,
- LPCWSTR wszWindowsSdkPath,
- LPCWSTR * rgPackageGraphPaths,
- INT32 cPackageGraphPaths,
- QCall::ObjectHandleOnStack retFileNames);
-
-}; // class CLRPrivTypeCaheReflectionOnlyWinRT
-
-#endif //FEATURE_REFLECTION_ONLY_LOAD
protected:
- friend class CLRPrivBinderFusion;
#ifndef DACCESS_COMPILE
- // CLRPrivBinderFusion calls this for Fusion-bound assemblies in AppX processes.
void SetHostAssembly(ICLRPrivAssembly * pHostAssembly)
{ LIMITED_METHOD_CONTRACT; m_pHostAssembly = clr::SafeAddRef(pHostAssembly); }
#endif //DACCESS_COMPILE