This commit is contained in:
Andrey Smirnoff 2021-04-25 22:28:39 +05:00
parent 69999e06ec
commit 79552c2097
11 changed files with 119 additions and 83 deletions

View file

@ -11,17 +11,16 @@ namespace PotatoNV_next.Controls
public AboutTab() public AboutTab()
{ {
InitializeComponent(); InitializeComponent();
version.Text = string.Format(version.Text, GetVersion(3)); var versionTag = $"v{Common.GetAssemblyVersion(typeof(MainWindow).Assembly)}\n[" +
fireLogo.Source = MediaConverter.ImageSourceFromBitmap(Properties.Resources.Fire.ToBitmap()); string.Join(", ", new (string AssemblyName, string Tag)[] {
} ("Potato.Fastboot", "FB"),
("Potato.ImageFlasher", "IF"),
("LibUsbDotNet.LibUsbDotNet", "LD"),
("libusb-1.0", "LU"),
}.Select(x => $"{x.Tag} v{Common.GetAssemblyVersion($"{x.AssemblyName}.dll") ?? "??"}").ToArray()) + "]";
public static string GetVersion(int depth = 3) version.Text = versionTag;
{ fireLogo.Source = MediaConverter.ImageSourceFromBitmap(Properties.Resources.Fire.ToBitmap());
return string.Join(".",
typeof(MainWindow).Assembly.GetName().Version
.ToString()
.Split('.')
.Take(depth));
} }
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)

View file

@ -1,10 +1,6 @@
<UserControl x:Class="PotatoNV_next.Controls.LogBox" <UserControl x:Class="PotatoNV_next.Controls.LogBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Margin="4"> <Grid Margin="4">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
@ -13,9 +9,10 @@
<TextBox x:Name="logBox" <TextBox x:Name="logBox"
Grid.Row="0" Grid.Row="0"
Margin="0,5" Margin="0"
IsReadOnlyCaretVisible="True" IsReadOnlyCaretVisible="True"
IsReadOnly="True" /> IsReadOnly="True"
ScrollViewer.VerticalScrollBarVisibility="Visible" />
<ProgressBar x:Name="progressBar" Grid.Row="1" /> <ProgressBar x:Name="progressBar" Grid.Row="1" />
</Grid> </Grid>
</UserControl> </UserControl>

View file

@ -37,7 +37,11 @@ namespace PotatoNV_next.Controls
Dispatcher.Invoke(() => logBox.AppendText(e.Message)); Dispatcher.Invoke(() => logBox.AppendText(e.Message));
return; return;
} }
logBox.AppendText(e.Message); logBox.AppendText(e.Message);
logBox.Focus();
logBox.CaretIndex = logBox.Text.Length;
logBox.ScrollToEnd();
} }
private void OnProgress(Log.ProgressEventArgs progressEventArgs) private void OnProgress(Log.ProgressEventArgs progressEventArgs)

View file

@ -4,7 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" IsEnabledChanged="NVForm_IsEnabledChanged"> IsEnabledChanged="NVForm_IsEnabledChanged">
<StackPanel Style="{x:Null}"> <StackPanel Style="{x:Null}">
<StackPanel> <StackPanel>
<Label Content="Target device" /> <Label Content="Target device" />
@ -15,11 +15,8 @@
<ComboBox Name="deviceBootloader" /> <ComboBox Name="deviceBootloader" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<Label Content="Unlock code" /> <CheckBox x:Name="disableFBLOCK" Content="Disable FBLOCK (not recommended)" IsChecked="False" />
<TextBox x:Name="nvUnlockCode" /> <CheckBox x:Name="reboot" Content="Reboot after unlock" IsChecked="True" />
</StackPanel>
<StackPanel>
<CheckBox x:Name="disableFBLOCK" Content="Disable FBLOCK" IsChecked="True" />
<Button x:Name="startButton" Content="Start!" Height="40" Margin="0,10,0,0" Click="StartButton_Click" /> <Button x:Name="startButton" Content="Start!" Height="40" Margin="0,10,0,0" Click="StartButton_Click" />
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>

