// Return the attributes on this type of the given custom attribute type internal MiniCustomAttributeInfo[] GetCustomAttributeInfos(Type caReflectedType) { List <MiniCustomAttributeInfo> result = new List <MiniCustomAttributeInfo>(); PEFileReader peFile = _assembly.PEFileReader; peFile.InitMetaData(); MDTables metaData = peFile.MetaData; uint numRows = metaData.RowsInTable(MDTables.Tables.CustomAttribute); for (uint i = 0; i < numRows; i++) { metaData.SeekToRowOfTable(MDTables.Tables.CustomAttribute, i); // Format: Parent type token, CA type token (really the constructor method), value (index into blob heap) MetadataToken targetType = metaData.ReadMetadataToken(MDTables.Encodings.HasCustomAttribute); MetadataToken caType = metaData.ReadMetadataToken(MDTables.Encodings.CustomAttributeType); byte[] caBlob = metaData.ReadBlob(); if (targetType.Equals(this._mdToken)) { //Console.WriteLine("CA - Applied to: {0} CA .ctor: {1} Value: {2}", targetType, caType, value); //Console.WriteLine("CA MD Tokens Parent: {0} Type: {1}", targetType.ToMDToken(), caType.ToMDToken()); // Ensure the custom attribute type is the type we expect metaData.SeekToMDToken(caType); String caTypeName = null, caNameSpace = null; if (caType.Table != MDTables.Tables.MemberRef) { // Custom attribute was defined in the assembly we are currently inspecting? // Ignore it. System.Diagnostics.Contracts.Contract.Assert(caType.Table == MDTables.Tables.MethodDef); continue; } MetadataToken customAttributeType = metaData.ReadMetadataToken(MDTables.Encodings.MemberRefParent); //Console.WriteLine(" MemberRef: {0} Type of MemberRef: {1}", caType.ToMDToken(), customAttributeType.ToMDToken()); metaData.SeekToMDToken(customAttributeType); MetadataToken resolutionScope = metaData.ReadMetadataToken(MDTables.Encodings.ResolutionScope); caTypeName = metaData.ReadString(); caNameSpace = metaData.ReadString(); if (caTypeName == caReflectedType.Name && caNameSpace == caReflectedType.Namespace) { MiniCustomAttributeInfo customAttributeInfo = ParseCustomAttribute(caBlob, caReflectedType); result.Add(customAttributeInfo); } } } return(result.ToArray()); }
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; }
// Get the immediate interfaces on this type. public TypeInfo[] GetInterfaces() { List <TypeInfo> interfaces = new List <TypeInfo>(); if (HasReflectionType) { foreach (Type interfaceType in _reflectionType.GetInterfaces()) { interfaces.Add(new TypeInfo(interfaceType)); } } else if (HasTypeRef) { TypeInfo defInfo = TypeRefToTypeDef(_mdToken, true); return(defInfo.GetInterfaces()); } else { System.Diagnostics.Contracts.Contract.Assert(_mdToken.Table == MDTables.Tables.TypeDef); PEFileReader peFile = _assembly.PEFileReader; MDTables mdScope = peFile.MetaData; // Walk through all rows of the interface implementation table, // looking for this _mdToken. uint numRows = mdScope.RowsInTable(MDTables.Tables.InterfaceImpl); for (uint i = 0; i < numRows; i++) { try { mdScope.SeekToRowOfTable(MDTables.Tables.InterfaceImpl, i); uint typeDefRow = mdScope.ReadRowIndex(MDTables.Tables.TypeDef); if (typeDefRow == _mdToken.Index) { MetadataToken interfaceToken = mdScope.ReadMetadataToken(MDTables.Encodings.TypeDefOrRef); interfaces.Add(TypeInfoFromTypeDefOrRef(interfaceToken)); } } catch (GenericsNotImplementedException) // ignore interfaces such as IComparable<int> that aren't relevant to the addin model {} } } return(interfaces.ToArray()); }
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); }
public IList <TypeInfo> GetTypesWithAttributeInModule(Type customAttribute, bool includePrivate) { if (IsDisposed) { throw new ObjectDisposedException(null); } if (customAttribute == null) { throw new ArgumentNullException("customAttribute"); } System.Diagnostics.Contracts.Contract.EndContractBlock(); _peFile.InitMetaData(); MDTables MetaData = _peFile.MetaData; List <TypeInfo> types = new List <TypeInfo>(); String attributeName = customAttribute.Name; String attributeNameSpace = customAttribute.Namespace; IList <MetadataToken> genericTypeTokens = GetGenericTypes(); uint numRows = MetaData.RowsInTable(MDTables.Tables.CustomAttribute); for (uint i = 0; i < numRows; i++) { MetaData.SeekToRowOfTable(MDTables.Tables.CustomAttribute, i); // Format: Parent type token, CA type token, value (index into blob heap) MetadataToken targetType = MetaData.ReadMetadataToken(MDTables.Encodings.HasCustomAttribute); MetadataToken caType = MetaData.ReadMetadataToken(MDTables.Encodings.CustomAttributeType); //UInt32 value = MetaData.ReadBlobIndex(); //Console.WriteLine("CA - Applied to: {0} CA .ctor: {1} Value: {2}", targetType, caType, value); //Console.WriteLine("CA MD Tokens Parent: {0} Type: {1}", targetType.ToMDToken(), caType.ToMDToken()); // Ensure the custom attribute type is the type we expect MetaData.SeekToMDToken(caType); String caTypeName = null, caNameSpace = null; if (caType.Table != MDTables.Tables.MemberRef) { // Custom attribute was defined in the assembly we are currently inspecting? // Ignore it. System.Diagnostics.Contracts.Contract.Assert(caType.Table == MDTables.Tables.MethodDef); continue; } MetadataToken customAttributeType = MetaData.ReadMetadataToken(MDTables.Encodings.MemberRefParent); //Console.WriteLine(" MemberRef: {0} Type of MemberRef: {1}", caType.ToMDToken(), customAttributeType.ToMDToken()); MetaData.SeekToMDToken(customAttributeType); MetadataToken resolutionScope = MetaData.ReadMetadataToken(MDTables.Encodings.ResolutionScope); // @ caTypeName = MetaData.ReadString(); if (!String.Equals(caTypeName, attributeName)) { continue; } caNameSpace = MetaData.ReadString(); if (!String.Equals(caNameSpace, attributeNameSpace)) { continue; } // Get type name & namespace. switch (targetType.Table) { case MDTables.Tables.TypeDef: MetaData.SeekToMDToken(targetType); System.Reflection.TypeAttributes flags = (System.Reflection.TypeAttributes)_peFile.B.ReadUInt32(); System.Reflection.TypeAttributes vis = flags & System.Reflection.TypeAttributes.VisibilityMask; bool isPublic = vis == System.Reflection.TypeAttributes.Public; // NestedPublic not supported if (!includePrivate && !isPublic) { continue; } String typeName = MetaData.ReadString(); String nameSpace = MetaData.ReadString(); bool isGeneric = genericTypeTokens.Contains(targetType); TypeInfo type = new TypeInfo(targetType, _assembly, this, typeName, nameSpace, isGeneric); types.Add(type); break; default: throw new NotImplementedException(String.Format(CultureInfo.CurrentCulture, Res.UnknownTokenType, targetType.Table, Assembly.FullName)); } } return(types); }
// 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); }
public MiniConstructorInfo[] GetConstructors(bool includePrivate) { System.Diagnostics.Contracts.Contract.Assert(HasToken /* || HasReflectionType*/, "GetConstructors needs a token (or you should uncomment the support for Reflection types)"); List <MiniConstructorInfo> ctors = new List <MiniConstructorInfo>(); /* * if (HasReflectionType) { * System.Reflection.BindingFlags visibility = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public; * if (includePrivate) * visibility |= System.Reflection.BindingFlags.NonPublic; * foreach (System.Reflection.ConstructorInfo ctor in _reflectionType.GetConstructors(visibility)) * ctors.Add(new MiniConstructorInfo(ctor)); * return ctors.ToArray(); * } */ System.Diagnostics.Contracts.Contract.Assert(_mdToken.Table == MDTables.Tables.TypeDef); PEFileReader peFile = _assembly.PEFileReader; peFile.InitMetaData(); MDTables MetaData = peFile.MetaData; MetaData.SeekToMDToken(_mdToken); System.Reflection.TypeAttributes flags = (System.Reflection.TypeAttributes)peFile.B.ReadUInt32(); System.Reflection.TypeAttributes vis = System.Reflection.TypeAttributes.VisibilityMask & flags; bool isPublic = (vis == System.Reflection.TypeAttributes.Public); // don't support NestedPublic if (!includePrivate && !isPublic) { return(new MiniConstructorInfo[0]); } MetaData.ReadStringIndex(); // typename MetaData.ReadStringIndex(); // namespace MetadataToken baseClass = MetaData.ReadMetadataToken(MDTables.Encodings.TypeDefOrRef); // Base class uint firstMemberIndex = MetaData.ReadRowIndex(MDTables.Tables.FieldDef); // Field list uint firstMethodIndex = MetaData.ReadRowIndex(MDTables.Tables.MethodDef); // Method list uint lastMethodIndex; // If this is the last entry in the TypeDef table, then all the rest of the methods in the MethodDef // table belong to this type. Otherwise, look for the methods belonging to the next type. if (_mdToken.Index == MetaData.RowsInTable(MDTables.Tables.TypeDef)) { lastMethodIndex = MetaData.RowsInTable(MDTables.Tables.MethodDef); } else { MetaData.SeekToRowOfTable(MDTables.Tables.TypeDef, _mdToken.Index); // Seek to next type (not off by 1!) peFile.B.ReadUInt32(); // Flags MetaData.ReadStringIndex(); // type name MetaData.ReadStringIndex(); // namespace MetaData.ReadMetadataToken(MDTables.Encodings.TypeDefOrRef); // Next type's base class MetaData.ReadRowIndex(MDTables.Tables.FieldDef); // field list; uint firstMethodOfNextType = MetaData.ReadRowIndex(MDTables.Tables.MethodDef); // method list lastMethodIndex = firstMethodOfNextType - 1; } // Now walk through list of methods, looking for ones w/ the name ".ctor". for (uint i = firstMethodIndex; i <= lastMethodIndex; i++) { MetadataToken method = new MetadataToken(MDTables.Tables.MethodDef, i); MetaData.SeekToMDToken(method); UInt32 rva = peFile.B.ReadUInt32(); UInt16 implFlags = peFile.B.ReadUInt16(); // MethodImplAttributes System.Reflection.MethodAttributes attrs = (System.Reflection.MethodAttributes)peFile.B.ReadUInt16(); // Flags - MethodAttributes // Visibility check if (!includePrivate && (attrs & System.Reflection.MethodAttributes.Public) == 0) { continue; } String methodName = MetaData.ReadString(); // Name // @ if (!String.Equals(methodName, ".ctor")) { continue; } byte[] sig = MetaData.ReadBlob(); try { MiniParameterInfo[] parameters = ParseSig(sig); ctors.Add(new MiniConstructorInfo(parameters)); } catch (GenericsNotImplementedException) { // may be caused by a Generic contract. The user will be warned elsewhere that generic contracts are not supported. /* * if (Warnings != null) { * lock (Warnings) { * Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.UnparsibleConstructorSignature, this.Name, e.GetType().Name, e.Message)); * } * } */ } } // for each .ctor return(ctors.ToArray()); }