//=====================================================================================================================
// Used only for designer binding context
CLRPrivBinderAppX * CLRPrivBinderAppX::CreateParentedBinder(
    ICLRPrivBinder *         pParentBinder, 
    CLRPrivTypeCacheWinRT *  pWinRtTypeCache,
    LPCWSTR *                rgwzAltPath, 
    UINT                     cAltPaths,
    BOOL                     fCanUseNativeImages)
{
    STANDARD_VM_CONTRACT;
    HRESULT hr = S_OK;

    ReleaseHolder<CLRPrivBinderAppX> pBinder;
    pBinder = clr::SafeAddRef(new CLRPrivBinderAppX(rgwzAltPath, cAltPaths));

    pBinder->m_pParentBinder = clr::SafeAddRef(pParentBinder);
    pBinder->m_fCanUseNativeImages = fCanUseNativeImages;
    
    // We want to share FusionBinder with pParentBinder (which bubbles up through the chain of binders to the global AppXBinder code:s_pSingleton)
    // Ideally we would get the FusionBinder from pParentBinder (via casting to a new interface). It is much easier just to fetch it from 
    // the global AppX binder directly
    pBinder->m_pFusionBinder = clr::SafeAddRef(s_pSingleton->GetFusionBinder());
    
    if (cAltPaths > 0)
    {
        pBinder->m_pWinRTBinder = clr::SafeAddRef(new CLRPrivBinderWinRT(
            pBinder, 
            pWinRtTypeCache, 
            rgwzAltPath, 
            cAltPaths, 
            CLRPrivBinderWinRT::NamespaceResolutionKind_WindowsAPI,
            fCanUseNativeImages));
    }

    pBinder.SuppressRelease();
    return pBinder;
}
// ============================================================================
// CLRPrivBinderCoreCLR implementation
// ============================================================================
HRESULT CLRPrivBinderCoreCLR::BindAssemblyByName(IAssemblyName     *pIAssemblyName,
                                                 ICLRPrivAssembly **ppAssembly)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(pIAssemblyName != nullptr && ppAssembly != nullptr);
    
    EX_TRY
    {
        *ppAssembly = nullptr;

        ReleaseHolder<BINDER_SPACE::Assembly> pCoreCLRFoundAssembly;
        ReleaseHolder<AssemblyName> pAssemblyName;

        SAFE_NEW(pAssemblyName, AssemblyName);
        IF_FAIL_GO(pAssemblyName->Init(pIAssemblyName));
        
        hr = BindAssemblyByNameWorker(pAssemblyName, &pCoreCLRFoundAssembly, false /* excludeAppPaths */);
        IF_FAIL_GO(hr);
            
        *ppAssembly = pCoreCLRFoundAssembly.Extract();

Exit:;        
    }
    EX_CATCH_HRESULT(hr);

    return hr;
}
HRESULT CCoreCLRBinderHelper::DefaultBinderSetupContext(DWORD dwAppDomainId,CLRPrivBinderCoreCLR **ppTPABinder)
{
    HRESULT hr = S_OK;
    EX_TRY
    {
        if(ppTPABinder != NULL)
        {
            ReleaseHolder<CLRPrivBinderCoreCLR> pBinder;
            SAFE_NEW(pBinder, CLRPrivBinderCoreCLR);

            BINDER_SPACE::ApplicationContext *pApplicationContext = pBinder->GetAppContext();
            hr = pApplicationContext->Init();
            if(SUCCEEDED(hr))
            {
                pApplicationContext->SetAppDomainId(dwAppDomainId);
                pBinder->SetManagedAssemblyLoadContext(NULL);
                *ppTPABinder = clr::SafeAddRef(pBinder.Extract());
            }
        }
    }
    EX_CATCH_HRESULT(hr);

Exit:
    return hr;
}
/* static */
HRESULT CLRPrivBinderAssemblyLoadContext::SetupContext(DWORD      dwAppDomainId,
                                            CLRPrivBinderCoreCLR *pTPABinder,
                                            LoaderAllocator* pLoaderAllocator,
                                            void* loaderAllocatorHandle,
                                            UINT_PTR ptrAssemblyLoadContext,
                                            CLRPrivBinderAssemblyLoadContext **ppBindContext)
{
    HRESULT hr = E_FAIL;
    EX_TRY
    {
        if(ppBindContext != NULL)
        {
            ReleaseHolder<CLRPrivBinderAssemblyLoadContext> pBinder;
            
            SAFE_NEW(pBinder, CLRPrivBinderAssemblyLoadContext);
            hr = pBinder->m_appContext.Init();
            if(SUCCEEDED(hr))
            {
                // Save the reference to the AppDomain in which the binder lives
                pBinder->m_appContext.SetAppDomainId(dwAppDomainId);
                
                // Mark that this binder can explicitly bind to native images
                pBinder->m_appContext.SetExplicitBindToNativeImages(true);
                
                // Save reference to the TPABinder that is required to be present.
                _ASSERTE(pTPABinder != NULL);
                pBinder->m_pTPABinder = pTPABinder;
                
                // Save the reference to the IntPtr for GCHandle for the managed
                // AssemblyLoadContext instance
                pBinder->m_ptrManagedAssemblyLoadContext = ptrAssemblyLoadContext;

                if (pLoaderAllocator != NULL)
                {
                    // Link to LoaderAllocator, keep a reference to it
                    VERIFY(pLoaderAllocator->AddReferenceIfAlive());
                }
                pBinder->m_pAssemblyLoaderAllocator = pLoaderAllocator;
                pBinder->m_loaderAllocatorHandle = loaderAllocatorHandle;

#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
                if (pLoaderAllocator != NULL)
                {
                    ((AssemblyLoaderAllocator*)pLoaderAllocator)->RegisterBinder(pBinder);
                }
#endif
                // Return reference to the allocated Binder instance
                *ppBindContext = clr::SafeAddRef(pBinder.Extract());
            }
        }
    }
    EX_CATCH_HRESULT(hr);

Exit:
    return hr;
}
//=====================================================================================================================
STDMETHODIMP CLRPrivBinderLoadFile::BindAssemblyExplicit(
        PEImage* pImage,
        IAssemblyName **ppAssemblyName,
        ICLRPrivAssembly ** ppAssembly)
{
    STANDARD_BIND_CONTRACT;
    PRECONDITION(AppDomain::GetCurrentDomain()->IsDefaultDomain());
    VALIDATE_ARG_RET(pImage != nullptr);
    VALIDATE_ARG_RET(ppAssemblyName != nullptr);
    VALIDATE_ARG_RET(ppAssembly != nullptr);

    HRESULT hr = S_OK;

    fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_LOAD_FILE, &hr);

    ReleaseHolder<IAssemblyName> pAssemblyName;
    ReleaseHolder<ICLRPrivAssembly> pAssembly;

    EX_TRY
    {
        // check if a framework assembly
        {
            AssemblySpec spec;
            mdAssembly a;
            IfFailThrow(pImage->GetMDImport()->GetAssemblyFromScope(&a));
            spec.InitializeSpec(a, pImage->GetMDImport(), NULL, false);
            IfFailThrow(spec.CreateFusionName(&pAssemblyName));
        }

        hr = IfTransientFailThrow(m_pFrameworkBinder->BindFusionAssemblyByName(
                pAssemblyName, 
                CLRPrivBinderFusion::kBindingScope_FrameworkSubset, 
                &pAssembly));
        if (FAILED(hr)) // not a Framework assembly
        {
            ReleaseHolder<CLRPrivResourcePathImpl> pPathResource =
                clr::SafeAddRef(new CLRPrivResourcePathImpl(pImage->GetPath().GetUnicode()));
            pAssembly = clr::SafeAddRef(new CLRPrivAssemblyLoadFile(this, m_pFrameworkBinder, pPathResource));

            hr = S_OK;
        }
    }
    EX_CATCH_HRESULT(hr);

    if (SUCCEEDED(hr))
    {
        *ppAssemblyName = pAssemblyName.Extract();
        *ppAssembly = pAssembly.Extract();
    }

    return hr;
};
//=====================================================================================================================
HRESULT CLRPrivBinderAppX::BindAppXAssemblyByName(
    IAssemblyName * pIAssemblyName,
    DWORD dwAppXBindFlags,
    ICLRPrivAssembly ** ppPrivAssembly)
{
    STANDARD_VM_CONTRACT;
    HRESULT hr = S_OK;

    ReleaseHolder<CLRPrivAssemblyAppX> pAppXAssembly;
    IfFailRet(BindAppXAssemblyByNameWorker(pIAssemblyName, dwAppXBindFlags, &pAppXAssembly));
    IfFailRet(pAppXAssembly->QueryInterface(__uuidof(ICLRPrivAssembly), (LPVOID*)ppPrivAssembly));

    return hr;
}
//=====================================================================================================================
CLRPrivBinderAppX * 
CLRPrivBinderAppX::GetOrCreateBinder()
{
    STANDARD_VM_CONTRACT;
    HRESULT hr = S_OK;

    if (s_pSingleton == nullptr)
    {
        ReleaseHolder<IAssemblyUsageLog> pNewUsageLog;
        IfFailThrow(AssemblyUsageLogManager::GetUsageLogForContext(W("App"), AppX::GetHeadPackageMoniker(), &pNewUsageLog));

        ReleaseHolder<CLRPrivBinderAppX> pBinder;
        pBinder = clr::SafeAddRef(new CLRPrivBinderAppX(nullptr, 0));
        
        pBinder->m_pFusionBinder = clr::SafeAddRef(new CLRPrivBinderFusion());
        
        CLRPrivTypeCacheWinRT * pWinRtTypeCache = CLRPrivTypeCacheWinRT::GetOrCreateTypeCache();
        pBinder->m_pWinRTBinder = clr::SafeAddRef(new CLRPrivBinderWinRT(
            pBinder, 
            pWinRtTypeCache, 
            nullptr,    // rgwzAltPath
            0,          // cAltPaths
            CLRPrivBinderWinRT::NamespaceResolutionKind_WindowsAPI, 
            TRUE // fCanUseNativeImages
            ));
        
        if (InterlockedCompareExchangeT<decltype(s_pSingleton)>(&s_pSingleton, pBinder, nullptr) == nullptr)
            pBinder.SuppressRelease();

        // Register binder with usagelog infrastructure.
        UINT_PTR binderId;
        IfFailThrow(pBinder->GetBinderID(&binderId));
        IfFailThrow(AssemblyUsageLogManager::RegisterBinderWithUsageLog(binderId, pNewUsageLog));
        
        // Create and register WinRT usage log
        ReleaseHolder<IAssemblyUsageLog> pNewWinRTUsageLog;
        IfFailThrow(AssemblyUsageLogManager::GetUsageLogForContext(W("WinRT"), AppX::GetHeadPackageMoniker(), &pNewWinRTUsageLog));

        UINT_PTR winRTBinderId;
        IfFailThrow(pBinder->m_pWinRTBinder->GetBinderID(&winRTBinderId));
        IfFailThrow(AssemblyUsageLogManager::RegisterBinderWithUsageLog(winRTBinderId, pNewWinRTUsageLog));
    }

    return s_pSingleton;
}
//=====================================================================================================================
HRESULT CLRPrivBinderAppX::PreBindAppXAssemblyByName(
    IAssemblyName * pIAssemblyName,
    DWORD           dwAppXBindFlags,
    IBindResult **  ppIBindResult)
{
    STANDARD_VM_CONTRACT;
    HRESULT hr = S_OK;

    VALIDATE_ARG_RET(pIAssemblyName != nullptr);
    VALIDATE_ARG_RET(ppIBindResult != nullptr);


    ReleaseHolder<CLRPrivAssemblyAppX> pAppXAssembly;
    IfFailRet(BindAppXAssemblyByNameWorker(pIAssemblyName, dwAppXBindFlags, &pAppXAssembly));
    IfFailRet(pAppXAssembly->GetIBindResult(ppIBindResult));

    return hr;
}
// See code:BINDER_SPACE::AssemblyBinder::GetAssembly for info on fNgenExplicitBind
// and fExplicitBindToNativeImage, and see code:CEECompileInfo::LoadAssemblyByPath
// for an example of how they're used.
HRESULT CLRPrivBinderCoreCLR::Bind(SString           &assemblyDisplayName,
                                   LPCWSTR            wszCodeBase,
                                   PEAssembly        *pParentAssembly,
                                   BOOL               fNgenExplicitBind,
                                   BOOL               fExplicitBindToNativeImage,
                                   ICLRPrivAssembly **ppAssembly)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(ppAssembly != NULL);

    AssemblyName assemblyName;
    
    ReleaseHolder<AssemblyName> pAssemblyName;
    
    if (!assemblyDisplayName.IsEmpty())
    {
        // AssemblyDisplayName can be empty if wszCodeBase is specified.
        SAFE_NEW(pAssemblyName, AssemblyName);
        IF_FAIL_GO(pAssemblyName->Init(assemblyDisplayName));
    }
    
    EX_TRY
    {
        ReleaseHolder<BINDER_SPACE::Assembly> pAsm;
        hr = AssemblyBinder::BindAssembly(&m_appContext,
                                          pAssemblyName,
                                          wszCodeBase,
                                          pParentAssembly,
                                          fNgenExplicitBind,
                                          fExplicitBindToNativeImage,
                                          false, // excludeAppPaths
                                          &pAsm);
        if(SUCCEEDED(hr))
        {
            _ASSERTE(pAsm != NULL);
            pAsm->SetBinder(this);
            *ppAssembly = pAsm.Extract();
        }
    }
    EX_CATCH_HRESULT(hr);
    
