// See the comments in Equals - we're doing string comparisons here // to compare full type names. public static bool Equals(MiniAssembly assemblyA, PEFileReader peFileB, MetadataToken assemblyRefB) { System.Diagnostics.Contracts.Contract.Requires(assemblyA != null); System.Diagnostics.Contracts.Contract.Requires(peFileB != null); System.Diagnostics.Contracts.Contract.Requires(assemblyRefB.Table == MDTables.Tables.AssemblyRef); String nameA, nameRefB; if (assemblyA.IsReflectionAssembly) { nameA = AppDomain.CurrentDomain.ApplyPolicy(assemblyA._reflectionAssembly.FullName); } else { AssemblyInfo assemblyInfoA = new AssemblyInfo(); assemblyA._peFile.GetAssemblyInfo(ref assemblyInfoA); nameA = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfoA.ToString()); } AssemblyInfo assemblyInfoB = ReadAssemblyRef(peFileB, assemblyRefB); nameRefB = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfoB.ToString()); return(Utils.AssemblyRefEqualsDef(nameRefB, nameA)); }
internal TypeInfo(MetadataToken typeRefToken, MiniAssembly referencingAssembly, bool disambiguatingJunkForTypeRefOverload) { System.Diagnostics.Contracts.Contract.Requires(referencingAssembly != null); System.Diagnostics.Contracts.Contract.Requires(typeRefToken.Table == MDTables.Tables.TypeRef); _mdToken = typeRefToken; _assembly = referencingAssembly; _representation = Representation.TypeRef | Representation.Name; PEFileReader peFile = referencingAssembly.PEFileReader; MDTables MetaData = peFile.MetaData; MetaData.SeekToMDToken(typeRefToken); MetadataToken assemblyRef = MetaData.ReadMetadataToken(MDTables.Encodings.ResolutionScope); _typeName = MetaData.ReadString(); _nameSpace = MetaData.ReadString(); // Read assembly information MetaData.SeekToMDToken(assemblyRef); UInt16 major = peFile.B.ReadUInt16(); UInt16 minor = peFile.B.ReadUInt16(); UInt16 build = peFile.B.ReadUInt16(); UInt16 revision = peFile.B.ReadUInt16(); peFile.B.ReadUInt32(); // assembly flags byte[] publicKeyOrToken = MetaData.ReadBlob(); String simpleName = MetaData.ReadString(); String culture = MetaData.ReadString(); // assert so we can get the AssemblyName of mscorlib.dll FileIOPermission permission = new FileIOPermission(PermissionState.None); permission.AllLocalFiles = FileIOPermissionAccess.PathDiscovery; permission.Assert(); System.Reflection.Assembly mscorlib = typeof(Object).Assembly; if (simpleName == "mscorlib" && (culture.Length == 0) && Utils.PublicKeyMatches(mscorlib.GetName(), publicKeyOrToken)) { // Upgrade to using a Type! Type t = mscorlib.GetType(FullName, false); if (t != null) { _reflectionType = t; _representation |= Representation.ReflectionType; } } String typeRefDefiningAssemblyName = String.Format(CultureInfo.InvariantCulture, "{0}, Version={1}.{2}.{3}.{4}, Culture={5}, PublicKeyToken={6}", simpleName, major, minor, build, revision, (culture.Length == 0 ? "neutral" : culture), Utils.PublicKeyToString(publicKeyOrToken)); _assemblyQualifiedName = FullName + ", " + typeRefDefiningAssemblyName; _representation |= Representation.AssemblyQualifiedName; }
internal TypeInfo(SerializationInfo info, StreamingContext context) { _assembly = (MiniAssembly)info.GetValue(AssemblyFieldName, typeof(MiniAssembly)); _module = (MiniModule)info.GetValue(ModuleFieldName, typeof(MiniModule)); _mdToken = (MetadataToken)info.GetValue(MDTokenFieldName, typeof(MetadataToken)); _typeName = info.GetString(TypeNameFieldName); _nameSpace = info.GetString(NameSpaceFieldName); _assemblyQualifiedName = info.GetString(AssemblyQualifiedFieldName); _representation = (Representation)info.GetInt32(RepresentationFieldName); System.Diagnostics.Contracts.Contract.Assert((_representation & Representation.ReflectionType) == 0); _isGeneric = info.GetBoolean(IsGenericFieldName); }
internal TypeInfo(MetadataToken typeDef, MiniAssembly assembly, String typeName, String nameSpace) { System.Diagnostics.Contracts.Contract.Requires(assembly != null); System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(typeName)); System.Diagnostics.Contracts.Contract.Requires(typeDef.Table == MDTables.Tables.TypeDef); _mdToken = typeDef; _assembly = assembly; _typeName = typeName; _nameSpace = nameSpace; _assemblyQualifiedName = FullTypeName + ", " + assembly.FullName; _representation = Representation.Token | Representation.Name | Representation.AssemblyQualifiedName; }
public MiniAssembly ResolveAssemblyRef(MetadataToken token, bool throwOnError) { System.Diagnostics.Contracts.Contract.Requires(token.Table == MDTables.Tables.AssemblyRef); PEFileReader peFile = this.PEFileReader; MDTables metaData = peFile.MetaData; metaData.SeekToMDToken(token); peFile.B.ReadUInt64(); // Skip 4 parts of the version number. peFile.B.ReadUInt32(); // AssemblyFlags byte[] publicKeyOrToken = metaData.ReadBlob(); // Public key or token String assemblySimpleName = metaData.ReadString(); // simple name String cultureName = metaData.ReadString(); // assembly culture if (!String.IsNullOrEmpty(cultureName)) { throw new BadImageFormatException(Res.UnexpectedlyLoadingASatellite, FullName); } if (assemblySimpleName == "mscorlib" && (cultureName.Length == 0 || cultureName == "neutral")) { return(new MiniAssembly(typeof(Object).Assembly)); } MiniAssembly loadedAssembly = Open(assemblySimpleName, _dependencyDirs, throwOnError); if (loadedAssembly != null) { // Check whether the reference to the assembly matches what we actually loaded. // We don't respect the "throwOnError" parameter here because if someone does // violate this, they've either severely messed up their deployment, or they're // attempting a security exploit. System.Reflection.AssemblyName loadedAssemblyName = new System.Reflection.AssemblyName(loadedAssembly.FullName); if (!Utils.PublicKeyMatches(loadedAssemblyName, publicKeyOrToken)) { throw new FileLoadException(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadRefDefMismatch, assemblySimpleName, publicKeyOrToken, loadedAssemblyName.GetPublicKeyToken())); } if (!String.IsNullOrEmpty(loadedAssemblyName.CultureInfo.Name)) { throw new FileLoadException(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadRefDefMismatch, assemblySimpleName, String.Empty, loadedAssemblyName.CultureInfo.Name)); } } return(loadedAssembly); }
internal TypeInfo(MetadataToken typeDef, MiniAssembly assembly) { System.Diagnostics.Contracts.Contract.Requires(assembly != null); System.Diagnostics.Contracts.Contract.Requires(typeDef.Table == MDTables.Tables.TypeDef); _mdToken = typeDef; _assembly = assembly; _representation = Representation.Token; PEFileReader peFile = _assembly.PEFileReader; MDTables mdScope = peFile.MetaData; mdScope.SeekToMDToken(_mdToken); peFile.B.ReadUInt32(); // TypeAttributes; _typeName = mdScope.ReadString(); // this type's name _nameSpace = mdScope.ReadString(); // this type's namespace _representation |= Representation.Name; }
public override bool Equals(object obj) { MiniAssembly thatAssembly = obj as MiniAssembly; if (thatAssembly == null) { return(false); } // Note that assembly binding redirects and publisher policy will affect // versioning (ie binds to 2.0.0.0 redirected to 2.0.1.5). But for // the Orcas release, we're only planning on using our existing // directory structure, which does not have a great servicing story. // As long as we use ReflectionOnlyLoad during discovery, we should // be fetching the exact assembly on disk used to build the entire // pipeline (modulo in-place updates which must keep the same // assembly version number), and we'll load the right version // during activation time. That should work for Orcas. // Long term, we may need an approximately-equals method that gets // the assembly info and compares the version number w.r.t. policy. return(Utils.AssemblyDefEqualsDef(FullName, thatAssembly.FullName)); }
internal TypeInfo TypeRefToTypeDef(MetadataToken typeRef, bool throwOnError) { System.Diagnostics.Contracts.Contract.Requires(typeRef.Table == MDTables.Tables.TypeRef); PEFileReader peFile = _assembly.PEFileReader; peFile.InitMetaData(); MDTables thisMetaData = peFile.MetaData; thisMetaData.SeekToMDToken(_mdToken); MetadataToken resolutionScope = thisMetaData.ReadMetadataToken(MDTables.Encodings.ResolutionScope); String refTypeName = thisMetaData.ReadString(); // Name String refNamespace = thisMetaData.ReadString(); // Namespace System.Diagnostics.Contracts.Contract.Assert(resolutionScope.Table == MDTables.Tables.AssemblyRef); MiniAssembly definingAssembly = _assembly.ResolveAssemblyRef(resolutionScope, throwOnError); if (definingAssembly != null) { return(definingAssembly.FindTypeInfo(refTypeName, refNamespace)); } return(null); }
// See the comments in Equals - we're doing string comparisons here // to compare full type names. public static bool Equals(MiniAssembly assemblyA, PEFileReader peFileB, MetadataToken assemblyRefB) { System.Diagnostics.Contracts.Contract.Requires(assemblyA != null); System.Diagnostics.Contracts.Contract.Requires(peFileB != null); System.Diagnostics.Contracts.Contract.Requires(assemblyRefB.Table == MDTables.Tables.AssemblyRef); String nameA, nameRefB; if (assemblyA.IsReflectionAssembly) nameA = AppDomain.CurrentDomain.ApplyPolicy(assemblyA._reflectionAssembly.FullName); else { AssemblyInfo assemblyInfoA = new AssemblyInfo(); assemblyA._peFile.GetAssemblyInfo(ref assemblyInfoA); nameA = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfoA.ToString()); } AssemblyInfo assemblyInfoB = ReadAssemblyRef(peFileB, assemblyRefB); nameRefB = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfoB.ToString()); return Utils.AssemblyRefEqualsDef(nameRefB, nameA); }
// Does a given typedef in the specified PE file implement the specified interface? private bool ImplementsHelper(PEFileReader peFile, MetadataToken typeDefToken, TypeInfo ifaceType) { System.Diagnostics.Contracts.Contract.Requires(typeDefToken.Table == MDTables.Tables.TypeDef); MDTables mdScope = peFile.MetaData; // Walk through all rules of the interface implementation table, // looking for this typeDefToken. If we find it, check to see if // that row says this type implements the specified interface. // If not, continue walking the interface impl table. uint numRows = mdScope.RowsInTable(MDTables.Tables.InterfaceImpl); for (uint i = 0; i < numRows; i++) { mdScope.SeekToRowOfTable(MDTables.Tables.InterfaceImpl, i); uint typeDefRow = mdScope.ReadRowIndex(MDTables.Tables.TypeDef); if (typeDefRow == typeDefToken.Index) { // if we implement it, return true. Else continue. MetadataToken interfaceToken = mdScope.ReadMetadataToken(MDTables.Encodings.TypeDefOrRef); if (ifaceType.HasName) { mdScope.SeekToMDToken(interfaceToken); // Interface for IContract should be a typeref. switch (interfaceToken.Table) { case MDTables.Tables.TypeRef: { MetadataToken resolutionScope = mdScope.ReadMetadataToken(MDTables.Encodings.ResolutionScope); String ifaceName = mdScope.ReadString(); if (!String.Equals(ifaceName, ifaceType._typeName)) { continue; } String ifaceNameSpace = mdScope.ReadString(); if (!String.Equals(ifaceNameSpace, ifaceType._nameSpace)) { continue; } if (MiniAssembly.Equals(ifaceType.Assembly, peFile, resolutionScope)) { return(true); } break; } case MDTables.Tables.TypeDef: { // This type implements an interface defined in the same assembly. // This isn't really interesting for the add-in model, based on what // we've currently designed and our limited use of this class. mdScope.B.ReadUInt32(); // TypeAttributes String ifaceName = mdScope.ReadString(); if (!String.Equals(ifaceName, ifaceType._typeName)) { continue; } String ifaceNameSpace = mdScope.ReadString(); if (!String.Equals(ifaceNameSpace, ifaceType._nameSpace)) { continue; } if (this._assembly.Equals(ifaceType._assembly)) { return(true); } break; } case MDTables.Tables.TypeSpec: // Since we're only looking for IContract, which is non-generic, // we should ignore this row and move on. System.Diagnostics.Contracts.Contract.Assert(false, "Checking whether a type implements a TypeSpec is NYI (generic interface?)"); break; default: System.Diagnostics.Contracts.Contract.Assert(false, "Support for this interface type is NYI"); throw new NotImplementedException(String.Format(CultureInfo.CurrentCulture, Res.UnsupportedInterfaceType, interfaceToken.Table)); } } else { throw new NotImplementedException(); } } } return(false); }