Esempio n. 1
0
        private static AssemblyInfo ReadAssemblyRef(PEFileReader peFile, MetadataToken assemblyRef)
        {
            System.Diagnostics.Contracts.Contract.Requires(peFile != null);
            System.Diagnostics.Contracts.Contract.Requires(assemblyRef.Table == MDTables.Tables.AssemblyRef);
            MDTables     metaData = peFile.MetaData;
            BinaryReader B        = metaData.B;

            metaData.SeekToMDToken(assemblyRef);
            UInt16  major         = B.ReadUInt16();
            UInt16  minor         = B.ReadUInt16();
            UInt16  build         = B.ReadUInt16();
            UInt16  revision      = B.ReadUInt16();
            Version v             = new Version(major, minor, build, revision);
            UInt32  assemblyFlags = B.ReadUInt32();

            byte[] publicKey  = metaData.ReadBlob();
            String simpleName = metaData.ReadString();
            String culture    = metaData.ReadString();

            if ((culture != null) && (culture.Length == 0))
            {
                culture = null;
            }
            return(new AssemblyInfo(v, assemblyFlags, publicKey, simpleName, culture));
        }
Esempio n. 2
0
        public MiniModule[] GetModules()
        {
            // There are two forms of "multiple module" assemblies.  The first is a
            // multi-module assembly where the assembly's ModuleRef lists multiple
            // different modules.  The second is a multi-file assembly, where an
            // entry in the File metadata table refers to another file on disk and
            // explicitly declares the file contains metadata (and potentially types).
            // ALink can produce .netmodules, which seem to show up as multi-file
            // assemblies.
            MDTables metaData = _peFile.MetaData;

            for (uint i = 0; i < metaData.RowsInTable(MDTables.Tables.File); i++)
            {
                metaData.SeekToRowOfTable(MDTables.Tables.File, i);
                MDFileAttributes attrs = (MDFileAttributes)metaData.B.ReadUInt32();
                if ((attrs & MDFileAttributes.ContainsNoMetaData) != 0)
                {
                    continue;
                }
                System.Diagnostics.Contracts.Contract.Assert(attrs == MDFileAttributes.ContainsMetaData);
                throw new NotImplementedException(String.Format(CultureInfo.CurrentCulture, Res.MultiFileAssembliesNotSupported, FullName));
            }

            return(new MiniModule[] { this });
        }
Esempio n. 3
0
        // 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);
        }
Esempio n. 4
0
        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;
        }
Esempio n. 5
0
        // 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());
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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;
        }
Esempio n. 8
0
        // 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());
        }
Esempio n. 9
0
        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();
            }
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        private static MetadataToken FindTypeDef(PEFileReader peFile, MDTables mdScope, String typeName, String nameSpace)
        {
            System.Diagnostics.Contracts.Contract.Requires(typeName != null);

            uint numTypeDefs = mdScope.RowsInTable(MDTables.Tables.TypeDef);

            for (uint i = 0; i < numTypeDefs; i++)
            {
                mdScope.SeekToRowOfTable(MDTables.Tables.TypeDef, i);
                peFile.B.ReadUInt32();  // TypeAttributes
                String rowTypeName = mdScope.ReadString();
                if (!String.Equals(typeName, rowTypeName))
                {
                    continue;
                }
                String rowNameSpace = mdScope.ReadString();
                if (!String.Equals(nameSpace, rowNameSpace))
                {
                    continue;
                }
                return(new MetadataToken(MDTables.Tables.TypeDef, i + 1));
            }
            throw new TypeLoadException(String.Format(CultureInfo.CurrentCulture, Res.CantFindTypeName, nameSpace, typeName));
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        // 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);
        }
Esempio n. 14
0
        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());
        }