HRESULT CAsmLink::GetResolutionScope(mdAssembly AssemblyID, mdToken FileToken, mdToken TargetFile, mdToken* pScope) { ASSERT(m_bInited && !m_bPreClosed && m_pAssem); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile) || (FileToken == AssemblyID)); ASSERT(pScope != NULL); if (FileToken == TargetFile) { *pScope = TokenFromRid(1, mdtModule); return S_OK; } HRESULT hr = S_OK; CFile *file = NULL; if (FileToken == AssemblyID) { file = m_pAssem; } else { if (FAILED(hr = m_pAssem->GetFile(FileToken, &file))) return hr; } if (TypeFromToken(TargetFile) == mdtFile) { // make a moduleref to target file in "file" CFile *target; if (FAILED(hr = m_pAssem->GetFile(TargetFile, &target))) return hr; hr = target->MakeModuleRef(file->GetEmitScope(), pScope); } else if (TypeFromToken(TargetFile) == mdtModule) { // make a moduleref to target file in "file" CFile *target; if (FAILED(hr = m_pModules->GetFile(TargetFile, &target))) return hr; hr = target->MakeModuleRef(file->GetEmitScope(), pScope); } else if (TypeFromToken(TargetFile) == mdtAssembly) { ASSERT(TargetFile != AssemblyIsUBM); // make a moduleref to the manifest file in "file" hr = m_pAssem->MakeModuleRef(file->GetEmitScope(), pScope); } else if (TypeFromToken(TargetFile) == mdtAssemblyRef) { // make an assembly ref in "file" CFile *target; if (FAILED(hr = m_pImports->GetFile(TargetFile, &target))) return hr; if (file == m_pAssem) // Special Case this so we don't have to re-QI for the AssemblyEmit interface hr = ((CAssemblyFile*)target)->MakeAssemblyRef(m_pAssem->GetEmitter(), pScope); else hr = ((CAssemblyFile*)target)->MakeAssemblyRef(file->GetEmitScope(), pScope); } else hr = E_INVALIDARG; return hr; }
HRESULT CAsmLink::EndMerge(mdAssembly AssemblyID) { ASSERT(m_bInited && !m_bPreClosed && !m_bManifestEmitted); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1)); return m_pAssem->ImportCAs(m_pAssem); }
HRESULT CAsmLink::EmitAssemblyCustomAttribute(mdAssembly AssemblyID, mdToken FileToken, mdToken tkType, void const* pCustomValue, DWORD cbCustomValue, BOOL bSecurity, BOOL bAllowMultiple) { ASSERT(m_bInited && !m_bPreClosed && !m_bManifestEmitted); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile) || (FileToken == AssemblyID)); HRESULT hr = S_OK; if (AssemblyID == AssemblyIsUBM) { CFile *file = NULL; if (FAILED(hr = m_pAssem->GetFile(FileToken, &file))) return hr; hr = file->AddCustomAttribute(tkType, pCustomValue, cbCustomValue, bSecurity, bAllowMultiple, NULL); } else if (FileToken == AssemblyID) { hr = m_pAssem->AddCustomAttribute(tkType, pCustomValue, cbCustomValue, bSecurity, bAllowMultiple, NULL); } else { // An assembly level custom attribute that is in the wrong scope CFile *file = NULL; if (FAILED(hr = m_pAssem->GetFile(FileToken, &file))) return hr; hr = m_pAssem->AddCustomAttribute(tkType, pCustomValue, cbCustomValue, bSecurity, bAllowMultiple, file); } return hr; }
//***************************************************************************** // cascading Mark of all properties associated with a TypeDef token //***************************************************************************** HRESULT FilterManager::MarkPropertiesWithParentToken( mdTypeDef td) { HRESULT hr = NOERROR; RID ridPropertyMap; RID ulStart, ulEnd; RID index; PropertyMapRec *pPropertyMapRec; // get the starting/ending rid of properties of this typedef IfFailGo(m_pMiniMd->FindPropertyMapFor(RidFromToken(td), &ridPropertyMap)); if ( !InvalidRid(ridPropertyMap) ) { IfFailGo(m_pMiniMd->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec)); ulStart = m_pMiniMd->getPropertyListOfPropertyMap( pPropertyMapRec ); IfFailGo(m_pMiniMd->getEndPropertyListOfPropertyMap(ridPropertyMap, &ulEnd)); for ( index = ulStart; index < ulEnd; index ++ ) { RID rid; IfFailGo(m_pMiniMd->GetPropertyRid(index, &rid)); IfFailGo(MarkProperty(TokenFromRid( rid, mdtProperty))); } } ErrExit: return hr; } // HRESULT FilterManager::MarkPropertiesWithParentToken()
HRESULT CAsmLink::AddImport(mdAssembly AssemblyID, mdToken ImportToken, DWORD dwFlags, mdFile * pFileToken) { // If we have already emitted the manifest, and then we import // a file with a CA that maps to an assembly option, we're in trouble! ASSERT(m_bInited && !m_bPreClosed && !m_bManifestEmitted); HRESULT hr; CFile *file = NULL; if (TypeFromToken(ImportToken) == mdtModule) { ASSERT(RidFromToken(ImportToken) < m_pModules->CountFiles()); hr = m_pModules->GetFile( ImportToken, &file); } else { ASSERT(TypeFromToken(ImportToken) == mdtAssemblyRef && RidFromToken(ImportToken) < m_pImports->CountFiles()); hr = m_pImports->GetFile( ImportToken, &file); } if (FAILED(hr)) return hr; ASSERT(file != NULL); if (FAILED(hr = m_pAssem->AddFile(file, dwFlags, pFileToken))) return hr; else if (AssemblyID == AssemblyIsUBM) { if (pFileToken) *pFileToken = ImportToken; return S_FALSE; } ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1)); if (FAILED(hr = m_pModules->RemoveFile( ImportToken))) return hr; if (FAILED(hr = file->ImportFile( NULL, m_pAssem))) return hr; return file->ImportResources(m_pAssem); }
HRESULT CAsmLink::SetAssemblyFile(LPCWSTR pszFilename, IMetaDataEmit *pEmitter, AssemblyFlags afFlags, mdAssembly *pAssemblyID) { ASSERT(m_bInited && !m_bPreClosed && !m_pAssem); ASSERT(pEmitter != NULL && pAssemblyID != NULL); HRESULT hr = E_FAIL; // NULL filename means 'InMemory' assembly, but we need a filename so convert it to the // empty string. if (pszFilename == NULL) { ASSERT(afFlags & afInMemory); pszFilename = L""; } if (FAILED(hr = SetNonAssemblyFlags(afFlags))) return hr; if (wcslen(pszFilename) > MAX_PATH) return FileNameTooLong(pszFilename); // File name too long CComPtr<IMetaDataAssemblyEmit> pAEmitter; hr = pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**)&pAEmitter); if (SUCCEEDED(hr)) { m_pAssem = new CAssemblyFile(pszFilename, afFlags, pAEmitter, pEmitter, m_pError, this); *pAssemblyID = TokenFromRid(mdtAssembly, 1); } return hr; }
HRESULT CAsmLink::AddFile(mdAssembly AssemblyID, LPCWSTR pszFilename, DWORD dwFlags, IMetaDataEmit *pEmitter, mdFile * pFileToken) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); // NULL filename means 'InMemory' module, but we need a filename so convert it to the // empty string. if (pszFilename == NULL) pszFilename = L""; if (AssemblyID == AssemblyIsUBM) { if (m_pAssem == NULL) m_pAssem = new CAssemblyFile(m_pError, this); } if (wcslen(pszFilename) > MAX_PATH) return FileNameTooLong(pszFilename); // File name too long HRESULT hr = S_OK; CFile *file = new CFile(pszFilename, pEmitter, m_pError, this); if (FAILED(hr = m_pAssem->AddFile(file, dwFlags, pFileToken))) delete file; return hr; }
HRESULT CAsmLink::LinkResource(mdAssembly AssemblyID, LPCWSTR pszFileName, LPCWSTR pszNewLocation, LPCWSTR pszResourceName, DWORD dwFlags) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); if (wcslen(pszFileName) > MAX_PATH) return FileNameTooLong(pszFileName); // File name too long HRESULT hr = S_OK; if (AssemblyID == AssemblyIsUBM) { hr = E_INVALIDARG; } else { if (pszNewLocation == NULL || pszNewLocation[0] == 0) pszNewLocation = pszFileName; CFile *file = NULL; file = new CFile( pszNewLocation, (IMetaDataEmit*)NULL, m_pError, this); if (file != NULL && pszNewLocation != NULL && pszNewLocation[0] != 0 && wcscmp(pszFileName, pszNewLocation) != 0) { if (FAILED(hr = file->SetSource(pszFileName))) { delete file; return hr; } } hr = m_pAssem->AddFile( file, ffContainsNoMetaData, NULL); if (SUCCEEDED(hr)) hr = m_pAssem->AddResource(file->GetFileToken(), pszResourceName, 0, dwFlags); else delete file; } return hr; }
mdFieldDef Binder::GetFieldDef(BinderFieldID id) { _ASSERTE(id != FIELD__NIL); _ASSERTE(id <= m_cFieldRIDs); if (m_pFieldRIDs[id-1] == 0) LookupField(id); return TokenFromRid(m_pFieldRIDs[id-1], mdtFieldDef); }
mdMethodDef Binder::GetMethodDef(BinderMethodID id) { _ASSERTE(id != METHOD__NIL); _ASSERTE(id <= m_cMethodRIDs); if (m_pMethodRIDs[id-1] == 0) LookupMethod(id); return TokenFromRid(m_pMethodRIDs[id-1], mdtMethodDef); }
mdTypeDef Binder::GetTypeDef(BinderClassID id) { _ASSERTE(id != CLASS__NIL); _ASSERTE(id <= m_cClassRIDs); if (m_pClassRIDs[id-1] == 0) LookupClass(id); return TokenFromRid(m_pClassRIDs[id-1], mdtTypeDef); }
HRESULT CAsmLink::EmitManifest(mdAssembly AssemblyID, DWORD* pdwReserveSize, mdAssembly* ptkManifest) { ASSERT(m_bInited && !m_bPreClosed && !m_bManifestEmitted); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1)); m_bManifestEmitted = true; return m_pAssem->EmitManifest(pdwReserveSize, ptkManifest); }
FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameUNSAFE) { FCALL_CONTRACT; struct _gc { ASSEMBLYNAMEREF result; STRINGREF filename; } gc; gc.result = NULL; gc.filename = (STRINGREF) filenameUNSAFE; HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); if (gc.filename == NULL) COMPlusThrow(kArgumentNullException, W("ArgumentNull_FileName")); if (gc.filename->GetStringLength() == 0) COMPlusThrow(kArgumentException, W("Argument_EmptyFileName")); gc.result = (ASSEMBLYNAMEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME)); /////////////////////////////////////////////// SString sFileName(gc.filename->GetBuffer()); PEImageHolder pImage = PEImage::OpenImage(sFileName, MDInternalImport_NoCache); EX_TRY { #ifdef FEATURE_CORECLR // Allow AssemblyLoadContext.GetAssemblyName for native images on CoreCLR if (pImage->HasNTHeaders() && pImage->HasCorHeader() && pImage->HasNativeHeader()) pImage->VerifyIsNIAssembly(); else pImage->VerifyIsAssembly(); #else pImage->VerifyIsAssembly(); #endif } EX_CATCH { Exception *ex = GET_EXCEPTION(); EEFileLoadException::Throw(sFileName,ex->GetHR(),ex); } EX_END_CATCH_UNREACHABLE; SString sUrl = sFileName; PEAssembly::PathToUrl(sUrl); AssemblySpec spec; spec.InitializeSpec(TokenFromRid(mdtAssembly,1),pImage->GetMDImport(),NULL,TRUE); spec.SetCodeBase(sUrl); spec.AssemblyNameInit(&gc.result, pImage); HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(gc.result); }
HRESULT RegMeta::OpenExistingMD( IMDCustomDataSource* pDataSource, // Name of database. ULONG dwOpenFlags) // Flags to control open. { HRESULT hr = NOERROR; m_OpenFlags = dwOpenFlags; if (!IsOfReOpen(dwOpenFlags)) { // Allocate our m_pStgdb, if we should. _ASSERTE(m_pStgdb == NULL); IfNullGo(m_pStgdb = new (nothrow)CLiteWeightStgdbRW); } IfFailGo(m_pStgdb->OpenForRead( pDataSource, m_OpenFlags)); if (m_pStgdb->m_MiniMd.m_Schema.m_major == METAMODEL_MAJOR_VER_V1_0 && m_pStgdb->m_MiniMd.m_Schema.m_minor == METAMODEL_MINOR_VER_V1_0) m_OptionValue.m_MetadataVersion = MDVersion1; else m_OptionValue.m_MetadataVersion = MDVersion2; IfFailGo(m_pStgdb->m_MiniMd.SetOption(&m_OptionValue)); if (IsThreadSafetyOn()) { m_pSemReadWrite = new (nothrow)UTSemReadWrite(); IfNullGo(m_pSemReadWrite); IfFailGo(m_pSemReadWrite->Init()); m_fOwnSem = true; INDEBUG(m_pStgdb->m_MiniMd.Debug_SetLock(m_pSemReadWrite);) } if (!IsOfReOpen(dwOpenFlags)) { #ifdef FEATURE_METADATA_EMIT_ALL // initialize the embedded merger m_newMerger.Init(this); #endif //FEATURE_METADATA_EMIT_ALL // There must always be a Global Module class and its the first entry in // the TypeDef table. m_tdModule = TokenFromRid(1, mdtTypeDef); } ErrExit: return hr; } //RegMeta::OpenExistingMD
HRESULT CAsmLink::ImportTypes(mdAssembly AssemblyID, mdToken FileToken, DWORD dwScope, HALINKENUM* phEnum, IMetaDataImport **ppImportScope, DWORD* pdwCountOfTypes) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((TypeFromToken(FileToken) == mdtFile && RidFromToken(FileToken) < m_pAssem->CountFiles()) || (TypeFromToken(FileToken) == mdtAssemblyRef && RidFromToken(FileToken) < m_pImports->CountFiles()) || (TypeFromToken(FileToken) == mdtModule && RidFromToken(FileToken) < m_pModules->CountFiles()) || FileToken == AssemblyID); ASSERT(dwScope == 0 || TypeFromToken(FileToken) == mdtAssemblyRef); // Initialize to empty values if (ppImportScope) *ppImportScope = NULL; if (pdwCountOfTypes) *pdwCountOfTypes = 0; *phEnum = (HALINKENUM)NULL; HRESULT hr = S_OK; TypeEnumerator *TypeEnum = new TypeEnumerator; if (TypeEnum == NULL) return E_OUTOFMEMORY; TypeEnum->TypeID = 0; if (TypeFromToken(FileToken) == mdtAssemblyRef) { // Import from another assembly (possibly a nested file) if (SUCCEEDED(hr = m_pImports->GetFile( FileToken, &TypeEnum->file)) && dwScope > 0) { CAssemblyFile *assembly = (CAssemblyFile*)TypeEnum->file; TypeEnum->file = NULL; hr = assembly->GetFile(dwScope - 1, &TypeEnum->file); } } else if (TypeFromToken(FileToken) == mdtModule) { hr = m_pModules->GetFile( FileToken, &TypeEnum->file); } else if (TypeFromToken(FileToken) == mdtFile){ // Import from this Assembly hr = m_pAssem->GetFile( FileToken, &TypeEnum->file); } else { TypeEnum->file = m_pAssem; hr = S_OK; } if (SUCCEEDED(hr) && SUCCEEDED(hr = TypeEnum->file->ImportFile(pdwCountOfTypes, NULL))) { if ((ppImportScope != NULL) && (*ppImportScope = TypeEnum->file->GetImportScope())) (*ppImportScope)->AddRef(); // Give a copy to them, AddRef so they can release if (pdwCountOfTypes) *pdwCountOfTypes = TypeEnum->file->CountTypes(); *phEnum = (HALINKENUM)TypeEnum; if (hr == S_OK && TypeEnum->file->CountTypes() == 0) hr = S_FALSE; } else { delete TypeEnum; } return hr; }
MethodTable *Binder::RawGetClass(BinderClassID id) { CANNOTTHROWCOMPLUSEXCEPTION(); _ASSERTE(m_pModule != NULL); _ASSERTE(id != CLASS__NIL); _ASSERTE(id <= m_cClassRIDs); TypeHandle th = m_pModule->LookupTypeDef(TokenFromRid(m_pClassRIDs[id-1], mdtTypeDef)); _ASSERTE(!th.IsNull()); _ASSERTE(th.IsUnsharedMT()); return th.AsMethodTable(); }
HRESULT CAsmLink::PreCloseAssembly(mdAssembly AssemblyID) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1)); m_bPreClosed = true; m_bManifestEmitted = false; // Emit the Manifest, all the cached CAs, and the hashes of files HRESULT hr = m_pAssem->EmitAssembly(m_pDisp); m_pAssem->PreClose(); return hr; }
HRESULT CAsmLink::ExportNestedType(mdAssembly AssemblyID, mdToken FileToken, mdTypeDef TypeToken, mdExportedType ParentType, LPCWSTR pszTypename, DWORD dwFlags, mdExportedType* pType) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT(AssemblyID == FileToken || (RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile)); ASSERT(IsTdNested(dwFlags)); if (AssemblyID == AssemblyIsUBM || FileToken == AssemblyID) return S_FALSE; return m_pAssem->AddExportType( ParentType, TypeToken, pszTypename, dwFlags, pType); }
//***************************************************************************** // cascading Mark of all securities associated with a token //***************************************************************************** HRESULT FilterManager::MarkDeclSecuritiesWithParentToken(mdToken tkParent) { HRESULT hr = NOERROR; RID ridStart, ridEnd; RID index; DeclSecurityRec *pRec; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); if ( m_pMiniMd->IsSorted( TBL_DeclSecurity ) ) { // table is sorted. ridStart to ridEnd - 1 are all DeclSecurity // associated with tkParent // IfFailGo(m_pMiniMd->getDeclSecurityForToken(tkParent, &ridEnd, &ridStart)); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo( m_pMiniMd->GetFilterTable()->MarkDeclSecurity( TokenFromRid(index, mdtPermission) ) ); } } else { // table scan is needed ridStart = 1; ridEnd = m_pMiniMd->getCountDeclSecuritys() + 1; for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(m_pMiniMd->GetDeclSecurityRecord(index, &pRec)); if ( tkParent == m_pMiniMd->getParentOfDeclSecurity(pRec) ) { // This DeclSecurity is associated with tkParent IfFailGo( m_pMiniMd->GetFilterTable()->MarkDeclSecurity( TokenFromRid(index, mdtPermission) ) ); } } } ErrExit: return hr; } // HRESULT FilterManager::MarkDeclSecuritiesWithParentToken()
//***************************************************************************** // call stgdb InitNew //***************************************************************************** __checkReturn HRESULT RegMeta::CreateNewMD() { HRESULT hr = NOERROR; m_OpenFlags = ofWrite; // Allocate our m_pStgdb. _ASSERTE(m_pStgdb == NULL); IfNullGo(m_pStgdb = new (nothrow) CLiteWeightStgdbRW); // Initialize the new, empty database. // First tell the new database what sort of metadata to create m_pStgdb->m_MiniMd.m_OptionValue.m_MetadataVersion = m_OptionValue.m_MetadataVersion; m_pStgdb->m_MiniMd.m_OptionValue.m_InitialSize = m_OptionValue.m_InitialSize; IfFailGo(m_pStgdb->InitNew()); // Set up the Module record. ULONG iRecord; ModuleRec *pModule; GUID mvid; IfFailGo(m_pStgdb->m_MiniMd.AddModuleRecord(&pModule, &iRecord)); IfFailGo(CoCreateGuid(&mvid)); IfFailGo(m_pStgdb->m_MiniMd.PutGuid(TBL_Module, ModuleRec::COL_Mvid, pModule, mvid)); // Add the dummy module typedef which we are using to parent global items. TypeDefRec *pRecord; IfFailGo(m_pStgdb->m_MiniMd.AddTypeDefRecord(&pRecord, &iRecord)); m_tdModule = TokenFromRid(iRecord, mdtTypeDef); IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_TypeDef, TypeDefRec::COL_Name, pRecord, COR_WMODULE_CLASS)); IfFailGo(m_pStgdb->m_MiniMd.SetOption(&m_OptionValue)); if (IsThreadSafetyOn()) { m_pSemReadWrite = new (nothrow) UTSemReadWrite(); IfNullGo(m_pSemReadWrite); IfFailGo(m_pSemReadWrite->Init()); m_fOwnSem = true; INDEBUG(m_pStgdb->m_MiniMd.Debug_SetLock(m_pSemReadWrite);) } #ifdef FEATURE_METADATA_EMIT_ALL // initialize the embedded merger m_newMerger.Init(this); #endif //FEATURE_METADATA_EMIT_ALL ErrExit: return hr; } // RegMeta::CreateNewMD
//***************************************************************************** // cascading Mark of an TypeDef token //***************************************************************************** HRESULT FilterManager::MarkInterfaceImpls( mdTypeDef td) { HRESULT hr = NOERROR; ULONG ridStart, ridEnd; ULONG i; InterfaceImplRec *pRec; // We know that the filter table is not null here. Tell PREFIX that we know it. PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); if ( m_pMiniMd->IsSorted(TBL_InterfaceImpl) ) { IfFailGo(m_pMiniMd->getInterfaceImplsForTypeDef(RidFromToken(td), &ridEnd, &ridStart)); } else { ridStart = 1; ridEnd = m_pMiniMd->getCountInterfaceImpls() + 1; } // Search for the interfaceimpl with the parent of td for (i = ridStart; i < ridEnd; i++) { IfFailGo(m_pMiniMd->GetInterfaceImplRecord(i, &pRec)); if ( td != m_pMiniMd->getClassOfInterfaceImpl(pRec) ) continue; // found an InterfaceImpl associate with td. Mark the interface row and the interfaceimpl type IfFailGo( m_pMiniMd->GetFilterTable()->MarkInterfaceImpl(TokenFromRid(i, mdtInterfaceImpl)) ); IfFailGo( MarkCustomAttributesWithParentToken(TokenFromRid(i, mdtInterfaceImpl)) ); // IfFailGo( MarkDeclSecuritiesWithParentToken(TokenFromRid(i, mdtInterfaceImpl)) ); IfFailGo( Mark(m_pMiniMd->getInterfaceOfInterfaceImpl(pRec)) ); } ErrExit: return hr; } // HRESULT FilterManager::MarkInterfaceImpls()
//***************************************************************************** // cascading Mark of all of the custom values associated with a token //***************************************************************************** HRESULT FilterManager::MarkCustomAttributesWithParentToken(mdToken tkParent) { HRESULT hr = NOERROR; RID ridStart, ridEnd; RID index; CustomAttributeRec *pRec; if ( m_pMiniMd->IsSorted( TBL_CustomAttribute ) ) { // table is sorted. ridStart to ridEnd - 1 are all CustomAttribute // associated with tkParent // IfFailGo(m_pMiniMd->getCustomAttributeForToken(tkParent, &ridEnd, &ridStart)); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo( MarkCustomAttribute( TokenFromRid(index, mdtCustomAttribute) ) ); } } else { // table scan is needed ridStart = 1; ridEnd = m_pMiniMd->getCountCustomAttributes() + 1; for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(m_pMiniMd->GetCustomAttributeRecord(index, &pRec)); if ( tkParent == m_pMiniMd->getParentOfCustomAttribute(pRec) ) { // This CustomAttribute is associated with tkParent IfFailGo( MarkCustomAttribute( TokenFromRid(index, mdtCustomAttribute) ) ); } } } ErrExit: return hr; } // HRESULT FilterManager::MarkCustomAttributesWithParentToken()
HRESULT CAsmLink::ExportType(mdAssembly AssemblyID, mdToken FileToken, mdTypeDef TypeToken, LPCWSTR pszTypename, DWORD dwFlags, mdExportedType* pType) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT(AssemblyID == FileToken || (RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile)); if (AssemblyID == AssemblyIsUBM || FileToken == AssemblyID) return S_FALSE; HRESULT hr; CFile *file = NULL; if (FAILED(hr = m_pAssem->GetFile(RidFromToken(FileToken), &file))) return hr; return m_pAssem->AddExportType( file->GetFileToken(), TypeToken, pszTypename, dwFlags, pType); }
HRESULT CAsmLink::EmbedResource(mdAssembly AssemblyID, mdToken FileToken, LPCWSTR pszResourceName, DWORD dwOffset, DWORD dwFlags) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile) || (FileToken == AssemblyID)); HRESULT hr = S_OK; CFile *file = NULL; if (AssemblyID == AssemblyIsUBM) { if (SUCCEEDED(hr = m_pAssem->GetFile(FileToken, &file))) hr = file->AddResource(mdTokenNil, pszResourceName, dwOffset, dwFlags); } else if (FileToken == AssemblyID) { hr = m_pAssem->AddResource(mdTokenNil, pszResourceName, dwOffset, dwFlags); } else { if (SUCCEEDED(hr = m_pAssem->GetFile(FileToken, &file))) hr = m_pAssem->AddResource(file->GetFileToken(), pszResourceName, dwOffset, dwFlags); } return hr; }
//***************************************************************************** // cascading Mark of all fields associated with a TypeDef token //***************************************************************************** HRESULT FilterManager::MarkFieldsWithParentToken(mdTypeDef td) { HRESULT hr = NOERROR; RID ulStart, ulEnd; RID index; TypeDefRec *pTypeDefRec; IfFailGo(m_pMiniMd->GetTypeDefRecord(RidFromToken(td), &pTypeDefRec)); ulStart = m_pMiniMd->getFieldListOfTypeDef( pTypeDefRec ); IfFailGo(m_pMiniMd->getEndFieldListOfTypeDef(RidFromToken(td), &ulEnd)); for ( index = ulStart; index < ulEnd; index ++ ) { RID rid; IfFailGo(m_pMiniMd->GetFieldRid(index, &rid)); IfFailGo(MarkField(TokenFromRid( rid, mdtFieldDef))); } ErrExit: return hr; } // HRESULT FilterManager::MarkFieldsWithParentToken()
//***************************************************************************** // cascading Mark of all GenericPar associated with a TypeDef or MethodDef token //***************************************************************************** HRESULT FilterManager::MarkGenericParamWithParentToken( mdToken tk) { HRESULT hr = NOERROR; RID ulStart, ulEnd; RID index; GenericParamRec *pGenericParamRec; mdToken constraint; HENUMInternal hEnum; // To enumerate constraints. // Enumerate the GenericPar //@todo: Handle the unsorted case. IfFailGo( m_pMiniMd->GetGenericParamsForToken(tk, &ulStart, &ulEnd) ); for (; ulStart < ulEnd; ++ulStart) { index = m_pMiniMd->GetGenericParamRid(ulStart); IfFailGo(m_pMiniMd->GetGenericParamRecord(index, &pGenericParamRec)); RID ridConstraint; IfFailGo( m_pMiniMd->FindGenericParamConstraintHelper(TokenFromRid(ulStart, mdtGenericParam), &hEnum) ); while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &ridConstraint)) { // Get the constraint. GenericParamConstraintRec *pRec; IfFailGo(m_pMiniMd->GetGenericParamConstraintRecord(RidFromToken(ridConstraint), &pRec)); constraint = m_pMiniMd->getConstraintOfGenericParamConstraint(pRec); // Mark it. IfFailGo( Mark(constraint) ); } HENUMInternal::ClearEnum(&hEnum); } ErrExit: HENUMInternal::ClearEnum(&hEnum); return hr; } // HRESULT FilterManager::MarkGenericParamWithParentToken()
//***************************************************************************** // cascading Mark of all MemberRefs associated with a parent token //***************************************************************************** HRESULT FilterManager::MarkMemberRefsWithParentToken(mdToken tk) { HRESULT hr = NOERROR; RID ulEnd; RID index; mdToken tkParent; MemberRefRec *pRec; ulEnd = m_pMiniMd->getCountMemberRefs(); for (index = 1; index <= ulEnd; index ++ ) { // memberRef table is not sorted. Table scan is needed. IfFailGo(m_pMiniMd->GetMemberRefRecord(index, &pRec)); tkParent = m_pMiniMd->getClassOfMemberRef(pRec); if ( tk == tkParent ) { IfFailGo( MarkMemberRef( TokenFromRid(index, mdtMemberRef) ) ); } } ErrExit: return hr; } // HRESULT FilterManager::MarkMemberRefsWithParentToken()
//***************************************************************************** // cascading Mark of all ParamDef associated with a methoddef //***************************************************************************** HRESULT FilterManager::MarkParamsWithParentToken(mdMethodDef md) { HRESULT hr = NOERROR; RID ulStart, ulEnd; RID index; MethodRec *pMethodRec; IfFailGo(m_pMiniMd->GetMethodRecord(RidFromToken(md), &pMethodRec)); // figure out the start rid and end rid of the parameter list of this methoddef ulStart = m_pMiniMd->getParamListOfMethod(pMethodRec); IfFailGo(m_pMiniMd->getEndParamListOfMethod(RidFromToken(md), &ulEnd)); for (index = ulStart; index < ulEnd; index ++ ) { RID rid; IfFailGo(m_pMiniMd->GetParamRid(index, &rid)); IfFailGo(MarkParam(TokenFromRid( rid, mdtParamDef))); } ErrExit: return hr; } // HRESULT FilterManager::MarkParamsWithParentToken()
HRESULT CAsmLink::GetScope(mdAssembly AssemblyID, mdToken FileToken, DWORD dwScope, IMetaDataImport** ppImportScope) { ASSERT(m_bInited && !m_bPreClosed); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((TypeFromToken(FileToken) == mdtFile && RidFromToken(FileToken) < m_pAssem->CountFiles()) || (TypeFromToken(FileToken) == mdtAssemblyRef && RidFromToken(FileToken) < m_pImports->CountFiles()) || (TypeFromToken(FileToken) == mdtModule && RidFromToken(FileToken) < m_pModules->CountFiles())); ASSERT(dwScope == 0 || TypeFromToken(FileToken) == mdtAssemblyRef); // Initialize to empty values *ppImportScope = NULL; HRESULT hr = S_OK; CFile* file = NULL; if (TypeFromToken(FileToken) == mdtAssemblyRef) { // Import from another assembly (possibly a nested file) if (SUCCEEDED(hr = m_pImports->GetFile( FileToken, &file)) && dwScope > 0) { CAssemblyFile *assembly = (CAssemblyFile*)file; file = NULL; hr = assembly->GetFile(dwScope - 1, &file); } } else if (TypeFromToken(FileToken) == mdtModule) { hr = m_pModules->GetFile( FileToken, &file); } else { // Import from this Assembly // NOTE: we don't allow importing from the manifest file! ASSERT( TypeFromToken(FileToken) == mdtFile); hr = m_pAssem->GetFile( FileToken, &file); } if (SUCCEEDED(hr)) { if ((*ppImportScope = file->GetImportScope())) (*ppImportScope)->AddRef(); // Give a copy to them, AddRef so they can release } return hr; }
void AsmMan::AddFile(__in __nullterminated char* szName, DWORD dwAttr, BinStr* pHashBlob) { AsmManFile* tmp = GetFileByName(szName); Assembler* pAsm = (Assembler*)m_pAssembler; if(tmp==NULL) { tmp = new AsmManFile; if(tmp==NULL) { pAsm->report->error("\nOut of memory!\n"); return; } memset(tmp,0,sizeof(AsmManFile)); if((dwAttr & 0x80000000)!=0) pAsm->m_fEntryPointPresent = TRUE; tmp->szName = szName; tmp->dwAttr = dwAttr; tmp->pHash = pHashBlob; tmp->m_fNew = TRUE; m_FileLst.PUSH(tmp); tmp->tkTok = TokenFromRid(m_FileLst.COUNT(),mdtFile); } pAsm->m_tkCurrentCVOwner = 0; if(tmp) pAsm->m_pCustomDescrList = &(tmp->m_CustomDescrList); }