Пример #1
0
        /// <summary>Получить размер колонки в таблице</summary>
        /// <param name="type">Тип колонки</param>
        /// <returns>Размер колонки</returns>
        internal UInt32 SizeOfColumn(MetaColumnType type)
        {
            switch (type)
            {
            case MetaColumnType.UInt16:
                return(2);

            case MetaColumnType.UInt32:
                return(4);

            case MetaColumnType.String:
                return(this.Root.StreamTableHeader.StringIndexSize);

            case MetaColumnType.Blob:
                return(this.Root.StreamTableHeader.BlobIndexSize);

            case MetaColumnType.Guid:
                return(this.Root.StreamTableHeader.GuidIndexSize);

            default:
                if (MetaColumn.IsColumnCellPointer(type))                       //Указатель на другую таблицу
                {
                    return((UInt32)(this.Root.GetRowsCount((Cor.MetaTableType)type) < 65536 ? 2 : 4));
                }

                //CodedToken
                MetaColumnType[] referredTypes = MetaTable.GetCodedTokenTypes(type);
                UInt32           maxRows       = 0;
                foreach (MetaColumnType referredType in referredTypes)
                {
                    if (referredType != MetaColumnType.UserString)                           //but what if there is a large user string table?
                    {
                        UInt32 rows = (UInt32)this.Root.GetRowsCount((Cor.MetaTableType)referredType);
                        if (maxRows < rows)
                        {
                            maxRows = rows;
                        }
                    }
                }
                maxRows = maxRows << MetaCellCodedToken.CodedTokenBits[referredTypes.Length];
                return((UInt32)(maxRows < 65536 ? 2 : 4));
            }
        }
