mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-01 18:35:13 +00:00
Add built-in ELF viewer plugin
Support for binary ELF, UImage, Mach-O files
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
<UserControl x:Class="QuickLook.Plugin.ELFViewer.InfoPanels.ELFInfoPanel"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:QuickLook.Plugin.ELFViewer.InfoPanels"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Height="192"
|
||||
FontSize="14"
|
||||
UseLayoutRounding="True"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="15" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="image"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Width="128"
|
||||
Height="128"
|
||||
Margin="0,-20,0,0"
|
||||
Opacity="0"
|
||||
Stretch="Fill">
|
||||
<Image.Style>
|
||||
<Style TargetType="{x:Type Image}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Source, ElementName=image}" Value="{x:Null}">
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation BeginTime="0:0:0"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0"
|
||||
To="1"
|
||||
Duration="0:0:0.05" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Image.Style>
|
||||
</Image>
|
||||
<Grid Grid.Row="1" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
MaxHeight="60"
|
||||
Padding="3"
|
||||
FontSize="19"
|
||||
FontWeight="SemiBold"
|
||||
LineHeight="25"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap">
|
||||
<TextBlock.Inlines>
|
||||
<Run x:Name="filename" Text="FilenameFilenameFilenameFilenameFilenameFilenameFilenameFilenameFilenameFilename.ext" />
|
||||
<InlineUIContainer>
|
||||
<local:FluentBorder x:Name="architectureContainer"
|
||||
Background="#0067C0"
|
||||
CornerRadius="5"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock x:Name="architecture"
|
||||
Height="20"
|
||||
Padding="6,0,6,0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="15"
|
||||
Foreground="White" />
|
||||
</local:FluentBorder>
|
||||
</InlineUIContainer>
|
||||
</TextBlock.Inlines>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
<!-- Total Size -->
|
||||
<TextBlock x:Name="totalSizeTitle"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Total Size" />
|
||||
<TextBlock x:Name="totalSize"
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Calculating size..." />
|
||||
<!-- Format -->
|
||||
<TextBlock x:Name="formatTitle"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Format" />
|
||||
<TextBlock x:Name="format"
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<!-- Format Profile -->
|
||||
<TextBlock x:Name="formatProfileTitle"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Format Profile" />
|
||||
<TextBlock x:Name="formatProfile"
|
||||
Grid.Row="5"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
@@ -0,0 +1,238 @@
|
||||
// Copyright © 2017-2025 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using ELFSharp.ELF;
|
||||
using QuickLook.Common.ExtensionMethods;
|
||||
using QuickLook.Common.Helpers;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace QuickLook.Plugin.ELFViewer.InfoPanels;
|
||||
|
||||
public partial class ELFInfoPanel : UserControl, IInfoPanel
|
||||
{
|
||||
public ELFInfoPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
string translationFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Translations.config");
|
||||
totalSizeTitle.Text = TranslationHelper.Get("TOTAL_SIZE", translationFile);
|
||||
formatTitle.Text = TranslationHelper.Get("FORMAT", translationFile);
|
||||
formatProfileTitle.Text = TranslationHelper.Get("FORMAT_PROFILE", translationFile);
|
||||
}
|
||||
|
||||
public void DisplayInfo(string path)
|
||||
{
|
||||
var name = Path.GetFileName(path);
|
||||
filename.Text = string.IsNullOrEmpty(name) ? path : name;
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var size = new FileInfo(path).Length;
|
||||
var isElf = ELFReader.TryLoad(path, out var elf);
|
||||
var arch = elf?.Machine.ToMachineName();
|
||||
var typeLogo = elf?.Type switch
|
||||
{
|
||||
FileType.Executable => "exec",
|
||||
FileType.SharedObject => "dyn",
|
||||
FileType.None or FileType.Relocatable or FileType.Core or _ => "none",
|
||||
};
|
||||
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
architectureContainer.Visibility = string.IsNullOrEmpty(arch) ? System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
|
||||
architecture.Text = arch;
|
||||
format.Text = "ELF";
|
||||
formatProfile.Text = elf != null ? $"{elf.Type} / {elf.Machine}" : "NotELF";
|
||||
totalSize.Text = size.ToPrettySize(2);
|
||||
image.Source = new BitmapImage(new Uri($"pack://application:,,,/QuickLook.Plugin.ELFViewer;component/Resources/{typeLogo}.png"));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
file static class MachineTypeExtension
|
||||
{
|
||||
public static string ToMachineName(this Machine machine)
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||
return machine switch
|
||||
{
|
||||
Machine.M32 => "M32",
|
||||
Machine.SPARC => "SPARC",
|
||||
Machine.Intel386 => "x86",
|
||||
Machine.M68K => "M68K",
|
||||
Machine.M88K => "M88K",
|
||||
Machine.Intel486 => "Intel486",
|
||||
Machine.Intel860 => "Intel860",
|
||||
Machine.MIPS => "MIPS",
|
||||
Machine.S370 => "S370",
|
||||
Machine.MIPSRS3LE => "MIPSRS3LE",
|
||||
Machine.PARISC => "PA-RISC",
|
||||
Machine.VPP500 => "VPP500",
|
||||
Machine.SPARC32Plus => "SPARCv8+",
|
||||
Machine.Intel960 => "Intel960",
|
||||
Machine.PPC => "PowerPC",
|
||||
Machine.PPC64 => "PowerPC64",
|
||||
Machine.S390 => "S390",
|
||||
Machine.SPU => "SPU",
|
||||
Machine.V800 => "V800",
|
||||
Machine.FR20 => "FR20",
|
||||
Machine.RH32 => "RH-32",
|
||||
Machine.RCE => "RCE",
|
||||
Machine.ARM => "ARM",
|
||||
Machine.Alpha => "Alpha",
|
||||
Machine.SuperH => "SuperH",
|
||||
Machine.SPARCv9 => "SPARCv9",
|
||||
Machine.TriCore => "TriCore",
|
||||
Machine.ARC => "Argonaut RISC Core",
|
||||
Machine.H8300 => "H8300",
|
||||
Machine.H8300H => "H8300H",
|
||||
Machine.H8S => "H8S",
|
||||
Machine.H8500 => "H8500",
|
||||
Machine.IA64 => "IA64",
|
||||
Machine.MIPSX => "MIPSX",
|
||||
Machine.ColdFire => "ColdFire",
|
||||
Machine.M68HC12 => "M68HC12",
|
||||
Machine.MMA => "MMA",
|
||||
Machine.PCP => "PCP",
|
||||
Machine.NCPU => "RISC",
|
||||
Machine.NDR1 => "NDR1",
|
||||
Machine.StarCore => "Star*Core",
|
||||
Machine.ME16 => "ME16",
|
||||
Machine.ST100 => "ST100",
|
||||
Machine.TinyJ => "TinyJ",
|
||||
Machine.AMD64 => "x64",
|
||||
Machine.PDSP => "PDSP",
|
||||
Machine.PDP10 => "PDP10",
|
||||
Machine.PDP11 => "PDP11",
|
||||
Machine.FX66 => "FX66",
|
||||
Machine.ST9PLUS => "ST9PLUS",
|
||||
Machine.ST7 => "ST7",
|
||||
Machine.M68HC16 => "M68HC16",
|
||||
Machine.M68HC11 => "M68HC11",
|
||||
Machine.M68HC08 => "M68HC08",
|
||||
Machine.M68HC05 => "M68HC05",
|
||||
Machine.SVX => "SVx",
|
||||
Machine.ST19 => "ST19",
|
||||
Machine.VAX => "VAX",
|
||||
Machine.CRIS => "CRIS",
|
||||
Machine.Javelin => "Javelin",
|
||||
Machine.FirePath => "FirePath",
|
||||
Machine.ZSP => "ZSP",
|
||||
Machine.MMIX => "MMIX",
|
||||
Machine.HUANY => "HUANY",
|
||||
Machine.PRISM => "PRISM",
|
||||
Machine.AVR => "AVR",
|
||||
Machine.FR30 => "FR30",
|
||||
Machine.D10V => "D10V",
|
||||
Machine.D30V => "D30V",
|
||||
Machine.V850 => "V850",
|
||||
Machine.M32R => "M32R",
|
||||
Machine.MN10300 => "MN10300",
|
||||
Machine.MN10200 => "MN10200",
|
||||
Machine.PicoJava => "PicoJava",
|
||||
Machine.OpenRISC => "OpenRISC",
|
||||
Machine.ARCompact => "ARCompact",
|
||||
Machine.Xtensa => "Xtensa",
|
||||
Machine.VideoCore => "VideoCore",
|
||||
Machine.TMMGPP => "TMMGPP",
|
||||
Machine.NS32K => "NS32K",
|
||||
Machine.TPC => "TPC",
|
||||
Machine.SNP1k => "SNP1k",
|
||||
Machine.ST200 => "ST200",
|
||||
Machine.IP2K => "IP2K",
|
||||
Machine.MAX => "MAX",
|
||||
Machine.CompactRISC => "CompactRISC",
|
||||
Machine.F2MC16 => "F2MC16",
|
||||
Machine.MSP430 => "MSP430",
|
||||
Machine.Blackfin => "Blackfin",
|
||||
Machine.S1C33 => "S1C33",
|
||||
Machine.SEP => "SEP",
|
||||
Machine.ArcaRISC => "ArcaRISC",
|
||||
Machine.UNICORE => "UNICORE",
|
||||
Machine.Excess => "Excess",
|
||||
Machine.DXP => "DXP",
|
||||
Machine.AlteraNios2 => "AlteraNios2",
|
||||
Machine.CRX => "CRX",
|
||||
Machine.XGATE => "XGATE",
|
||||
Machine.C166 => "C166",
|
||||
Machine.M16C => "M16C",
|
||||
Machine.DSPIC30F => "DSPIC30F",
|
||||
Machine.EngineRISC => "EngineRISC",
|
||||
Machine.M32C => "M32C",
|
||||
Machine.TSK3000 => "TSK3000",
|
||||
Machine.RS08 => "RS08",
|
||||
Machine.SHARC => "SHARC",
|
||||
Machine.ECOG2 => "ECOG2",
|
||||
Machine.Score7 => "Score7",
|
||||
Machine.DSP24 => "DSP24",
|
||||
Machine.VideoCore3 => "VideoCore3",
|
||||
Machine.LatticeMico32 => "LatticeMico32",
|
||||
Machine.SeikoEpsonC17 => "SeikoEpsonC17",
|
||||
Machine.TIC6000 => "TIC6000",
|
||||
Machine.TIC2000 => "TIC2000",
|
||||
Machine.TIC5500 => "TIC5500",
|
||||
Machine.MMDSPPlus => "MMDSPPlus",
|
||||
Machine.CypressM8C => "CypressM8C",
|
||||
Machine.R32C => "R32C",
|
||||
Machine.TriMedia => "TriMedia",
|
||||
Machine.Hexagon => "Hexagon",
|
||||
Machine.Intel8051 => "Intel8051",
|
||||
Machine.STxP7x => "STxP7x",
|
||||
Machine.NDS32 => "NDS32",
|
||||
Machine.ECOG1 or Machine.ECOG1X => "ECOG1",
|
||||
Machine.MAXQ30 => "MAXQ30",
|
||||
Machine.XIMO16 => "XIMO16",
|
||||
Machine.MANIK => "MANIK",
|
||||
Machine.CrayNV2 => "CrayNV2",
|
||||
Machine.RX => "RX",
|
||||
Machine.METAG => "METAG",
|
||||
Machine.MCSTElbrus => "MCSTElbrus",
|
||||
Machine.ECOG16 => "ECOG16",
|
||||
Machine.CR16 => "CR16",
|
||||
Machine.ETPU => "ETPU",
|
||||
Machine.SLE9X => "SLE9X",
|
||||
Machine.L10M => "L10M",
|
||||
Machine.K10M => "K10M",
|
||||
Machine.AArch64 => "ARM64",
|
||||
Machine.AVR32 => "AVR32",
|
||||
Machine.STM8 => "STM8",
|
||||
Machine.TILE64 => "TILE64",
|
||||
Machine.TILEPro => "TILEPro",
|
||||
Machine.CUDA => "CUDA",
|
||||
Machine.TILEGx => "TILEGx",
|
||||
Machine.CloudShield => "CloudShield",
|
||||
Machine.CoreA1st => "CoreA1st",
|
||||
Machine.CoreA2nd => "CoreA2nd",
|
||||
Machine.ARCompact2 => "ARCompactV2",
|
||||
Machine.Open8 => "Open8",
|
||||
Machine.RL78 => "RL78",
|
||||
Machine.VideoCore5 => "VideoCore5",
|
||||
Machine.R78KOR => "R78KOR",
|
||||
Machine.F56800EX => "F56800EX",
|
||||
Machine.None or _ => "UNKNOWN",
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
// Copyright © 2017-2025 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace QuickLook.Plugin.ELFViewer.InfoPanels;
|
||||
|
||||
public class FluentBorder : Decorator
|
||||
{
|
||||
public static readonly DependencyProperty CornerRadiusProperty =
|
||||
DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(FluentBorder), new FrameworkPropertyMetadata(new CornerRadius()));
|
||||
|
||||
public CornerRadius CornerRadius
|
||||
{
|
||||
get => (CornerRadius)GetValue(CornerRadiusProperty);
|
||||
set => SetValue(CornerRadiusProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty BackgroundProperty =
|
||||
DependencyProperty.Register("Background", typeof(Brush), typeof(FluentBorder), new FrameworkPropertyMetadata(Brushes.Transparent));
|
||||
|
||||
public Brush Background
|
||||
{
|
||||
get => (Brush)GetValue(BackgroundProperty);
|
||||
set => SetValue(BackgroundProperty, value);
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext drawingContext)
|
||||
{
|
||||
if (Child != null)
|
||||
{
|
||||
Rect rect = new(new Point(0, 0), RenderSize);
|
||||
drawingContext.DrawRoundedRectangle(Background, new Pen(Brushes.Transparent, 1), rect, CornerRadius.TopLeft, CornerRadius.TopRight);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
// Copyright © 2017-2025 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace QuickLook.Plugin.ELFViewer.InfoPanels;
|
||||
|
||||
public interface IInfoPanel
|
||||
{
|
||||
public void DisplayInfo(string path);
|
||||
}
|
@@ -0,0 +1,144 @@
|
||||
<UserControl x:Class="QuickLook.Plugin.ELFViewer.InfoPanels.MachOInfoPanel"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:QuickLook.Plugin.ELFViewer.InfoPanels"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Height="192"
|
||||
FontSize="14"
|
||||
UseLayoutRounding="True"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="15" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="image"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Width="128"
|
||||
Height="128"
|
||||
Margin="0,-20,0,0"
|
||||
Opacity="0"
|
||||
Stretch="Fill">
|
||||
<Image.Style>
|
||||
<Style TargetType="{x:Type Image}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Source, ElementName=image}" Value="{x:Null}">
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation BeginTime="0:0:0"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0"
|
||||
To="1"
|
||||
Duration="0:0:0.05" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Image.Style>
|
||||
</Image>
|
||||
<Grid Grid.Row="1" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
MaxHeight="60"
|
||||
Padding="3"
|
||||
FontSize="19"
|
||||
FontWeight="SemiBold"
|
||||
LineHeight="25"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap">
|
||||
<TextBlock.Inlines>
|
||||
<Run x:Name="filename" Text="FilenameFilenameFilenameFilenameFilenameFilenameFilenameFilenameFilenameFilename.ext" />
|
||||
<InlineUIContainer>
|
||||
<local:FluentBorder x:Name="architectureContainer"
|
||||
Background="#0067C0"
|
||||
CornerRadius="5"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock x:Name="architecture"
|
||||
Height="20"
|
||||
Padding="6,0,6,0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="15"
|
||||
Foreground="White" />
|
||||
</local:FluentBorder>
|
||||
</InlineUIContainer>
|
||||
</TextBlock.Inlines>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
<!-- Total Size -->
|
||||
<TextBlock x:Name="totalSizeTitle"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Total Size" />
|
||||
<TextBlock x:Name="totalSize"
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Calculating size..." />
|
||||
<!-- Format -->
|
||||
<TextBlock x:Name="formatTitle"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Format" />
|
||||
<TextBlock x:Name="format"
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<!-- Format Profile -->
|
||||
<TextBlock x:Name="formatProfileTitle"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Format Profile" />
|
||||
<TextBlock x:Name="formatProfile"
|
||||
Grid.Row="5"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
@@ -0,0 +1,109 @@
|
||||
// Copyright © 2017-2025 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using ELFSharp.MachO;
|
||||
using QuickLook.Common.ExtensionMethods;
|
||||
using QuickLook.Common.Helpers;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace QuickLook.Plugin.ELFViewer.InfoPanels;
|
||||
|
||||
public partial class MachOInfoPanel : UserControl, IInfoPanel
|
||||
{
|
||||
public MachOInfoPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
string translationFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Translations.config");
|
||||
totalSizeTitle.Text = TranslationHelper.Get("TOTAL_SIZE", translationFile);
|
||||
formatTitle.Text = TranslationHelper.Get("FORMAT", translationFile);
|
||||
formatProfileTitle.Text = TranslationHelper.Get("FORMAT_PROFILE", translationFile);
|
||||
}
|
||||
|
||||
public void DisplayInfo(string path)
|
||||
{
|
||||
var name = Path.GetFileName(path);
|
||||
filename.Text = string.IsNullOrEmpty(name) ? path : name;
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var size = new FileInfo(path).Length;
|
||||
var tried = MachOReader.TryLoad(path, out MachO machO);
|
||||
var arch = string.Empty;
|
||||
var profile = string.Empty;
|
||||
|
||||
if (tried == MachOResult.OK)
|
||||
{
|
||||
arch = machO.Machine.ToMachineName();
|
||||
profile = machO.Machine.ToString();
|
||||
}
|
||||
else if (tried == MachOResult.FatMachO)
|
||||
{
|
||||
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
|
||||
if (MachOReader.TryLoadFat(stream, shouldOwnStream: true, out var machOs) == MachOResult.FatMachO)
|
||||
{
|
||||
arch = string.Join(", ", machOs.Select(m => m.Machine.ToMachineName()).Distinct());
|
||||
profile = string.Join(", ", machOs.Select(m => m.Machine.ToString()).Distinct());
|
||||
}
|
||||
}
|
||||
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
architectureContainer.Visibility = string.IsNullOrEmpty(arch) ? System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
|
||||
architecture.Text = arch;
|
||||
format.Text = "DynamicLibrary";
|
||||
formatProfile.Text = profile;
|
||||
totalSize.Text = size.ToPrettySize(2);
|
||||
image.Source = new BitmapImage(new Uri("pack://application:,,,/QuickLook.Plugin.ELFViewer;component/Resources/dyn.png"));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
file static class MachineTypeExtension
|
||||
{
|
||||
public static string ToMachineName(this Machine machine)
|
||||
{
|
||||
return machine switch
|
||||
{
|
||||
Machine.Vax => "Vax",
|
||||
Machine.M68k => "M68k",
|
||||
Machine.X86 => "x86",
|
||||
Machine.X86_64 => "x64",
|
||||
Machine.M98k => "M98k",
|
||||
Machine.PaRisc => "PaRisc",
|
||||
Machine.Arm => "Arm",
|
||||
Machine.Arm64 => "Arm64",
|
||||
Machine.M88k => "M88k",
|
||||
Machine.Sparc => "Sparc",
|
||||
Machine.I860 => "I860",
|
||||
Machine.PowerPc => "PowerPc",
|
||||
Machine.PowerPc64 => "PowerPc64",
|
||||
Machine.Any or _ => "UNKNOWN",
|
||||
};
|
||||
}
|
||||
}
|
@@ -0,0 +1,159 @@
|
||||
<UserControl x:Class="QuickLook.Plugin.ELFViewer.InfoPanels.UImageInfoPanel"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:QuickLook.Plugin.ELFViewer.InfoPanels"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Height="192"
|
||||
FontSize="14"
|
||||
UseLayoutRounding="True"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="15" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image x:Name="image"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Width="128"
|
||||
Height="128"
|
||||
Margin="0,-20,0,0"
|
||||
Opacity="0"
|
||||
Stretch="Fill">
|
||||
<Image.Style>
|
||||
<Style TargetType="{x:Type Image}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Source, ElementName=image}" Value="{x:Null}">
|
||||
<DataTrigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation BeginTime="0:0:0"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0"
|
||||
To="1"
|
||||
Duration="0:0:0.05" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Image.Style>
|
||||
</Image>
|
||||
<Grid Grid.Row="1" Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="10" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
MaxHeight="60"
|
||||
Padding="3"
|
||||
FontSize="19"
|
||||
FontWeight="SemiBold"
|
||||
LineHeight="25"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap">
|
||||
<TextBlock.Inlines>
|
||||
<Run x:Name="filename" Text="FilenameFilenameFilenameFilenameFilenameFilenameFilenameFilenameFilenameFilename.ext" />
|
||||
<InlineUIContainer>
|
||||
<local:FluentBorder x:Name="architectureContainer"
|
||||
Background="#0067C0"
|
||||
CornerRadius="5"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock x:Name="architecture"
|
||||
Height="20"
|
||||
Padding="6,0,6,0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="15"
|
||||
Foreground="White" />
|
||||
</local:FluentBorder>
|
||||
</InlineUIContainer>
|
||||
</TextBlock.Inlines>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
<!-- Name -->
|
||||
<TextBlock x:Name="imageNameTitle"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Name" />
|
||||
<TextBlock x:Name="imageName"
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..." />
|
||||
<!-- Total Size -->
|
||||
<TextBlock x:Name="totalSizeTitle"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Total Size" />
|
||||
<TextBlock x:Name="totalSize"
|
||||
Grid.Row="4"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Calculating size..." />
|
||||
<!-- Format -->
|
||||
<TextBlock x:Name="formatTitle"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Format" />
|
||||
<TextBlock x:Name="format"
|
||||
Grid.Row="5"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<!-- Format Profile -->
|
||||
<TextBlock x:Name="formatProfileTitle"
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Format Profile" />
|
||||
<TextBlock x:Name="formatProfile"
|
||||
Grid.Row="6"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,0,0"
|
||||
Padding="3"
|
||||
Foreground="{DynamicResource WindowTextForegroundAlternative}"
|
||||
Text="Searching..."
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
@@ -0,0 +1,112 @@
|
||||
// Copyright © 2017-2025 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using ELFSharp.UImage;
|
||||
using QuickLook.Common.ExtensionMethods;
|
||||
using QuickLook.Common.Helpers;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace QuickLook.Plugin.ELFViewer.InfoPanels;
|
||||
|
||||
public partial class UImageInfoPanel : UserControl, IInfoPanel
|
||||
{
|
||||
public UImageInfoPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
string translationFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Translations.config");
|
||||
imageNameTitle.Text = TranslationHelper.Get("NAME", translationFile);
|
||||
totalSizeTitle.Text = TranslationHelper.Get("TOTAL_SIZE", translationFile);
|
||||
formatTitle.Text = TranslationHelper.Get("FORMAT", translationFile);
|
||||
formatProfileTitle.Text = TranslationHelper.Get("FORMAT_PROFILE", translationFile);
|
||||
}
|
||||
|
||||
public void DisplayInfo(string path)
|
||||
{
|
||||
var name = Path.GetFileName(path);
|
||||
filename.Text = string.IsNullOrEmpty(name) ? path : name;
|
||||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var size = new FileInfo(path).Length;
|
||||
var tried = UImageReader.TryLoad(path, out UImage uImage);
|
||||
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
var arch = tried == UImageResult.OK ? uImage.Architecture.ToMachineName() : string.Empty;
|
||||
architectureContainer.Visibility = string.IsNullOrEmpty(arch) ? System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
|
||||
|
||||
if (tried == UImageResult.OK)
|
||||
{
|
||||
imageName.Text = uImage.Name;
|
||||
architecture.Text = arch;
|
||||
format.Text = $"UImage - {uImage.OperatingSystem} / {uImage.Compression}";
|
||||
formatProfile.Text = $"{uImage.Type} / {uImage.Architecture}";
|
||||
}
|
||||
else
|
||||
{
|
||||
imageName.Text = string.Empty;
|
||||
architecture.Text = string.Empty;
|
||||
format.Text = tried.ToString();
|
||||
formatProfile.Text = tried.ToString();
|
||||
}
|
||||
|
||||
totalSize.Text = size.ToPrettySize(2);
|
||||
image.Source = new BitmapImage(new Uri("pack://application:,,,/QuickLook.Plugin.ELFViewer;component/Resources/uboot.png"));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
file static class MachineTypeExtension
|
||||
{
|
||||
public static string ToMachineName(this Architecture arch)
|
||||
{
|
||||
return arch switch
|
||||
{
|
||||
Architecture.Alpha => "Alpha",
|
||||
Architecture.ARM => "ARM",
|
||||
Architecture.Ix86 => "Ix86",
|
||||
Architecture.Itanium => "Itanium",
|
||||
Architecture.MIPS => "MIPS",
|
||||
Architecture.MIPS64 => "MIPS64",
|
||||
Architecture.PowerPC => "PowerPC",
|
||||
Architecture.S390 => "S390",
|
||||
Architecture.SuperH => "SuperH",
|
||||
Architecture.SPARC => "SPARC",
|
||||
Architecture.SPARC64 => "SPARC64",
|
||||
Architecture.M68k => "M68k",
|
||||
Architecture.MicroBlaze => "MicroBlaze",
|
||||
Architecture.Nios2 => "Nios2",
|
||||
Architecture.Blackfin => "Blackfin",
|
||||
Architecture.AVR32 => "AVR32",
|
||||
Architecture.ST200 => "ST200",
|
||||
Architecture.Sandbox => "Sandbox",
|
||||
Architecture.NDS32 => "NDS32",
|
||||
Architecture.OpenRISC => "OpenRISC",
|
||||
Architecture.Invalid or _ => "UNKNOWN",
|
||||
};
|
||||
}
|
||||
}
|
150
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Plugin.cs
Normal file
150
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Plugin.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright © 2017-2025 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using ELFSharp.ELF;
|
||||
using ELFSharp.MachO;
|
||||
using ELFSharp.UImage;
|
||||
using QuickLook.Common.Plugin;
|
||||
using QuickLook.Plugin.ELFViewer.InfoPanels;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
|
||||
namespace QuickLook.Plugin.ELFViewer;
|
||||
|
||||
public class Plugin : IViewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Magic number of ELF files
|
||||
/// 0x7F 'E' 'L' 'F'
|
||||
/// </summary>
|
||||
private static readonly byte[] _magic = [0x7F, 0x45, 0x4C, 0x46];
|
||||
|
||||
private static readonly string[] _extensions =
|
||||
[
|
||||
".axf", ".bin", ".elf", ".o", ".out", ".prx", ".puff", ".ko", ".mod", "so",
|
||||
];
|
||||
|
||||
private IInfoPanel _ip;
|
||||
private string _path;
|
||||
private FileEnum _type;
|
||||
|
||||
public int Priority => 11;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
}
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
return DetectFormat(path) != FileEnum.None;
|
||||
}
|
||||
|
||||
public void Prepare(string path, ContextObject context)
|
||||
{
|
||||
context.PreferredSize = new Size { Width = 520, Height = 192 };
|
||||
context.Title = string.Empty;
|
||||
context.TitlebarOverlap = false;
|
||||
context.TitlebarBlurVisibility = false;
|
||||
context.TitlebarColourVisibility = false;
|
||||
context.FullWindowDragging = true;
|
||||
}
|
||||
|
||||
public void View(string path, ContextObject context)
|
||||
{
|
||||
_path = path;
|
||||
_type = DetectFormat(path);
|
||||
_ip = _type switch
|
||||
{
|
||||
FileEnum.ELF => new ELFInfoPanel(),
|
||||
FileEnum.MachO => new MachOInfoPanel(),
|
||||
FileEnum.UImage => new UImageInfoPanel(),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
_ip.DisplayInfo(_path);
|
||||
|
||||
context.ViewerContent = _ip;
|
||||
context.IsBusy = false;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
_ip = null;
|
||||
}
|
||||
|
||||
private static FileEnum DetectFormat(string path)
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
return FileEnum.None;
|
||||
|
||||
var pathLower = Path.GetFileName(path).ToLower();
|
||||
var extension = Path.GetExtension(pathLower);
|
||||
|
||||
// UImage
|
||||
if (pathLower.EndsWith(".uimage"))
|
||||
{
|
||||
return FileEnum.UImage;
|
||||
}
|
||||
else if (pathLower.Equals("uimage"))
|
||||
{
|
||||
if (UImageReader.TryLoad(path, out _) == UImageResult.OK)
|
||||
return FileEnum.UImage;
|
||||
}
|
||||
|
||||
// Mach-O
|
||||
if (pathLower.EndsWith(".dylib"))
|
||||
{
|
||||
return FileEnum.MachO;
|
||||
}
|
||||
else if (extension == string.Empty)
|
||||
{
|
||||
if (MachOReader.TryLoad(path, out _) != MachOResult.NotMachO)
|
||||
return FileEnum.MachO;
|
||||
}
|
||||
|
||||
// ELF
|
||||
if (_extensions.Any(pathLower.EndsWith) || extension == string.Empty)
|
||||
{
|
||||
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var br = new BinaryReader(fs);
|
||||
|
||||
if (br.BaseStream.Length < Consts.MinimalELFSize)
|
||||
return FileEnum.None;
|
||||
|
||||
var magic = br.ReadBytes(4);
|
||||
for (var i = 0; i < 4; i++)
|
||||
if (magic[i] != _magic[i])
|
||||
return FileEnum.None;
|
||||
|
||||
return FileEnum.ELF;
|
||||
}
|
||||
|
||||
return FileEnum.None;
|
||||
}
|
||||
|
||||
private enum FileEnum
|
||||
{
|
||||
None,
|
||||
ELF,
|
||||
UImage,
|
||||
MachO,
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
// Copyright © 2017-2025 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("QuickLook.Plugin.ELFViewer")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("pooi.moe")]
|
||||
[assembly: AssemblyProduct("QuickLook.Plugin.ELFViewer")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017-2025 QL-Win Contributors")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("63c00175-0ff3-42c7-8621-2f1959f26064")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
@@ -0,0 +1,83 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net462</TargetFramework>
|
||||
<RootNamespace>QuickLook.Plugin.ELFViewer</RootNamespace>
|
||||
<AssemblyName>QuickLook.Plugin.ELFViewer</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<UseWPF>true</UseWPF>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<ProjectGuid>{63C00175-0FF3-42C7-8621-2F1959F26064}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.ELFViewer\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.ELFViewer\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<OutputPath>..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.ELFViewer\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.ELFViewer\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\QuickLook.Common\QuickLook.Common.csproj">
|
||||
<Project>{85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95}</Project>
|
||||
<Name>QuickLook.Common</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\*.png" />
|
||||
<Resource Include="Resources\*.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\GitVersion.cs">
|
||||
<Link>Properties\GitVersion.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ELFSharp" Version="2.17.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Translations.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
BIN
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Resources/dyn.png
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Resources/dyn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
BIN
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Resources/exec.png
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Resources/exec.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
BIN
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Resources/none.png
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Resources/none.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 949 B |
BIN
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Resources/uboot.png
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.ELFViewer/Resources/uboot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Translations>
|
||||
<en>
|
||||
<TOTAL_SIZE>Total Size</TOTAL_SIZE>
|
||||
<FORMAT>Format</FORMAT>
|
||||
<FORMAT_PROFILE>Format Profile</FORMAT_PROFILE>
|
||||
<NAME>Name</NAME>
|
||||
</en>
|
||||
<pt-BR>
|
||||
<TOTAL_SIZE>Tamanho total</TOTAL_SIZE>
|
||||
<FORMAT>Formato</FORMAT>
|
||||
<FORMAT_PROFILE>Perfil do Formato</FORMAT_PROFILE>
|
||||
<NAME>Nome</NAME>
|
||||
</pt-BR>
|
||||
<zh-CN>
|
||||
<TOTAL_SIZE>总大小</TOTAL_SIZE>
|
||||
<FORMAT>格式</FORMAT>
|
||||
<FORMAT_PROFILE>格式配置</FORMAT_PROFILE>
|
||||
<NAME>名称</NAME>
|
||||
</zh-CN>
|
||||
<zh-TW>
|
||||
<TOTAL_SIZE>縂大小</TOTAL_SIZE>
|
||||
<FORMAT>格式</FORMAT>
|
||||
<FORMAT_PROFILE>格式設定</FORMAT_PROFILE>
|
||||
<NAME>名稱</NAME>
|
||||
</zh-TW>
|
||||
<ja>
|
||||
<TOTAL_SIZE>合計サイズ</TOTAL_SIZE>
|
||||
<FORMAT>フォーマット</FORMAT>
|
||||
<FORMAT_PROFILE>フォーマットプロファイル</FORMAT_PROFILE>
|
||||
<NAME>名称</NAME>
|
||||
</ja>
|
||||
<de>
|
||||
<TOTAL_SIZE>Gesamtgröße</TOTAL_SIZE>
|
||||
<FORMAT>Format</FORMAT>
|
||||
<FORMAT_PROFILE>Formatprofil</FORMAT_PROFILE>
|
||||
<NAME>Name</NAME>
|
||||
</de>
|
||||
</Translations>
|
@@ -1,4 +1,21 @@
|
||||
using System.Windows;
|
||||
// Copyright © 2017-2025 QL-Win Contributors
|
||||
//
|
||||
// This file is part of QuickLook program.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
|
@@ -53,6 +53,7 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "QuickLook.Installer", "Quic
|
||||
{538FD6BA-2AF1-4DDA-93A2-6C0A12B00843} = {538FD6BA-2AF1-4DDA-93A2-6C0A12B00843}
|
||||
{EB7D1F10-6E04-4F7E-96A0-4E18359FBD30} = {EB7D1F10-6E04-4F7E-96A0-4E18359FBD30}
|
||||
{88B6FFC8-AD86-41D9-B03D-BD83886CFC18} = {88B6FFC8-AD86-41D9-B03D-BD83886CFC18}
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064} = {63C00175-0FF3-42C7-8621-2F1959F26064}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuickLook.Native64", "QuickLook.Native\QuickLook.Native64\QuickLook.Native64.vcxproj", "{794E4DCF-F715-4836-9D30-ABD296586D23}"
|
||||
@@ -77,6 +78,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.AppViewer"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.OfficeViewer", "QuickLook.Plugin\QuickLook.Plugin.OfficeViewer\QuickLook.Plugin.OfficeViewer.csproj", "{88B6FFC8-AD86-41D9-B03D-BD83886CFC18}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.ELFViewer", "QuickLook.Plugin\QuickLook.Plugin.ELFViewer\QuickLook.Plugin.ELFViewer.csproj", "{63C00175-0FF3-42C7-8621-2F1959F26064}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -245,6 +248,14 @@ Global
|
||||
{88B6FFC8-AD86-41D9-B03D-BD83886CFC18}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{88B6FFC8-AD86-41D9-B03D-BD83886CFC18}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{88B6FFC8-AD86-41D9-B03D-BD83886CFC18}.Release|x64.Build.0 = Release|Any CPU
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -267,6 +278,7 @@ Global
|
||||
{538FD6BA-2AF1-4DDA-93A2-6C0A12B00843} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93}
|
||||
{EB7D1F10-6E04-4F7E-96A0-4E18359FBD30} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93}
|
||||
{88B6FFC8-AD86-41D9-B03D-BD83886CFC18} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93}
|
||||
{63C00175-0FF3-42C7-8621-2F1959F26064} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D3761C32-8C5F-498A-892B-3B0882994B62}
|
||||
|
Reference in New Issue
Block a user