示例#1
0
// Used by the IMetadata API's to access an assemblies metadata. 
HRESULT 
FusionBind::FindAssemblyByName(LPCWSTR  szAppBase,
                               LPCWSTR  szPrivateBin,
                               LPCWSTR  szAssemblyName,
                               IAssembly** ppAssembly,
                               IApplicationContext** ppFusionContext)
{
    TIMELINE_START(FUSIONBIND, ("FindAssemblyByName %S", szAssemblyName));

    _ASSERTE(szAssemblyName);

    IApplicationContext *pFusionContext = NULL;

    MAKE_UTF8PTR_FROMWIDE(pName, szAssemblyName);
    FusionBind spec;
    
    spec.Init(pName);
    HRESULT hr = SetupFusionContext(szAppBase, szPrivateBin, &pFusionContext);
    if(SUCCEEDED(hr)) {
        IAssembly* fusionAssembly;
        hr = spec.LoadAssembly(pFusionContext, 
                               &fusionAssembly);
        
        *ppAssembly = fusionAssembly;
        
        if(ppFusionContext) 
            *ppFusionContext = pFusionContext;
        else if(pFusionContext)
            pFusionContext->Release();
    }

    TIMELINE_END(FUSIONBIND, ("FindAssemblyByName %S", szAssemblyName));

    return hr;
}
示例#2
0
HRESULT AssemblySpec::InitializeSpec(IAssemblyName *pName, PEFile *pFile)
{
    _ASSERTE(pFile != NULL || pName != NULL);

    HRESULT hr = S_OK;
   
    //
    // Fill out info from name, if we have it.
    //

    if (pName != NULL)
    {
        hr = Init(pName);
    }
    else
    {
        MAKE_UTF8PTR_FROMWIDE(pName, pFile->GetFileName());

        m_pAssemblyName = new char [strlen(pName) + 1];
        if (m_pAssemblyName == NULL)
            return E_OUTOFMEMORY;
        strcpy((char*)m_pAssemblyName, pName);
        m_ownedFlags |= NAME_OWNED;           
    }

    return hr;
}
示例#3
0
FCIMPLEND

