internal ClrMetadataAccessor(PeDotNetInformation mdParent, Stream peStream, STORAGESTREAM streamInfo, long baseOffset) { _mdParent = mdParent; long offset = baseOffset + streamInfo.iOffset; long end = offset + streamInfo.iSize; peStream.Seek(offset, SeekOrigin.Begin); _md = new CMiniMdBase(peStream); _tables = new MetadataTableBase[_md.TableCount]; peStream.AlignToBytes(4); for (int i = 0; i < _tables.Length; i++) { ClrTable table = (ClrTable)i; Type recordType = _md[table].m_RecordType; Type tableType = typeof(MetadataTable <>).MakeGenericType(recordType); long startPosition = peStream.Position; long tableSize = _md[table].m_cbRec * _md.Schema.RowCount[table]; long expectedEnd = startPosition + tableSize; _tables[i] = (MetadataTableBase)Activator.CreateInstance(tableType, _md, table, peStream); Debug.Assert(peStream.Position == expectedEnd); } long diff = peStream.Position - end; Debug.Assert(diff == 0 || diff == -2 || diff == -4); ulong validBits = _md.Schema.TableValidityBits; for (int i = 0; i < _tables.Length; i++, validBits >>= 1) { if ((validBits & 1) != 0) { Debug.Assert(_tables[i].RowCount > 0, "used table has no rows."); } else { Debug.Assert(_tables[i].RowCount == 0, "unused table has rows."); } } }
internal ClrType(PeDotNetInformation rootAccessor, uint typeDefIndex) { _typeIndex = typeDefIndex; _record = rootAccessor.Metadata.TypeDefTable[typeDefIndex]; if (!rootAccessor.MetadataStrings.TryGetStringByOffset(_record.m_Name, out _name)) { throw new BadImageFormatException("Type definition name is not valid."); } if (!rootAccessor.MetadataStrings.TryGetStringByOffset(_record.m_Namespace, out _namespace)) { throw new BadImageFormatException("Type definition namespace is not valid."); } NestedClassRec_Full nestedType; if (rootAccessor.Metadata.NestedClassTable.TryGetRecordByKey(typeDefIndex, out nestedType)) { _enclosingType = new ClrType(rootAccessor, nestedType.m_EnclosingClass); } }