diff --git a/BiosPatcher.sln b/BiosPatcher.sln
new file mode 100644
index 0000000..625a536
--- /dev/null
+++ b/BiosPatcher.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2042
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BiosPatcher", "BiosPatcher\BiosPatcher.csproj", "{F0D44547-57A0-4062-BD18-BD8CC8DF0D68}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F0D44547-57A0-4062-BD18-BD8CC8DF0D68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F0D44547-57A0-4062-BD18-BD8CC8DF0D68}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F0D44547-57A0-4062-BD18-BD8CC8DF0D68}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F0D44547-57A0-4062-BD18-BD8CC8DF0D68}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {80697FE6-200B-4059-B63D-FC0DB7AEB8A1}
+ EndGlobalSection
+EndGlobal
diff --git a/BiosPatcher/App.config b/BiosPatcher/App.config
new file mode 100644
index 0000000..b50c74f
--- /dev/null
+++ b/BiosPatcher/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BiosPatcher/App.xaml b/BiosPatcher/App.xaml
new file mode 100644
index 0000000..b75ec14
--- /dev/null
+++ b/BiosPatcher/App.xaml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/BiosPatcher/App.xaml.cs b/BiosPatcher/App.xaml.cs
new file mode 100644
index 0000000..582fdc2
--- /dev/null
+++ b/BiosPatcher/App.xaml.cs
@@ -0,0 +1,9 @@
+namespace BiosPatcher
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App
+ {
+ }
+}
diff --git a/BiosPatcher/BiosPatcher.csproj b/BiosPatcher/BiosPatcher.csproj
new file mode 100644
index 0000000..4891cbc
--- /dev/null
+++ b/BiosPatcher/BiosPatcher.csproj
@@ -0,0 +1,110 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {F0D44547-57A0-4062-BD18-BD8CC8DF0D68}
+ WinExe
+ BiosPatcher
+ BiosPatcher
+ v4.6.2
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\JetBrains.Annotations.2018.2.1\lib\net20\JetBrains.Annotations.dll
+
+
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+ ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.dll
+
+
+ ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll
+
+
+ ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll
+
+
+ ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll
+
+
+ ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.DataGrid.dll
+
+
+ ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.Toolkit.dll
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+
+
+
+
+
+
+
+ Patching.xaml
+
+
+
+
+ Code
+
+
+
+
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+
\ No newline at end of file
diff --git a/BiosPatcher/Models/BitConverterLE.cs b/BiosPatcher/Models/BitConverterLE.cs
new file mode 100644
index 0000000..8379a38
--- /dev/null
+++ b/BiosPatcher/Models/BitConverterLE.cs
@@ -0,0 +1,32 @@
+using System;
+using JetBrains.Annotations;
+
+namespace BiosPatcher.Models
+{
+ public static class BitConverterLittleEndian
+ {
+ public static int ReadInt([NotNull] byte[] bytes, int offset)
+ {
+ var data = new byte[4];
+ Array.Copy(bytes, offset, data, 0, 4);
+
+ if (!BitConverter.IsLittleEndian)
+ {
+ Array.Reverse(data);
+ }
+
+ return BitConverter.ToInt32(data, 0);
+ }
+
+ public static void WriteInt(int value, [NotNull] byte[] bytes, int offset)
+ {
+ var data = BitConverter.GetBytes(value);
+ if (!BitConverter.IsLittleEndian)
+ {
+ Array.Reverse(data);
+ }
+
+ Array.Copy(data, 0, bytes, offset, data.Length);
+ }
+ }
+}
\ No newline at end of file
diff --git a/BiosPatcher/Models/CheckSumCalculator.cs b/BiosPatcher/Models/CheckSumCalculator.cs
new file mode 100644
index 0000000..efe59cf
--- /dev/null
+++ b/BiosPatcher/Models/CheckSumCalculator.cs
@@ -0,0 +1,18 @@
+using JetBrains.Annotations;
+
+namespace BiosPatcher.Models
+{
+ public static class CheckSumCalculator
+ {
+ public static int Calculate([NotNull] byte[] data, int from, int length)
+ {
+ int result = 0;
+ for (int i = from; i < length + from; ++i)
+ {
+ result += data[i];
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BiosPatcher/Models/DefaultValues.cs b/BiosPatcher/Models/DefaultValues.cs
new file mode 100644
index 0000000..1c8a95c
--- /dev/null
+++ b/BiosPatcher/Models/DefaultValues.cs
@@ -0,0 +1,13 @@
+using JetBrains.Annotations;
+
+namespace BiosPatcher.Models
+{
+ public static class DefaultValues
+ {
+ [NotNull]
+ public static readonly int[] OffLevels = {38, 43, 47, 53, 59};
+
+ [NotNull]
+ public static readonly int[] OnLevels = {42, 46, 52, 58, 64};
+ }
+}
\ No newline at end of file
diff --git a/BiosPatcher/Models/PatchingModel.cs b/BiosPatcher/Models/PatchingModel.cs
new file mode 100644
index 0000000..32cbbc9
--- /dev/null
+++ b/BiosPatcher/Models/PatchingModel.cs
@@ -0,0 +1,243 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using JetBrains.Annotations;
+
+namespace BiosPatcher.Models
+{
+ public sealed class PatchingModel
+ {
+ private const int FirstTableOffset = 0x155AF;
+ private const int SecondTableOffset = 0x155C7;
+ private const int DataLengthOffset = 0x18;
+ private const int CheckSumOffset = 0x44;
+ private const int HeaderLength = 0x100;
+ private const int ChecksumDivider = 0x40;
+ private const int CopyrightOffset = 0x564;
+
+ //Copyright 1996-1999, all rights reserved Insyde Software Corp.
+ private static readonly byte[] CopyrightString =
+ {
+ 0x43, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31, 0x39,
+ 0x39, 0x36, 0x2D, 0x31, 0x39, 0x39, 0x39, 0x2C, 0x20, 0x61, 0x6C, 0x6C,
+ 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65,
+ 0x72, 0x76, 0x65, 0x64, 0x0A, 0x0D, 0x49, 0x6E, 0x73, 0x79, 0x64, 0x65,
+ 0x20, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x43, 0x6F,
+ 0x72, 0x70, 0x2E, 0x00
+ };
+
+ static PatchingModel()
+ {
+ Debug.Assert(SecondTableOffset > FirstTableOffset);
+ Debug.Assert(FirstTableOffset > HeaderLength);
+ Debug.Assert(CheckSumOffset + 4 < HeaderLength);
+ Debug.Assert(DataLengthOffset + 4 < HeaderLength);
+ }
+
+ [NotNull]
+ private const string FileSignatureDiffersFromSupportedBios = "File signature differs from supported bios";
+
+ [CanBeNull]
+ private byte[] _image;
+
+ [CanBeNull]
+ private string _outFileName;
+
+ [NotNull]
+ public int[] OffLevels { get; } = new int[5];
+
+ [NotNull]
+ public int[] OnLevels { get; } = new int[5];
+
+ [NotNull]
+ public string LastError { get; private set; } = string.Empty;
+
+ private int _currentFirstTableOffset = FirstTableOffset;
+ private int _currentSecondTableOffset = SecondTableOffset;
+ private bool _inputCorrect;
+
+ public PatchingModel()
+ {
+ Array.Copy(DefaultValues.OffLevels, OffLevels, 5);
+ Array.Copy(DefaultValues.OnLevels, OnLevels, 5);
+ CheckInputCorrect();
+ }
+
+ public int CustomOffset
+ {
+ get { return _currentFirstTableOffset; }
+ set
+ {
+ _currentFirstTableOffset = value;
+ _currentSecondTableOffset = value + (SecondTableOffset - FirstTableOffset);
+ _inputCorrect = CheckInputCorrect();
+ }
+ }
+
+ public void SetInputFilePath([NotNull] string filename)
+ {
+ _image = null;
+ if (File.Exists(filename))
+ {
+ _image = File.ReadAllBytes(filename);
+ }
+
+ _inputCorrect = CheckInputCorrect();
+ }
+
+ public void SetOutputFilePath([NotNull] string filename)
+ {
+ _outFileName = filename;
+ }
+
+ public bool CheckCorrect()
+ {
+ if (!_inputCorrect)
+ {
+ return false;
+ }
+
+ if (string.IsNullOrEmpty(_outFileName))
+ {
+ LastError = "Output path is not specified";
+ return false;
+ }
+
+ for (int i = 0; i < 5; ++i)
+ {
+ if (OffLevels[i] >= OnLevels[i])
+ {
+ LastError = $"Level {i + 1} activate threshold is not bigger than deactivate";
+ return false;
+ }
+ }
+
+ for (int i = 1; i < 5; ++i)
+ {
+ if (OffLevels[i] <= OnLevels[i - 1])
+ {
+ LastError = $"Level {i} deactivate threshold is not bigger than level {i - 1} activate threshold";
+ return false;
+ }
+ }
+
+ LastError = string.Empty;
+ return true;
+ }
+
+ public string Patch()
+ {
+ if (!CheckCorrect())
+ {
+ return "Invalid settings!";
+ }
+
+ // ReSharper disable once PossibleNullReferenceException
+ var newImage = new byte[_image.Length];
+ Array.Copy(_image, newImage, newImage.Length);
+
+
+ for (int i = 0; i < 10; ++i)
+ {
+ var currentArray = i % 2 == 0 ? OnLevels : OffLevels;
+ var newValue = currentArray[i / 2];
+
+ newImage[_currentFirstTableOffset + i] = (byte) newValue;
+ newImage[_currentSecondTableOffset + i] = (byte) newValue;
+ }
+
+ var dataLength = 2 * BitConverterLittleEndian.ReadInt(newImage, DataLengthOffset);
+ var checksum = CheckSumCalculator.Calculate(newImage, HeaderLength, dataLength);
+
+ var modulo = checksum % ChecksumDivider;
+ if (modulo != 0)
+ {
+ newImage[CopyrightOffset + CopyrightString.Length - 2] = 0;
+ newImage[CopyrightOffset + CopyrightString.Length - 1] =
+ (byte) (CopyrightString[CopyrightString.Length - 2] + ChecksumDivider - modulo);
+ }
+
+ var correctedChecksum = CheckSumCalculator.Calculate(newImage, HeaderLength, dataLength);
+ if (correctedChecksum % ChecksumDivider != 0)
+ {
+ return "Internal error";
+ }
+
+ BitConverterLittleEndian.WriteInt(correctedChecksum, newImage, CheckSumOffset);
+
+ // ReSharper disable once AssignNullToNotNullAttribute
+ try
+ {
+ File.WriteAllBytes(_outFileName, newImage);
+ }
+ catch (Exception e)
+ {
+ return $"Unable to write patched image: {e}";
+ }
+
+ return "Image patched successfully";
+ }
+
+ private bool CheckInputCorrect()
+ {
+ if (_image is null)
+ {
+ LastError = "Can't read input file";
+ return false;
+ }
+
+ if (_image.Length < _currentSecondTableOffset + 10)
+ {
+ LastError = "File length is smaller than offset to fan speed tables";
+ return false;
+ }
+
+ var dataLength = 2 * BitConverterLittleEndian.ReadInt(_image, DataLengthOffset);
+ if (_image.Length < dataLength + HeaderLength)
+ {
+ LastError = FileSignatureDiffersFromSupportedBios;
+ return false;
+ }
+
+ var actualChecksum = CheckSumCalculator.Calculate(_image, HeaderLength, dataLength);
+ var writtenChecksum = BitConverterLittleEndian.ReadInt(_image, CheckSumOffset);
+
+ if (actualChecksum != writtenChecksum || actualChecksum % ChecksumDivider != 0)
+ {
+ LastError = FileSignatureDiffersFromSupportedBios;
+ return false;
+ }
+
+ if (_image.Length < CopyrightString.Length + CopyrightOffset)
+ {
+ LastError = FileSignatureDiffersFromSupportedBios;
+ return false;
+ }
+
+ for (int i = 0; i < CopyrightString.Length; ++i)
+ {
+ if (_image[CopyrightOffset + i] != CopyrightString[i])
+ {
+ LastError = (i == CopyrightString.Length - 2 && _image[CopyrightOffset + i] == 0) ?
+ "Image was patched" :
+ FileSignatureDiffersFromSupportedBios;
+ return false;
+ }
+ }
+
+ for (int i = 0; i < 10; ++i)
+ {
+ var currentArray = i % 2 == 0 ? DefaultValues.OnLevels : DefaultValues.OffLevels;
+ var defaultValue = currentArray[i / 2];
+ if (_image[_currentFirstTableOffset + i] != defaultValue ||
+ _image[_currentSecondTableOffset + i] != defaultValue)
+ {
+ LastError = "Speed tables have incorrect values (image was patched or offset is incorrect)";
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BiosPatcher/Properties/AssemblyInfo.cs b/BiosPatcher/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..38f5ac1
--- /dev/null
+++ b/BiosPatcher/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// 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("BiosPatcher")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BiosPatcher")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[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)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+
+// 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.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BiosPatcher/ViewModels/PatchingViewModel.cs b/BiosPatcher/ViewModels/PatchingViewModel.cs
new file mode 100644
index 0000000..3a5acdd
--- /dev/null
+++ b/BiosPatcher/ViewModels/PatchingViewModel.cs
@@ -0,0 +1,206 @@
+using System.ComponentModel;
+using System.IO;
+using System.Runtime.CompilerServices;
+using BiosPatcher.Models;
+using JetBrains.Annotations;
+
+namespace BiosPatcher.ViewModels
+{
+ public sealed class PatchingViewModel : INotifyPropertyChanged
+ {
+ [NotNull]
+ private readonly PatchingModel _model;
+
+ [NotNull]
+ private string _inputFileName = string.Empty;
+
+ [NotNull]
+ private string _outputFileName = string.Empty;
+
+ private bool _isAutoSettingOut = true;
+
+ public PatchingViewModel()
+ {
+ _model = new PatchingModel();
+ }
+
+ [NotNull]
+ public string InputFileName
+ {
+ get { return _inputFileName; }
+ set
+ {
+ _inputFileName = value;
+ _model.SetInputFilePath(value);
+ OnPropertyChanged();
+
+ if (_isAutoSettingOut)
+ {
+ AutoSetOutput();
+ }
+ }
+ }
+
+ [NotNull]
+ public string OutputFileName
+ {
+ get { return _outputFileName; }
+ set
+ {
+ _isAutoSettingOut = false;
+ _outputFileName = value;
+ _model.SetOutputFilePath(value);
+ OnPropertyChanged();
+ }
+ }
+
+ public bool InputCorrect
+ {
+ get { return _model.CheckCorrect(); }
+ }
+
+ [NotNull]
+ public string ErrorMessage
+ {
+ get { return _model.LastError; }
+ }
+
+ public int CustomTablesOffset
+ {
+ get { return _model.CustomOffset; }
+ set
+ {
+ _model.CustomOffset = value;
+ OnPropertyChanged();
+ }
+ }
+
+ #region LevelsData
+
+ public int Level1Off
+ {
+ get { return _model.OffLevels[0]; }
+ set
+ {
+ _model.OffLevels[0] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level1On
+ {
+ get { return _model.OnLevels[0]; }
+ set
+ {
+ _model.OnLevels[0] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level2Off
+ {
+ get { return _model.OffLevels[1]; }
+ set
+ {
+ _model.OffLevels[1] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level2On
+ {
+ get { return _model.OnLevels[1]; }
+ set
+ {
+ _model.OnLevels[1] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level3Off
+ {
+ get { return _model.OffLevels[2]; }
+ set
+ {
+ _model.OffLevels[2] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level3On
+ {
+ get { return _model.OnLevels[2]; }
+ set
+ {
+ _model.OnLevels[2] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level4Off
+ {
+ get { return _model.OffLevels[3]; }
+ set
+ {
+ _model.OffLevels[3] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level4On
+ {
+ get { return _model.OnLevels[3]; }
+ set
+ {
+ _model.OnLevels[3] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level5Off
+ {
+ get { return _model.OffLevels[4]; }
+ set
+ {
+ _model.OffLevels[4] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public int Level5On
+ {
+ get { return _model.OnLevels[4]; }
+ set
+ {
+ _model.OnLevels[4] = value;
+ OnPropertyChanged();
+ }
+ }
+
+ #endregion
+
+ public string Patch()
+ {
+ return _model.Patch();
+ }
+
+ private void AutoSetOutput()
+ {
+ var extension = Path.GetExtension(_inputFileName);
+ _outputFileName =
+ $"{_inputFileName.Substring(0, _inputFileName.Length - extension.Length)}-patched{extension}";
+ _model.SetOutputFilePath(_outputFileName);
+ OnPropertyChanged(nameof(OutputFileName));
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ [NotifyPropertyChangedInvocator]
+ private void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(InputCorrect)));
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ErrorMessage)));
+ }
+ }
+}
\ No newline at end of file
diff --git a/BiosPatcher/Views/BooleanHidingConverter.cs b/BiosPatcher/Views/BooleanHidingConverter.cs
new file mode 100644
index 0000000..dc26503
--- /dev/null
+++ b/BiosPatcher/Views/BooleanHidingConverter.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace BiosPatcher.Views
+{
+ public class BooleanHidingConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ bool result = false;
+ if (value is bool b)
+ {
+ result = b;
+ }
+
+ return result ? Visibility.Visible : Visibility.Hidden;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is Visibility visibility)
+ return visibility == Visibility.Visible;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BiosPatcher/Views/InverseBooleanToVisibilityConverter.cs b/BiosPatcher/Views/InverseBooleanToVisibilityConverter.cs
new file mode 100644
index 0000000..abdff44
--- /dev/null
+++ b/BiosPatcher/Views/InverseBooleanToVisibilityConverter.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace BiosPatcher.Views
+{
+ public class InverseBooleanToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ bool result = false;
+ if (value is bool b)
+ {
+ result = b;
+ }
+
+ return result ? Visibility.Collapsed : Visibility.Visible;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is Visibility visibility)
+ return visibility != Visibility.Visible;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BiosPatcher/Views/Patching.xaml b/BiosPatcher/Views/Patching.xaml
new file mode 100644
index 0000000..0a7e33b
--- /dev/null
+++ b/BiosPatcher/Views/Patching.xaml
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BiosPatcher/Views/Patching.xaml.cs b/BiosPatcher/Views/Patching.xaml.cs
new file mode 100644
index 0000000..dafb23b
--- /dev/null
+++ b/BiosPatcher/Views/Patching.xaml.cs
@@ -0,0 +1,41 @@
+using System.Windows;
+using BiosPatcher.ViewModels;
+using Microsoft.Win32;
+
+namespace BiosPatcher.Views
+{
+ ///
+ /// Interaction logic for Patching.xaml
+ ///
+ public partial class Patching
+ {
+ public Patching()
+ {
+ InitializeComponent();
+ }
+
+ private void SelectInputFileName(object sender, RoutedEventArgs e)
+ {
+ var openFileDialog = new OpenFileDialog();
+ if (openFileDialog.ShowDialog() == true)
+ {
+ InputFileName.Text = openFileDialog.FileName;
+ }
+ }
+
+ private void SelectOutputFileName(object sender, RoutedEventArgs e)
+ {
+ var openFileDialog = new OpenFileDialog();
+ if (openFileDialog.ShowDialog() == true)
+ {
+ OutputFileName.Text = openFileDialog.FileName;
+ }
+ }
+
+ private void PatchClicked(object sender, RoutedEventArgs e)
+ {
+ var result = ((PatchingViewModel)DataContext).Patch();
+ MessageBox.Show(result);
+ }
+ }
+}
diff --git a/BiosPatcher/packages.config b/BiosPatcher/packages.config
new file mode 100644
index 0000000..8f4aa68
--- /dev/null
+++ b/BiosPatcher/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file