/// <summary> /// Obtains an entry in the specified table at the specified index /// </summary> /// <param name="table">The table to get the metadata for</param> /// <param name="index">The index in the table</param> /// <returns>The MetadataTableRow or null if not found</returns> public MetadataRow GetEntryFor(MetadataTables table, uint index) { MetadataRow o = null; if (index <= _tables[table].Length) { o = _tables[table][index - 1]; } return(o); }
/// <summary> /// Returns the index for a specified metadata row from a metadata table. /// </summary> /// <param name="table">The table to get the metadata items index from</param> /// <param name="entry">The entry which resides in the metadata table</param> /// <returns>The index of the item or -1 if not found</returns> public int GetIndexFor(MetadataTables table, MetadataRow entry) { int index = -1; if (this.ContainsKey(table) && this.indexTable.ContainsKey(entry.FileOffset)) { index = this.indexTable[entry.FileOffset]; } return(index); }
/// <summary> /// Gets the metadata row information from the specified table /// at the specified index. /// </summary> /// <param name="table">The table the metadata row resides in</param> /// <param name="index">The index of the item in the table</param> /// <returns>The metadata row if it exists else null</returns> public MetadataRow GetEntryFor(MetadataTables table, int index) { MetadataRow o = null; if (this.ContainsKey(table) && index <= this[table].Length) { o = this[table][index - 1]; } return(o); }
/// <summary> /// Adds a new entry in to the definition map. /// </summary> /// <param name="table">The table this row and definition are from</param> /// <param name="metadataRow">The row the definition is associated with</param> /// <param name="definition">The definition the row is associated with</param> /// <remarks> /// If a table is created and no unique key is provided for it, you will not be able to use /// a unique key for that table at any point. /// </remarks> public void Add(Core.COFF.MetadataTables table, Core.COFF.MetadataRow metadataRow, ReflectedMember definition) { // Make sure the table store is initialised if (!internalMap.ContainsKey(table)) { internalMap[table] = new Dictionary <int, ReflectedMember>(); } internalMap[table].Add(metadataRow.FileOffset, definition); _uniqueCounter++; }
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); } }
/// <summary> /// Obatains the definition for the specified metadataRow and table. /// </summary> /// <param name="table">The table the row and definition are from</param> /// <param name="metadataRow">The row the definition was instantiated from</param> /// <returns>The definition or null if not found</returns> public ReflectedMember GetDefinition(Core.COFF.MetadataTables table, Core.COFF.MetadataRow metadataRow) { return(this.GetDefinition(table, metadataRow.FileOffset)); }