// See the ECMA CLI spec, Partition II, section 23.2.1. private MiniParameterInfo[] ParseSig(byte[] sig) { PEFileReader peFile = _assembly.PEFileReader; peFile.InitMetaData(); MDTables MetaData = peFile.MetaData; uint i = 0; // The first byte of the Signature holds bits for HASTHIS, EXPLICITTHIS // and calling convention (DEFAULT, VARARG, or GENERIC). These are OR'ed // together. i++; uint numParams = DecodeInteger(sig, ref i); // Skip over return type // Skip custom modifiers. do { if (sig[i] == (byte)CorElementType.CModOpt) { i++; } else if (sig[i] == (byte)CorElementType.CModReqd) { i++; } else { break; } } while (true); // Skip return type. Note that for constructors, it should be void. if (sig[i] == (byte)CorElementType.Void) { i++; } else if (sig[i] == (byte)CorElementType.TypedByRef) { i++; } else { if (sig[i] == (byte)CorElementType.ByRef) { i++; } ParseType(sig, ref i, false, true); } MiniParameterInfo[] parameters = new MiniParameterInfo[numParams]; for (uint paramNum = 0; paramNum < numParams; paramNum++) { parameters[paramNum] = ParseType(sig, ref i, false, false); //Console.WriteLine("Read a parameter: {0}", parameters[paramNum]); } return(parameters); }
// 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()); }
public bool Implements(TypeInfo ifaceType) { System.Diagnostics.Contracts.Contract.Requires(ifaceType != null); System.Diagnostics.Contracts.Contract.Assert(HasToken || HasReflectionType || HasTypeRef); if (HasReflectionType) { System.Diagnostics.Contracts.Contract.Assert(ifaceType.HasAssemblyQualifiedName); foreach (Type implementsIFace in _reflectionType.GetInterfaces()) { if (Utils.FullTypeNameDefEqualsDef(implementsIFace.AssemblyQualifiedName, ifaceType.AssemblyQualifiedName)) { return(true); } } return(false); } // This can be a typeref. ---- the other assembly to parse this. // I need to support the HAV in assembly A, the HA in B, the specific contract // interface in assembly C, and IContract in assembly D. I'm inspecting the HA, // and I'll get a typeref for C, and I need to make sure it implements IContract in D. PEFileReader peFile = _assembly.PEFileReader; peFile.InitMetaData(); MDTables thisMetaData = peFile.MetaData; if (_mdToken.Table == MDTables.Tables.TypeRef) { TypeInfo def = TypeRefToTypeDef(_mdToken, true); return(def.ImplementsHelper(def._assembly.PEFileReader, def._mdToken, ifaceType)); } else { System.Diagnostics.Contracts.Contract.Assert(_mdToken.Table == MDTables.Tables.TypeDef); throw new NotImplementedException(); } }
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); }
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()); }