internal MetadataStream(PeCoffFile file, uint address) { _owningFile = file; byte[] contents = file.FileContents; Offset offset = (int)address; offset.Shift(4); // reserved1 = BitConverter.ToUInt32(contents, offset.Shift(4)); offset.Shift(1); // majorVersion = contents[offset.Shift(1)]; offset.Shift(1); // minorVersion = contents[offset.Shift(1)]; _heapOffsetSizes = (HeapOffsetSizes)contents.GetValue(offset.Shift(1)); offset.Shift(1); // reserved2 = contents[offset.Shift(1)]; ulong valid = BitConverter.ToUInt64(contents, offset.Shift(8)); offset.Shift(8); // sorted = BitConverter.ToUInt64(contents, offset.Shift(8)); // Now we need to read the number of rows present in the available tables, we have // had to add the unused tables to the MEtadatTables as mscorlib seems to use one. Not // sure which though. Dictionary <MetadataTables, int> rowsInPresentTables = new Dictionary <MetadataTables, int>(); Array values = Enum.GetValues(typeof(MetadataTables)); for (int i = 0; i < values.Length - 1; i++) { MetadataTables current = (MetadataTables)values.GetValue(i); ulong mask = (ulong)1 << (int)current; if ((mask & valid) == mask) { rowsInPresentTables.Add(current, BitConverter.ToInt32(contents, offset.Shift(4))); } } // build index helper classes for metadata row creation ICodedIndexResolver resolver = new CodedIndexResolver(rowsInPresentTables); IIndexDetails indexDetails = new IndexDetails(rowsInPresentTables, SizeOfStringIndexes, SizeOfBlobIndexes, SizeOfGuidIndexes ); // Following the array of row size we get the actual metadata tables _tables = new MetadataTablesDictionary(rowsInPresentTables.Count); for (int i = 0; i < values.Length; i++) { MetadataTables current = (MetadataTables)values.GetValue(i); if (!rowsInPresentTables.ContainsKey(current)) { continue; } int numRows = rowsInPresentTables[current]; MetadataRow[] rows = new MetadataRow[numRows]; switch (current) { case MetadataTables.Module: for (int j = 0; j < numRows; j++) { rows[j] = new ModuleMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.TypeRef: for (int j = 0; j < numRows; j++) { rows[j] = new TypeRefMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.TypeDef: for (int j = 0; j < numRows; j++) { rows[j] = new TypeDefMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.Field: for (int j = 0; j < numRows; j++) { rows[j] = new FieldMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.MethodDef: for (int j = 0; j < numRows; j++) { rows[j] = new MethodMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.Param: for (int j = 0; j < numRows; j++) { rows[j] = new ParamMetadataTableRow(contents, offset, SizeOfStringIndexes); } break; case MetadataTables.InterfaceImpl: for (int j = 0; j < numRows; j++) { rows[j] = new InterfaceImplMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.MemberRef: for (int j = 0; j < numRows; j++) { rows[j] = new MemberRefMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.Constant: for (int j = 0; j < numRows; j++) { rows[j] = new ConstantMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.CustomAttribute: for (int j = 0; j < numRows; j++) { rows[j] = new CustomAttributeMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.FieldMarshal: for (int j = 0; j < numRows; j++) { rows[j] = new FieldMarshalMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.DeclSecurity: for (int j = 0; j < numRows; j++) { rows[j] = new DeclSecurityMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.ClassLayout: for (int j = 0; j < numRows; j++) { rows[j] = new ClassLayoutMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.FieldLayout: for (int j = 0; j < numRows; j++) { rows[j] = new FieldLayoutMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.StandAloneSig: for (int j = 0; j < numRows; j++) { rows[j] = new StandAloneSigMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.EventMap: for (int j = 0; j < numRows; j++) { rows[j] = new EventMapMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.Event: for (int j = 0; j < numRows; j++) { rows[j] = new EventMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.PropertyMap: for (int j = 0; j < numRows; j++) { rows[j] = new PropertyMapMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.Property: for (int j = 0; j < numRows; j++) { rows[j] = new PropertyMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.MethodSemantics: for (int j = 0; j < numRows; j++) { rows[j] = new MethodSemanticsMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.MethodImpl: for (int j = 0; j < numRows; j++) { rows[j] = new MethodImplMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.ModuleRef: for (int j = 0; j < numRows; j++) { rows[j] = new ModuleRefMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.TypeSpec: for (int j = 0; j < numRows; j++) { rows[j] = new TypeSpecMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.ImplMap: for (int j = 0; j < numRows; j++) { rows[j] = new ImplMapMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.FieldRVA: for (int j = 0; j < numRows; j++) { rows[j] = new FieldRVAMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.Assembly: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.AssemblyProcessor: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyProcessorMetadataTableRow(contents, offset); } break; case MetadataTables.AssemblyOS: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyOSMetadataTableRow(contents, offset); } break; case MetadataTables.AssemblyRef: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyRefMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.AssemblyRefProcessor: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyRefProcessorMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.AssemblyRefOS: for (int j = 0; j < numRows; j++) { rows[j] = new AssemblyRefOSMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.File: for (int j = 0; j < numRows; j++) { rows[j] = new FileMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.ExportedType: for (int j = 0; j < numRows; j++) { rows[j] = new ExportedTypeMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.ManifestResource: for (int j = 0; j < numRows; j++) { rows[j] = new ManifestResourceMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.NestedClass: for (int j = 0; j < numRows; j++) { rows[j] = new NestedClassMetadataTableRow(contents, offset, indexDetails); } break; case MetadataTables.GenericParam: for (int j = 0; j < numRows; j++) { rows[j] = new GenericParamMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.MethodSpec: for (int j = 0; j < numRows; j++) { rows[j] = new MethodSpecMetadataTableRow(contents, offset, resolver, indexDetails); } break; case MetadataTables.GenericParamConstraint: for (int j = 0; j < numRows; j++) { rows[j] = new GenericParamConstraintMetadataTableRow(contents, offset, resolver, indexDetails); } break; } _tables.SetMetadataTable(current, rows); } }