Exit:    
    return hr;
}
Exemple #10
0
//*************************************************************
//
// Open the file with anme wzModule and check to see if there is a type 
// with namespace/class of wzNamespace/wzType. If so, return the RegMeta
// corresponding to the file and the mdTypeDef of the typedef
//
//*************************************************************
HRESULT CORPATHService::FindTypeDef(
    __in __in_z LPWSTR wzModule,    // name of the module that we are going to open
    mdTypeRef          tr,          // TypeRef to resolve.
    IMetaModelCommon * pCommon,     // Scope in which the TypeRef is defined.
    REFIID             riid, 
    IUnknown **        ppIScope,
    mdTypeDef *        ptd)         // [OUT] the type that we resolve to
{
    HRESULT                         hr = NOERROR;
    NewHolder<Disp>                 pDisp;
    ReleaseHolder<IMetaDataImport2> pImport = NULL;
    CQuickArray<mdTypeRef>          cqaNesters;
    CQuickArray<LPCUTF8>            cqaNesterNamespaces;
    CQuickArray<LPCUTF8>            cqaNesterNames;
    RegMeta *                       pRegMeta;
    
    _ASSERTE((ppIScope != NULL) && (ptd != NULL));
    
    *ppIScope = NULL;
    
    pDisp = new (nothrow) Disp;
    IfNullGo(pDisp);
    
    IfFailGo(pDisp->OpenScope(wzModule, 0, IID_IMetaDataImport2, (IUnknown **)&pImport));
    pRegMeta = static_cast<RegMeta *>(pImport.GetValue());
    
    // Get the Nesting hierarchy.
    IfFailGo(ImportHelper::GetNesterHierarchy(pCommon, tr, cqaNesters,
                                cqaNesterNamespaces, cqaNesterNames));

    hr = ImportHelper::FindNestedTypeDef(
                                pRegMeta->GetMiniMd(),
                                cqaNesterNamespaces,
                                cqaNesterNames,
                                mdTokenNil,
                                ptd);
    if (SUCCEEDED(hr))
    {
        *ppIScope = pImport.Extract();
    }
    
ErrExit:
    return hr;
} // CORPATHService::FindTypeDef
Exemple #11
0
HRESULT CCoreCLRBinderHelper::GetAssemblyFromImage(PEImage           *pPEImage,
        PEImage           *pNativePEImage,
        ICLRPrivAssembly **ppAssembly)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(pPEImage != NULL && ppAssembly != NULL);

    EX_TRY
    {
        ReleaseHolder<BINDER_SPACE::Assembly> pAsm;
        hr = AssemblyBinder::GetAssemblyFromImage(pPEImage, pNativePEImage, &pAsm);
        if(SUCCEEDED(hr))
        {
            _ASSERTE(pAsm != nullptr);
            *ppAssembly = pAsm.Extract();
        }
    }
    EX_CATCH_HRESULT(hr);

    return hr;
}
//=====================================================================================================================
CLRPrivBinderLoadFile * CLRPrivBinderLoadFile::GetOrCreateBinder()
{
    STANDARD_VM_CONTRACT;
    HRESULT hr = S_OK;

    if (s_pSingleton == nullptr)
    {
        ReleaseHolder<CLRPrivBinderLoadFile> pBinder = SafeAddRef(new CLRPrivBinderLoadFile());
        
        CLRPrivBinderAppX *   pAppXBinder = CLRPrivBinderAppX::GetOrCreateBinder();
        CLRPrivBinderFusion * pFusionBinder = pAppXBinder->GetFusionBinder();
        
        pBinder->m_pFrameworkBinder = SafeAddRef(pFusionBinder);
        _ASSERTE(pBinder->m_pFrameworkBinder != nullptr);
        
        if (InterlockedCompareExchangeT<decltype(s_pSingleton)>(&s_pSingleton, pBinder, nullptr) == nullptr)
            pBinder.SuppressRelease();
    }
    
    return s_pSingleton;
}
/* static */
HRESULT CLRPrivBinderAssemblyLoadContext::SetupContext(DWORD      dwAppDomainId,
        CLRPrivBinderCoreCLR *pTPABinder,
        UINT_PTR ptrAssemblyLoadContext,
        CLRPrivBinderAssemblyLoadContext **ppBindContext)
{
    HRESULT hr = E_FAIL;
    EX_TRY
    {
        if(ppBindContext != NULL)
        {
            ReleaseHolder<CLRPrivBinderAssemblyLoadContext> pBinder;

            SAFE_NEW(pBinder, CLRPrivBinderAssemblyLoadContext);
            hr = pBinder->m_appContext.Init();
            if(SUCCEEDED(hr))
            {
                // Save the reference to the AppDomain in which the binder lives
                pBinder->m_appContext.SetAppDomainId(dwAppDomainId);

                // Mark that this binder can explicitly bind to native images
                pBinder->m_appContext.SetExplicitBindToNativeImages(true);

                // Save reference to the TPABinder that is required to be present.
                _ASSERTE(pTPABinder != NULL);
                pBinder->m_pTPABinder = pTPABinder;

                // Save the reference to the IntPtr for GCHandle for the managed
                // AssemblyLoadContext instance
                pBinder->m_ptrManagedAssemblyLoadContext = ptrAssemblyLoadContext;

                // Return reference to the allocated Binder instance
                *ppBindContext = clr::SafeAddRef(pBinder.Extract());
            }
        }
    }
    EX_CATCH_HRESULT(hr);

Exit:
    return hr;
}
Exemple #14
0
HRESULT CCoreCLRBinderHelper::BindToSystemSatellite(SString            &systemPath,
        SString           &sSimpleName,
        SString           &sCultureName,
        ICLRPrivAssembly **ppSystemAssembly)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(ppSystemAssembly != NULL && !systemPath.IsEmpty());

    EX_TRY
    {
        ReleaseHolder<BINDER_SPACE::Assembly> pAsm;
        hr = AssemblyBinder::BindToSystemSatellite(systemPath, sSimpleName, sCultureName, &pAsm);
        if(SUCCEEDED(hr))
        {
            _ASSERTE(pAsm != NULL);
            *ppSystemAssembly = pAsm.Extract();
        }
    }
    EX_CATCH_HRESULT(hr);

    return hr;
}
HRESULT CLRPrivBinderAssemblyLoadContext::BindUsingPEImage( /* in */ PEImage *pPEImage, 
                                                            /* in */ BOOL fIsNativeImage, 
                                                            /* [retval][out] */ ICLRPrivAssembly **ppAssembly)
{
    HRESULT hr = S_OK;

    EX_TRY
    {
        ReleaseHolder<BINDER_SPACE::Assembly> pCoreCLRFoundAssembly;
        ReleaseHolder<BINDER_SPACE::AssemblyName> pAssemblyName;        
        ReleaseHolder<IMDInternalImport> pIMetaDataAssemblyImport;
        
        PEKIND PeKind = peNone;
        
        // Get the Metadata interface
        DWORD dwPAFlags[2];
        IF_FAIL_GO(BinderAcquireImport(pPEImage, &pIMetaDataAssemblyImport, dwPAFlags, fIsNativeImage));
        IF_FAIL_GO(AssemblyBinder::TranslatePEToArchitectureType(dwPAFlags, &PeKind));
        
        _ASSERTE(pIMetaDataAssemblyImport != NULL);
        
        // Using the information we just got, initialize the assemblyname
        SAFE_NEW(pAssemblyName, AssemblyName);
        IF_FAIL_GO(pAssemblyName->Init(pIMetaDataAssemblyImport, PeKind));
        
        // Validate architecture
        if (!BINDER_SPACE::Assembly::IsValidArchitecture(pAssemblyName->GetArchitecture()))
        {
            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).
        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();
        }
Exit:;        
    }
    EX_CATCH_HRESULT(hr);

    return hr;
}
Exemple #16
0
HRESULT 
DacVirtualUnwind(DWORD threadId, PT_CONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers)
{
    if (!g_dacImpl)
    {
        DacError(E_UNEXPECTED);
        UNREACHABLE();
    }

    // The DAC code doesn't use these context pointers but zero them out to be safe.
    if (contextPointers != NULL)
    {
        memset(contextPointers, 0, sizeof(T_KNONVOLATILE_CONTEXT_POINTERS));
    }

    HRESULT hr = S_OK;

#ifdef FEATURE_DATATARGET4
    ReleaseHolder<ICorDebugDataTarget4> dt;
    hr = g_dacImpl->m_pTarget->QueryInterface(IID_ICorDebugDataTarget4, (void **)&dt);
    if (SUCCEEDED(hr))
    {
        hr = dt->VirtualUnwind(threadId, sizeof(CONTEXT), (BYTE*)context);
    }
    else 
#endif
    {
        SIZE_T baseAddress = DacGlobalBase();
        if (baseAddress == 0 || !PAL_VirtualUnwindOutOfProc(context, contextPointers, baseAddress, DacReadAllAdapter))
        {
            hr = E_FAIL;
        }
    }

    return hr;
}
Exemple #17
0
HRESULT CCoreCLRBinderHelper::BindToSystem(ICLRPrivAssembly **ppSystemAssembly, bool fBindToNativeImage)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(ppSystemAssembly != NULL);

    EX_TRY
    {
        ReleaseHolder<BINDER_SPACE::Assembly> pAsm;
#ifdef FEATURE_CORECLR
        StackSString systemPath(SystemDomain::System()->SystemDirectory());
        hr = AssemblyBinder::BindToSystem(systemPath, &pAsm, fBindToNativeImage);
#else
        AssemblySpec::BindToSystem(&pAsm);
#endif
        if(SUCCEEDED(hr))
        {
            _ASSERTE(pAsm != NULL);
            *ppSystemAssembly = pAsm.Extract();
        }
    }
    EX_CATCH_HRESULT(hr);

    return hr;
}
Exemple #18
0
int coreclr_initialize(
            const char* exePath,
            const char* appDomainFriendlyName,
            int propertyCount,
            const char** propertyKeys,
            const char** propertyValues,
            void** hostHandle,
            unsigned int* domainId)
{
    HRESULT hr;
#ifdef FEATURE_PAL
    DWORD error = PAL_InitializeCoreCLR(exePath);
    hr = HRESULT_FROM_WIN32(error);

    // If PAL initialization failed, then we should return right away and avoid
    // calling any other APIs because they can end up calling into the PAL layer again.
    if (FAILED(hr))
    {
        return hr;
    }
#endif

    ReleaseHolder<ICLRRuntimeHost2> host;

    hr = CorHost2::CreateObject(IID_ICLRRuntimeHost2, (void**)&host);
    IfFailRet(hr);

    ConstWStringHolder appDomainFriendlyNameW = StringToUnicode(appDomainFriendlyName);

    STARTUP_FLAGS startupFlags;
    LPCWSTR* propertyKeysWTemp;
    LPCWSTR* propertyValuesWTemp;
    ExtractStartupFlagsAndConvertToUnicode(
        propertyKeys,
        propertyValues,
        &propertyCount,
        &startupFlags,
        &propertyKeysWTemp,
        &propertyValuesWTemp);
    
    ConstWStringArrayHolder propertyKeysW;
    propertyKeysW.Set(propertyKeysWTemp, propertyCount);
    
    ConstWStringArrayHolder propertyValuesW;
    propertyValuesW.Set(propertyValuesWTemp, propertyCount);

    hr = host->SetStartupFlags(startupFlags);
    IfFailRet(hr);

    hr = host->Start();
    IfFailRet(hr);

    hr = host->CreateAppDomainWithManager(
        appDomainFriendlyNameW,
        // Flags:
        // APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS
        // - By default CoreCLR only allows platform neutral assembly to be run. To allow
        //   assemblies marked as platform specific, include this flag
        //
        // APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP
        // - Allows sandboxed applications to make P/Invoke calls and use COM interop
        //
        // APPDOMAIN_SECURITY_SANDBOXED
        // - Enables sandboxing. If not set, the app is considered full trust
        //
        // APPDOMAIN_IGNORE_UNHANDLED_EXCEPTION
        // - Prevents the application from being torn down if a managed exception is unhandled
        //
        APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS |
        APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP |
        APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT,
        NULL,                    // Name of the assembly that contains the AppDomainManager implementation
        NULL,                    // The AppDomainManager implementation type name
        propertyCount,
        propertyKeysW,
        propertyValuesW,
        (DWORD *)domainId);

    if (SUCCEEDED(hr))
    {
        host.SuppressRelease();
        *hostHandle = host;
    }

    return hr;
}
HRESULT CLRPrivBinderAssemblyLoadContext::BindAssemblyByName(IAssemblyName     *pIAssemblyName,
                                                             ICLRPrivAssembly **ppAssembly)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(pIAssemblyName != nullptr && ppAssembly != nullptr);

    // DevDiv #933506: Exceptions thrown during AssemblyLoadContext.Load should propagate
    // EX_TRY
    {
        _ASSERTE(m_pTPABinder != NULL);
        
        ReleaseHolder<BINDER_SPACE::Assembly> pCoreCLRFoundAssembly;
        ReleaseHolder<AssemblyName> pAssemblyName;

        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.
        
        {
            // 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))
            {
                // If we are here, one of the following is possible:
                //
                // 1) The assembly has not been found in the current binder's application context (i.e. it has not already been loaded), OR
                // 2) An assembly with the same simple name was already loaded in the context of the current binder but we ran into a Ref/Def
                //    mismatch (either due to version difference or strong-name difference).
                //
                // 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);
                if (SUCCEEDED(hr))
                {
                    // We maybe returned an assembly that was bound to a different AssemblyLoadContext instance.
                    // In such a case, we will not overwrite the binding context (which would be wrong since it would not
                    // be present in the cache of the current binding context).
                    if (pCoreCLRFoundAssembly->GetBinder() == NULL)
                    {
                        pCoreCLRFoundAssembly->SetBinder(this);
                    }
                }
            }
        }
        
        IF_FAIL_GO(hr);
        
        // Extract the assembly reference. 
        //
        // For TPA assemblies that were bound, TPABinder
        // would have already set the binder reference for the assembly, so we just need to
        // extract the reference now.
        *ppAssembly = pCoreCLRFoundAssembly.Extract();
Exit:;        
    }
    // EX_CATCH_HRESULT(hr);

    return hr;
}
Exemple #20
0
//=====================================================================================================================
HRESULT CLRPrivBinderAppX::BindAppXAssemblyByNameWorker(
    IAssemblyName * pIAssemblyName,
    DWORD dwAppXBindFlags,
    CLRPrivAssemblyAppX ** ppAssembly)
{
    STANDARD_VM_CONTRACT;
    HRESULT hr = S_OK;

    fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_IMMERSIVE, &hr);

    VALIDATE_ARG_RET(pIAssemblyName != nullptr);
    VALIDATE_ARG_RET((dwAppXBindFlags & ABF_BindIL) == ABF_BindIL);
    VALIDATE_ARG_RET(ppAssembly != nullptr);

    DWORD dwContentType = AssemblyContentType_Default;
    IfFailRet(hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_CONTENT_TYPE, &dwContentType));
    if ((hr == S_OK) && (dwContentType != AssemblyContentType_Default))
    {
        IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
    }

    ReleaseHolder<CLRPrivAssemblyAppX> pAssembly;

    // Get the simple name.
    WCHAR wzSimpleName[_MAX_PATH];
    DWORD cchSimpleName = _MAX_PATH;
    IfFailRet(pIAssemblyName->GetName(&cchSimpleName, wzSimpleName));

    {   // Look for previous successful bind. Host callouts are now forbidden.
        ForbidSuspendThreadCrstHolder lock(&m_MapReadLock);
        pAssembly = clr::SafeAddRef(m_NameToAssemblyMap.Lookup(wzSimpleName));
    }

    if (pAssembly == nullptr)
    {
        ReleaseHolder<ICLRPrivResource> pResourceIL;
        ReleaseHolder<ICLRPrivResource> pResourceNI;

        // Create assembly identity using the simple name. For successful binds this will be updated
        // with the full assembly identity in the VerifyBind callback.
        NewHolder<AssemblyIdentity> pIdentity = new AssemblyIdentity();
        IfFailRet(pIdentity->Initialize(wzSimpleName));

        //
        // Check the head package first to see if this matches an EXE, then check
        // all packages to see if this matches a DLL.
        //
        WCHAR wzFilePath[_MAX_PATH];
        {
            hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

            if (FAILED(hr))
            {
                // Create simple name with .EXE extension
                WCHAR wzSimpleFileName[_MAX_PATH];
                wcscpy_s(wzSimpleFileName, NumItems(wzSimpleFileName), wzSimpleName);
                wcscat_s(wzSimpleFileName, NumItems(wzSimpleFileName), W(".EXE"));

                // Search for the file using AppX::FileFileInCurrentPackage helper.
                UINT32 cchFilePath = NumItems(wzFilePath);
                hr = AppX::FindFileInCurrentPackage(
                        wzSimpleFileName,
                        &cchFilePath,
                        wzFilePath,
                        PACKAGE_FILTER_CLR_DEFAULT,
                        (PCWSTR *)(void *)m_rgAltPaths,
                        m_cAltPaths,
                        m_pParentBinder != NULL ? AppX::FindFindInPackageFlags_SkipCurrentPackageGraph : AppX::FindFindInPackageFlags_None);
            }

            if (FAILED(hr))
            {
                // Create simple name with .DLL extension
                WCHAR wzSimpleFileName[_MAX_PATH];
                wcscpy_s(wzSimpleFileName, NumItems(wzSimpleFileName), wzSimpleName);
                wcscat_s(wzSimpleFileName, NumItems(wzSimpleFileName), W(".DLL"));

                // Search for the file using AppX::FileFileInCurrentPackage helper
                UINT32 cchFilePath = NumItems(wzFilePath);
                hr = AppX::FindFileInCurrentPackage(
                        wzSimpleFileName,
                        &cchFilePath,
                        wzFilePath,
                        PACKAGE_FILTER_CLR_DEFAULT,
                        (PCWSTR *)(void *)m_rgAltPaths,
                        m_cAltPaths,
                        m_pParentBinder != NULL ? AppX::FindFindInPackageFlags_SkipCurrentPackageGraph : AppX::FindFindInPackageFlags_None);
            }

            if (SUCCEEDED(hr))
            {
                fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FOUND, wzFilePath);
            }
            else
            {
                // Cache the bind failure result before returning. Careful not to overwrite the bind result with the cache insertion result.
                HRESULT hrResult = hr;
                IfFailRet(CacheBindResult(pIdentity, hr));
                if (hr == S_OK)
                {   // Cache now owns identity object lifetime.
                    pIdentity.SuppressRelease();
                }
                hr = hrResult;
            }
            IfFailRet(hr);
        }

        NewHolder<CLRPrivResourcePathImpl> pResourcePath = new CLRPrivResourcePathImpl(wzFilePath);
        IfFailRet(pResourcePath->QueryInterface(__uuidof(ICLRPrivResource), (LPVOID*)&pResourceIL));
        pResourcePath.SuppressRelease();

        // Create an IBindResult and provide it to the new CLRPrivAssemblyAppX object.
        ReleaseHolder<IBindResult> pIBindResult = ToInterface<IBindResult>(
            new CLRPrivAssemblyBindResultWrapper(pIAssemblyName, wzFilePath, m_pFingerprintFactory));


        // Create the new CLRPrivAssemblyAppX object.
        NewHolder<CLRPrivAssemblyAppX> pAssemblyObj =
            new CLRPrivAssemblyAppX(pIdentity, this, pResourceIL, pIBindResult);

        //
        // Check cache. If someone beat us then use it instead; otherwise add new ICLRPrivAssembly.
        //
        do
        {
            // Because the read lock must be taken within a ForbidSuspend region, use AddInPhases.
            if (m_NameToAssemblyMap.CheckAddInPhases<ForbidSuspendThreadCrstHolder, CrstHolder>(
                    pAssemblyObj, m_MapReadLock, m_MapWriteLock, pAssemblyObj.GetValue()))
            {
                {   // Careful not to allow the cache insertion result to overwrite the bind result.
                    HRESULT hrResult = hr;
                    IfFailRet(CacheBindResult(pIdentity, hr));
                    if (hr == S_OK)
                    {   // Cache now owns identity object lifetime, but ~CLRPrivBinderAssembly
                        // can also remove the identity from the cache prior to cache deletion.
                        pIdentity.SuppressRelease();
                    }
                    hr = hrResult;
                }
                
                pAssembly = pAssemblyObj.Extract();
            }
            else
            {
                ForbidSuspendThreadCrstHolder lock(&m_MapReadLock);
                pAssembly = clr::SafeAddRef(m_NameToAssemblyMap.Lookup(wzSimpleName));
            }
        }
        while (pAssembly == nullptr); // Keep looping until we find the existing one, or add a new one
    }

    _ASSERTE(pAssembly != nullptr);

    if (((dwAppXBindFlags & ABF_BindNI) == ABF_BindNI) && 
        m_fCanUseNativeImages)
    {
        //
        // Look to see if there's a native image available.
        //

        // Fire BindingNgenPhaseStart ETW event if enabled.
        {
            InlineSString<128> ssAssemblyName;
            FireEtwBindingNgenPhaseStart(
                (AppDomain::GetCurrentDomain()->GetId().m_dwId),
                LOADCTX_TYPE_HOSTED,
                ETWFieldUnused,
                ETWLoaderLoadTypeNotAvailable,
                NULL,
                FusionBind::GetAssemblyNameDisplayName(pIAssemblyName, ssAssemblyName, ASM_DISPLAYF_FULL).GetUnicode(),
                GetClrInstanceId());
        }

        ReleaseHolder<IBindResult> pIBindResultIL;
        IfFailRet(pAssembly->GetIBindResult(&pIBindResultIL));
        _ASSERTE(pIBindResultIL != nullptr);

        NewArrayHolder<WCHAR> wzZapSet = DuplicateStringThrowing(g_pConfig->ZapSet());
        NativeConfigData cfgData = {
            wzZapSet,
            PEFile::GetNativeImageConfigFlags()
        };

        IfFailRet(BindToNativeAssembly(
            pIBindResultIL, &cfgData, static_cast<IBindContext*>(this), fusion::logging::GetCurrentFusionBindLog()));

        // Ensure that the native image found above in BindToNativeAssembly is reported as existing in the CLRPrivAssembly object
        if (hr == S_OK)
        {
            ReleaseHolder<ICLRPrivResource> pNIImageResource;
            // This will make GetAvailableImageTypes return that a native image exists.
            IfFailRet(pAssembly->GetImageResource(ASSEMBLY_IMAGE_TYPE_NATIVE, NULL, &pNIImageResource));
#ifdef _DEBUG
            DWORD dwImageTypes;

            _ASSERTE(SUCCEEDED(pAssembly->GetAvailableImageTypes(&dwImageTypes)));
            _ASSERTE((dwImageTypes & ASSEMBLY_IMAGE_TYPE_NATIVE) == ASSEMBLY_IMAGE_TYPE_NATIVE);
#endif
        }

        // Fire BindingNgenPhaseEnd ETW event if enabled.
        {
            InlineSString<128> ssAssemblyName;
            FireEtwBindingNgenPhaseEnd(
                (AppDomain::GetCurrentDomain()->GetId().m_dwId),
                LOADCTX_TYPE_HOSTED,
                ETWFieldUnused,
                ETWLoaderLoadTypeNotAvailable,
                NULL,
                FusionBind::GetAssemblyNameDisplayName(pIAssemblyName, ssAssemblyName, ASM_DISPLAYF_FULL).GetUnicode(),
                GetClrInstanceId());
        }

        // BindToNativeAssembly can return S_FALSE, but this could be misleading.
        if (hr == S_FALSE)
            hr = S_OK;
    }

    if (SUCCEEDED(hr))
    {
        *ppAssembly = pAssembly.Extract();
    }

    return hr;
}
HRESULT CLRPrivBinderAssemblyLoadContext::BindAssemblyByName(IAssemblyName     *pIAssemblyName,
        ICLRPrivAssembly **ppAssembly)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(pIAssemblyName != nullptr && ppAssembly != nullptr);

    // DevDiv #933506: Exceptions thrown during AssemblyLoadContext.Load should propagate
    // EX_TRY
    {
        _ASSERTE(m_pTPABinder != NULL);

        ReleaseHolder<BINDER_SPACE::Assembly> pCoreCLRFoundAssembly;
        ReleaseHolder<AssemblyName> pAssemblyName;

        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))
        {
            // 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))
            {
                // If we are here, one of the following is possible:
                //
                // 1) The assembly has not been found in the current binder's application context (i.e. it has not already been loaded), OR
                // 2) An assembly with the same simple name was already loaded in the context of the current binder but we ran into a Ref/Def
                //    mismatch (either due to version difference or strong-name difference).
                //
                // 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);
                if (SUCCEEDED(hr))
                {
                    // We maybe returned an assembly that was bound to a different AssemblyLoadContext instance.
                    // In such a case, we will not overwrite the binding context (which would be wrong since it would not
                    // be present in the cache of the current binding context).
                    if (pCoreCLRFoundAssembly->GetBinder() == NULL)
                    {
                        pCoreCLRFoundAssembly->SetBinder(this);
                    }
                }
            }
        }

        IF_FAIL_GO(hr);

        // Extract the assembly reference.
        //
        // For TPA assemblies that were bound, TPABinder
        // would have already set the binder reference for the assembly, so we just need to
        // extract the reference now.
        *ppAssembly = pCoreCLRFoundAssembly.Extract();