Пример #2
0
        /// <summary>Получить описатель таблицы</summary>
        /// <param name="table">Таблица для получения колонок</param>
        /// <exception cref="T:NotSupportedException">Unknown table</exception>
        /// <exception cref="T:InvalidOperationException">Column names not equal column types</exception>
        /// <returns>Массив колонок в таблице</returns>
        private static MetaColumn[] GetTableDescription(Cor.MetaTableType table)
        {
            MetaColumnType[] columnType;
            String[]         columnName;
            switch (table)
            {
            case Cor.MetaTableType.Module:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.String, MetaColumnType.Guid, MetaColumnType.Guid, MetaColumnType.Guid, };
                columnName = new String[] { "Generation", "Name", "Mvid", "EncId", "EncBaseId", };
                break;

            case Cor.MetaTableType.TypeRef:
                columnType = new MetaColumnType[] { MetaColumnType.ResolutionScope, MetaColumnType.String, MetaColumnType.String, };
                columnName = new String[] { "ResolutionScope", "TypeName", "TypeNamespace" };
                break;

            case Cor.MetaTableType.TypeDef:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.String, MetaColumnType.String, MetaColumnType.TypeDefOrRef, MetaColumnType.Field, MetaColumnType.MethodDef, };
                columnName = new String[] { "Flags", "TypeName", "TypeNamespace", "Extends", "FieldList", "MethodList", };
                break;

            case Cor.MetaTableType.FieldPtr:
                columnType = new MetaColumnType[] { MetaColumnType.Field, };
                columnName = new String[] { "Field" };
                break;

            case Cor.MetaTableType.Field:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.String, MetaColumnType.Blob, };
                columnName = new String[] { "Flags", "Name", "Signature", };
                break;

            case Cor.MetaTableType.MethodPtr:
                columnType = new MetaColumnType[] { MetaColumnType.MethodDef, };
                columnName = new String[] { "Method", };
                break;

            case Cor.MetaTableType.MethodDef:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.String, MetaColumnType.Blob, MetaColumnType.Param, };
                columnName = new String[] { "RVA", "ImplFlags", "Flags", "Name", "Signature", "ParamList", };
                break;

            case Cor.MetaTableType.ParamPtr:
                columnType = new MetaColumnType[] { MetaColumnType.Param, };
                columnName = new String[] { "Param", };
                break;

            case Cor.MetaTableType.Param:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.String, };
                columnName = new String[] { "Flags", "Sequence", "Name", };
                break;

            case Cor.MetaTableType.InterfaceImpl:
                columnType = new MetaColumnType[] { MetaColumnType.TypeDef, MetaColumnType.TypeDefOrRef, };
                columnName = new String[] { "Class", "Interface", };
                break;

            case Cor.MetaTableType.MemberRef:
                columnType = new MetaColumnType[] { MetaColumnType.MemberRefParent, MetaColumnType.String, MetaColumnType.Blob, };
                columnName = new String[] { "Class", "Name", "Signature", };
                break;

            case Cor.MetaTableType.Constant:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.HasConstant, MetaColumnType.Blob, };
                columnName = new String[] { "Type", "Parent", "Value", };
                break;

            case Cor.MetaTableType.CustomAttribute:
                columnType = new MetaColumnType[] { MetaColumnType.HasCustomAttribute, MetaColumnType.CustomAttributeType, MetaColumnType.Blob, };
                columnName = new String[] { "Parent", "Type", "Value", };
                break;

            case Cor.MetaTableType.FieldMarshal:
                columnType = new MetaColumnType[] { MetaColumnType.HasFieldMarshal, MetaColumnType.Blob, };
                columnName = new String[] { "Parent", "Native", };
                break;

            case Cor.MetaTableType.DeclSecurity:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.HasDeclSecurity, MetaColumnType.Blob, };
                columnName = new String[] { "Action", "Parent", "PermissionSet", };
                break;

            case Cor.MetaTableType.ClassLayout:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.UInt32, MetaColumnType.TypeDef, };
                columnName = new String[] { "PackingSize", "ClassSize", "Parent", };
                break;

            case Cor.MetaTableType.FieldLayout:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.Field, };
                columnName = new String[] { "Offset", "Field", };
                break;

            case Cor.MetaTableType.StandAloneSig:
                columnType = new MetaColumnType[] { MetaColumnType.Blob, };
                columnName = new String[] { "Signature", };
                break;

            case Cor.MetaTableType.EventMap:
                columnType = new MetaColumnType[] { MetaColumnType.TypeDef, MetaColumnType.Event, };
                columnName = new String[] { "Parent", "EventList", };
                break;

            case Cor.MetaTableType.EventPtr:
                columnType = new MetaColumnType[] { MetaColumnType.Event, };
                columnName = new String[] { "Event", };
                break;

            case Cor.MetaTableType.Event:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.String, MetaColumnType.TypeDefOrRef, };
                columnName = new String[] { "EventFlags", "Name", "EventType", };
                break;

            case Cor.MetaTableType.PropertyMap:
                columnType = new MetaColumnType[] { MetaColumnType.TypeDef, MetaColumnType.Property, };
                columnName = new String[] { "Parent", "PropertyList", };
                break;

            case Cor.MetaTableType.PropertyPtr:
                columnType = new MetaColumnType[] { MetaColumnType.Property, };
                columnName = new String[] { "Property", };
                break;

            case Cor.MetaTableType.Property:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.String, MetaColumnType.Blob, };
                columnName = new String[] { "Flags", "Name", "Type", };
                break;

            case Cor.MetaTableType.MethodSemantics:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.MethodDef, MetaColumnType.HasSemantic, };
                columnName = new String[] { "Semantic", "Method", "Association", };
                break;

            case Cor.MetaTableType.MethodImpl:
                columnType = new MetaColumnType[] { MetaColumnType.TypeDef, MetaColumnType.MethodDefOrRef, MetaColumnType.MethodDefOrRef, };
                columnName = new String[] { "Class", "MethodBody", "MethodDeclaration", };
                break;

            case Cor.MetaTableType.ModuleRef:
                columnType = new MetaColumnType[] { MetaColumnType.String, };
                columnName = new String[] { "Name", };
                break;

            case Cor.MetaTableType.TypeSpec:
                columnType = new MetaColumnType[] { MetaColumnType.Blob, };
                columnName = new String[] { "Signature", };
                break;

            case Cor.MetaTableType.ImplMap:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.MemberForwarded, MetaColumnType.String, MetaColumnType.ModuleRef, };
                columnName = new String[] { "MappingFlags", "MemberForwarded", "ImportName", "ImportScope", };
                break;

            case Cor.MetaTableType.FieldRVA:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.Field, };
                columnName = new String[] { "RVA", "Field", };
                break;

            case Cor.MetaTableType.ENCLog:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.UInt32, };
                columnName = new String[] { "Token", "FuncCode", };
                break;

            case Cor.MetaTableType.ENCMap:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, };
                columnName = new String[] { "Token", };
                break;

            case Cor.MetaTableType.Assembly:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.UInt32, MetaColumnType.Blob, MetaColumnType.String, MetaColumnType.String, };
                columnName = new String[] { "HashAlgId", "MajorVersion", "MinorVersion", "BuildNumber", "RevisionNumber", "Flags", "PublicKey", "Name", "Locale", };
                break;

            case Cor.MetaTableType.AssemblyProcessor:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, };
                columnName = new String[] { "Processor", };
                break;

            case Cor.MetaTableType.AssemblyOS:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.UInt32, MetaColumnType.UInt32, };
                columnName = new String[] { "OSPlatformId", "OSMajorVersion", "OSMinorVersion", };
                break;

            case Cor.MetaTableType.AssemblyRef:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.UInt32, MetaColumnType.Blob, MetaColumnType.String, MetaColumnType.String, MetaColumnType.Blob, };
                columnName = new String[] { "MajorVersion", "MinorVersion", "BuildNumber", "RevisionNumber", "Flags", "PublicKeyOrToken", "Name", "Locale", "HashValue", };
                break;

            case Cor.MetaTableType.AssemblyRefProcessor:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.AssemblyRef, };
                columnName = new String[] { "Processor", "AssemblyRef", };
                break;

            case Cor.MetaTableType.AssemblyRefOS:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.UInt32, MetaColumnType.UInt32, MetaColumnType.AssemblyRef, };
                columnName = new String[] { "OSPlatformId", "OSMajorVersion", "OSMinorVersion", "AssemblyRef", };
                break;

            case Cor.MetaTableType.File:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.String, MetaColumnType.Blob, };
                columnName = new String[] { "Flags", "Name", "HashValue", };
                break;

            case Cor.MetaTableType.ExportedType:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.UInt32, MetaColumnType.String, MetaColumnType.String, MetaColumnType.Implementation, };
                columnName = new String[] { "Flags", "TypeDefId", "TypeName", "TypeNamespace", "Implementation", };
                break;

            case Cor.MetaTableType.ManifestResource:
                columnType = new MetaColumnType[] { MetaColumnType.UInt32, MetaColumnType.UInt32, MetaColumnType.String, MetaColumnType.Implementation, };
                columnName = new String[] { "Offset", "Flags", "Name", "Implementation", };
                break;

            case Cor.MetaTableType.NestedClass:
                columnType = new MetaColumnType[] { MetaColumnType.TypeDef, MetaColumnType.TypeDef, };
                columnName = new String[] { "NestedClass", "EnclosingClass", };
                break;

            case Cor.MetaTableType.GenericParam:
                columnType = new MetaColumnType[] { MetaColumnType.UInt16, MetaColumnType.UInt16, MetaColumnType.TypeOrMethodDef, MetaColumnType.String, };
                columnName = new String[] { "Number", "Flags", "Owner", "Name", };
                break;

            case Cor.MetaTableType.MethodSpec:
                columnType = new MetaColumnType[] { MetaColumnType.MethodDefOrRef, MetaColumnType.Blob, };
                columnName = new String[] { "Method", "Instantiation", };
                break;

            case Cor.MetaTableType.GenericParamConstraint:
                columnType = new MetaColumnType[] { MetaColumnType.GenericParam, MetaColumnType.TypeDefOrRef, };
                columnName = new String[] { "Owner", "Constraint", };
                break;

            default: throw new NotSupportedException();
            }

            if (columnType.Length != columnName.Length)
            {
                throw new InvalidOperationException("Length of column type and names must be equal");
            }

            MetaColumn[] result = new MetaColumn[columnType.Length];
            for (UInt16 loop = 0; loop < result.Length; loop++)
            {
                result[loop] = new MetaColumn(table, columnType[loop], columnName[loop], loop);
            }

            return(result);
        }
