mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-06-14 03:16:40 +10:00
Split phone info structures for each app type
This commit is contained in:
+75
-30
@@ -85,8 +85,11 @@ namespace WPinternals
|
|||||||
PhoneNotifierViewModel Notifier;
|
PhoneNotifierViewModel Notifier;
|
||||||
LumiaFlashAppModel FlashModel;
|
LumiaFlashAppModel FlashModel;
|
||||||
LumiaBootManagerAppModel BootMgrModel;
|
LumiaBootManagerAppModel BootMgrModel;
|
||||||
|
LumiaPhoneInfoAppModel PhoneInfoModel;
|
||||||
NokiaPhoneModel NormalModel;
|
NokiaPhoneModel NormalModel;
|
||||||
PhoneInfo Info;
|
LumiaFlashAppPhoneInfo FlashInfo;
|
||||||
|
LumiaPhoneInfoAppPhoneInfo PhoneInfo;
|
||||||
|
LumiaBootManagerPhoneInfo BootManagerInfo;
|
||||||
string ProductType;
|
string ProductType;
|
||||||
string ProductCode;
|
string ProductCode;
|
||||||
string OperatorCode;
|
string OperatorCode;
|
||||||
@@ -543,8 +546,8 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
|
|
||||||
FFU ProfileFFU = null;
|
FFU ProfileFFU = null;
|
||||||
FFU CurrentFFU;
|
FFU CurrentFFU;
|
||||||
@@ -557,7 +560,7 @@ namespace WPinternals
|
|||||||
string PlatformID = CurrentFFU.PlatformID;
|
string PlatformID = CurrentFFU.PlatformID;
|
||||||
|
|
||||||
// Check if the current FFU matches the connected phone, so that the FFU can be used for profiling.
|
// Check if the current FFU matches the connected phone, so that the FFU can be used for profiling.
|
||||||
if (Info.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase))
|
if (FlashInfo.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
ProfileFFU = CurrentFFU;
|
ProfileFFU = CurrentFFU;
|
||||||
}
|
}
|
||||||
@@ -566,7 +569,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
if (ProfileFFU == null)
|
if (ProfileFFU == null)
|
||||||
{
|
{
|
||||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => Info.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists()).ToList();
|
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => FlashInfo.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists()).ToList();
|
||||||
ProfileFFU = FFUs.Count > 0
|
ProfileFFU = FFUs.Count > 0
|
||||||
? new FFU(FFUs[0].Path)
|
? new FFU(FFUs[0].Path)
|
||||||
: throw new WPinternalsException("Profile FFU missing", "No profile FFU has been found in the repository for your device. You can add a profile FFU within the download section of the tool or by using the command line.");
|
: throw new WPinternalsException("Profile FFU missing", "No profile FFU has been found in the repository for your device. You can add a profile FFU within the download section of the tool or by using the command line.");
|
||||||
@@ -692,8 +695,8 @@ namespace WPinternals
|
|||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
Notifier.Stop();
|
Notifier.Stop();
|
||||||
break;
|
break;
|
||||||
case "unlockbootloader":
|
case "unlockbootloader":
|
||||||
@@ -704,8 +707,8 @@ namespace WPinternals
|
|||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
|
|
||||||
FFU ProfileFFU = null;
|
FFU ProfileFFU = null;
|
||||||
FFU SupportedFFU = null;
|
FFU SupportedFFU = null;
|
||||||
@@ -719,7 +722,7 @@ namespace WPinternals
|
|||||||
string PlatformID = CurrentFFU.PlatformID;
|
string PlatformID = CurrentFFU.PlatformID;
|
||||||
|
|
||||||
// Check if the current FFU matches the connected phone, so that the FFU can be used for profiling.
|
// Check if the current FFU matches the connected phone, so that the FFU can be used for profiling.
|
||||||
if (Info.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase))
|
if (FlashInfo.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
ProfileFFU = CurrentFFU;
|
ProfileFFU = CurrentFFU;
|
||||||
}
|
}
|
||||||
@@ -734,7 +737,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
if (ProfileFFU == null)
|
if (ProfileFFU == null)
|
||||||
{
|
{
|
||||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => Info.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists()).ToList();
|
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => FlashInfo.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists()).ToList();
|
||||||
ProfileFFU = FFUs.Count > 0
|
ProfileFFU = FFUs.Count > 0
|
||||||
? new FFU(FFUs[0].Path)
|
? new FFU(FFUs[0].Path)
|
||||||
: throw new WPinternalsException("Profile FFU missing", "No profile FFU has been found in the repository for your device. You can add a profile FFU within the download section of the tool or by using the command line.");
|
: throw new WPinternalsException("Profile FFU missing", "No profile FFU has been found in the repository for your device. You can add a profile FFU within the download section of the tool or by using the command line.");
|
||||||
@@ -777,8 +780,8 @@ namespace WPinternals
|
|||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
LogFile.Log("Preparing to flash Custom ROM", LogType.FileAndConsole);
|
LogFile.Log("Preparing to flash Custom ROM", LogType.FileAndConsole);
|
||||||
await LumiaV2UnlockBootViewModel.LumiaV2FlashArchive(Notifier, CustomRomPath);
|
await LumiaV2UnlockBootViewModel.LumiaV2FlashArchive(Notifier, CustomRomPath);
|
||||||
LogFile.Log("Custom ROM flashed successfully", LogType.FileAndConsole);
|
LogFile.Log("Custom ROM flashed successfully", LogType.FileAndConsole);
|
||||||
@@ -808,10 +811,10 @@ namespace WPinternals
|
|||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
LogFile.Log("Flashing FFU...", LogType.FileAndConsole);
|
LogFile.Log("Flashing FFU...", LogType.FileAndConsole);
|
||||||
await Task.Run(() => FlashModel.FlashFFU(new FFU(FFUPath), true, (byte)(!Info.IsBootloaderSecure ? FlashOptions.SkipSignatureCheck : 0)));
|
await Task.Run(() => FlashModel.FlashFFU(new FFU(FFUPath), true, (byte)(!FlashInfo.IsBootloaderSecure ? FlashOptions.SkipSignatureCheck : 0)));
|
||||||
LogFile.Log("FFU flashed successfully", LogType.FileAndConsole);
|
LogFile.Log("FFU flashed successfully", LogType.FileAndConsole);
|
||||||
Notifier.Stop();
|
Notifier.Stop();
|
||||||
}
|
}
|
||||||
@@ -1275,15 +1278,53 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||||
{
|
{
|
||||||
BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
|
(Notifier.CurrentModel as LumiaBootManagerAppModel).SwitchToPhoneInfoAppContext();
|
||||||
Info = BootMgrModel.ReadPhoneInfo();
|
|
||||||
ProductCode = Info.ProductCode;
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
await Notifier.WaitForArrival();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
PhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
||||||
|
PhoneInfo = PhoneInfoModel.ReadPhoneInfo();
|
||||||
|
ProductCode = PhoneInfo.ProductCode;
|
||||||
|
}
|
||||||
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
PhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
||||||
|
PhoneInfo = PhoneInfoModel.ReadPhoneInfo();
|
||||||
|
ProductCode = PhoneInfo.ProductCode;
|
||||||
}
|
}
|
||||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
||||||
{
|
{
|
||||||
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
|
bool ModernFlashApp = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
if (ModernFlashApp)
|
||||||
ProductCode = Info.ProductCode;
|
{
|
||||||
|
((LumiaFlashAppModel)Notifier.CurrentModel).SwitchToPhoneInfoAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)Notifier.CurrentModel).SwitchToPhoneInfoAppContextLegacy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
await Notifier.WaitForArrival();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
PhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
||||||
|
PhoneInfo = PhoneInfoModel.ReadPhoneInfo();
|
||||||
|
ProductCode = PhoneInfo.ProductCode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1447,14 +1488,16 @@ namespace WPinternals
|
|||||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||||
{
|
{
|
||||||
BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
|
BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
|
||||||
Info = BootMgrModel.ReadPhoneInfo();
|
BootManagerInfo = BootMgrModel.ReadPhoneInfo();
|
||||||
ProductType = Info.Type;
|
//ProductType = BootManagerInfo.Type; // TODO: FIXME
|
||||||
|
ProductType = "";
|
||||||
}
|
}
|
||||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
||||||
{
|
{
|
||||||
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
|
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
ProductType = Info.Type;
|
//ProductType = FlashInfo.Type; // TODO: FIXME
|
||||||
|
ProductType = "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1564,14 +1607,16 @@ namespace WPinternals
|
|||||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||||
{
|
{
|
||||||
BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
|
BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
|
||||||
Info = BootMgrModel.ReadPhoneInfo();
|
BootManagerInfo = BootMgrModel.ReadPhoneInfo();
|
||||||
ProductCode = Info.ProductCode;
|
//ProductCode = BootManagerInfo.ProductCode; // TODO: FIXME
|
||||||
|
ProductCode = "";
|
||||||
}
|
}
|
||||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
||||||
{
|
{
|
||||||
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
|
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
ProductCode = Info.ProductCode;
|
//ProductCode = FlashInfo.ProductCode; // TODO: FIXME
|
||||||
|
ProductCode = "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,375 +0,0 @@
|
|||||||
// 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.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace WPinternals
|
|
||||||
{
|
|
||||||
internal delegate void InterfaceChangedHandler(PhoneInterfaces NewInterface, string DevicePath);
|
|
||||||
|
|
||||||
internal class NokiaFlashModel : NokiaPhoneModel
|
|
||||||
{
|
|
||||||
private string _devicePath;
|
|
||||||
|
|
||||||
internal readonly PhoneInfo Info = new();
|
|
||||||
|
|
||||||
internal event InterfaceChangedHandler InterfaceChanged = delegate { };
|
|
||||||
|
|
||||||
//
|
|
||||||
// Not valid commands
|
|
||||||
//
|
|
||||||
/* NOK */
|
|
||||||
private const string Signature = "NOK";
|
|
||||||
/* NOKX */
|
|
||||||
private const string ExtendedMessageSignature = $"{Signature}X";
|
|
||||||
/* NOKXC */
|
|
||||||
private const string CommonExtendedMessageSignature = $"{ExtendedMessageSignature}C";
|
|
||||||
|
|
||||||
//
|
|
||||||
// Common extended commands
|
|
||||||
//
|
|
||||||
/* NOKXCB */
|
|
||||||
private const string SwitchModeSignature = $"{CommonExtendedMessageSignature}B";
|
|
||||||
/* NOKXCE */
|
|
||||||
private const string EchoSignature = $"{CommonExtendedMessageSignature}E";
|
|
||||||
|
|
||||||
public NokiaFlashModel(string DevicePath) : base(DevicePath)
|
|
||||||
{
|
|
||||||
_devicePath = DevicePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void SwitchToBootManagerContext(bool DisableTimeOut = true)
|
|
||||||
{
|
|
||||||
PhoneInfo info = ReadPhoneInfoCommon();
|
|
||||||
|
|
||||||
bool ModernFlashApp = false;
|
|
||||||
switch (info.App)
|
|
||||||
{
|
|
||||||
case FlashAppType.FlashApp:
|
|
||||||
ModernFlashApp = info.FlashAppProtocolVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
case FlashAppType.PhoneInfoApp:
|
|
||||||
ModernFlashApp = info.PhoneInfoAppVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
case FlashAppType.BootManager:
|
|
||||||
ModernFlashApp = info.BootManagerVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
Info.App = FlashAppType.BootManager;
|
|
||||||
|
|
||||||
// If current Info class was retrieved while in BootMgr mode, then we need to invalidate this data, because it is incomplete.
|
|
||||||
if (Info.PlatformID == null)
|
|
||||||
{
|
|
||||||
Info.State = PhoneInfoState.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceChanged(PhoneInterfaces.Lumia_Bootloader, _devicePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void SwitchToPhoneInfoAppContext()
|
|
||||||
{
|
|
||||||
PhoneInfo info = ReadPhoneInfoCommon();
|
|
||||||
|
|
||||||
bool ModernFlashApp = false;
|
|
||||||
switch (info.App)
|
|
||||||
{
|
|
||||||
case FlashAppType.FlashApp:
|
|
||||||
ModernFlashApp = info.FlashAppProtocolVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
case FlashAppType.PhoneInfoApp:
|
|
||||||
ModernFlashApp = info.PhoneInfoAppVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
case FlashAppType.BootManager:
|
|
||||||
ModernFlashApp = info.BootManagerVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
Info.App = FlashAppType.PhoneInfoApp;
|
|
||||||
|
|
||||||
// If current Info class was retrieved while in BootMgr mode, then we need to invalidate this data, because it is incomplete.
|
|
||||||
if (Info.PlatformID == null)
|
|
||||||
{
|
|
||||||
Info.State = PhoneInfoState.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceChanged(PhoneInterfaces.Lumia_PhoneInfo, _devicePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void SwitchToMmosContext()
|
|
||||||
{
|
|
||||||
byte[] Request = new byte[7];
|
|
||||||
ByteOperations.WriteAsciiString(Request, 0, SwitchModeSignature + "A");
|
|
||||||
ExecuteRawVoidMethod(Request);
|
|
||||||
|
|
||||||
ResetDevice();
|
|
||||||
|
|
||||||
Dispose(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void SwitchToFlashAppContext()
|
|
||||||
{
|
|
||||||
PhoneInfo info = ReadPhoneInfoCommon();
|
|
||||||
|
|
||||||
bool ModernFlashApp = false;
|
|
||||||
switch (info.App)
|
|
||||||
{
|
|
||||||
case FlashAppType.FlashApp:
|
|
||||||
ModernFlashApp = info.FlashAppProtocolVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
case FlashAppType.PhoneInfoApp:
|
|
||||||
ModernFlashApp = info.PhoneInfoAppVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
case FlashAppType.BootManager:
|
|
||||||
ModernFlashApp = info.BootManagerVersionMajor >= 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
Info.App = FlashAppType.FlashApp;
|
|
||||||
|
|
||||||
// If current Info class was retrieved while in BootMgr mode, then we need to invalidate this data, because it is incomplete.
|
|
||||||
if (Info.PlatformID == null)
|
|
||||||
{
|
|
||||||
Info.State = PhoneInfoState.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceChanged(PhoneInterfaces.Lumia_Flash, _devicePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Normal commands
|
|
||||||
//
|
|
||||||
/* NOKD */
|
|
||||||
private const string DisableTimeoutsSignature = $"{Signature}D";
|
|
||||||
/* NOKI */
|
|
||||||
private const string HelloSignature = $"{Signature}I";
|
|
||||||
/* NOKV */
|
|
||||||
private const string InfoQuerySignature = $"{Signature}V";
|
|
||||||
|
|
||||||
internal FlashAppType GetFlashAppType()
|
|
||||||
{
|
|
||||||
byte[] Request = new byte[4];
|
|
||||||
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
|
||||||
byte[] Response = ExecuteRawMethod(Request);
|
|
||||||
if ((Response == null) || (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU"))
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FlashAppType)Response[5];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal PhoneInfo ReadPhoneInfoCommon()
|
|
||||||
{
|
|
||||||
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
|
||||||
// NOKV = Info Query
|
|
||||||
|
|
||||||
PhoneInfo Result = Info;
|
|
||||||
|
|
||||||
if (Result.State == PhoneInfoState.Empty)
|
|
||||||
{
|
|
||||||
byte[] Request = new byte[4];
|
|
||||||
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
|
||||||
byte[] Response = ExecuteRawMethod(Request);
|
|
||||||
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
|
||||||
{
|
|
||||||
Result.App = (FlashAppType)Response[5];
|
|
||||||
|
|
||||||
switch (Result.App)
|
|
||||||
{
|
|
||||||
case FlashAppType.BootManager:
|
|
||||||
Result.BootManagerProtocolVersionMajor = Response[6];
|
|
||||||
Result.BootManagerProtocolVersionMinor = Response[7];
|
|
||||||
Result.BootManagerVersionMajor = Response[8];
|
|
||||||
Result.BootManagerVersionMinor = Response[9];
|
|
||||||
break;
|
|
||||||
case FlashAppType.FlashApp:
|
|
||||||
Result.FlashAppProtocolVersionMajor = Response[6];
|
|
||||||
Result.FlashAppProtocolVersionMinor = Response[7];
|
|
||||||
Result.FlashAppVersionMajor = Response[8];
|
|
||||||
Result.FlashAppVersionMinor = Response[9];
|
|
||||||
break;
|
|
||||||
case FlashAppType.PhoneInfoApp:
|
|
||||||
Result.PhoneInfoAppProtocolVersionMajor = Response[6];
|
|
||||||
Result.PhoneInfoAppProtocolVersionMinor = Response[7];
|
|
||||||
Result.PhoneInfoAppVersionMajor = Response[8];
|
|
||||||
Result.PhoneInfoAppVersionMinor = Response[9];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte SubblockCount = Response[10];
|
|
||||||
int SubblockOffset = 11;
|
|
||||||
|
|
||||||
for (int i = 0; i < SubblockCount; i++)
|
|
||||||
{
|
|
||||||
byte SubblockID = Response[SubblockOffset + 0x00];
|
|
||||||
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
|
||||||
int SubblockPayloadOffset = SubblockOffset + 3;
|
|
||||||
byte SubblockVersion;
|
|
||||||
switch (SubblockID)
|
|
||||||
{
|
|
||||||
case 0x01:
|
|
||||||
Result.TransferSize = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
Result.WriteBufferSize = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
Result.EmmcSizeInSectors = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
if (Result.App == FlashAppType.BootManager)
|
|
||||||
{
|
|
||||||
Result.FlashAppProtocolVersionMajor = Response[SubblockPayloadOffset + 0x00];
|
|
||||||
Result.FlashAppProtocolVersionMinor = Response[SubblockPayloadOffset + 0x01];
|
|
||||||
Result.FlashAppVersionMajor = Response[SubblockPayloadOffset + 0x02];
|
|
||||||
Result.FlashAppVersionMinor = Response[SubblockPayloadOffset + 0x03];
|
|
||||||
}
|
|
||||||
else if (Result.App == FlashAppType.FlashApp)
|
|
||||||
{
|
|
||||||
Result.SdCardSizeInSectors = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
Result.PlatformID = ByteOperations.ReadAsciiString(Response, (uint)SubblockPayloadOffset, SubblockLength).Trim([' ', '\0']);
|
|
||||||
break;
|
|
||||||
case 0x0D:
|
|
||||||
Result.AsyncSupport = Response[SubblockPayloadOffset + 1] == 1;
|
|
||||||
break;
|
|
||||||
case 0x0F:
|
|
||||||
SubblockVersion = Response[SubblockPayloadOffset]; // 0x03
|
|
||||||
Result.PlatformSecureBootEnabled = Response[SubblockPayloadOffset + 0x01] == 0x01;
|
|
||||||
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.UefiSecureBootEnabled = Response[SubblockPayloadOffset + 0x06] == 0x01;
|
|
||||||
Result.SecondaryHardwareKeyPresent = Response[SubblockPayloadOffset + 0x07] == 0x01;
|
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
SubblockVersion = Response[SubblockPayloadOffset]; // 0x01
|
|
||||||
Result.SecureFfuSupportedProtocolMask = BigEndian.ToUInt16(Response, SubblockPayloadOffset + 0x01);
|
|
||||||
break;
|
|
||||||
case 0x1F:
|
|
||||||
Result.MmosOverUsbSupported = Response[SubblockPayloadOffset] == 1;
|
|
||||||
break;
|
|
||||||
case 0x20:
|
|
||||||
// CRC header info
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SubblockOffset += SubblockLength + 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result.State = PhoneInfoState.Basic;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result.IsBootloaderSecure = !(Info.Authenticated || Info.RdcPresent || !Info.SecureFfuEnabled);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisableRebootTimeOut()
|
|
||||||
{
|
|
||||||
byte[] Request = new byte[4];
|
|
||||||
const string Header = DisableTimeoutsSignature;
|
|
||||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
|
||||||
ExecuteRawMethod(Request);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Hello()
|
|
||||||
{
|
|
||||||
byte[] Request = new byte[4];
|
|
||||||
ByteOperations.WriteAsciiString(Request, 0, HelloSignature);
|
|
||||||
byte[] Response = ExecuteRawMethod(Request);
|
|
||||||
if (Response == null)
|
|
||||||
{
|
|
||||||
throw new BadConnectionException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ByteOperations.ReadAsciiString(Response, 0, 4) != HelloSignature)
|
|
||||||
{
|
|
||||||
throw new WPinternalsException("Bad response from phone!", "The phone did not answer properly to the Hello message sent.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
// 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
|
|
||||||
{
|
|
||||||
internal class PhoneInfo
|
|
||||||
{
|
|
||||||
public PhoneInfoState State = PhoneInfoState.Empty;
|
|
||||||
|
|
||||||
public string Type; // Extended info
|
|
||||||
public string ProductCode; // Extended info
|
|
||||||
public string Imei; // Extended info
|
|
||||||
public string Firmware; // Extended info
|
|
||||||
public byte[] RKH; // Extended info
|
|
||||||
|
|
||||||
public FlashAppType App;
|
|
||||||
|
|
||||||
public byte FlashAppVersionMajor;
|
|
||||||
public byte FlashAppVersionMinor;
|
|
||||||
public byte FlashAppProtocolVersionMajor;
|
|
||||||
public byte FlashAppProtocolVersionMinor;
|
|
||||||
|
|
||||||
public byte BootManagerVersionMajor;
|
|
||||||
public byte BootManagerVersionMinor;
|
|
||||||
public byte BootManagerProtocolVersionMajor;
|
|
||||||
public byte BootManagerProtocolVersionMinor;
|
|
||||||
|
|
||||||
public byte PhoneInfoAppVersionMajor;
|
|
||||||
public byte PhoneInfoAppVersionMinor;
|
|
||||||
public byte PhoneInfoAppProtocolVersionMajor;
|
|
||||||
public byte PhoneInfoAppProtocolVersionMinor;
|
|
||||||
|
|
||||||
public UInt32 TransferSize;
|
|
||||||
public bool MmosOverUsbSupported;
|
|
||||||
public UInt32 SdCardSizeInSectors;
|
|
||||||
public UInt32 WriteBufferSize;
|
|
||||||
public UInt32 EmmcSizeInSectors;
|
|
||||||
public string PlatformID;
|
|
||||||
public UInt16 SecureFfuSupportedProtocolMask;
|
|
||||||
public bool AsyncSupport;
|
|
||||||
|
|
||||||
public bool PlatformSecureBootEnabled;
|
|
||||||
public bool SecureFfuEnabled;
|
|
||||||
public bool JtagDisabled;
|
|
||||||
public bool RdcPresent;
|
|
||||||
public bool Authenticated;
|
|
||||||
public bool UefiSecureBootEnabled;
|
|
||||||
public bool SecondaryHardwareKeyPresent;
|
|
||||||
|
|
||||||
public bool IsBootloaderSecure;
|
|
||||||
|
|
||||||
internal void Log(LogType Type)
|
|
||||||
{
|
|
||||||
if (State == PhoneInfoState.Extended)
|
|
||||||
{
|
|
||||||
if (this.Type != null)
|
|
||||||
{
|
|
||||||
LogFile.Log("Phone type: " + this.Type, Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ProductCode != null)
|
|
||||||
{
|
|
||||||
LogFile.Log("Product code: " + ProductCode, Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RKH != null)
|
|
||||||
{
|
|
||||||
LogFile.Log("Root key hash: " + Converter.ConvertHexToString(RKH, ""), Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Firmware?.Length > 0)
|
|
||||||
{
|
|
||||||
LogFile.Log("Firmware version: " + Firmware, Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Type != LogType.ConsoleOnly && (Imei != null))
|
|
||||||
{
|
|
||||||
LogFile.Log("IMEI: " + Imei, LogType.FileOnly);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (App)
|
|
||||||
{
|
|
||||||
case FlashAppType.BootManager:
|
|
||||||
LogFile.Log("Bootmanager: " + BootManagerVersionMajor + "." + BootManagerVersionMinor, Type);
|
|
||||||
LogFile.Log("Bootmanager protocol: " + BootManagerProtocolVersionMajor + "." + BootManagerProtocolVersionMinor, Type);
|
|
||||||
LogFile.Log("Flash app: " + FlashAppVersionMajor + "." + FlashAppVersionMinor, Type);
|
|
||||||
LogFile.Log("Flash protocol: " + FlashAppProtocolVersionMajor + "." + FlashAppProtocolVersionMinor, Type);
|
|
||||||
break;
|
|
||||||
case FlashAppType.FlashApp:
|
|
||||||
LogFile.Log("Flash app: " + FlashAppVersionMajor + "." + FlashAppVersionMinor, Type);
|
|
||||||
LogFile.Log("Flash protocol: " + FlashAppProtocolVersionMajor + "." + FlashAppProtocolVersionMinor, Type);
|
|
||||||
break;
|
|
||||||
case FlashAppType.PhoneInfoApp:
|
|
||||||
LogFile.Log("Phone info app: " + PhoneInfoAppVersionMajor + "." + PhoneInfoAppVersionMinor, Type);
|
|
||||||
LogFile.Log("Phone info protocol: " + PhoneInfoAppProtocolVersionMajor + "." + PhoneInfoAppProtocolVersionMinor, Type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
LogFile.Log("Flash app security: " + (!IsBootloaderSecure ? "Disabled" : "Enabled"), LogType.ConsoleOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogFile.Log("JTAG: " + (JtagDisabled ? "Disabled" : "Enabled"), Type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// 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
|
||||||
|
{
|
||||||
|
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,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;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class LumiaBootManagerPhoneInfo
|
||||||
|
{
|
||||||
|
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||||
|
|
||||||
|
public FlashAppType App;
|
||||||
|
|
||||||
|
public byte FlashAppVersionMajor;
|
||||||
|
public byte FlashAppVersionMinor;
|
||||||
|
public byte FlashAppProtocolVersionMajor;
|
||||||
|
public byte FlashAppProtocolVersionMinor;
|
||||||
|
|
||||||
|
public byte BootManagerVersionMajor;
|
||||||
|
public byte BootManagerVersionMinor;
|
||||||
|
public byte BootManagerProtocolVersionMajor;
|
||||||
|
public byte BootManagerProtocolVersionMinor;
|
||||||
|
|
||||||
|
public UInt32 TransferSize;
|
||||||
|
public bool MmosOverUsbSupported;
|
||||||
|
|
||||||
|
internal void Log(LogType Type)
|
||||||
|
{
|
||||||
|
switch (App)
|
||||||
|
{
|
||||||
|
case FlashAppType.BootManager:
|
||||||
|
LogFile.Log($"Bootmanager: {BootManagerVersionMajor}.{BootManagerVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Bootmanager protocol: {BootManagerProtocolVersionMajor}.{BootManagerProtocolVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash app: {FlashAppVersionMajor}.{FlashAppVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash protocol: {FlashAppProtocolVersionMajor}.{FlashAppProtocolVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash app: {FlashAppVersionMajor}.{FlashAppVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash protocol: {FlashAppProtocolVersionMajor}.{FlashAppProtocolVersionMinor}", Type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
// 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
|
||||||
|
{
|
||||||
|
internal class LumiaFlashAppPhoneInfo
|
||||||
|
{
|
||||||
|
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||||
|
|
||||||
|
public string Firmware; // Extended info
|
||||||
|
public byte[] RKH; // Extended info
|
||||||
|
|
||||||
|
public FlashAppType App;
|
||||||
|
|
||||||
|
public byte FlashAppVersionMajor;
|
||||||
|
public byte FlashAppVersionMinor;
|
||||||
|
public byte FlashAppProtocolVersionMajor;
|
||||||
|
public byte FlashAppProtocolVersionMinor;
|
||||||
|
|
||||||
|
public UInt32 TransferSize;
|
||||||
|
public bool MmosOverUsbSupported;
|
||||||
|
public UInt32 SdCardSizeInSectors;
|
||||||
|
public UInt32 WriteBufferSize;
|
||||||
|
public UInt32 EmmcSizeInSectors;
|
||||||
|
public string PlatformID;
|
||||||
|
public UInt16 SecureFfuSupportedProtocolMask;
|
||||||
|
public bool AsyncSupport;
|
||||||
|
|
||||||
|
public bool PlatformSecureBootEnabled;
|
||||||
|
public bool SecureFfuEnabled;
|
||||||
|
public bool JtagDisabled;
|
||||||
|
public bool RdcPresent;
|
||||||
|
public bool Authenticated;
|
||||||
|
public bool UefiSecureBootEnabled;
|
||||||
|
public bool SecondaryHardwareKeyPresent;
|
||||||
|
|
||||||
|
public bool IsBootloaderSecure;
|
||||||
|
|
||||||
|
internal void Log(LogType Type)
|
||||||
|
{
|
||||||
|
if (State == PhoneInfoState.Extended)
|
||||||
|
{
|
||||||
|
if (RKH != null)
|
||||||
|
{
|
||||||
|
LogFile.Log($"Root key hash: {Converter.ConvertHexToString(RKH, "")}", Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Firmware?.Length > 0)
|
||||||
|
{
|
||||||
|
LogFile.Log($"Firmware version: {Firmware}", Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (App)
|
||||||
|
{
|
||||||
|
case FlashAppType.FlashApp:
|
||||||
|
LogFile.Log($"Flash app: {FlashAppVersionMajor}.{FlashAppVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash protocol: {FlashAppProtocolVersionMajor}.{FlashAppProtocolVersionMinor}", Type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
LogFile.Log($"Flash app security: {(!IsBootloaderSecure ? "Disabled" : "Enabled")}", LogType.ConsoleOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogFile.Log($"JTAG: {(JtagDisabled ? "Disabled" : "Enabled")}", Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
// 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
|
||||||
|
{
|
||||||
|
internal class LumiaPhoneInfoAppPhoneInfo
|
||||||
|
{
|
||||||
|
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||||
|
|
||||||
|
public string Type; // Extended info
|
||||||
|
public string ProductCode; // Extended info
|
||||||
|
public string Imei; // Extended info
|
||||||
|
|
||||||
|
public FlashAppType App;
|
||||||
|
|
||||||
|
public byte PhoneInfoAppVersionMajor;
|
||||||
|
public byte PhoneInfoAppVersionMinor;
|
||||||
|
public byte PhoneInfoAppProtocolVersionMajor;
|
||||||
|
public byte PhoneInfoAppProtocolVersionMinor;
|
||||||
|
|
||||||
|
internal void Log(LogType Type)
|
||||||
|
{
|
||||||
|
if (State == PhoneInfoState.Extended)
|
||||||
|
{
|
||||||
|
if (this.Type != null)
|
||||||
|
{
|
||||||
|
LogFile.Log($"Phone type: {this.Type}", Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProductCode != null)
|
||||||
|
{
|
||||||
|
LogFile.Log($"Product code: {ProductCode}", Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type != LogType.ConsoleOnly && (Imei != null))
|
||||||
|
{
|
||||||
|
LogFile.Log($"IMEI: {Imei}", LogType.FileOnly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (App)
|
||||||
|
{
|
||||||
|
case FlashAppType.PhoneInfoApp:
|
||||||
|
LogFile.Log($"Phone info app: {PhoneInfoAppVersionMajor}.{PhoneInfoAppVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Phone info protocol: {PhoneInfoAppProtocolVersionMajor}.{PhoneInfoAppProtocolVersionMinor}", Type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+67
-4
@@ -26,6 +26,8 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
internal class LumiaBootManagerAppModel : NokiaFlashModel
|
internal class LumiaBootManagerAppModel : NokiaFlashModel
|
||||||
{
|
{
|
||||||
|
internal readonly LumiaBootManagerPhoneInfo BootManagerInfo = new();
|
||||||
|
|
||||||
internal enum SecureBootKeyType : byte
|
internal enum SecureBootKeyType : byte
|
||||||
{
|
{
|
||||||
Retail = 0,
|
Retail = 0,
|
||||||
@@ -102,15 +104,15 @@ namespace WPinternals
|
|||||||
ExecuteRawVoidMethod(Request);
|
ExecuteRawVoidMethod(Request);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal PhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
internal LumiaBootManagerPhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
||||||
{
|
{
|
||||||
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
// NOKV = Info Query
|
// NOKV = Info Query
|
||||||
|
|
||||||
bool PhoneInfoLogged = Info.State != PhoneInfoState.Empty;
|
bool PhoneInfoLogged = BootManagerInfo.State != PhoneInfoState.Empty;
|
||||||
ReadPhoneInfoCommon();
|
ReadPhoneInfoBootManager();
|
||||||
|
|
||||||
PhoneInfo Result = Info;
|
LumiaBootManagerPhoneInfo Result = BootManagerInfo;
|
||||||
|
|
||||||
if (!PhoneInfoLogged)
|
if (!PhoneInfoLogged)
|
||||||
{
|
{
|
||||||
@@ -120,6 +122,67 @@ namespace WPinternals
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal LumiaBootManagerPhoneInfo ReadPhoneInfoBootManager()
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
LumiaBootManagerPhoneInfo Result = BootManagerInfo;
|
||||||
|
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||||
|
{
|
||||||
|
Result.App = (FlashAppType)Response[5];
|
||||||
|
|
||||||
|
switch (Result.App)
|
||||||
|
{
|
||||||
|
case FlashAppType.BootManager:
|
||||||
|
Result.BootManagerProtocolVersionMajor = Response[6];
|
||||||
|
Result.BootManagerProtocolVersionMinor = Response[7];
|
||||||
|
Result.BootManagerVersionMajor = Response[8];
|
||||||
|
Result.BootManagerVersionMinor = Response[9];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SubblockCount = Response[10];
|
||||||
|
int SubblockOffset = 11;
|
||||||
|
|
||||||
|
for (int i = 0; i < SubblockCount; i++)
|
||||||
|
{
|
||||||
|
byte SubblockID = Response[SubblockOffset + 0x00];
|
||||||
|
|
||||||
|
LogFile.Log($"{Result.App} SubblockID: 0x{SubblockID:X}");
|
||||||
|
|
||||||
|
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||||
|
int SubblockPayloadOffset = SubblockOffset + 3;
|
||||||
|
byte SubblockVersion;
|
||||||
|
switch (SubblockID)
|
||||||
|
{
|
||||||
|
case 0x01:
|
||||||
|
Result.TransferSize = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
Result.FlashAppProtocolVersionMajor = Response[SubblockPayloadOffset + 0x00];
|
||||||
|
Result.FlashAppProtocolVersionMinor = Response[SubblockPayloadOffset + 0x01];
|
||||||
|
Result.FlashAppVersionMajor = Response[SubblockPayloadOffset + 0x02];
|
||||||
|
Result.FlashAppVersionMinor = Response[SubblockPayloadOffset + 0x03];
|
||||||
|
break;
|
||||||
|
case 0x1F:
|
||||||
|
Result.MmosOverUsbSupported = Response[SubblockPayloadOffset] == 1;
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
// CRC header info
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SubblockOffset += SubblockLength + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal GPT ReadGPT()
|
internal GPT ReadGPT()
|
||||||
{
|
{
|
||||||
// If this function is used with a locked BootMgr v1,
|
// If this function is used with a locked BootMgr v1,
|
||||||
+95
-8
@@ -70,6 +70,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
internal class LumiaFlashAppModel : NokiaFlashModel
|
internal class LumiaFlashAppModel : NokiaFlashModel
|
||||||
{
|
{
|
||||||
|
internal readonly LumiaFlashAppPhoneInfo FlashAppInfo = new();
|
||||||
private UefiSecurityStatusResponse _SecurityStatus = null;
|
private UefiSecurityStatusResponse _SecurityStatus = null;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -156,15 +157,15 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
internal PhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
internal LumiaFlashAppPhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
||||||
{
|
{
|
||||||
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
// NOKV = Info Query
|
// NOKV = Info Query
|
||||||
|
|
||||||
bool PhoneInfoLogged = Info.State != PhoneInfoState.Empty;
|
bool PhoneInfoLogged = FlashAppInfo.State != PhoneInfoState.Empty;
|
||||||
ReadPhoneInfoCommon();
|
ReadPhoneInfoFlashApp();
|
||||||
|
|
||||||
PhoneInfo Result = Info;
|
LumiaFlashAppPhoneInfo Result = FlashAppInfo;
|
||||||
|
|
||||||
if (ExtendedInfo && (Result.State == PhoneInfoState.Basic))
|
if (ExtendedInfo && (Result.State == PhoneInfoState.Basic))
|
||||||
{
|
{
|
||||||
@@ -185,6 +186,92 @@ namespace WPinternals
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal LumiaFlashAppPhoneInfo ReadPhoneInfoFlashApp()
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
LumiaFlashAppPhoneInfo Result = FlashAppInfo;
|
||||||
|
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||||
|
{
|
||||||
|
Result.App = (FlashAppType)Response[5];
|
||||||
|
|
||||||
|
switch (Result.App)
|
||||||
|
{
|
||||||
|
case FlashAppType.FlashApp:
|
||||||
|
Result.FlashAppProtocolVersionMajor = Response[6];
|
||||||
|
Result.FlashAppProtocolVersionMinor = Response[7];
|
||||||
|
Result.FlashAppVersionMajor = Response[8];
|
||||||
|
Result.FlashAppVersionMinor = Response[9];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SubblockCount = Response[10];
|
||||||
|
int SubblockOffset = 11;
|
||||||
|
|
||||||
|
for (int i = 0; i < SubblockCount; i++)
|
||||||
|
{
|
||||||
|
byte SubblockID = Response[SubblockOffset + 0x00];
|
||||||
|
|
||||||
|
LogFile.Log($"{Result.App} SubblockID: 0x{SubblockID:X}");
|
||||||
|
|
||||||
|
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||||
|
int SubblockPayloadOffset = SubblockOffset + 3;
|
||||||
|
byte SubblockVersion;
|
||||||
|
switch (SubblockID)
|
||||||
|
{
|
||||||
|
case 0x01:
|
||||||
|
Result.TransferSize = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
Result.WriteBufferSize = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
Result.EmmcSizeInSectors = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
Result.SdCardSizeInSectors = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
||||||
|
break;
|
||||||
|
case 0x05:
|
||||||
|
Result.PlatformID = ByteOperations.ReadAsciiString(Response, (uint)SubblockPayloadOffset, SubblockLength).Trim([' ', '\0']);
|
||||||
|
break;
|
||||||
|
case 0x0D:
|
||||||
|
Result.AsyncSupport = Response[SubblockPayloadOffset + 1] == 1;
|
||||||
|
break;
|
||||||
|
case 0x0F:
|
||||||
|
SubblockVersion = Response[SubblockPayloadOffset]; // 0x03
|
||||||
|
Result.PlatformSecureBootEnabled = Response[SubblockPayloadOffset + 0x01] == 0x01;
|
||||||
|
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.UefiSecureBootEnabled = Response[SubblockPayloadOffset + 0x06] == 0x01;
|
||||||
|
Result.SecondaryHardwareKeyPresent = Response[SubblockPayloadOffset + 0x07] == 0x01;
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
SubblockVersion = Response[SubblockPayloadOffset]; // 0x01
|
||||||
|
Result.SecureFfuSupportedProtocolMask = BigEndian.ToUInt16(Response, SubblockPayloadOffset + 0x01);
|
||||||
|
break;
|
||||||
|
case 0x1F:
|
||||||
|
Result.MmosOverUsbSupported = Response[SubblockPayloadOffset] == 1;
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
// CRC header info
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SubblockOffset += SubblockLength + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.IsBootloaderSecure = !(FlashAppInfo.Authenticated || FlashAppInfo.RdcPresent || !FlashAppInfo.SecureFfuEnabled);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal GPT ReadGPT()
|
internal GPT ReadGPT()
|
||||||
{
|
{
|
||||||
// If this function is used with a locked BootMgr v1,
|
// If this function is used with a locked BootMgr v1,
|
||||||
@@ -193,7 +280,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
// Only works in BootLoader-mode or on unlocked bootloaders in Flash-mode!!
|
// Only works in BootLoader-mode or on unlocked bootloaders in Flash-mode!!
|
||||||
|
|
||||||
PhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
|
LumiaFlashAppPhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
|
||||||
FlashAppType OriginalAppType = Info.App;
|
FlashAppType OriginalAppType = Info.App;
|
||||||
bool Switch = Info.IsBootloaderSecure;
|
bool Switch = Info.IsBootloaderSecure;
|
||||||
if (Switch)
|
if (Switch)
|
||||||
@@ -230,7 +317,7 @@ namespace WPinternals
|
|||||||
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
|
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
|
||||||
byte[] GPTChunk = new byte[Size];
|
byte[] GPTChunk = new byte[Size];
|
||||||
|
|
||||||
PhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
|
LumiaFlashAppPhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
|
||||||
FlashAppType OriginalAppType = Info.App;
|
FlashAppType OriginalAppType = Info.App;
|
||||||
bool Switch = Info.IsBootloaderSecure;
|
bool Switch = Info.IsBootloaderSecure;
|
||||||
if (Switch)
|
if (Switch)
|
||||||
@@ -825,7 +912,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
ProgressUpdater Progress = UpdaterPerChunk;
|
ProgressUpdater Progress = UpdaterPerChunk;
|
||||||
|
|
||||||
PhoneInfo Info = ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = ReadPhoneInfo();
|
||||||
if (!Info.MmosOverUsbSupported)
|
if (!Info.MmosOverUsbSupported)
|
||||||
{
|
{
|
||||||
throw new WPinternalsException("Flash failed!", "Protocols not supported. The device reports that loading Microsoft Manufacturing Operating System over USB is not supported.");
|
throw new WPinternalsException("Flash failed!", "Protocols not supported. The device reports that loading Microsoft Manufacturing Operating System over USB is not supported.");
|
||||||
@@ -884,7 +971,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
ProgressUpdater Progress = UpdaterPerChunk;
|
ProgressUpdater Progress = UpdaterPerChunk;
|
||||||
|
|
||||||
PhoneInfo Info = ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = ReadPhoneInfo();
|
||||||
if ((Info.SecureFfuSupportedProtocolMask & ((ushort)FfuProtocol.ProtocolSyncV1 | (ushort)FfuProtocol.ProtocolSyncV2)) == 0)
|
if ((Info.SecureFfuSupportedProtocolMask & ((ushort)FfuProtocol.ProtocolSyncV1 | (ushort)FfuProtocol.ProtocolSyncV2)) == 0)
|
||||||
{
|
{
|
||||||
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?");
|
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?");
|
||||||
+95
-9
@@ -19,6 +19,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -26,6 +27,8 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
internal class LumiaPhoneInfoAppModel : NokiaFlashModel
|
internal class LumiaPhoneInfoAppModel : NokiaFlashModel
|
||||||
{
|
{
|
||||||
|
internal readonly LumiaPhoneInfoAppPhoneInfo PhoneInfoAppInfo = new();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Not valid commands
|
// Not valid commands
|
||||||
//
|
//
|
||||||
@@ -73,7 +76,7 @@ namespace WPinternals
|
|||||||
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
// NOKV = Info Query
|
// NOKV = Info Query
|
||||||
|
|
||||||
if (Info.FlashAppProtocolVersionMajor >= 2)
|
if (PhoneInfoAppInfo.PhoneInfoAppVersionMajor >= 2)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -93,23 +96,58 @@ namespace WPinternals
|
|||||||
return PhoneInfoData;
|
return PhoneInfoData;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal PhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
internal LumiaPhoneInfoAppPhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
||||||
{
|
{
|
||||||
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
// NOKV = Info Query
|
// NOKV = Info Query
|
||||||
|
|
||||||
bool PhoneInfoLogged = Info.State != PhoneInfoState.Empty;
|
bool PhoneInfoLogged = PhoneInfoAppInfo.State != PhoneInfoState.Empty;
|
||||||
ReadPhoneInfoCommon();
|
ReadPhoneInfoPhoneInfoApp();
|
||||||
|
|
||||||
PhoneInfo Result = Info;
|
LumiaPhoneInfoAppPhoneInfo Result = PhoneInfoAppInfo;
|
||||||
|
|
||||||
if (ExtendedInfo && (Result.State == PhoneInfoState.Basic))
|
if (ExtendedInfo && (Result.State == PhoneInfoState.Basic))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Result.Type = ReadPhoneInfoVariable("TYPE");
|
if (Result.PhoneInfoAppProtocolVersionMajor >= 2)
|
||||||
Result.ProductCode = ReadPhoneInfoVariable("CTR");
|
{
|
||||||
Result.Imei = ReadPhoneInfoVariable("IMEI");
|
Result.Type = ReadPhoneInfoVariable("TYPE");
|
||||||
|
Result.ProductCode = ReadPhoneInfoVariable("CTR");
|
||||||
|
Result.Imei = ReadPhoneInfoVariable("IMEI");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Version: 1.1.1.3
|
||||||
|
* TYPE: RM-885
|
||||||
|
* BTR: 059R0M0
|
||||||
|
* LPSN: ...
|
||||||
|
* HWID: 1000
|
||||||
|
* CTR: 059S4B1
|
||||||
|
* MC: 0205354
|
||||||
|
* IMEI: ...
|
||||||
|
*/
|
||||||
|
string PhoneInfoData = GetPhoneInfo();
|
||||||
|
if (!string.IsNullOrEmpty(PhoneInfoData))
|
||||||
|
{
|
||||||
|
string[] Variables = PhoneInfoData.Split("\n");
|
||||||
|
Dictionary<string, string> FormattedVariables = [];
|
||||||
|
foreach (string Variable in Variables)
|
||||||
|
{
|
||||||
|
if (!Variable.Contains(":"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormattedVariables.Add(Variable.Split(":")[0].Trim(), Variable.Split(":")[1].Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.Type = FormattedVariables["TYPE"];
|
||||||
|
Result.ProductCode = FormattedVariables["CTR"];
|
||||||
|
Result.Imei = FormattedVariables["IMEI"];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -127,6 +165,55 @@ namespace WPinternals
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal LumiaPhoneInfoAppPhoneInfo ReadPhoneInfoPhoneInfoApp()
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
LumiaPhoneInfoAppPhoneInfo Result = PhoneInfoAppInfo;
|
||||||
|
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||||
|
{
|
||||||
|
Result.App = (FlashAppType)Response[5];
|
||||||
|
|
||||||
|
switch (Result.App)
|
||||||
|
{
|
||||||
|
case FlashAppType.PhoneInfoApp:
|
||||||
|
Result.PhoneInfoAppProtocolVersionMajor = Response[6];
|
||||||
|
Result.PhoneInfoAppProtocolVersionMinor = Response[7];
|
||||||
|
Result.PhoneInfoAppVersionMajor = Response[8];
|
||||||
|
Result.PhoneInfoAppVersionMinor = Response[9];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SubblockCount = Response[10];
|
||||||
|
int SubblockOffset = 11;
|
||||||
|
|
||||||
|
for (int i = 0; i < SubblockCount; i++)
|
||||||
|
{
|
||||||
|
byte SubblockID = Response[SubblockOffset + 0x00];
|
||||||
|
|
||||||
|
LogFile.Log($"{Result.App} SubblockID: 0x{SubblockID:X}");
|
||||||
|
|
||||||
|
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||||
|
int SubblockPayloadOffset = SubblockOffset + 3;
|
||||||
|
byte SubblockVersion;
|
||||||
|
switch (SubblockID)
|
||||||
|
{
|
||||||
|
case 0x20:
|
||||||
|
// CRC header info
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SubblockOffset += SubblockLength + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
internal string ReadPhoneInfoVariable(string VariableName)
|
internal string ReadPhoneInfoVariable(string VariableName)
|
||||||
{
|
{
|
||||||
// This function assumes the phone is in Phone Info App context
|
// This function assumes the phone is in Phone Info App context
|
||||||
@@ -141,7 +228,6 @@ namespace WPinternals
|
|||||||
internal string ReadProductCode()
|
internal string ReadProductCode()
|
||||||
{
|
{
|
||||||
string Result = ReadPhoneInfoVariable("CTR");
|
string Result = ReadPhoneInfoVariable("CTR");
|
||||||
SwitchToFlashAppContext();
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
// 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
|
||||||
|
{
|
||||||
|
internal delegate void InterfaceChangedHandler(PhoneInterfaces NewInterface, string DevicePath);
|
||||||
|
|
||||||
|
internal class NokiaFlashModel : NokiaPhoneModel
|
||||||
|
{
|
||||||
|
private string _devicePath;
|
||||||
|
|
||||||
|
private readonly CommonPhoneInfo CommonInfo = new();
|
||||||
|
|
||||||
|
internal event InterfaceChangedHandler InterfaceChanged = delegate { };
|
||||||
|
|
||||||
|
//
|
||||||
|
// Not valid commands
|
||||||
|
//
|
||||||
|
/* NOK */
|
||||||
|
private const string Signature = "NOK";
|
||||||
|
/* NOKX */
|
||||||
|
private const string ExtendedMessageSignature = $"{Signature}X";
|
||||||
|
/* NOKXC */
|
||||||
|
private const string CommonExtendedMessageSignature = $"{ExtendedMessageSignature}C";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common extended commands
|
||||||
|
//
|
||||||
|
/* NOKXCB */
|
||||||
|
private const string SwitchModeSignature = $"{CommonExtendedMessageSignature}B";
|
||||||
|
/* NOKXCE */
|
||||||
|
private const string EchoSignature = $"{CommonExtendedMessageSignature}E";
|
||||||
|
|
||||||
|
public NokiaFlashModel(string DevicePath) : base(DevicePath)
|
||||||
|
{
|
||||||
|
_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");
|
||||||
|
ExecuteRawVoidMethod(Request);
|
||||||
|
|
||||||
|
ResetDevice();
|
||||||
|
|
||||||
|
Dispose(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
//
|
||||||
|
/* NOKD */
|
||||||
|
private const string DisableTimeoutsSignature = $"{Signature}D";
|
||||||
|
/* NOKI */
|
||||||
|
private const string HelloSignature = $"{Signature}I";
|
||||||
|
/* NOKV */
|
||||||
|
private const string InfoQuerySignature = $"{Signature}V";
|
||||||
|
|
||||||
|
internal FlashAppType GetFlashAppType()
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response == null) || (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU"))
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (FlashAppType)Response[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CommonPhoneInfo ReadPhoneInfoCommon()
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
CommonPhoneInfo Result = CommonInfo;
|
||||||
|
|
||||||
|
if (Result.State == PhoneInfoState.Empty)
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||||
|
{
|
||||||
|
Result.App = (FlashAppType)Response[5];
|
||||||
|
Result.ProtocolVersionMajor = Response[6];
|
||||||
|
Result.ProtocolVersionMinor = Response[7];
|
||||||
|
Result.VersionMajor = Response[8];
|
||||||
|
Result.VersionMinor = Response[9];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.State = PhoneInfoState.Basic;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisableRebootTimeOut()
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
const string Header = DisableTimeoutsSignature;
|
||||||
|
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||||
|
ExecuteRawMethod(Request);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Hello()
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, HelloSignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if (Response == null)
|
||||||
|
{
|
||||||
|
throw new BadConnectionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ByteOperations.ReadAsciiString(Response, 0, 4) != HelloSignature)
|
||||||
|
{
|
||||||
|
throw new WPinternalsException("Bad response from phone!", "The phone did not answer properly to the Hello message sent.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -258,7 +258,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
LogFile.Log("Phone needs to be switched to emergency mode.", LogType.FileAndConsole);
|
LogFile.Log("Phone needs to be switched to emergency mode.", LogType.FileAndConsole);
|
||||||
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
PhoneInfo Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
Info.Log(LogType.ConsoleOnly);
|
||||||
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Qualcomm_Download);
|
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Qualcomm_Download);
|
||||||
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download)
|
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download)
|
||||||
|
|||||||
@@ -531,39 +531,62 @@ namespace WPinternals
|
|||||||
|
|
||||||
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
||||||
{
|
{
|
||||||
PhoneInfo FlashAppInfo = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
LumiaFlashAppPhoneInfo FlashAppInfo = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
||||||
FirmwareVersion = FlashAppInfo.Firmware;
|
FirmwareVersion = FlashAppInfo.Firmware;
|
||||||
|
|
||||||
IsSwitchingInterface = true;
|
IsSwitchingInterface = true;
|
||||||
|
|
||||||
(Notifier.CurrentModel as LumiaFlashAppModel).SwitchToPhoneInfoAppContext();
|
try
|
||||||
|
|
||||||
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
|
||||||
{
|
{
|
||||||
await Notifier.WaitForArrival();
|
bool ModernFlashApp = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)Notifier.CurrentModel).SwitchToPhoneInfoAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)Notifier.CurrentModel).SwitchToPhoneInfoAppContextLegacy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
await Notifier.WaitForArrival();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
LumiaPhoneInfoAppModel LumiaPhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
||||||
|
LumiaPhoneInfoAppPhoneInfo Info = LumiaPhoneInfoModel.ReadPhoneInfo();
|
||||||
|
ProductType = Info.Type;
|
||||||
|
OperatorCode = "";
|
||||||
|
ProductCode = Info.ProductCode;
|
||||||
|
|
||||||
|
ModernFlashApp = Info.PhoneInfoAppVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
LumiaPhoneInfoModel.SwitchToFlashAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LumiaPhoneInfoModel.ContinueBoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
||||||
|
{
|
||||||
|
await Notifier.WaitForArrival();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
||||||
|
{
|
||||||
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
|
||||||
{
|
{
|
||||||
throw new WPinternalsException("Unexpected Mode");
|
LogFile.LogException(ex);
|
||||||
}
|
|
||||||
|
|
||||||
LumiaPhoneInfoAppModel LumiaPhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
|
||||||
PhoneInfo Info = LumiaPhoneInfoModel.ReadPhoneInfo();
|
|
||||||
ProductType = Info.Type;
|
|
||||||
OperatorCode = "";
|
|
||||||
ProductCode = Info.ProductCode;
|
|
||||||
|
|
||||||
((LumiaPhoneInfoAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
|
|
||||||
|
|
||||||
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
|
||||||
{
|
|
||||||
await Notifier.WaitForArrival();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
|
||||||
{
|
|
||||||
throw new WPinternalsException("Unexpected Mode");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IsSwitchingInterface = false;
|
IsSwitchingInterface = false;
|
||||||
@@ -571,14 +594,22 @@ namespace WPinternals
|
|||||||
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_PhoneInfo)
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
{
|
{
|
||||||
LumiaPhoneInfoAppModel LumiaPhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
LumiaPhoneInfoAppModel LumiaPhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
||||||
PhoneInfo Info = LumiaPhoneInfoModel.ReadPhoneInfo();
|
LumiaPhoneInfoAppPhoneInfo Info = LumiaPhoneInfoModel.ReadPhoneInfo();
|
||||||
ProductType = Info.Type;
|
ProductType = Info.Type;
|
||||||
OperatorCode = "";
|
OperatorCode = "";
|
||||||
ProductCode = Info.ProductCode;
|
ProductCode = Info.ProductCode;
|
||||||
|
|
||||||
IsSwitchingInterface = true;
|
IsSwitchingInterface = true;
|
||||||
|
|
||||||
((LumiaPhoneInfoAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
|
bool ModernFlashApp = Info.PhoneInfoAppVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
LumiaPhoneInfoModel.SwitchToFlashAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LumiaPhoneInfoModel.ContinueBoot();
|
||||||
|
}
|
||||||
|
|
||||||
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
||||||
{
|
{
|
||||||
@@ -590,10 +621,18 @@ namespace WPinternals
|
|||||||
throw new WPinternalsException("Unexpected Mode");
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
PhoneInfo FlashAppInfo = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
LumiaFlashAppPhoneInfo FlashAppInfo = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
||||||
FirmwareVersion = FlashAppInfo.Firmware;
|
FirmwareVersion = FlashAppInfo.Firmware;
|
||||||
|
|
||||||
(Notifier.CurrentModel as LumiaFlashAppModel).SwitchToPhoneInfoAppContext();
|
ModernFlashApp = FlashAppInfo.FlashAppProtocolVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)Notifier.CurrentModel).SwitchToPhoneInfoAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)Notifier.CurrentModel).SwitchToPhoneInfoAppContextLegacy();
|
||||||
|
}
|
||||||
|
|
||||||
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
{
|
{
|
||||||
@@ -619,6 +658,8 @@ namespace WPinternals
|
|||||||
|
|
||||||
ProductType = TempProductType;
|
ProductType = TempProductType;
|
||||||
ProductCode = LumiaNormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); // 059Q9D7
|
ProductCode = LumiaNormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); // 059Q9D7
|
||||||
|
|
||||||
|
FirmwareVersion = LumiaNormalModel.ExecuteJsonMethodAsString("ReadSwVersion", "SwVersion");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public DelegateCommand AddFFUCommand { get; } = null;
|
public DelegateCommand AddFFUCommand { get; } = null;
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ namespace WPinternals
|
|||||||
bool Result = true;
|
bool Result = true;
|
||||||
|
|
||||||
LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
||||||
PhoneInfo Info = Phone.ReadPhoneInfo(false);
|
LumiaFlashAppPhoneInfo Info = Phone.ReadPhoneInfo(false);
|
||||||
|
|
||||||
#region Remove bootloader changes
|
#region Remove bootloader changes
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
TestPos = 2;
|
TestPos = 2;
|
||||||
|
|
||||||
PhoneInfo Info = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo();
|
||||||
if (SecurityStatus == null)
|
if (SecurityStatus == null)
|
||||||
{
|
{
|
||||||
IsBootLoaderUnlocked = !Info.IsBootloaderSecure;
|
IsBootLoaderUnlocked = !Info.IsBootloaderSecure;
|
||||||
@@ -297,11 +297,11 @@ namespace WPinternals
|
|||||||
|
|
||||||
if (DoUnlock)
|
if (DoUnlock)
|
||||||
{
|
{
|
||||||
ActivateSubContext(new BootUnlockResourcesViewModel("Lumia Flash mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunction, Abort, IsBootLoaderUnlocked, true, Info.PlatformID, Info.Type));
|
ActivateSubContext(new BootUnlockResourcesViewModel("Lumia Flash mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunction, Abort, IsBootLoaderUnlocked, true, Info.PlatformID, /*TODO FIXME: Info.Type*/""));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ActivateSubContext(new BootRestoreResourcesViewModel("Lumia Flash mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunction, Abort, IsBootLoaderUnlocked, true, Info.PlatformID, Info.Type));
|
ActivateSubContext(new BootRestoreResourcesViewModel("Lumia Flash mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunction, Abort, IsBootLoaderUnlocked, true, Info.PlatformID, /*TODO FIXME: Info.Type*/""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -511,7 +511,7 @@ namespace WPinternals
|
|||||||
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download && PhoneNotifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
|
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download && PhoneNotifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
|
||||||
{
|
{
|
||||||
LumiaFlashAppModel Model = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
LumiaFlashAppModel Model = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
||||||
PhoneInfo Info = Model.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = Model.ReadPhoneInfo();
|
||||||
|
|
||||||
if (EDEPath == null)
|
if (EDEPath == null)
|
||||||
{
|
{
|
||||||
@@ -524,7 +524,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
Key.SetValue("EDEPath", EDEPath);
|
Key.SetValue("EDEPath", EDEPath);
|
||||||
|
|
||||||
App.Config.AddEmergencyToRepository(Info.Type, EDEPath, null);
|
App.Config.AddEmergencyToRepository(/*TODO FIXME: Info.Type*/"", EDEPath, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1510,7 +1510,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
byte[] EFIESPBackup = null;
|
byte[] EFIESPBackup = null;
|
||||||
|
|
||||||
PhoneInfo Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
|
||||||
bool IsSpecB = Info.FlashAppProtocolVersionMajor >= 2;
|
bool IsSpecB = Info.FlashAppProtocolVersionMajor >= 2;
|
||||||
bool UndoEFIESPPadding = false;
|
bool UndoEFIESPPadding = false;
|
||||||
|
|
||||||
@@ -1862,7 +1862,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo();
|
||||||
bool IsSpecB = Info.FlashAppProtocolVersionMajor >= 2;
|
bool IsSpecB = Info.FlashAppProtocolVersionMajor >= 2;
|
||||||
|
|
||||||
if (ProfileFFUPath == null)
|
if (ProfileFFUPath == null)
|
||||||
@@ -2589,7 +2589,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
private static async Task LumiaFlashParts(PhoneNotifierViewModel Notifier, string FFUPath, bool PerformFullFlashFirst, bool SkipWrite, List<FlashPart> Parts, bool DoResetFirst = true, bool ClearFlashingStatusAtEnd = true, bool CheckSectorAlignment = true, bool ShowProgress = true, bool Experimental = false, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, string EDEPath = null)
|
private static async Task LumiaFlashParts(PhoneNotifierViewModel Notifier, string FFUPath, bool PerformFullFlashFirst, bool SkipWrite, List<FlashPart> Parts, bool DoResetFirst = true, bool ClearFlashingStatusAtEnd = true, bool CheckSectorAlignment = true, bool ShowProgress = true, bool Experimental = false, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, string EDEPath = null)
|
||||||
{
|
{
|
||||||
PhoneInfo Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
|
||||||
bool IsSpecA = Info.FlashAppProtocolVersionMajor < 2;
|
bool IsSpecA = Info.FlashAppProtocolVersionMajor < 2;
|
||||||
|
|
||||||
if (IsSpecA)
|
if (IsSpecA)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
|
|
||||||
PhoneInfo Info;
|
LumiaFlashAppPhoneInfo Info;
|
||||||
if (DoResetFirst)
|
if (DoResetFirst)
|
||||||
{
|
{
|
||||||
// The phone will be reset before flashing, so we have the opportunity to get some more info from the phone
|
// The phone will be reset before flashing, so we have the opportunity to get some more info from the phone
|
||||||
@@ -232,7 +232,7 @@ namespace WPinternals
|
|||||||
if (DoResetFirst)
|
if (DoResetFirst)
|
||||||
{
|
{
|
||||||
// The phone will be reset before flashing, so we have the opportunity to get some more info from the phone
|
// The phone will be reset before flashing, so we have the opportunity to get some more info from the phone
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
Info.Log(LogType.ConsoleOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
|
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo();
|
||||||
|
|
||||||
// Use GetGptChunk() here instead of ReadGPT(), because ReadGPT() skips the first sector.
|
// Use GetGptChunk() here instead of ReadGPT(), because ReadGPT() skips the first sector.
|
||||||
// We need the fist sector if we want to write back the GPT.
|
// We need the fist sector if we want to write back the GPT.
|
||||||
@@ -447,7 +447,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
|
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo();
|
||||||
|
|
||||||
byte[] Data = File.ReadAllBytes(DataPath);
|
byte[] Data = File.ReadAllBytes(DataPath);
|
||||||
|
|
||||||
@@ -484,7 +484,7 @@ namespace WPinternals
|
|||||||
internal async static Task LumiaV2CustomFlash(PhoneNotifierViewModel Notifier, string FFUPath, bool PerformFullFlashFirst, bool SkipWrite, List<FlashPart> FlashParts, bool DoResetFirst = true, bool ClearFlashingStatusAtEnd = true, bool CheckSectorAlignment = true, bool ShowProgress = true, bool Experimental = false, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, string ProgrammerPath = null)
|
internal async static Task LumiaV2CustomFlash(PhoneNotifierViewModel Notifier, string FFUPath, bool PerformFullFlashFirst, bool SkipWrite, List<FlashPart> FlashParts, bool DoResetFirst = true, bool ClearFlashingStatusAtEnd = true, bool CheckSectorAlignment = true, bool ShowProgress = true, bool Experimental = false, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, string ProgrammerPath = null)
|
||||||
{
|
{
|
||||||
LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
|
LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
|
||||||
PhoneInfo Info = Model.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = Model.ReadPhoneInfo();
|
||||||
|
|
||||||
byte[] GPTChunk = Model.GetGptChunk(131072u);
|
byte[] GPTChunk = Model.GetGptChunk(131072u);
|
||||||
|
|
||||||
@@ -555,9 +555,9 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
|
|
||||||
LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
|
LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
|
||||||
PhoneInfo Info = Model.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = Model.ReadPhoneInfo();
|
||||||
|
|
||||||
string Type = Info.Type;
|
string Type = /*TODO: FIXME: Info.Type*/"";
|
||||||
if (ProgrammerPath == null)
|
if (ProgrammerPath == null)
|
||||||
{
|
{
|
||||||
ProgrammerPath = GetProgrammerPath(Info.RKH, Type);
|
ProgrammerPath = GetProgrammerPath(Info.RKH, Type);
|
||||||
@@ -1293,7 +1293,7 @@ namespace WPinternals
|
|||||||
if (!HeadersFull)
|
if (!HeadersFull)
|
||||||
{
|
{
|
||||||
Step = 12;
|
Step = 12;
|
||||||
App.Config.SetProfile(Info.Type, Info.PlatformID, Info.ProductCode, Info.Firmware, FFU.GetFirmwareVersion(), CurrentGapFill, ExploitHeaderAllocationSize, AssumeImageHeaderFallsInGap, AllocateAsyncBuffersOnPhone);
|
App.Config.SetProfile(/*TODO: FIXME: Info.Type*/"", Info.PlatformID, /*TODO: FIXME: Info.ProductCode*/"", Info.Firmware, FFU.GetFirmwareVersion(), CurrentGapFill, ExploitHeaderAllocationSize, AssumeImageHeaderFallsInGap, AllocateAsyncBuffersOnPhone);
|
||||||
if (ShowProgress)
|
if (ShowProgress)
|
||||||
{
|
{
|
||||||
LogFile.Log("Custom flash succeeded!", LogType.FileAndConsole);
|
LogFile.Log("Custom flash succeeded!", LogType.FileAndConsole);
|
||||||
@@ -2161,7 +2161,7 @@ namespace WPinternals
|
|||||||
GPTChanged = true;
|
GPTChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo(false);
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(false);
|
||||||
|
|
||||||
// We should only clear NV if there was no backup NV to be restored and the current NV contains the SB unlock.
|
// We should only clear NV if there was no backup NV to be restored and the current NV contains the SB unlock.
|
||||||
if ((NvBackupPartition == null) && !Info.UefiSecureBootEnabled)
|
if ((NvBackupPartition == null) && !Info.UefiSecureBootEnabled)
|
||||||
@@ -2520,7 +2520,7 @@ namespace WPinternals
|
|||||||
GPTChanged = true;
|
GPTChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo(false);
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(false);
|
||||||
|
|
||||||
// We should only clear NV if there was no backup NV to be restored and the current NV contains the SB unlock.
|
// We should only clear NV if there was no backup NV to be restored and the current NV contains the SB unlock.
|
||||||
if ((NvBackupPartition == null) && !Info.UefiSecureBootEnabled)
|
if ((NvBackupPartition == null) && !Info.UefiSecureBootEnabled)
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ namespace WPinternals
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
|
LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
|
||||||
PhoneInfo Info = Model.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = Model.ReadPhoneInfo();
|
||||||
|
|
||||||
if ((Info.SecureFfuSupportedProtocolMask & ((ushort)FfuProtocol.ProtocolSyncV2)) == 0) // Exploit needs protocol v2 -> This check is not conclusive, because old phones also report support for this protocol, although it is really not supported.
|
if ((Info.SecureFfuSupportedProtocolMask & ((ushort)FfuProtocol.ProtocolSyncV2)) == 0) // Exploit needs protocol v2 -> This check is not conclusive, because old phones also report support for this protocol, although it is really not supported.
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -222,15 +222,15 @@ namespace WPinternals
|
|||||||
LogFile.Log("Charging status: " + ChargingStatus);
|
LogFile.Log("Charging status: " + ChargingStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
PhoneInfo Info = CurrentModel.ReadPhoneInfo(true);
|
LumiaFlashAppPhoneInfo Info = CurrentModel.ReadPhoneInfo(true);
|
||||||
BootloaderDescription = Info.FlashAppProtocolVersionMajor < 2 ? "Lumia Bootloader Spec A" : "Lumia Bootloader Spec B";
|
BootloaderDescription = Info.FlashAppProtocolVersionMajor < 2 ? "Lumia Bootloader Spec A" : "Lumia Bootloader Spec B";
|
||||||
|
|
||||||
LogFile.Log("Bootloader: " + BootloaderDescription);
|
LogFile.Log("Bootloader: " + BootloaderDescription);
|
||||||
|
|
||||||
ProductCode = Info.ProductCode;
|
ProductCode = "";//TODO: FIXME: Info.ProductCode;
|
||||||
LogFile.Log("ProductCode: " + ProductCode);
|
LogFile.Log("ProductCode: " + ProductCode);
|
||||||
|
|
||||||
ProductType = Info.Type;
|
ProductType = "";//TODO: FIXME: Info.Type;
|
||||||
LogFile.Log("ProductType: " + ProductType);
|
LogFile.Log("ProductType: " + ProductType);
|
||||||
|
|
||||||
if (RootKeyHash == null)
|
if (RootKeyHash == null)
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PhoneInfo Info = CurrentModel.ReadPhoneInfo();
|
LumiaBootManagerPhoneInfo Info = CurrentModel.ReadPhoneInfo();
|
||||||
|
|
||||||
EffectiveBootloaderSecurityStatus = Info.UefiSecureBootEnabled;
|
//EffectiveBootloaderSecurityStatus = Info.UefiSecureBootEnabled; // FIXME
|
||||||
|
|
||||||
LogFile.Log("Effective Bootloader Security Status: " + EffectiveBootloaderSecurityStatus.ToString());
|
LogFile.Log("Effective Bootloader Security Status: " + EffectiveBootloaderSecurityStatus.ToString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PhoneInfo Info = CurrentModel.ReadPhoneInfo();
|
LumiaFlashAppPhoneInfo Info = CurrentModel.ReadPhoneInfo();
|
||||||
|
|
||||||
if (Info.FlashAppProtocolVersionMajor < 2)
|
if (Info.FlashAppProtocolVersionMajor < 2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PhoneInfo Info = CurrentModel.ReadPhoneInfo();
|
LumiaPhoneInfoAppPhoneInfo Info = CurrentModel.ReadPhoneInfo();
|
||||||
|
|
||||||
EffectivePhoneInfoSecurityStatus = Info.UefiSecureBootEnabled;
|
//EffectivePhoneInfoSecurityStatus = Info.UefiSecureBootEnabled; // FIXME
|
||||||
|
|
||||||
LogFile.Log("Effective Bootloader Security Status: " + EffectivePhoneInfoSecurityStatus.ToString());
|
LogFile.Log("Effective Bootloader Security Status: " + EffectivePhoneInfoSecurityStatus.ToString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ namespace WPinternals
|
|||||||
LogFile.Log("HWID: " + HWID);
|
LogFile.Log("HWID: " + HWID);
|
||||||
}
|
}
|
||||||
|
|
||||||
PhoneInfo Info = CurrentModel.ReadPhoneInfo(true);
|
LumiaPhoneInfoAppPhoneInfo Info = CurrentModel.ReadPhoneInfo(true);
|
||||||
BootloaderDescription = Info.FlashAppProtocolVersionMajor < 2 ? "Lumia Bootloader Spec A" : "Lumia Bootloader Spec B";
|
BootloaderDescription = Info.PhoneInfoAppVersionMajor < 2 ? "Lumia Bootloader Spec A" : "Lumia Bootloader Spec B";
|
||||||
|
|
||||||
LogFile.Log("Bootloader: " + BootloaderDescription);
|
LogFile.Log("Bootloader: " + BootloaderDescription);
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
if ((PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) && (TargetMode == PhoneInterfaces.Lumia_Flash))
|
if ((PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) && (TargetMode == PhoneInterfaces.Lumia_Flash))
|
||||||
{
|
{
|
||||||
PhoneInfo Info = ((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(false);
|
LumiaBootManagerPhoneInfo Info = ((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(false);
|
||||||
if (Info.BootManagerProtocolVersionMajor >= 2)
|
if (Info.BootManagerProtocolVersionMajor >= 2)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -293,7 +293,7 @@ namespace WPinternals
|
|||||||
Params.Add("ResetMethod", "HwReset");
|
Params.Add("ResetMethod", "HwReset");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
((NokiaPhoneModel)CurrentModel).ExecuteJsonMethodAsync("SetDeviceMode", Params);
|
((NokiaPhoneModel)PhoneNotifier.CurrentModel).ExecuteJsonMethodAsync("SetDeviceMode", Params);
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
}
|
}
|
||||||
catch (Exception Ex)
|
catch (Exception Ex)
|
||||||
@@ -308,7 +308,7 @@ namespace WPinternals
|
|||||||
switch (TargetMode)
|
switch (TargetMode)
|
||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
((LumiaFlashAppModel)CurrentModel).Shutdown();
|
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).Shutdown();
|
||||||
ModeSwitchProgressWrapper("Please disconnect your device. Waiting...", null);
|
ModeSwitchProgressWrapper("Please disconnect your device. Waiting...", null);
|
||||||
LogFile.Log("Please disconnect your device. Waiting...", LogType.FileAndConsole);
|
LogFile.Log("Please disconnect your device. Waiting...", LogType.FileAndConsole);
|
||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
@@ -319,26 +319,26 @@ namespace WPinternals
|
|||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_Normal:
|
case PhoneInterfaces.Lumia_Normal:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
((LumiaFlashAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_Bootloader:
|
case PhoneInterfaces.Lumia_Bootloader:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
((LumiaFlashAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_PhoneInfo:
|
case PhoneInterfaces.Lumia_PhoneInfo:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
ModernFlashApp = ((LumiaFlashAppModel)CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
|
ModernFlashApp = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
|
||||||
if (ModernFlashApp)
|
if (ModernFlashApp)
|
||||||
{
|
{
|
||||||
((LumiaFlashAppModel)CurrentModel).SwitchToPhoneInfoAppContext();
|
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).SwitchToPhoneInfoAppContext();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
((LumiaFlashAppModel)CurrentModel).SwitchToPhoneInfoAppContextLegacy();
|
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).SwitchToPhoneInfoAppContextLegacy();
|
||||||
}
|
}
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Phone Info mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Phone Info mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Phone Info mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Phone Info mode", LogType.FileAndConsole);
|
||||||
@@ -349,7 +349,7 @@ namespace WPinternals
|
|||||||
case PhoneInterfaces.Lumia_Flash: // attempt to boot from limited flash to full flash
|
case PhoneInterfaces.Lumia_Flash: // attempt to boot from limited flash to full flash
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
byte[] RebootToFlashCommand = [0x4E, 0x4F, 0x4B, 0x53]; // NOKS
|
byte[] RebootToFlashCommand = [0x4E, 0x4F, 0x4B, 0x53]; // NOKS
|
||||||
((LumiaFlashAppModel)CurrentModel).ExecuteRawVoidMethod(RebootToFlashCommand);
|
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ExecuteRawVoidMethod(RebootToFlashCommand);
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
@@ -359,7 +359,7 @@ namespace WPinternals
|
|||||||
case PhoneInterfaces.Qualcomm_Download:
|
case PhoneInterfaces.Qualcomm_Download:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
|
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
|
||||||
RebootCommandResult = ((LumiaFlashAppModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
RebootCommandResult = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
||||||
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
|
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
|
||||||
{
|
{
|
||||||
IsSwitchingInterface = false;
|
IsSwitchingInterface = false;
|
||||||
@@ -381,26 +381,26 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
case PhoneInterfaces.Lumia_Normal:
|
case PhoneInterfaces.Lumia_Normal:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
((LumiaPhoneInfoAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_Bootloader:
|
case PhoneInterfaces.Lumia_Bootloader:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
ModernFlashApp = ((LumiaPhoneInfoAppModel)CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
|
ModernFlashApp = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
|
||||||
if (ModernFlashApp)
|
if (ModernFlashApp)
|
||||||
{
|
{
|
||||||
((LumiaPhoneInfoAppModel)CurrentModel).SwitchToBootManagerContext();
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToBootManagerContext();
|
||||||
}
|
}
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_PhoneInfo: // attempt to boot from limited phone info to full phone info
|
case PhoneInterfaces.Lumia_PhoneInfo: // attempt to boot from limited phone info to full phone info
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
ModernFlashApp = ((LumiaPhoneInfoAppModel)CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
|
ModernFlashApp = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
|
||||||
if (ModernFlashApp)
|
if (ModernFlashApp)
|
||||||
{
|
{
|
||||||
((LumiaPhoneInfoAppModel)CurrentModel).SwitchToPhoneInfoAppContext();
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToPhoneInfoAppContext();
|
||||||
}
|
}
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Phone Info mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Phone Info mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Phone Info mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Phone Info mode", LogType.FileAndConsole);
|
||||||
@@ -410,14 +410,14 @@ namespace WPinternals
|
|||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_Flash:
|
case PhoneInterfaces.Lumia_Flash:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
ModernFlashApp = ((LumiaPhoneInfoAppModel)CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
|
ModernFlashApp = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
|
||||||
if (ModernFlashApp)
|
if (ModernFlashApp)
|
||||||
{
|
{
|
||||||
((LumiaPhoneInfoAppModel)CurrentModel).SwitchToFlashAppContext();
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
((LumiaPhoneInfoAppModel)CurrentModel).ContinueBoot();
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ContinueBoot();
|
||||||
}
|
}
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
|
||||||
@@ -428,7 +428,7 @@ namespace WPinternals
|
|||||||
case PhoneInterfaces.Qualcomm_Download:
|
case PhoneInterfaces.Qualcomm_Download:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
|
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
|
||||||
RebootCommandResult = ((LumiaPhoneInfoAppModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
RebootCommandResult = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
||||||
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
|
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
|
||||||
{
|
{
|
||||||
IsSwitchingInterface = false;
|
IsSwitchingInterface = false;
|
||||||
@@ -449,7 +449,7 @@ namespace WPinternals
|
|||||||
switch (TargetMode)
|
switch (TargetMode)
|
||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
((LumiaBootManagerAppModel)CurrentModel).Shutdown();
|
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).Shutdown();
|
||||||
ModeSwitchProgressWrapper("Please disconnect your device. Waiting...", null);
|
ModeSwitchProgressWrapper("Please disconnect your device. Waiting...", null);
|
||||||
LogFile.Log("Please disconnect your device. Waiting...", LogType.FileAndConsole);
|
LogFile.Log("Please disconnect your device. Waiting...", LogType.FileAndConsole);
|
||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
@@ -460,13 +460,13 @@ namespace WPinternals
|
|||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_Normal:
|
case PhoneInterfaces.Lumia_Normal:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
((LumiaBootManagerAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_Bootloader:
|
case PhoneInterfaces.Lumia_Bootloader:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
((LumiaBootManagerAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
@@ -476,7 +476,7 @@ namespace WPinternals
|
|||||||
case PhoneInterfaces.Lumia_Flash: // attempt to boot from limited flash to full flash
|
case PhoneInterfaces.Lumia_Flash: // attempt to boot from limited flash to full flash
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
byte[] RebootToFlashCommand = [0x4E, 0x4F, 0x4B, 0x53]; // NOKS
|
byte[] RebootToFlashCommand = [0x4E, 0x4F, 0x4B, 0x53]; // NOKS
|
||||||
((LumiaBootManagerAppModel)CurrentModel).ExecuteRawVoidMethod(RebootToFlashCommand);
|
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ExecuteRawVoidMethod(RebootToFlashCommand);
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
@@ -486,7 +486,7 @@ namespace WPinternals
|
|||||||
case PhoneInterfaces.Qualcomm_Download:
|
case PhoneInterfaces.Qualcomm_Download:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
|
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
|
||||||
RebootCommandResult = ((LumiaBootManagerAppModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
RebootCommandResult = ((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
||||||
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
|
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
|
||||||
{
|
{
|
||||||
IsSwitchingInterface = false;
|
IsSwitchingInterface = false;
|
||||||
@@ -508,25 +508,25 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
case PhoneInterfaces.Lumia_Normal:
|
case PhoneInterfaces.Lumia_Normal:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||||
((MassStorage)CurrentModel).Reboot();
|
((MassStorage)PhoneNotifier.CurrentModel).Reboot();
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_Label:
|
case PhoneInterfaces.Lumia_Label:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
|
||||||
((MassStorage)CurrentModel).Reboot();
|
((MassStorage)PhoneNotifier.CurrentModel).Reboot();
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Label mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Label mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Label mode...", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Label mode...", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
case PhoneInterfaces.Lumia_Flash:
|
case PhoneInterfaces.Lumia_Flash:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
|
||||||
((MassStorage)CurrentModel).Reboot();
|
((MassStorage)PhoneNotifier.CurrentModel).Reboot();
|
||||||
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
||||||
LogFile.Log("Rebooting phone to Flash mode...", LogType.FileAndConsole);
|
LogFile.Log("Rebooting phone to Flash mode...", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
case null:
|
case null:
|
||||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
|
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
|
||||||
((MassStorage)CurrentModel).Reboot();
|
((MassStorage)PhoneNotifier.CurrentModel).Reboot();
|
||||||
ModeSwitchProgressWrapper("First rebooting phone to Flash mode...", null);
|
ModeSwitchProgressWrapper("First rebooting phone to Flash mode...", null);
|
||||||
LogFile.Log("First rebooting phone to Bootloader mode...", LogType.FileAndConsole);
|
LogFile.Log("First rebooting phone to Bootloader mode...", LogType.FileAndConsole);
|
||||||
break;
|
break;
|
||||||
@@ -626,7 +626,7 @@ namespace WPinternals
|
|||||||
// SwitchToFlashAppContext() will only switch context. Phone will not charge.
|
// SwitchToFlashAppContext() will only switch context. Phone will not charge.
|
||||||
// ResetPhoneToFlashMode() reboots to real flash app. Phone will charge. Works when in BootMgrApp, not when already in FlashApp.
|
// ResetPhoneToFlashMode() reboots to real flash app. Phone will charge. Works when in BootMgrApp, not when already in FlashApp.
|
||||||
|
|
||||||
((LumiaBootManagerAppModel)CurrentModel).ResetPhoneToFlashMode();
|
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ResetPhoneToFlashMode();
|
||||||
CurrentMode = PhoneInterfaces.Lumia_Flash;
|
CurrentMode = PhoneInterfaces.Lumia_Flash;
|
||||||
PhoneNotifier.NotifyArrival();
|
PhoneNotifier.NotifyArrival();
|
||||||
}
|
}
|
||||||
@@ -640,7 +640,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
if (TargetMode == PhoneInterfaces.Lumia_Bootloader)
|
if (TargetMode == PhoneInterfaces.Lumia_Bootloader)
|
||||||
{
|
{
|
||||||
((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
|
((NokiaFlashModel)PhoneNotifier.CurrentModel).DisableRebootTimeOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModeSwitchSuccessWrapper();
|
ModeSwitchSuccessWrapper();
|
||||||
@@ -669,7 +669,7 @@ namespace WPinternals
|
|||||||
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
|
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
|
||||||
IsSwitchingInterface = true;
|
IsSwitchingInterface = true;
|
||||||
LogFile.Log("Sending command for rebooting to Emergency Download mode");
|
LogFile.Log("Sending command for rebooting to Emergency Download mode");
|
||||||
byte[] RebootCommandResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
byte[] RebootCommandResult = ((NokiaPhoneModel)PhoneNotifier.CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
||||||
if (RebootCommandResult?.Length >= 8)
|
if (RebootCommandResult?.Length >= 8)
|
||||||
{
|
{
|
||||||
int ResultCode = (RebootCommandResult[6] << 8) + RebootCommandResult[7];
|
int ResultCode = (RebootCommandResult[6] << 8) + RebootCommandResult[7];
|
||||||
@@ -722,11 +722,19 @@ namespace WPinternals
|
|||||||
|
|
||||||
string ProgressText = Continuation ? "And now preparing to boot the phone to Label mode..." : "Preparing to boot the phone to Label mode...";
|
string ProgressText = Continuation ? "And now preparing to boot the phone to Label mode..." : "Preparing to boot the phone to Label mode...";
|
||||||
|
|
||||||
PhoneInfo PhoneInfoAppInfo = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
LumiaPhoneInfoAppPhoneInfo PhoneInfoAppInfo = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
||||||
|
|
||||||
new Thread(async () =>
|
new Thread(async () =>
|
||||||
{
|
{
|
||||||
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
|
bool ModernFlashApp = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ContinueBoot();
|
||||||
|
}
|
||||||
|
|
||||||
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
||||||
{
|
{
|
||||||
@@ -739,7 +747,7 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
|
|
||||||
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: true);
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: true);
|
||||||
|
|
||||||
if (Info.MmosOverUsbSupported)
|
if (Info.MmosOverUsbSupported)
|
||||||
{
|
{
|
||||||
@@ -760,7 +768,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
(string ENOSWFileUrl, string DPLFileUrl) = LumiaDownloadModel.SearchENOSW(PhoneInfoAppInfo.Type, Info.Firmware);
|
(string ENOSWFileUrl, string DPLFileUrl) = LumiaDownloadModel.SearchENOSW(PhoneInfoAppInfo.Type, Info.Firmware);
|
||||||
|
|
||||||
SetWorkingStatus($"Downloading {Info.Type} Test Mode package...", MaxProgressValue: 100);
|
SetWorkingStatus($"Downloading {PhoneInfoAppInfo.Type} Test Mode package...", MaxProgressValue: 100);
|
||||||
|
|
||||||
DownloadEntry downloadEntry = new(ENOSWFileUrl, TempFolder, null, (string[] Files, object State) =>
|
DownloadEntry downloadEntry = new(ENOSWFileUrl, TempFolder, null, (string[] Files, object State) =>
|
||||||
{
|
{
|
||||||
@@ -829,11 +837,19 @@ namespace WPinternals
|
|||||||
throw new WPinternalsException("Unexpected Mode");
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
PhoneInfo Info = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
LumiaFlashAppPhoneInfo Info = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
||||||
|
|
||||||
new Thread(async () =>
|
new Thread(async () =>
|
||||||
{
|
{
|
||||||
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).SwitchToPhoneInfoAppContext();
|
bool ModernFlashApp = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).SwitchToPhoneInfoAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).SwitchToPhoneInfoAppContextLegacy();
|
||||||
|
}
|
||||||
|
|
||||||
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
{
|
{
|
||||||
@@ -845,9 +861,18 @@ namespace WPinternals
|
|||||||
throw new WPinternalsException("Unexpected Mode");
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
PhoneInfo PhoneInfoAppInfo = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true);
|
LumiaPhoneInfoAppModel LumiaPhoneInfoAppModel = (LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel;
|
||||||
|
LumiaPhoneInfoAppPhoneInfo PhoneInfoAppInfo = LumiaPhoneInfoAppModel.ReadPhoneInfo(ExtendedInfo: true);
|
||||||
|
|
||||||
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
|
ModernFlashApp = PhoneInfoAppInfo.PhoneInfoAppVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
LumiaPhoneInfoAppModel.SwitchToFlashAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LumiaPhoneInfoAppModel.ContinueBoot();
|
||||||
|
}
|
||||||
|
|
||||||
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
|
||||||
{
|
{
|
||||||
@@ -946,11 +971,19 @@ namespace WPinternals
|
|||||||
|
|
||||||
new Thread(async () =>
|
new Thread(async () =>
|
||||||
{
|
{
|
||||||
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
|
bool ModernFlashApp = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ContinueBoot();
|
||||||
|
}
|
||||||
await PhoneNotifier.WaitForArrival();
|
await PhoneNotifier.WaitForArrival();
|
||||||
|
|
||||||
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
|
||||||
|
|
||||||
MassStorageWarning = null;
|
MassStorageWarning = null;
|
||||||
if (Info.FlashAppProtocolVersionMajor < 2)
|
if (Info.FlashAppProtocolVersionMajor < 2)
|
||||||
@@ -1159,7 +1192,7 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
|
||||||
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
|
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
|
||||||
|
|
||||||
MassStorageWarning = null;
|
MassStorageWarning = null;
|
||||||
if (Info.FlashAppProtocolVersionMajor < 2)
|
if (Info.FlashAppProtocolVersionMajor < 2)
|
||||||
|
|||||||
Reference in New Issue
Block a user