View file

@ -37,11 +37,6 @@ namespace PotatoNV_next.Controls
{ {
deviceBootloader.SelectedIndex = 0; deviceBootloader.SelectedIndex = 0;
} }
var random = new Random(Guid.NewGuid().GetHashCode());
nvUnlockCode.Text = new string(Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 16)
.Select(s => s[random.Next(s.Length)]).ToArray());
} }
public class FormEventArgs : EventArgs public class FormEventArgs : EventArgs
@ -50,6 +45,7 @@ namespace PotatoNV_next.Controls
public string Target { get; set; } public string Target { get; set; }
public string UnlockCode { get; set; } public string UnlockCode { get; set; }
public bool DisableFBLOCK { get; set; } public bool DisableFBLOCK { get; set; }
public bool Reboot { get; set; }
public Bootloader Bootloader { get; set; } = null; public Bootloader Bootloader { get; set; } = null;
} }
@ -110,8 +106,6 @@ namespace PotatoNV_next.Controls
"Check connection and required drivers."); "Check connection and required drivers.");
Assert(deviceBootloader.SelectedIndex != -1, "Couldn't find any valid bootloader!"); Assert(deviceBootloader.SelectedIndex != -1, "Couldn't find any valid bootloader!");
Assert(VerifyNVValue(nvUnlockCode.Text, true), "Unlock code is not valid.");
} }
catch catch
{ {
@ -126,8 +120,8 @@ namespace PotatoNV_next.Controls
? UsbController.Device.DMode.Fastboot ? UsbController.Device.DMode.Fastboot
: UsbController.Device.DMode.DownloadVCOM, : UsbController.Device.DMode.DownloadVCOM,
Target = deviceList.SelectedItem.ToString(), Target = deviceList.SelectedItem.ToString(),
UnlockCode = nvUnlockCode.Text, DisableFBLOCK = disableFBLOCK.IsChecked.Value,
DisableFBLOCK = disableFBLOCK.IsChecked.Value Reboot = reboot.IsChecked.Value
}; };
if (!IsSelectedDeviceInFastbootMode) if (!IsSelectedDeviceInFastbootMode)
@ -142,7 +136,6 @@ namespace PotatoNV_next.Controls
{ {
deviceList.IsEnabled = IsEnabled; deviceList.IsEnabled = IsEnabled;
deviceBootloader.IsEnabled = IsEnabled; deviceBootloader.IsEnabled = IsEnabled;
nvUnlockCode.IsEnabled = IsEnabled;
disableFBLOCK.IsEnabled = IsEnabled; disableFBLOCK.IsEnabled = IsEnabled;
startButton.IsEnabled = IsEnabled; startButton.IsEnabled = IsEnabled;
} }

View file