Пример #3
0
        /// <summary>Create instance of MetaTable cell class</summary>
        /// <param name="table">Owner table</param>
        /// <param name="column">Owner column</param>
        /// <param name="rowIndex">Owner row index</param>
        /// <param name="reader">Image reader pointed to cell value</param>
        public MetaCell(MetaTable table, MetaColumn column, UInt32 rowIndex, BinaryReader reader)
        {
            if (table == null)
            {
                throw new ArgumentNullException("table");
            }
            if (column == null)
            {
                throw new ArgumentNullException("column");
            }
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            this._table    = table;
            this._column   = column;
            this._rowIndex = rowIndex;

            switch (this.Column.ColumnType)
            {
            case MetaColumnType.UInt16:
                this._rawValue = reader.ReadUInt16();
                this._value    = (UInt16)this.RawValue;
                break;

            case MetaColumnType.UInt32:
                this._rawValue = reader.ReadUInt32();
                this._value    = (UInt32)this.RawValue;
                break;

            case MetaColumnType.String:
                this._rawValue = this.Table.Root.StreamTableHeader.StringIndexSize == 2 ? (UInt32)reader.ReadUInt16() : reader.ReadUInt32();
                this._value    = this.Table.Root.Parent.StringHeap[(Int32)this.RawValue];
                break;

            case MetaColumnType.Guid:
                this._rawValue = this.Table.Root.StreamTableHeader.GuidIndexSize == 2 ? (UInt32)reader.ReadUInt16() : reader.ReadUInt32();
                this._value    = this.Table.Root.Parent.GuidHeap[(Int32)this.RawValue];
                break;

            case MetaColumnType.Blob:
                this._rawValue = this.Table.Root.StreamTableHeader.BlobIndexSize == 2 ? (UInt32)reader.ReadUInt16() : reader.ReadUInt32();
                this._value    = this.Table.Root.Parent.BlobHeap[(Int32)this.RawValue];
                break;

            /*case MetaColumnType.UserString:
             *      this._value = this.Table.Root.MetaData.USHeap[(Int32)this.RawValue];
             * break;*/
            default:
                if (this.Column.IsCellPointer)               //Указатель на другую таблицу
                {
                    MetaTable refTable = this.Table.Root[(Cor.MetaTableType) this.Column.ColumnType];
                    this._rawValue = ((refTable.RowsCount < 65536) ? reader.ReadUInt16() : reader.ReadUInt32());
                    this._value    = new MetaCellPointer(this, this.RawValue);
                    //TODO: Не понял необходимость сдвига исходя из типа таблицы.
                    //this.RawValue = (((uint)this.Column.Type << 24) | ((refTable.RowsCount < 65536) ? reader.ReadUInt16() : reader.ReadUInt32()));
                }
                else if (this.Column.IsCodedToken) //Coded token
                {                                  // Coded token (may need to be uncompressed from 2-byte form)
                    UInt32           codedToken = this.Table.SizeOfColumn(this.Column.ColumnType) == 2 ? reader.ReadUInt16() : reader.ReadUInt32();
                    MetaColumnType[] columns    = MetaTable.GetCodedTokenTypes(this.Column.ColumnType);

                    Int32 tableIndex = ((Int32)codedToken) & ~(-1 << MetaCellCodedToken.CodedTokenBits[columns.Length]);
                    Int32 index      = ((Int32)codedToken) >> MetaCellCodedToken.CodedTokenBits[columns.Length];

                    Int32 token = MetaCellCodedToken.ToToken(columns[tableIndex], index);
                    this._rawValue = (UInt32)token;

                    this._value = new MetaCellCodedToken(this, (UInt32)index, columns[tableIndex]);
                    //this._value = new MetaCellCodedToken(this, this.RawValue);
                }
                break;
            }
        }