예제 #1
0
HRESULT FusionBind::ParseName()
{
    HRESULT hr = S_OK;

    if (m_fParsed || !m_pAssemblyName)
        return S_OK;

    TIMELINE_START(FUSIONBIND, ("ParseName %s", m_pAssemblyName));

    IAssemblyName *pName;

    CQuickBytes qb;
    long pwNameLen = WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, 0, 0);
    LPWSTR pwName = (LPWSTR) qb.Alloc(pwNameLen*sizeof(WCHAR));

    WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, pwName, pwNameLen); 
    IfFailRet(CreateAssemblyNameObject(&pName, pwName, CANOF_PARSE_DISPLAY_NAME, NULL));

    if (m_ownedFlags & NAME_OWNED)
        delete [] m_pAssemblyName;
    m_pAssemblyName = NULL;

    hr = Init(pName);

    pName->Release();

    TIMELINE_END(FUSIONBIND, ("ParseName %s", m_pAssemblyName));

    return hr;
}
예제 #2
0
HRESULT FusionBind::EmitToken(IMetaDataAssemblyEmit *pEmit, 
                              mdAssemblyRef *pToken)
{
    HRESULT hr;
    ASSEMBLYMETADATA AMD;

    IfFailRet(ParseName());

    AMD.usMajorVersion = m_context.usMajorVersion;
    AMD.usMinorVersion = m_context.usMinorVersion;
    AMD.usBuildNumber = m_context.usBuildNumber;
    AMD.usRevisionNumber = m_context.usRevisionNumber;

    if (m_context.szLocale) {
        AMD.cbLocale = MultiByteToWideChar(CP_ACP, 0, m_context.szLocale, -1, NULL, 0);
        AMD.szLocale = (LPWSTR) alloca(AMD.cbLocale);
        MultiByteToWideChar(CP_ACP, 0, m_context.szLocale, -1, AMD.szLocale, AMD.cbLocale);
    }
    else {
        AMD.cbLocale = 0;
        AMD.szLocale = NULL;
    }

    long pwNameLen = WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, 0, 0);
    CQuickBytes qb;
    LPWSTR pwName = (LPWSTR) qb.Alloc(pwNameLen*sizeof(WCHAR));

    WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, pwName, pwNameLen);
    return pEmit->DefineAssemblyRef(m_pbPublicKeyOrToken, m_cbPublicKeyOrToken,
                                    pwName,
                                    &AMD,
                                    NULL, 0,
                                    m_dwFlags, pToken);
}
예제 #3
0
int ns::MakeNestedTypeName(             // true ok, false out of memory
    CQuickBytes &qb,                    // Where to put results.
    LPCUTF8     szEnclosingName,        // Full name for enclosing type
    LPCUTF8     szNestedName)           // Full name for nested type
{
    _ASSERTE(szEnclosingName && szNestedName);
    int iLen = 2;
    iLen += (int)strlen(szEnclosingName);
    iLen += (int)strlen(szNestedName);
    LPUTF8 szOut = (LPUTF8) qb.Alloc(iLen);
    if (!szOut)
        return false;
    return ns::MakeNestedTypeName(szOut, iLen, szEnclosingName, szNestedName);
}   // int ns::MakeNestedTypeName()
예제 #4
0
int ns::MakePath(                       // true ok, false out of memory
    CQuickBytes &qb,                    // Where to put results.
    const WCHAR *szNameSpace,           // Namespace for name.
    const WCHAR *szName)                // Final part of name.
{
    int iLen = 2;
    if (szNameSpace)
        iLen += (int)wcslen(szNameSpace);
    if (szName)
        iLen += (int)wcslen(szName);
    WCHAR *szOut = (WCHAR *) qb.Alloc(iLen * sizeof(WCHAR));
    if (!szOut)
        return false;
    return ns::MakePath(szOut, iLen, szNameSpace, szName);
}   // int ns::MakePath()
예제 #5
0
int ns::MakePath(                       // true ok, false out of memory
    CQuickBytes &qb,                    // Where to put results.
    LPCUTF8     szNameSpace,            // Namespace for name.
    LPCUTF8     szName)                 // Final part of name.
{
    int iLen = 2;
    if (szNameSpace)
        iLen += (int)strlen(szNameSpace);
    if (szName)
        iLen += (int)strlen(szName);
    LPUTF8 szOut = (LPUTF8) qb.Alloc(iLen);
    if (!szOut)
        return false;
    return ns::MakePath(szOut, iLen, szNameSpace, szName);
}   // int ns::MakePath()
예제 #6
0
bool ns::MakeAssemblyQualifiedName(                                        // true ok, false out of memory
                                   CQuickBytes &qb,                        // Where to put results.
                                   const WCHAR *szTypeName,                // Namespace for name.
                                   const WCHAR *szAssemblyName)            // Final part of name.
{
    int iTypeName = 0;
    int iAssemblyName = 0;
    if (szTypeName)
        iTypeName = (int)wcslen(szTypeName);
    if (szAssemblyName)
        iAssemblyName = (int)wcslen(szAssemblyName);

    int iLen = ASSEMBLY_SEPARATOR_LEN + iTypeName + iAssemblyName + 1; // Space for null terminator
    WCHAR *szOut = (WCHAR *) qb.Alloc(iLen * sizeof(WCHAR));
    if (!szOut)
        return false;

#ifdef _DEBUG
	bool ret =
#endif
	ns::MakeAssemblyQualifiedName(szOut, iLen, szTypeName, iTypeName, szAssemblyName, iAssemblyName);
    _ASSERTE(ret);
    return true;
}   
예제 #7
0
HRESULT FusionBind::CreateFusionName(IAssemblyName **ppName, BOOL fIncludeHash)
{
    TIMELINE_START(FUSIONBIND, ("CreateFusionName %s", m_pAssemblyName));

    HRESULT hr;
    IAssemblyName *pFusionAssemblyName = NULL;
    LPWSTR pwAssemblyName = NULL;
    CQuickBytes qb;

    if (m_pAssemblyName) {
        long pwNameLen = WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, 0, 0);
        pwAssemblyName = (LPWSTR) qb.Alloc(pwNameLen*sizeof(WCHAR));

        WszMultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, pwAssemblyName, pwNameLen);
    }

    IfFailGo(CreateAssemblyNameObject(&pFusionAssemblyName, pwAssemblyName, 
                                      m_fParsed || (!pwAssemblyName) ? 0 : CANOF_PARSE_DISPLAY_NAME, NULL));


    if (m_fParsed) {
        if (m_context.usMajorVersion != (USHORT) -1) {
            IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_MAJOR_VERSION, 
                                                      &m_context.usMajorVersion, 
                                                      sizeof(USHORT)));
            
            if (m_context.usMinorVersion != (USHORT) -1) {
                IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_MINOR_VERSION, 
                                                          &m_context.usMinorVersion, 
                                                          sizeof(USHORT)));
                
                if (m_context.usBuildNumber != (USHORT) -1) {
                    IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_BUILD_NUMBER, 
                                                              &m_context.usBuildNumber, 
                                                              sizeof(USHORT)));
                    
                    if (m_context.usRevisionNumber != (USHORT) -1)
                        IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_REVISION_NUMBER, 
                                                                  &m_context.usRevisionNumber, 
                                                                  sizeof(USHORT)));
                }
            }
        }
        
        if (m_context.szLocale) {
            MAKE_WIDEPTR_FROMUTF8(pwLocale,m_context.szLocale);
            
            IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_CULTURE, 
                                                      pwLocale, 
                                                      (DWORD)(wcslen(pwLocale) + 1) * sizeof (WCHAR)));
        }
        
        if (m_pbPublicKeyOrToken) {
            if (m_cbPublicKeyOrToken) {
                if(m_dwFlags & afPublicKey) {
                    IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_PUBLIC_KEY,
                                                              m_pbPublicKeyOrToken, m_cbPublicKeyOrToken));
                }
                else {
                        IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
                                                                  m_pbPublicKeyOrToken, m_cbPublicKeyOrToken));
                }
            }
            else {
                IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN,
                                                          NULL, 0));
            }
        }
    }

    if (m_CodeInfo.m_dwCodeBase > 0) {
        IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_CODEBASE_URL,
                                                  (void*)m_CodeInfo.m_pszCodeBase, 
                                                  m_CodeInfo.m_dwCodeBase*sizeof(WCHAR)));
    }

    *ppName = pFusionAssemblyName;

    TIMELINE_END(FUSIONBIND, ("CreateFusionName %s", m_pAssemblyName));

    return S_OK;

 ErrExit:
    if (pFusionAssemblyName)
        pFusionAssemblyName->Release();

    TIMELINE_END(FUSIONBIND, ("CreateFusionName %s", m_pAssemblyName));

    return hr;
}
예제 #8
0
HRESULT FusionBind::Init(IAssemblyName *pName)
{
    _ASSERTE(pName);

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

    DWORD cbSize = 0;
    if (pName->GetProperty(ASM_NAME_NAME, NULL, &cbSize) 
        == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
        CQuickBytes qb;
        LPWSTR pwName = (LPWSTR) qb.Alloc(cbSize);

        IfFailRet(pName->GetProperty(ASM_NAME_NAME, pwName, &cbSize));

        cbSize = WszWideCharToMultiByte(CP_UTF8, 0, pwName, -1, NULL, 0, NULL, NULL);

        m_pAssemblyName = new char[cbSize];
        if (!m_pAssemblyName)
            return E_OUTOFMEMORY;

        m_ownedFlags |= NAME_OWNED;
        WszWideCharToMultiByte(CP_UTF8, 0, pwName, -1, (LPSTR) m_pAssemblyName, cbSize, NULL, NULL);
    }

    m_fParsed = TRUE;

    // Note: cascade checks so we don't set lower priority version #'s if higher ones are missing
    cbSize = sizeof(m_context.usMajorVersion);
    pName->GetProperty(ASM_NAME_MAJOR_VERSION, &m_context.usMajorVersion, &cbSize);

    if (!cbSize)
        m_context.usMajorVersion = (USHORT) -1;
    else {
        cbSize = sizeof(m_context.usMinorVersion);
        pName->GetProperty(ASM_NAME_MINOR_VERSION, &m_context.usMinorVersion, &cbSize);
    }

    if (!cbSize)
        m_context.usMinorVersion = (USHORT) -1;
    else {
        cbSize = sizeof(m_context.usBuildNumber);
        pName->GetProperty(ASM_NAME_BUILD_NUMBER, &m_context.usBuildNumber, &cbSize);
    }

    if (!cbSize)
        m_context.usBuildNumber = (USHORT) -1;
    else {
        cbSize = sizeof(m_context.usRevisionNumber);
        pName->GetProperty(ASM_NAME_REVISION_NUMBER, &m_context.usRevisionNumber, &cbSize);
    }

    if (!cbSize)
        m_context.usRevisionNumber = (USHORT) -1;

    cbSize = 0;
    if (pName->GetProperty(ASM_NAME_CULTURE, NULL, &cbSize)
        == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
        LPWSTR pwName = (LPWSTR) alloca(cbSize);
        IfFailRet(pName->GetProperty(ASM_NAME_CULTURE, pwName, &cbSize));

        cbSize = WszWideCharToMultiByte(CP_UTF8, 0, pwName, -1, NULL, 0, NULL, NULL);

        m_context.szLocale = new char [cbSize];
        if (!m_context.szLocale)
            return E_OUTOFMEMORY;
        m_ownedFlags |= LOCALE_OWNED;
        WszWideCharToMultiByte(CP_UTF8, 0, pwName, -1, (LPSTR) m_context.szLocale, cbSize, NULL, NULL);        
    }

    m_dwFlags = 0;

    cbSize = 0;
    if (pName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, NULL, &cbSize)
        == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
        m_pbPublicKeyOrToken = new BYTE[cbSize];
        if (m_pbPublicKeyOrToken == NULL)
            return E_OUTOFMEMORY;
        m_cbPublicKeyOrToken = cbSize;
        IfFailRet(pName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, m_pbPublicKeyOrToken, &cbSize));
        m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED;           
    }
    else if (pName->GetProperty(ASM_NAME_PUBLIC_KEY, NULL, &cbSize)
             == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
        m_pbPublicKeyOrToken = new BYTE[cbSize];
        if (m_pbPublicKeyOrToken == NULL)
            return E_OUTOFMEMORY;
        m_cbPublicKeyOrToken = cbSize;
        IfFailRet(pName->GetProperty(ASM_NAME_PUBLIC_KEY, m_pbPublicKeyOrToken, &cbSize));
        m_dwFlags |= afPublicKey;
        m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED;           
    }
    else if ((pName->GetProperty(ASM_NAME_NULL_PUBLIC_KEY, NULL, &cbSize) == S_OK) ||
             (pName->GetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN, NULL, &cbSize) == S_OK)) {
        m_pbPublicKeyOrToken = new BYTE[0];
        if (m_pbPublicKeyOrToken == NULL)
            return E_OUTOFMEMORY;
        m_cbPublicKeyOrToken = 0;
        m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED;           
    }

    cbSize = 0;
    if (pName->GetProperty(ASM_NAME_CODEBASE_URL, NULL, &cbSize)
        == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
        m_CodeInfo.m_pszCodeBase = new WCHAR [ cbSize/sizeof(WCHAR) ];
        if (m_CodeInfo.m_pszCodeBase == NULL)
            return E_OUTOFMEMORY;
        IfFailRet(pName->GetProperty(ASM_NAME_CODEBASE_URL, 
                                    (void*)m_CodeInfo.m_pszCodeBase, &cbSize));
        m_CodeInfo.m_dwCodeBase = cbSize/sizeof(WCHAR);
        m_ownedFlags |= CODE_BASE_OWNED;
    }

    return S_OK;
}
예제 #9
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;
}