mirror of https://github.com/icsharpcode/ILSpy.git
19 changed files with 1770 additions and 1 deletions
@ -0,0 +1,91 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Diagnostics; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Input; |
||||||
|
using System.Windows.Media; |
||||||
|
using ICSharpCode.Decompiler.TypeSystem; |
||||||
|
using ICSharpCode.ILSpy.Analyzers; |
||||||
|
using ICSharpCode.ILSpy.Controls; |
||||||
|
using ICSharpCode.ILSpy.Metadata; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Commands |
||||||
|
{ |
||||||
|
[ExportContextMenuEntry(Header = "Decompile", Order = 10)] |
||||||
|
class DecompileCommand : IContextMenuEntry |
||||||
|
{ |
||||||
|
public bool IsVisible(TextViewContext context) |
||||||
|
{ |
||||||
|
var (c, selectedItem) = context.GetColumnAndRowFromMousePosition(); |
||||||
|
if (c is FilterableGridViewColumn column && column.CellTemplateSelector is HandleTemplate && selectedItem is IMemberTreeNode) { |
||||||
|
var selectedHandle = MetadataTokens.EntityHandle((int)selectedItem.GetType().GetProperty(column.SortBy).GetValue(selectedItem)); |
||||||
|
return !selectedHandle.IsNil && (selectedHandle.Kind == HandleKind.TypeDefinition || selectedHandle.Kind == HandleKind.FieldDefinition || selectedHandle.Kind == HandleKind.MethodDefinition || selectedHandle.Kind == HandleKind.PropertyDefinition || selectedHandle.Kind == HandleKind.EventDefinition); |
||||||
|
} |
||||||
|
if (context.SelectedTreeNodes == null) |
||||||
|
return context.Reference?.Reference is IEntity; |
||||||
|
return context.SelectedTreeNodes.Length == 1 && context.SelectedTreeNodes.All(n => n is IMemberTreeNode); |
||||||
|
} |
||||||
|
|
||||||
|
public bool IsEnabled(TextViewContext context) |
||||||
|
{ |
||||||
|
var (c, selectedItem) = context.GetColumnAndRowFromMousePosition(); |
||||||
|
if (c is FilterableGridViewColumn column && column.CellTemplateSelector is HandleTemplate && selectedItem is IMemberTreeNode) { |
||||||
|
var selectedHandle = MetadataTokens.EntityHandle((int)selectedItem.GetType().GetProperty(column.SortBy).GetValue(selectedItem)); |
||||||
|
return !selectedHandle.IsNil && (selectedHandle.Kind == HandleKind.TypeDefinition || selectedHandle.Kind == HandleKind.FieldDefinition || selectedHandle.Kind == HandleKind.MethodDefinition || selectedHandle.Kind == HandleKind.PropertyDefinition || selectedHandle.Kind == HandleKind.EventDefinition); |
||||||
|
} |
||||||
|
if (context.SelectedTreeNodes == null) |
||||||
|
return context.Reference?.Reference is IEntity; |
||||||
|
foreach (IMemberTreeNode node in context.SelectedTreeNodes) { |
||||||
|
if (!IsValidReference(node.Member)) |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool IsValidReference(object reference) |
||||||
|
{ |
||||||
|
return reference is IEntity; |
||||||
|
} |
||||||
|
|
||||||
|
public void Execute(TextViewContext context) |
||||||
|
{ |
||||||
|
IEntity selection = null; |
||||||
|
var (c, selectedItem) = context.GetColumnAndRowFromMousePosition(); |
||||||
|
if (c is FilterableGridViewColumn column && column.CellTemplateSelector is HandleTemplate && selectedItem is IMemberTreeNode semanticContext) { |
||||||
|
var selectedHandle = MetadataTokens.EntityHandle((int)selectedItem.GetType().GetProperty(column.SortBy).GetValue(selectedItem)); |
||||||
|
var module = (MetadataModule)semanticContext.Member.ParentModule; |
||||||
|
switch (selectedHandle.Kind) { |
||||||
|
case HandleKind.TypeDefinition: |
||||||
|
selection = module.GetDefinition((TypeDefinitionHandle)selectedHandle); |
||||||
|
break; |
||||||
|
case HandleKind.FieldDefinition: |
||||||
|
selection = module.GetDefinition((FieldDefinitionHandle)selectedHandle); |
||||||
|
break; |
||||||
|
case HandleKind.MethodDefinition: |
||||||
|
selection = module.GetDefinition((MethodDefinitionHandle)selectedHandle); |
||||||
|
break; |
||||||
|
case HandleKind.PropertyDefinition: |
||||||
|
selection = module.GetDefinition((PropertyDefinitionHandle)selectedHandle); |
||||||
|
break; |
||||||
|
case HandleKind.EventDefinition: |
||||||
|
selection = module.GetDefinition((EventDefinitionHandle)selectedHandle); |
||||||
|
break; |
||||||
|
} |
||||||
|
} else if (context.SelectedTreeNodes?[0] is IMemberTreeNode node) { |
||||||
|
selection = node.Member; |
||||||
|
} else if (context.Reference?.Reference is IEntity entity) { |
||||||
|
selection = entity; |
||||||
|
} |
||||||
|
if (selection != null) |
||||||
|
MainWindow.Instance.JumpToReference(selection); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,101 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
class CoffHeaderTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public CoffHeaderTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => "COFF Header"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
var dataGrid = new DataGrid { |
||||||
|
Columns = { |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Member", Binding = new Binding("Member") }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Offset", Binding = new Binding("Offset") { StringFormat = "X8" } }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Size", Binding = new Binding("Size") }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Value", Binding = new Binding(".") { Converter = ByteWidthConverter.Instance } }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Meaning", Binding = new Binding("Meaning") }, |
||||||
|
}, |
||||||
|
AutoGenerateColumns = false, |
||||||
|
CanUserAddRows = false, |
||||||
|
CanUserDeleteRows = false, |
||||||
|
RowDetailsTemplateSelector = new CharacteristicsDataTemplateSelector(), |
||||||
|
RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Visible |
||||||
|
}; |
||||||
|
var headers = module.Reader.PEHeaders; |
||||||
|
var header = headers.CoffHeader; |
||||||
|
|
||||||
|
var entries = new List<Entry>(); |
||||||
|
entries.Add(new Entry(headers.CoffHeaderStartOffset, (int)header.Machine, 2, "Machine", header.Machine.ToString())); |
||||||
|
entries.Add(new Entry(headers.CoffHeaderStartOffset + 2, (int)header.NumberOfSections, 2, "Number of Sections", "Number of sections; indicates size of the Section Table, which immediately follows the headers.")); |
||||||
|
entries.Add(new Entry(headers.CoffHeaderStartOffset + 4, header.TimeDateStamp, 4, "Time/Date Stamp", DateTimeOffset.FromUnixTimeSeconds(unchecked((uint)header.TimeDateStamp)).DateTime + " - Time and date the file was created in seconds since January 1st 1970 00:00:00 or 0.")); |
||||||
|
entries.Add(new Entry(headers.CoffHeaderStartOffset + 8, header.PointerToSymbolTable, 4, "Pointer to Symbol Table", "Always 0 in .NET executables.")); |
||||||
|
entries.Add(new Entry(headers.CoffHeaderStartOffset + 12, header.NumberOfSymbols, 4, "Number of Symbols", "Always 0 in .NET executables.")); |
||||||
|
entries.Add(new Entry(headers.CoffHeaderStartOffset + 16, (int)header.SizeOfOptionalHeader, 2, "Optional Header Size", "Size of the optional header.")); |
||||||
|
entries.Add(new Entry(headers.CoffHeaderStartOffset + 18, (int)header.Characteristics, 2, "Characteristics", "Flags indicating attributes of the file.")); |
||||||
|
|
||||||
|
dataGrid.ItemsSource = entries; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, dataGrid); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private class CharacteristicsDataTemplateSelector : DataTemplateSelector |
||||||
|
{ |
||||||
|
public override DataTemplate SelectTemplate(object item, DependencyObject container) |
||||||
|
{ |
||||||
|
if (((Entry)item).Member == "Characteristics") |
||||||
|
return MakeDataTemplate((int)((Entry)item).Value); |
||||||
|
return new DataTemplate(); |
||||||
|
} |
||||||
|
|
||||||
|
private DataTemplate MakeDataTemplate(int flags) |
||||||
|
{ |
||||||
|
FrameworkElementFactory dataGridFactory = new FrameworkElementFactory(typeof(DataGrid)); |
||||||
|
dataGridFactory.SetValue(DataGrid.ItemsSourceProperty, new[] { |
||||||
|
new { Value = (flags & 0x0001) != 0, Meaning = "Relocation info stripped from file" }, |
||||||
|
new { Value = (flags & 0x0002) != 0, Meaning = "File is executable" }, |
||||||
|
new { Value = (flags & 0x0004) != 0, Meaning = "Line numbers stripped from file" }, |
||||||
|
new { Value = (flags & 0x0008) != 0, Meaning = "Local symbols stripped from file" }, |
||||||
|
new { Value = (flags & 0x0010) != 0, Meaning = "Aggressively trim working set" }, |
||||||
|
new { Value = (flags & 0x0020) != 0, Meaning = "Large address aware" }, |
||||||
|
new { Value = (flags & 0x0040) != 0, Meaning = "Reserved" }, |
||||||
|
new { Value = (flags & 0x0080) != 0, Meaning = "Bytes of machine words are reversed (Low)" }, |
||||||
|
new { Value = (flags & 0x0100) != 0, Meaning = "32-bit word machine" }, |
||||||
|
new { Value = (flags & 0x0200) != 0, Meaning = "Debugging info stripped from file in .DBG file" }, |
||||||
|
new { Value = (flags & 0x0400) != 0, Meaning = "If image is on removable media, copy and run from the swap file" }, |
||||||
|
new { Value = (flags & 0x0800) != 0, Meaning = "If image is on Net, copy and run from the swap file" }, |
||||||
|
new { Value = (flags & 0x1000) != 0, Meaning = "System" }, |
||||||
|
new { Value = (flags & 0x2000) != 0, Meaning = "DLL" }, |
||||||
|
new { Value = (flags & 0x4000) != 0, Meaning = "File should only be run on a UP machine" }, |
||||||
|
new { Value = (flags & 0x8000) != 0, Meaning = "Bytes of machine words are reversed (High)" }, |
||||||
|
}); |
||||||
|
DataTemplate template = new DataTemplate(); |
||||||
|
template.VisualTree = dataGridFactory; |
||||||
|
return template; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "COFF Header"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
using System.Reflection.PortableExecutable; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
class DataDirectoriesTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public DataDirectoriesTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => "Data Directories"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
var dataGrid = new DataGrid { |
||||||
|
Columns = { |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Name", Binding = new Binding("Name") }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "RVA", Binding = new Binding("RVA") { StringFormat = "X8" } }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Size", Binding = new Binding("Size") { StringFormat = "X8" } }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Section", Binding = new Binding("Section") }, |
||||||
|
}, |
||||||
|
AutoGenerateColumns = false, |
||||||
|
CanUserAddRows = false, |
||||||
|
CanUserDeleteRows = false, |
||||||
|
}; |
||||||
|
var headers = module.Reader.PEHeaders; |
||||||
|
var reader = module.Reader.GetEntireImage().GetReader(headers.PEHeaderStartOffset, 128); |
||||||
|
var header = headers.PEHeader; |
||||||
|
|
||||||
|
var entries = new DataDirectoryEntry[] { |
||||||
|
new DataDirectoryEntry(headers, "Export Table", header.ExportTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Import Table", header.ImportTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Resource Table", header.ResourceTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Exception Table", header.ExceptionTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Certificate Table", header.CertificateTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Base Relocation Table", header.BaseRelocationTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Debug Table", header.DebugTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Copyright Table", header.CopyrightTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Global Pointer Table", header.GlobalPointerTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Thread Local Storage Table", header.ThreadLocalStorageTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Load Config", header.LoadConfigTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Bound Import", header.BoundImportTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Import Address Table", header.ImportAddressTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "Delay Import Descriptor", header.DelayImportTableDirectory), |
||||||
|
new DataDirectoryEntry(headers, "CLI Header", header.CorHeaderTableDirectory), |
||||||
|
}; |
||||||
|
|
||||||
|
dataGrid.ItemsSource = entries; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, dataGrid); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "Data Directories"); |
||||||
|
} |
||||||
|
|
||||||
|
class DataDirectoryEntry |
||||||
|
{ |
||||||
|
public string Name { get; set; } |
||||||
|
public int RVA { get; set; } |
||||||
|
public int Size { get; set; } |
||||||
|
public string Section { get; set; } |
||||||
|
|
||||||
|
public DataDirectoryEntry(string name, int rva, int size, string section) |
||||||
|
{ |
||||||
|
this.Name = name; |
||||||
|
this.RVA = rva; |
||||||
|
this.Size = size; |
||||||
|
this.Section = section; |
||||||
|
} |
||||||
|
|
||||||
|
public DataDirectoryEntry(PEHeaders headers, string name, DirectoryEntry entry) |
||||||
|
: this(name, entry.RelativeVirtualAddress, entry.Size, (headers.GetContainingSectionIndex(entry.RelativeVirtualAddress) >= 0) ? headers.SectionHeaders[headers.GetContainingSectionIndex(entry.RelativeVirtualAddress)].Name : "") |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
using System.Collections.Generic; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
class DosHeaderTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public DosHeaderTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => "DOS Header"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
var view = Helpers.CreateListView("EntryView"); |
||||||
|
var reader = module.Reader.GetEntireImage().GetReader(0, 64); |
||||||
|
|
||||||
|
var entries = new List<Entry>(); |
||||||
|
|
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_magic", "Magic Number (MZ)")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_cblp", "Bytes on last page of file")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_cp", "Pages in file")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_crlc", "Relocations")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_cparhdr", "Size of header in paragraphs")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_minalloc", "Minimum extra paragraphs needed")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_maxalloc", "Maximum extra paragraphs needed")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_ss", "Initial (relative) SS value")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_sp", "Initial SP value")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_csum", "Checksum")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_ip", "Initial IP value")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_cs", "Initial (relative) CS value")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_lfarlc", "File address of relocation table")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_ovno", "Overlay number")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res[0]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res[1]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res[2]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res[3]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_oemid", "OEM identifier (for e_oeminfo)")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_oeminfo", "OEM information; e_oemid specific")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[0]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[1]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[2]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[3]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[4]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[5]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[6]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[7]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[8]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "e_res2[9]", "Reserved words")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "e_lfanew", "File address of new exe header")); |
||||||
|
|
||||||
|
view.ItemsSource = entries; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, view); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "DOS Header"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
public class HandleTemplate : DataTemplateSelector |
||||||
|
{ |
||||||
|
public string ValuePropertyName { get; set; } |
||||||
|
public string TooltipPropertyName { get; set; } |
||||||
|
|
||||||
|
private DataTemplate template; |
||||||
|
|
||||||
|
public override DataTemplate SelectTemplate(object item, DependencyObject container) |
||||||
|
{ |
||||||
|
if (template != null) |
||||||
|
return template; |
||||||
|
var textBlock = new FrameworkElementFactory(typeof(TextBlock), "textBlock"); |
||||||
|
textBlock.SetValue(FrameworkElement.MarginProperty, new Thickness(3, 1, 0, 0)); |
||||||
|
textBlock.SetBinding(TextBlock.TextProperty, new Binding(ValuePropertyName) { StringFormat = "X8" }); |
||||||
|
var textBox = new FrameworkElementFactory(typeof(TextBox), "textBox"); |
||||||
|
textBox.SetBinding(TextBox.TextProperty, new Binding(ValuePropertyName) { StringFormat = "X8", Mode = BindingMode.OneWay }); |
||||||
|
textBox.SetValue(TextBox.VisibilityProperty, Visibility.Hidden); |
||||||
|
textBox.SetValue(TextBox.IsReadOnlyCaretVisibleProperty, true); |
||||||
|
textBox.SetValue(TextBox.IsReadOnlyProperty, true); |
||||||
|
if (TooltipPropertyName != null) |
||||||
|
textBox.SetBinding(FrameworkElement.ToolTipProperty, new Binding(TooltipPropertyName)); |
||||||
|
var grid = new FrameworkElementFactory(typeof(Grid)); |
||||||
|
grid.AppendChild(textBlock); |
||||||
|
grid.AppendChild(textBox); |
||||||
|
template = new DataTemplate { |
||||||
|
VisualTree = grid, |
||||||
|
Triggers = { |
||||||
|
new Trigger { |
||||||
|
Property = UIElement.IsMouseOverProperty, |
||||||
|
Value = true, |
||||||
|
Setters = { |
||||||
|
new Setter(UIElement.VisibilityProperty, Visibility.Visible, "textBox"), |
||||||
|
new Setter(UIElement.VisibilityProperty, Visibility.Hidden, "textBlock"), |
||||||
|
} |
||||||
|
}, |
||||||
|
new Trigger { |
||||||
|
Property = UIElement.IsKeyboardFocusWithinProperty, |
||||||
|
Value = true, |
||||||
|
Setters = { |
||||||
|
new Setter(UIElement.VisibilityProperty, Visibility.Visible, "textBox"), |
||||||
|
new Setter(UIElement.VisibilityProperty, Visibility.Hidden, "textBlock"), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
return template; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,96 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.CSharp.Syntax; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.Controls; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
using ICSharpCode.TreeView; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class ExportedTypeTableTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public ExportedTypeTableTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"27 ExportedType ({module.Metadata.GetTableRowCount(TableIndex.ExportedType)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
ListView view = Helpers.CreateListView("ExportedTypesView"); |
||||||
|
|
||||||
|
var metadata = module.Metadata; |
||||||
|
|
||||||
|
var list = new List<ExportedTypeEntry>(); |
||||||
|
|
||||||
|
foreach (var row in metadata.ExportedTypes) { |
||||||
|
list.Add(new ExportedTypeEntry(module.Reader.PEHeaders.MetadataStartOffset, metadata, row, metadata.GetExportedType(row))); |
||||||
|
} |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, view); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct ExportedTypeEntry |
||||||
|
{ |
||||||
|
readonly int metadataOffset; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly ExportedTypeHandle handle; |
||||||
|
readonly ExportedType type; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public int Token => MetadataTokens.GetToken(handle); |
||||||
|
|
||||||
|
public int Offset => metadataOffset |
||||||
|
+ metadata.GetTableMetadataOffset(TableIndex.ExportedType) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.ExportedType) * (RID-1); |
||||||
|
|
||||||
|
public int Attributes => (int)type.Attributes; |
||||||
|
|
||||||
|
public string AttributesTooltip => Helpers.AttributesToString(type.Attributes); |
||||||
|
|
||||||
|
public int TypeDefId => type.GetTypeDefinitionId(); |
||||||
|
|
||||||
|
public int TypeName => MetadataTokens.GetHeapOffset(type.Name); |
||||||
|
|
||||||
|
public string TypeNameTooltip => metadata.GetString(type.Name); |
||||||
|
|
||||||
|
public int TypeNamespace => MetadataTokens.GetHeapOffset(type.Namespace); |
||||||
|
|
||||||
|
public string TypeNamespaceTooltip => metadata.GetString(type.Namespace); |
||||||
|
|
||||||
|
public int Implementation => MetadataTokens.GetToken(type.Implementation); |
||||||
|
|
||||||
|
public ExportedTypeEntry(int metadataOffset, MetadataReader metadata, ExportedTypeHandle handle, ExportedType type) |
||||||
|
{ |
||||||
|
this.metadataOffset = metadataOffset; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "ExportedType"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Windows.Controls; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.IL; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.Decompiler.TypeSystem; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class FieldTableTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public FieldTableTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"04 Field ({module.Metadata.GetTableRowCount(TableIndex.Field)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
ListView view = Helpers.CreateListView("FieldDefsView"); |
||||||
|
var metadata = module.Metadata; |
||||||
|
|
||||||
|
var list = new List<FieldDefEntry>(); |
||||||
|
|
||||||
|
foreach (var row in metadata.FieldDefinitions) |
||||||
|
list.Add(new FieldDefEntry(module, row)); |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, view); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct FieldDefEntry : IMemberTreeNode |
||||||
|
{ |
||||||
|
readonly int metadataOffset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly FieldDefinitionHandle handle; |
||||||
|
readonly FieldDefinition fieldDef; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public int Token => MetadataTokens.GetToken(handle); |
||||||
|
|
||||||
|
public int Offset => metadataOffset |
||||||
|
+ metadata.GetTableMetadataOffset(TableIndex.Field) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.Field) * (RID - 1); |
||||||
|
|
||||||
|
public int Attributes => (int)fieldDef.Attributes; |
||||||
|
|
||||||
|
public string AttributesTooltip => null; //Helpers.AttributesToString(fieldDef.Attributes);
|
||||||
|
|
||||||
|
public int NameStringHandle => MetadataTokens.GetHeapOffset(fieldDef.Name); |
||||||
|
|
||||||
|
public string Name => metadata.GetString(fieldDef.Name); |
||||||
|
|
||||||
|
IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemOrNull()?.MainModule).GetDefinition(handle); |
||||||
|
|
||||||
|
public int Signature => MetadataTokens.GetHeapOffset(fieldDef.Signature); |
||||||
|
|
||||||
|
public string SignatureTooltip { |
||||||
|
get { |
||||||
|
ITextOutput output = new PlainTextOutput(); |
||||||
|
var context = new Decompiler.Metadata.GenericContext(default(TypeDefinitionHandle), module); |
||||||
|
((EntityHandle)handle).WriteTo(module, output, context); |
||||||
|
return output.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public FieldDefEntry(PEFile module, FieldDefinitionHandle handle) |
||||||
|
{ |
||||||
|
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; |
||||||
|
this.module = module; |
||||||
|
this.metadata = module.Metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.fieldDef = metadata.GetFieldDefinition(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "FieldDefs"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,70 @@ |
|||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Media; |
||||||
|
using ICSharpCode.ILSpy.Controls; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
static class Helpers |
||||||
|
{ |
||||||
|
public static ListView CreateListView(string name) |
||||||
|
{ |
||||||
|
MetadataTableViews dict = new MetadataTableViews(); |
||||||
|
var view = new ListView { |
||||||
|
View = (GridView)dict[name], |
||||||
|
ItemContainerStyle = (Style)dict["ItemContainerStyle"] |
||||||
|
}; |
||||||
|
ContextMenuProvider.Add(view); |
||||||
|
FilterableGridViewColumn.SetSortMode(view, ListViewSortMode.Automatic); |
||||||
|
foreach (var column in ((GridView)view.View).Columns) { |
||||||
|
FilterableGridViewColumn.SetParentView(column, view); |
||||||
|
} |
||||||
|
|
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
public static string AttributesToString(TypeAttributes attributes) |
||||||
|
{ |
||||||
|
const TypeAttributes allMasks = TypeAttributes.ClassSemanticsMask | TypeAttributes.CustomFormatMask | TypeAttributes.LayoutMask | TypeAttributes.ReservedMask | TypeAttributes.StringFormatMask | TypeAttributes.VisibilityMask; |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
var visibility = attributes & TypeAttributes.VisibilityMask; |
||||||
|
sb.AppendLine("Visibility: " + (visibility == 0 ? "NotPublic" : typeof(TypeAttributes).GetEnumName(visibility))); |
||||||
|
var layout = attributes & TypeAttributes.LayoutMask; |
||||||
|
sb.AppendLine("Class layout: " + (layout == 0 ? "AutoLayout" : typeof(TypeAttributes).GetEnumName(layout))); |
||||||
|
var semantics = attributes & TypeAttributes.ClassSemanticsMask; |
||||||
|
sb.AppendLine("Class semantics: " + (semantics == 0 ? "Class" : typeof(TypeAttributes).GetEnumName(semantics))); |
||||||
|
var stringFormat = attributes & TypeAttributes.StringFormatMask; |
||||||
|
sb.AppendLine("String format: " + (stringFormat == 0 ? "AnsiClass" : typeof(TypeAttributes).GetEnumName(stringFormat))); |
||||||
|
var customStringFormat = attributes & TypeAttributes.CustomFormatMask; |
||||||
|
sb.AppendLine("Custom string format: 0x" + customStringFormat.ToString("x")); |
||||||
|
var reserved = attributes & TypeAttributes.ReservedMask; |
||||||
|
sb.AppendLine("Reserved attributes: " + (reserved == 0 ? "" : reserved.ToString())); |
||||||
|
var additional = attributes & ~allMasks; |
||||||
|
sb.Append("Additional attributes: "); |
||||||
|
AdditionalAttributes(sb, additional); |
||||||
|
if (sb.Length == 0) |
||||||
|
return null; |
||||||
|
return sb.ToString(); |
||||||
|
} |
||||||
|
|
||||||
|
static void AdditionalAttributes(StringBuilder sb, TypeAttributes attributes) |
||||||
|
{ |
||||||
|
bool first = true; |
||||||
|
for (int bit = 0; bit < 32; bit++) { |
||||||
|
var value = (TypeAttributes)(1 << bit); |
||||||
|
if ((attributes & value) != 0) { |
||||||
|
if (!first) |
||||||
|
sb.Append(", "); |
||||||
|
first = false; |
||||||
|
sb.Append(typeof(TypeAttributes).GetEnumName(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,339 @@ |
|||||||
|
<ResourceDictionary x:Class="ICSharpCode.ILSpy.Metadata.MetadataTableViews" |
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||||
|
xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls" |
||||||
|
xmlns:local="clr-namespace:ICSharpCode.ILSpy.Metadata"> |
||||||
|
|
||||||
|
<Style x:Key="ItemContainerStyle" TargetType="ListViewItem"> |
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"/> |
||||||
|
</Style> |
||||||
|
|
||||||
|
<DataTemplate x:Key="RowIDDataTemplate"> |
||||||
|
<Grid> |
||||||
|
<TextBlock Margin="3,1,0,0" x:Name="textBlock" Text="{Binding RID}" /> |
||||||
|
<TextBox x:Name="textBox" Text="{Binding RID, Mode=OneWay}" Visibility="Hidden" IsReadOnly="True" IsReadOnlyCaretVisible="True" /> |
||||||
|
</Grid> |
||||||
|
<DataTemplate.Triggers> |
||||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsKeyboardFocusWithin" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
</DataTemplate.Triggers> |
||||||
|
</DataTemplate> |
||||||
|
|
||||||
|
<DataTemplate x:Key="OffsetDataTemplate"> |
||||||
|
<Grid> |
||||||
|
<TextBlock Margin="3,1,0,0" x:Name="textBlock" Text="{Binding Offset, StringFormat=X8}" /> |
||||||
|
<TextBox x:Name="textBox" Text="{Binding Offset, Mode=OneWay, StringFormat=X8}" Visibility="Hidden" IsReadOnly="True" IsReadOnlyCaretVisible="True" /> |
||||||
|
</Grid> |
||||||
|
<DataTemplate.Triggers> |
||||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsKeyboardFocusWithin" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
</DataTemplate.Triggers> |
||||||
|
</DataTemplate> |
||||||
|
|
||||||
|
<local:ByteWidthConverter x:Key="byteWidthConverter" /> |
||||||
|
|
||||||
|
<local:HandleTemplate x:Key="DefinitionHandleDataTemplate" ValuePropertyName="Token" /> |
||||||
|
|
||||||
|
<local:StringHandleTemplate x:Key="NameStringHandleDataTemplate" ValuePropertyName="Name" HandlePropertyName="NameStringHandle" /> |
||||||
|
<local:StringHandleTemplate x:Key="NamespaceStringHandleDataTemplate" ValuePropertyName="Namespace" HandlePropertyName="NamespaceStringHandle" /> |
||||||
|
|
||||||
|
<local:HandleTemplate x:Key="SignatureBlobHandleDataTemplate" TooltipPropertyName="SignatureTooltip" ValuePropertyName="Signature" /> |
||||||
|
|
||||||
|
<GridView x:Key="EntryView" AllowsColumnReorder="False"> |
||||||
|
<controls:FilterableGridViewColumn Header="Member" SortBy="Member" FilterBy="Member"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<Grid> |
||||||
|
<TextBlock Margin="3,1,0,0" x:Name="textBlock" Text="{Binding Member}" /> |
||||||
|
<TextBox x:Name="textBox" Text="{Binding Member, Mode=OneWay}" Visibility="Hidden" IsReadOnly="True" IsReadOnlyCaretVisible="True" /> |
||||||
|
</Grid> |
||||||
|
<DataTemplate.Triggers> |
||||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsKeyboardFocusWithin" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
</DataTemplate.Triggers> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Offset" SortBy="Offset" FilterBy="Offset" FilterFormatString="X8" CellTemplate="{StaticResource OffsetDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Size" SortBy="Size" FilterBy="Size"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<Grid> |
||||||
|
<TextBlock Margin="3,1,0,0" x:Name="textBlock" Text="{Binding Size}" /> |
||||||
|
<TextBox x:Name="textBox" Text="{Binding Size, Mode=OneWay}" Visibility="Hidden" IsReadOnly="True" IsReadOnlyCaretVisible="True" /> |
||||||
|
</Grid> |
||||||
|
<DataTemplate.Triggers> |
||||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsKeyboardFocusWithin" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
</DataTemplate.Triggers> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Value" SortBy="Value" FilterBy="Value"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<Grid> |
||||||
|
<TextBlock Margin="3,1,0,0" x:Name="textBlock" Text="{Binding ., Converter={StaticResource byteWidthConverter}}" /> |
||||||
|
<TextBox x:Name="textBox" Text="{Binding ., Mode=OneWay, Converter={StaticResource byteWidthConverter}}" Visibility="Hidden" IsReadOnly="True" IsReadOnlyCaretVisible="True" /> |
||||||
|
</Grid> |
||||||
|
<DataTemplate.Triggers> |
||||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsKeyboardFocusWithin" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
</DataTemplate.Triggers> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Meaning" SortBy="Meaning" FilterBy="Meaning"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<Grid> |
||||||
|
<TextBlock Margin="3,1,0,0" x:Name="textBlock" Text="{Binding Meaning}" /> |
||||||
|
<TextBox x:Name="textBox" Text="{Binding Meaning, Mode=OneWay}" Visibility="Hidden" IsReadOnly="True" IsReadOnlyCaretVisible="True" /> |
||||||
|
</Grid> |
||||||
|
<DataTemplate.Triggers> |
||||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
<Trigger Property="IsKeyboardFocusWithin" Value="True"> |
||||||
|
<Setter TargetName="textBox" Property="Visibility" Value="Visible" /> |
||||||
|
<Setter TargetName="textBlock" Property="Visibility" Value="Hidden" /> |
||||||
|
</Trigger> |
||||||
|
</DataTemplate.Triggers> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
</GridView> |
||||||
|
|
||||||
|
<GridView x:Key="ModulesView" AllowsColumnReorder="False"> |
||||||
|
<controls:FilterableGridViewColumn Header="RID" SortBy="RID" FilterBy="RID" CellTemplate="{StaticResource RowIDDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Token" SortBy="Token" FilterBy="Token" FilterFormatString="X8" CellTemplateSelector="{StaticResource DefinitionHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Offset" SortBy="Offset" FilterBy="Offset" FilterFormatString="X8"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Offset, StringFormat=X8}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Generation" SortBy="Generation" FilterBy="Generation"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Generation}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Name" SortBy="Name" FilterBy="Name" CellTemplateSelector="{StaticResource NameStringHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Mvid" SortBy="Mvid" FilterBy="Mvid"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Mvid, StringFormat=X}" ToolTip="{Binding MvidTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="GenerationId" SortBy="GenerationId" FilterBy="GenerationId"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding GenerationId, StringFormat=X}" ToolTip="{Binding GenerationIdTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="BaseGenerationId" SortBy="BaseGenerationId" FilterBy="BaseGenerationId"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding BaseGenerationId, StringFormat=X}" ToolTip="{Binding BaseGenerationIdTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
</GridView> |
||||||
|
|
||||||
|
<GridView x:Key="TypeRefsView" AllowsColumnReorder="False"> |
||||||
|
<controls:FilterableGridViewColumn Header="RID" SortBy="RID" FilterBy="RID" CellTemplate="{StaticResource RowIDDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Token" SortBy="Token" FilterBy="Token" FilterFormatString="X8" CellTemplateSelector="{StaticResource DefinitionHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Offset" SortBy="Offset" FilterBy="Offset" FilterFormatString="X8"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Offset, StringFormat=X8}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="ResolutionScope" SortBy="ResolutionScope" FilterBy="ResolutionScope"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplateSelector> |
||||||
|
<local:HandleTemplate ValuePropertyName="ResolutionScope" TooltipPropertyName="ResolutionScopeSignature" /> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplateSelector> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Name" SortBy="Name" FilterBy="Name" CellTemplateSelector="{StaticResource NameStringHandleDataTemplate}" /> |
||||||
|
<controls:FilterableGridViewColumn Header="Namespace" SortBy="Namespace" FilterBy="Namespace" CellTemplateSelector="{StaticResource NamespaceStringHandleDataTemplate}"/> |
||||||
|
</GridView> |
||||||
|
|
||||||
|
<GridView x:Key="TypeDefsView" AllowsColumnReorder="False"> |
||||||
|
<controls:FilterableGridViewColumn Header="RID" SortBy="RID" FilterBy="RID" CellTemplate="{StaticResource RowIDDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Token" SortBy="Token" FilterBy="Token" FilterFormatString="X8" CellTemplateSelector="{StaticResource DefinitionHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Offset" SortBy="Offset" FilterBy="Offset" FilterFormatString="X8"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Offset, StringFormat=X8}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Attributes" SortBy="Attributes" FilterBy="Attributes"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Attributes, StringFormat=X8}" ToolTip="{Binding AttributesTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Name" SortBy="Name" FilterBy="Name" CellTemplateSelector="{StaticResource NameStringHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Namespace" SortBy="Namespace" FilterBy="Namespace" CellTemplateSelector="{StaticResource NamespaceStringHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="BaseType" SortBy="BaseType" FilterBy="BaseType"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplateSelector> |
||||||
|
<local:HandleTemplate ValuePropertyName="BaseType" TooltipPropertyName="BaseTypeSignature" /> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplateSelector> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="FieldList" SortBy="FieldList" FilterBy="FieldList"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding FieldList, StringFormat=X}" ToolTip="{Binding FieldListTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="MethodList" SortBy="MethodList" FilterBy="MethodList"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding MethodList, StringFormat=X}" ToolTip="{Binding MethodListTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
</GridView> |
||||||
|
|
||||||
|
<GridView x:Key="FieldDefsView" AllowsColumnReorder="False"> |
||||||
|
<controls:FilterableGridViewColumn Header="RID" SortBy="RID" FilterBy="RID" CellTemplate="{StaticResource RowIDDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Token" SortBy="Token" FilterBy="Token" FilterFormatString="X8" CellTemplateSelector="{StaticResource DefinitionHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Offset" SortBy="Offset" FilterBy="Offset" FilterFormatString="X8"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Offset, StringFormat=X8}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Attributes" SortBy="Attributes" FilterBy="Attributes"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Attributes, StringFormat=X8}" ToolTip="{Binding AttributesTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Name" SortBy="Name" FilterBy="Name" CellTemplateSelector="{StaticResource NameStringHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Signature" SortBy="Signature" FilterBy="Signature" CellTemplateSelector="{StaticResource SignatureBlobHandleDataTemplate}"/> |
||||||
|
</GridView> |
||||||
|
|
||||||
|
<GridView x:Key="MethodDefsView" AllowsColumnReorder="False"> |
||||||
|
<controls:FilterableGridViewColumn Header="RID" SortBy="RID" FilterBy="RID" CellTemplate="{StaticResource RowIDDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Token" SortBy="Token" FilterBy="Token" FilterFormatString="X8" CellTemplateSelector="{StaticResource DefinitionHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Offset" SortBy="Offset" FilterBy="Offset" FilterFormatString="X8"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Offset, StringFormat=X8}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Attributes" SortBy="Attributes" FilterBy="Attributes"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Attributes, StringFormat=X8}" ToolTip="{Binding AttributesTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Name" SortBy="Name" FilterBy="Name" CellTemplateSelector="{StaticResource NameStringHandleDataTemplate}"/> |
||||||
|
<controls:FilterableGridViewColumn Header="Signature" SortBy="Signature" FilterBy="Signature" CellTemplateSelector="{StaticResource SignatureBlobHandleDataTemplate}"/> |
||||||
|
</GridView> |
||||||
|
|
||||||
|
<GridView x:Key="ExportedTypesView" AllowsColumnReorder="False"> |
||||||
|
<controls:FilterableGridViewColumn Header="RID" SortBy="RID" FilterBy="RID"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding RID}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Token" SortBy="Token" FilterBy="Token" FilterFormatString="X8"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Token, StringFormat=X8}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Offset" SortBy="Offset" FilterBy="Offset" FilterFormatString="X8"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Offset, StringFormat=X8}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Attributes" SortBy="Attributes" FilterBy="Attributes" FilterFormatString="X8"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Attributes, StringFormat=X8}" ToolTip="{Binding AttributesTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="TypeDefId" SortBy="TypeDefId" FilterBy="TypeDefId"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding TypeDefId, StringFormat=X}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="TypeName" SortBy="TypeName" FilterBy="TypeName"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding TypeName, StringFormat=X}" ToolTip="{Binding TypeNameTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="TypeNamespace" SortBy="TypeNamespace" FilterBy="TypeNamespace"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding TypeNamespace, StringFormat=X}" ToolTip="{Binding TypeNamespaceTooltip}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
<controls:FilterableGridViewColumn Header="Implementation" SortBy="Implementation" FilterBy="Implementation"> |
||||||
|
<controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
<DataTemplate> |
||||||
|
<TextBlock Text="{Binding Implementation, StringFormat=X8}" /> |
||||||
|
</DataTemplate> |
||||||
|
</controls:FilterableGridViewColumn.CellTemplate> |
||||||
|
</controls:FilterableGridViewColumn> |
||||||
|
</GridView> |
||||||
|
</ResourceDictionary> |
@ -0,0 +1,39 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using System.Windows.Documents; |
||||||
|
using System.Windows.Input; |
||||||
|
using System.Windows.Media; |
||||||
|
using System.Windows.Media.Imaging; |
||||||
|
using System.Windows.Navigation; |
||||||
|
using System.Windows.Shapes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MetadataTableViews.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class MetadataTableViews : ResourceDictionary |
||||||
|
{ |
||||||
|
public MetadataTableViews() |
||||||
|
{ |
||||||
|
InitializeComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
static MetadataTableViews instance; |
||||||
|
|
||||||
|
public static MetadataTableViews Instance { |
||||||
|
get { |
||||||
|
if (instance == null) { |
||||||
|
instance = new MetadataTableViews(); |
||||||
|
} |
||||||
|
return instance; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,84 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Globalization; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection.PortableExecutable; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
class MetadataTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
private AssemblyTreeNode assemblyTreeNode; |
||||||
|
|
||||||
|
public MetadataTreeNode(PEFile module, AssemblyTreeNode assemblyTreeNode) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
this.assemblyTreeNode = assemblyTreeNode; |
||||||
|
this.LazyLoading = true; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => "Metadata"; |
||||||
|
|
||||||
|
public override object Icon => Images.Library; |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "Metadata"); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void LoadChildren() |
||||||
|
{ |
||||||
|
this.Children.Add(new DosHeaderTreeNode(module)); |
||||||
|
this.Children.Add(new CoffHeaderTreeNode(module)); |
||||||
|
this.Children.Add(new OptionalHeaderTreeNode(module)); |
||||||
|
this.Children.Add(new DataDirectoriesTreeNode(module)); |
||||||
|
this.Children.Add(new ModuleTableTreeNode(module)); |
||||||
|
this.Children.Add(new TypeRefTableTreeNode(module)); |
||||||
|
this.Children.Add(new TypeDefTableTreeNode(module)); |
||||||
|
this.Children.Add(new FieldTableTreeNode(module)); |
||||||
|
this.Children.Add(new MethodTableTreeNode(module)); |
||||||
|
this.Children.Add(new ExportedTypeTableTreeNode(module)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class Entry |
||||||
|
{ |
||||||
|
public string Member { get; set; } |
||||||
|
public int Offset { get; set; } |
||||||
|
public int Size { get; set; } |
||||||
|
public object Value { get; set; } |
||||||
|
public string Meaning { get; set; } |
||||||
|
|
||||||
|
public Entry(int offset, object value, int size, string member, string meaning) |
||||||
|
{ |
||||||
|
this.Member = member; |
||||||
|
this.Offset = offset; |
||||||
|
this.Size = size; |
||||||
|
this.Value = value; |
||||||
|
this.Meaning = meaning; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ByteWidthConverter : IValueConverter |
||||||
|
{ |
||||||
|
public static readonly ByteWidthConverter Instance = new ByteWidthConverter(); |
||||||
|
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
||||||
|
{ |
||||||
|
return string.Format("{0:X" + 2 * ((Entry)value).Size + "}", ((Entry)value).Value); |
||||||
|
} |
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Windows.Controls; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.IL; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.Decompiler.TypeSystem; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class MethodTableTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public MethodTableTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"06 Method ({module.Metadata.GetTableRowCount(TableIndex.MethodDef)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
ListView view = Helpers.CreateListView("MethodDefsView"); |
||||||
|
var metadata = module.Metadata; |
||||||
|
|
||||||
|
var list = new List<MethodDefEntry>(); |
||||||
|
|
||||||
|
foreach (var row in metadata.MethodDefinitions) |
||||||
|
list.Add(new MethodDefEntry(module, row)); |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, view); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct MethodDefEntry : IMemberTreeNode |
||||||
|
{ |
||||||
|
readonly int metadataOffset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly MethodDefinitionHandle handle; |
||||||
|
readonly MethodDefinition methodDef; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public int Token => MetadataTokens.GetToken(handle); |
||||||
|
|
||||||
|
public int Offset => metadataOffset |
||||||
|
+ metadata.GetTableMetadataOffset(TableIndex.MethodDef) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.MethodDef) * (RID - 1); |
||||||
|
|
||||||
|
public int Attributes => (int)methodDef.Attributes; |
||||||
|
|
||||||
|
public string AttributesTooltip => null; //Helpers.AttributesToString(MethodDef.Attributes);
|
||||||
|
|
||||||
|
public int NameStringHandle => MetadataTokens.GetHeapOffset(methodDef.Name); |
||||||
|
|
||||||
|
public string Name => metadata.GetString(methodDef.Name); |
||||||
|
|
||||||
|
IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemOrNull()?.MainModule).GetDefinition(handle); |
||||||
|
|
||||||
|
public int Signature => MetadataTokens.GetHeapOffset(methodDef.Signature); |
||||||
|
|
||||||
|
public string SignatureTooltip { |
||||||
|
get { |
||||||
|
ITextOutput output = new PlainTextOutput(); |
||||||
|
var context = new Decompiler.Metadata.GenericContext(default(TypeDefinitionHandle), module); |
||||||
|
((EntityHandle)handle).WriteTo(module, output, context); |
||||||
|
return output.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public MethodDefEntry(PEFile module, MethodDefinitionHandle handle) |
||||||
|
{ |
||||||
|
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; |
||||||
|
this.module = module; |
||||||
|
this.metadata = module.Metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.methodDef = metadata.GetMethodDefinition(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "MethodDefs"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.CSharp.Syntax; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.Controls; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
using ICSharpCode.TreeView; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class ModuleTableTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public ModuleTableTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"00 Module ({module.Metadata.GetTableRowCount(TableIndex.Module)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
ListView view = Helpers.CreateListView("ModulesView"); |
||||||
|
var metadata = module.Metadata; |
||||||
|
|
||||||
|
var list = new List<ModuleEntry>(); |
||||||
|
|
||||||
|
list.Add(new ModuleEntry(module.Reader.PEHeaders.MetadataStartOffset, metadata, EntityHandle.ModuleDefinition, metadata.GetModuleDefinition())); |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, view); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct ModuleEntry |
||||||
|
{ |
||||||
|
readonly int metadataOffset; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly ModuleDefinitionHandle handle; |
||||||
|
readonly ModuleDefinition module; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public int Token => MetadataTokens.GetToken(handle); |
||||||
|
|
||||||
|
public int Offset => metadataOffset |
||||||
|
+ metadata.GetTableMetadataOffset(TableIndex.Module) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.Module) * (RID-1); |
||||||
|
|
||||||
|
public int Generation => module.Generation; |
||||||
|
|
||||||
|
public int NameStringHandle => MetadataTokens.GetHeapOffset(module.Name); |
||||||
|
|
||||||
|
public string Name => metadata.GetString(module.Name); |
||||||
|
|
||||||
|
public int Mvid => MetadataTokens.GetHeapOffset(module.Mvid); |
||||||
|
|
||||||
|
public string MvidTooltip => metadata.GetGuid(module.Mvid).ToString(); |
||||||
|
|
||||||
|
public int GenerationId => MetadataTokens.GetHeapOffset(module.GenerationId); |
||||||
|
|
||||||
|
public string GenerationIdTooltip => module.GenerationId.IsNil ? null : metadata.GetGuid(module.GenerationId).ToString(); |
||||||
|
|
||||||
|
public int BaseGenerationId => MetadataTokens.GetHeapOffset(module.BaseGenerationId); |
||||||
|
|
||||||
|
public string BaseGenerationIdTooltip => module.BaseGenerationId.IsNil ? null : metadata.GetGuid(module.BaseGenerationId).ToString(); |
||||||
|
|
||||||
|
public ModuleEntry(int metadataOffset, MetadataReader metadata, ModuleDefinitionHandle handle, ModuleDefinition module) |
||||||
|
{ |
||||||
|
this.metadataOffset = metadataOffset; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "Modules"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,125 @@ |
|||||||
|
using System.Collections.Generic; |
||||||
|
using System.Reflection.PortableExecutable; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
class OptionalHeaderTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public OptionalHeaderTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => "Optional Header"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
var dataGrid = new DataGrid { |
||||||
|
Columns = { |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Member", Binding = new Binding("Member") }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Offset", Binding = new Binding("Offset") { StringFormat = "X8" } }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Size", Binding = new Binding("Size") }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Value", Binding = new Binding(".") { Converter = ByteWidthConverter.Instance } }, |
||||||
|
new DataGridTextColumn { IsReadOnly = true, Header = "Meaning", Binding = new Binding("Meaning") }, |
||||||
|
}, |
||||||
|
AutoGenerateColumns = false, |
||||||
|
CanUserAddRows = false, |
||||||
|
CanUserDeleteRows = false, |
||||||
|
RowDetailsTemplateSelector = new DllCharacteristicsDataTemplateSelector(), |
||||||
|
RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Visible |
||||||
|
}; |
||||||
|
var headers = module.Reader.PEHeaders; |
||||||
|
var reader = module.Reader.GetEntireImage().GetReader(headers.PEHeaderStartOffset, 128); |
||||||
|
var header = headers.PEHeader; |
||||||
|
|
||||||
|
var entries = new List<Entry>(); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 2, "Magic", header.Magic.ToString())); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadByte(), 1, "Major Linker Version", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadByte(), 1, "Minor Linker Version", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Code Size", "Size of the code (text) section, or the sum of all code sections if there are multiple sections.")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Initialized Data Size", "Size of the initialized data section, or the sum of all code sections if there are multiple data sections.")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Uninitialized Data Size", "Size of the uninitialized data section, or the sum of all code sections if there are multiple uninitialized data sections.")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Entry Point RVA", "RVA of entry point, needs to point to bytes 0xFF 0x25 followed by the RVA in a section marked execute / read for EXEs or 0 for DLLs")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Base Of Code", "RVA of the code section.")); |
||||||
|
entries.Add(new Entry(reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Base Of Data", "RVA of the data section.")); |
||||||
|
entries.Add(new Entry(reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Image Base", "Shall be a multiple of 0x10000.")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Section Alignment", "Shall be greater than File Alignment.")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "File Alignment", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 4, "Major OS Version", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 4, "Minor OS Version", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 4, "Major Image Version", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 4, "Minor Image Version", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 4, "Major Subsystem Version", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 4, "Minor Subsystem Version", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt32(), 4, "Win32VersionValue", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Image Size", "Size, in bytes, of image, including all headers and padding; shall be a multiple of Section Alignment.")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Header Size", "Combined size of MS-DOS Header, PE Header, PE Optional Header and padding; shall be a multiple of the file alignment.")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "File Checksum", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 4, "Subsystem", header.Subsystem.ToString())); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt16(), 4, "DLL Characteristics", header.DllCharacteristics.ToString())); |
||||||
|
entries.Add(new Entry(reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Stack Reserve Size", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Stack Commit Size", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Heap Reserve Size", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, header.Magic == PEMagic.PE32Plus ? reader.ReadUInt64() : reader.ReadUInt32(), header.Magic == PEMagic.PE32Plus ? 8 : 4, "Heap Commit Size", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadUInt32(), 4, "Loader Flags", "")); |
||||||
|
entries.Add(new Entry(reader.Offset, reader.ReadInt32(), 4, "Number of Data Directories", "")); |
||||||
|
|
||||||
|
dataGrid.ItemsSource = entries; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, dataGrid); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private class DllCharacteristicsDataTemplateSelector : DataTemplateSelector |
||||||
|
{ |
||||||
|
public override DataTemplate SelectTemplate(object item, DependencyObject container) |
||||||
|
{ |
||||||
|
if (((Entry)item).Member == "DLL Characteristics") |
||||||
|
return MakeDataTemplate((ushort)((Entry)item).Value); |
||||||
|
return new DataTemplate(); |
||||||
|
} |
||||||
|
|
||||||
|
private DataTemplate MakeDataTemplate(ushort flags) |
||||||
|
{ |
||||||
|
FrameworkElementFactory dataGridFactory = new FrameworkElementFactory(typeof(DataGrid)); |
||||||
|
dataGridFactory.SetValue(DataGrid.ItemsSourceProperty, new[] { |
||||||
|
new { Value = (flags & 0x0001) != 0, Meaning = "Unused" }, |
||||||
|
new { Value = (flags & 0x0002) != 0, Meaning = "Unused" }, |
||||||
|
new { Value = (flags & 0x0004) != 0, Meaning = "Unused" }, |
||||||
|
new { Value = (flags & 0x0008) != 0, Meaning = "Unused" }, |
||||||
|
new { Value = (flags & 0x0010) != 0, Meaning = "Unused" }, |
||||||
|
new { Value = (flags & 0x0020) != 0, Meaning = "ASLR with 64-bit address space" }, |
||||||
|
new { Value = (flags & 0x0040) != 0, Meaning = "DLL can be relocated at load time" }, |
||||||
|
new { Value = (flags & 0x0080) != 0, Meaning = "Code integrity checks are enforced" }, |
||||||
|
new { Value = (flags & 0x0100) != 0, Meaning = "Image is NX compatible" }, |
||||||
|
new { Value = (flags & 0x0200) != 0, Meaning = "Isolation aware, but do not isolate the image" }, |
||||||
|
new { Value = (flags & 0x0400) != 0, Meaning = "Does not use structured exception handling (SEH)" }, |
||||||
|
new { Value = (flags & 0x0800) != 0, Meaning = "Do not bind the image" }, |
||||||
|
new { Value = (flags & 0x1000) != 0, Meaning = "Image should execute in an AppContainer" }, |
||||||
|
new { Value = (flags & 0x2000) != 0, Meaning = "Driver is a WDM Driver" }, |
||||||
|
new { Value = (flags & 0x4000) != 0, Meaning = "Image supports Control Flow Guard" }, |
||||||
|
new { Value = (flags & 0x8000) != 0, Meaning = "Image is Terminal Server aware" }, |
||||||
|
}); |
||||||
|
DataTemplate template = new DataTemplate(); |
||||||
|
template.VisualTree = dataGridFactory; |
||||||
|
return template; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "Optional Header"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
using System; |
||||||
|
using System.Globalization; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
public class StringHandleTemplate : DataTemplateSelector |
||||||
|
{ |
||||||
|
public string ValuePropertyName { get; set; } |
||||||
|
public string HandlePropertyName { get; set; } |
||||||
|
|
||||||
|
private DataTemplate template; |
||||||
|
|
||||||
|
public override DataTemplate SelectTemplate(object item, DependencyObject container) |
||||||
|
{ |
||||||
|
if (template != null) |
||||||
|
return template; |
||||||
|
var textBlock = new FrameworkElementFactory(typeof(TextBlock), "textBlock"); |
||||||
|
textBlock.SetValue(FrameworkElement.MarginProperty, new Thickness(3, 1, 0, 0)); |
||||||
|
textBlock.SetBinding(TextBlock.TextProperty, new Binding(ValuePropertyName) { StringFormat = "\"{0}\"" }); |
||||||
|
var textBox = new FrameworkElementFactory(typeof(TextBox), "textBox"); |
||||||
|
textBox.SetBinding(TextBox.TextProperty, new Binding(ValuePropertyName) { StringFormat = "\"{0}\"", Mode = BindingMode.OneWay }); |
||||||
|
textBox.SetValue(TextBox.VisibilityProperty, Visibility.Hidden); |
||||||
|
textBox.SetValue(TextBox.IsReadOnlyCaretVisibleProperty, true); |
||||||
|
textBox.SetValue(TextBox.IsReadOnlyProperty, true); |
||||||
|
textBox.SetBinding(FrameworkElement.ToolTipProperty, new MultiBinding { |
||||||
|
Converter = new StringHandleConverter(), |
||||||
|
Bindings = { |
||||||
|
new Binding(HandlePropertyName), |
||||||
|
new Binding(ValuePropertyName) |
||||||
|
} |
||||||
|
}); |
||||||
|
var grid = new FrameworkElementFactory(typeof(Grid)); |
||||||
|
grid.AppendChild(textBlock); |
||||||
|
grid.AppendChild(textBox); |
||||||
|
template = new DataTemplate { |
||||||
|
VisualTree = grid, |
||||||
|
Triggers = { |
||||||
|
new Trigger { |
||||||
|
Property = UIElement.IsMouseOverProperty, |
||||||
|
Value = true, |
||||||
|
Setters = { |
||||||
|
new Setter(UIElement.VisibilityProperty, Visibility.Visible, "textBox"), |
||||||
|
new Setter(UIElement.VisibilityProperty, Visibility.Hidden, "textBlock"), |
||||||
|
} |
||||||
|
}, |
||||||
|
new Trigger { |
||||||
|
Property = UIElement.IsKeyboardFocusWithinProperty, |
||||||
|
Value = true, |
||||||
|
Setters = { |
||||||
|
new Setter(UIElement.VisibilityProperty, Visibility.Visible, "textBox"), |
||||||
|
new Setter(UIElement.VisibilityProperty, Visibility.Hidden, "textBlock"), |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
return template; |
||||||
|
} |
||||||
|
|
||||||
|
private class StringHandleConverter : IMultiValueConverter |
||||||
|
{ |
||||||
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) |
||||||
|
{ |
||||||
|
return string.Format("{0:X} \"{1}\"", values[0], values[1]); |
||||||
|
} |
||||||
|
|
||||||
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) |
||||||
|
{ |
||||||
|
throw new NotImplementedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,125 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using System.Windows; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.CSharp.Syntax; |
||||||
|
using ICSharpCode.Decompiler.Disassembler; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.Decompiler.TypeSystem; |
||||||
|
using ICSharpCode.ILSpy.Controls; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
using ICSharpCode.TreeView; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class TypeDefTableTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public TypeDefTableTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"02 TypeDef ({module.Metadata.GetTableRowCount(TableIndex.TypeDef)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
ListView view = Helpers.CreateListView("TypeDefsView"); |
||||||
|
var metadata = module.Metadata; |
||||||
|
|
||||||
|
var list = new List<TypeDefEntry>(); |
||||||
|
|
||||||
|
foreach (var row in metadata.TypeDefinitions) |
||||||
|
list.Add(new TypeDefEntry(module, row)); |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, view); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct TypeDefEntry : IMemberTreeNode |
||||||
|
{ |
||||||
|
readonly int metadataOffset; |
||||||
|
readonly PEFile module; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly TypeDefinitionHandle handle; |
||||||
|
readonly TypeDefinition typeDef; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public int Token => MetadataTokens.GetToken(handle); |
||||||
|
|
||||||
|
public int Offset => metadataOffset |
||||||
|
+ metadata.GetTableMetadataOffset(TableIndex.TypeDef) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.TypeDef) * (RID-1); |
||||||
|
|
||||||
|
public int Attributes => (int)typeDef.Attributes; |
||||||
|
|
||||||
|
public string AttributesTooltip => Helpers.AttributesToString(typeDef.Attributes); |
||||||
|
|
||||||
|
public int NameStringHandle => MetadataTokens.GetHeapOffset(typeDef.Name); |
||||||
|
|
||||||
|
public string Name => metadata.GetString(typeDef.Name); |
||||||
|
|
||||||
|
public int NamespaceStringHandle => MetadataTokens.GetHeapOffset(typeDef.Namespace); |
||||||
|
|
||||||
|
public string Namespace => metadata.GetString(typeDef.Namespace); |
||||||
|
|
||||||
|
public int BaseType => MetadataTokens.GetToken(typeDef.BaseType); |
||||||
|
|
||||||
|
public string BaseTypeSignature { |
||||||
|
get { |
||||||
|
var output = new PlainTextOutput(); |
||||||
|
var provider = new DisassemblerSignatureProvider(module, output); |
||||||
|
if (typeDef.BaseType.IsNil) |
||||||
|
return null; |
||||||
|
switch (typeDef.BaseType.Kind) { |
||||||
|
case HandleKind.TypeDefinition: |
||||||
|
provider.GetTypeFromDefinition(module.Metadata, (TypeDefinitionHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature); |
||||||
|
return output.ToString(); |
||||||
|
case HandleKind.TypeReference: |
||||||
|
provider.GetTypeFromReference(module.Metadata, (TypeReferenceHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature); |
||||||
|
return output.ToString(); |
||||||
|
case HandleKind.TypeSpecification: |
||||||
|
provider.GetTypeFromSpecification(module.Metadata, new Decompiler.Metadata.GenericContext(default(TypeDefinitionHandle), module), (TypeSpecificationHandle)typeDef.BaseType, 0)(ILNameSyntax.Signature); |
||||||
|
return output.ToString(); |
||||||
|
default: |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public int FieldList => MetadataTokens.GetToken(typeDef.GetFields().FirstOrDefault()); |
||||||
|
|
||||||
|
public int MethodList => MetadataTokens.GetToken(typeDef.GetMethods().FirstOrDefault()); |
||||||
|
|
||||||
|
IEntity IMemberTreeNode.Member => ((MetadataModule)module.GetTypeSystemOrNull()?.MainModule).GetDefinition(handle); |
||||||
|
|
||||||
|
public TypeDefEntry(PEFile module, TypeDefinitionHandle handle) |
||||||
|
{ |
||||||
|
this.metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; |
||||||
|
this.module = module; |
||||||
|
this.metadata = module.Metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.typeDef = metadata.GetTypeDefinition(handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "TypeDefs"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using System.Reflection.Metadata; |
||||||
|
using System.Reflection.Metadata.Ecma335; |
||||||
|
using System.Text; |
||||||
|
using System.Windows.Controls; |
||||||
|
using System.Windows.Data; |
||||||
|
using ICSharpCode.Decompiler; |
||||||
|
using ICSharpCode.Decompiler.CSharp.Syntax; |
||||||
|
using ICSharpCode.Decompiler.Metadata; |
||||||
|
using ICSharpCode.ILSpy.Controls; |
||||||
|
using ICSharpCode.ILSpy.TextView; |
||||||
|
using ICSharpCode.ILSpy.TreeNodes; |
||||||
|
using ICSharpCode.TreeView; |
||||||
|
|
||||||
|
namespace ICSharpCode.ILSpy.Metadata |
||||||
|
{ |
||||||
|
internal class TypeRefTableTreeNode : ILSpyTreeNode |
||||||
|
{ |
||||||
|
private PEFile module; |
||||||
|
|
||||||
|
public TypeRefTableTreeNode(PEFile module) |
||||||
|
{ |
||||||
|
this.module = module; |
||||||
|
} |
||||||
|
|
||||||
|
public override object Text => $"01 TypeRef ({module.Metadata.GetTableRowCount(TableIndex.TypeRef)})"; |
||||||
|
|
||||||
|
public override object Icon => Images.Literal; |
||||||
|
|
||||||
|
public override bool View(DecompilerTextView textView) |
||||||
|
{ |
||||||
|
ListView view = Helpers.CreateListView("TypeRefsView"); |
||||||
|
|
||||||
|
var metadata = module.Metadata; |
||||||
|
|
||||||
|
var list = new List<TypeRefEntry>(); |
||||||
|
|
||||||
|
foreach (var row in metadata.TypeReferences) |
||||||
|
list.Add(new TypeRefEntry(module.Reader.PEHeaders.MetadataStartOffset, metadata, row, metadata.GetTypeReference(row))); |
||||||
|
|
||||||
|
view.ItemsSource = list; |
||||||
|
|
||||||
|
textView.ShowContent(new[] { this }, view); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
struct TypeRefEntry |
||||||
|
{ |
||||||
|
readonly int metadataOffset; |
||||||
|
readonly MetadataReader metadata; |
||||||
|
readonly TypeReferenceHandle handle; |
||||||
|
readonly TypeReference typeRef; |
||||||
|
|
||||||
|
public int RID => MetadataTokens.GetRowNumber(handle); |
||||||
|
|
||||||
|
public int Token => MetadataTokens.GetToken(handle); |
||||||
|
|
||||||
|
public int Offset => metadataOffset |
||||||
|
+ metadata.GetTableMetadataOffset(TableIndex.TypeRef) |
||||||
|
+ metadata.GetTableRowSize(TableIndex.TypeRef) * (RID-1); |
||||||
|
|
||||||
|
public int ResolutionScope => MetadataTokens.GetToken(typeRef.ResolutionScope); |
||||||
|
|
||||||
|
public int Name => MetadataTokens.GetHeapOffset(typeRef.Name); |
||||||
|
|
||||||
|
public string NameTooltip => metadata.GetString(typeRef.Name); |
||||||
|
|
||||||
|
public int Namespace => MetadataTokens.GetHeapOffset(typeRef.Namespace); |
||||||
|
|
||||||
|
public string NamespaceTooltip => metadata.GetString(typeRef.Namespace); |
||||||
|
|
||||||
|
public TypeRefEntry(int metadataOffset, MetadataReader metadata, TypeReferenceHandle handle, TypeReference typeRef) |
||||||
|
{ |
||||||
|
this.metadataOffset = metadataOffset; |
||||||
|
this.metadata = metadata; |
||||||
|
this.handle = handle; |
||||||
|
this.typeRef = typeRef; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) |
||||||
|
{ |
||||||
|
language.WriteCommentLine(output, "TypeRefs"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue