/// <summary> /// Registers metadata token to TypeRef table from metadata scope A to metadata scope B. /// </summary> /// <param name="token">Token in metadata scope A.</param> /// <returns>Token in metadata scope B.</returns> private MetadataToken registerTypeRef(MetadataToken token) { string name; uint scope,newToken; NewImporter.GetTypeRefProps(token.ToUInt32(),out name,out scope); MetadataToken assmToken = TranslateToken(new MetadataToken(scope)); OldEmitter.CorMetaDataEmit.DefineTypeRefByName(assmToken.ToUInt32(),name,out newToken); return new MetadataToken(newToken); }
/// <summary> /// Registers metadata token to TypeSpec table from metadata scope A to metadata scope B. /// </summary> /// <param name="token">Token in metadata scope A.</param> /// <returns>Token in metadata scope B.</returns> private MetadataToken registerTypeSpec(MetadataToken token) { uint nToken; byte[] signature = NewImporter.GetTypeSpec(token.ToUInt32()); Signature sig = new Signature(signature); sig.Migrate(this); signature = sig.Compress(); OldEmitter.CorMetaDataEmit.GetTokenFromTypeSpec(signature,(uint)signature.Length,out nToken); return new MetadataToken(nToken); }
/// <summary> /// Registers metadata token to MemberRef table from metadata scope A to metadata scope B. /// </summary> /// <param name="token">Token in metadata scope A.</param> /// <returns>Token in metadata scope B.</returns> private MetadataToken registerMemberRef(MetadataToken token) { string name; byte[] sig; uint ptk,nToken; NewImporter.GetMemberRefProps(token.ToUInt32(),out name,out ptk,out sig); MetadataToken scope = TranslateToken(new MetadataToken(ptk)); Signature signa = new Signature(sig); signa.Migrate(this); sig = signa.Compress(); OldEmitter.CorMetaDataEmit.DefineMemberRef(scope.ToUInt32(),name,sig,(uint)sig.Length,out nToken); return new MetadataToken(nToken); }
/// <summary> /// Registers any metadata token from tables /// (MemberRef,UserString,TypeRef,Method,TypeDef,Field,ModuleRef,AssemblyRef) /// from metadata scope A to metadata scope B. /// </summary> /// <param name="token">Token in metadata scope A.(new assembly)</param> /// <returns>Token in metadata scope B.(running assembly)</returns> public MetadataToken TranslateToken(MetadataToken cecToken) { uint token = cecToken.ToUInt32(); MetadataToken new_token; // Look in cache first if(cache.TryGetValue(token,out new_token)){ return new_token; } switch(cecToken.TokenType){ case TokenType.MemberRef: new_token = registerMemberRef(cecToken); break; case TokenType.String: { uint nToken; string str = NewImporter.GetUserString(token); OldEmitter.CorMetaDataEmit.DefineUserString(str,(uint)str.Length,out nToken); new_token = new MetadataToken(nToken); } break; case TokenType.TypeRef: new_token = registerTypeRef(cecToken); break; case TokenType.Method: { if(addedMethods.TryGetValue(token,out new_token)){ break; } string name;uint classTk;byte[] signature;uint attr;uint rva;uint flags; NewImporter.GetMethodProps(token,out name,out classTk,out attr,out signature,out rva,out flags); MetadataToken classToken = TranslateToken(new MetadataToken(classTk)); Signature sig = new Signature(signature); sig.Migrate(this); signature = sig.Compress(); new_token = new MetadataToken(OldImporter.FindMethod(classToken.ToUInt32(), name, signature)); } break; case TokenType.Field: { FieldProps fProps = NewImporter.GetFieldProps(token); uint newMClass = TranslateToken(new MetadataToken(fProps.mClass)).ToUInt32(); fProps.sigBlob = Signature.Migrate(fProps.sigBlob, this, 1); //metadata.OldEmitter.CorMetaDataEmit.DefineMemberRef(newMClass,fProps.fName,fProps.sigBlob,(uint)fProps.sigBlob.Length,out new_token); uint nCorToken = OldImporter.FindField(newMClass, fProps.fName, fProps.sigBlob); if (nCorToken == 0) { OldEmitter.CorMetaDataEmit.DefineField(newMClass,fProps.fName,fProps.pdwAttr,fProps.sigBlob,(uint)fProps.sigBlob.Length,fProps.pdwCPlusTypeFlag,fProps.ppValue,(uint)fProps.ppValue.Length,out nCorToken); } new_token = new MetadataToken(nCorToken); } break; case TokenType.TypeDef: TypeDefProps tProps = NewImporter.GetTypeDefProps(token); new_token = new MetadataToken(OldImporter.FindTypeDef(tProps.tName)); break; case TokenType.ModuleRef: { uint nToken; string name = NewImporter.GetModuleRefProps(token); OldEmitter.CorMetaDataEmit.DefineModuleRef(name,out nToken); new_token = new MetadataToken(nToken); } break; case TokenType.AssemblyRef: { int index = manager.ResourceManager.NewAssembly.Modules[0].AssemblyReferences.FindIndex(delegate(AssemblyNameReference asmRef){ return (asmRef.MetadataToken.ToUInt32() == token); }); string scopeName = manager.ResourceManager.NewAssembly.Modules[0].AssemblyReferences[index].FullName; index = manager.ResourceManager.OldAssembly.Modules[0].AssemblyReferences.FindIndex(delegate(AssemblyNameReference asmRef){ return (asmRef.FullName == scopeName); }); if(index == -1){ throw new TranslatingException("Assembly reference not found, maybe it wasn't in used in original version"); } else { new_token = manager.ResourceManager.OldAssembly.Modules[0].AssemblyReferences[index].MetadataToken; } } break; case TokenType.TypeSpec: new_token = registerTypeSpec(cecToken); break; case TokenType.MethodSpec: uint new_token_cor; MethodSpecProps props = newImporter.GetMethodSpecProps(token); props.tkParent = TranslateToken(new MetadataToken(props.tkParent)).ToUInt32(); props.signature = Signature.Migrate(props.signature,this); OldEmitter.CorMetaDataEmit.DefineMethodSpec(props.tkParent,props.signature,(uint)props.signature.Length,out new_token_cor); new_token = new MetadataToken(new_token_cor); break; case TokenType.Property: default: throw new NotImplementedException(); } // Add to cache cache.Add(token,new_token); return new_token; }
/// <summary> /// Used to be able to reference methods created in this round from code changed also in the same round. Must not be in cache, /// because it can be cleared. /// </summary> /// <param name="newToken">Token in new assembly.</param> /// <param name="registeredToken">Token in running assembly.</param> public void RegisterNewMethod(MetadataToken newToken, MetadataToken registeredToken) { addedMethods.Add(newToken.ToUInt32(),registeredToken); }
public static string GetFullMetadataTokenString(MetadataToken mt) { return UintToHexString(mt.ToUInt32(), 8); }
/// <summary> /// This method returns the member with the specified metadata token in the given module. It supports more TokenTypes than the standard Cecil method. /// </summary> /// <param name="module"></param> /// <param name="token"></param> /// <returns></returns> internal static IMetadataTokenProvider LookupTokenExtended(this ModuleDefinition module, MetadataToken token) { switch (token.TokenType) { case TokenType.TypeDef: case TokenType.TypeRef: case TokenType.MemberRef: case TokenType.Field: case TokenType.Method: case TokenType.MethodSpec: case TokenType.TypeSpec: return module.LookupToken(token); default: IMetadataTokenProvider provider; var success = _tokenProviderCache.GetValue(module, InitializeTokenProviderCache).TryGetValue(token.ToUInt32(), out provider); return success ? provider : null; } }