object GetToolTip(TableRecordData tableRecord, HexPosition position) { var tablesHeap = tableRecord.TablesHeap; Debug.Assert((uint)tableRecord.Token.Table < (uint)tablesHeap.MDTables.Count); if ((uint)tableRecord.Token.Table >= (uint)tablesHeap.MDTables.Count) { return(null); } var mdTable = tablesHeap.MDTables[(int)tableRecord.Token.Table]; int offset = (int)(position - tableRecord.Span.Span.Start).ToUInt64(); var column = mdTable.Columns.FirstOrDefault(a => a.Offset <= offset && offset < a.Offset + a.Size); Debug.Assert(column != null); if (column == null) { return(null); } var mdHeaders = tablesHeap.Metadata; var toolTipCreator = toolTipCreatorFactory.Create(); var contentCreator = toolTipCreator.ToolTipContentCreator; contentCreator.Image = ImageReferenceUtils.GetImageReference(tableRecord.Token.Table); contentCreator.Writer.WriteFieldAndValue(tableRecord, position); var pos = tableRecord.Span.Span.Start + column.Offset; switch (column.ColumnSize) { case ColumnSize.Strings: var s = GetString(mdHeaders.StringsStream, column, pos); if (s == null) { break; } contentCreator.Writer.WriteSpace(); contentCreator.Writer.Write("(", PredefinedClassifiedTextTags.Punctuation); contentCreator.Writer.WriteString(s); contentCreator.Writer.Write(")", PredefinedClassifiedTextTags.Punctuation); break; case ColumnSize.GUID: var g = GetGuid(mdHeaders.GUIDStream, column, pos); if (g == null) { break; } contentCreator.Writer.WriteSpace(); contentCreator.Writer.Write("(", PredefinedClassifiedTextTags.Punctuation); contentCreator.Writer.Write(g.Value.ToString(), PredefinedClassifiedTextTags.Text); contentCreator.Writer.Write(")", PredefinedClassifiedTextTags.Punctuation); break; } return(toolTipCreator.Create()); }
HexSpan?GetFieldReferenceSpan(HexBufferFile file, TableRecordData record, HexPosition position) { if (record.Token.Table == Table.ManifestResource) { var recordOffset = (position - record.Span.Span.Start).ToUInt64(); // Check if it's not Offset column if (recordOffset >= 4) { return(null); } var mdTable = record.TablesHeap.MDTables[(int)Table.ManifestResource]; Debug.Assert(mdTable.IsValidRID(record.Token.Rid)); if (!mdTable.IsValidRID(record.Token.Rid)) { return(null); } var recordPos = mdTable.Span.Start + (record.Token.Rid - 1) * mdTable.RowSize; var buffer = file.Buffer; uint offset = buffer.ReadUInt32(recordPos); uint implementation = mdTable.TableInfo.Columns[3].Size == 2 ? buffer.ReadUInt16(recordPos + mdTable.RowSize - 2) : buffer.ReadUInt32(recordPos + mdTable.RowSize - 4); MDToken implementationToken; if (!CodedToken.Implementation.Decode(implementation, out implementationToken)) { return(null); } if (implementationToken.Rid != 0) { return(null); } var resources = file.GetHeaders <DotNetHeaders>()?.ResourceProvider; if (resources == null) { return(null); } if (offset >= resources.ResourcesSpan.Length) { return(null); } var pos = resources.ResourcesSpan.Start + offset; uint size = pos + 4 > resources.ResourcesSpan.End ? 0 : buffer.ReadUInt32(pos); var end = (pos + 4) + size; if (end > resources.ResourcesSpan.End) { return(new HexSpan(pos, 0)); } return(HexSpan.FromBounds(pos, end)); } return(null); }