mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-06-14 03:16:40 +10:00
Some cleanup
This commit is contained in:
@@ -22,6 +22,8 @@ using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Config;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -26,6 +26,13 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WPinternals.Config;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.MSR;
|
||||
using WPinternals.Models.Lumia.NCSd;
|
||||
using WPinternals.Models.UEFIApps.BootMgr;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
using WPinternals.Models.UEFIApps.PhoneInfo;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -86,7 +93,7 @@ namespace WPinternals
|
||||
LumiaFlashAppModel FlashModel;
|
||||
LumiaBootManagerAppModel BootMgrModel;
|
||||
LumiaPhoneInfoAppModel PhoneInfoModel;
|
||||
NokiaPhoneModel NormalModel;
|
||||
NokiaCareSuiteModel NormalModel;
|
||||
LumiaFlashAppPhoneInfo FlashInfo;
|
||||
LumiaPhoneInfoAppPhoneInfo PhoneInfo;
|
||||
LumiaBootManagerPhoneInfo BootManagerInfo;
|
||||
@@ -244,7 +251,7 @@ namespace WPinternals
|
||||
LogFile.BeginAction("ConvertGPT");
|
||||
try
|
||||
{
|
||||
using var stream = File.OpenRead(args[2]);
|
||||
using FileStream stream = File.OpenRead(args[2]);
|
||||
byte[] GPTBuffer = new byte[34 * 0x200];
|
||||
stream.Read(GPTBuffer, 0, 34 * 0x200);
|
||||
GPT GPT = new(GPTBuffer);// May throw NotSupportedException
|
||||
@@ -1273,7 +1280,7 @@ namespace WPinternals
|
||||
UIContext.Send(s => Notifier.Start(), null);
|
||||
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Normal)
|
||||
{
|
||||
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
||||
NormalModel = (NokiaCareSuiteModel)Notifier.CurrentModel;
|
||||
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
|
||||
}
|
||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||
@@ -1328,7 +1335,7 @@ namespace WPinternals
|
||||
}
|
||||
else
|
||||
{
|
||||
NormalModel = (NokiaPhoneModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal);
|
||||
NormalModel = (NokiaCareSuiteModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal);
|
||||
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
|
||||
}
|
||||
URL = LumiaDownloadModel.SearchFFU(null, ProductCode, null, out ProductType);
|
||||
@@ -1478,7 +1485,7 @@ namespace WPinternals
|
||||
UIContext.Send(s => Notifier.Start(), null);
|
||||
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Normal)
|
||||
{
|
||||
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
||||
NormalModel = (NokiaCareSuiteModel)Notifier.CurrentModel;
|
||||
ProductType = NormalModel.ExecuteJsonMethodAsString("ReadManufacturerModelName", "ManufacturerModelName");
|
||||
if (ProductType.Contains('_'))
|
||||
{
|
||||
@@ -1501,7 +1508,7 @@ namespace WPinternals
|
||||
}
|
||||
else
|
||||
{
|
||||
NormalModel = (NokiaPhoneModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal);
|
||||
NormalModel = (NokiaCareSuiteModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal);
|
||||
ProductType = NormalModel.ExecuteJsonMethodAsString("ReadManufacturerModelName", "ManufacturerModelName");
|
||||
if (ProductType.Contains('_'))
|
||||
{
|
||||
@@ -1601,7 +1608,7 @@ namespace WPinternals
|
||||
UIContext.Send(s => Notifier.Start(), null);
|
||||
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Normal)
|
||||
{
|
||||
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
||||
NormalModel = (NokiaCareSuiteModel)Notifier.CurrentModel;
|
||||
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
|
||||
}
|
||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||
@@ -1620,7 +1627,7 @@ namespace WPinternals
|
||||
}
|
||||
else
|
||||
{
|
||||
NormalModel = (NokiaPhoneModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal);
|
||||
NormalModel = (NokiaCareSuiteModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal);
|
||||
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
|
||||
}
|
||||
URL = LumiaDownloadModel.SearchFFU(null, ProductCode, null, out ProductType);
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals.Config
|
||||
{
|
||||
public class EmergencyFileEntry
|
||||
{
|
||||
public string Type;
|
||||
|
||||
[XmlIgnore]
|
||||
public byte[] RKH;
|
||||
[XmlElement(ElementName = "RKH")]
|
||||
public string RKHAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
return RKH == null ? null : Converter.ConvertHexToString(RKH, "");
|
||||
}
|
||||
set
|
||||
{
|
||||
RKH = value == null ? null : Converter.ConvertStringToHex(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string ProgrammerPath;
|
||||
public string PayloadPath;
|
||||
|
||||
internal bool ProgrammerExists()
|
||||
{
|
||||
return File.Exists(ProgrammerPath);
|
||||
}
|
||||
|
||||
internal bool PayloadExists()
|
||||
{
|
||||
return File.Exists(PayloadPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,23 +18,20 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace WPinternals
|
||||
using System.IO;
|
||||
|
||||
namespace WPinternals.Config
|
||||
{
|
||||
internal class CommonPhoneInfo
|
||||
public class FFUEntry
|
||||
{
|
||||
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||
public string PlatformID;
|
||||
public string FirmwareVersion;
|
||||
public string OSVersion;
|
||||
public string Path;
|
||||
|
||||
public FlashAppType App;
|
||||
|
||||
public byte VersionMajor;
|
||||
public byte VersionMinor;
|
||||
public byte ProtocolVersionMajor;
|
||||
public byte ProtocolVersionMinor;
|
||||
|
||||
internal void Log(LogType Type)
|
||||
internal bool Exists()
|
||||
{
|
||||
LogFile.Log($"App: {VersionMajor}.{VersionMinor}", Type);
|
||||
LogFile.Log($"Protocol: {ProtocolVersionMajor}.{ProtocolVersionMinor}", Type);
|
||||
return File.Exists(Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace WPinternals.Config
|
||||
{
|
||||
public class FlashProfile
|
||||
{
|
||||
public string Type;
|
||||
public string PlatformID;
|
||||
public string ProductCode;
|
||||
public string PhoneFirmware;
|
||||
public string FfuFirmware;
|
||||
|
||||
[XmlIgnore]
|
||||
internal uint FillSize;
|
||||
[XmlIgnore]
|
||||
internal uint HeaderSize;
|
||||
[XmlIgnore]
|
||||
internal bool AssumeImageHeaderFallsInGap;
|
||||
[XmlIgnore]
|
||||
internal bool AllocateAsyncBuffersOnPhone;
|
||||
|
||||
[XmlElement(ElementName = "Profile")]
|
||||
public string ProfileAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] ValueBuffer = new byte[10];
|
||||
ValueBuffer[0] = 1; // Profile version
|
||||
ByteOperations.WriteUInt32(ValueBuffer, 1, FillSize);
|
||||
ByteOperations.WriteUInt32(ValueBuffer, 5, HeaderSize);
|
||||
if (AssumeImageHeaderFallsInGap)
|
||||
{
|
||||
ValueBuffer[9] |= 1;
|
||||
}
|
||||
|
||||
if (AllocateAsyncBuffersOnPhone)
|
||||
{
|
||||
ValueBuffer[9] |= 2;
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(ValueBuffer);
|
||||
}
|
||||
set
|
||||
{
|
||||
byte[] ValueBuffer = Convert.FromBase64String(value);
|
||||
byte Version = ValueBuffer[0];
|
||||
FillSize = ByteOperations.ReadUInt32(ValueBuffer, 1);
|
||||
HeaderSize = ByteOperations.ReadUInt32(ValueBuffer, 5);
|
||||
AssumeImageHeaderFallsInGap = (ValueBuffer[9] & 1) != 0;
|
||||
AllocateAsyncBuffersOnPhone = (ValueBuffer[9] & 2) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Windows;
|
||||
|
||||
namespace WPinternals.Config
|
||||
{
|
||||
internal static class Registration
|
||||
{
|
||||
#if PREVIEW
|
||||
internal const bool IsPrerelease = true;
|
||||
#else
|
||||
internal const bool IsPrerelease = false;
|
||||
#endif
|
||||
|
||||
internal static readonly DateTime ExpirationDate = new(2024, 12, 21);
|
||||
|
||||
internal static void CheckExpiration()
|
||||
{
|
||||
#if PREVIEW
|
||||
//if (IsPrerelease && (DateTime.Now >= ExpirationDate))
|
||||
if (DateTime.Now >= ExpirationDate)
|
||||
{
|
||||
if (Environment.GetCommandLineArgs().Count() > 1)
|
||||
{
|
||||
Console.WriteLine("This prerelease version is expired!");
|
||||
CommandLine.CloseConsole();
|
||||
}
|
||||
else
|
||||
MessageBox.Show("This prerelease version is expired!", "Windows Phone Internals", MessageBoxButton.OK, MessageBoxImage.Exclamation);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static bool IsRegistered()
|
||||
{
|
||||
bool Result = false;
|
||||
if (App.Config.RegistrationName != null)
|
||||
{
|
||||
Result = CalcRegKey() == App.Config.RegistrationKey;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal static string CalcRegKey()
|
||||
{
|
||||
string KeyBase = App.Config.RegistrationName;
|
||||
if (Environment.MachineName == null)
|
||||
{
|
||||
KeyBase += "-Unknown";
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBase += "-" + Environment.MachineName;
|
||||
}
|
||||
|
||||
byte[] KeyBytes = System.Text.Encoding.UTF8.GetBytes(KeyBase);
|
||||
SHA1Managed sha = new();
|
||||
byte[] Key = sha.ComputeHash(KeyBytes);
|
||||
return Convert.ToBase64String(Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace WPinternals.Config
|
||||
{
|
||||
public class SecWimEntry
|
||||
{
|
||||
public string FirmwareVersion;
|
||||
public string Path;
|
||||
|
||||
internal bool Exists()
|
||||
{
|
||||
return File.Exists(Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,68 +22,11 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Windows;
|
||||
using System.Xml.Serialization;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Config
|
||||
{
|
||||
internal static class Registration
|
||||
{
|
||||
#if PREVIEW
|
||||
internal const bool IsPrerelease = true;
|
||||
#else
|
||||
internal const bool IsPrerelease = false;
|
||||
#endif
|
||||
|
||||
internal static readonly DateTime ExpirationDate = new(2024, 12, 21);
|
||||
|
||||
internal static void CheckExpiration()
|
||||
{
|
||||
#if PREVIEW
|
||||
//if (IsPrerelease && (DateTime.Now >= ExpirationDate))
|
||||
if (DateTime.Now >= ExpirationDate)
|
||||
{
|
||||
if (Environment.GetCommandLineArgs().Count() > 1)
|
||||
{
|
||||
Console.WriteLine("This prerelease version is expired!");
|
||||
CommandLine.CloseConsole();
|
||||
}
|
||||
else
|
||||
MessageBox.Show("This prerelease version is expired!", "Windows Phone Internals", MessageBoxButton.OK, MessageBoxImage.Exclamation);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static bool IsRegistered()
|
||||
{
|
||||
bool Result = false;
|
||||
if (App.Config.RegistrationName != null)
|
||||
{
|
||||
Result = CalcRegKey() == App.Config.RegistrationKey;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal static string CalcRegKey()
|
||||
{
|
||||
string KeyBase = App.Config.RegistrationName;
|
||||
if (Environment.MachineName == null)
|
||||
{
|
||||
KeyBase += "-Unknown";
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBase += "-" + Environment.MachineName;
|
||||
}
|
||||
|
||||
byte[] KeyBytes = System.Text.Encoding.UTF8.GetBytes(KeyBase);
|
||||
SHA1Managed sha = new();
|
||||
byte[] Key = sha.ComputeHash(KeyBytes);
|
||||
return Convert.ToBase64String(Key);
|
||||
}
|
||||
}
|
||||
|
||||
public class WPinternalsConfig
|
||||
{
|
||||
@@ -122,7 +65,7 @@ namespace WPinternals
|
||||
FileWriter.Close();
|
||||
}
|
||||
|
||||
internal void SetProfile(string Type, string PlatformID, string ProductCode, string PhoneFirmware, string FfuFirmware, UInt32 FillSize, UInt32 HeaderSize, bool AssumeImageHeaderFallsInGap, bool AllocateAsyncBuffersOnPhone)
|
||||
internal void SetProfile(string Type, string PlatformID, string ProductCode, string PhoneFirmware, string FfuFirmware, uint FillSize, uint HeaderSize, bool AssumeImageHeaderFallsInGap, bool AllocateAsyncBuffersOnPhone)
|
||||
{
|
||||
FlashProfile Profile = GetProfile(PlatformID, PhoneFirmware, FfuFirmware);
|
||||
if (Profile == null)
|
||||
@@ -148,7 +91,7 @@ namespace WPinternals
|
||||
|
||||
internal FlashProfile GetProfile(string PlatformID, string PhoneFirmware, string FfuFirmware = null)
|
||||
{
|
||||
return FlashProfiles.Find(p => string.Equals(p.PlatformID, PlatformID, StringComparison.CurrentCultureIgnoreCase) && string.Equals(p.PhoneFirmware, PhoneFirmware, StringComparison.CurrentCultureIgnoreCase) && ((FfuFirmware == null) || string.Equals(p.FfuFirmware, FfuFirmware, StringComparison.CurrentCultureIgnoreCase)));
|
||||
return FlashProfiles.Find(p => string.Equals(p.PlatformID, PlatformID, StringComparison.CurrentCultureIgnoreCase) && string.Equals(p.PhoneFirmware, PhoneFirmware, StringComparison.CurrentCultureIgnoreCase) && (FfuFirmware == null || string.Equals(p.FfuFirmware, FfuFirmware, StringComparison.CurrentCultureIgnoreCase)));
|
||||
}
|
||||
|
||||
public List<FlashProfile> FlashProfiles = [];
|
||||
@@ -168,7 +111,7 @@ namespace WPinternals
|
||||
|
||||
internal void AddFfuToRepository(string FFUPath, string PlatformID, string FirmwareVersion, string OSVersion)
|
||||
{
|
||||
FFUEntry Entry = FFURepository.Find(e => (e.PlatformID == PlatformID) && (e.FirmwareVersion == FirmwareVersion) && string.Equals(e.Path, FFUPath, StringComparison.CurrentCultureIgnoreCase));
|
||||
FFUEntry Entry = FFURepository.Find(e => e.PlatformID == PlatformID && e.FirmwareVersion == FirmwareVersion && string.Equals(e.Path, FFUPath, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (Entry == null)
|
||||
{
|
||||
LogFile.Log("Adding FFU to repository: " + FFUPath, LogType.FileAndConsole);
|
||||
@@ -222,7 +165,7 @@ namespace WPinternals
|
||||
|
||||
internal void AddSecWimToRepository(string SecWimPath, string FirmwareVersion)
|
||||
{
|
||||
SecWimEntry Entry = SecWimRepository.Find(e => (e.FirmwareVersion == FirmwareVersion) && string.Equals(e.Path, SecWimPath, StringComparison.CurrentCultureIgnoreCase));
|
||||
SecWimEntry Entry = SecWimRepository.Find(e => e.FirmwareVersion == FirmwareVersion && string.Equals(e.Path, SecWimPath, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (Entry == null)
|
||||
{
|
||||
LogFile.Log("Adding Secure WIM to repository: " + SecWimPath, LogType.FileAndConsole);
|
||||
@@ -270,8 +213,8 @@ namespace WPinternals
|
||||
|
||||
internal void AddEmergencyToRepository(string Type, string ProgrammerPath, string PayloadPath)
|
||||
{
|
||||
EmergencyFileEntry Entry = EmergencyRepository.Find(e => (e.Type == Type) && string.Equals(e.ProgrammerPath, ProgrammerPath, StringComparison.CurrentCultureIgnoreCase));
|
||||
if ((Entry != null) && (PayloadPath != null) && (!string.Equals(Entry.PayloadPath, PayloadPath, StringComparison.CurrentCultureIgnoreCase)))
|
||||
EmergencyFileEntry Entry = EmergencyRepository.Find(e => e.Type == Type && string.Equals(e.ProgrammerPath, ProgrammerPath, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (Entry != null && PayloadPath != null && !string.Equals(Entry.PayloadPath, PayloadPath, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
LogFile.Log("Updating emergency payload path in repository: " + PayloadPath, LogType.FileAndConsole);
|
||||
Entry.PayloadPath = PayloadPath;
|
||||
@@ -326,111 +269,4 @@ namespace WPinternals
|
||||
public string RegistrationTelegramID;
|
||||
public string RegistrationKey;
|
||||
}
|
||||
|
||||
public class FlashProfile
|
||||
{
|
||||
public string Type;
|
||||
public string PlatformID;
|
||||
public string ProductCode;
|
||||
public string PhoneFirmware;
|
||||
public string FfuFirmware;
|
||||
|
||||
[XmlIgnore]
|
||||
internal UInt32 FillSize;
|
||||
[XmlIgnore]
|
||||
internal UInt32 HeaderSize;
|
||||
[XmlIgnore]
|
||||
internal bool AssumeImageHeaderFallsInGap;
|
||||
[XmlIgnore]
|
||||
internal bool AllocateAsyncBuffersOnPhone;
|
||||
|
||||
[XmlElement(ElementName = "Profile")]
|
||||
public string ProfileAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] ValueBuffer = new byte[10];
|
||||
ValueBuffer[0] = 1; // Profile version
|
||||
ByteOperations.WriteUInt32(ValueBuffer, 1, FillSize);
|
||||
ByteOperations.WriteUInt32(ValueBuffer, 5, HeaderSize);
|
||||
if (AssumeImageHeaderFallsInGap)
|
||||
{
|
||||
ValueBuffer[9] |= 1;
|
||||
}
|
||||
|
||||
if (AllocateAsyncBuffersOnPhone)
|
||||
{
|
||||
ValueBuffer[9] |= 2;
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(ValueBuffer);
|
||||
}
|
||||
set
|
||||
{
|
||||
byte[] ValueBuffer = Convert.FromBase64String(value);
|
||||
byte Version = ValueBuffer[0];
|
||||
FillSize = ByteOperations.ReadUInt32(ValueBuffer, 1);
|
||||
HeaderSize = ByteOperations.ReadUInt32(ValueBuffer, 5);
|
||||
AssumeImageHeaderFallsInGap = (ValueBuffer[9] & 1) != 0;
|
||||
AllocateAsyncBuffersOnPhone = (ValueBuffer[9] & 2) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FFUEntry
|
||||
{
|
||||
public string PlatformID;
|
||||
public string FirmwareVersion;
|
||||
public string OSVersion;
|
||||
public string Path;
|
||||
|
||||
internal bool Exists()
|
||||
{
|
||||
return File.Exists(Path);
|
||||
}
|
||||
}
|
||||
|
||||
public class SecWimEntry
|
||||
{
|
||||
public string FirmwareVersion;
|
||||
public string Path;
|
||||
|
||||
internal bool Exists()
|
||||
{
|
||||
return File.Exists(Path);
|
||||
}
|
||||
}
|
||||
|
||||
public class EmergencyFileEntry
|
||||
{
|
||||
public string Type;
|
||||
|
||||
[XmlIgnore]
|
||||
public byte[] RKH;
|
||||
[XmlElement(ElementName = "RKH")]
|
||||
public string RKHAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
return RKH == null ? null : Converter.ConvertHexToString(RKH, "");
|
||||
}
|
||||
set
|
||||
{
|
||||
RKH = value == null ? null : Converter.ConvertStringToHex(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string ProgrammerPath;
|
||||
public string PayloadPath;
|
||||
|
||||
internal bool ProgrammerExists()
|
||||
{
|
||||
return File.Exists(ProgrammerPath);
|
||||
}
|
||||
|
||||
internal bool PayloadExists()
|
||||
{
|
||||
return File.Exists(PayloadPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -149,7 +150,7 @@ namespace WPinternals
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var resultSize = new Size(availableSize.Width, 0);
|
||||
Size resultSize = new Size(availableSize.Width, 0);
|
||||
|
||||
#if NETCORE
|
||||
FormattedText formatted = new FormattedText(
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace WPinternals
|
||||
/// <returns>True if the user presses OK else false</returns>
|
||||
public bool ShowDialog(IntPtr hWndOwner)
|
||||
{
|
||||
var fbd = new FolderBrowserDialog
|
||||
FolderBrowserDialog fbd = new FolderBrowserDialog
|
||||
{
|
||||
Description = this.Title,
|
||||
SelectedPath = this.InitialDirectory,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal class ArrivalEventArgs : EventArgs
|
||||
{
|
||||
public PhoneInterfaces NewInterface;
|
||||
public IDisposable NewModel;
|
||||
|
||||
public ArrivalEventArgs(PhoneInterfaces NewInterface, IDisposable NewModel)
|
||||
: base()
|
||||
{
|
||||
this.NewInterface = NewInterface;
|
||||
this.NewModel = NewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal class AsyncAutoResetEvent
|
||||
{
|
||||
private readonly LinkedList<TaskCompletionSource<bool>> waiters =
|
||||
new();
|
||||
|
||||
private bool isSignaled;
|
||||
|
||||
public AsyncAutoResetEvent(bool signaled)
|
||||
{
|
||||
isSignaled = signaled;
|
||||
}
|
||||
|
||||
public Task<bool> WaitAsync(TimeSpan timeout)
|
||||
{
|
||||
return WaitAsync(timeout, CancellationToken.None);
|
||||
}
|
||||
|
||||
public async Task<bool> WaitAsync(TimeSpan timeout, CancellationToken cancellationToken)
|
||||
{
|
||||
TaskCompletionSource<bool> tcs;
|
||||
|
||||
lock (waiters)
|
||||
{
|
||||
if (isSignaled)
|
||||
{
|
||||
isSignaled = false;
|
||||
return true;
|
||||
}
|
||||
else if (timeout == TimeSpan.Zero)
|
||||
{
|
||||
return isSignaled;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcs = new TaskCompletionSource<bool>();
|
||||
waiters.AddLast(tcs);
|
||||
}
|
||||
}
|
||||
|
||||
Task winner = await Task.WhenAny(tcs.Task, Task.Delay(timeout, cancellationToken));
|
||||
if (winner == tcs.Task)
|
||||
{
|
||||
// The task was signaled.
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We timed-out; remove our reference to the task.
|
||||
// This is an O(n) operation since waiters is a LinkedList<T>.
|
||||
lock (waiters)
|
||||
{
|
||||
bool removed = waiters.Remove(tcs);
|
||||
System.Diagnostics.Debug.Assert(removed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Set()
|
||||
{
|
||||
TaskCompletionSource<bool> toRelease = null;
|
||||
|
||||
lock (waiters)
|
||||
{
|
||||
if (waiters.Count > 0)
|
||||
{
|
||||
// Signal the first task in the waiters list.
|
||||
toRelease = waiters.First.Value;
|
||||
waiters.RemoveFirst();
|
||||
}
|
||||
else if (!isSignaled)
|
||||
{
|
||||
// No tasks are pending
|
||||
isSignaled = true;
|
||||
}
|
||||
}
|
||||
|
||||
toRelease?.SetResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// This class was found online.
|
||||
// Original author is probably: John Melville
|
||||
// https://social.msdn.microsoft.com/Forums/en-US/163ef755-ff7b-4ea5-b226-bbe8ef5f4796/is-there-a-pattern-for-calling-an-async-method-synchronously?forum=async
|
||||
public static class AsyncHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Execute's an async Task<T> method which has a void return value synchronously
|
||||
/// </summary>
|
||||
/// <param name="task">Task<T> method to execute</param>
|
||||
public static void RunSync(Func<Task> task)
|
||||
{
|
||||
SynchronizationContext oldContext = SynchronizationContext.Current;
|
||||
ExclusiveSynchronizationContext synch = new ExclusiveSynchronizationContext();
|
||||
SynchronizationContext.SetSynchronizationContext(synch);
|
||||
synch.Post(async _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await task();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
synch.InnerException = e;
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
synch.EndMessageLoop();
|
||||
}
|
||||
}, null);
|
||||
synch.BeginMessageLoop();
|
||||
|
||||
SynchronizationContext.SetSynchronizationContext(oldContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute's an async Task<T> method which has a T return type synchronously
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Return Type</typeparam>
|
||||
/// <param name="task">Task<T> method to execute</param>
|
||||
/// <returns></returns>
|
||||
public static T RunSync<T>(Func<Task<T>> task)
|
||||
{
|
||||
SynchronizationContext oldContext = SynchronizationContext.Current;
|
||||
ExclusiveSynchronizationContext synch = new ExclusiveSynchronizationContext();
|
||||
SynchronizationContext.SetSynchronizationContext(synch);
|
||||
T ret = default;
|
||||
synch.Post(async _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
ret = await task();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
synch.InnerException = e;
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
synch.EndMessageLoop();
|
||||
}
|
||||
}, null);
|
||||
synch.BeginMessageLoop();
|
||||
SynchronizationContext.SetSynchronizationContext(oldContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private class ExclusiveSynchronizationContext : SynchronizationContext
|
||||
{
|
||||
private bool done;
|
||||
public Exception InnerException
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
private readonly AutoResetEvent workItemsWaiting = new(false);
|
||||
private readonly Queue<Tuple<SendOrPostCallback, object>> items =
|
||||
new();
|
||||
|
||||
public override void Send(SendOrPostCallback d, object state)
|
||||
{
|
||||
throw new NotSupportedException("We cannot send to our same thread");
|
||||
}
|
||||
|
||||
public override void Post(SendOrPostCallback d, object state)
|
||||
{
|
||||
lock (items)
|
||||
{
|
||||
items.Enqueue(Tuple.Create(d, state));
|
||||
}
|
||||
workItemsWaiting.Set();
|
||||
}
|
||||
|
||||
public void EndMessageLoop()
|
||||
{
|
||||
Post(_ => done = true, null);
|
||||
}
|
||||
|
||||
public void BeginMessageLoop()
|
||||
{
|
||||
while (!done)
|
||||
{
|
||||
Tuple<SendOrPostCallback, object> task = null;
|
||||
lock (items)
|
||||
{
|
||||
if (items.Count > 0)
|
||||
{
|
||||
task = items.Dequeue();
|
||||
}
|
||||
}
|
||||
if (task != null)
|
||||
{
|
||||
task.Item1(task.Item2);
|
||||
if (InnerException != null) // the method threw an exeption
|
||||
{
|
||||
throw new AggregateException("AsyncHelpers.Run method threw an exception.", InnerException);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
workItemsWaiting.WaitOne();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override SynchronizationContext CreateCopy()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal static class BigEndian
|
||||
{
|
||||
public static byte[] GetBytes(object Value)
|
||||
{
|
||||
byte[] Bytes;
|
||||
if (Value is short)
|
||||
{
|
||||
Bytes = BitConverter.GetBytes((short)Value);
|
||||
}
|
||||
else if (Value is ushort)
|
||||
{
|
||||
Bytes = BitConverter.GetBytes((ushort)Value);
|
||||
}
|
||||
else if (Value is int)
|
||||
{
|
||||
Bytes = BitConverter.GetBytes((int)Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bytes = Value is uint ? BitConverter.GetBytes((uint)Value) : throw new NotSupportedException();
|
||||
}
|
||||
|
||||
byte[] Result = new byte[Bytes.Length];
|
||||
for (int i = 0; i < Bytes.Length; i++)
|
||||
{
|
||||
Result[i] = Bytes[Bytes.Length - 1 - i];
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
public static byte[] GetBytes(object Value, int Width)
|
||||
{
|
||||
byte[] Result;
|
||||
byte[] BigEndianBytes = GetBytes(Value);
|
||||
if (BigEndianBytes.Length == Width)
|
||||
{
|
||||
return BigEndianBytes;
|
||||
}
|
||||
else if (BigEndianBytes.Length > Width)
|
||||
{
|
||||
Result = new byte[Width];
|
||||
Buffer.BlockCopy(BigEndianBytes, BigEndianBytes.Length - Width, Result, 0, Width);
|
||||
return Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = new byte[Width];
|
||||
Buffer.BlockCopy(BigEndianBytes, 0, Result, Width - BigEndianBytes.Length, BigEndianBytes.Length);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static ushort ToUInt16(byte[] Buffer, int Offset)
|
||||
{
|
||||
byte[] Bytes = new byte[2];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Bytes[i] = Buffer[Offset + 1 - i];
|
||||
}
|
||||
|
||||
return BitConverter.ToUInt16(Bytes, 0);
|
||||
}
|
||||
|
||||
public static short ToInt16(byte[] Buffer, int Offset)
|
||||
{
|
||||
byte[] Bytes = new byte[2];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Bytes[i] = Buffer[Offset + 1 - i];
|
||||
}
|
||||
|
||||
return BitConverter.ToInt16(Bytes, 0);
|
||||
}
|
||||
|
||||
public static uint ToUInt32(byte[] Buffer, int Offset)
|
||||
{
|
||||
byte[] Bytes = new byte[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Bytes[i] = Buffer[Offset + 3 - i];
|
||||
}
|
||||
|
||||
return BitConverter.ToUInt32(Bytes, 0);
|
||||
}
|
||||
|
||||
public static int ToInt32(byte[] Buffer, int Offset)
|
||||
{
|
||||
byte[] Bytes = new byte[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Bytes[i] = Buffer[Offset + 3 - i];
|
||||
}
|
||||
|
||||
return BitConverter.ToInt32(Bytes, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
public class BooleanConverter : DependencyObject, IValueConverter
|
||||
{
|
||||
public static readonly DependencyProperty OnTrueProperty =
|
||||
DependencyProperty.Register("OnTrue", typeof(object), typeof(BooleanConverter),
|
||||
new PropertyMetadata(default(object)));
|
||||
|
||||
public static readonly DependencyProperty OnFalseProperty =
|
||||
DependencyProperty.Register("OnFalse", typeof(object), typeof(BooleanConverter),
|
||||
new PropertyMetadata(default(object)));
|
||||
|
||||
public static readonly DependencyProperty OnNullProperty =
|
||||
DependencyProperty.Register("OnNull", typeof(object), typeof(BooleanConverter),
|
||||
new PropertyMetadata(default(object)));
|
||||
|
||||
public object OnTrue
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetValue(OnTrueProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(OnTrueProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public object OnFalse
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetValue(OnFalseProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(OnFalseProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public object OnNull
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetValue(OnNullProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(OnNullProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value == null
|
||||
? OnNull ?? Default(targetType)
|
||||
: string.Equals(value.ToString(), false.ToString(), StringComparison.CurrentCultureIgnoreCase)
|
||||
? OnFalse
|
||||
: OnTrue;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == OnNull)
|
||||
{
|
||||
return Default(targetType);
|
||||
}
|
||||
|
||||
if (value == OnFalse)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value == OnTrue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (OnNull != null &&
|
||||
string.Equals(value.ToString(), OnNull.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return Default(targetType);
|
||||
}
|
||||
|
||||
if (OnFalse != null &&
|
||||
string.Equals(value.ToString(), OnFalse.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (OnTrue != null &&
|
||||
string.Equals(value.ToString(), OnTrue.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static object Default(Type type)
|
||||
{
|
||||
return type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal class CollapsibleRun : Run
|
||||
{
|
||||
private string CollapsibleText;
|
||||
|
||||
protected override void OnInitialized(EventArgs e)
|
||||
{
|
||||
base.OnInitialized(e);
|
||||
|
||||
CollapsibleText = Text;
|
||||
}
|
||||
|
||||
public bool IsVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(IsVisibleProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(IsVisibleProperty, value);
|
||||
}
|
||||
}
|
||||
public static readonly DependencyProperty IsVisibleProperty = DependencyProperty.Register(
|
||||
"IsVisible", typeof(bool), typeof(CollapsibleRun), new PropertyMetadata(true, IsVisibleChanged));
|
||||
public static void IsVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
((CollapsibleRun)d).Text = (bool)e.NewValue ? ((CollapsibleRun)d).CollapsibleText : string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal class CollapsibleSection : Section
|
||||
{
|
||||
public CollapsibleSection()
|
||||
{
|
||||
CollapsibleBlocks = [];
|
||||
}
|
||||
|
||||
protected override void OnInitialized(EventArgs e)
|
||||
{
|
||||
base.OnInitialized(e);
|
||||
|
||||
foreach (Block Block in Blocks)
|
||||
{
|
||||
CollapsibleBlocks.Add(Block);
|
||||
}
|
||||
|
||||
Blocks.Clear();
|
||||
}
|
||||
|
||||
public List<Block> CollapsibleBlocks
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public bool IsCollapsed
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(IsCollapsedProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(IsCollapsedProperty, value);
|
||||
|
||||
Blocks.Clear();
|
||||
|
||||
if (IsInitialized && !value)
|
||||
{
|
||||
foreach (Block Block in CollapsibleBlocks)
|
||||
{
|
||||
Blocks.Add(Block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static readonly DependencyProperty IsCollapsedProperty = DependencyProperty.Register(
|
||||
"IsCollapsed", typeof(bool), typeof(CollapsibleSection), new PropertyMetadata(false));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// For writing a compressed stream
|
||||
internal class CompressedStream : Stream
|
||||
{
|
||||
private readonly uint HeaderSize;
|
||||
private ulong WritePosition;
|
||||
private readonly GZipStream UnderlyingStream;
|
||||
|
||||
internal CompressedStream(Stream OutputStream, ulong TotalDecompressedStreamLength)
|
||||
{
|
||||
// Write header
|
||||
HeaderSize = (uint)(0x12 + "CompressedPartition".Length);
|
||||
OutputStream.WriteByte(0xFF);
|
||||
OutputStream.Write(Encoding.ASCII.GetBytes("CompressedPartition"), 0, "CompressedPartition".Length);
|
||||
OutputStream.WriteByte(0x00);
|
||||
OutputStream.Write(BitConverter.GetBytes((uint)1), 0, 4); // Format version = 1
|
||||
OutputStream.Write(BitConverter.GetBytes(HeaderSize), 0, 4); // Headersize
|
||||
OutputStream.Write(BitConverter.GetBytes(TotalDecompressedStreamLength), 0, 8);
|
||||
|
||||
UnderlyingStream = new GZipStream(OutputStream, CompressionLevel.Optimal, false);
|
||||
WritePosition = 0;
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return (long)WritePosition;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
public override bool CanTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnderlyingStream.CanTimeout;
|
||||
}
|
||||
}
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return (long)WritePosition;
|
||||
}
|
||||
}
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
WritePosition += (ulong)count;
|
||||
UnderlyingStream.Write(buffer, offset, count);
|
||||
}
|
||||
public override void Flush()
|
||||
{
|
||||
UnderlyingStream.Flush();
|
||||
}
|
||||
public override void Close()
|
||||
{
|
||||
UnderlyingStream.Close();
|
||||
}
|
||||
public new void Dispose()
|
||||
{
|
||||
UnderlyingStream.Dispose();
|
||||
}
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
UnderlyingStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal static class Compression
|
||||
{
|
||||
internal static Stream GetDecompressedStreamWithSeek(Stream InputStream)
|
||||
{
|
||||
long P = InputStream.Position;
|
||||
byte[] GZipHeader = new byte[3];
|
||||
InputStream.Read(GZipHeader, 0, 3);
|
||||
InputStream.Position = P;
|
||||
if (StructuralComparisons.StructuralEqualityComparer.Equals(GZipHeader, new byte[] { 0x1F, 0x8B, 0x08 }))
|
||||
{
|
||||
return new GZipStream(InputStream, CompressionMode.Decompress, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return InputStream;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool IsCompressedStream(Stream InputStream)
|
||||
{
|
||||
byte[] GZipHeader = new byte[3];
|
||||
InputStream.Read(GZipHeader, 0, 3);
|
||||
return StructuralComparisons.StructuralEqualityComparer.Equals(GZipHeader, new byte[] { 0x1F, 0x8B, 0x08 });
|
||||
}
|
||||
|
||||
internal static GZipStream GetDecompressedStream(Stream InputStream)
|
||||
{
|
||||
return new GZipStream(InputStream, CompressionMode.Decompress, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
public static class Converter
|
||||
{
|
||||
public static string ConvertHexToString(byte[] Bytes, string Separator)
|
||||
{
|
||||
StringBuilder s = new(1000);
|
||||
for (int i = Bytes.GetLowerBound(0); i <= Bytes.GetUpperBound(0); i++)
|
||||
{
|
||||
if (i != Bytes.GetLowerBound(0))
|
||||
{
|
||||
s.Append(Separator);
|
||||
}
|
||||
|
||||
s.Append(Bytes[i].ToString("X2"));
|
||||
}
|
||||
return s.ToString();
|
||||
}
|
||||
|
||||
public static byte[] ConvertStringToHex(string HexString)
|
||||
{
|
||||
if (HexString.Length % 2 == 1)
|
||||
{
|
||||
throw new Exception("The binary key cannot have an odd number of digits");
|
||||
}
|
||||
|
||||
byte[] arr = new byte[HexString.Length >> 1];
|
||||
|
||||
for (int i = 0; i < HexString.Length >> 1; ++i)
|
||||
{
|
||||
arr[i] = (byte)((GetHexVal(HexString[i << 1]) << 4) + GetHexVal(HexString[(i << 1) + 1]));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static int GetHexVal(char hex)
|
||||
{
|
||||
int val = hex;
|
||||
//For uppercase A-F letters:
|
||||
//return val - (val < 58 ? 48 : 55);
|
||||
//For lowercase a-f letters:
|
||||
//return val - (val < 58 ? 48 : 87);
|
||||
//Or the two combined, but a bit slower:
|
||||
return val - (val < 58 ? 48 : val < 97 ? 55 : 87);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// For reading a compressed stream or normal stream
|
||||
internal class DecompressedStream : Stream
|
||||
{
|
||||
private readonly Stream UnderlyingStream;
|
||||
private readonly bool IsSourceCompressed;
|
||||
private readonly ulong DecompressedLength;
|
||||
private long ReadPosition = 0;
|
||||
|
||||
// For reading a compressed stream
|
||||
internal DecompressedStream(Stream InputStream)
|
||||
{
|
||||
UnderlyingStream = new ReadSeekableStream(InputStream, 0x100);
|
||||
|
||||
byte[] Signature = new byte["CompressedPartition".Length + 2];
|
||||
Signature[0x00] = 0xFF;
|
||||
Buffer.BlockCopy(Encoding.ASCII.GetBytes("CompressedPartition"), 0, Signature, 0x01, "CompressedPartition".Length);
|
||||
Signature["CompressedPartition".Length + 1] = 0x00;
|
||||
|
||||
int PrimaryHeaderSize = 0x0A + "CompressedPartition".Length;
|
||||
byte[] SignatureRead = new byte[Signature.Length];
|
||||
UnderlyingStream.Read(SignatureRead, 0, Signature.Length);
|
||||
|
||||
IsSourceCompressed = StructuralComparisons.StructuralEqualityComparer.Equals(Signature, SignatureRead);
|
||||
if (IsSourceCompressed)
|
||||
{
|
||||
byte[] FormatVersionBytes = new byte[4];
|
||||
UnderlyingStream.Read(FormatVersionBytes, 0, 4);
|
||||
if (BitConverter.ToUInt32(FormatVersionBytes, 0) > 1) // Max supported format version = 1
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
|
||||
byte[] HeaderSizeBytes = new byte[4];
|
||||
UnderlyingStream.Read(HeaderSizeBytes, 0, 4);
|
||||
uint HeaderSize = BitConverter.ToUInt32(HeaderSizeBytes, 0);
|
||||
|
||||
if (HeaderSize >= Signature.Length + 0x10)
|
||||
{
|
||||
byte[] DecompressedLengthBytes = new byte[8];
|
||||
UnderlyingStream.Read(DecompressedLengthBytes, 0, 8);
|
||||
DecompressedLength = BitConverter.ToUInt64(DecompressedLengthBytes, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidDataException();
|
||||
}
|
||||
|
||||
uint HeaderBytesRemaining = (uint)(HeaderSize - Signature.Length - 0x10);
|
||||
if (HeaderBytesRemaining > 0)
|
||||
{
|
||||
byte[] HeaderBytes = new byte[HeaderBytesRemaining];
|
||||
UnderlyingStream.Read(HeaderBytes, 0, (int)HeaderBytesRemaining);
|
||||
}
|
||||
|
||||
UnderlyingStream = new GZipStream(UnderlyingStream, CompressionMode.Decompress, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnderlyingStream.Position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int RealCount = UnderlyingStream.Read(buffer, offset, count);
|
||||
ReadPosition += RealCount;
|
||||
return RealCount;
|
||||
}
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return ReadPosition;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
public override bool CanTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnderlyingStream.CanTimeout;
|
||||
}
|
||||
}
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsSourceCompressed)
|
||||
{
|
||||
return (long)DecompressedLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
return UnderlyingStream.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override void Flush()
|
||||
{
|
||||
UnderlyingStream.Flush();
|
||||
}
|
||||
public override void Close()
|
||||
{
|
||||
UnderlyingStream.Close();
|
||||
}
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
UnderlyingStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// This class is taken from the Prism library by Microsoft Patterns & Practices
|
||||
// License: http://compositewpf.codeplex.com/license
|
||||
public class DelegateCommand : DelegateCommandBase
|
||||
{
|
||||
public DelegateCommand(Action executeMethod)
|
||||
: this(executeMethod, () => true)
|
||||
{
|
||||
}
|
||||
|
||||
public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod) : base(o => executeMethod(), f => canExecuteMethod())
|
||||
{
|
||||
}
|
||||
|
||||
public bool CanExecute()
|
||||
{
|
||||
return CanExecute(null);
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// This class is taken from the Prism library by Microsoft Patterns & Practices
|
||||
// License: http://compositewpf.codeplex.com/license
|
||||
public abstract class DelegateCommandBase : ICommand, IActiveAware
|
||||
{
|
||||
private List<WeakReference> _canExecuteChangedHandlers;
|
||||
private bool _isActive;
|
||||
private readonly Func<object, bool> canExecuteMethod;
|
||||
private readonly Action<object> executeMethod;
|
||||
|
||||
public event EventHandler CanExecuteChanged
|
||||
{
|
||||
add
|
||||
{
|
||||
WeakEventHandlerManager.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
|
||||
}
|
||||
remove
|
||||
{
|
||||
WeakEventHandlerManager.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler IsActiveChanged;
|
||||
|
||||
protected DelegateCommandBase(Action<object> executeMethod, Func<object, bool> canExecuteMethod)
|
||||
{
|
||||
if (executeMethod == null || canExecuteMethod == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(executeMethod), "Delegate Command Delegates Cannot Be Null");
|
||||
}
|
||||
this.executeMethod = executeMethod;
|
||||
this.canExecuteMethod = canExecuteMethod;
|
||||
}
|
||||
|
||||
protected bool CanExecute(object parameter)
|
||||
{
|
||||
if (canExecuteMethod != null)
|
||||
{
|
||||
return canExecuteMethod(parameter);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Execute(object parameter)
|
||||
{
|
||||
executeMethod(parameter);
|
||||
}
|
||||
|
||||
protected virtual void OnCanExecuteChanged()
|
||||
{
|
||||
WeakEventHandlerManager.CallWeakReferenceHandlers(this, _canExecuteChangedHandlers);
|
||||
}
|
||||
|
||||
protected virtual void OnIsActiveChanged()
|
||||
{
|
||||
IsActiveChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void RaiseCanExecuteChanged()
|
||||
{
|
||||
OnCanExecuteChanged();
|
||||
}
|
||||
|
||||
bool ICommand.CanExecute(object parameter)
|
||||
{
|
||||
return CanExecute(parameter);
|
||||
}
|
||||
|
||||
void ICommand.Execute(object parameter)
|
||||
{
|
||||
Execute(parameter);
|
||||
}
|
||||
|
||||
public bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isActive;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_isActive != value)
|
||||
{
|
||||
_isActive = value;
|
||||
OnIsActiveChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal static class ExtensionMethods
|
||||
{
|
||||
// This method was written by: Lawrence Johnston
|
||||
// https://stackoverflow.com/a/22078975
|
||||
public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
|
||||
{
|
||||
using CancellationTokenSource timeoutCancellationTokenSource = new CancellationTokenSource();
|
||||
Task completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token));
|
||||
if (completedTask == task)
|
||||
{
|
||||
timeoutCancellationTokenSource.Cancel();
|
||||
return await task; // Very important in order to propagate exceptions
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new TimeoutException("The operation has timed out.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal class FlowDocumentScrollViewerNoMouseWheel : FlowDocumentScrollViewer
|
||||
{
|
||||
protected override void OnMouseWheel(MouseWheelEventArgs e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// This class was found online.
|
||||
// Original author is probably: mdm20
|
||||
// https://stackoverflow.com/questions/5566330/get-gif-to-play-in-wpf-with-gifimage-class/5568703#5568703
|
||||
internal class GifImage : Image
|
||||
{
|
||||
private bool _isInitialized;
|
||||
private GifBitmapDecoder _gifDecoder;
|
||||
private Int32Animation _animation;
|
||||
|
||||
public int FrameIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)GetValue(FrameIndexProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(FrameIndexProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
_gifDecoder = new GifBitmapDecoder(new Uri("pack://application:,,," + GifSource), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
|
||||
_animation = new Int32Animation(0, _gifDecoder.Frames.Count - 1, new Duration(new TimeSpan(0, 0, 0, _gifDecoder.Frames.Count / 10, (int)((_gifDecoder.Frames.Count / 10.0 - _gifDecoder.Frames.Count / 10) * 1000))))
|
||||
{
|
||||
RepeatBehavior = RepeatBehavior.Forever
|
||||
};
|
||||
Source = _gifDecoder.Frames[0];
|
||||
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
static GifImage()
|
||||
{
|
||||
VisibilityProperty.OverrideMetadata(typeof(GifImage),
|
||||
new FrameworkPropertyMetadata(VisibilityPropertyChanged));
|
||||
}
|
||||
|
||||
private static void VisibilityPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if ((Visibility)e.NewValue == Visibility.Visible)
|
||||
{
|
||||
((GifImage)sender).StartAnimation();
|
||||
}
|
||||
else
|
||||
{
|
||||
((GifImage)sender).StopAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FrameIndexProperty =
|
||||
DependencyProperty.Register("FrameIndex", typeof(int), typeof(GifImage), new UIPropertyMetadata(0, new PropertyChangedCallback(ChangingFrameIndex)));
|
||||
|
||||
private static void ChangingFrameIndex(DependencyObject obj, DependencyPropertyChangedEventArgs ev)
|
||||
{
|
||||
GifImage gifImage = obj as GifImage;
|
||||
gifImage.Source = gifImage._gifDecoder.Frames[(int)ev.NewValue];
|
||||
}
|
||||
|
||||
public bool AutoStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue(AutoStartProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(AutoStartProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty AutoStartProperty =
|
||||
DependencyProperty.Register("AutoStart", typeof(bool), typeof(GifImage), new UIPropertyMetadata(false, AutoStartPropertyChanged));
|
||||
|
||||
private static void AutoStartPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
(sender as GifImage)?.StartAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
public string GifSource
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(GifSourceProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(GifSourceProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty GifSourceProperty =
|
||||
DependencyProperty.Register("GifSource", typeof(string), typeof(GifImage), new UIPropertyMetadata(string.Empty, GifSourcePropertyChanged));
|
||||
|
||||
private static void GifSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
(sender as GifImage)?.Initialize();
|
||||
}
|
||||
|
||||
public void StartAnimation()
|
||||
{
|
||||
if (!_isInitialized)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
BeginAnimation(FrameIndexProperty, _animation);
|
||||
}
|
||||
|
||||
public void StopAnimation()
|
||||
{
|
||||
BeginAnimation(FrameIndexProperty, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// This class was written by: Rolf Wessels
|
||||
// https://github.com/rolfwessels/lazycowprojects/tree/master/Wpf
|
||||
|
||||
/// <summary>
|
||||
/// Static class used to attach to wpf control
|
||||
/// </summary>
|
||||
public static class GridViewColumnResize
|
||||
{
|
||||
#region DependencyProperties
|
||||
|
||||
public static readonly DependencyProperty WidthProperty =
|
||||
DependencyProperty.RegisterAttached("Width", typeof(string), typeof(GridViewColumnResize),
|
||||
new PropertyMetadata(OnSetWidthCallback));
|
||||
|
||||
public static readonly DependencyProperty GridViewColumnResizeBehaviorProperty =
|
||||
DependencyProperty.RegisterAttached("GridViewColumnResizeBehavior",
|
||||
typeof(GridViewColumnResizeBehavior), typeof(GridViewColumnResize),
|
||||
null);
|
||||
|
||||
public static readonly DependencyProperty EnabledProperty =
|
||||
DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(GridViewColumnResize),
|
||||
new PropertyMetadata(OnSetEnabledCallback));
|
||||
|
||||
public static readonly DependencyProperty ListViewResizeBehaviorProperty =
|
||||
DependencyProperty.RegisterAttached("ListViewResizeBehaviorProperty",
|
||||
typeof(ListViewResizeBehavior), typeof(GridViewColumnResize), null);
|
||||
|
||||
#endregion
|
||||
|
||||
public static string GetWidth(DependencyObject obj)
|
||||
{
|
||||
return (string)obj.GetValue(WidthProperty);
|
||||
}
|
||||
|
||||
public static void SetWidth(DependencyObject obj, string value)
|
||||
{
|
||||
obj.SetValue(WidthProperty, value);
|
||||
}
|
||||
|
||||
public static bool GetEnabled(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(EnabledProperty);
|
||||
}
|
||||
|
||||
public static void SetEnabled(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(EnabledProperty, value);
|
||||
}
|
||||
|
||||
#region CallBack
|
||||
|
||||
private static void OnSetWidthCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (dependencyObject is GridViewColumn element)
|
||||
{
|
||||
GridViewColumnResizeBehavior behavior = GetOrCreateBehavior(element);
|
||||
behavior.Width = e.NewValue as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine("Error: Expected type GridViewColumn but found " +
|
||||
dependencyObject.GetType().Name);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSetEnabledCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (dependencyObject is ListView element)
|
||||
{
|
||||
ListViewResizeBehavior behavior = GetOrCreateBehavior(element);
|
||||
behavior.Enabled = (bool)e.NewValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine("Error: Expected type ListView but found " + dependencyObject.GetType().Name);
|
||||
}
|
||||
}
|
||||
|
||||
private static ListViewResizeBehavior GetOrCreateBehavior(ListView element)
|
||||
{
|
||||
if (element.GetValue(GridViewColumnResizeBehaviorProperty) is not ListViewResizeBehavior behavior)
|
||||
{
|
||||
behavior = new ListViewResizeBehavior(element);
|
||||
element.SetValue(ListViewResizeBehaviorProperty, behavior);
|
||||
}
|
||||
|
||||
return behavior;
|
||||
}
|
||||
|
||||
private static GridViewColumnResizeBehavior GetOrCreateBehavior(GridViewColumn element)
|
||||
{
|
||||
if (element.GetValue(GridViewColumnResizeBehaviorProperty) is not GridViewColumnResizeBehavior behavior)
|
||||
{
|
||||
behavior = new GridViewColumnResizeBehavior(element);
|
||||
element.SetValue(GridViewColumnResizeBehaviorProperty, behavior);
|
||||
}
|
||||
|
||||
return behavior;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: GridViewColumnResizeBehavior
|
||||
|
||||
// This class was written by: Rolf Wessels
|
||||
// https://github.com/rolfwessels/lazycowprojects/tree/master/Wpf
|
||||
|
||||
/// <summary>
|
||||
/// GridViewColumn class that gets attached to the GridViewColumn control
|
||||
/// </summary>
|
||||
public class GridViewColumnResizeBehavior
|
||||
{
|
||||
private readonly GridViewColumn _element;
|
||||
|
||||
public GridViewColumnResizeBehavior(GridViewColumn element)
|
||||
{
|
||||
_element = element;
|
||||
}
|
||||
|
||||
public string Width
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public bool IsStatic
|
||||
{
|
||||
get
|
||||
{
|
||||
return StaticWidth >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double StaticWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return double.TryParse(Width, out double result) ? result : -1;
|
||||
}
|
||||
}
|
||||
|
||||
public double Percentage
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsStatic)
|
||||
{
|
||||
return Mulitplier * 100;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double Mulitplier
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Width == "*" || Width == "1*")
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Width.EndsWith("*") && double.TryParse(Width[0..^1], out double perc))
|
||||
{
|
||||
return perc;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetWidth(double allowedSpace, double totalPercentage)
|
||||
{
|
||||
if (IsStatic)
|
||||
{
|
||||
_element.Width = StaticWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
_element.Width = (double)Math.Max(allowedSpace * (Percentage / totalPercentage), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: ListViewResizeBehavior
|
||||
|
||||
// This class was written by: Rolf Wessels
|
||||
// https://github.com/rolfwessels/lazycowprojects/tree/master/Wpf
|
||||
|
||||
/// <summary>
|
||||
/// ListViewResizeBehavior class that gets attached to the ListView control
|
||||
/// </summary>
|
||||
public class ListViewResizeBehavior
|
||||
{
|
||||
private const int Margin = 25;
|
||||
private const long RefreshTime = Timeout.Infinite;
|
||||
private const long Delay = 500;
|
||||
|
||||
private readonly ListView _element;
|
||||
private readonly Timer _timer;
|
||||
|
||||
public ListViewResizeBehavior(ListView element)
|
||||
{
|
||||
_element = element ?? throw new ArgumentNullException(nameof(element));
|
||||
element.Loaded += OnLoaded;
|
||||
|
||||
// Action for resizing and re-enable the size lookup
|
||||
// This stops the columns from constantly resizing to improve performance
|
||||
Action resizeAndEnableSize = () =>
|
||||
{
|
||||
Resize();
|
||||
_element.SizeChanged += OnSizeChanged;
|
||||
};
|
||||
_timer = new Timer(x => Application.Current.Dispatcher.BeginInvoke(resizeAndEnableSize), null, Delay,
|
||||
RefreshTime);
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_element.SizeChanged += OnSizeChanged;
|
||||
}
|
||||
|
||||
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
if (e.WidthChanged)
|
||||
{
|
||||
_element.SizeChanged -= OnSizeChanged;
|
||||
_timer.Change(Delay, RefreshTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void Resize()
|
||||
{
|
||||
if (Enabled)
|
||||
{
|
||||
double totalWidth = _element.ActualWidth;
|
||||
if (_element.View is GridView gv)
|
||||
{
|
||||
double allowedSpace = totalWidth - GetAllocatedSpace(gv);
|
||||
allowedSpace -= Margin;
|
||||
double totalPercentage = GridViewColumnResizeBehaviors(gv).Sum(x => x.Percentage);
|
||||
foreach (GridViewColumnResizeBehavior behavior in GridViewColumnResizeBehaviors(gv))
|
||||
{
|
||||
behavior.SetWidth(allowedSpace, totalPercentage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<GridViewColumnResizeBehavior> GridViewColumnResizeBehaviors(GridView gv)
|
||||
{
|
||||
foreach (GridViewColumn t in gv.Columns)
|
||||
{
|
||||
if (t.GetValue(GridViewColumnResizeBehaviorProperty) is GridViewColumnResizeBehavior gridViewColumnResizeBehavior)
|
||||
{
|
||||
yield return gridViewColumnResizeBehavior;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static double GetAllocatedSpace(GridView gv)
|
||||
{
|
||||
double totalWidth = 0;
|
||||
foreach (GridViewColumn t in gv.Columns)
|
||||
{
|
||||
if (t.GetValue(GridViewColumnResizeBehaviorProperty) is GridViewColumnResizeBehavior gridViewColumnResizeBehavior)
|
||||
{
|
||||
if (gridViewColumnResizeBehavior.IsStatic)
|
||||
{
|
||||
totalWidth += gridViewColumnResizeBehavior.StaticWidth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
totalWidth += t.ActualWidth;
|
||||
}
|
||||
}
|
||||
return totalWidth;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal delegate void SetWorkingStatus(string Message, string SubMessage = null, ulong? MaxProgressValue = null, bool ShowAnimation = true, WPinternalsStatus Status = WPinternalsStatus.Undefined);
|
||||
internal delegate void UpdateWorkingStatus(string Message, string SubMessage = null, ulong? CurrentProgressValue = null, WPinternalsStatus Status = WPinternalsStatus.Undefined);
|
||||
internal delegate void ExitSuccess(string Message, string SubMessage = null);
|
||||
internal delegate void ExitFailure(string Message, string SubMessage = null);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
public class HexConverter : DependencyObject, IValueConverter
|
||||
{
|
||||
public static readonly DependencyProperty SeparatorProperty =
|
||||
DependencyProperty.Register("OnTrue", typeof(object), typeof(HexConverter),
|
||||
new PropertyMetadata(" "));
|
||||
|
||||
public object Separator
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetValue(SeparatorProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(SeparatorProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is byte[] bytes)
|
||||
{
|
||||
StringBuilder s = new(1000);
|
||||
for (int i = bytes.GetLowerBound(0); i <= bytes.GetUpperBound(0); i++)
|
||||
{
|
||||
if (i != bytes.GetLowerBound(0))
|
||||
{
|
||||
s.Append(Separator);
|
||||
}
|
||||
|
||||
s.Append(bytes[i].ToString("X2"));
|
||||
}
|
||||
return s.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static object Default(Type type)
|
||||
{
|
||||
return type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// This interface is taken from the Prism library by Microsoft Patterns & Practices
|
||||
// License: http://compositewpf.codeplex.com/license
|
||||
public interface IActiveAware
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the object is active.
|
||||
/// </summary>
|
||||
/// <value><see langword="true" /> if the object is active; otherwise <see langword="false" />.</value>
|
||||
bool IsActive
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies that the value for <see cref="IsActive"/> property has changed.
|
||||
/// </summary>
|
||||
event EventHandler IsActiveChanged;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
public class InverseObjectToVisibilityConverter : DependencyObject, IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return "Visible";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Collapsed";
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static object Default(Type type)
|
||||
{
|
||||
return type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal static class LogFile
|
||||
{
|
||||
private static readonly StreamWriter w = null;
|
||||
private static readonly object lockobject = new();
|
||||
#if PREVIEW
|
||||
private static string LogAction = null;
|
||||
private static StringBuilder LogBuilder;
|
||||
#endif
|
||||
|
||||
static LogFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals")))
|
||||
{
|
||||
Directory.CreateDirectory(Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals"));
|
||||
}
|
||||
|
||||
w = File.AppendText(Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\WPInternals.log"));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public static void Log(string logMessage, LogType Type = LogType.FileOnly)
|
||||
{
|
||||
if (w == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (lockobject)
|
||||
{
|
||||
if (Type == LogType.FileOnly || Type == LogType.FileAndConsole)
|
||||
{
|
||||
DateTime Now = DateTime.Now;
|
||||
string Text = Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + ": " + logMessage;
|
||||
w.WriteLine(Text);
|
||||
w.Flush();
|
||||
|
||||
#if PREVIEW
|
||||
if (LogAction != null)
|
||||
LogBuilder.AppendLine(Text);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (CommandLine.IsConsoleVisible && (Type == LogType.ConsoleOnly || Type == LogType.FileAndConsole))
|
||||
{
|
||||
Console.WriteLine(logMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void LogException(Exception Ex, LogType Type = LogType.FileAndConsole, string AdditionalInfo = null)
|
||||
{
|
||||
string Indent = "";
|
||||
Exception CurrentEx = Ex;
|
||||
while (CurrentEx != null)
|
||||
{
|
||||
Log(Indent + "Error: " + RemoveBadChars(CurrentEx.Message).Replace("of type '.' ", "") + (AdditionalInfo == null ? "" : " - " + AdditionalInfo), Type);
|
||||
AdditionalInfo = null;
|
||||
if (CurrentEx is WPinternalsException)
|
||||
{
|
||||
Log(Indent + ((WPinternalsException)CurrentEx).SubMessage, Type);
|
||||
}
|
||||
#if DEBUG
|
||||
if (CurrentEx.StackTrace != null)
|
||||
{
|
||||
Log(Indent + CurrentEx.StackTrace, LogType.FileOnly);
|
||||
}
|
||||
#endif
|
||||
Indent += " ";
|
||||
CurrentEx = CurrentEx.InnerException;
|
||||
}
|
||||
}
|
||||
|
||||
private static string RemoveBadChars(string Text)
|
||||
{
|
||||
return System.Text.RegularExpressions.Regex.Replace(Text, @"[^\u0020-\u007E]+", string.Empty);
|
||||
}
|
||||
|
||||
public static void DumpLog(StreamReader r)
|
||||
{
|
||||
string line;
|
||||
while ((line = r.ReadLine()) != null)
|
||||
{
|
||||
Console.WriteLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LogApplicationVersion()
|
||||
{
|
||||
Log("Windows Phone Internals version " +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Major.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Build.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Revision.ToString(), LogType.FileAndConsole);
|
||||
Log("Copyright Heathcliff74", LogType.FileAndConsole);
|
||||
}
|
||||
|
||||
internal static void BeginAction(string Action)
|
||||
{
|
||||
#if PREVIEW
|
||||
if (LogAction == null)
|
||||
{
|
||||
LogAction = Action;
|
||||
LogBuilder = new StringBuilder();
|
||||
LogBuilder.AppendLine("Windows Phone Internals version " +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Major.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Build.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Revision.ToString());
|
||||
LogBuilder.AppendLine("Copyright Heathcliff74");
|
||||
LogBuilder.AppendLine("Action: " + Action);
|
||||
if (App.Config.RegistrationName != null)
|
||||
LogBuilder.AppendLine("Name: " + App.Config.RegistrationName);
|
||||
if (App.Config.RegistrationEmail != null)
|
||||
LogBuilder.AppendLine("Mail: " + App.Config.RegistrationEmail);
|
||||
if (App.Config.RegistrationSkypeID != null)
|
||||
LogBuilder.AppendLine("Skype: " + App.Config.RegistrationSkypeID);
|
||||
if (App.Config.RegistrationTelegramID != null)
|
||||
LogBuilder.AppendLine("Telegram: " + App.Config.RegistrationTelegramID);
|
||||
if (Environment.MachineName != null)
|
||||
LogBuilder.AppendLine("Machine: " + Environment.MachineName);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static void EndAction()
|
||||
{
|
||||
EndAction(null);
|
||||
}
|
||||
|
||||
internal static void EndAction(string Action)
|
||||
{
|
||||
#if PREVIEW
|
||||
if (LogAction != null && (Action == null || LogAction == Action))
|
||||
{
|
||||
Action = LogAction;
|
||||
LogAction = null;
|
||||
string FileName = "";
|
||||
if (App.Config.RegistrationName != null)
|
||||
FileName += App.Config.RegistrationName + " - ";
|
||||
FileName += DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture) + " - " + Action + " - " +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Major.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Build.ToString() + "." +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.Revision.ToString() + ".log";
|
||||
|
||||
// Normalize filename
|
||||
try
|
||||
{
|
||||
FileName = Encoding.ASCII.GetString(Encoding.GetEncoding("ISO-8859-8").GetBytes(FileName));
|
||||
}
|
||||
catch { }
|
||||
FileName = FileName.Replace("?", "");
|
||||
|
||||
if (Action.ToLower() == "registration")
|
||||
Uploader.Upload(FileName, LogBuilder.ToString());
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Uploader.Upload(FileName, LogBuilder.ToString());
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal enum LogType
|
||||
{
|
||||
FileOnly,
|
||||
FileAndConsole,
|
||||
ConsoleOnly
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
public class ObjectToVisibilityConverter : DependencyObject, IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return "Collapsed";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Visible";
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static object Default(Type type)
|
||||
{
|
||||
return type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal static class PE
|
||||
{
|
||||
internal static byte[] GetResource(byte[] PEfile, int[] Index)
|
||||
{
|
||||
// Explanation of PE header here:
|
||||
// https://msdn.microsoft.com/en-us/library/ms809762.aspx?f=255&MSPPError=-2147217396
|
||||
|
||||
uint PEPointer = ByteOperations.ReadUInt32(PEfile, 0x3C);
|
||||
ushort OptionalHeaderSize = ByteOperations.ReadUInt16(PEfile, PEPointer + 0x14);
|
||||
uint SectionTablePointer = PEPointer + 0x18 + OptionalHeaderSize;
|
||||
ushort SectionCount = ByteOperations.ReadUInt16(PEfile, PEPointer + 0x06);
|
||||
uint? ResourceSectionEntryPointer = null;
|
||||
for (int i = 0; i < SectionCount; i++)
|
||||
{
|
||||
string SectionName = ByteOperations.ReadAsciiString(PEfile, (uint)(SectionTablePointer + i * 0x28), 8);
|
||||
int e = SectionName.IndexOf('\0');
|
||||
if (e >= 0)
|
||||
{
|
||||
SectionName = SectionName.Substring(0, e);
|
||||
}
|
||||
|
||||
if (SectionName == ".rsrc")
|
||||
{
|
||||
ResourceSectionEntryPointer = (uint)(SectionTablePointer + i * 0x28);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ResourceSectionEntryPointer == null)
|
||||
{
|
||||
throw new WPinternalsException("Resource-section not found");
|
||||
}
|
||||
|
||||
uint ResourceRawSize = ByteOperations.ReadUInt32(PEfile, (uint)ResourceSectionEntryPointer + 0x10);
|
||||
uint ResourceRawPointer = ByteOperations.ReadUInt32(PEfile, (uint)ResourceSectionEntryPointer + 0x14);
|
||||
uint ResourceVirtualPointer = ByteOperations.ReadUInt32(PEfile, (uint)ResourceSectionEntryPointer + 0x0C);
|
||||
|
||||
uint p = ResourceRawPointer;
|
||||
for (int i = 0; i < Index.Length; i++)
|
||||
{
|
||||
ushort ResourceNamedEntryCount = ByteOperations.ReadUInt16(PEfile, p + 0x0c);
|
||||
ushort ResourceIdEntryCount = ByteOperations.ReadUInt16(PEfile, p + 0x0e);
|
||||
for (int j = ResourceNamedEntryCount; j < ResourceNamedEntryCount + ResourceIdEntryCount; j++)
|
||||
{
|
||||
uint ResourceID = ByteOperations.ReadUInt32(PEfile, (uint)(p + 0x10 + j * 8));
|
||||
uint NextPointer = ByteOperations.ReadUInt32(PEfile, (uint)(p + 0x10 + j * 8 + 4));
|
||||
if (ResourceID == (uint)Index[i])
|
||||
{
|
||||
// Check high bit
|
||||
if ((NextPointer & 0x80000000) == 0 != (i == Index.Length - 1))
|
||||
{
|
||||
throw new WPinternalsException("Bad resource path");
|
||||
}
|
||||
|
||||
p = ResourceRawPointer + (NextPointer & 0x7fffffff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint ResourceValuePointer = ByteOperations.ReadUInt32(PEfile, p) - ResourceVirtualPointer + ResourceRawPointer;
|
||||
uint ResourceValueSize = ByteOperations.ReadUInt32(PEfile, p + 4);
|
||||
|
||||
byte[] ResourceValue = new byte[ResourceValueSize];
|
||||
Array.Copy(PEfile, ResourceValuePointer, ResourceValue, 0, ResourceValueSize);
|
||||
|
||||
return ResourceValue;
|
||||
}
|
||||
|
||||
internal static Version GetFileVersion(byte[] PEfile)
|
||||
{
|
||||
byte[] version = GetResource(PEfile, [(int)ResourceType.RT_VERSION, 1, 1033]);
|
||||
|
||||
// RT_VERSION format:
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms646997(v=vs.85).aspx
|
||||
const uint FixedFileInfoPointer = 0x28;
|
||||
ushort Major = ByteOperations.ReadUInt16(version, FixedFileInfoPointer + 0x0A);
|
||||
ushort Minor = ByteOperations.ReadUInt16(version, FixedFileInfoPointer + 0x08);
|
||||
ushort Build = ByteOperations.ReadUInt16(version, FixedFileInfoPointer + 0x0E);
|
||||
ushort Revision = ByteOperations.ReadUInt16(version, FixedFileInfoPointer + 0x0C);
|
||||
|
||||
return new Version(Major, Minor, Build, Revision);
|
||||
}
|
||||
|
||||
internal static Version GetProductVersion(byte[] PEfile)
|
||||
{
|
||||
byte[] version = GetResource(PEfile, [(int)ResourceType.RT_VERSION, 1, 1033]);
|
||||
|
||||
// RT_VERSION format:
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms646997(v=vs.85).aspx
|
||||
const uint FixedFileInfoPointer = 0x28;
|
||||
ushort Major = ByteOperations.ReadUInt16(version, FixedFileInfoPointer + 0x12);
|
||||
ushort Minor = ByteOperations.ReadUInt16(version, FixedFileInfoPointer + 0x10);
|
||||
ushort Build = ByteOperations.ReadUInt16(version, FixedFileInfoPointer + 0x16);
|
||||
ushort Revision = ByteOperations.ReadUInt16(version, FixedFileInfoPointer + 0x14);
|
||||
|
||||
return new Version(Major, Minor, Build, Revision);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Documents;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// Overloaded Paragraph class to remove empty Run-elements, caused by auto-formatting new-lines in the XAML
|
||||
// Use helpers:Paragraph in a FlowDocument
|
||||
// This correction only works at run-time
|
||||
public class Paragraph : System.Windows.Documents.Paragraph
|
||||
{
|
||||
protected override void OnInitialized(EventArgs e)
|
||||
{
|
||||
base.OnInitialized(e);
|
||||
int inlinesCount = Inlines.Count;
|
||||
for (int i = 0; i < inlinesCount; i++)
|
||||
{
|
||||
Inline inline = Inlines.ElementAt(i);
|
||||
if (inline is Run run)
|
||||
{
|
||||
if (run.Text == Convert.ToChar(32).ToString()) //ACSII 32 is the white space
|
||||
{
|
||||
run.Text = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal class ProgressUpdater
|
||||
{
|
||||
private readonly DateTime InitTime;
|
||||
private DateTime LastUpdateTime;
|
||||
private readonly ulong MaxValue;
|
||||
private readonly Action<int, TimeSpan?> ProgressUpdateCallback;
|
||||
internal int ProgressPercentage;
|
||||
|
||||
internal ProgressUpdater(ulong MaxValue, Action<int, TimeSpan?> ProgressUpdateCallback)
|
||||
{
|
||||
InitTime = DateTime.Now;
|
||||
LastUpdateTime = DateTime.Now;
|
||||
this.MaxValue = MaxValue;
|
||||
this.ProgressUpdateCallback = ProgressUpdateCallback;
|
||||
SetProgress(0);
|
||||
}
|
||||
|
||||
private ulong _Progress;
|
||||
internal ulong Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Progress;
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetProgress(ulong NewValue)
|
||||
{
|
||||
if (_Progress != NewValue)
|
||||
{
|
||||
int PreviousProgressPercentage = (int)((double)_Progress / MaxValue * 100);
|
||||
ProgressPercentage = (int)((double)NewValue / MaxValue * 100);
|
||||
|
||||
_Progress = NewValue;
|
||||
|
||||
if (DateTime.Now - LastUpdateTime > TimeSpan.FromSeconds(0.5) || ProgressPercentage == 100)
|
||||
{
|
||||
#if DEBUG
|
||||
Console.WriteLine("Init time: " + InitTime.ToShortTimeString() + " / Now: " + DateTime.Now.ToString() + " / NewValue: " + NewValue.ToString() + " / MaxValue: " + MaxValue.ToString() + " ->> Percentage: " + ProgressPercentage.ToString() + " / Remaining: " + TimeSpan.FromTicks((long)((DateTime.Now - InitTime).Ticks / ((double)NewValue / MaxValue) * (1 - (double)NewValue / MaxValue))).ToString());
|
||||
#endif
|
||||
|
||||
if (DateTime.Now - InitTime < TimeSpan.FromSeconds(30) && ProgressPercentage < 15)
|
||||
{
|
||||
ProgressUpdateCallback(ProgressPercentage, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressUpdateCallback(ProgressPercentage, TimeSpan.FromTicks((long)((DateTime.Now - InitTime).Ticks / ((double)NewValue / MaxValue) * (1 - (double)NewValue / MaxValue))));
|
||||
}
|
||||
|
||||
LastUpdateTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void IncreaseProgress(ulong Progress)
|
||||
{
|
||||
SetProgress(_Progress + Progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// This class is written by: Eugene Beresovsky
|
||||
// https://stackoverflow.com/questions/13035925/stream-wrapper-to-make-stream-seekable/28036366#28036366
|
||||
internal class ReadSeekableStream : Stream
|
||||
{
|
||||
private long _underlyingPosition;
|
||||
private readonly byte[] _seekBackBuffer;
|
||||
private int _seekBackBufferCount;
|
||||
private int _seekBackBufferIndex;
|
||||
private readonly Stream _underlyingStream;
|
||||
|
||||
public ReadSeekableStream(Stream underlyingStream, int seekBackBufferSize)
|
||||
{
|
||||
if (!underlyingStream.CanRead)
|
||||
{
|
||||
throw new Exception("Provided stream " + underlyingStream + " is not readable");
|
||||
}
|
||||
|
||||
_underlyingStream = underlyingStream;
|
||||
_seekBackBuffer = new byte[seekBackBufferSize];
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int copiedFromBackBufferCount = 0;
|
||||
if (_seekBackBufferIndex < _seekBackBufferCount)
|
||||
{
|
||||
copiedFromBackBufferCount = Math.Min(count, _seekBackBufferCount - _seekBackBufferIndex);
|
||||
Buffer.BlockCopy(_seekBackBuffer, _seekBackBufferIndex, buffer, offset, copiedFromBackBufferCount);
|
||||
offset += copiedFromBackBufferCount;
|
||||
count -= copiedFromBackBufferCount;
|
||||
_seekBackBufferIndex += copiedFromBackBufferCount;
|
||||
}
|
||||
int bytesReadFromUnderlying = 0;
|
||||
if (count > 0)
|
||||
{
|
||||
bytesReadFromUnderlying = _underlyingStream.Read(buffer, offset, count);
|
||||
if (bytesReadFromUnderlying > 0)
|
||||
{
|
||||
_underlyingPosition += bytesReadFromUnderlying;
|
||||
|
||||
int copyToBufferCount = Math.Min(bytesReadFromUnderlying, _seekBackBuffer.Length);
|
||||
int copyToBufferOffset = Math.Min(_seekBackBufferCount, _seekBackBuffer.Length - copyToBufferCount);
|
||||
int bufferBytesToMove = Math.Min(_seekBackBufferCount - 1, copyToBufferOffset);
|
||||
|
||||
if (bufferBytesToMove > 0)
|
||||
{
|
||||
Buffer.BlockCopy(_seekBackBuffer, _seekBackBufferCount - bufferBytesToMove, _seekBackBuffer, 0, bufferBytesToMove);
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(buffer, offset, _seekBackBuffer, copyToBufferOffset, copyToBufferCount);
|
||||
_seekBackBufferCount = Math.Min(_seekBackBuffer.Length, _seekBackBufferCount + copyToBufferCount);
|
||||
_seekBackBufferIndex = _seekBackBufferCount;
|
||||
}
|
||||
}
|
||||
return copiedFromBackBufferCount + bytesReadFromUnderlying;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
if (origin == SeekOrigin.End)
|
||||
{
|
||||
return SeekFromEnd((int)Math.Max(0, -offset));
|
||||
}
|
||||
|
||||
long relativeOffset = origin == SeekOrigin.Current
|
||||
? offset
|
||||
: offset - Position;
|
||||
|
||||
if (relativeOffset == 0)
|
||||
{
|
||||
return Position;
|
||||
}
|
||||
else if (relativeOffset > 0)
|
||||
{
|
||||
return SeekForward(relativeOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SeekBackwards(-relativeOffset);
|
||||
}
|
||||
}
|
||||
|
||||
private long SeekForward(long origOffset)
|
||||
{
|
||||
long offset = origOffset;
|
||||
int seekBackBufferLength = _seekBackBuffer.Length;
|
||||
|
||||
int backwardSoughtBytes = _seekBackBufferCount - _seekBackBufferIndex;
|
||||
int seekForwardInBackBuffer = (int)Math.Min(offset, backwardSoughtBytes);
|
||||
offset -= seekForwardInBackBuffer;
|
||||
_seekBackBufferIndex += seekForwardInBackBuffer;
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
// first completely fill seekBackBuffer to remove special cases from while loop below
|
||||
if (_seekBackBufferCount < seekBackBufferLength)
|
||||
{
|
||||
int maxRead = seekBackBufferLength - _seekBackBufferCount;
|
||||
if (offset < maxRead)
|
||||
{
|
||||
maxRead = (int)offset;
|
||||
}
|
||||
|
||||
int bytesRead = _underlyingStream.Read(_seekBackBuffer, _seekBackBufferCount, maxRead);
|
||||
_underlyingPosition += bytesRead;
|
||||
_seekBackBufferCount += bytesRead;
|
||||
_seekBackBufferIndex = _seekBackBufferCount;
|
||||
if (bytesRead < maxRead)
|
||||
{
|
||||
if (_seekBackBufferCount < offset)
|
||||
{
|
||||
throw new NotSupportedException("Reached end of stream seeking forward " + origOffset + " bytes");
|
||||
}
|
||||
|
||||
return Position;
|
||||
}
|
||||
offset -= bytesRead;
|
||||
}
|
||||
|
||||
// now alternate between filling tempBuffer and seekBackBuffer
|
||||
bool fillTempBuffer = true;
|
||||
byte[] tempBuffer = new byte[seekBackBufferLength];
|
||||
while (offset > 0)
|
||||
{
|
||||
int maxRead = offset < seekBackBufferLength ? (int)offset : seekBackBufferLength;
|
||||
int bytesRead = _underlyingStream.Read(fillTempBuffer ? tempBuffer : _seekBackBuffer, 0, maxRead);
|
||||
_underlyingPosition += bytesRead;
|
||||
int bytesReadDiff = maxRead - bytesRead;
|
||||
offset -= bytesRead;
|
||||
if (bytesReadDiff > 0 /* reached end-of-stream */ || offset == 0)
|
||||
{
|
||||
if (fillTempBuffer)
|
||||
{
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
Buffer.BlockCopy(_seekBackBuffer, bytesRead, _seekBackBuffer, 0, bytesReadDiff);
|
||||
Buffer.BlockCopy(tempBuffer, 0, _seekBackBuffer, bytesReadDiff, bytesRead);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
Buffer.BlockCopy(_seekBackBuffer, 0, _seekBackBuffer, bytesReadDiff, bytesRead);
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(tempBuffer, bytesRead, _seekBackBuffer, 0, bytesReadDiff);
|
||||
}
|
||||
if (offset > 0)
|
||||
{
|
||||
throw new NotSupportedException("Reached end of stream seeking forward " + origOffset + " bytes");
|
||||
}
|
||||
}
|
||||
fillTempBuffer = !fillTempBuffer;
|
||||
}
|
||||
}
|
||||
return Position;
|
||||
}
|
||||
|
||||
private long SeekBackwards(long offset)
|
||||
{
|
||||
int intOffset = (int)offset;
|
||||
if (offset > int.MaxValue || intOffset > _seekBackBufferIndex)
|
||||
{
|
||||
throw new NotSupportedException("Cannot currently seek backwards more than " + _seekBackBufferIndex + " bytes");
|
||||
}
|
||||
|
||||
_seekBackBufferIndex -= intOffset;
|
||||
return Position;
|
||||
}
|
||||
|
||||
private long SeekFromEnd(long offset)
|
||||
{
|
||||
int intOffset = (int)offset;
|
||||
int seekBackBufferLength = _seekBackBuffer.Length;
|
||||
if (offset > int.MaxValue || intOffset > seekBackBufferLength)
|
||||
{
|
||||
throw new NotSupportedException("Cannot seek backwards from end more than " + seekBackBufferLength + " bytes");
|
||||
}
|
||||
|
||||
// first completely fill seekBackBuffer to remove special cases from while loop below
|
||||
if (_seekBackBufferCount < seekBackBufferLength)
|
||||
{
|
||||
int maxRead = seekBackBufferLength - _seekBackBufferCount;
|
||||
int bytesRead = _underlyingStream.Read(_seekBackBuffer, _seekBackBufferCount, maxRead);
|
||||
_underlyingPosition += bytesRead;
|
||||
_seekBackBufferCount += bytesRead;
|
||||
_seekBackBufferIndex = Math.Max(0, _seekBackBufferCount - intOffset);
|
||||
if (bytesRead < maxRead)
|
||||
{
|
||||
if (_seekBackBufferCount < intOffset)
|
||||
{
|
||||
throw new NotSupportedException("Could not seek backwards from end " + intOffset + " bytes");
|
||||
}
|
||||
|
||||
return Position;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_seekBackBufferIndex = _seekBackBufferCount;
|
||||
}
|
||||
|
||||
// now alternate between filling tempBuffer and seekBackBuffer
|
||||
bool fillTempBuffer = true;
|
||||
byte[] tempBuffer = new byte[seekBackBufferLength];
|
||||
while (true)
|
||||
{
|
||||
int bytesRead = _underlyingStream.Read(fillTempBuffer ? tempBuffer : _seekBackBuffer, 0, seekBackBufferLength);
|
||||
_underlyingPosition += bytesRead;
|
||||
int bytesReadDiff = seekBackBufferLength - bytesRead;
|
||||
if (bytesReadDiff > 0) // reached end-of-stream
|
||||
{
|
||||
if (fillTempBuffer)
|
||||
{
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
Buffer.BlockCopy(_seekBackBuffer, bytesRead, _seekBackBuffer, 0, bytesReadDiff);
|
||||
Buffer.BlockCopy(tempBuffer, 0, _seekBackBuffer, bytesReadDiff, bytesRead);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
Buffer.BlockCopy(_seekBackBuffer, 0, _seekBackBuffer, bytesReadDiff, bytesRead);
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(tempBuffer, bytesRead, _seekBackBuffer, 0, bytesReadDiff);
|
||||
}
|
||||
_seekBackBufferIndex -= intOffset;
|
||||
return Position;
|
||||
}
|
||||
fillTempBuffer = !fillTempBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return _underlyingPosition - (_seekBackBufferCount - _seekBackBufferIndex);
|
||||
}
|
||||
set
|
||||
{
|
||||
Seek(value, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return _underlyingStream.CanTimeout;
|
||||
}
|
||||
}
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return _underlyingStream.CanWrite;
|
||||
}
|
||||
}
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return _underlyingStream.Length;
|
||||
}
|
||||
}
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
_underlyingStream.SetLength(value);
|
||||
}
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
_underlyingStream.Write(buffer, offset, count);
|
||||
}
|
||||
public override void Flush()
|
||||
{
|
||||
_underlyingStream.Flush();
|
||||
}
|
||||
public override void Close()
|
||||
{
|
||||
_underlyingStream.Close();
|
||||
}
|
||||
public new void Dispose()
|
||||
{
|
||||
_underlyingStream.Dispose();
|
||||
}
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_underlyingStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal enum ResourceType
|
||||
{
|
||||
RT_CURSOR = 1,
|
||||
RT_BITMAP = 2,
|
||||
RT_ICON = 3,
|
||||
RT_MENU = 4,
|
||||
RT_DIALOG = 5,
|
||||
RT_STRING = 6,
|
||||
RT_FONTDIR = 7,
|
||||
RT_FONT = 8,
|
||||
RT_ACCELERATOR = 9,
|
||||
RT_RCDATA = 10,
|
||||
RT_MESSAGETABLE = 11,
|
||||
RT_GROUP_CURSOR = RT_CURSOR + 11,
|
||||
RT_GROUP_ICON = RT_ICON + 11,
|
||||
RT_VERSION = 16,
|
||||
RT_DLGINCLUDE = 17,
|
||||
RT_PLUGPLAY = 19,
|
||||
RT_VXD = 20,
|
||||
RT_ANICURSOR = 21,
|
||||
RT_ANIICON = 22,
|
||||
RT_HTML = 23,
|
||||
RT_MANIFEST = 24,
|
||||
RT_DLGINIT = 240,
|
||||
RT_TOOLBAR = 241
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal class SeekableStream : Stream
|
||||
{
|
||||
private Stream UnderlyingStream;
|
||||
private long ReadPosition = 0;
|
||||
private readonly Func<Stream> StreamInitializer;
|
||||
private readonly long UnderlyingStreamLength;
|
||||
|
||||
// For reading a compressed stream
|
||||
internal SeekableStream(Func<Stream> StreamInitializer, long? Length = null)
|
||||
{
|
||||
this.StreamInitializer = StreamInitializer;
|
||||
UnderlyingStream = StreamInitializer();
|
||||
if (Length != null)
|
||||
{
|
||||
UnderlyingStreamLength = (long)Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
UnderlyingStreamLength = UnderlyingStream.Length;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentException("Unknown stream length");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override bool CanSeek
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int RealCount = UnderlyingStream.Read(buffer, offset, count);
|
||||
ReadPosition += RealCount;
|
||||
return RealCount;
|
||||
}
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
if (UnderlyingStream.CanSeek)
|
||||
{
|
||||
ReadPosition = UnderlyingStream.Seek(offset, origin);
|
||||
return ReadPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
long NewPosition = 0;
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin.Begin:
|
||||
NewPosition = offset;
|
||||
break;
|
||||
case SeekOrigin.Current:
|
||||
NewPosition = ReadPosition + offset;
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
NewPosition = UnderlyingStreamLength - offset;
|
||||
break;
|
||||
}
|
||||
if (NewPosition < 0 || NewPosition > UnderlyingStreamLength)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(offset));
|
||||
}
|
||||
|
||||
if (NewPosition < ReadPosition)
|
||||
{
|
||||
UnderlyingStream.Close();
|
||||
UnderlyingStream = StreamInitializer();
|
||||
ReadPosition = 0;
|
||||
}
|
||||
ulong Remaining;
|
||||
byte[] Buffer = new byte[16384];
|
||||
while (ReadPosition < NewPosition)
|
||||
{
|
||||
Remaining = (ulong)(NewPosition - ReadPosition);
|
||||
if (Remaining > (ulong)Buffer.Length)
|
||||
{
|
||||
Remaining = (ulong)Buffer.Length;
|
||||
}
|
||||
|
||||
UnderlyingStream.Read(Buffer, 0, (int)Remaining);
|
||||
ReadPosition += (long)Remaining;
|
||||
}
|
||||
return ReadPosition;
|
||||
}
|
||||
}
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
return ReadPosition;
|
||||
}
|
||||
set
|
||||
{
|
||||
Seek(value, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
public override bool CanTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnderlyingStream.CanTimeout;
|
||||
}
|
||||
}
|
||||
public override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnderlyingStreamLength;
|
||||
}
|
||||
}
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
public override void Close()
|
||||
{
|
||||
UnderlyingStream.Close();
|
||||
}
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
UnderlyingStream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
#if PREVIEW
|
||||
internal static class Uploader
|
||||
{
|
||||
internal static List<Task> Uploads = [];
|
||||
|
||||
internal static void Upload(string FileName, string Text)
|
||||
{
|
||||
byte[] byteArray = Encoding.UTF8.GetBytes(Text);
|
||||
MemoryStream FileStream = new(byteArray);
|
||||
Upload(FileName, FileStream);
|
||||
}
|
||||
|
||||
internal static void Upload(string FileName, byte[] Data)
|
||||
{
|
||||
Upload(FileName, new MemoryStream(Data));
|
||||
}
|
||||
|
||||
internal static void Upload(string FileName, Stream FileStream)
|
||||
{
|
||||
//TODO: Fix
|
||||
//Upload(new Uri(@"https://www.wpinternals.net/upload.php", UriKind.Absolute), "uploadedfile", FileName, FileStream);
|
||||
}
|
||||
|
||||
private static void Upload(Uri Address, string InputName, string FileName, Stream FileStream)
|
||||
{
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||
System.Net.Http.HttpClient httpClient = new();
|
||||
System.Net.Http.MultipartFormDataContent form = [];
|
||||
System.Net.Http.StreamContent Content = new(FileStream);
|
||||
Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");
|
||||
form.Add(Content, InputName, FileName);
|
||||
Task<System.Net.Http.HttpResponseMessage> UploadTask = httpClient.PostAsync(Address, form);
|
||||
|
||||
Uploads.Add(
|
||||
UploadTask.ContinueWith((t) =>
|
||||
{
|
||||
Uploads.Remove(t);
|
||||
httpClient.Dispose();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
internal static void WaitForUploads()
|
||||
{
|
||||
Task.WaitAll([.. Uploads]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal class WPinternalsException : Exception
|
||||
{
|
||||
// Message and SubMessaage are always printable
|
||||
internal string SubMessage = null;
|
||||
|
||||
internal WPinternalsException() : base() { }
|
||||
|
||||
internal WPinternalsException(string Message) : base(Message) { }
|
||||
|
||||
internal WPinternalsException(string Message, Exception InnerException) : base(Message, InnerException) { }
|
||||
|
||||
internal WPinternalsException(string Message, string SubMessage) : base(Message) { this.SubMessage = SubMessage; }
|
||||
|
||||
internal WPinternalsException(string Message, string SubMessage, Exception InnerException) : base(Message, InnerException) { this.SubMessage = SubMessage; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
internal enum WPinternalsStatus
|
||||
{
|
||||
Undefined,
|
||||
Scanning,
|
||||
Flashing,
|
||||
Patching,
|
||||
WaitingForManualReset,
|
||||
SwitchingMode,
|
||||
Initializing
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// Some of the classes and functions in this file were found online.
|
||||
// Where possible the original authors are referenced.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace WPinternals.HelperClasses
|
||||
{
|
||||
// This class is taken from the Prism library by Microsoft Patterns & Practices
|
||||
// License: http://compositewpf.codeplex.com/license
|
||||
internal static class WeakEventHandlerManager
|
||||
{
|
||||
public static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler, int defaultListSize)
|
||||
{
|
||||
(handlers ??= defaultListSize > 0 ? new List<WeakReference>(defaultListSize) : []).Add(new WeakReference(handler));
|
||||
}
|
||||
|
||||
private static void CallHandler(object sender, EventHandler eventHandler)
|
||||
{
|
||||
DispatcherProxy proxy = DispatcherProxy.CreateDispatcher();
|
||||
if (eventHandler != null)
|
||||
{
|
||||
if (proxy?.CheckAccess() == false)
|
||||
{
|
||||
proxy.BeginInvoke(new Action<object, EventHandler>(CallHandler), [sender, eventHandler]);
|
||||
}
|
||||
else
|
||||
{
|
||||
eventHandler(sender, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CallWeakReferenceHandlers(object sender, List<WeakReference> handlers)
|
||||
{
|
||||
if (handlers != null)
|
||||
{
|
||||
EventHandler[] callees = new EventHandler[handlers.Count];
|
||||
int count = 0;
|
||||
count = CleanupOldHandlers(handlers, callees, count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
CallHandler(sender, callees[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int CleanupOldHandlers(List<WeakReference> handlers, EventHandler[] callees, int count)
|
||||
{
|
||||
for (int i = handlers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
WeakReference reference = handlers[i];
|
||||
if (reference.Target is not EventHandler target)
|
||||
{
|
||||
handlers.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
callees[count] = target;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static void RemoveWeakReferenceHandler(List<WeakReference> handlers, EventHandler handler)
|
||||
{
|
||||
if (handlers != null)
|
||||
{
|
||||
for (int i = handlers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
WeakReference reference = handlers[i];
|
||||
if (reference.Target is not EventHandler target || target == handler)
|
||||
{
|
||||
handlers.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DispatcherProxy
|
||||
{
|
||||
private readonly Dispatcher innerDispatcher;
|
||||
|
||||
private DispatcherProxy(Dispatcher dispatcher)
|
||||
{
|
||||
innerDispatcher = dispatcher;
|
||||
}
|
||||
|
||||
public DispatcherOperation BeginInvoke(Delegate method, params object[] args)
|
||||
{
|
||||
return innerDispatcher.BeginInvoke(method, DispatcherPriority.Normal, args);
|
||||
}
|
||||
|
||||
public bool CheckAccess()
|
||||
{
|
||||
return innerDispatcher.CheckAccess();
|
||||
}
|
||||
|
||||
public static DispatcherProxy CreateDispatcher()
|
||||
{
|
||||
if (Application.Current == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new DispatcherProxy(Application.Current.Dispatcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,7 +388,7 @@ namespace WPinternals
|
||||
unchecked
|
||||
{
|
||||
uint crc = (uint)(((uint)0) ^ (-1));
|
||||
for (var i = Offset; i < (Offset + Length); i++)
|
||||
for (uint i = Offset; i < (Offset + Length); i++)
|
||||
{
|
||||
crc = (crc >> 8) ^ CRC32Table[(crc ^ Input[i]) & 0xFF];
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -288,7 +289,7 @@ namespace WPinternals
|
||||
Partition Target = GPT.Partitions.Find(p => string.Equals(p.Name, Name, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (Target == null)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException(nameof(Name));
|
||||
}
|
||||
|
||||
return GetSectors((int)Target.FirstSector, (int)(Target.LastSector - Target.FirstSector + 1));
|
||||
@@ -314,7 +315,7 @@ namespace WPinternals
|
||||
Partition Target = GPT.Partitions.Find(p => string.Equals(p.Name, Name, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (Target == null)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException(nameof(Name));
|
||||
}
|
||||
|
||||
int FirstChunk = GetChunkIndexFromSectorIndex((int)Target.FirstSector);
|
||||
|
||||
@@ -24,6 +24,7 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
+207
-65
@@ -31,8 +31,9 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.Lumia.MSR
|
||||
{
|
||||
internal static class LumiaDownloadModel
|
||||
{
|
||||
@@ -301,12 +302,12 @@ namespace WPinternals
|
||||
|
||||
private static bool IsFirmwareBetween(string PhoneFirmwareRevision, string Limit1, string Limit2)
|
||||
{
|
||||
var version = new Version(PhoneFirmwareRevision);
|
||||
var version1 = new Version(Limit1);
|
||||
var version2 = new Version(Limit2);
|
||||
Version version = new Version(PhoneFirmwareRevision);
|
||||
Version version1 = new Version(Limit1);
|
||||
Version version2 = new Version(Limit2);
|
||||
|
||||
var result = version.CompareTo(version1);
|
||||
var result2 = version.CompareTo(version2);
|
||||
int result = version.CompareTo(version1);
|
||||
int result2 = version.CompareTo(version2);
|
||||
|
||||
return result >= 0 && result2 <= 0;
|
||||
}
|
||||
@@ -321,7 +322,7 @@ namespace WPinternals
|
||||
|
||||
LogFile.Log("Getting Emergency files for: " + ProductType, LogType.FileAndConsole);
|
||||
|
||||
if ((ProductType == "RM-1072") || (ProductType == "RM-1073"))
|
||||
if (ProductType == "RM-1072" || ProductType == "RM-1073")
|
||||
{
|
||||
LogFile.Log("Due to mix-up in online-repository, redirecting to emergency files of RM-1113", LogType.FileAndConsole);
|
||||
ProductType = "RM-1113";
|
||||
@@ -486,20 +487,20 @@ namespace WPinternals
|
||||
|
||||
public DiscoveryParameters(DiscoveryCondition Condition)
|
||||
{
|
||||
this.apiVersion = "1";
|
||||
this.query = new DiscoveryQueryParameters();
|
||||
this.condition = [];
|
||||
apiVersion = "1";
|
||||
query = new DiscoveryQueryParameters();
|
||||
condition = [];
|
||||
if (Condition == DiscoveryCondition.All)
|
||||
{
|
||||
this.condition.Add("all");
|
||||
condition.Add("all");
|
||||
return;
|
||||
}
|
||||
if (Condition == DiscoveryCondition.Latest)
|
||||
{
|
||||
this.condition.Add("latest");
|
||||
condition.Add("latest");
|
||||
return;
|
||||
}
|
||||
this.condition.Add("default");
|
||||
condition.Add("default");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,18 +518,18 @@ namespace WPinternals
|
||||
|
||||
public ExtendedAttributes()
|
||||
{
|
||||
this.Dictionary = [];
|
||||
Dictionary = [];
|
||||
}
|
||||
|
||||
protected ExtendedAttributes(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info != null)
|
||||
{
|
||||
this.Dictionary = [];
|
||||
Dictionary = [];
|
||||
SerializationInfoEnumerator Enumerator = info.GetEnumerator();
|
||||
while (Enumerator.MoveNext())
|
||||
{
|
||||
this.Dictionary.Add(Enumerator.Current.Name, (string)Enumerator.Current.Value);
|
||||
Dictionary.Add(Enumerator.Current.Name, (string)Enumerator.Current.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -537,9 +538,9 @@ namespace WPinternals
|
||||
{
|
||||
if (info != null)
|
||||
{
|
||||
foreach (string Current in this.Dictionary.Keys)
|
||||
foreach (string Current in Dictionary.Keys)
|
||||
{
|
||||
info.AddValue(Current, this.Dictionary[Current]);
|
||||
info.AddValue(Current, Dictionary[Current]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -651,209 +652,350 @@ namespace WPinternals
|
||||
public class BasicProductCodes
|
||||
{
|
||||
[XmlElement(ElementName = "BasicProductCode")]
|
||||
public List<string> BasicProductCode { get; set; }
|
||||
public List<string> BasicProductCode
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Identification")]
|
||||
public class Identification
|
||||
{
|
||||
[XmlElement(ElementName = "TypeDesignator")]
|
||||
public string TypeDesignator { get; set; }
|
||||
public string TypeDesignator
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "BasicProductCodes")]
|
||||
public BasicProductCodes BasicProductCodes { get; set; }
|
||||
public BasicProductCodes BasicProductCodes
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Purpose")]
|
||||
public string Purpose { get; set; }
|
||||
public string Purpose
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Extensions")]
|
||||
public class Extensions
|
||||
{
|
||||
[XmlElement(ElementName = "PackageType")]
|
||||
public string PackageType { get; set; }
|
||||
public string PackageType
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Identification")]
|
||||
public Identification Identification { get; set; }
|
||||
public Identification Identification
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "FileType")]
|
||||
public string FileType { get; set; }
|
||||
public string FileType
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "MmosWimFile")]
|
||||
public MmosWimFile MmosWimFile { get; set; }
|
||||
public MmosWimFile MmosWimFile
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "PackageDescription")]
|
||||
public class PackageDescription
|
||||
{
|
||||
[XmlElement(ElementName = "Identifier")]
|
||||
public string Identifier { get; set; }
|
||||
public string Identifier
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Revision")]
|
||||
public string Revision { get; set; }
|
||||
public string Revision
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Extensions")]
|
||||
public Extensions Extensions { get; set; }
|
||||
public Extensions Extensions
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Digest")]
|
||||
public class Digest
|
||||
{
|
||||
[XmlAttribute(AttributeName = "method")]
|
||||
public string Method { get; set; }
|
||||
public string Method
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlAttribute(AttributeName = "encoding")]
|
||||
public string Encoding { get; set; }
|
||||
public string Encoding
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlText]
|
||||
public string Text { get; set; }
|
||||
public string Text
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Digests")]
|
||||
public class Digests
|
||||
{
|
||||
[XmlElement(ElementName = "Digest")]
|
||||
public List<Digest> Digest { get; set; }
|
||||
public List<Digest> Digest
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Range")]
|
||||
public class Range
|
||||
{
|
||||
[XmlAttribute(AttributeName = "from")]
|
||||
public string From { get; set; }
|
||||
public string From
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlAttribute(AttributeName = "to")]
|
||||
public string To { get; set; }
|
||||
public string To
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Compatibility")]
|
||||
public class Compatibility
|
||||
{
|
||||
[XmlElement(ElementName = "Range")]
|
||||
public Range Range { get; set; }
|
||||
public Range Range
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlAttribute(AttributeName = "useCase")]
|
||||
public string UseCase { get; set; }
|
||||
public string UseCase
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "UseCaseCompatibilities")]
|
||||
public class UseCaseCompatibilities
|
||||
{
|
||||
[XmlElement(ElementName = "Compatibility")]
|
||||
public List<Compatibility> Compatibility { get; set; }
|
||||
public List<Compatibility> Compatibility
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "MmosWimFile")]
|
||||
public class MmosWimFile
|
||||
{
|
||||
[XmlElement(ElementName = "UseCaseCompatibilities")]
|
||||
public UseCaseCompatibilities UseCaseCompatibilities { get; set; }
|
||||
public UseCaseCompatibilities UseCaseCompatibilities
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "File")]
|
||||
public class File
|
||||
{
|
||||
[XmlElement(ElementName = "Name")]
|
||||
public string Name { get; set; }
|
||||
public string Name
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Digests")]
|
||||
public Digests Digests { get; set; }
|
||||
public Digests Digests
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Revision")]
|
||||
public string Revision { get; set; }
|
||||
public string Revision
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Extensions")]
|
||||
public Extensions Extensions { get; set; }
|
||||
public Extensions Extensions
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Files")]
|
||||
public class Files
|
||||
{
|
||||
[XmlElement(ElementName = "File")]
|
||||
public List<File> File { get; set; }
|
||||
public List<File> File
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Content")]
|
||||
public class Content
|
||||
{
|
||||
[XmlElement(ElementName = "PackageDescription")]
|
||||
public PackageDescription PackageDescription { get; set; }
|
||||
public PackageDescription PackageDescription
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Files")]
|
||||
public Files Files { get; set; }
|
||||
public Files Files
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "CanonicalizationMethod", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class CanonicalizationMethod
|
||||
{
|
||||
[XmlAttribute(AttributeName = "Algorithm")]
|
||||
public string Algorithm { get; set; }
|
||||
public string Algorithm
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "SignatureMethod", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class SignatureMethod
|
||||
{
|
||||
[XmlAttribute(AttributeName = "Algorithm")]
|
||||
public string Algorithm { get; set; }
|
||||
public string Algorithm
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Transform", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class Transform
|
||||
{
|
||||
[XmlAttribute(AttributeName = "Algorithm")]
|
||||
public string Algorithm { get; set; }
|
||||
public string Algorithm
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Transforms", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class Transforms
|
||||
{
|
||||
[XmlElement(ElementName = "Transform", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public Transform Transform { get; set; }
|
||||
public Transform Transform
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "DigestMethod", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class DigestMethod
|
||||
{
|
||||
[XmlAttribute(AttributeName = "Algorithm")]
|
||||
public string Algorithm { get; set; }
|
||||
public string Algorithm
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Reference", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class Reference
|
||||
{
|
||||
[XmlElement(ElementName = "Transforms", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public Transforms Transforms { get; set; }
|
||||
public Transforms Transforms
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "DigestMethod", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public DigestMethod DigestMethod { get; set; }
|
||||
public DigestMethod DigestMethod
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "DigestValue", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public string DigestValue { get; set; }
|
||||
public string DigestValue
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlAttribute(AttributeName = "URI")]
|
||||
public string URI { get; set; }
|
||||
public string URI
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "SignedInfo", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class SignedInfo
|
||||
{
|
||||
[XmlElement(ElementName = "CanonicalizationMethod", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public CanonicalizationMethod CanonicalizationMethod { get; set; }
|
||||
public CanonicalizationMethod CanonicalizationMethod
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "SignatureMethod", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public SignatureMethod SignatureMethod { get; set; }
|
||||
public SignatureMethod SignatureMethod
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Reference", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public Reference Reference { get; set; }
|
||||
public Reference Reference
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "KeyInfo", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class KeyInfo
|
||||
{
|
||||
[XmlElement(ElementName = "KeyName", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public string KeyName { get; set; }
|
||||
public string KeyName
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Signature", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public class Signature
|
||||
{
|
||||
[XmlElement(ElementName = "SignedInfo", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public SignedInfo SignedInfo { get; set; }
|
||||
public SignedInfo SignedInfo
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "SignatureValue", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public string SignatureValue { get; set; }
|
||||
public string SignatureValue
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "KeyInfo", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public KeyInfo KeyInfo { get; set; }
|
||||
public KeyInfo KeyInfo
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlAttribute(AttributeName = "xmlns")]
|
||||
public string Xmlns { get; set; }
|
||||
public string Xmlns
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlRoot(ElementName = "Package")]
|
||||
public class Package
|
||||
{
|
||||
[XmlElement(ElementName = "Content")]
|
||||
public Content Content { get; set; }
|
||||
public Content Content
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
[XmlElement(ElementName = "Signature", Namespace = "http://www.w3.org/2000/09/xmldsig#")]
|
||||
public Signature Signature { get; set; }
|
||||
public Signature Signature
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
-132
@@ -18,32 +18,20 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using MadWizard.WinUSBNet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.Lumia.NCSd
|
||||
{
|
||||
internal class NokiaPhoneModel : IDisposable
|
||||
internal class NokiaCareSuiteModel : NokiaPhoneModel
|
||||
{
|
||||
protected bool Disposed = false;
|
||||
private readonly USBDevice Device = null;
|
||||
private int MessageId = 0;
|
||||
private readonly object UsbLock = new();
|
||||
|
||||
public NokiaPhoneModel(string DevicePath)
|
||||
public NokiaCareSuiteModel(string DevicePath) : base(DevicePath)
|
||||
{
|
||||
// Mass Storage device is not WinUSB
|
||||
try
|
||||
{
|
||||
Device = new USBDevice(DevicePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogFile.LogException(ex, LogType.FileOnly);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private JsonElement? ExecuteJsonMethodAsJsonToken(string JsonMethod, Dictionary<string, object> Params, string ResultElement)
|
||||
@@ -72,7 +60,13 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
@params.Add("MessageVersion", 0);
|
||||
string Request = JsonSerializer.Serialize(new { jsonrpc, id, method, @params });
|
||||
string Request = JsonSerializer.Serialize(new
|
||||
{
|
||||
jsonrpc,
|
||||
id,
|
||||
method,
|
||||
@params
|
||||
});
|
||||
Device.OutputPipe.Write(System.Text.Encoding.ASCII.GetBytes(Request));
|
||||
|
||||
Buffer = new byte[0x10000];
|
||||
@@ -84,7 +78,7 @@ namespace WPinternals
|
||||
try
|
||||
{
|
||||
JsonElement? ResultToken = ResultMessage.RootElement.GetProperty("result");
|
||||
if ((ResultToken == null) || (ResultElement == null))
|
||||
if (ResultToken == null || ResultElement == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -207,7 +201,13 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
@params.Add("MessageVersion", 0);
|
||||
string Request = JsonSerializer.Serialize(new { jsonrpc, id, method, @params });
|
||||
string Request = JsonSerializer.Serialize(new
|
||||
{
|
||||
jsonrpc,
|
||||
id,
|
||||
method,
|
||||
@params
|
||||
});
|
||||
|
||||
byte[] OutBuffer = System.Text.Encoding.ASCII.GetBytes(Request);
|
||||
Device.OutputPipe.BeginWrite(OutBuffer, 0, OutBuffer.Length, (AsyncResultWrite) => Device.OutputPipe.EndWrite(AsyncResultWrite), null);
|
||||
@@ -295,28 +295,34 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
@params.Add("MessageVersion", 0);
|
||||
string Request = JsonSerializer.Serialize(new { jsonrpc, id, method, @params });
|
||||
string Request = JsonSerializer.Serialize(new
|
||||
{
|
||||
jsonrpc,
|
||||
id,
|
||||
method,
|
||||
@params
|
||||
});
|
||||
|
||||
byte[] OutBuffer = System.Text.Encoding.ASCII.GetBytes(Request);
|
||||
Device.OutputPipe.BeginWrite(OutBuffer, 0, OutBuffer.Length, (AsyncResultWrite) =>
|
||||
{
|
||||
Device.OutputPipe.EndWrite(AsyncResultWrite);
|
||||
Buffer = new byte[0x10000];
|
||||
Device.InputPipe.BeginRead(Buffer, 0, 0x10000, (AsyncResultRead) =>
|
||||
{
|
||||
Device.OutputPipe.EndWrite(AsyncResultWrite);
|
||||
Buffer = new byte[0x10000];
|
||||
Device.InputPipe.BeginRead(Buffer, 0, 0x10000, (AsyncResultRead) =>
|
||||
{
|
||||
Length = Device.InputPipe.EndRead(AsyncResultRead);
|
||||
Length = Device.InputPipe.EndRead(AsyncResultRead);
|
||||
|
||||
JsonDocument ResultMessage = JsonDocument.Parse(System.Text.Encoding.ASCII.GetString(Buffer, 0, Length));
|
||||
JsonDocument ResultMessage = JsonDocument.Parse(System.Text.Encoding.ASCII.GetString(Buffer, 0, Length));
|
||||
|
||||
JsonElement? ResultToken = ResultMessage.RootElement.GetProperty("result");
|
||||
if ((ResultToken == null) || (ResultElement == null))
|
||||
{
|
||||
Callback(AsyncResultRead.AsyncState, null);
|
||||
}
|
||||
JsonElement? ResultToken = ResultMessage.RootElement.GetProperty("result");
|
||||
if (ResultToken == null || ResultElement == null)
|
||||
{
|
||||
Callback(AsyncResultRead.AsyncState, null);
|
||||
}
|
||||
|
||||
Callback(AsyncResultRead.AsyncState, ResultToken.Value.GetProperty(ResultElement));
|
||||
}, AsyncResultWrite.AsyncState);
|
||||
}, State);
|
||||
Callback(AsyncResultRead.AsyncState, ResultToken.Value.GetProperty(ResultElement));
|
||||
}, AsyncResultWrite.AsyncState);
|
||||
}, State);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,103 +330,5 @@ namespace WPinternals
|
||||
{
|
||||
ExecuteJsonMethodAsTokenAsync(JsonMethod, null, ResultElement, State, Callback);
|
||||
}
|
||||
|
||||
public byte[] ExecuteRawMethod(byte[] RawMethod)
|
||||
{
|
||||
return ExecuteRawMethod(RawMethod, RawMethod.Length);
|
||||
}
|
||||
|
||||
public byte[] ExecuteRawMethod(byte[] RawMethod, int Length)
|
||||
{
|
||||
byte[] Buffer = new byte[0x8000]; // Should be at least 0x4408 for receiving the GPT packet.
|
||||
byte[] Result = null;
|
||||
lock (UsbLock)
|
||||
{
|
||||
Device.OutputPipe.Write(RawMethod, 0, Length);
|
||||
try
|
||||
{
|
||||
int OutputLength = Device.InputPipe.Read(Buffer);
|
||||
Result = new byte[OutputLength];
|
||||
System.Buffer.BlockCopy(Buffer, 0, Result, 0, OutputLength);
|
||||
}
|
||||
catch (Exception ex) // Reboot command looses connection
|
||||
{
|
||||
LogFile.LogException(ex, LogType.FileOnly);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
public void ExecuteRawVoidMethod(byte[] RawMethod)
|
||||
{
|
||||
ExecuteRawVoidMethod(RawMethod, RawMethod.Length);
|
||||
}
|
||||
|
||||
public void ExecuteRawVoidMethod(byte[] RawMethod, int Length)
|
||||
{
|
||||
lock (UsbLock)
|
||||
{
|
||||
Device.OutputPipe.Write(RawMethod, 0, Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetDevice()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var pipe in Device.Pipes)
|
||||
{
|
||||
pipe.Abort();
|
||||
pipe.Reset();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogFile.LogException(ex, LogType.FileOnly);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the UsbDevice including all unmanaged WinUSB handles. This function
|
||||
/// should be called when the UsbDevice object is no longer in use, otherwise
|
||||
/// unmanaged handles will remain open until the garbage collector finalizes the
|
||||
/// object.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer for the UsbDevice. Disposes all unmanaged handles.
|
||||
/// </summary>
|
||||
~NokiaPhoneModel()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the object
|
||||
/// </summary>
|
||||
/// <param name="disposing">Indicates wether Dispose was called manually (true) or by
|
||||
/// the garbage collector (false) via the destructor.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Device?.Dispose();
|
||||
}
|
||||
|
||||
// Clean unmanaged resources here.
|
||||
// (none currently)
|
||||
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using MadWizard.WinUSBNet;
|
||||
using System;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals.Models.Lumia
|
||||
{
|
||||
internal class NokiaPhoneModel : IDisposable
|
||||
{
|
||||
protected bool Disposed = false;
|
||||
internal readonly USBDevice Device = null;
|
||||
internal readonly object UsbLock = new();
|
||||
|
||||
public NokiaPhoneModel(string DevicePath)
|
||||
{
|
||||
// Mass Storage device is not WinUSB
|
||||
try
|
||||
{
|
||||
Device = new USBDevice(DevicePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogFile.LogException(ex, LogType.FileOnly);
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetDevice()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (USBPipe pipe in Device.Pipes)
|
||||
{
|
||||
pipe.Abort();
|
||||
pipe.Reset();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogFile.LogException(ex, LogType.FileOnly);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the UsbDevice including all unmanaged WinUSB handles. This function
|
||||
/// should be called when the UsbDevice object is no longer in use, otherwise
|
||||
/// unmanaged handles will remain open until the garbage collector finalizes the
|
||||
/// object.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer for the UsbDevice. Disposes all unmanaged handles.
|
||||
/// </summary>
|
||||
~NokiaPhoneModel()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the object
|
||||
/// </summary>
|
||||
/// <param name="disposing">Indicates wether Dispose was called manually (true) or by
|
||||
/// the garbage collector (false) via the destructor.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Device?.Dispose();
|
||||
}
|
||||
|
||||
// Clean unmanaged resources here.
|
||||
// (none currently)
|
||||
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
-10
@@ -19,8 +19,10 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.UEFIApps.BootMgr
|
||||
{
|
||||
internal class LumiaBootManagerAppModel : NokiaUEFIModel
|
||||
{
|
||||
@@ -94,6 +96,26 @@ namespace WPinternals
|
||||
{
|
||||
}
|
||||
|
||||
internal void ResetToMassStorageMode()
|
||||
{
|
||||
byte[] Request = new byte[4];
|
||||
ByteOperations.WriteAsciiString(Request, 0, RebootToMassStorageSignature);
|
||||
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
|
||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("SendCommonExtendedSwitchToCommand: Error 0x" + Error.ToString("X4"));
|
||||
}
|
||||
}
|
||||
|
||||
internal void ContinueBoot()
|
||||
{
|
||||
LogFile.Log("Continue boot...");
|
||||
@@ -132,7 +154,7 @@ namespace WPinternals
|
||||
byte[] Request = new byte[4];
|
||||
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||
if (Response != null && ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU")
|
||||
{
|
||||
Result.App = (FlashAppType)Response[5];
|
||||
|
||||
@@ -155,9 +177,8 @@ namespace WPinternals
|
||||
|
||||
LogFile.Log($"{Result.App} SubblockID: 0x{SubblockID:X}");
|
||||
|
||||
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||
ushort SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||
int SubblockPayloadOffset = SubblockOffset + 3;
|
||||
byte SubblockVersion;
|
||||
switch (SubblockID)
|
||||
{
|
||||
case 0x01:
|
||||
@@ -200,12 +221,12 @@ namespace WPinternals
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
|
||||
byte[] Buffer = ExecuteRawMethod(Request);
|
||||
if ((Buffer == null) || (Buffer.Length < 0x4408))
|
||||
if (Buffer == null || Buffer.Length < 0x4408)
|
||||
{
|
||||
throw new InvalidOperationException("Unable to read GPT!");
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
|
||||
ushort Error = (ushort)((Buffer[6] << 8) + Buffer[7]);
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
|
||||
@@ -217,7 +238,7 @@ namespace WPinternals
|
||||
return new GPT(GPTBuffer); // NOKT message header and MBR are ignored
|
||||
}
|
||||
|
||||
internal byte[] GetGptChunk(UInt32 Size) // TODO!
|
||||
internal byte[] GetGptChunk(uint Size) // TODO!
|
||||
{
|
||||
// This function is also used to generate a dummy chunk to flash for testing.
|
||||
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
|
||||
@@ -229,12 +250,12 @@ namespace WPinternals
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
|
||||
byte[] Buffer = ExecuteRawMethod(Request);
|
||||
if ((Buffer == null) || (Buffer.Length < 0x4408))
|
||||
if (Buffer == null || Buffer.Length < 0x4408)
|
||||
{
|
||||
throw new InvalidOperationException("Unable to read GPT!");
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
|
||||
ushort Error = (ushort)((Buffer[6] << 8) + Buffer[7]);
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
|
||||
@@ -252,7 +273,7 @@ namespace WPinternals
|
||||
Request[6] = 0; // Options
|
||||
Request[7] = (byte)KeyType;
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
UInt32 Status = ByteOperations.ReadUInt32(Response, 6);
|
||||
uint Status = ByteOperations.ReadUInt32(Response, 6);
|
||||
if (Status != 0)
|
||||
{
|
||||
ThrowFlashError((int)Status);
|
||||
+4
-2
@@ -19,8 +19,10 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.UEFIApps.BootMgr
|
||||
{
|
||||
internal class LumiaBootManagerPhoneInfo
|
||||
{
|
||||
@@ -38,7 +40,7 @@ namespace WPinternals
|
||||
public byte BootManagerProtocolVersionMajor;
|
||||
public byte BootManagerProtocolVersionMinor;
|
||||
|
||||
public UInt32 TransferSize;
|
||||
public uint TransferSize;
|
||||
public bool MmosOverUsbSupported;
|
||||
|
||||
internal void Log(LogType Type)
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals.Models.Lumia.UEFI
|
||||
{
|
||||
internal class CommonPhoneInfo
|
||||
{
|
||||
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||
|
||||
public FlashAppType App;
|
||||
|
||||
public byte VersionMajor;
|
||||
public byte VersionMinor;
|
||||
public byte ProtocolVersionMajor;
|
||||
public byte ProtocolVersionMinor;
|
||||
|
||||
internal void Log(LogType Type)
|
||||
{
|
||||
LogFile.Log($"App: {VersionMajor}.{VersionMinor}", Type);
|
||||
LogFile.Log($"Protocol: {ProtocolVersionMajor}.{ProtocolVersionMinor}", Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace WPinternals.Models.UEFIApps.Flash
|
||||
{
|
||||
internal enum FfuProtocol
|
||||
{
|
||||
ProtocolSyncV1 = 1,
|
||||
ProtocolAsyncV1 = 2,
|
||||
ProtocolSyncV2 = 4,
|
||||
ProtocolAsyncV2 = 8,
|
||||
ProtocolAsyncV3 = 16
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.Models.UEFIApps.Flash
|
||||
{
|
||||
[Flags]
|
||||
internal enum FlashOptions : byte
|
||||
{
|
||||
SkipWrite = 1,
|
||||
SkipHashCheck = 2,
|
||||
SkipIdCheck = 4,
|
||||
SkipSignatureCheck = 8
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.Lumia.UEFI.Flash
|
||||
{
|
||||
internal class FlashVersion
|
||||
{
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.Models.UEFIApps.Flash
|
||||
{
|
||||
[Flags]
|
||||
internal enum Fuse
|
||||
{
|
||||
SecureBoot = 1,
|
||||
FfuVerify = 2,
|
||||
Jtag = 4,
|
||||
Shk = 8,
|
||||
Simlock = 16,
|
||||
ProductionDone = 32,
|
||||
Rkh = 64,
|
||||
PublicId = 128,
|
||||
Dak = 256,
|
||||
SecGen = 512,
|
||||
OemId = 1024,
|
||||
FastBoot = 2048,
|
||||
SpdmSecMode = 4096,
|
||||
RpmWdog = 8192,
|
||||
Ssm = 16384
|
||||
}
|
||||
}
|
||||
+104
-87
@@ -21,53 +21,14 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI;
|
||||
using WPinternals.Models.Lumia.UEFI.Flash;
|
||||
using WPinternals.Terminal;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.UEFIApps.Flash
|
||||
{
|
||||
internal enum SecureBootKeyType : byte
|
||||
{
|
||||
Retail = 0,
|
||||
Engineering = 1
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum Fuse
|
||||
{
|
||||
SecureBoot = 1,
|
||||
FfuVerify = 2,
|
||||
Jtag = 4,
|
||||
Shk = 8,
|
||||
Simlock = 16,
|
||||
ProductionDone = 32,
|
||||
Rkh = 64,
|
||||
PublicId = 128,
|
||||
Dak = 256,
|
||||
SecGen = 512,
|
||||
OemId = 1024,
|
||||
FastBoot = 2048,
|
||||
SpdmSecMode = 4096,
|
||||
RpmWdog = 8192,
|
||||
Ssm = 16384
|
||||
}
|
||||
|
||||
internal enum FfuProtocol
|
||||
{
|
||||
ProtocolSyncV1 = 1,
|
||||
ProtocolAsyncV1 = 2,
|
||||
ProtocolSyncV2 = 4,
|
||||
ProtocolAsyncV2 = 8,
|
||||
ProtocolAsyncV3 = 16
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum FlashOptions : byte
|
||||
{
|
||||
SkipWrite = 1,
|
||||
SkipHashCheck = 2,
|
||||
SkipIdCheck = 4,
|
||||
SkipSignatureCheck = 8
|
||||
}
|
||||
|
||||
internal class LumiaFlashAppModel : NokiaUEFIModel
|
||||
{
|
||||
internal readonly LumiaFlashAppPhoneInfo FlashAppInfo = new();
|
||||
@@ -157,6 +118,62 @@ namespace WPinternals
|
||||
{
|
||||
}
|
||||
|
||||
public void WriteParam(string Param, byte[] Value)
|
||||
{
|
||||
// Command: NOKXFW
|
||||
// Padding (one byte)
|
||||
// Parameter (4 bytes)
|
||||
// Length (4 bytes)
|
||||
// Data
|
||||
|
||||
if (Param.Length > 4)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(Param));
|
||||
}
|
||||
|
||||
byte[] Request = new byte[15 + Param.Length];
|
||||
const string Header = WriteParamSignature;
|
||||
|
||||
Buffer.BlockCopy(Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(Encoding.ASCII.GetBytes(Param), 0, Request, 7, Param.Length);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(Value.Length, 4), 0, Request, 11, 4);
|
||||
Buffer.BlockCopy(Value, 0, Request, 15, Value.Length);
|
||||
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
|
||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("WriteParam: Error 0x" + Error.ToString("X4"));
|
||||
}
|
||||
}
|
||||
|
||||
internal void ResetToMassStorageMode()
|
||||
{
|
||||
byte[] Request = new byte[4];
|
||||
ByteOperations.WriteAsciiString(Request, 0, RebootToMassStorageSignature);
|
||||
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
|
||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("SendCommonExtendedSwitchToCommand: Error 0x" + Error.ToString("X4"));
|
||||
}
|
||||
}
|
||||
|
||||
internal LumiaFlashAppPhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
||||
{
|
||||
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||
@@ -167,7 +184,7 @@ namespace WPinternals
|
||||
|
||||
LumiaFlashAppPhoneInfo Result = FlashAppInfo;
|
||||
|
||||
if (ExtendedInfo && (Result.State == PhoneInfoState.Basic))
|
||||
if (ExtendedInfo && Result.State == PhoneInfoState.Basic)
|
||||
{
|
||||
if (Result.App == FlashAppType.FlashApp)
|
||||
{
|
||||
@@ -198,7 +215,7 @@ namespace WPinternals
|
||||
byte[] Request = new byte[4];
|
||||
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||
if (Response != null && ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU")
|
||||
{
|
||||
Result.App = (FlashAppType)Response[5];
|
||||
|
||||
@@ -221,7 +238,7 @@ namespace WPinternals
|
||||
|
||||
LogFile.Log($"{Result.App} SubblockID: 0x{SubblockID:X}");
|
||||
|
||||
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||
ushort SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||
int SubblockPayloadOffset = SubblockOffset + 3;
|
||||
byte SubblockVersion;
|
||||
switch (SubblockID)
|
||||
@@ -250,7 +267,7 @@ namespace WPinternals
|
||||
Result.SecureFfuEnabled = Response[SubblockPayloadOffset + 0x02] == 0x01;
|
||||
Result.JtagDisabled = Response[SubblockPayloadOffset + 0x03] == 0x01;
|
||||
Result.RdcPresent = Response[SubblockPayloadOffset + 0x04] == 0x01;
|
||||
Result.Authenticated = (Response[SubblockPayloadOffset + 0x05] == 0x01) || (Response[SubblockPayloadOffset + 0x05] == 0x02);
|
||||
Result.Authenticated = Response[SubblockPayloadOffset + 0x05] == 0x01 || Response[SubblockPayloadOffset + 0x05] == 0x02;
|
||||
Result.UefiSecureBootEnabled = Response[SubblockPayloadOffset + 0x06] == 0x01;
|
||||
Result.SecondaryHardwareKeyPresent = Response[SubblockPayloadOffset + 0x07] == 0x01;
|
||||
break;
|
||||
@@ -299,12 +316,12 @@ namespace WPinternals
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
|
||||
byte[] Buffer = ExecuteRawMethod(Request);
|
||||
if ((Buffer == null) || (Buffer.Length < 0x4408))
|
||||
if (Buffer == null || Buffer.Length < 0x4408)
|
||||
{
|
||||
throw new InvalidOperationException("Unable to read GPT!");
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
|
||||
ushort Error = (ushort)((Buffer[6] << 8) + Buffer[7]);
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
|
||||
@@ -316,7 +333,7 @@ namespace WPinternals
|
||||
return new GPT(GPTBuffer); // NOKT message header and MBR are ignored
|
||||
}
|
||||
|
||||
internal byte[] GetGptChunk(UInt32 Size) // TODO!
|
||||
internal byte[] GetGptChunk(uint Size) // TODO!
|
||||
{
|
||||
// This function is also used to generate a dummy chunk to flash for testing.
|
||||
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
|
||||
@@ -336,12 +353,12 @@ namespace WPinternals
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
|
||||
byte[] Buffer = ExecuteRawMethod(Request);
|
||||
if ((Buffer == null) || (Buffer.Length < 0x4408))
|
||||
if (Buffer == null || Buffer.Length < 0x4408)
|
||||
{
|
||||
throw new InvalidOperationException("Unable to read GPT!");
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
|
||||
ushort Error = (ushort)((Buffer[6] << 8) + Buffer[7]);
|
||||
if (Error > 0)
|
||||
{
|
||||
ThrowFlashError(Error);
|
||||
@@ -362,7 +379,7 @@ namespace WPinternals
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Param), 0, Request, 7, Param.Length);
|
||||
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if ((Response == null) || (Response.Length < 0x10))
|
||||
if (Response == null || Response.Length < 0x10)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -386,37 +403,37 @@ namespace WPinternals
|
||||
public uint? ReadSecurityFlags()
|
||||
{
|
||||
byte[] Response = ReadParam("FCS");
|
||||
if ((Response == null) || (Response.Length != 4))
|
||||
if (Response == null || Response.Length != 4)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// This value is in big endian
|
||||
return (UInt32)((Response[0] << 24) | (Response[1] << 16) | (Response[2] << 8) | Response[3]);
|
||||
return (uint)(Response[0] << 24 | Response[1] << 16 | Response[2] << 8 | Response[3]);
|
||||
}
|
||||
|
||||
public uint? ReadCurrentChargeLevel()
|
||||
{
|
||||
byte[] Response = ReadParam("CS");
|
||||
if ((Response == null) || (Response.Length != 8))
|
||||
if (Response == null || Response.Length != 8)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// This value is in big endian
|
||||
return (UInt32)((Response[0] << 24) | (Response[1] << 16) | (Response[2] << 8) | Response[3]) + 1;
|
||||
return (uint)(Response[0] << 24 | Response[1] << 16 | Response[2] << 8 | Response[3]) + 1;
|
||||
}
|
||||
|
||||
public int? ReadCurrentChargeCurrent()
|
||||
{
|
||||
byte[] Response = ReadParam("CS");
|
||||
if ((Response == null) || (Response.Length != 8))
|
||||
if (Response == null || Response.Length != 8)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// This value is in big endian and needs to be XOR'd with 0xFFFFFFFF
|
||||
return (Int32)(((Response[4] << 24) | (Response[5] << 16) | (Response[6] << 8) | Response[7]) ^ 0xFFFFFFFF) + 1;
|
||||
return (int)((Response[4] << 24 | Response[5] << 16 | Response[6] << 8 | Response[7]) ^ 0xFFFFFFFF) + 1;
|
||||
}
|
||||
|
||||
public UefiSecurityStatusResponse ReadSecurityStatus()
|
||||
@@ -451,7 +468,7 @@ namespace WPinternals
|
||||
public FlashVersion GetFlashVersion()
|
||||
{
|
||||
byte[] Response = ReadParam("FAI");
|
||||
if ((Response == null) || (Response.Length < 6))
|
||||
if (Response == null || Response.Length < 6)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -466,7 +483,7 @@ namespace WPinternals
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal UInt16 ReadSecureFfuSupportedProtocolMask()
|
||||
internal ushort ReadSecureFfuSupportedProtocolMask()
|
||||
{
|
||||
return BigEndian.ToUInt16(ReadParam("SFPI"), 0);
|
||||
}
|
||||
@@ -483,10 +500,10 @@ namespace WPinternals
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x00, 4), 0, Request, 0x10, 4); // AsicIndex = 0x00
|
||||
Buffer.BlockCopy(AsskMask, 0, Request, 0x14, 0x10);
|
||||
byte[] TerminalResponse = ExecuteRawMethod(Request);
|
||||
if ((TerminalResponse?.Length > 0x20) && (BigEndian.ToUInt32(TerminalResponse, 0x14) == (TerminalResponse.Length - 0x18)) && (BitConverter.ToUInt32(TerminalResponse, 0x1C) == (TerminalResponse.Length - 0x20)))
|
||||
if (TerminalResponse?.Length > 0x20 && BigEndian.ToUInt32(TerminalResponse, 0x14) == TerminalResponse.Length - 0x18 && BitConverter.ToUInt32(TerminalResponse, 0x1C) == TerminalResponse.Length - 0x20)
|
||||
{
|
||||
// Parse Terminal Response from offset 0x18
|
||||
return Terminal.Parse(TerminalResponse, 0x18);
|
||||
return Terminal.Terminal.Parse(TerminalResponse, 0x18);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -524,7 +541,7 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
public void SendFfuHeaderV2(UInt32 TotalHeaderLength, UInt32 OffsetForThisPart, byte[] FfuHeader, byte Options = 0)
|
||||
public void SendFfuHeaderV2(uint TotalHeaderLength, uint OffsetForThisPart, byte[] FfuHeader, byte Options = 0)
|
||||
{
|
||||
byte[] Request = new byte[FfuHeader.Length + 0x3C];
|
||||
|
||||
@@ -627,7 +644,7 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
public void SendFfuPayloadV3(byte[] FfuChunk, UInt32 WriteDescriptorIndex, UInt32 CRC, int Progress = 0, byte Options = 0)
|
||||
public void SendFfuPayloadV3(byte[] FfuChunk, uint WriteDescriptorIndex, uint CRC, int Progress = 0, byte Options = 0)
|
||||
{
|
||||
byte[] Request = new byte[FfuChunk.Length + 0x20];
|
||||
|
||||
@@ -691,7 +708,7 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadMmosBinary(UInt32 TotalLength, UInt32 Offset, bool SkipMmosSupportCheck, byte[] MmosPart)
|
||||
public void LoadMmosBinary(uint TotalLength, uint Offset, bool SkipMmosSupportCheck, byte[] MmosPart)
|
||||
{
|
||||
byte[] Request = new byte[MmosPart.Length + 0x20];
|
||||
const string Header = LoadSignature;
|
||||
@@ -763,7 +780,7 @@ namespace WPinternals
|
||||
Request[6] = 0; // Options
|
||||
Request[7] = (byte)KeyType;
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
UInt32 Status = ByteOperations.ReadUInt32(Response, 6);
|
||||
uint Status = ByteOperations.ReadUInt32(Response, 6);
|
||||
if (Status != 0)
|
||||
{
|
||||
ThrowFlashError((int)Status);
|
||||
@@ -827,7 +844,7 @@ namespace WPinternals
|
||||
return null;
|
||||
}
|
||||
|
||||
var finalconfig = (Fuse)flags.Value;
|
||||
Fuse finalconfig = (Fuse)flags.Value;
|
||||
return finalconfig.HasFlag(fuse);
|
||||
}
|
||||
|
||||
@@ -842,7 +859,7 @@ namespace WPinternals
|
||||
return null;
|
||||
}
|
||||
|
||||
public void FlashSectors(UInt32 StartSector, byte[] Data, int Progress = 0)
|
||||
public void FlashSectors(uint StartSector, byte[] Data, int Progress = 0)
|
||||
{
|
||||
// Start sector is in UInt32, so max size of eMMC is 2 TB.
|
||||
|
||||
@@ -903,7 +920,7 @@ namespace WPinternals
|
||||
|
||||
byte[] Buffer = NewGPT.Rebuild();
|
||||
|
||||
UInt32? HeaderOffset = ByteOperations.FindAscii(Buffer, "EFI PART");
|
||||
uint? HeaderOffset = ByteOperations.FindAscii(Buffer, "EFI PART");
|
||||
if (HeaderOffset != 0)
|
||||
{
|
||||
throw new BadImageFormatException();
|
||||
@@ -984,14 +1001,14 @@ namespace WPinternals
|
||||
throw new WPinternalsException("Flash failed!", "Protocols not supported. The device reports that both Protocol Sync v1 and Protocol Sync v2 are not supported for FFU flashing. Is this an old device?");
|
||||
}
|
||||
|
||||
UInt64 CombinedFFUHeaderSize = FFU.HeaderSize;
|
||||
ulong CombinedFFUHeaderSize = FFU.HeaderSize;
|
||||
byte[] FfuHeader = new byte[CombinedFFUHeaderSize];
|
||||
using (FileStream FfuFile = new(FFU.Path, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
FfuFile.Read(FfuHeader, 0, (int)CombinedFFUHeaderSize);
|
||||
SendFfuHeaderV1(FfuHeader, Options);
|
||||
|
||||
UInt64 Position = CombinedFFUHeaderSize;
|
||||
ulong Position = CombinedFFUHeaderSize;
|
||||
byte[] Payload;
|
||||
int ChunkCount = 0;
|
||||
|
||||
@@ -1000,7 +1017,7 @@ namespace WPinternals
|
||||
// Protocol v1
|
||||
Payload = new byte[FFU.ChunkSize];
|
||||
|
||||
while (Position < (UInt64)FfuFile.Length)
|
||||
while (Position < (ulong)FfuFile.Length)
|
||||
{
|
||||
FfuFile.Read(Payload, 0, Payload.Length);
|
||||
ChunkCount++;
|
||||
@@ -1015,12 +1032,12 @@ namespace WPinternals
|
||||
// Protocol v2
|
||||
Payload = new byte[Info.WriteBufferSize];
|
||||
|
||||
while (Position < (UInt64)FfuFile.Length)
|
||||
while (Position < (ulong)FfuFile.Length)
|
||||
{
|
||||
UInt32 PayloadSize = Info.WriteBufferSize;
|
||||
if (((UInt64)FfuFile.Length - Position) < PayloadSize)
|
||||
uint PayloadSize = Info.WriteBufferSize;
|
||||
if ((ulong)FfuFile.Length - Position < PayloadSize)
|
||||
{
|
||||
PayloadSize = (UInt32)((UInt64)FfuFile.Length - Position);
|
||||
PayloadSize = (uint)((ulong)FfuFile.Length - Position);
|
||||
Payload = new byte[PayloadSize];
|
||||
}
|
||||
|
||||
@@ -1124,25 +1141,25 @@ namespace WPinternals
|
||||
{
|
||||
using (InputStream)
|
||||
{
|
||||
UInt64? InputStreamLength = null;
|
||||
ulong? InputStreamLength = null;
|
||||
try
|
||||
{
|
||||
InputStreamLength = (UInt64)InputStream.Length;
|
||||
InputStreamLength = (ulong)InputStream.Length;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogFile.LogException(ex, LogType.FileOnly);
|
||||
}
|
||||
|
||||
if ((InputStreamLength != null) && ((UInt64)InputStream.Length > PartitionSize))
|
||||
if (InputStreamLength != null && (ulong)InputStream.Length > PartitionSize)
|
||||
{
|
||||
throw new InvalidOperationException("Partition can not be flashed, because its size is too big!");
|
||||
}
|
||||
|
||||
ProgressUpdater Progress = UpdaterPerSector;
|
||||
if ((Progress == null) && (ProgressUpdateCallback != null) && (InputStreamLength != null))
|
||||
if (Progress == null && ProgressUpdateCallback != null && InputStreamLength != null)
|
||||
{
|
||||
Progress = new ProgressUpdater((UInt64)(InputStreamLength / 0x200), ProgressUpdateCallback);
|
||||
Progress = new ProgressUpdater((ulong)(InputStreamLength / 0x200), ProgressUpdateCallback);
|
||||
}
|
||||
|
||||
int ProgressPercentage = 0;
|
||||
@@ -1150,7 +1167,7 @@ namespace WPinternals
|
||||
const int FlashBufferSize = 0x200000; // Flash 8 GB phone -> buffersize 0x200000 = 11:45 min, buffersize 0x20000 = 12:30 min
|
||||
byte[] FlashBuffer = new byte[FlashBufferSize];
|
||||
int BytesRead;
|
||||
UInt64 i = 0;
|
||||
ulong i = 0;
|
||||
do
|
||||
{
|
||||
BytesRead = InputStream.Read(FlashBuffer, 0, FlashBufferSize);
|
||||
@@ -1168,12 +1185,12 @@ namespace WPinternals
|
||||
Buffer.BlockCopy(FlashBuffer, 0, FlashBufferFinalSize, 0, BytesRead);
|
||||
}
|
||||
|
||||
FlashSectors((UInt32)(Partition.FirstSector + (i / 0x200)), FlashBufferFinalSize, ProgressPercentage);
|
||||
FlashSectors((uint)(Partition.FirstSector + i / 0x200), FlashBufferFinalSize, ProgressPercentage);
|
||||
}
|
||||
|
||||
if (Progress != null)
|
||||
{
|
||||
Progress.IncreaseProgress((UInt64)FlashBuffer.Length / 0x200);
|
||||
Progress.IncreaseProgress((ulong)FlashBuffer.Length / 0x200);
|
||||
ProgressPercentage = Progress.ProgressPercentage;
|
||||
}
|
||||
|
||||
+11
-9
@@ -19,8 +19,10 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.UEFIApps.Flash
|
||||
{
|
||||
internal class LumiaFlashAppPhoneInfo
|
||||
{
|
||||
@@ -36,13 +38,13 @@ namespace WPinternals
|
||||
public byte FlashAppProtocolVersionMajor;
|
||||
public byte FlashAppProtocolVersionMinor;
|
||||
|
||||
public UInt32 TransferSize;
|
||||
public uint TransferSize;
|
||||
public bool MmosOverUsbSupported;
|
||||
public UInt32 SdCardSizeInSectors;
|
||||
public UInt32 WriteBufferSize;
|
||||
public UInt32 EmmcSizeInSectors;
|
||||
public uint SdCardSizeInSectors;
|
||||
public uint WriteBufferSize;
|
||||
public uint EmmcSizeInSectors;
|
||||
public string PlatformID;
|
||||
public UInt16 SecureFfuSupportedProtocolMask;
|
||||
public ushort SecureFfuSupportedProtocolMask;
|
||||
public bool AsyncSupport;
|
||||
|
||||
public bool PlatformSecureBootEnabled;
|
||||
@@ -78,14 +80,14 @@ namespace WPinternals
|
||||
break;
|
||||
}
|
||||
|
||||
LogFile.Log($"SecureBoot: {((!PlatformSecureBootEnabled || !UefiSecureBootEnabled) ? "Disabled" : "Enabled")} (Platform Secure Boot: {(PlatformSecureBootEnabled ? "Enabled" : "Disabled")}, UEFI Secure Boot: {(UefiSecureBootEnabled ? "Enabled" : "Disabled")})", Type);
|
||||
LogFile.Log($"SecureBoot: {(!PlatformSecureBootEnabled || !UefiSecureBootEnabled ? "Disabled" : "Enabled")} (Platform Secure Boot: {(PlatformSecureBootEnabled ? "Enabled" : "Disabled")}, UEFI Secure Boot: {(UefiSecureBootEnabled ? "Enabled" : "Disabled")})", Type);
|
||||
|
||||
if ((Type == LogType.ConsoleOnly) || (Type == LogType.FileAndConsole))
|
||||
if (Type == LogType.ConsoleOnly || Type == LogType.FileAndConsole)
|
||||
{
|
||||
LogFile.Log($"Flash app security: {(!IsBootloaderSecure ? "Disabled" : "Enabled")}", LogType.ConsoleOnly);
|
||||
}
|
||||
|
||||
if ((Type == LogType.FileOnly) || (Type == LogType.FileAndConsole))
|
||||
if (Type == LogType.FileOnly || Type == LogType.FileAndConsole)
|
||||
{
|
||||
LogFile.Log($"Flash app security: {(!IsBootloaderSecure ? "Disabled" : "Enabled")} (FFU security: {(SecureFfuEnabled ? "Enabled" : "Disabled")}, RDC: {(RdcPresent ? "Present" : "Not found")}, Authenticated: {(Authenticated ? "True" : "False")})", LogType.FileOnly);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace WPinternals.Models.UEFIApps.Flash
|
||||
{
|
||||
internal enum SecureBootKeyType : byte
|
||||
{
|
||||
Retail = 0,
|
||||
Engineering = 1
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.Lumia.UEFI.Flash
|
||||
{
|
||||
internal class UefiSecurityStatusResponse
|
||||
{
|
||||
@@ -18,7 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.Lumia.UEFI
|
||||
{
|
||||
internal enum FlashAppType
|
||||
{
|
||||
@@ -0,0 +1,122 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
|
||||
namespace WPinternals.Models.Lumia.UEFI
|
||||
{
|
||||
internal partial class NokiaUEFIModel : NokiaPhoneModel
|
||||
{
|
||||
internal void SwitchToFlashAppContext()
|
||||
{
|
||||
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||
|
||||
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||
|
||||
SendCommonExtendedSwitchToCommand('F');
|
||||
|
||||
if (ModernFlashApp)
|
||||
{
|
||||
DisableRebootTimeOut();
|
||||
|
||||
InterfaceChanged(PhoneInterfaces.Lumia_Flash, _devicePath);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SwitchToPhoneInfoAppContext()
|
||||
{
|
||||
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||
|
||||
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||
|
||||
SendCommonExtendedSwitchToCommand('P');
|
||||
|
||||
if (ModernFlashApp)
|
||||
{
|
||||
DisableRebootTimeOut();
|
||||
|
||||
CommonInfo.App = FlashAppType.PhoneInfoApp;
|
||||
|
||||
InterfaceChanged(PhoneInterfaces.Lumia_PhoneInfo, _devicePath);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SwitchToBootManagerContext(bool DisableTimeOut = true)
|
||||
{
|
||||
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||
|
||||
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||
|
||||
SendCommonExtendedSwitchToCommand('B');
|
||||
|
||||
if (ModernFlashApp)
|
||||
{
|
||||
DisableRebootTimeOut();
|
||||
|
||||
InterfaceChanged(PhoneInterfaces.Lumia_Bootloader, _devicePath);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SwitchToMmosContext()
|
||||
{
|
||||
SendCommonExtendedSwitchToCommand('A');
|
||||
}
|
||||
|
||||
internal void SwitchToNormalModeContext()
|
||||
{
|
||||
SendCommonExtendedSwitchToCommand('W');
|
||||
}
|
||||
|
||||
internal void SwitchToMassStorageModeContext()
|
||||
{
|
||||
SendCommonExtendedSwitchToCommand('M');
|
||||
}
|
||||
|
||||
internal void SwitchToResetContext()
|
||||
{
|
||||
SendCommonExtendedSwitchToCommand('R');
|
||||
}
|
||||
|
||||
internal void SwitchToEmergencyMode()
|
||||
{
|
||||
SendCommonExtendedSwitchToCommand('E');
|
||||
}
|
||||
|
||||
internal void SendCommonExtendedSwitchToCommand(char Mode)
|
||||
{
|
||||
byte[] Request = new byte[7];
|
||||
ByteOperations.WriteAsciiString(Request, 0, $"{SwitchModeSignature}{Mode}");
|
||||
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
|
||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("SendCommonExtendedSwitchToCommand: Error 0x" + Error.ToString("X4"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
-106
@@ -19,12 +19,13 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.Lumia.UEFI
|
||||
{
|
||||
internal delegate void InterfaceChangedHandler(PhoneInterfaces NewInterface, string DevicePath);
|
||||
|
||||
internal class NokiaUEFIModel : NokiaPhoneModel
|
||||
internal partial class NokiaUEFIModel : NokiaPhoneModel
|
||||
{
|
||||
private string _devicePath;
|
||||
|
||||
@@ -55,110 +56,6 @@ namespace WPinternals
|
||||
_devicePath = DevicePath;
|
||||
}
|
||||
|
||||
internal void SwitchToBootManagerContext(bool DisableTimeOut = true)
|
||||
{
|
||||
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||
|
||||
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||
|
||||
byte[] Request = new byte[7];
|
||||
ByteOperations.WriteAsciiString(Request, 0, $"{SwitchModeSignature}B");
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("SwitchToBootManagerContext: Error 0x" + Error.ToString("X4"));
|
||||
}
|
||||
|
||||
if (ModernFlashApp)
|
||||
{
|
||||
DisableRebootTimeOut();
|
||||
|
||||
InterfaceChanged(PhoneInterfaces.Lumia_Bootloader, _devicePath);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SwitchToPhoneInfoAppContext()
|
||||
{
|
||||
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||
|
||||
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||
|
||||
byte[] Request = new byte[7];
|
||||
ByteOperations.WriteAsciiString(Request, 0, SwitchModeSignature + "P");
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("SwitchToPhoneInfoAppContext: Error 0x" + Error.ToString("X4"));
|
||||
}
|
||||
|
||||
if (ModernFlashApp)
|
||||
{
|
||||
DisableRebootTimeOut();
|
||||
|
||||
CommonInfo.App = FlashAppType.PhoneInfoApp;
|
||||
|
||||
InterfaceChanged(PhoneInterfaces.Lumia_PhoneInfo, _devicePath);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SwitchToMmosContext()
|
||||
{
|
||||
byte[] Request = new byte[7];
|
||||
ByteOperations.WriteAsciiString(Request, 0, $"{SwitchModeSignature}A");
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("SwitchToPhoneInfoAppContext: Error 0x" + Error.ToString("X4"));
|
||||
}
|
||||
}
|
||||
|
||||
internal void SwitchToFlashAppContext()
|
||||
{
|
||||
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||
|
||||
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||
|
||||
byte[] Request = new byte[7];
|
||||
ByteOperations.WriteAsciiString(Request, 0, $"{SwitchModeSignature}F"); // This will stop charging the phone
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||
if (Error > 0)
|
||||
{
|
||||
throw new NotSupportedException("SwitchToFlashAppContext: Error 0x" + Error.ToString("X4"));
|
||||
}
|
||||
|
||||
if (ModernFlashApp)
|
||||
{
|
||||
DisableRebootTimeOut();
|
||||
|
||||
InterfaceChanged(PhoneInterfaces.Lumia_Flash, _devicePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Normal commands
|
||||
//
|
||||
@@ -237,5 +134,46 @@ namespace WPinternals
|
||||
{
|
||||
InterfaceChanged(NewInterface, _devicePath);
|
||||
}
|
||||
|
||||
// Raw USB Interfaces
|
||||
|
||||
protected byte[] ExecuteRawMethod(byte[] RawMethod)
|
||||
{
|
||||
return ExecuteRawMethod(RawMethod, RawMethod.Length);
|
||||
}
|
||||
|
||||
protected byte[] ExecuteRawMethod(byte[] RawMethod, int Length)
|
||||
{
|
||||
byte[] Buffer = new byte[0x8000]; // Should be at least 0x4408 for receiving the GPT packet.
|
||||
byte[] Result = null;
|
||||
lock (UsbLock)
|
||||
{
|
||||
Device.OutputPipe.Write(RawMethod, 0, Length);
|
||||
try
|
||||
{
|
||||
int OutputLength = Device.InputPipe.Read(Buffer);
|
||||
Result = new byte[OutputLength];
|
||||
System.Buffer.BlockCopy(Buffer, 0, Result, 0, OutputLength);
|
||||
}
|
||||
catch (Exception ex) // Reboot command looses connection
|
||||
{
|
||||
LogFile.LogException(ex, LogType.FileOnly);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
protected void ExecuteRawVoidMethod(byte[] RawMethod)
|
||||
{
|
||||
ExecuteRawVoidMethod(RawMethod, RawMethod.Length);
|
||||
}
|
||||
|
||||
protected void ExecuteRawVoidMethod(byte[] RawMethod, int Length)
|
||||
{
|
||||
lock (UsbLock)
|
||||
{
|
||||
Device.OutputPipe.Write(RawMethod, 0, Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-8
@@ -20,8 +20,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.UEFIApps.PhoneInfo
|
||||
{
|
||||
internal class LumiaPhoneInfoAppModel : NokiaUEFIModel
|
||||
{
|
||||
@@ -82,12 +84,12 @@ namespace WPinternals
|
||||
byte[] Request = new byte[4];
|
||||
ByteOperations.WriteAsciiString(Request, 0, GetPhoneInfoSignature);
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if ((Response == null) || (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU"))
|
||||
if (Response == null || ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
UInt16 Length = BigEndian.ToUInt16(Response, 0x04);
|
||||
ushort Length = BigEndian.ToUInt16(Response, 0x04);
|
||||
|
||||
string PhoneInfoData = ByteOperations.ReadAsciiString(Response, 0x8, Length);
|
||||
|
||||
@@ -104,7 +106,7 @@ namespace WPinternals
|
||||
|
||||
LumiaPhoneInfoAppPhoneInfo Result = PhoneInfoAppInfo;
|
||||
|
||||
if (ExtendedInfo && (Result.State == PhoneInfoState.Basic))
|
||||
if (ExtendedInfo && Result.State == PhoneInfoState.Basic)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -175,7 +177,7 @@ namespace WPinternals
|
||||
byte[] Request = new byte[4];
|
||||
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||
if (Response != null && ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU")
|
||||
{
|
||||
Result.App = (FlashAppType)Response[5];
|
||||
|
||||
@@ -198,9 +200,8 @@ namespace WPinternals
|
||||
|
||||
LogFile.Log($"{Result.App} SubblockID: 0x{SubblockID:X}");
|
||||
|
||||
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||
ushort SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||
int SubblockPayloadOffset = SubblockOffset + 3;
|
||||
byte SubblockVersion;
|
||||
switch (SubblockID)
|
||||
{
|
||||
case 0x20:
|
||||
@@ -224,7 +225,7 @@ namespace WPinternals
|
||||
byte[] Request = new byte[16];
|
||||
ByteOperations.WriteAsciiString(Request, 0, GetVariableSignature + VariableName + "\0"); // BTR or CTR, CTR is public ProductCode
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
UInt16 Length = BigEndian.ToUInt16(Response, 6);
|
||||
ushort Length = BigEndian.ToUInt16(Response, 6);
|
||||
return ByteOperations.ReadAsciiString(Response, 8, Length).Trim([' ', '\0']);
|
||||
}
|
||||
|
||||
+26
-2
@@ -18,7 +18,31 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace WPinternals
|
||||
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI;
|
||||
|
||||
namespace WPinternals.Models.UEFIApps.PhoneInfo
|
||||
{
|
||||
internal class LumiaPhoneInfoAppPhoneInfo
|
||||
{
|
||||
@@ -49,7 +73,7 @@ namespace WPinternals
|
||||
LogFile.Log($"Product code: {ProductCode}", Type);
|
||||
}
|
||||
|
||||
if (Type != LogType.ConsoleOnly && (Imei != null))
|
||||
if (Type != LogType.ConsoleOnly && Imei != null)
|
||||
{
|
||||
LogFile.Log($"IMEI: {Imei}", LogType.FileOnly);
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Models.Lumia.UEFI
|
||||
{
|
||||
internal enum PhoneInfoState
|
||||
{
|
||||
@@ -23,6 +23,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -41,14 +43,14 @@ namespace WPinternals
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (ManagementObject logical in new ManagementObjectSearcher("select * from Win32_LogicalDisk").Get())
|
||||
foreach (ManagementObject logical in new ManagementObjectSearcher("select * from Win32_LogicalDisk").Get().Cast<ManagementObject>())
|
||||
{
|
||||
System.Diagnostics.Debug.Print(logical["Name"].ToString());
|
||||
|
||||
string Label = "";
|
||||
foreach (ManagementObject partition in logical.GetRelated("Win32_DiskPartition"))
|
||||
foreach (ManagementObject partition in logical.GetRelated("Win32_DiskPartition").Cast<ManagementObject>())
|
||||
{
|
||||
foreach (ManagementObject drive in partition.GetRelated("Win32_DiskDrive"))
|
||||
foreach (ManagementObject drive in partition.GetRelated("Win32_DiskDrive").Cast<ManagementObject>())
|
||||
{
|
||||
if (drive["PNPDeviceID"].ToString().Contains("VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.CurrentCulture) ||
|
||||
drive["PNPDeviceID"].ToString().Contains("VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.CurrentCulture))
|
||||
|
||||
@@ -28,6 +28,7 @@ using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
using MadWizard.WinUSBNet;
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -316,7 +316,7 @@ namespace WPinternals
|
||||
EFI File = EFIs.Find(f => string.Equals(Name, f.Name, StringComparison.CurrentCultureIgnoreCase) || string.Equals(Name, f.Guid.ToString(), StringComparison.CurrentCultureIgnoreCase));
|
||||
if (File == null)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException(nameof(Name));
|
||||
}
|
||||
|
||||
UInt32 OldBinarySize = File.Size;
|
||||
|
||||
@@ -19,9 +19,8 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WPinternals
|
||||
namespace WPinternals.Terminal
|
||||
{
|
||||
internal static class Terminal
|
||||
{
|
||||
@@ -30,13 +29,13 @@ namespace WPinternals
|
||||
TerminalResponse Response = new();
|
||||
|
||||
// Get root node
|
||||
if (Buffer.Length >= (Offset + 8))
|
||||
if (Buffer.Length >= Offset + 8)
|
||||
{
|
||||
int NodeNumber = BitConverter.ToInt32(Buffer, Offset);
|
||||
int NodeSize = BitConverter.ToInt32(Buffer, Offset + 4);
|
||||
int End = NodeSize + Offset + 8;
|
||||
int Index = Offset + 8;
|
||||
if ((NodeNumber == 0x10000) && (End <= Buffer.Length))
|
||||
if (NodeNumber == 0x10000 && End <= Buffer.Length)
|
||||
{
|
||||
// Get subnodes
|
||||
while (Index < End)
|
||||
@@ -58,11 +57,4 @@ namespace WPinternals
|
||||
return Response;
|
||||
}
|
||||
}
|
||||
|
||||
internal class TerminalResponse
|
||||
{
|
||||
public Dictionary<int, byte[]> RawEntries = [];
|
||||
public byte[] PublicId = null;
|
||||
public byte[] RootKeyHash = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WPinternals.Terminal
|
||||
{
|
||||
internal class TerminalResponse
|
||||
{
|
||||
public Dictionary<int, byte[]> RawEntries = [];
|
||||
public byte[] PublicId = null;
|
||||
public byte[] RootKeyHash = null;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -181,9 +183,9 @@ namespace WPinternals
|
||||
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage);
|
||||
MassStorage MassStorage = (MassStorage)Notifier.CurrentModel;
|
||||
|
||||
foreach (var part in Directory.EnumerateFiles(PartPath))
|
||||
foreach (string part in Directory.EnumerateFiles(PartPath))
|
||||
{
|
||||
var partname = part.Split('\\').Last().Replace(".img", "");
|
||||
string partname = part.Split('\\').Last().Replace(".img", "");
|
||||
try
|
||||
{
|
||||
LogFile.Log($"Writing {partname} to the device.", LogType.ConsoleOnly);
|
||||
@@ -203,7 +205,7 @@ namespace WPinternals
|
||||
|
||||
internal static void PatchImg(string dump)
|
||||
{
|
||||
using var fil = File.Open(dump, FileMode.Open);
|
||||
using FileStream fil = File.Open(dump, FileMode.Open);
|
||||
byte[] gptbuffer = new byte[0x4200];
|
||||
|
||||
fil.Seek(0x200, SeekOrigin.Begin);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -30,6 +30,11 @@ using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.MSR;
|
||||
using WPinternals.Models.Lumia.NCSd;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
using WPinternals.Models.UEFIApps.PhoneInfo;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -663,7 +668,7 @@ namespace WPinternals
|
||||
}
|
||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Normal)
|
||||
{
|
||||
NokiaPhoneModel LumiaNormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
||||
NokiaCareSuiteModel LumiaNormalModel = (NokiaCareSuiteModel)Notifier.CurrentModel;
|
||||
OperatorCode = LumiaNormalModel.ExecuteJsonMethodAsString("ReadOperatorName", "OperatorName"); // Example: 000-NL
|
||||
string TempProductType = LumiaNormalModel.ExecuteJsonMethodAsString("ReadManufacturerModelName", "ManufacturerModelName"); // RM-821_eu_denmark_251
|
||||
if (TempProductType.Contains('_'))
|
||||
@@ -1082,7 +1087,7 @@ namespace WPinternals
|
||||
|
||||
public static class HttpClientProgressExtensions
|
||||
{
|
||||
public static async Task DownloadFileAsync(this HttpClient client, Uri address, string fileName, Action<HttpClientDownloadProgress> progress = null, Action<bool> completed = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static async Task DownloadFileAsync(this HttpClient client, Uri address, string fileName, Action<HttpClientDownloadProgress> progress = null, Action<bool> completed = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1094,25 +1099,22 @@ namespace WPinternals
|
||||
if (progress is null || !contentLength.HasValue)
|
||||
{
|
||||
await download.CopyToAsync(destination);
|
||||
if (completed != null)
|
||||
completed(true);
|
||||
completed?.Invoke(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Progress<long> progressWrapper = new Progress<long>(totalBytes => progress(new HttpClientDownloadProgress(totalBytes, contentLength.Value)));
|
||||
Progress<long> progressWrapper = new(totalBytes => progress(new HttpClientDownloadProgress(totalBytes, contentLength.Value)));
|
||||
await download.CopyToAsync(destination, 81920, progressWrapper, cancellationToken);
|
||||
|
||||
if (completed != null)
|
||||
completed(true);
|
||||
completed?.Invoke(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (completed != null)
|
||||
completed(false);
|
||||
completed?.Invoke(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
private static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (bufferSize < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(bufferSize));
|
||||
@@ -1128,9 +1130,9 @@ namespace WPinternals
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
long totalBytesRead = 0;
|
||||
int bytesRead;
|
||||
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
|
||||
while ((bytesRead = await source.ReadAsync(buffer, cancellationToken).ConfigureAwait(false)) != 0)
|
||||
{
|
||||
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
|
||||
await destination.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(false);
|
||||
totalBytesRead += bytesRead;
|
||||
progress?.Report(totalBytesRead);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -438,12 +438,12 @@ namespace WPinternals
|
||||
//read the content
|
||||
//TODO: it may throw an exception (stream closed because file expired?)
|
||||
//In that case we would wrap into another try catch and try to read the reason behind this
|
||||
while ((bytesRead = await streamToReadFrom.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
|
||||
while ((bytesRead = await streamToReadFrom.ReadAsync(buffer, cancellationToken)) > 0)
|
||||
{
|
||||
totalBytesRead += bytesRead;
|
||||
|
||||
//simply write to the file
|
||||
await streamToWriteTo.WriteAsync(buffer, 0, bytesRead, cancellationToken);
|
||||
await streamToWriteTo.WriteAsync(buffer.AsMemory(0, bytesRead), cancellationToken);
|
||||
|
||||
//report progress
|
||||
downloadProgress?.Report(new FileDownloadStatus(downloadFile)
|
||||
@@ -593,9 +593,9 @@ namespace WPinternals
|
||||
byte[] buffer = new byte[bufSizeEffective];
|
||||
using MemoryStream ms = new(buffer);
|
||||
using CryptoStream cs = new(ms, hashAlgorithm, CryptoStreamMode.Write);
|
||||
while ((readBytes = await fileStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0)
|
||||
while ((readBytes = await fileStream.ReadAsync(buffer, cancellationToken)) > 0)
|
||||
{
|
||||
await cs.WriteAsync(buffer, 0, readBytes, cancellationToken);
|
||||
await cs.WriteAsync(buffer.AsMemory(0, readBytes), cancellationToken);
|
||||
ms.Position = 0;
|
||||
totalBytesRead += readBytes;
|
||||
progress?.Report(totalBytesRead);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -25,6 +25,9 @@ using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.UEFIApps.BootMgr;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.NCSd;
|
||||
using WPinternals.Models.UEFIApps.BootMgr;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
using WPinternals.Models.UEFIApps.PhoneInfo;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -75,13 +80,13 @@ namespace WPinternals
|
||||
ActivateSubContext(new NokiaPhoneInfoViewModel((LumiaPhoneInfoAppModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Normal:
|
||||
ActivateSubContext(new NokiaNormalViewModel((NokiaPhoneModel)CurrentModel, ModeSwitchRequestCallback));
|
||||
ActivateSubContext(new NokiaNormalViewModel((NokiaCareSuiteModel)CurrentModel, ModeSwitchRequestCallback));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Flash:
|
||||
ActivateSubContext(new NokiaFlashViewModel((LumiaFlashAppModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Label:
|
||||
ActivateSubContext(new NokiaLabelViewModel((NokiaPhoneModel)CurrentModel, ModeSwitchRequestCallback));
|
||||
ActivateSubContext(new NokiaLabelViewModel((NokiaCareSuiteModel)CurrentModel, ModeSwitchRequestCallback));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_MassStorage:
|
||||
ActivateSubContext(new NokiaMassStorageViewModel((MassStorage)CurrentModel));
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.NCSd;
|
||||
using WPinternals.Models.UEFIApps.BootMgr;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
using WPinternals.Models.UEFIApps.PhoneInfo;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -93,13 +98,13 @@ namespace WPinternals
|
||||
ActivateSubContext(new NokiaModePhoneInfoViewModel((LumiaPhoneInfoAppModel)CurrentModel, OnModeSwitchRequested));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Normal:
|
||||
ActivateSubContext(new NokiaModeNormalViewModel((NokiaPhoneModel)CurrentModel, OnModeSwitchRequested));
|
||||
ActivateSubContext(new NokiaModeNormalViewModel((NokiaCareSuiteModel)CurrentModel, OnModeSwitchRequested));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Flash:
|
||||
ActivateSubContext(new NokiaModeFlashViewModel((LumiaFlashAppModel)CurrentModel, OnModeSwitchRequested));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Label:
|
||||
ActivateSubContext(new NokiaModeLabelViewModel((NokiaPhoneModel)CurrentModel, OnModeSwitchRequested));
|
||||
ActivateSubContext(new NokiaModeLabelViewModel((NokiaCareSuiteModel)CurrentModel, OnModeSwitchRequested));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_MassStorage:
|
||||
ActivateSubContext(new NokiaModeMassStorageViewModel((MassStorage)CurrentModel, OnModeSwitchRequested));
|
||||
|
||||
@@ -24,6 +24,11 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using WPinternals.Config;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI.Flash;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
using WPinternals.Models.UEFIApps.PhoneInfo;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -26,6 +26,10 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI.Flash;
|
||||
using WPinternals.Models.UEFIApps.BootMgr;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -51,8 +55,7 @@ namespace WPinternals
|
||||
FlashModel.SendFfuPayloadV1(EmptyChunk);
|
||||
|
||||
// Reboot to Qualcomm Emergency mode
|
||||
byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52]; // NOKR
|
||||
FlashModel.ExecuteRawVoidMethod(RebootCommand);
|
||||
FlashModel.ResetPhone();
|
||||
}
|
||||
|
||||
private static void SendLoader(PhoneNotifierViewModel PhoneNotifier, List<QualcommPartition> PossibleLoaders)
|
||||
@@ -1960,7 +1963,7 @@ namespace WPinternals
|
||||
string SBRes = IsSpecB ? "WPinternals.SB" : "WPinternals.SBA";
|
||||
Part.Stream = new SeekableStream(() =>
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
|
||||
// Magic!
|
||||
// The SB(A) resource is a compressed version of a raw NV-variable-partition.
|
||||
@@ -1968,7 +1971,7 @@ namespace WPinternals
|
||||
// It overwrites the variable in a different NV-partition than where this variable is stored usually.
|
||||
// This normally leads to endless-loops when the NV-variables are enumerated.
|
||||
// But the partition contains an extra hack to break out the endless loops.
|
||||
var stream = assembly.GetManifestResourceStream(SBRes);
|
||||
Stream stream = assembly.GetManifestResourceStream(SBRes);
|
||||
|
||||
return new DecompressedStream(stream);
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using WPinternals.HelperClasses;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
|
||||
@@ -25,6 +25,13 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using WPinternals.Config;
|
||||
using WPinternals.HelperClasses;
|
||||
using WPinternals.Models.Lumia.UEFI;
|
||||
using WPinternals.Models.UEFIApps;
|
||||
using WPinternals.Models.UEFIApps.BootMgr;
|
||||
using WPinternals.Models.UEFIApps.Flash;
|
||||
using WPinternals.Models.UEFIApps.PhoneInfo;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
@@ -183,7 +190,7 @@ namespace WPinternals
|
||||
Part.StartSector = (UInt32)TargetPartition.FirstSector; // GPT is prepared for 64-bit sector-offset, but flash app isn't.
|
||||
Part.Stream = new SeekableStream(() =>
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
|
||||
// Magic!
|
||||
// The SB resource is a compressed version of a raw NV-variable-partition.
|
||||
@@ -191,7 +198,7 @@ namespace WPinternals
|
||||
// It overwrites the variable in a different NV-partition than where this variable is stored usually.
|
||||
// This normally leads to endless-loops when the NV-variables are enumerated.
|
||||
// But the partition contains an extra hack to break out the endless loops.
|
||||
var stream = assembly.GetManifestResourceStream("WPinternals.SB");
|
||||
Stream stream = assembly.GetManifestResourceStream("WPinternals.SB");
|
||||
|
||||
return new DecompressedStream(stream);
|
||||
});
|
||||
@@ -500,7 +507,7 @@ namespace WPinternals
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var part in FlashParts)
|
||||
foreach (FlashPart part in FlashParts)
|
||||
{
|
||||
if (part.StartSector >= UefiBSNV.FirstSector && part.StartSector <= UefiBSNV.LastSector)
|
||||
{
|
||||
@@ -1877,7 +1884,7 @@ namespace WPinternals
|
||||
ulong CurrentProcess1 = 0;
|
||||
SetWorkingStatus("Hashing resources...", "Initializing flash...", (UInt64)TotalProcess1, Status: WPinternalsStatus.Initializing);
|
||||
|
||||
var crypto = System.Security.Cryptography.SHA256.Create();
|
||||
System.Security.Cryptography.SHA256 crypto = System.Security.Cryptography.SHA256.Create();
|
||||
List<FlashingPayload> flashingPayloads = [];
|
||||
if (flashParts == null)
|
||||
{
|
||||
@@ -1888,7 +1895,7 @@ namespace WPinternals
|
||||
{
|
||||
FlashPart flashPart = flashParts[(Int32)j];
|
||||
flashPart.Stream.Seek(0, SeekOrigin.Begin);
|
||||
var totalChunkCount = flashPart.Stream.Length / chunkSize;
|
||||
long totalChunkCount = flashPart.Stream.Length / chunkSize;
|
||||
for (UInt32 i = 0; i < totalChunkCount; i++)
|
||||
{
|
||||
UpdateWorkingStatus("Hashing resources...", "Initializing flash...", CurrentProcess1, WPinternalsStatus.Initializing);
|
||||
@@ -1931,19 +1938,19 @@ namespace WPinternals
|
||||
{
|
||||
FlashPart flashPart = flashParts[(Int32)j];
|
||||
flashPart.Stream.Seek(0, SeekOrigin.Begin);
|
||||
var totalChunkCount = flashPart.Stream.Length / chunkSize;
|
||||
long totalChunkCount = flashPart.Stream.Length / chunkSize;
|
||||
for (UInt32 i = 0; i < totalChunkCount; i++)
|
||||
{
|
||||
UpdateWorkingStatus("Hashing resources...", "Initializing flash...", CurrentProcess1, WPinternalsStatus.Initializing);
|
||||
byte[] buffer = new byte[chunkSize];
|
||||
Int64 position = flashPart.Stream.Position;
|
||||
flashPart.Stream.Read(buffer, 0, chunkSize);
|
||||
var hash = crypto.ComputeHash(buffer);
|
||||
byte[] hash = crypto.ComputeHash(buffer);
|
||||
|
||||
if (flashingPayloads.Any(x => ByteOperations.Compare(x.ChunkHashes[0], hash)))
|
||||
{
|
||||
var payloadIndex = flashingPayloads.FindIndex(x => ByteOperations.Compare(x.ChunkHashes[0], hash));
|
||||
var locationList = flashingPayloads[payloadIndex].TargetLocations.ToList();
|
||||
int payloadIndex = flashingPayloads.FindIndex(x => ByteOperations.Compare(x.ChunkHashes[0], hash));
|
||||
List<uint> locationList = flashingPayloads[payloadIndex].TargetLocations.ToList();
|
||||
locationList.Add((flashPart.StartSector * 0x200 / (UInt32)chunkSize) + i);
|
||||
flashingPayloads[payloadIndex].TargetLocations = [.. locationList];
|
||||
}
|
||||
@@ -2255,15 +2262,15 @@ namespace WPinternals
|
||||
Part.StartSector = (UInt32)Target.FirstSector; // GPT is prepared for 64-bit sector-offset, but flash app isn't.
|
||||
Part.Stream = new SeekableStream(() =>
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
|
||||
// Magic!
|
||||
// The SB resource is a compressed version of a raw NV-variable-partition.
|
||||
// In this partition the SecureBoot variable is disabled.
|
||||
// It overwrites the variable in a different NV-partition than where this variable is stored usually.
|
||||
// This normally leads to endless-loops when the NV-variables are enumerated.
|
||||
// But the partition contains an extra hack to break out the endless loops.
|
||||
var stream = assembly.GetManifestResourceStream("WPinternals.SB");
|
||||
// Magic!
|
||||
// The SB resource is a compressed version of a raw NV-variable-partition.
|
||||
// In this partition the SecureBoot variable is disabled.
|
||||
// It overwrites the variable in a different NV-partition than where this variable is stored usually.
|
||||
// This normally leads to endless-loops when the NV-variables are enumerated.
|
||||
// But the partition contains an extra hack to break out the endless loops.
|
||||
Stream stream = assembly.GetManifestResourceStream("WPinternals.SB");
|
||||
|
||||
return new DecompressedStream(stream);
|
||||
});
|
||||
@@ -2614,7 +2621,7 @@ namespace WPinternals
|
||||
Part.StartSector = (UInt32)Target.FirstSector; // GPT is prepared for 64-bit sector-offset, but flash app isn't.
|
||||
Part.Stream = new SeekableStream(() =>
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
|
||||
// Magic!
|
||||
// The SB resource is a compressed version of a raw NV-variable-partition.
|
||||
@@ -2622,7 +2629,7 @@ namespace WPinternals
|
||||
// It overwrites the variable in a different NV-partition than where this variable is stored usually.
|
||||
// This normally leads to endless-loops when the NV-variables are enumerated.
|
||||
// But the partition contains an extra hack to break out the endless loops.
|
||||
var stream = assembly.GetManifestResourceStream("WPinternals.SB");
|
||||
Stream stream = assembly.GetManifestResourceStream("WPinternals.SB");
|
||||
|
||||
return new DecompressedStream(stream);
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user