Exit:
        ;
    }
    // EX_CATCH_HRESULT(hr);

    return hr;
}
HRESULT CLRPrivBinderAssemblyLoadContext::BindUsingPEImage( /* in */ PEImage *pPEImage,
        /* in */ BOOL fIsNativeImage,
        /* [retval][out] */ ICLRPrivAssembly **ppAssembly)
{
    HRESULT hr = S_OK;

    EX_TRY
    {
        ReleaseHolder<BINDER_SPACE::Assembly> pCoreCLRFoundAssembly;
        ReleaseHolder<BINDER_SPACE::AssemblyName> pAssemblyName;
        ReleaseHolder<IMDInternalImport> pIMetaDataAssemblyImport;

        PEKIND PeKind = peNone;

        // Get the Metadata interface
        DWORD dwPAFlags[2];
        IF_FAIL_GO(BinderAcquireImport(pPEImage, &pIMetaDataAssemblyImport, dwPAFlags, fIsNativeImage));
        IF_FAIL_GO(AssemblyBinder::TranslatePEToArchitectureType(dwPAFlags, &PeKind));

        _ASSERTE(pIMetaDataAssemblyImport != NULL);

        // Using the information we just got, initialize the assemblyname
        SAFE_NEW(pAssemblyName, AssemblyName);
        IF_FAIL_GO(pAssemblyName->Init(pIMetaDataAssemblyImport, PeKind));

        // Validate architecture
        if (!BINDER_SPACE::Assembly::IsValidArchitecture(pAssemblyName->GetArchitecture()))
        {
            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
        if (pAssemblyName->IsMscorlib())
        {
            IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
        }

        {
            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:
        ;
    }
    EX_CATCH_HRESULT(hr);

    return hr;
}
Exemple #23
0
HRESULT ExecuteAssembly(
            LPCSTR exePath,
            LPCSTR coreClrPath,
            LPCSTR appDomainFriendlyName,
            int propertyCount,
            LPCSTR* propertyKeys,
            LPCSTR* propertyValues,
            int argc,
            LPCSTR* argv,
            LPCSTR managedAssemblyPath,
            LPCSTR entryPointAssemblyName,
            LPCSTR entryPointTypeName,
            LPCSTR entryPointMethodName,
            DWORD* exitCode)
{
    if (exitCode == NULL)
    {
        return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
    }
    *exitCode = -1;

    DWORD error = PAL_InitializeCoreCLR(exePath, coreClrPath, true);
    HRESULT hr = HRESULT_FROM_WIN32(error);

    // If PAL initialization failed, then we should return right away and avoid
    // calling any other APIs because they can end up calling into the PAL layer again.
    if (FAILED(hr))
    {
        return hr;
    }

    ReleaseHolder<ICLRRuntimeHost2> host;

    hr = CorHost2::CreateObject(IID_ICLRRuntimeHost2, (void**)&host);
    IfFailRet(hr);

    hr = host->SetStartupFlags((STARTUP_FLAGS)
                               (STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN |
                                STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN));
    IfFailRet(hr);

    hr = host->Start();
    IfFailRet(hr);
    
    ConstWStringHolder appDomainFriendlyNameW = StringToUnicode(appDomainFriendlyName);
    
    ConstWStringArrayHolder propertyKeysW;
    propertyKeysW.Set(StringArrayToUnicode(propertyCount, propertyKeys), propertyCount);
    
    ConstWStringArrayHolder propertyValuesW;
    propertyValuesW.Set(StringArrayToUnicode(propertyCount, propertyValues), propertyCount);

    DWORD domainId;

    hr = host->CreateAppDomainWithManager(
        appDomainFriendlyNameW,
        // Flags:
        // APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS
        // - By default CoreCLR only allows platform neutral assembly to be run. To allow
        //   assemblies marked as platform specific, include this flag
        //
        // APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP
        // - Allows sandboxed applications to make P/Invoke calls and use COM interop
        //
        // APPDOMAIN_SECURITY_SANDBOXED
        // - Enables sandboxing. If not set, the app is considered full trust
        //
        // APPDOMAIN_IGNORE_UNHANDLED_EXCEPTION
        // - Prevents the application from being torn down if a managed exception is unhandled
        //
        APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS |
        APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP |
        APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT,
        NULL,                    // Name of the assembly that contains the AppDomainManager implementation
        NULL,                    // The AppDomainManager implementation type name
        propertyCount,
        propertyKeysW,
        propertyValuesW,
        &domainId);
    IfFailRet(hr);

    ConstWStringArrayHolder argvW;
    argvW.Set(StringArrayToUnicode(argc, argv), argc);
    
    if (entryPointAssemblyName == NULL || entryPointTypeName == NULL || entryPointMethodName == NULL)
    {
        ConstWStringHolder managedAssemblyPathW = StringToUnicode(managedAssemblyPath);

        hr = host->ExecuteAssembly(domainId, managedAssemblyPathW, argc, argvW, exitCode);
        IfFailRet(hr);
    }
    else
    {
        ConstWStringHolder entryPointAssemblyNameW = StringToUnicode(entryPointAssemblyName);
        ConstWStringHolder entryPointTypeNameW = StringToUnicode(entryPointTypeName);
        ConstWStringHolder entryPointMethodNameW = StringToUnicode(entryPointMethodName);

        HostMain pHostMain;

        hr = host->CreateDelegate(
            domainId,
            entryPointAssemblyNameW,
            entryPointTypeNameW,
            entryPointMethodNameW,
            (INT_PTR*)&pHostMain);
        
        IfFailRet(hr);

        *exitCode = pHostMain(argc, argvW);
    }
    
    hr = host->UnloadAppDomain(domainId,
                               true); // Wait until done
    IfFailRet(hr);

    hr = host->Stop();

    // The PAL_Terminate is not called here since it would terminate the current process.

    return hr;
}
Exemple #24
0
HRESULT ExecuteAssembly(
            LPCSTR exePath,
            LPCSTR coreClrPath,
            LPCSTR appDomainFriendlyName,
            int propertyCount,
            LPCSTR* propertyKeys,
            LPCSTR* propertyValues,
            int argc,
            LPCSTR* argv,
            LPCSTR managedAssemblyPath,
            LPCSTR entryPointAssemblyName,
            LPCSTR entryPointTypeName,
            LPCSTR entryPointMethodName,
            DWORD* exitCode)
{
    if (exitCode == NULL)
    {
        return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
    }
    *exitCode = -1;

    ReleaseHolder<ICLRRuntimeHost2> host; //(reinterpret_cast<ICLRRuntimeHost2*>(hostHandle));
    DWORD domainId;

    HRESULT hr = coreclr_initialize(exePath, appDomainFriendlyName, propertyCount, propertyKeys, propertyValues, &host, &domainId);
    IfFailRet(hr);

    ConstWStringArrayHolder argvW;
    argvW.Set(StringArrayToUnicode(argc, argv), argc);
    
    if (entryPointAssemblyName == NULL || entryPointTypeName == NULL || entryPointMethodName == NULL)
    {
        ConstWStringHolder managedAssemblyPathW = StringToUnicode(managedAssemblyPath);

        hr = host->ExecuteAssembly(domainId, managedAssemblyPathW, argc, argvW, exitCode);
        IfFailRet(hr);
    }
    else
    {
        ConstWStringHolder entryPointAssemblyNameW = StringToUnicode(entryPointAssemblyName);
        ConstWStringHolder entryPointTypeNameW = StringToUnicode(entryPointTypeName);
        ConstWStringHolder entryPointMethodNameW = StringToUnicode(entryPointMethodName);

        HostMain pHostMain;

        hr = host->CreateDelegate(
            domainId,
            entryPointAssemblyNameW,
            entryPointTypeNameW,
            entryPointMethodNameW,
            (INT_PTR*)&pHostMain);
        
        IfFailRet(hr);

        *exitCode = pHostMain(argc, argvW);
    }

    hr = coreclr_shutdown(host, domainId);

    return hr;
}
Exemple #25
0
    /* static */
    HRESULT Compatibility::Retarget(AssemblyName  *pAssemblyName,
                                    AssemblyName **ppRetargetedAssemblyName,
                                    BOOL          *pfIsRetargeted)
    {
        HRESULT hr = S_OK;
        BINDER_LOG_ENTER(W("Compatibility::Retarget"));

        IF_FALSE_GO(pAssemblyName != NULL);
        IF_FALSE_GO(ppRetargetedAssemblyName != NULL);

        BINDER_LOG_ASSEMBLY_NAME(W("source"), pAssemblyName);

        if (pfIsRetargeted)
        {
            *pfIsRetargeted = FALSE;
        }
#ifdef FEATURE_CORESYSTEM
        // Apply retargeting only for strong-named culture neutral assemblies
        if (pAssemblyName->IsStronglyNamed() &&
            pAssemblyName->GetDeNormalizedCulture().IsEmpty())
        {
            ReleaseHolder<AssemblyName> pRetargetedAssemblyName;
            SString &simpleName = pAssemblyName->GetSimpleName();
            AssemblyVersion *pAssemblyVersion = pAssemblyName->GetVersion();
            SString publicKeyToken;

            TextualIdentityParser::BlobToHex(pAssemblyName->GetPublicKeyTokenBLOB(),
                                                 publicKeyToken);

            // Perform linear search for matching assembly. Legacy Fusion also does that
            for (unsigned int i = 0; i < LENGTH_OF(arRetargetConfig); i++)
            {
#ifdef FEATURE_LEGACYNETCF
                if (!RuntimeIsLegacyNetCF(0) && arRetargetConfig[i].fMangoOnly == TRUE)
                    continue;
#endif
                if (IsMatchingString(simpleName, arRetargetConfig[i].pwzSimpleName) &&
                    IsMatchingVersion(pAssemblyVersion, arRetargetConfig[i].pwzVersion) &&
                    IsMatchingString(publicKeyToken, arRetargetConfig[i].pwzPublicKeyToken))
                {
                    AssemblyVersion newAssemblyVersion;
                    IF_FALSE_GO(newAssemblyVersion.SetVersion(arRetargetConfig[i].pwzNewVersion));

                    SAFE_NEW(pRetargetedAssemblyName, AssemblyName);

                    if (arRetargetConfig[i].pwzNewSimpleName != NULL)
                    {
                        pRetargetedAssemblyName->
                            GetSimpleName().Set(arRetargetConfig[i].pwzNewSimpleName);
                    }
                    else
                    {
                        pRetargetedAssemblyName->GetSimpleName().Set(simpleName);
                    }
                    pRetargetedAssemblyName->SetVersion(&newAssemblyVersion);
                    
                    SBuffer newPublicKeyTokenBlob;
                    SmallStackSString newPublicKeyToken(arRetargetConfig[i].pwzNewPublicKeyToken);
                    TextualIdentityParser::HexToBlob(newPublicKeyToken,
                                                          FALSE /* fValidateHex */,
                                                          TRUE /* fIsToken */,
                                                          newPublicKeyTokenBlob);

                    pRetargetedAssemblyName->GetPublicKeyTokenBLOB().Set(newPublicKeyTokenBlob);

                    BINDER_LOG_ASSEMBLY_NAME(W("retargeted"), pRetargetedAssemblyName);

                    *ppRetargetedAssemblyName = pRetargetedAssemblyName.Extract();

                    if (pfIsRetargeted)
                    {
                        *pfIsRetargeted = TRUE;
                    }

                    GO_WITH_HRESULT(S_OK);
                }
            }

            // Create a clone without retargetable flag
            if (pAssemblyName->GetIsRetargetable())
            {
                IF_FAIL_GO(pAssemblyName->Clone(&pRetargetedAssemblyName));
                pRetargetedAssemblyName->SetIsRetargetable(FALSE);
                *ppRetargetedAssemblyName = pRetargetedAssemblyName.Extract();
            } else
            {
                pAssemblyName->AddRef();
                *ppRetargetedAssemblyName = pAssemblyName;
            }
        }
        else
#endif // FEATURE_CORESYSTEM
        {
            pAssemblyName->AddRef();
            *ppRetargetedAssemblyName = pAssemblyName;
        }

    Exit:
        BINDER_LOG_LEAVE_HR(W("Compatibility::Retarget"), hr);
        return hr;
    }
// ============================================================================
// CLRPrivBinderCoreCLR implementation
// ============================================================================
HRESULT CLRPrivBinderCoreCLR::BindAssemblyByName(IAssemblyName     *pIAssemblyName,
                                                 ICLRPrivAssembly **ppAssembly)
{
    HRESULT hr = S_OK;
    VALIDATE_ARG_RET(pIAssemblyName != nullptr && ppAssembly != nullptr);
    
    EX_TRY
    {
        *ppAssembly = nullptr;

        ReleaseHolder<BINDER_SPACE::Assembly> pCoreCLRFoundAssembly;
        ReleaseHolder<AssemblyName> pAssemblyName;

        SAFE_NEW(pAssemblyName, AssemblyName);
        IF_FAIL_GO(pAssemblyName->Init(pIAssemblyName));
        
        hr = BindAssemblyByNameWorker(pAssemblyName, &pCoreCLRFoundAssembly, false /* excludeAppPaths */);

#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
        if ((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
            (hr == FUSION_E_APP_DOMAIN_LOCKED) || (hr == FUSION_E_REF_DEF_MISMATCH))
        {
            // If we are here, one of the following is possible:
            //
            // 1) The assembly has not been found in the current binder's application context (i.e. it has not already been loaded), OR
            // 2) An assembly with the same simple name was already loaded in the context of the current binder but we ran into a Ref/Def
            //    mismatch (either due to version difference or strong-name difference).
            //
            // 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.

            // Attempt to resolve the assembly via managed TPA ALC instance if one exists
            INT_PTR pManagedAssemblyLoadContext = GetManagedAssemblyLoadContext();
            if (pManagedAssemblyLoadContext != NULL)
            {
              hr = AssemblyBinder::BindUsingHostAssemblyResolver(pManagedAssemblyLoadContext, pAssemblyName, pIAssemblyName, 
              NULL, &pCoreCLRFoundAssembly);
              if (SUCCEEDED(hr))
              {
                  // We maybe returned an assembly that was bound to a different AssemblyLoadContext instance.
                  // In such a case, we will not overwrite the binding context (which would be wrong since it would not
                  // be present in the cache of the current binding context).
                  if (pCoreCLRFoundAssembly->GetBinder() == NULL)
                  {
                      pCoreCLRFoundAssembly->SetBinder(this);
                  }
              }
            }
        }
#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
        
        IF_FAIL_GO(hr);

        *ppAssembly = pCoreCLRFoundAssembly.Extract();

Exit:;        
    }
    EX_CATCH_HRESULT(hr);

    return hr;
}