//**************************************************
// LoadInMemoryTypeByName
// Explicitly loading an in memory type
// <TODO>@todo: this function is not dealing with nested type correctly yet.
// We will need to parse the full name by finding "+" for enclosing type, etc.</TODO>
//**************************************************
void QCALLTYPE COMModule::LoadInMemoryTypeByName(QCall::ModuleHandle pModule, LPCWSTR wszFullName)
{
    QCALL_CONTRACT;
    
    TypeHandle      typeHnd;

    BEGIN_QCALL;

    if (!pModule->IsReflection())  
        COMPlusThrow(kNotSupportedException, W("NotSupported_NonReflectedType"));   

    RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
    _ASSERTE(pRCW);

    // it is ok to use public import API because this is a dynamic module anyway. We are also receiving Unicode full name as
    // parameter.
    IMetaDataImport * pImport = pRCW->GetRWImporter();

    if (wszFullName == NULL)
        IfFailThrow( E_FAIL );

    // look up the handle
    mdTypeDef  td;
    HRESULT hr = pImport->FindTypeDefByName(wszFullName, mdTokenNil, &td);
    if (FAILED(hr))
    {
        if (hr != CLDB_E_RECORD_NOTFOUND)
            COMPlusThrowHR(hr);

        // Get the UTF8 version of strFullName
        MAKE_UTF8PTR_FROMWIDE(szFullName, wszFullName);
        pModule->GetAssembly()->ThrowTypeLoadException(szFullName, IDS_CLASSLOAD_GENERAL);
    }

    TypeKey typeKey(pModule, td);
    typeHnd = pModule->GetClassLoader()->LoadTypeHandleForTypeKey(&typeKey, TypeHandle());

    END_QCALL;

    return;
}
示例#4
0
HRESULT AssemblySpec::LoadAssembly(Assembly** ppAssembly,
                                   OBJECTREF* pThrowable, /*= NULL*/
                                   OBJECTREF* pExtraEvidence, /*= NULL*/
                                   BOOL fPolicyLoad) /*= FALSE*/
{
    IAssembly* pIAssembly = NULL;

    HRESULT hr;
    Assembly *pAssembly = GetAppDomain()->FindCachedAssembly(this);
    if(pAssembly) {
        if ((pExtraEvidence != NULL) && (*pExtraEvidence != NULL))
            IfFailGo(SECURITY_E_INCOMPATIBLE_EVIDENCE);

        *ppAssembly = pAssembly;
        return S_FALSE;
    }

    PEFile *pFile;
    IfFailGo(GetAppDomain()->BindAssemblySpec(this, 
                                              &pFile, 
                                              &pIAssembly, 
                                              &pAssembly, 
                                              pExtraEvidence,
                                              pThrowable));

    // Loaded by AssemblyResolve event handler
    if (hr == S_FALSE) {

        //If loaded by the AssemblyResolve event, check that
        // the public keys are the same as in the AR.
        // However, if the found assembly is a dynamically
        // created one, security has decided to allow it.
        if (m_cbPublicKeyOrToken &&
            pAssembly->m_pManifestFile) {
                
            if (!pAssembly->m_cbPublicKey)
                IfFailGo(FUSION_E_PRIVATE_ASM_DISALLOWED);

            // Ref has the full key
            if (m_dwFlags & afPublicKey) {
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbPublicKey) ||
                    memcmp(m_pbPublicKeyOrToken, pAssembly->m_pbPublicKey, m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
            
            // Ref has a token
            else if (pAssembly->m_cbRefedPublicKeyToken) {
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbRefedPublicKeyToken) ||
                    memcmp(m_pbPublicKeyOrToken,
                           pAssembly->m_pbRefedPublicKeyToken,
                           m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
            else {
                if (!StrongNameTokenFromPublicKey(pAssembly->m_pbPublicKey,
                                                  pAssembly->m_cbPublicKey,
                                                  &pAssembly->m_pbRefedPublicKeyToken,
                                                  &pAssembly->m_cbRefedPublicKeyToken))
                    IfFailGo(StrongNameErrorInfo());
                
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbRefedPublicKeyToken) ||
                    memcmp(m_pbPublicKeyOrToken,
                           pAssembly->m_pbRefedPublicKeyToken,
                           m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
        }
        
        *ppAssembly = pAssembly;
        return S_OK;
    }


    // Until we can create multiple Assembly objects for a single HMODULE
    // we can only store one IAssembly* per Assembly. It is very important
    // to maintain the IAssembly* for an image that is in the load-context.
    // An Assembly in the load-from-context can bind to an assembly in the
    // load-context but not visa-versa. Therefore, if we every get an IAssembly
    // from the load-from-context we must make sure that it will never be 
    // found using a load. If it did then we could end up with Assembly dependencies
    // that are wrong. For example, if I do a LoadFrom() on an assembly in the GAC
    // and it requires another Assembly that I have preloaded in the load-from-context
    // then that dependency gets burnt into the Jitted code. Later on a Load() is
    // done on the assembly in the GAC and we single instance it back to the one
    // we have gotten from the load-from-context because the HMODULES are the same.
    // Now the dependency is wrong because it would not have the preloaded assembly
    // if the order was reversed.
    
    if (pIAssembly) {
        IFusionLoadContext *pLoadContext;
        hr = pIAssembly->GetFusionLoadContext(&pLoadContext);
        _ASSERTE(SUCCEEDED(hr));
        if (SUCCEEDED(hr)) {
            if (pLoadContext->GetContextType() == LOADCTX_TYPE_LOADFROM) {

                mdAssembly mda;
                if (FAILED(pFile->GetMDImport()->GetAssemblyFromScope(&mda))) {
                    hr = COR_E_ASSEMBLYEXPECTED;
                    goto exit;
                }

                LPCUTF8 psName;
                PBYTE pbPublicKey;
                DWORD cbPublicKey;
                AssemblyMetaDataInternal context;
                DWORD dwFlags;
                pFile->GetMDImport()->GetAssemblyProps(mda,
                                                       (const void**) &pbPublicKey,
                                                       &cbPublicKey,
                                                       NULL, // hash alg
                                                       &psName,
                                                       &context,
                                                       &dwFlags);
                
                AssemblySpec spec;
                if (FAILED(hr = spec.Init(psName, 
                                          &context, 
                                          pbPublicKey,
                                          cbPublicKey, 
                                          dwFlags)))
                    goto exit;
                    
                IAssemblyName* pFoundAssemblyName;
                if (FAILED(hr = spec.CreateFusionName(&pFoundAssemblyName, FALSE)))
                    goto exit;
                
                AssemblySink* pFoundSink = GetAppDomain()->GetAssemblySink();
                if(!pFoundSink) {
                    pFoundAssemblyName->Release();
                    hr = E_OUTOFMEMORY;
                    goto exit;
                }
                    
                IAssembly *pFoundIAssembly;
                BEGIN_ENSURE_PREEMPTIVE_GC();
                hr = FusionBind::GetAssemblyFromFusion(GetAppDomain()->GetFusionContext(),
                                                       pFoundSink,
                                                       pFoundAssemblyName,
                                                       &spec.m_CodeInfo,
                                                       &pFoundIAssembly);

                if(SUCCEEDED(hr)) {
                    DWORD dwFoundSize = MAX_PATH;
                    WCHAR wszFoundPath[MAX_PATH];
                    // Get the path to the module containing the manifest
                    if (SUCCEEDED(pFoundIAssembly->GetManifestModulePath(wszFoundPath,
                                                                         &dwFoundSize))) {
                        
                        // Keep the default context's IAssembly if the paths are the same
                        if (!_wcsicmp(wszFoundPath, pFile->GetFileName())) {
                            pIAssembly->Release();
                            pIAssembly = pFoundIAssembly;

                            // Make sure the new IAssembly isn't holding its own refcount on 
                            // the file (we've just verified we're holding the same file.)
                            // Otherwise we will leak the handle when we unload the assembly,
                            // assuming fusion decides to cache this IAssembly pointer 
                            // somewhere internally.
                            PEFile::ReleaseFusionMetadataImport(pFoundIAssembly);

                        }
                        else
                            pFoundIAssembly->Release();
                    }
                }

                pFoundAssemblyName->Release();
                pFoundSink->Release();
                END_ENSURE_PREEMPTIVE_GC();
                hr = S_OK;
            }
        exit:
            pLoadContext->Release();
        }
    }


    // Create the assembly and delay loading the main module.
    Module* pModule;
    hr = GetAppDomain()->LoadAssembly(pFile, 
                                      pIAssembly, 
                                      &pModule, 
                                      &pAssembly,
                                      pExtraEvidence, 
                                      fPolicyLoad,
                                      pThrowable);

    BEGIN_ENSURE_PREEMPTIVE_GC();
    if(SUCCEEDED(hr)) {
        *ppAssembly = pAssembly;
        /*HRESULT hrLoose =*/ GetAppDomain()->AddAssemblyToCache(this, pAssembly);
    }

    if(pIAssembly)
        pIAssembly->Release();
    END_ENSURE_PREEMPTIVE_GC();

 ErrExit:
    if (FAILED(hr) && (pThrowable!=NULL)) { 
        BEGIN_ENSURE_COOPERATIVE_GC();
        if ((pThrowable != RETURN_ON_ERROR) && (*pThrowable == NULL)) {
            if (m_pAssemblyName)
                PostFileLoadException(m_pAssemblyName, FALSE,NULL, hr, pThrowable);
            else {
                MAKE_UTF8PTR_FROMWIDE(szName, m_CodeInfo.m_pszCodeBase);
                PostFileLoadException(szName, TRUE,NULL, hr, pThrowable);
            }
        }
        END_ENSURE_COOPERATIVE_GC();
    }

    return hr;
}
示例#5
0
HRESULT AssemblySpec::LowLevelLoadManifestFile(PEFile** ppFile,
                                               IAssembly** ppIAssembly,
                                               Assembly **ppDynamicAssembly,
                                               OBJECTREF* pExtraEvidence,
                                               OBJECTREF* pThrowable)
{
    CANNOTTHROWCOMPLUSEXCEPTION();

    HRESULT hr = S_OK;
    IAssemblyName* pFusionAssemblyName = NULL;     // Assembly object to assembly in fusion cache

    if(!(m_pAssemblyName || m_CodeInfo.m_pszCodeBase)) {
        PostFileLoadException("", FALSE, NULL, COR_E_FILENOTFOUND, pThrowable);
        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
    }

    //
    // Check to see if this fits our rather loose idea of a reference to mscorlib.
    // If so, don't use fusion to bind it - do it ourselves.
    //

    if (IsMscorlib())
    {
        _ASSERTE(wcslen(SystemDomain::System()->BaseLibrary()) > 0);
        hr = PEFile::Create(SystemDomain::System()->BaseLibrary(), 
                            NULL, 
                            mdFileNil, 
                            TRUE, 
                            NULL, 
                            NULL, // Code base is the same as the name
                            NULL, // Extra Evidence
                            ppFile);
        _ASSERTE((*ppFile)->IsSystem());
        if (ppDynamicAssembly) *ppDynamicAssembly = NULL;
        return hr;
    }

    CQuickWSTR FusionLog;
    FusionLog.Ptr()[0]=L'\0';

    BEGIN_ENSURE_PREEMPTIVE_GC();

    Assembly *pAssembly = NULL;
    PEFile *pFile = NULL;

    hr = CreateFusionName(&pFusionAssemblyName);
    if (FAILED(hr))
        goto exit;

    hr = pFusionAssemblyName->SetProperty(ASM_NAME_NULL_CUSTOM,NULL,0); //do not look in ZAP
    if (FAILED(hr))
        goto exit;

    hr = GetAssemblyFromFusion(GetAppDomain(),
                               pFusionAssemblyName,
                               &m_CodeInfo,
                               ppIAssembly,
                               &pFile,
                               &FusionLog,
                               pExtraEvidence,
                               pThrowable);
    if(FAILED(hr)) {

            DWORD cb = 0;
            pFusionAssemblyName->GetDisplayName(NULL, &cb, 0);
            if(cb) {
                CQuickBytes qb;
                LPWSTR pwsFullName = (LPWSTR) qb.Alloc(cb*sizeof(WCHAR));

                if (SUCCEEDED(pFusionAssemblyName->GetDisplayName(pwsFullName, &cb, 0))) {
                if ((pAssembly = GetAppDomain()->RaiseAssemblyResolveEvent(pwsFullName, pThrowable)) != NULL) {
                        pFile = pAssembly->GetManifestFile();
                        hr = S_FALSE;
                    }
                }
            }

#ifdef _DEBUG
        if(FAILED(hr)) {
            if (m_pAssemblyName)
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load from full name, %s\n", m_pAssemblyName));
            else if (m_CodeInfo.m_pszCodeBase)
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load from codebase, %s\n",m_CodeInfo.m_pszCodeBase));
            else
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load unknown assembly.\n"));
        }
#endif //_DEBUG

    }

 exit:
    if (SUCCEEDED(hr)) {
        if (ppFile) *ppFile = pFile;
        if (ppDynamicAssembly) *ppDynamicAssembly = pAssembly;
    }

    if(pFusionAssemblyName)
        pFusionAssemblyName->Release();

    END_ENSURE_PREEMPTIVE_GC();

    if (FAILED(hr)) {
        if (m_pAssemblyName)
            PostFileLoadException(m_pAssemblyName, FALSE,FusionLog.Ptr(), hr, pThrowable);
        else {
            MAKE_UTF8PTR_FROMWIDE(szName, m_CodeInfo.m_pszCodeBase);
            PostFileLoadException(szName, TRUE,FusionLog.Ptr(), hr, pThrowable);
        }
    }

    return hr;
}