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); }
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; }
FCIMPLEND #ifndef FEATURE_CORECLR FCIMPL1(Object*, AssemblyNameNative::EscapeCodeBase, StringObject* filenameUNSAFE) { FCALL_CONTRACT; STRINGREF rv = NULL; STRINGREF filename = (STRINGREF) filenameUNSAFE; HELPER_METHOD_FRAME_BEGIN_RET_1(filename); LPWSTR pCodeBase = NULL; DWORD dwCodeBase = 0; CQuickBytes qb; if (filename != NULL) { WCHAR* pString; int iString; filename->RefInterpretGetStringValuesDangerousForGC(&pString, &iString); dwCodeBase = (DWORD) iString; pCodeBase = (LPWSTR) qb.AllocThrows((++dwCodeBase) * sizeof(WCHAR)); memcpy(pCodeBase, pString, dwCodeBase*sizeof(WCHAR)); } if(pCodeBase) { CQuickBytes qb2; DWORD dwEscaped = 1; DWORD flags = 0; if (RunningOnWin7()) flags |= URL_ESCAPE_AS_UTF8; UrlEscape(pCodeBase, (LPWSTR) qb2.Ptr(), &dwEscaped, flags); LPWSTR result = (LPWSTR)qb2.AllocThrows((++dwEscaped) * sizeof(WCHAR)); HRESULT hr = UrlEscape(pCodeBase, result, &dwEscaped, flags); if (SUCCEEDED(hr)) rv = StringObject::NewString(result); else COMPlusThrowHR(hr); } HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(rv); }
int show_trace (char * str, va_list marker) { CQuickBytes buffer; int count = -1; int i = 1; while (count < 0) { # if _MSC_VER < 1400 HRESULT hr; if (FAILED(hr = buffer.ReSize (STRING_BUFFER_LEN * i))) die("Resize failed.", hr); #else buffer.ReSizeThrows (STRING_BUFFER_LEN * i); #endif count = _vsnprintf ((char *) buffer.Ptr(), STRING_BUFFER_LEN * i, str, marker); i *= 2; } fprintf (stderr, "%s", (char *) buffer.Ptr()); return count; }
FCIMPLEND FCIMPL1(Object*, AssemblyNameNative::GetPublicKeyToken, Object* refThisUNSAFE) { FCALL_CONTRACT; OBJECTREF orOutputArray = NULL; OBJECTREF refThis = (OBJECTREF) refThisUNSAFE; HELPER_METHOD_FRAME_BEGIN_RET_1(refThis); if (refThis == NULL) COMPlusThrow(kNullReferenceException, W("NullReference_This")); ASSEMBLYNAMEREF orThis = (ASSEMBLYNAMEREF)refThis; U1ARRAYREF orPublicKey = orThis->GetPublicKey(); if (orPublicKey != NULL) { DWORD cb = orPublicKey->GetNumComponents(); StrongNameBufferHolder<BYTE> pbToken; if (cb) { CQuickBytes qb; BYTE *pbKey = (BYTE*) qb.AllocThrows(cb); memcpy(pbKey, orPublicKey->GetDataPtr(), cb); { GCX_PREEMP(); if (!StrongNameTokenFromPublicKey(pbKey, cb, &pbToken, &cb)) COMPlusThrowHR(StrongNameErrorInfo()); } } Security::CopyEncodingToByteArray(pbToken, cb, &orOutputArray); } HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(orOutputArray); }
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. 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()
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()
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; }
//***************************************************************************** // translating signature from one scope to another scope // // Implements public API code:IMetaDataEmit::TranslateSigWithScope. // Implements internal API code:IMetaDataHelper::TranslateSigWithScope. //***************************************************************************** STDMETHODIMP RegMeta::TranslateSigWithScope( // S_OK or error. IMetaDataAssemblyImport *pAssemImport, // [IN] importing assembly interface const void *pbHashValue, // [IN] Hash Blob for Assembly. ULONG cbHashValue, // [IN] Count of bytes. IMetaDataImport *pImport, // [IN] importing interface PCCOR_SIGNATURE pbSigBlob, // [IN] signature in the importing scope ULONG cbSigBlob, // [IN] count of bytes of signature IMetaDataAssemblyEmit *pAssemEmit,// [IN] emit assembly interface IMetaDataEmit *pEmit, // [IN] emit interface PCOR_SIGNATURE pvTranslatedSig, // [OUT] buffer to hold translated signature ULONG cbTranslatedSigMax, ULONG *pcbTranslatedSig) // [OUT] count of bytes in the translated signature { #ifdef FEATURE_METADATA_EMIT HRESULT hr = S_OK; IMDCommon *pAssemImportMDCommon = NULL; IMDCommon *pImportMDCommon = NULL; BEGIN_ENTRYPOINT_NOTHROW; RegMeta *pRegMetaAssemEmit = static_cast<RegMeta*>(pAssemEmit); RegMeta *pRegMetaEmit = NULL; CQuickBytes qkSigEmit; ULONG cbEmit; pRegMetaEmit = static_cast<RegMeta*>(pEmit); { // This function can cause new TypeRef being introduced. LOCKWRITE(); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); _ASSERTE(pvTranslatedSig && pcbTranslatedSig); if (pAssemImport) { IfFailGo(pAssemImport->QueryInterface(IID_IMDCommon, (void**)&pAssemImportMDCommon)); } IMetaModelCommon *pAssemImportMetaModelCommon = pAssemImportMDCommon ? pAssemImportMDCommon->GetMetaModelCommon() : 0; IfFailGo(pImport->QueryInterface(IID_IMDCommon, (void**)&pImportMDCommon)); IMetaModelCommon *pImportMetaModelCommon = pImportMDCommon->GetMetaModelCommon(); IfFailGo( ImportHelper::MergeUpdateTokenInSig( // S_OK or error. pRegMetaAssemEmit ? &(pRegMetaAssemEmit->m_pStgdb->m_MiniMd) : 0, // The assembly emit scope. &(pRegMetaEmit->m_pStgdb->m_MiniMd), // The emit scope. pAssemImportMetaModelCommon, // Assembly where the signature is from. pbHashValue, // Hash value for the import assembly. cbHashValue, // Size in bytes. pImportMetaModelCommon, // The scope where signature is from. pbSigBlob, // signature from the imported scope NULL, // Internal OID mapping structure. &qkSigEmit, // [OUT] translated signature 0, // start from first byte of the signature 0, // don't care how many bytes consumed &cbEmit)); // [OUT] total number of bytes write to pqkSigEmit memcpy(pvTranslatedSig, qkSigEmit.Ptr(), cbEmit > cbTranslatedSigMax ? cbTranslatedSigMax :cbEmit ); *pcbTranslatedSig = cbEmit; if (cbEmit > cbTranslatedSigMax) hr = CLDB_S_TRUNCATION; } ErrExit: END_ENTRYPOINT_NOTHROW; if (pAssemImportMDCommon) pAssemImportMDCommon->Release(); if (pImportMDCommon) pImportMDCommon->Release(); return hr; #else //!FEATURE_METADATA_EMIT return E_NOTIMPL; #endif //!FEATURE_METADATA_EMIT } // RegMeta::TranslateSigWithScope
//PrettyPrinting type names PCCOR_SIGNATURE PrettyPrintType( PCCOR_SIGNATURE typePtr, // type to convert, CQuickBytes *out, // where to put the pretty printed string IMDInternalImport *pIMDI, // ptr to IMDInternal class with ComSig DWORD formatFlags /*= formatILDasm*/) { mdToken tk; const char* str; int typ; CQuickBytes tmp; CQuickBytes Appendix; BOOL Reiterate; int n; do { Reiterate = FALSE; switch(typ = *typePtr++) { case ELEMENT_TYPE_VOID : str = "void"; goto APPEND; case ELEMENT_TYPE_BOOLEAN : str = "bool"; goto APPEND; case ELEMENT_TYPE_CHAR : str = "char"; goto APPEND; case ELEMENT_TYPE_I1 : str = "int8"; goto APPEND; case ELEMENT_TYPE_U1 : str = "uint8"; goto APPEND; case ELEMENT_TYPE_I2 : str = "int16"; goto APPEND; case ELEMENT_TYPE_U2 : str = "uint16"; goto APPEND; case ELEMENT_TYPE_I4 : str = "int32"; goto APPEND; case ELEMENT_TYPE_U4 : str = "uint32"; goto APPEND; case ELEMENT_TYPE_I8 : str = "int64"; goto APPEND; case ELEMENT_TYPE_U8 : str = "uint64"; goto APPEND; case ELEMENT_TYPE_R4 : str = "float32"; goto APPEND; case ELEMENT_TYPE_R8 : str = "float64"; goto APPEND; case ELEMENT_TYPE_U : str = "native uint"; goto APPEND; case ELEMENT_TYPE_I : str = "native int"; goto APPEND; case ELEMENT_TYPE_OBJECT : str = "object"; goto APPEND; case ELEMENT_TYPE_STRING : str = "string"; goto APPEND; case ELEMENT_TYPE_TYPEDBYREF : str = "typedref"; goto APPEND; APPEND: appendStr(out, (char*)str); break; case ELEMENT_TYPE_VALUETYPE : if ((formatFlags & FormatKwInNames) != 0) str = "valuetype "; else str = ""; goto DO_CLASS; case ELEMENT_TYPE_CLASS : if ((formatFlags & FormatKwInNames) != 0) str = "class "; else str = ""; goto DO_CLASS; DO_CLASS: appendStr(out, (char*)str); typePtr += CorSigUncompressToken(typePtr, &tk); if(IsNilToken(tk)) { appendStr(out, "[ERROR! NIL TOKEN]"); } else PrettyPrintClass(out, tk, pIMDI, formatFlags); break; case ELEMENT_TYPE_SZARRAY : insertStr(&Appendix,"[]"); Reiterate = TRUE; break; case ELEMENT_TYPE_ARRAY : { typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags); unsigned rank = CorSigUncompressData(typePtr); // <TODO> what is the syntax for the rank 0 case? </TODO> if (rank == 0) { appendStr(out, "[BAD: RANK == 0!]"); } else { _ASSERTE(rank != 0); #ifdef _PREFAST_ #pragma warning(push) #pragma warning(disable:22009) // "Suppress PREfast warnings about integer overflow" // PREFAST warns about using _alloca in a loop. However when we're in this switch case we do NOT // set Reiterate to true, so we only execute through the loop once! #pragma warning(disable:6263) // "Suppress PREfast warnings about stack overflow due to _alloca in a loop." #endif int* lowerBounds = (int*) _alloca(sizeof(int)*2*rank); int* sizes = &lowerBounds[rank]; memset(lowerBounds, 0, sizeof(int)*2*rank); unsigned numSizes = CorSigUncompressData(typePtr); _ASSERTE(numSizes <= rank); unsigned i; for(i =0; i < numSizes; i++) sizes[i] = CorSigUncompressData(typePtr); unsigned numLowBounds = CorSigUncompressData(typePtr); _ASSERTE(numLowBounds <= rank); for(i = 0; i < numLowBounds; i++) typePtr+=CorSigUncompressSignedInt(typePtr,&lowerBounds[i]); appendChar(out, '['); if (rank == 1 && numSizes == 0 && numLowBounds == 0) appendStr(out, "..."); else { for(i = 0; i < rank; i++) { //if (sizes[i] != 0 || lowerBounds[i] != 0) { if (lowerBounds[i] == 0 && i < numSizes) appendStrNum(out, sizes[i]); else { if(i < numLowBounds) { appendStrNum(out, lowerBounds[i]); appendStr(out, "..."); if (/*sizes[i] != 0 && */i < numSizes) appendStrNum(out, lowerBounds[i] + sizes[i] - 1); } } } if (i < rank-1) appendChar(out, ','); } } appendChar(out, ']'); #ifdef _PREFAST_ #pragma warning(pop) #endif } } break; case ELEMENT_TYPE_VAR : appendChar(out, '!'); n = CorSigUncompressData(typePtr); appendStrNum(out, n); break; case ELEMENT_TYPE_MVAR : appendChar(out, '!'); appendChar(out, '!'); n = CorSigUncompressData(typePtr); appendStrNum(out, n); break; case ELEMENT_TYPE_FNPTR : appendStr(out, "method "); appendStr(out, "METHOD"); // was: typePtr = PrettyPrintSignature(typePtr, 0x7FFF, "*", out, pIMDI, NULL); break; case ELEMENT_TYPE_GENERICINST : { typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags); if ((formatFlags & FormatSignature) == 0) break; if ((formatFlags & FormatAngleBrackets) != 0) appendStr(out, "<"); else appendStr(out,"["); unsigned numArgs = CorSigUncompressData(typePtr); bool needComma = false; while(numArgs--) { if (needComma) appendChar(out, ','); typePtr = PrettyPrintType(typePtr, out, pIMDI, formatFlags); needComma = true; } if ((formatFlags & FormatAngleBrackets) != 0) appendStr(out, ">"); else appendStr(out,"]"); break; } case ELEMENT_TYPE_PINNED : str = " pinned"; goto MODIFIER; case ELEMENT_TYPE_PTR : str = "*"; goto MODIFIER; case ELEMENT_TYPE_BYREF : str = "&"; goto MODIFIER; MODIFIER: insertStr(&Appendix, str); Reiterate = TRUE; break; default: case ELEMENT_TYPE_SENTINEL : case ELEMENT_TYPE_END : //_ASSERTE(!"Unknown Type"); if(typ) { char sz[64]; sprintf_s(sz,COUNTOF(sz),"/* UNKNOWN TYPE (0x%X)*/",typ); appendStr(out, sz); } break; } // end switch } while(Reiterate); if (Appendix.Size() > 0) appendStr(out,asString(&Appendix)); return(typePtr); }
LPSTR FillSymbolSearchPathThrows(CQuickBytes &qb) { STATIC_CONTRACT_GC_NOTRIGGER; STATIC_CONTRACT_CANNOT_TAKE_LOCK; SCAN_IGNORE_FAULT; // Faults from Wsz funcs are handled. #ifndef DACCESS_COMPILE // not allowed to do allocation if current thread suspends EE. if (IsSuspendEEThread ()) return NULL; #endif InlineSString<MAX_SYM_PATH> rcBuff ; // Working buffer WCHAR rcVerString[64]; // Extension for install directory. int chTotal = 0; // How full is working buffer. int ch; // If the NT symbol server path vars are there, then use those. chTotal = WszGetEnvironmentVariable(W("_NT_SYMBOL_PATH"), rcBuff); if (chTotal + 1 < MAX_SYM_PATH) rcBuff.Append(W(';')); // Copy the defacto NT symbol path as well. size_t sympathLength = chTotal + NumItems(DEFAULT_SYM_PATH) + 1; // integer overflow occurred if (sympathLength < (size_t)chTotal || sympathLength < NumItems(DEFAULT_SYM_PATH)) { return NULL; } if (sympathLength < MAX_SYM_PATH) { rcBuff.Append(DEFAULT_SYM_PATH); chTotal = rcBuff.GetCount(); } // Next, if there is a URTTARGET, add that since that is where ndpsetup places // your symobls on an install. PathString rcBuffTemp; ch = WszGetEnvironmentVariable(W("URTTARGET"), rcBuffTemp); rcBuff.Append(rcBuffTemp); if (ch != 0 && (chTotal + ch + 1 < MAX_SYM_PATH)) { size_t chNewTotal = chTotal + ch; if (chNewTotal < (size_t)chTotal || chNewTotal < (size_t)ch) { // integer overflow occurred return NULL; } chTotal += ch; rcBuff.Append(W(';')); } #ifndef SELF_NO_HOST // Fetch the path location of the engine dll and add that path as well, just // in case URTARGET didn't cut it either. // For no-host builds of utilcode, we don't necessarily have an engine DLL in the // process, so skip this part. ch = WszGetModuleFileName(GetCLRModuleHack(), rcBuffTemp); size_t pathLocationLength = chTotal + ch + 1; // integer overflow occurred if (pathLocationLength < (size_t)chTotal || pathLocationLength < (size_t)ch) { return NULL; } if (ch != 0 && (pathLocationLength < MAX_SYM_PATH)) { chTotal = chTotal + ch - NumItems(STR_ENGINE_NAME); rcBuff.Append(W(';')); } #endif // Now we have a working buffer with a bunch of interesting stuff. Time // to convert it back to ansi for the imagehlp api's. Allocate the buffer // 2x bigger to handle worst case for MBCS. ch = ::WszWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, 0, 0, 0, 0); LPSTR szRtn = (LPSTR) qb.AllocNoThrow(ch + 1); if (!szRtn) return NULL; WszWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, szRtn, ch+1, 0, 0); return (szRtn); }
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; }
// //****************************************************************************** void COMModule::DefineTypeRefHelper( IMetaDataEmit *pEmit, // given emit scope mdTypeDef td, // given typedef in the emit scope mdTypeRef *ptr) // return typeref { CONTRACTL { STANDARD_VM_CHECK; PRECONDITION(CheckPointer(pEmit)); PRECONDITION(CheckPointer(ptr)); } CONTRACTL_END; CQuickBytes qb; WCHAR* szTypeDef = (WCHAR*) qb.AllocThrows((MAX_CLASSNAME_LENGTH+1) * sizeof(WCHAR)); mdToken rs; // resolution scope DWORD dwFlags; SafeComHolder<IMetaDataImport> pImport; IfFailThrow( pEmit->QueryInterface(IID_IMetaDataImport, (void **)&pImport) ); IfFailThrow( pImport->GetTypeDefProps(td, szTypeDef, MAX_CLASSNAME_LENGTH, NULL, &dwFlags, NULL) ); if ( IsTdNested(dwFlags) ) { mdToken tdNested; IfFailThrow( pImport->GetNestedClassProps(td, &tdNested) ); DefineTypeRefHelper( pEmit, tdNested, &rs); } else rs = TokenFromRid( 1, mdtModule );
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; }
//****************************************************************************** // // GetMemberRefToken // This function will return a MemberRef token given a MethodDef token and the module where the MethodDef/FieldDef is defined. // //****************************************************************************** INT32 QCALLTYPE COMModule::GetMemberRef(QCall::ModuleHandle pModule, QCall::ModuleHandle pRefedModule, INT32 tr, INT32 token) { QCALL_CONTRACT; mdMemberRef memberRefE = 0; BEGIN_QCALL; RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter(); _ASSERTE( pRCW ); LPCUTF8 szName; ULONG cbComSig; PCCOR_SIGNATURE pvComSig; if (TypeFromToken(token) == mdtMethodDef) { IfFailThrow(pRefedModule->GetMDImport()->GetNameOfMethodDef(token, &szName)); IfFailThrow(pRefedModule->GetMDImport()->GetSigOfMethodDef(token, &cbComSig, &pvComSig)); } else { IfFailThrow(pRefedModule->GetMDImport()->GetNameOfFieldDef(token, &szName)); IfFailThrow(pRefedModule->GetMDImport()->GetSigOfFieldDef(token, &cbComSig, &pvComSig)); } MAKE_WIDEPTR_FROMUTF8(wzName, szName); // Translate the method sig into this scope // Assembly * pRefedAssembly = pRefedModule->GetAssembly(); Assembly * pRefingAssembly = pModule->GetAssembly(); if (pRefedAssembly->IsCollectible() && pRefedAssembly != pRefingAssembly) { if (pRefingAssembly->IsCollectible()) pRefingAssembly->GetLoaderAllocator()->EnsureReference(pRefedAssembly->GetLoaderAllocator()); else COMPlusThrow(kNotSupportedException, W("NotSupported_CollectibleBoundNonCollectible")); } SafeComHolderPreemp<IMetaDataAssemblyEmit> pAssemblyEmit; IfFailThrow( pRefingAssembly->GetManifestModule()->GetEmitter()->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) ); CQuickBytes qbNewSig; ULONG cbNewSig; IfFailThrow( pRefedModule->GetMDImport()->TranslateSigWithScope( pRefedAssembly->GetManifestImport(), NULL, 0, // hash value pvComSig, cbComSig, pAssemblyEmit, // Emit assembly scope. pRCW->GetEmitter(), &qbNewSig, &cbNewSig) ); mdTypeRef tref; if (TypeFromToken(tr) == mdtTypeDef) { // define a TypeRef using the TypeDef DefineTypeRefHelper(pRCW->GetEmitter(), tr, &tref); } else tref = tr; // Define the memberRef IfFailThrow( pRCW->GetEmitter()->DefineMemberRef(tref, wzName, (PCCOR_SIGNATURE) qbNewSig.Ptr(), cbNewSig, &memberRefE) ); END_QCALL; // assign output parameter return (INT32)memberRefE; }