@ -4,6 +4,7 @@ using PotatoNV_next.Utils;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -82,17 +83,28 @@ namespace PotatoNV_next
var build = fb.Command("oem get-build-number"); var build = fb.Command("oem get-build-number");
Log.Info($"Build number: {build.Payload.Replace(":", "")}"); Log.Info($"Build number: {build.Payload.Replace(":", "")}");
var regex = new Regex(@"FB[\w: ]{1,}UNLOCKED");
var fblock = fb.Command("oem lock-state info"); var fblock = fb.Command("oem lock-state info");
var state = regex.IsMatch(fblock.Payload); var state = Regex.IsMatch(fblock.Payload, @"FB[\w: ]{1,}UNLOCKED");
Log.Info($"FBLOCK state: {(state ? "unlocked" : "locked")}"); Log.Info($"FBLOCK state: {(state ? "unlocked" : "locked")}");
LogResponse(fblock); LogResponse(fblock);
if (!state) if (!state)
{ {
Log.Error("*** FBLOCK is locked! ***"); throw new Exception("*** FBLOCK is locked! ***");
} }
var factoryKey = ReadFactoryKey();
if (factoryKey != null)
{
Log.Info($"Unlock key: {factoryKey}");
}
var random = new Random(Guid.NewGuid().GetHashCode());
args.UnlockCode = factoryKey ?? new string(Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 16)
.Select(s => s[random.Next(s.Length)]).ToArray());
} }
private void SetNVMEProp(string prop, byte[] value) private void SetNVMEProp(string prop, byte[] value)
@ -122,7 +134,7 @@ namespace PotatoNV_next
} }
} }
private void SetHWDogCertify(byte state) private void SetHWDogState(byte state)
{ {
foreach (var command in new[] { "hwdog certify set", "backdoor set" }) foreach (var command in new[] { "hwdog certify set", "backdoor set" })
{ {
@ -139,24 +151,12 @@ namespace PotatoNV_next
Log.Error("Failed to set FBLOCK state!"); Log.Error("Failed to set FBLOCK state!");
} }
private void WidevineLock() private string ReadFactoryKey()
{ {
Log.Debug("WV Lock");
var res = fb.Command("getvar:nve:WVLOCK"); var res = fb.Command("getvar:nve:WVLOCK");
LogResponse(res); var match = Regex.Match(res.Payload, @"\w{16}");
if (res.Status != Fastboot.Status.Fail && res.Payload.Replace("\n", "").Trim() != "UUUUUUUUUUUUUUUU")
{
Log.Info($"Read factory key: {res.Payload}");
}
try return match.Success ? match.Value : null;
{
SetNVMEProp("WVLOCK", Encoding.ASCII.GetBytes(args.UnlockCode));
}
catch
{
Log.Error("Failed to set the WVLOCK.");
}
} }
private void WriteNVME() private void WriteNVME()
@ -171,13 +171,13 @@ namespace PotatoNV_next
{ {
Log.Error("Failed to set the FBLOCK, using the alternative method..."); Log.Error("Failed to set the FBLOCK, using the alternative method...");
Log.Debug(ex.Message); Log.Debug(ex.Message);
SetHWDogCertify(fblockState); SetHWDogState(fblockState);
} }
try try
{ {
SetNVMEProp("WVLOCK", Encoding.ASCII.GetBytes(args.UnlockCode));
SetNVMEProp("USRKEY", GetSHA256(args.UnlockCode)); SetNVMEProp("USRKEY", GetSHA256(args.UnlockCode));
WidevineLock();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -207,11 +207,16 @@ namespace PotatoNV_next
ReadInfo(); ReadInfo();
WriteNVME(); WriteNVME();
Log.Info("Rebooting..."); Log.Info("Finalizing...");
LogResponse(fb.Command($"oem unlock {args.UnlockCode}"));
fb.Command("reboot"); if (args.Reboot)
{
Log.Info("Rebooting...");
fb.Command("reboot");
}
Log.Info($"New bootloader unlock code: {args.UnlockCode}"); Log.Info($"Bootloader unlock code: {args.UnlockCode}");
fb.Disconnect(); fb.Disconnect();
} }
@ -220,10 +225,6 @@ namespace PotatoNV_next
Log.Error(ex.Message); Log.Error(ex.Message);
Log.Debug(ex.StackTrace); Log.Debug(ex.StackTrace);
} }
finally
{
fb.Disconnect();
}
} }
public void StartProcess(Controls.NVForm.FormEventArgs args) public void StartProcess(Controls.NVForm.FormEventArgs args)

View file

