public MetadataTable(TablesHeap h, TableType t) { this.h = h; def = TableDefs.MdTableDefs[t]; rs = new MetadataRowCollection(this); cols = new MetadataColumn[def.Columns.Length]; for (int i = 0; i < def.Columns.Length; i++) { cols[i] = new MetadataColumn(i, def.Columns[i].Key, def.Columns[i].Value); } }
void ReadRvaData(MetadataTable tbl, MetadataReader mdRdr, List <Rva> rvas, MetadataRowCollection rows) { List <Rva> sorted = new List <Rva>(rvas); sorted.Sort(); for (int i = 0; i < rvas.Count; i++) { Rva rva = rvas[i]; MetadataRow r = rows[i + 1]; byte[] dat = null; VirtualReader rdr = new VirtualReader(mdRdr.BaseStream.File.SectionHeaders.GetVirtualStream()); if (tbl.Type == TableType.FieldRVA) { MetadataRoot root = tbl.Heap.Stream.Root; rdr.SetPosition(rva); MetadataRow fd = (r["Field"] as TableToken).ResolveRow(); FieldSig sig = new FieldSig(); SignatureReader sigRdr = new SignatureReader(new MetadataReader(root[MetadataStreamType.Blob])); sigRdr.BaseStream.Position = (fd["Signature"] as BlobToken).Token.Index; sig.Read(sigRdr); int c = 0; switch (sig.Type.Element) { case ElementType.Boolean: case ElementType.UInt8: case ElementType.Int8: c = 1; break; case ElementType.UInt16: case ElementType.Int16: case ElementType.Char: c = 2; break; case ElementType.UInt32: case ElementType.Int32: case ElementType.Single: c = 4; break; case ElementType.UInt64: case ElementType.Int64: case ElementType.Double: c = 8; break; case ElementType.ValueType: TableToken vt = (sig.Type as VALUETYPE).Type; foreach (MetadataRow cl in tbl.Heap[TableType.ClassLayout]) { if (cl["Parent"] == vt) { c = (int)cl["ClassSize"]; break; } } break; default: throw new InvalidOperationException("ReadRvaData"); } dat = rdr.ReadBytes(c); } else if (tbl.Type == TableType.MethodDef && rva != 0) { //MethodBody bdy; //if (((MethodImplAttributes)r["ImplFlags"] & MethodImplAttributes.Native) == MethodImplAttributes.Native) //{ // bdy = new NativeMethodBody(r); //} //else //{ // bdy = new ManagedMethodBody(r); //} //rdr.SetPosition(rva); //bdy.Load(rdr); //rdr.SetPosition(rva); //dat = rdr.ReadBytes((int)bdy.Size); int idx; Rva next; if ((idx = sorted.IndexOf(rva)) == sorted.Count - 1) { CLRDirectory root = tbl.Heap.Stream.Root.Directory; Rva now; next = uint.MaxValue; rdr.SetPosition(root.Location.Address); rdr.BaseStream.Seek(0x8, System.IO.SeekOrigin.Current); if ((now = rdr.ReadRva()) < next && now != 0 && now > rva) { next = now; } rdr.BaseStream.Seek(0xC, System.IO.SeekOrigin.Current); if ((now = rdr.ReadRva()) < next && now != 0 && now > rva) { next = now; } rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current); if ((now = rdr.ReadRva()) < next && now != 0 && now > rva) { next = now; } rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current); if ((now = rdr.ReadRva()) < next && now != 0 && now > rva) { next = now; } rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current); if ((now = rdr.ReadRva()) < next && now != 0 && now > rva) { next = now; } rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current); if ((now = rdr.ReadRva()) < next && now != 0 && now > rva) { next = now; } rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current); if ((now = rdr.ReadRva()) < next && now != 0 && now > rva) { next = now; } } else { next = sorted[idx + 1]; } rdr.SetPosition(rva); dat = rdr.ReadBytes((int)(next - rva)); } if (!tbl.Heap.Stream.Root.Directory.Datas.ContainsAddress(rva) && dat != null) { tbl.Heap.Stream.Root.Directory.Datas.Add(new CLRData() { Address = rva, Data = dat }); } } }