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; }
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); }
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()
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()
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()
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; }
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; }
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; }
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; }