@ -6,36 +6,47 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="PotatoNV" Title="PotatoNV"
Width="720" Width="450"
Height="416" Height="500"
ResizeMode="NoResize" ResizeMode="NoResize"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
mc:Ignorable="d"> mc:Ignorable="d">
<Window.Resources> <Window.Resources>
<Style TargetType="StackPanel"> <Style TargetType="CheckBox">
<Setter Property="Margin" Value="4" /> <Setter Property="Margin" Value="3,6,0,0" />
</Style> </Style>
<Style TargetType="TextBox"> <Style TargetType="ProgressBar">
<Setter Property="MaxLength" Value="16" /> <Setter Property="Margin" Value="0,3,0,0" />
</Style> </Style>
<Style TargetType="TextBlock"> <Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" /> <Setter Property="TextAlignment" Value="Center" />
<Setter Property="Padding" Value="2" /> <Setter Property="Padding" Value="2" />
</Style> </Style>
<Style TargetType="TextBox">
<Setter Property="FontFamily" Value="Consolas" />
</Style>
</Window.Resources> </Window.Resources>
<UniformGrid Columns="2"> <TabControl Grid.Row="0" Margin="4">
<TabControl Margin="3"> <TabItem Header="Bootloader unlock">
<TabItem Header="NVME Update"> <Grid>
<controls:NVForm x:Name="nvFrom" /> <Grid.RowDefinitions>
</TabItem> <RowDefinition Height="Auto" />
<TabItem Header="About program"> <RowDefinition Height="*" />
<controls:AboutTab /> </Grid.RowDefinitions>
</TabItem>
</TabControl> <controls:NVForm x:Name="nvFrom" Margin="4" />
<controls:LogBox x:Name="logBox" /> <Grid Height="Auto" Grid.Row="1">
</UniformGrid> <controls:LogBox x:Name="logBox" Grid.Row="0" />
</Grid>
</Grid>
</TabItem>
<TabItem Header="About">
<controls:AboutTab />
</TabItem>
</TabControl>
</Window> </Window>

View file

@ -1,8 +1,11 @@
using Microsoft.Win32; using Microsoft.Win32;
using PotatoNV_next.Utils; using PotatoNV_next.Utils;
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Interop; using System.Windows.Interop;
@ -96,11 +99,11 @@ namespace PotatoNV_next
SetupLog(); SetupLog();
core.StartProcess(formEventArgs); core.StartProcess(formEventArgs);
} }
public void SetupLog() public void SetupLog()
{ {
logBox.Clear(); logBox.Clear();
Log.Info($"PotatoNV v{Controls.AboutTab.GetVersion()}"); Log.Info($"PotatoNV v{Common.GetAssemblyVersion(typeof(MainWindow).Assembly)}");
Log.Info("User manual: https://kutt.it/pnv-" Log.Info("User manual: https://kutt.it/pnv-"
+ (CultureInfo.InstalledUICulture.TwoLetterISOLanguageName == "ru" + (CultureInfo.InstalledUICulture.TwoLetterISOLanguageName == "ru"
? "ru" ? "ru"

View file

@ -116,6 +116,7 @@
</Compile> </Compile>
<Compile Include="Core.cs" /> <Compile Include="Core.cs" />
<Compile Include="Utils\Bootloader.cs" /> <Compile Include="Utils\Bootloader.cs" />
<Compile Include="Utils\Common.cs" />
<Compile Include="Utils\Log.cs" /> <Compile Include="Utils\Log.cs" />
<Compile Include="Utils\MediaConverter.cs" /> <Compile Include="Utils\MediaConverter.cs" />
<Compile Include="Utils\UsbController.cs" /> <Compile Include="Utils\UsbController.cs" />

View file

@ -20,5 +20,5 @@ using System.Windows;
ResourceDictionaryLocation.SourceAssembly ResourceDictionaryLocation.SourceAssembly
)] )]
[assembly: AssemblyVersion("2.1.0.0")] [assembly: AssemblyVersion("2.2.0.0")]
[assembly: AssemblyFileVersion("2.1.0.0")] [assembly: AssemblyFileVersion("2.2.0.0")]

View file

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace PotatoNV_next.Utils
{
class Common
{
public static string GetAssemblyVersion(Assembly assembly)
{
return assembly.GetName().Version.ToString(3);
}
public static string GetAssemblyVersion(string name)
{
try
{
return FileVersionInfo.GetVersionInfo(name).FileVersion;
}
catch
{
return null;
}
}
}
}