wip: Refactor FlashApp Logic to account for the 3 split app states

This commit is contained in:
Gustave Monce
2024-08-31 16:39:44 +02:00
parent e6555741b0
commit 8e50c46357
40 changed files with 3098 additions and 1715 deletions
+37 -29
View File
@@ -83,7 +83,8 @@ namespace WPinternals
{ {
FFU FFU = null; FFU FFU = null;
PhoneNotifierViewModel Notifier; PhoneNotifierViewModel Notifier;
NokiaFlashModel FlashModel; LumiaFlashAppModel FlashModel;
LumiaBootManagerAppModel BootMgrModel;
NokiaPhoneModel NormalModel; NokiaPhoneModel NormalModel;
PhoneInfo Info; PhoneInfo Info;
string ProductType; string ProductType;
@@ -182,23 +183,14 @@ namespace WPinternals
Notifier = new PhoneNotifierViewModel(); Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader); // This also works for Bootloader Spec A BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader); // This also works for Bootloader Spec A
GPT GPT = FlashModel.ReadGPT(); // May throw NotSupportedException GPT GPT = BootMgrModel.ReadGPT(); // May throw NotSupportedException
foreach (Partition Partition in GPT.Partitions) foreach (Partition Partition in GPT.Partitions)
{ {
LogFile.Log(Partition.Name.PadRight(20) + "0x" + Partition.FirstSector.ToString("X8") + " - 0x" + Partition.LastSector.ToString("X8") + " " + Partition.Volume, LogType.ConsoleOnly); LogFile.Log(Partition.Name.PadRight(20) + "0x" + Partition.FirstSector.ToString("X8") + " - 0x" + Partition.LastSector.ToString("X8") + " " + Partition.Volume, LogType.ConsoleOnly);
} }
if (FlashModel.ReadPhoneInfo(false).FlashAppProtocolVersionMajor >= 2)
{
FlashModel.SwitchToFlashAppContext();
}
else
{
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
}
Notifier.Stop(); Notifier.Stop();
} }
catch (Exception Ex) catch (Exception Ex)
@@ -221,15 +213,14 @@ namespace WPinternals
{ {
Notifier = new PhoneNotifierViewModel(); Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader);
GPT GPT = FlashModel.ReadGPT(); // May throw NotSupportedException GPT GPT = BootMgrModel.ReadGPT(); // May throw NotSupportedException
string DirPath = Path.GetDirectoryName(args[2]); string DirPath = Path.GetDirectoryName(args[2]);
if (!string.IsNullOrEmpty(DirPath) && !Directory.Exists(DirPath)) if (!string.IsNullOrEmpty(DirPath) && !Directory.Exists(DirPath))
{ {
Directory.CreateDirectory(DirPath); Directory.CreateDirectory(DirPath);
} }
GPT.WritePartitions(args[2]); GPT.WritePartitions(args[2]);
FlashModel.SwitchToFlashAppContext();
Notifier.Stop(); Notifier.Stop();
} }
catch (Exception Ex) catch (Exception Ex)
@@ -281,14 +272,13 @@ namespace WPinternals
{ {
Notifier = new PhoneNotifierViewModel(); Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader);
byte[] GptChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(FlashModel, 0x20000); byte[] GptChunk = BootMgrModel.GetGptChunk(0x20000);
GPT GPT = new(GptChunk); GPT GPT = new(GptChunk);
string Xml = File.ReadAllText(args[2]); string Xml = File.ReadAllText(args[2]);
GPT.MergePartitions(Xml, false); GPT.MergePartitions(Xml, false);
GPT.Rebuild(); GPT.Rebuild();
await LumiaV2UnlockBootViewModel.LumiaV2CustomFlash(Notifier, null, false, false, 0, GptChunk, true, true); await LumiaV2UnlockBootViewModel.LumiaV2CustomFlash(Notifier, null, false, false, 0, GptChunk, true, true);
FlashModel.SwitchToFlashAppContext();
Notifier.Stop(); Notifier.Stop();
} }
catch (Exception Ex) catch (Exception Ex)
@@ -552,7 +542,7 @@ namespace WPinternals
try try
{ {
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
Info = FlashModel.ReadPhoneInfo(); Info = FlashModel.ReadPhoneInfo();
Info.Log(LogType.ConsoleOnly); Info.Log(LogType.ConsoleOnly);
@@ -701,7 +691,7 @@ namespace WPinternals
LogFile.Log("Command: Show phone info", LogType.FileAndConsole); LogFile.Log("Command: Show phone info", LogType.FileAndConsole);
Notifier = new PhoneNotifierViewModel(); Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
Info = FlashModel.ReadPhoneInfo(); Info = FlashModel.ReadPhoneInfo();
Info.Log(LogType.ConsoleOnly); Info.Log(LogType.ConsoleOnly);
Notifier.Stop(); Notifier.Stop();
@@ -713,7 +703,7 @@ namespace WPinternals
LogFile.Log("Command: Unlock Bootloader", LogType.FileAndConsole); LogFile.Log("Command: Unlock Bootloader", LogType.FileAndConsole);
Notifier = new PhoneNotifierViewModel(); Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
Info = FlashModel.ReadPhoneInfo(); Info = FlashModel.ReadPhoneInfo();
Info.Log(LogType.ConsoleOnly); Info.Log(LogType.ConsoleOnly);
@@ -786,7 +776,7 @@ namespace WPinternals
LogFile.Log("Custom ROM: " + CustomRomPath, LogType.FileAndConsole); LogFile.Log("Custom ROM: " + CustomRomPath, LogType.FileAndConsole);
Notifier = new PhoneNotifierViewModel(); Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
Info = FlashModel.ReadPhoneInfo(); Info = FlashModel.ReadPhoneInfo();
Info.Log(LogType.ConsoleOnly); Info.Log(LogType.ConsoleOnly);
LogFile.Log("Preparing to flash Custom ROM", LogType.FileAndConsole); LogFile.Log("Preparing to flash Custom ROM", LogType.FileAndConsole);
@@ -817,7 +807,7 @@ namespace WPinternals
LogFile.Log("FFU file: " + FFUPath, LogType.FileAndConsole); LogFile.Log("FFU file: " + FFUPath, LogType.FileAndConsole);
Notifier = new PhoneNotifierViewModel(); Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
Info = FlashModel.ReadPhoneInfo(); Info = FlashModel.ReadPhoneInfo();
Info.Log(LogType.ConsoleOnly); Info.Log(LogType.ConsoleOnly);
LogFile.Log("Flashing FFU...", LogType.FileAndConsole); LogFile.Log("Flashing FFU...", LogType.FileAndConsole);
@@ -1283,9 +1273,15 @@ namespace WPinternals
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel; NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
} }
else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)) else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
FlashModel = (NokiaFlashModel)Notifier.CurrentModel; BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
Info = BootMgrModel.ReadPhoneInfo();
ProductCode = Info.ProductCode;
}
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
{
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
Info = FlashModel.ReadPhoneInfo(); Info = FlashModel.ReadPhoneInfo();
ProductCode = Info.ProductCode; ProductCode = Info.ProductCode;
} }
@@ -1448,9 +1444,15 @@ namespace WPinternals
ProductType = ProductType.Substring(0, ProductType.IndexOf('_')); ProductType = ProductType.Substring(0, ProductType.IndexOf('_'));
} }
} }
else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)) else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
FlashModel = (NokiaFlashModel)Notifier.CurrentModel; BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
Info = BootMgrModel.ReadPhoneInfo();
ProductType = Info.Type;
}
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
{
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
Info = FlashModel.ReadPhoneInfo(); Info = FlashModel.ReadPhoneInfo();
ProductType = Info.Type; ProductType = Info.Type;
} }
@@ -1559,9 +1561,15 @@ namespace WPinternals
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel; NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
} }
else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)) else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
FlashModel = (NokiaFlashModel)Notifier.CurrentModel; BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
Info = BootMgrModel.ReadPhoneInfo();
ProductCode = Info.ProductCode;
}
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
{
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
Info = FlashModel.ReadPhoneInfo(); Info = FlashModel.ReadPhoneInfo();
ProductCode = Info.ProductCode; ProductCode = Info.ProductCode;
} }
+29
View File
@@ -0,0 +1,29 @@
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
namespace WPinternals
{
internal enum FlashAppType
{
BootManager = 1,
FlashApp = 2,
PhoneInfoApp = 3
};
}
+30
View File
@@ -0,0 +1,30 @@
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
namespace WPinternals
{
internal class FlashVersion
{
public int ApplicationMajor;
public int ApplicationMinor;
public int ProtocolMajor;
public int ProtocolMinor;
}
}
@@ -0,0 +1,392 @@
// 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;
namespace WPinternals
{
internal class LumiaBootManagerAppModel : NokiaFlashModel
{
private readonly PhoneInfo Info = new();
internal enum SecureBootKeyType : byte
{
Retail = 0,
Engineering = 1
}
//
// Not valid commands
//
/* NOK */
private const string Signature = "NOK";
/* NOKX */
private const string ExtendedMessageSignature = $"{Signature}X";
/* NOKXB */
private const string LumiaBootManagerExtendedMessageSignature = $"{ExtendedMessageSignature}B";
//
// Normal commands
//
/* NOKA */
private const string ContinueBootSignature = $"{Signature}A";
/* NOKB */
private const string RPMBSignature = $"{Signature}B";
/* NOKC */
private const string BatteryStatusSignature = $"{Signature}C";
/* NOKD */
private const string DisableTimeoutsSignature = $"{Signature}D";
/* NOKI */
private const string HelloSignature = $"{Signature}I";
/* NOKM */
private const string RebootToMassStorageSignature = $"{Signature}M";
/* NOKP */
private const string RebootToPhoneInfoAppSignature = $"{Signature}P";
/* NOKR */
private const string RebootSignature = $"{Signature}R";
/* NOKS */
private const string RebootToFlashAppSignature = $"{Signature}S";
/* NOKT */
private const string GetGPTSignature = $"{Signature}T";
/* NOKV */
private const string InfoQuerySignature = $"{Signature}V";
/* NOKW */
private const string WriteBootFlagFileSignature = $"{Signature}W";
/* NOKY */
private const string MMOSStartCommandSignature = $"{Signature}Y";
/* NOKZ */
private const string ShutdownSignature = $"{Signature}Z";
//
// Lumia Boot Manager extended commands
//
/* NOKXBD */
private const string PlatformSecureBootEnableSignature = $"{LumiaBootManagerExtendedMessageSignature}D";
/* NOKXBH */
private const string WriteRootCertificateHashSignature = $"{LumiaBootManagerExtendedMessageSignature}H";
/* NOKXBK */
private const string UEFIKeysProvisionSignature = $"{LumiaBootManagerExtendedMessageSignature}K";
/* NOKXBR */
private const string ReadManufacturingStateSignature = $"{LumiaBootManagerExtendedMessageSignature}R";
/* NOKXBU */
private const string FlushVariablesSignature = $"{LumiaBootManagerExtendedMessageSignature}U";
/* NOKXBW */
private const string WriteManufacturingStateSignature = $"{LumiaBootManagerExtendedMessageSignature}W";
public LumiaBootManagerAppModel(string DevicePath) : base(DevicePath)
{
}
internal void ContinueBoot()
{
LogFile.Log("Continue boot...");
byte[] Request = new byte[4];
ByteOperations.WriteAsciiString(Request, 0, ContinueBootSignature);
ExecuteRawVoidMethod(Request);
}
internal PhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
{
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
// NOKV = Info Query
bool PhoneInfoLogged = Info.State != PhoneInfoState.Empty;
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);
if (!PhoneInfoLogged)
{
Result.Log(LogType.FileOnly);
}
return Result;
}
internal GPT ReadGPT()
{
// If this function is used with a locked BootMgr v1,
// then the mode-switching should be done outside this function,
// because the context-switches that are used here are not supported on BootMgr v1.
// Only works in BootLoader-mode or on unlocked bootloaders in Flash-mode!!
byte[] Request = new byte[0x04];
const string Header = GetGPTSignature;
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
byte[] Buffer = ExecuteRawMethod(Request);
if ((Buffer == null) || (Buffer.Length < 0x4408))
{
throw new InvalidOperationException("Unable to read GPT!");
}
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
if (Error > 0)
{
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
}
byte[] GPTBuffer = new byte[Buffer.Length - 0x208];
System.Buffer.BlockCopy(Buffer, 0x208, GPTBuffer, 0, 0x4200);
return new GPT(GPTBuffer); // NOKT message header and MBR are ignored
}
internal byte[] GetGptChunk(UInt32 Size) // TODO!
{
// This function is also used to generate a dummy chunk to flash for testing.
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
byte[] GPTChunk = new byte[Size];
byte[] Request = new byte[0x04];
const string Header = "NOKT";
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
byte[] Buffer = ExecuteRawMethod(Request);
if ((Buffer == null) || (Buffer.Length < 0x4408))
{
throw new InvalidOperationException("Unable to read GPT!");
}
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
if (Error > 0)
{
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
}
System.Buffer.BlockCopy(Buffer, 8, GPTChunk, 0, 0x4400);
return GPTChunk;
}
internal void ProvisionSecureBootKeys(SecureBootKeyType KeyType) // Only for Flashmode, not BootManager mode.
{
byte[] Request = new byte[8];
ByteOperations.WriteAsciiString(Request, 0, UEFIKeysProvisionSignature);
Request[6] = 0; // Options
Request[7] = (byte)KeyType;
byte[] Response = ExecuteRawMethod(Request);
UInt32 Status = ByteOperations.ReadUInt32(Response, 6);
if (Status != 0)
{
ThrowFlashError((int)Status);
}
}
private void ThrowFlashError(int ErrorCode)
{
string SubMessage = ErrorCode switch
{
0x0008 => "Unsupported protocol / Invalid options",
0x000F => "Invalid sub block count",
0x0010 => "Invalid sub block length",
0x0012 => "Authentication required",
0x000E => "Invalid sub block type",
0x0013 => "Failed async message",
0x1000 => "Invalid header type",
0x1001 => "FFU header contain unknown extra data",
0x0001 => "Couldn't allocate memory",
0x1106 => "Security header validation failed",
0x1105 => "Invalid hash table size",
0x1104 => "Invalid catalog size",
0x1103 => "Invalid chunk size",
0x1102 => "Unsupported algorithm",
0x1101 => "Invalid struct size",
0x1100 => "Invalid signature",
0x1202 => "Invalid struct size",
0x1203 => "Unsupported algorithm",
0x1204 => "Invalid chunk size",
0x1005 => "Data not aligned correctly",
0x0009 => "Locate protocol failed",
0x1003 => "Hash mismatch",
0x1006 => "Couldn't find hash from security header for index",
0x1004 => "Security header import missing / All FFU headers have not been imported",
0x1304 => "Invalid platform ID",
0x1307 => "Invalid write descriptor info",
0x1306 => "Invalid write descriptor info",
0x1305 => "Invalid block size",
0x1303 => "Unsupported FFU version",
0x1302 => "Unsupported struct version",
0x1301 => "Invalid update type",
0x100B => "Too much payload data, all data has already been written",
0x1008 => "Internal error",
0x1007 => "Payload data does not contain all data",
0x0004 => "Flash write failed",
0x000D => "Flash verify failed",
0x0002 => "Flash read failed",
_ => "Unknown error",
};
WPinternalsException Ex = new("Flash failed!");
Ex.SubMessage = "Error 0x" + ErrorCode.ToString("X4") + ": " + SubMessage;
throw Ex;
}
public void Shutdown()
{
byte[] Request = new byte[4];
const string Header = ShutdownSignature;
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
ExecuteRawMethod(Request);
}
internal void ResetPhone()
{
LogFile.Log("Rebooting phone", LogType.FileAndConsole);
try
{
byte[] Request = new byte[4];
ByteOperations.WriteAsciiString(Request, 0, RebootSignature);
ExecuteRawVoidMethod(Request);
}
catch
{
LogFile.Log("Sending reset-request failed", LogType.FileOnly);
LogFile.Log("Assuming automatic reset already in progress", LogType.FileOnly);
}
}
internal void ResetPhoneToFlashMode()
{
// This only works when the phone is in BootMgr mode. If it is already in FlashApp, it will not reboot. It only makes the phone unresponsive.
LogFile.Log("Rebooting phone to Flash mode...");
byte[] Request = new byte[4];
ByteOperations.WriteAsciiString(Request, 0, RebootToFlashAppSignature);
ExecuteRawVoidMethod(Request);
}
internal void SwitchToPhoneInfoAppContextLegacy()
{
byte[] Request = new byte[4];
ByteOperations.WriteAsciiString(Request, 0, RebootToPhoneInfoAppSignature);
ExecuteRawVoidMethod(Request);
}
internal void RebootToFlashApp()
{
byte[] Request = new byte[4];
ByteOperations.WriteAsciiString(Request, 0, "NOKS"); // This will let the phone charge
ExecuteRawVoidMethod(Request); // On phone with bootloader Spec A this triggers a reboot, so DisableRebootTimeOut() cannot be called immediately.
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,248 @@
// 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;
namespace WPinternals
{
internal class LumiaPhoneInfoAppModel : NokiaFlashModel
{
private readonly PhoneInfo Info = new();
//
// Not valid commands
//
/* NOK */
private const string Signature = "NOK";
/* NOKX */
private const string ExtendedMessageSignature = $"{Signature}X";
/* NOKXP */
private const string PhoneInfoAppExtendedMessageSignature = $"{ExtendedMessageSignature}P";
//
// Normal commands
//
/* NOKA */
private const string ContinueBootSignature = $"{Signature}A";
/* NOKD */
private const string DisableTimeoutsSignature = $"{Signature}D";
/* NOKH */
private const string GetPhoneInfoSignature = $"{Signature}H";
/* NOKI */
private const string HelloSignature = $"{Signature}I";
/* NOKV */
private const string InfoQuerySignature = $"{Signature}V";
//
// Phone Info App extended commands
//
/* NOKXPH */
private const string GetVariableSignature = $"{PhoneInfoAppExtendedMessageSignature}H";
public LumiaPhoneInfoAppModel(string DevicePath) : base(DevicePath)
{
}
internal void ContinueBoot()
{
LogFile.Log("Continue boot...");
byte[] Request = new byte[4];
ByteOperations.WriteAsciiString(Request, 0, ContinueBootSignature);
ExecuteRawVoidMethod(Request);
}
internal string GetPhoneInfo()
{
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
// NOKV = Info Query
if (Info.FlashAppProtocolVersionMajor >= 2)
{
return null;
}
byte[] Request = new byte[4];
ByteOperations.WriteAsciiString(Request, 0, GetPhoneInfoSignature);
byte[] Response = ExecuteRawMethod(Request);
if ((Response == null) || (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU"))
{
throw new NotSupportedException();
}
UInt16 Length = BigEndian.ToUInt16(Response, 0x04);
string PhoneInfoData = ByteOperations.ReadAsciiString(Response, 0x8, Length);
return PhoneInfoData;
}
internal PhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
{
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
// NOKV = Info Query
bool PhoneInfoLogged = Info.State != PhoneInfoState.Empty;
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;
}
if (ExtendedInfo && (Result.State == PhoneInfoState.Basic))
{
try
{
Result.Type = ReadPhoneInfoVariable("TYPE");
Result.ProductCode = ReadPhoneInfoVariable("CTR");
Result.Imei = ReadPhoneInfoVariable("IMEI");
}
catch (Exception ex)
{
LogFile.LogException(ex, LogType.FileOnly);
}
Result.State = PhoneInfoState.Extended;
}
Result.IsBootloaderSecure = !(Info.Authenticated || Info.RdcPresent || !Info.SecureFfuEnabled);
if (!PhoneInfoLogged)
{
Result.Log(LogType.FileOnly);
}
return Result;
}
internal string ReadPhoneInfoVariable(string VariableName)
{
// This function assumes the phone is in Phone Info App context
byte[] Request = new byte[16];
ByteOperations.WriteAsciiString(Request, 0, GetVariableSignature + VariableName + "\0"); // BTR or CTR, CTR is public ProductCode
byte[] Response = ExecuteRawMethod(Request);
UInt16 Length = BigEndian.ToUInt16(Response, 6);
return ByteOperations.ReadAsciiString(Response, 8, Length).Trim([' ', '\0']);
}
internal string ReadProductCode()
{
string Result = ReadPhoneInfoVariable("CTR");
SwitchToFlashAppContext();
return Result;
}
}
}
File diff suppressed because it is too large Load Diff
+5
View File
@@ -176,6 +176,11 @@ namespace WPinternals
return null; return null;
} }
if (Token.Value.ValueKind == JsonValueKind.String)
{
return Token.Value.GetString().Equals("true", StringComparison.InvariantCultureIgnoreCase);
}
return Token.Value.GetBoolean(); return Token.Value.GetBoolean();
} }
+134
View File
@@ -0,0 +1,134 @@
// 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);
}
}
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
namespace WPinternals
{
internal enum PhoneInfoState
{
Empty,
Basic,
Extended
};
}
@@ -0,0 +1,34 @@
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
namespace WPinternals
{
internal class UefiSecurityStatusResponse
{
public byte IsTestDevice;
public bool PlatformSecureBootStatus;
public bool SecureFfuEfuseStatus;
public bool DebugStatus;
public bool RdcStatus;
public bool AuthenticationStatus;
public bool UefiSecureBootStatus;
public bool CryptoHardwareKey;
}
}
+1 -1
View File
@@ -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 = ((NokiaFlashModel)Notifier.CurrentModel).ReadPhoneInfo(); PhoneInfo 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)
+1 -1
View File
@@ -469,7 +469,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
{ {
NokiaFlashModel LumiaFlashModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel LumiaFlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
PhoneInfo Info = LumiaFlashModel.ReadPhoneInfo(); PhoneInfo Info = LumiaFlashModel.ReadPhoneInfo();
ProductType = Info.Type; ProductType = Info.Type;
OperatorCode = ""; OperatorCode = "";
@@ -73,7 +73,7 @@ namespace WPinternals
await SwitchModeViewModel.SwitchToWithProgress(PhoneNotifier, PhoneInterfaces.Lumia_Flash, await SwitchModeViewModel.SwitchToWithProgress(PhoneNotifier, PhoneInterfaces.Lumia_Flash,
(msg, sub) => (msg, sub) =>
ActivateSubContext(new BusyViewModel(msg, sub))); ActivateSubContext(new BusyViewModel(msg, sub)));
if (((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: false).FlashAppProtocolVersionMajor < 2) if (((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: false).FlashAppProtocolVersionMajor < 2)
{ {
FlashPartitionsTask(EFIESPPath, MainOSPath, DataPath); FlashPartitionsTask(EFIESPPath, MainOSPath, DataPath);
} }
@@ -96,7 +96,7 @@ namespace WPinternals
ActivateSubContext(new BusyViewModel("Initializing flash...")); ActivateSubContext(new BusyViewModel("Initializing flash..."));
NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel; LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
GPT GPT = Phone.ReadGPT(); GPT GPT = Phone.ReadGPT();
@@ -268,7 +268,7 @@ namespace WPinternals
await SwitchModeViewModel.SwitchToWithProgress(PhoneNotifier, PhoneInterfaces.Lumia_Flash, await SwitchModeViewModel.SwitchToWithProgress(PhoneNotifier, PhoneInterfaces.Lumia_Flash,
(msg, sub) => (msg, sub) =>
ActivateSubContext(new BusyViewModel(msg, sub))); ActivateSubContext(new BusyViewModel(msg, sub)));
if (((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: false).FlashAppProtocolVersionMajor < 2) if (((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: false).FlashAppProtocolVersionMajor < 2)
{ {
FlashArchiveTask(ArchivePath); FlashArchiveTask(ArchivePath);
} }
@@ -289,7 +289,7 @@ namespace WPinternals
{ {
ActivateSubContext(new BusyViewModel("Initializing flash...")); ActivateSubContext(new BusyViewModel("Initializing flash..."));
NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel; LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
ulong TotalSizeSectors = 0; ulong TotalSizeSectors = 0;
int PartitionCount = 0; int PartitionCount = 0;
@@ -505,7 +505,7 @@ namespace WPinternals
{ {
bool Result = true; bool Result = true;
NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel; LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
PhoneInfo Info = Phone.ReadPhoneInfo(false); PhoneInfo Info = Phone.ReadPhoneInfo(false);
#region Remove bootloader changes #region Remove bootloader changes
@@ -519,7 +519,7 @@ namespace WPinternals
if (Info.FlashAppProtocolVersionMajor >= 2) if (Info.FlashAppProtocolVersionMajor >= 2)
{ {
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(Phone, 0x20000); // TODO: Get proper profile FFU and get ChunkSizeInBytes byte[] GPTChunk = Phone.GetGptChunk(0x20000); // TODO: Get proper profile FFU and get ChunkSizeInBytes
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
FlashPart Part; FlashPart Part;
List<FlashPart> FlashParts = new(); List<FlashPart> FlashParts = new();
@@ -598,14 +598,14 @@ namespace WPinternals
if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext(); ((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
} }
} }
} }
#endregion #endregion
Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel; Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
ActivateSubContext(new BusyViewModel("Initializing flash...")); ActivateSubContext(new BusyViewModel("Initializing flash..."));
@@ -664,12 +664,13 @@ namespace WPinternals
internal void FlashMMOSTask(string MMOSPath) internal void FlashMMOSTask(string MMOSPath)
{ {
NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;
if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
Phone.SwitchToFlashAppContext(); ((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
} }
LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
new Thread(() => new Thread(() =>
{ {
bool Result = true; bool Result = true;
+5 -4
View File
@@ -66,18 +66,19 @@ namespace WPinternals
switch (CurrentInterface) switch (CurrentInterface)
{ {
case null: case null:
case PhoneInterfaces.Lumia_Bootloader:
ActivateSubContext(null); ActivateSubContext(null);
//ActivateSubContext(new NokiaBootloaderViewModel((NokiaFlashModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted)); break;
case PhoneInterfaces.Lumia_Bootloader:
ActivateSubContext(new NokiaBootloaderViewModel((LumiaBootManagerAppModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted));
break; break;
case PhoneInterfaces.Lumia_PhoneInfo: case PhoneInterfaces.Lumia_PhoneInfo:
ActivateSubContext(new NokiaPhoneInfoViewModel((NokiaFlashModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted)); ActivateSubContext(new NokiaPhoneInfoViewModel((LumiaPhoneInfoAppModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted));
break; break;
case PhoneInterfaces.Lumia_Normal: case PhoneInterfaces.Lumia_Normal:
ActivateSubContext(new NokiaNormalViewModel((NokiaPhoneModel)CurrentModel, ModeSwitchRequestCallback)); ActivateSubContext(new NokiaNormalViewModel((NokiaPhoneModel)CurrentModel, ModeSwitchRequestCallback));
break; break;
case PhoneInterfaces.Lumia_Flash: case PhoneInterfaces.Lumia_Flash:
ActivateSubContext(new NokiaFlashViewModel((NokiaFlashModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted)); ActivateSubContext(new NokiaFlashViewModel((LumiaFlashAppModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted));
break; break;
case PhoneInterfaces.Lumia_Label: case PhoneInterfaces.Lumia_Label:
ActivateSubContext(new NokiaLabelViewModel((NokiaPhoneModel)CurrentModel, ModeSwitchRequestCallback)); ActivateSubContext(new NokiaLabelViewModel((NokiaPhoneModel)CurrentModel, ModeSwitchRequestCallback));
+3 -4
View File
@@ -87,17 +87,16 @@ namespace WPinternals
ActivateSubContext(null); ActivateSubContext(null);
break; break;
case PhoneInterfaces.Lumia_Bootloader: case PhoneInterfaces.Lumia_Bootloader:
ActivateSubContext(null); ActivateSubContext(new NokiaModeBootloaderViewModel((LumiaBootManagerAppModel)CurrentModel, OnModeSwitchRequested));
//ActivateSubContext(new NokiaModeBootloaderViewModel((NokiaFlashModel)CurrentModel, OnModeSwitchRequested));
break; break;
case PhoneInterfaces.Lumia_PhoneInfo: case PhoneInterfaces.Lumia_PhoneInfo:
ActivateSubContext(new NokiaModePhoneInfoViewModel((NokiaFlashModel)CurrentModel, OnModeSwitchRequested)); ActivateSubContext(new NokiaModePhoneInfoViewModel((LumiaPhoneInfoAppModel)CurrentModel, OnModeSwitchRequested));
break; break;
case PhoneInterfaces.Lumia_Normal: case PhoneInterfaces.Lumia_Normal:
ActivateSubContext(new NokiaModeNormalViewModel((NokiaPhoneModel)CurrentModel, OnModeSwitchRequested)); ActivateSubContext(new NokiaModeNormalViewModel((NokiaPhoneModel)CurrentModel, OnModeSwitchRequested));
break; break;
case PhoneInterfaces.Lumia_Flash: case PhoneInterfaces.Lumia_Flash:
ActivateSubContext(new NokiaModeFlashViewModel((NokiaFlashModel)CurrentModel, OnModeSwitchRequested)); ActivateSubContext(new NokiaModeFlashViewModel((LumiaFlashAppModel)CurrentModel, OnModeSwitchRequested));
break; break;
case PhoneInterfaces.Lumia_Label: case PhoneInterfaces.Lumia_Label:
ActivateSubContext(new NokiaModeLabelViewModel((NokiaPhoneModel)CurrentModel, OnModeSwitchRequested)); ActivateSubContext(new NokiaModeLabelViewModel((NokiaPhoneModel)CurrentModel, OnModeSwitchRequested));
@@ -133,11 +133,11 @@ namespace WPinternals
{ {
// Some phones, like Lumia 928 verizon, do not support the Terminal interface! // Some phones, like Lumia 928 verizon, do not support the Terminal interface!
// To read the RootKeyHash we use ReadParam("RRKH"), instead of GetTerminalResponse().RootKeyHash. // To read the RootKeyHash we use ReadParam("RRKH"), instead of GetTerminalResponse().RootKeyHash.
RootKeyHash = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadParam("RRKH"); RootKeyHash = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadParam("RRKH");
TestPos = 1; TestPos = 1;
UefiSecurityStatusResponse SecurityStatus = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadSecurityStatus(); UefiSecurityStatusResponse SecurityStatus = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadSecurityStatus();
if (SecurityStatus != null) if (SecurityStatus != null)
{ {
IsBootLoaderUnlocked = SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus; IsBootLoaderUnlocked = SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus;
@@ -145,7 +145,7 @@ namespace WPinternals
TestPos = 2; TestPos = 2;
PhoneInfo Info = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(); PhoneInfo Info = ((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo();
if (SecurityStatus == null) if (SecurityStatus == null)
{ {
IsBootLoaderUnlocked = !Info.IsBootloaderSecure; IsBootLoaderUnlocked = !Info.IsBootloaderSecure;
@@ -213,7 +213,7 @@ namespace WPinternals
bool AlreadyUnlocked = false; bool AlreadyUnlocked = false;
if (DoUnlock) if (DoUnlock)
{ {
NokiaFlashModel FlashModel = (NokiaFlashModel)PhoneNotifier.CurrentModel; LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
GPT GPT = FlashModel.ReadGPT(); GPT GPT = FlashModel.ReadGPT();
if ((GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null)) if ((GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null))
{ {
@@ -510,7 +510,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)
{ {
NokiaFlashModel Model = (NokiaFlashModel)PhoneNotifier.CurrentModel; LumiaFlashAppModel Model = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
PhoneInfo Info = Model.ReadPhoneInfo(); PhoneInfo Info = Model.ReadPhoneInfo();
if (EDEPath == null) if (EDEPath == null)
@@ -34,7 +34,7 @@ namespace WPinternals
// TODO: Add logging // TODO: Add logging
private static void PerformSoftBrick(PhoneNotifierViewModel Notifier, FFU FFU) private static void PerformSoftBrick(PhoneNotifierViewModel Notifier, FFU FFU)
{ {
NokiaFlashModel FlashModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
// Send FFU headers // Send FFU headers
UInt64 CombinedFFUHeaderSize = FFU.HeaderSize; UInt64 CombinedFFUHeaderSize = FFU.HeaderSize;
@@ -139,7 +139,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -149,7 +149,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -159,7 +159,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -205,7 +205,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -215,7 +215,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -225,7 +225,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -273,7 +273,7 @@ namespace WPinternals
try try
{ {
if (Notifier.CurrentModel is NokiaFlashModel) if (Notifier.CurrentModel is LumiaFlashAppModel)
{ {
await LumiaRelockUEFI(Notifier, FFUPath, true, SetWorkingStatus, UpdateWorkingStatus, null, (string Message, string SubMessage) => await LumiaRelockUEFI(Notifier, FFUPath, true, SetWorkingStatus, UpdateWorkingStatus, null, (string Message, string SubMessage) =>
{ {
@@ -320,9 +320,9 @@ namespace WPinternals
throw new Exception("Error: Parsing FFU-file failed."); throw new Exception("Error: Parsing FFU-file failed.");
} }
if (Notifier.CurrentModel is NokiaFlashModel) if (Notifier.CurrentModel is LumiaFlashAppModel)
{ {
FlashVersion FlashVersion = ((NokiaFlashModel)Notifier.CurrentModel).GetFlashVersion(); FlashVersion FlashVersion = ((LumiaFlashAppModel)Notifier.CurrentModel).GetFlashVersion();
if (FlashVersion == null) if (FlashVersion == null)
{ {
throw new Exception("Error: The version of the Flash Application on the phone could not be determined."); throw new Exception("Error: The version of the Flash Application on the phone could not be determined.");
@@ -333,7 +333,7 @@ namespace WPinternals
throw new Exception("Error: The version of the Flash Application on the phone is too old. Update your phone using Windows Updates or flash a newer ROM to your phone. Then try again."); throw new Exception("Error: The version of the Flash Application on the phone is too old. Update your phone using Windows Updates or flash a newer ROM to your phone. Then try again.");
} }
UefiSecurityStatusResponse SecurityStatus = ((NokiaFlashModel)Notifier.CurrentModel).ReadSecurityStatus(); UefiSecurityStatusResponse SecurityStatus = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadSecurityStatus();
IsBootLoaderUnlocked = SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus; IsBootLoaderUnlocked = SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus;
} }
@@ -350,9 +350,9 @@ namespace WPinternals
#endif #endif
GPT NewGPT = null; GPT NewGPT = null;
if (Notifier.CurrentModel is NokiaFlashModel) if (Notifier.CurrentModel is LumiaFlashAppModel)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ResetPhone(); ((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{ {
@@ -364,7 +364,7 @@ namespace WPinternals
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode."); throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
} }
NewGPT = ((NokiaFlashModel)Notifier.CurrentModel).ReadGPT(); NewGPT = ((LumiaBootManagerAppModel)Notifier.CurrentModel).ReadGPT();
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
@@ -448,7 +448,7 @@ namespace WPinternals
} }
else if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash) else if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
{ {
RootKeyHash = ((NokiaFlashModel)Notifier.CurrentModel).ReadParam("RRKH"); RootKeyHash = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadParam("RRKH");
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash) if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
@@ -573,7 +573,7 @@ namespace WPinternals
if (IsBootLoaderUnlocked) if (IsBootLoaderUnlocked)
// Flash phone in Flash app // Flash phone in Flash app
{ {
NokiaFlashModel CurrentModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel CurrentModel = (LumiaFlashAppModel)Notifier.CurrentModel;
LogFile.Log("Start flashing in Custom Flash mode"); LogFile.Log("Start flashing in Custom Flash mode");
UInt64 TotalSectorCount = (UInt64)0x21 + 1 + UInt64 TotalSectorCount = (UInt64)0x21 + 1 +
@@ -732,7 +732,7 @@ namespace WPinternals
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode."); throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
} }
NokiaFlashModel FlashModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash && FlashModel.ReadParam("FS")[3] > 0) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash && FlashModel.ReadParam("FS")[3] > 0)
{ {
ExitSuccess("Bootloader is restored", "NOTE: You need to flash a stock ROM because you recovered a phone from a bootloader unlock failure."); ExitSuccess("Bootloader is restored", "NOTE: You need to flash a stock ROM because you recovered a phone from a bootloader unlock failure.");
@@ -743,7 +743,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -753,7 +753,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -763,7 +763,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -843,9 +843,9 @@ namespace WPinternals
throw new Exception("Error: Parsing FFU-file failed."); throw new Exception("Error: Parsing FFU-file failed.");
} }
if (Notifier.CurrentModel is NokiaFlashModel) if (Notifier.CurrentModel is LumiaFlashAppModel)
{ {
FlashVersion FlashVersion = ((NokiaFlashModel)Notifier.CurrentModel).GetFlashVersion(); FlashVersion FlashVersion = ((LumiaFlashAppModel)Notifier.CurrentModel).GetFlashVersion();
if (FlashVersion == null) if (FlashVersion == null)
{ {
throw new Exception("Error: The version of the Flash Application on the phone could not be determined."); throw new Exception("Error: The version of the Flash Application on the phone could not be determined.");
@@ -856,7 +856,7 @@ namespace WPinternals
throw new Exception("Error: The version of the Flash Application on the phone is too old. Update your phone using Windows Updates or flash a newer ROM to your phone. Then try again."); throw new Exception("Error: The version of the Flash Application on the phone is too old. Update your phone using Windows Updates or flash a newer ROM to your phone. Then try again.");
} }
UefiSecurityStatusResponse SecurityStatus = ((NokiaFlashModel)Notifier.CurrentModel).ReadSecurityStatus(); UefiSecurityStatusResponse SecurityStatus = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadSecurityStatus();
IsBootLoaderUnlocked = SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus; IsBootLoaderUnlocked = SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus;
} }
@@ -904,9 +904,9 @@ namespace WPinternals
#endif #endif
GPT NewGPT = null; GPT NewGPT = null;
if (Notifier.CurrentModel is NokiaFlashModel) if (Notifier.CurrentModel is LumiaFlashAppModel)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ResetPhone(); ((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{ {
@@ -918,7 +918,7 @@ namespace WPinternals
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode."); throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
} }
NewGPT = ((NokiaFlashModel)Notifier.CurrentModel).ReadGPT(); NewGPT = ((LumiaBootManagerAppModel)Notifier.CurrentModel).ReadGPT();
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
@@ -1013,7 +1013,7 @@ namespace WPinternals
} }
else if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash) else if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
{ {
RootKeyHash = ((NokiaFlashModel)Notifier.CurrentModel).ReadParam("RRKH"); RootKeyHash = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadParam("RRKH");
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash) if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
@@ -1252,7 +1252,7 @@ namespace WPinternals
if (IsBootLoaderUnlocked) if (IsBootLoaderUnlocked)
// Flash phone in Flash app // Flash phone in Flash app
{ {
NokiaFlashModel CurrentModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel CurrentModel = (LumiaFlashAppModel)Notifier.CurrentModel;
LogFile.Log("Start flashing in Custom Flash mode"); LogFile.Log("Start flashing in Custom Flash mode");
UInt64 TotalSectorCount = (UInt64)0x21 + 1 + UInt64 TotalSectorCount = (UInt64)0x21 + 1 +
@@ -1423,7 +1423,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -1433,7 +1433,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -1443,7 +1443,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ContinueBoot(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).ContinueBoot();
} }
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Normal)
@@ -1467,54 +1467,6 @@ namespace WPinternals
} }
} }
internal static byte[] GetGptChunk(NokiaFlashModel FlashModel, UInt32 Size)
{
// This function is also used to generate a dummy chunk to flash for testing.
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
byte[] GPTChunk = new byte[Size];
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
FlashAppType OriginalAppType = Info.App;
bool Switch = (Info.App != FlashAppType.BootManager) && Info.IsBootloaderSecure;
if (Switch)
{
FlashModel.SwitchToBootManagerContext();
}
byte[] Request = new byte[0x04];
const string Header = "NOKT";
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
byte[] Buffer = FlashModel.ExecuteRawMethod(Request);
if ((Buffer == null) || (Buffer.Length < 0x4408))
{
throw new InvalidOperationException("Unable to read GPT!");
}
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
if (Error > 0)
{
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
}
System.Buffer.BlockCopy(Buffer, 8, GPTChunk, 0, 0x4400);
if (Switch)
{
if (OriginalAppType == FlashAppType.FlashApp)
{
FlashModel.SwitchToFlashAppContext();
}
else
{
FlashModel.SwitchToPhoneInfoAppContext();
}
}
return GPTChunk;
}
// Magic! // Magic!
// UEFI Secure Boot Hack for Spec A and Spec B devices // UEFI Secure Boot Hack for Spec A and Spec B devices
// //
@@ -1547,7 +1499,7 @@ namespace WPinternals
{ {
GPT GPT = null; GPT GPT = null;
Partition Target = null; Partition Target = null;
NokiaFlashModel FlashModel = null; LumiaFlashAppModel FlashModel = null;
LogFile.Log("Command: Relock phone", LogType.FileAndConsole); LogFile.Log("Command: Relock phone", LogType.FileAndConsole);
@@ -1558,13 +1510,13 @@ namespace WPinternals
byte[] EFIESPBackup = null; byte[] EFIESPBackup = null;
PhoneInfo Info = ((NokiaFlashModel)Notifier.CurrentModel).ReadPhoneInfo(); PhoneInfo Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
bool IsSpecB = Info.FlashAppProtocolVersionMajor >= 2; bool IsSpecB = Info.FlashAppProtocolVersionMajor >= 2;
bool UndoEFIESPPadding = false; bool UndoEFIESPPadding = false;
if (!IsSpecB) if (!IsSpecB)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ResetPhone(); ((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{ {
@@ -1577,7 +1529,7 @@ namespace WPinternals
} }
} }
byte[] GPTChunk = GetGptChunk((NokiaFlashModel)Notifier.CurrentModel, 0x20000); byte[] GPTChunk = ((LumiaBootManagerAppModel)Notifier.CurrentModel).GetGptChunk(0x20000);
GPT = new GPT(GPTChunk); GPT = new GPT(GPTChunk);
bool GPTChanged = false; bool GPTChanged = false;
Partition IsUnlockedPartitionSBL3 = GPT.GetPartition("IS_UNLOCKED_SBL3"); Partition IsUnlockedPartitionSBL3 = GPT.GetPartition("IS_UNLOCKED_SBL3");
@@ -1719,7 +1671,7 @@ namespace WPinternals
SetWorkingStatus("Flashing...", "The phone may reboot a couple of times. Just wait for it.", null, Status: WPinternalsStatus.Initializing); SetWorkingStatus("Flashing...", "The phone may reboot a couple of times. Just wait for it.", null, Status: WPinternalsStatus.Initializing);
((NokiaFlashModel)Notifier.CurrentModel).SwitchToFlashAppContext(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
List<FlashPart> FlashParts = new(); List<FlashPart> FlashParts = new();
@@ -1730,7 +1682,7 @@ namespace WPinternals
FlashPart Part; FlashPart Part;
FlashModel = (NokiaFlashModel)Notifier.CurrentModel; FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
// Remove IS_UNLOCKED flag in GPT // Remove IS_UNLOCKED flag in GPT
Partition IsUnlockedPartition = GPT.GetPartition("IS_UNLOCKED"); Partition IsUnlockedPartition = GPT.GetPartition("IS_UNLOCKED");
@@ -1788,7 +1740,7 @@ namespace WPinternals
// 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.
bool NvCleared = false; bool NvCleared = false;
Info = ((NokiaFlashModel)Notifier.CurrentModel).ReadPhoneInfo(); Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
if ((NvBackupPartition == null) && !Info.UefiSecureBootEnabled) if ((NvBackupPartition == null) && !Info.UefiSecureBootEnabled)
{ {
// ClearNV // ClearNV
@@ -1857,7 +1809,7 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
((NokiaFlashModel)Notifier.CurrentModel).SwitchToFlashAppContext(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
} }
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
@@ -1886,7 +1838,7 @@ namespace WPinternals
internal static async Task LumiaUnlockUEFI(PhoneNotifierViewModel Notifier, string ProfileFFUPath, string EDEPath, string SupportedFFUPath, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, bool ExperimentalSpecBEFIESPUnlock = false, bool ExperimentalSpecAEFIESPUnlock = true, bool ReUnlockDevice = false) internal static async Task LumiaUnlockUEFI(PhoneNotifierViewModel Notifier, string ProfileFFUPath, string EDEPath, string SupportedFFUPath, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, bool ExperimentalSpecBEFIESPUnlock = false, bool ExperimentalSpecAEFIESPUnlock = true, bool ReUnlockDevice = false)
{ {
LogFile.BeginAction("UnlockBootloader"); LogFile.BeginAction("UnlockBootloader");
NokiaFlashModel FlashModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
if (SetWorkingStatus == null) if (SetWorkingStatus == null)
{ {
@@ -1957,7 +1909,7 @@ namespace WPinternals
LumiaPatchEFIESP(SupportedFFU, UnlockedEFIESP, IsSpecB); LumiaPatchEFIESP(SupportedFFU, UnlockedEFIESP, IsSpecB);
byte[] GPTChunk = GetGptChunk(FlashModel, (UInt32)ProfileFFU.ChunkSize); byte[] GPTChunk = FlashModel.GetGptChunk((UInt32)ProfileFFU.ChunkSize);
byte[] GPTChunkBackup = new byte[GPTChunk.Length]; byte[] GPTChunkBackup = new byte[GPTChunk.Length];
Buffer.BlockCopy(GPTChunk, 0, GPTChunkBackup, 0, GPTChunk.Length); Buffer.BlockCopy(GPTChunk, 0, GPTChunkBackup, 0, GPTChunk.Length);
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
@@ -2042,8 +1994,8 @@ namespace WPinternals
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{ {
FlashModel = (NokiaFlashModel)Notifier.CurrentModel; ((LumiaBootManagerAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
FlashModel.SwitchToFlashAppContext(); FlashModel = ((LumiaFlashAppModel)Notifier.CurrentModel);
} }
GPTChanged = false; GPTChanged = false;
@@ -2208,7 +2160,7 @@ namespace WPinternals
if (!IsSpecB && !SBL3Eng) if (!IsSpecB && !SBL3Eng)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ResetPhone(); ((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
LogFile.Log("Bootloader unlocked!", LogType.FileAndConsole); LogFile.Log("Bootloader unlocked!", LogType.FileAndConsole);
ExitSuccess("Bootloader unlocked successfully!", null); ExitSuccess("Bootloader unlocked successfully!", null);
@@ -2344,7 +2296,7 @@ namespace WPinternals
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{ {
throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode."); throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
} ((NokiaFlashModel)Notifier.CurrentModel).SwitchToFlashAppContext(); } ((LumiaBootManagerAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
UInt32 OriginalEfiespFirstSector; UInt32 OriginalEfiespFirstSector;
if (!ReUnlockDevice) if (!ReUnlockDevice)
@@ -2504,7 +2456,7 @@ namespace WPinternals
throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode."); throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
} }
} }
((NokiaFlashModel)Notifier.CurrentModel).SwitchToFlashAppContext(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
Parts = LumiaGenerateEFIESPFlashPayload(UnlockedEFIESP, GPT, ProfileFFU, IsSpecB); Parts = LumiaGenerateEFIESPFlashPayload(UnlockedEFIESP, GPT, ProfileFFU, IsSpecB);
@@ -2517,7 +2469,7 @@ namespace WPinternals
if (!IsSpecB) if (!IsSpecB)
{ {
((NokiaFlashModel)Notifier.CurrentModel).ResetPhone(); ((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
} }
} }
@@ -2637,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 = ((NokiaFlashModel)Notifier.CurrentModel).ReadPhoneInfo(); PhoneInfo Info = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo();
bool IsSpecA = Info.FlashAppProtocolVersionMajor < 2; bool IsSpecA = Info.FlashAppProtocolVersionMajor < 2;
if (IsSpecA) if (IsSpecA)
@@ -2654,7 +2606,7 @@ namespace WPinternals
{ {
SetWorkingStatus("Initializing flash...", null, 100, Status: WPinternalsStatus.Initializing); SetWorkingStatus("Initializing flash...", null, 100, Status: WPinternalsStatus.Initializing);
NokiaFlashModel FlashModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
UInt64 InputStreamLength = 0; UInt64 InputStreamLength = 0;
UInt64 totalwritten = 0; UInt64 totalwritten = 0;
@@ -57,7 +57,7 @@ namespace WPinternals
{ {
LogFile.Log("Find Flashing Profile", LogType.FileAndConsole); LogFile.Log("Find Flashing Profile", LogType.FileAndConsole);
NokiaFlashModel FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
PhoneInfo Info; PhoneInfo Info;
if (DoResetFirst) if (DoResetFirst)
@@ -125,14 +125,14 @@ namespace WPinternals
LogFile.Log("Command: Enable testsigning", LogType.FileAndConsole); LogFile.Log("Command: Enable testsigning", LogType.FileAndConsole);
PhoneNotifierViewModel Notifier = new(); PhoneNotifierViewModel Notifier = new();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
NokiaFlashModel FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
List<FlashPart> Parts = new(); List<FlashPart> Parts = new();
FlashPart Part; FlashPart Part;
// 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.
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(FlashModel, 0x20000); byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
bool GPTChanged = false; bool GPTChanged = false;
@@ -228,7 +228,7 @@ namespace WPinternals
return ((MassStorage)Notifier.CurrentModel).Drive; return ((MassStorage)Notifier.CurrentModel).Drive;
} }
NokiaFlashModel FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
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
@@ -260,12 +260,12 @@ namespace WPinternals
LogFile.Log("Command: Clear NV", LogType.FileAndConsole); LogFile.Log("Command: Clear NV", LogType.FileAndConsole);
PhoneNotifierViewModel Notifier = new(); PhoneNotifierViewModel Notifier = new();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
NokiaFlashModel FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
List<FlashPart> Parts = new(); List<FlashPart> Parts = new();
// 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.
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(FlashModel, 0x20000); byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
bool GPTChanged = false; bool GPTChanged = false;
Partition BACKUP_BS_NV = GPT.GetPartition("BACKUP_BS_NV"); Partition BACKUP_BS_NV = GPT.GetPartition("BACKUP_BS_NV");
@@ -336,13 +336,13 @@ namespace WPinternals
PhoneNotifierViewModel Notifier = new(); PhoneNotifierViewModel Notifier = new();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
NokiaFlashModel FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
PhoneInfo Info = FlashModel.ReadPhoneInfo(); PhoneInfo 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.
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(FlashModel, 0x20000); byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
Partition TargetPartition = GPT.GetPartition(PartitionName); Partition TargetPartition = GPT.GetPartition(PartitionName);
@@ -445,7 +445,7 @@ namespace WPinternals
PhoneNotifierViewModel Notifier = new(); PhoneNotifierViewModel Notifier = new();
UIContext.Send(s => Notifier.Start(), null); UIContext.Send(s => Notifier.Start(), null);
NokiaFlashModel FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
PhoneInfo Info = FlashModel.ReadPhoneInfo(); PhoneInfo Info = FlashModel.ReadPhoneInfo();
@@ -483,10 +483,10 @@ 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)
{ {
NokiaFlashModel Model = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
PhoneInfo Info = Model.ReadPhoneInfo(); PhoneInfo Info = Model.ReadPhoneInfo();
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(Model, 131072u); byte[] GPTChunk = Model.GetGptChunk(131072u);
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
@@ -554,7 +554,7 @@ namespace WPinternals
ExitFailure = (m, s) => { }; ExitFailure = (m, s) => { };
} }
NokiaFlashModel Model = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
PhoneInfo Info = Model.ReadPhoneInfo(); PhoneInfo Info = Model.ReadPhoneInfo();
string Type = Info.Type; string Type = Info.Type;
@@ -673,7 +673,7 @@ namespace WPinternals
MaximumAttempts = (int)(((MaximumGapFill / FFU.ChunkSize) + 1) * 8); MaximumAttempts = (int)(((MaximumGapFill / FFU.ChunkSize) + 1) * 8);
} }
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(Model, (UInt32)FFU.ChunkSize); byte[] GPTChunk = Model.GetGptChunk((UInt32)FFU.ChunkSize);
// Start with a reset // Start with a reset
if (DoResetFirst) if (DoResetFirst)
@@ -818,23 +818,12 @@ namespace WPinternals
throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader or flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode."); throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader or flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
} }
Model = (NokiaFlashModel)Notifier.CurrentModel;
UpdateWorkingStatus("Initializing flash...", null, null); UpdateWorkingStatus("Initializing flash...", null, null);
} }
try ((LumiaBootManagerAppModel)Notifier.CurrentModel).ResetPhoneToFlashMode();
{ await Notifier.WaitForArrival();
// This will succeed on new models Model = (LumiaFlashAppModel)Notifier.CurrentModel;
Model.SwitchToFlashAppContext();
Model.DisableRebootTimeOut();
}
catch
{
// This will succeed on old models
Model.ResetPhoneToFlashMode();
await Notifier.WaitForArrival();
Model = (NokiaFlashModel)Notifier.CurrentModel;
}
// The payloads must be ordered by the number of locations // The payloads must be ordered by the number of locations
// //
@@ -1516,10 +1505,9 @@ namespace WPinternals
break; break;
} }
Model = (NokiaFlashModel)Notifier.CurrentModel;
// In case we are on an Engineering phone which isn't stuck in flashmode and booted to BootMgrApp // In case we are on an Engineering phone which isn't stuck in flashmode and booted to BootMgrApp
Model.SwitchToFlashAppContext(); ((LumiaBootManagerAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
Model = (LumiaFlashAppModel)Notifier.CurrentModel;
Model.DisableRebootTimeOut(); Model.DisableRebootTimeOut();
} }
@@ -1644,7 +1632,7 @@ namespace WPinternals
} }
// Do the actual reset, which will result in a crash while cleaning up memory // Do the actual reset, which will result in a crash while cleaning up memory
((NokiaFlashModel)Notifier.CurrentModel).ResetPhone(); ((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
LogFile.Log("Phone performs hard exit", LogType.FileAndConsole); LogFile.Log("Phone performs hard exit", LogType.FileAndConsole);
@@ -1782,7 +1770,7 @@ namespace WPinternals
else else
{ {
// If we didn't do a hard exit, we need to do a normal reboot // If we didn't do a hard exit, we need to do a normal reboot
((NokiaFlashModel)Notifier.CurrentModel).ResetPhone(); ((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
} }
if (Success) if (Success)
@@ -1964,11 +1952,11 @@ namespace WPinternals
{ {
LogFile.BeginAction("FlashCustomROM"); LogFile.BeginAction("FlashCustomROM");
NokiaFlashModel FlashModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
// 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.
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(FlashModel, 0x20000); byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
Partition Target; Partition Target;
@@ -2357,11 +2345,11 @@ namespace WPinternals
// Assumes phone is in flash mode // Assumes phone is in flash mode
internal async static Task LumiaV2FlashPartitions(PhoneNotifierViewModel Notifier, string EFIESPPath, string MainOSPath, string DataPath, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null) internal async static Task LumiaV2FlashPartitions(PhoneNotifierViewModel Notifier, string EFIESPPath, string MainOSPath, string DataPath, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null)
{ {
NokiaFlashModel FlashModel = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
// 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.
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(FlashModel, 0x20000); byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
Partition Target; Partition Target;
@@ -192,7 +192,7 @@ namespace WPinternals
try try
{ {
NokiaFlashModel Model = (NokiaFlashModel)Notifier.CurrentModel; LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
PhoneInfo Info = Model.ReadPhoneInfo(); PhoneInfo 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.
@@ -282,7 +282,7 @@ namespace WPinternals
store.WriteDescriptorLength += payload.GetStoreHeaderSize(); store.WriteDescriptorLength += payload.GetStoreHeaderSize();
} }
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(Model, 0x20000); byte[] GPTChunk = Model.GetGptChunk(0x20000);
GPT GPT = new(GPTChunk); GPT GPT = new(GPTChunk);
UInt64 PlatEnd = 0; UInt64 PlatEnd = 0;
if (GPT.Partitions.Any(x => x.Name == "PLAT")) if (GPT.Partitions.Any(x => x.Name == "PLAT"))
@@ -30,7 +30,7 @@ namespace WPinternals
internal class NokiaBootloaderViewModel : ContextViewModel internal class NokiaBootloaderViewModel : ContextViewModel
{ {
private readonly NokiaFlashModel CurrentModel; private readonly LumiaBootManagerAppModel CurrentModel;
private readonly Action<PhoneInterfaces> RequestModeSwitch; private readonly Action<PhoneInterfaces> RequestModeSwitch;
internal Action SwitchToGettingStarted; internal Action SwitchToGettingStarted;
private readonly object LockDeviceInfo = new(); private readonly object LockDeviceInfo = new();
@@ -38,7 +38,7 @@ namespace WPinternals
internal NokiaBootloaderViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted) internal NokiaBootloaderViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted)
: base() : base()
{ {
this.CurrentModel = (NokiaFlashModel)CurrentModel; this.CurrentModel = (LumiaBootManagerAppModel)CurrentModel;
this.RequestModeSwitch = RequestModeSwitch; this.RequestModeSwitch = RequestModeSwitch;
this.SwitchToGettingStarted = SwitchToGettingStarted; this.SwitchToGettingStarted = SwitchToGettingStarted;
} }
@@ -63,6 +63,9 @@ namespace WPinternals
case "Normal": case "Normal":
RequestModeSwitch(PhoneInterfaces.Lumia_Normal); RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
+20 -17
View File
@@ -30,7 +30,7 @@ namespace WPinternals
internal class NokiaFlashViewModel : ContextViewModel internal class NokiaFlashViewModel : ContextViewModel
{ {
private readonly NokiaFlashModel CurrentModel; private readonly LumiaFlashAppModel CurrentModel;
private readonly Action<PhoneInterfaces> RequestModeSwitch; private readonly Action<PhoneInterfaces> RequestModeSwitch;
internal Action SwitchToGettingStarted; internal Action SwitchToGettingStarted;
private readonly object LockDeviceInfo = new(); private readonly object LockDeviceInfo = new();
@@ -39,7 +39,7 @@ namespace WPinternals
internal NokiaFlashViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted) internal NokiaFlashViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted)
: base() : base()
{ {
this.CurrentModel = (NokiaFlashModel)CurrentModel; this.CurrentModel = (LumiaFlashAppModel)CurrentModel;
this.RequestModeSwitch = RequestModeSwitch; this.RequestModeSwitch = RequestModeSwitch;
this.SwitchToGettingStarted = SwitchToGettingStarted; this.SwitchToGettingStarted = SwitchToGettingStarted;
} }
@@ -95,21 +95,21 @@ namespace WPinternals
SecurityFlags = (UInt32)CurrentModel.ReadSecurityFlags(); SecurityFlags = (UInt32)CurrentModel.ReadSecurityFlags();
LogFile.Log("Security flags: 0x" + SecurityFlags.ToString("X8")); LogFile.Log("Security flags: 0x" + SecurityFlags.ToString("X8"));
FinalConfigDakStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Dak); FinalConfigDakStatus = CurrentModel.ReadFuseStatus(Fuse.Dak);
FinalConfigFastBootStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.FastBoot); FinalConfigFastBootStatus = CurrentModel.ReadFuseStatus(Fuse.FastBoot);
FinalConfigFfuVerifyStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.FfuVerify); FinalConfigFfuVerifyStatus = CurrentModel.ReadFuseStatus(Fuse.FfuVerify);
FinalConfigJtagStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Jtag); FinalConfigJtagStatus = CurrentModel.ReadFuseStatus(Fuse.Jtag);
FinalConfigOemIdStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.OemId); FinalConfigOemIdStatus = CurrentModel.ReadFuseStatus(Fuse.OemId);
FinalConfigProductionDoneStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.ProductionDone); FinalConfigProductionDoneStatus = CurrentModel.ReadFuseStatus(Fuse.ProductionDone);
FinalConfigPublicIdStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.PublicId); FinalConfigPublicIdStatus = CurrentModel.ReadFuseStatus(Fuse.PublicId);
FinalConfigRkhStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Rkh); FinalConfigRkhStatus = CurrentModel.ReadFuseStatus(Fuse.Rkh);
FinalConfigRpmWdogStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.RpmWdog); FinalConfigRpmWdogStatus = CurrentModel.ReadFuseStatus(Fuse.RpmWdog);
FinalConfigSecGenStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.SecGen); FinalConfigSecGenStatus = CurrentModel.ReadFuseStatus(Fuse.SecGen);
FinalConfigSecureBootStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.SecureBoot); FinalConfigSecureBootStatus = CurrentModel.ReadFuseStatus(Fuse.SecureBoot);
FinalConfigShkStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Shk); FinalConfigShkStatus = CurrentModel.ReadFuseStatus(Fuse.Shk);
FinalConfigSimlockStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Simlock); FinalConfigSimlockStatus = CurrentModel.ReadFuseStatus(Fuse.Simlock);
FinalConfigSpdmSecModeStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.SpdmSecMode); FinalConfigSpdmSecModeStatus = CurrentModel.ReadFuseStatus(Fuse.SpdmSecMode);
FinalConfigSsmStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Ssm); FinalConfigSsmStatus = CurrentModel.ReadFuseStatus(Fuse.Ssm);
} }
else else
{ {
@@ -748,6 +748,9 @@ namespace WPinternals
case "Normal": case "Normal":
RequestModeSwitch(PhoneInterfaces.Lumia_Normal); RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
@@ -292,6 +292,9 @@ namespace WPinternals
case "Flash": case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash); RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
@@ -25,7 +25,7 @@ namespace WPinternals
{ {
internal class NokiaModeBootloaderViewModel : ContextViewModel internal class NokiaModeBootloaderViewModel : ContextViewModel
{ {
private readonly NokiaFlashModel CurrentModel; private readonly LumiaBootManagerAppModel CurrentModel;
private readonly Action<PhoneInterfaces?> RequestModeSwitch; private readonly Action<PhoneInterfaces?> RequestModeSwitch;
private readonly object LockDeviceInfo = new(); private readonly object LockDeviceInfo = new();
private bool DeviceInfoLoaded = false; private bool DeviceInfoLoaded = false;
@@ -33,7 +33,7 @@ namespace WPinternals
internal NokiaModeBootloaderViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch) internal NokiaModeBootloaderViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
: base() : base()
{ {
this.CurrentModel = (NokiaFlashModel)CurrentModel; this.CurrentModel = (LumiaBootManagerAppModel)CurrentModel;
this.RequestModeSwitch = RequestModeSwitch; this.RequestModeSwitch = RequestModeSwitch;
} }
@@ -69,19 +69,7 @@ namespace WPinternals
{ {
PhoneInfo Info = CurrentModel.ReadPhoneInfo(); PhoneInfo Info = CurrentModel.ReadPhoneInfo();
if (Info.FlashAppProtocolVersionMajor < 2) EffectiveBootloaderSecurityStatus = Info.UefiSecureBootEnabled;
{
UefiSecurityStatusResponse SecurityStatus = CurrentModel.ReadSecurityStatus();
if (SecurityStatus != null)
{
EffectiveBootloaderSecurityStatus = SecurityStatus.SecureFfuEfuseStatus && !SecurityStatus.AuthenticationStatus && !SecurityStatus.RdcStatus;
}
}
else
{
EffectiveBootloaderSecurityStatus = Info.UefiSecureBootEnabled;
}
LogFile.Log("Effective Bootloader Security Status: " + EffectiveBootloaderSecurityStatus.ToString()); LogFile.Log("Effective Bootloader Security Status: " + EffectiveBootloaderSecurityStatus.ToString());
} }
@@ -101,6 +89,9 @@ namespace WPinternals
case "Normal": case "Normal":
RequestModeSwitch(PhoneInterfaces.Lumia_Normal); RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "Flash": case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash); RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break; break;
@@ -25,7 +25,7 @@ namespace WPinternals
{ {
internal class NokiaModeFlashViewModel : ContextViewModel internal class NokiaModeFlashViewModel : ContextViewModel
{ {
private readonly NokiaFlashModel CurrentModel; private readonly LumiaFlashAppModel CurrentModel;
private readonly Action<PhoneInterfaces?> RequestModeSwitch; private readonly Action<PhoneInterfaces?> RequestModeSwitch;
private readonly object LockDeviceInfo = new(); private readonly object LockDeviceInfo = new();
private bool DeviceInfoLoaded = false; private bool DeviceInfoLoaded = false;
@@ -33,7 +33,7 @@ namespace WPinternals
internal NokiaModeFlashViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch) internal NokiaModeFlashViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
: base() : base()
{ {
this.CurrentModel = (NokiaFlashModel)CurrentModel; this.CurrentModel = (LumiaFlashAppModel)CurrentModel;
this.RequestModeSwitch = RequestModeSwitch; this.RequestModeSwitch = RequestModeSwitch;
} }
@@ -103,6 +103,12 @@ namespace WPinternals
case "Flash": case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash); RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "BootMgr":
RequestModeSwitch(PhoneInterfaces.Lumia_Bootloader);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
@@ -41,6 +41,12 @@ namespace WPinternals
case "Normal": case "Normal":
RequestModeSwitch(PhoneInterfaces.Lumia_Normal); RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "BootMgr":
RequestModeSwitch(PhoneInterfaces.Lumia_Bootloader);
break;
case "Flash": case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash); RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break; break;
@@ -63,6 +63,12 @@ namespace WPinternals
case "Normal": case "Normal":
RequestModeSwitch(PhoneInterfaces.Lumia_Normal); RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "BootMgr":
RequestModeSwitch(PhoneInterfaces.Lumia_Bootloader);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
@@ -41,6 +41,12 @@ namespace WPinternals
case "Flash": case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash); RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "BootMgr":
RequestModeSwitch(PhoneInterfaces.Lumia_Bootloader);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
@@ -25,7 +25,7 @@ namespace WPinternals
{ {
internal class NokiaModePhoneInfoViewModel : ContextViewModel internal class NokiaModePhoneInfoViewModel : ContextViewModel
{ {
private readonly NokiaFlashModel CurrentModel; private readonly LumiaPhoneInfoAppModel CurrentModel;
private readonly Action<PhoneInterfaces?> RequestModeSwitch; private readonly Action<PhoneInterfaces?> RequestModeSwitch;
private readonly object LockDeviceInfo = new(); private readonly object LockDeviceInfo = new();
private bool DeviceInfoLoaded = false; private bool DeviceInfoLoaded = false;
@@ -33,7 +33,7 @@ namespace WPinternals
internal NokiaModePhoneInfoViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch) internal NokiaModePhoneInfoViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
: base() : base()
{ {
this.CurrentModel = (NokiaFlashModel)CurrentModel; this.CurrentModel = (LumiaPhoneInfoAppModel)CurrentModel;
this.RequestModeSwitch = RequestModeSwitch; this.RequestModeSwitch = RequestModeSwitch;
} }
@@ -69,19 +69,7 @@ namespace WPinternals
{ {
PhoneInfo Info = CurrentModel.ReadPhoneInfo(); PhoneInfo Info = CurrentModel.ReadPhoneInfo();
if (Info.FlashAppProtocolVersionMajor < 2) EffectivePhoneInfoSecurityStatus = Info.UefiSecureBootEnabled;
{
UefiSecurityStatusResponse SecurityStatus = CurrentModel.ReadSecurityStatus();
if (SecurityStatus != null)
{
EffectivePhoneInfoSecurityStatus = SecurityStatus.SecureFfuEfuseStatus && !SecurityStatus.AuthenticationStatus && !SecurityStatus.RdcStatus;
}
}
else
{
EffectivePhoneInfoSecurityStatus = Info.UefiSecureBootEnabled;
}
LogFile.Log("Effective PhoneInfo Security Status: " + EffectivePhoneInfoSecurityStatus.ToString()); LogFile.Log("Effective PhoneInfo Security Status: " + EffectivePhoneInfoSecurityStatus.ToString());
} }
@@ -104,6 +92,9 @@ namespace WPinternals
case "Flash": case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash); RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break; break;
case "BootMgr":
RequestModeSwitch(PhoneInterfaces.Lumia_Bootloader);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
@@ -384,6 +384,12 @@ namespace WPinternals
case "Flash": case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash); RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break; break;
case "PhoneInfo":
RequestModeSwitch(PhoneInterfaces.Lumia_PhoneInfo);
break;
case "BootMgr":
RequestModeSwitch(PhoneInterfaces.Lumia_Bootloader);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
@@ -32,7 +32,7 @@ namespace WPinternals
internal class NokiaPhoneInfoViewModel : ContextViewModel internal class NokiaPhoneInfoViewModel : ContextViewModel
{ {
private readonly NokiaFlashModel CurrentModel; private readonly LumiaPhoneInfoAppModel CurrentModel;
private readonly Action<PhoneInterfaces> RequestModeSwitch; private readonly Action<PhoneInterfaces> RequestModeSwitch;
internal Action SwitchToGettingStarted; internal Action SwitchToGettingStarted;
private readonly object LockDeviceInfo = new(); private readonly object LockDeviceInfo = new();
@@ -41,7 +41,7 @@ namespace WPinternals
internal NokiaPhoneInfoViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted) internal NokiaPhoneInfoViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted)
: base() : base()
{ {
this.CurrentModel = (NokiaFlashModel)CurrentModel; this.CurrentModel = (LumiaPhoneInfoAppModel)CurrentModel;
this.RequestModeSwitch = RequestModeSwitch; this.RequestModeSwitch = RequestModeSwitch;
this.SwitchToGettingStarted = SwitchToGettingStarted; this.SwitchToGettingStarted = SwitchToGettingStarted;
} }
@@ -192,6 +192,12 @@ namespace WPinternals
case "Normal": case "Normal":
RequestModeSwitch(PhoneInterfaces.Lumia_Normal); RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
break; break;
case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break;
case "BootMgr":
RequestModeSwitch(PhoneInterfaces.Lumia_Bootloader);
break;
case "Label": case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label); RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break; break;
@@ -237,13 +237,12 @@ namespace WPinternals
e.DevicePath.Contains("&PID_0A02", StringComparison.OrdinalIgnoreCase) || // VID_045E&PID_0A02 is for Lumia 950 e.DevicePath.Contains("&PID_0A02", StringComparison.OrdinalIgnoreCase) || // VID_045E&PID_0A02 is for Lumia 950
e.DevicePath.Contains("&PID_05EE", StringComparison.OrdinalIgnoreCase)) // VID_0421&PID_05EE is for early RX100 e.DevicePath.Contains("&PID_05EE", StringComparison.OrdinalIgnoreCase)) // VID_0421&PID_05EE is for early RX100
{ {
CurrentModel = new NokiaFlashModel(e.DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
FlashAppType type = FlashAppType.FlashApp; FlashAppType type = FlashAppType.FlashApp;
try try
{ {
type = ((NokiaFlashModel)CurrentModel).GetFlashAppType(); NokiaFlashModel tmpModel = new NokiaFlashModel(e.DevicePath);
type = tmpModel.GetFlashAppType();
tmpModel.Dispose();
LogFile.Log("Flash App Type: " + type.ToString(), LogType.FileOnly); LogFile.Log("Flash App Type: " + type.ToString(), LogType.FileOnly);
} }
catch catch
@@ -255,6 +254,9 @@ namespace WPinternals
{ {
case FlashAppType.BootManager: case FlashAppType.BootManager:
{ {
CurrentModel = new LumiaBootManagerAppModel(e.DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
CurrentInterface = PhoneInterfaces.Lumia_Bootloader; CurrentInterface = PhoneInterfaces.Lumia_Bootloader;
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly); LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly); LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
@@ -265,6 +267,9 @@ namespace WPinternals
} }
case FlashAppType.FlashApp: case FlashAppType.FlashApp:
{ {
CurrentModel = new LumiaFlashAppModel(e.DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
((NokiaFlashModel)CurrentModel).DisableRebootTimeOut(); ((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
CurrentInterface = PhoneInterfaces.Lumia_Flash; CurrentInterface = PhoneInterfaces.Lumia_Flash;
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly); LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
@@ -276,6 +281,9 @@ namespace WPinternals
} }
case FlashAppType.PhoneInfoApp: case FlashAppType.PhoneInfoApp:
{ {
CurrentModel = new LumiaPhoneInfoAppModel(e.DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
((NokiaFlashModel)CurrentModel).DisableRebootTimeOut(); ((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
CurrentInterface = PhoneInterfaces.Lumia_PhoneInfo; CurrentInterface = PhoneInterfaces.Lumia_PhoneInfo;
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly); LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
@@ -415,9 +423,80 @@ namespace WPinternals
} }
} }
private void InterfaceChanged(PhoneInterfaces NewInterface) private void InterfaceChanged(PhoneInterfaces NewInterface, string DevicePath)
{ {
CurrentInterface = NewInterface; LastInterface = CurrentInterface;
CurrentInterface = null;
if (CurrentModel != null)
{
CurrentModel.Dispose();
CurrentModel = null;
LogFile.Log("Lumia disconnected", LogType.FileAndConsole);
}
DeviceRemoved();
switch (NewInterface)
{
case PhoneInterfaces.Lumia_Bootloader:
{
CurrentModel = new LumiaBootManagerAppModel(DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
CurrentInterface = PhoneInterfaces.Lumia_Bootloader;
LogFile.Log("Found device on interface: " + LumiaFlashInterfaceGuid.ToString(), LogType.FileOnly);
LogFile.Log("Device path: " + DevicePath, LogType.FileOnly);
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
LogFile.Log("Mode: Bootloader", LogType.FileAndConsole);
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
break;
}
case PhoneInterfaces.Lumia_Flash:
{
CurrentModel = new LumiaFlashAppModel(DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
CurrentInterface = PhoneInterfaces.Lumia_Flash;
LogFile.Log("Found device on interface: " + LumiaFlashInterfaceGuid.ToString(), LogType.FileOnly);
LogFile.Log("Device path: " + DevicePath, LogType.FileOnly);
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
LogFile.Log("Mode: Flash", LogType.FileAndConsole);
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
break;
}
case PhoneInterfaces.Lumia_PhoneInfo:
{
CurrentModel = new LumiaPhoneInfoAppModel(DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
CurrentInterface = PhoneInterfaces.Lumia_PhoneInfo;
LogFile.Log("Found device on interface: " + LumiaFlashInterfaceGuid.ToString(), LogType.FileOnly);
LogFile.Log("Device path: " + DevicePath, LogType.FileOnly);
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
LogFile.Log("Mode: Bootloader (Phone Info)", LogType.FileAndConsole);
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
break;
}
default:
{
LogFile.Log("Flash App Type could not be determined, assuming FlashApp", LogType.FileOnly);
CurrentModel = new LumiaFlashAppModel(DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
CurrentInterface = PhoneInterfaces.Lumia_Flash;
LogFile.Log("Found device on interface: " + LumiaFlashInterfaceGuid.ToString(), LogType.FileOnly);
LogFile.Log("Device path: " + DevicePath, LogType.FileOnly);
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
LogFile.Log("Mode: Flash", LogType.FileAndConsole);
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
break;
}
}
} }
private void LumiaNotifier_Removal(object sender, USBEvent e) private void LumiaNotifier_Removal(object sender, USBEvent e)
+1 -1
View File
@@ -113,7 +113,7 @@ namespace WPinternals
Result = false; Result = false;
} }
NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel; LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
BusyViewModel Busy = new("Restoring...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext); BusyViewModel Busy = new("Restoring...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
ProgressUpdater Updater = Busy.ProgressUpdater; ProgressUpdater Updater = Busy.ProgressUpdater;
+462 -31
View File
@@ -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 = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(false); PhoneInfo Info = ((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(false);
if (Info.BootManagerProtocolVersionMajor >= 2) if (Info.BootManagerProtocolVersionMajor >= 2)
{ {
try try
@@ -95,7 +95,7 @@ namespace WPinternals
// It does not disconnect / reconnect anymore and the apptype is changed immediately // It does not disconnect / reconnect anymore and the apptype is changed immediately
// NOKS still doesnt return a status // NOKS still doesnt return a status
// BootMgr v1 uses normal NOKS and waits for arrival of FlashApp // BootMgr v1 uses normal NOKS and waits for arrival of FlashApp
((NokiaFlashModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext(); ((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
// But this was called as a real switch, so we will raise an arrival event. // But this was called as a real switch, so we will raise an arrival event.
PhoneNotifier.CurrentInterface = PhoneInterfaces.Lumia_Flash; PhoneNotifier.CurrentInterface = PhoneInterfaces.Lumia_Flash;
@@ -233,6 +233,12 @@ namespace WPinternals
{ {
IsSwitching = true; IsSwitching = true;
byte[] BootModeFlagCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x46, 0x57, 0x00, 0x55, 0x42, 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00]; // NOKFW UBF
byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52]; // NOKR
byte[] RebootCommandResult;
bool ModernFlashApp;
// Make switch and set message or navigate to error // Make switch and set message or navigate to error
switch (CurrentMode) switch (CurrentMode)
{ {
@@ -298,15 +304,11 @@ namespace WPinternals
} }
break; break;
case PhoneInterfaces.Lumia_Flash: case PhoneInterfaces.Lumia_Flash:
case PhoneInterfaces.Lumia_Bootloader:
byte[] BootModeFlagCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x46, 0x57, 0x00, 0x55, 0x42, 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00]; // NOKFW UBF
byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52]; // NOKR
byte[] RebootCommandResult;
IsSwitchingInterface = true; IsSwitchingInterface = true;
switch (TargetMode) switch (TargetMode)
{ {
case null: case null:
((NokiaFlashModel)CurrentModel).Shutdown(); ((LumiaFlashAppModel)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(() =>
@@ -316,13 +318,154 @@ namespace WPinternals
}).Start(); }).Start();
break; break;
case PhoneInterfaces.Lumia_Normal: case PhoneInterfaces.Lumia_Normal:
((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand); ((LumiaFlashAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived; PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
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:
((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand); ((LumiaFlashAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
break;
case PhoneInterfaces.Lumia_PhoneInfo:
ModernFlashApp = ((LumiaFlashAppModel)CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
if (ModernFlashApp)
{
((LumiaFlashAppModel)CurrentModel).SwitchToPhoneInfoAppContext();
}
else
{
((LumiaFlashAppModel)CurrentModel).SwitchToPhoneInfoAppContextLegacy();
}
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Phone Info mode...", null);
LogFile.Log("Rebooting phone to Phone Info mode", LogType.FileAndConsole);
break;
case PhoneInterfaces.Lumia_Label:
SwitchFromFlashToLabelMode();
break;
case PhoneInterfaces.Lumia_Flash: // attempt to boot from limited flash to full flash
byte[] RebootToFlashCommand = [0x4E, 0x4F, 0x4B, 0x53]; // NOKS
((LumiaFlashAppModel)CurrentModel).ExecuteRawVoidMethod(RebootToFlashCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
break;
case PhoneInterfaces.Lumia_MassStorage:
SwitchFromFlashToMassStorageMode();
break;
case PhoneInterfaces.Qualcomm_Download:
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
RebootCommandResult = ((LumiaFlashAppModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
{
IsSwitchingInterface = false;
ModeSwitchErrorWrapper("Failed to switch to Qualcomm Download mode");
}
else
{
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Qualcomm Download mode...", null);
LogFile.Log("Rebooting phone to Qualcomm Download mode", LogType.FileAndConsole);
}
break;
default:
return;
}
break;
case PhoneInterfaces.Lumia_PhoneInfo:
IsSwitchingInterface = true;
switch (TargetMode)
{
case PhoneInterfaces.Lumia_Normal:
((LumiaPhoneInfoAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
break;
case PhoneInterfaces.Lumia_Bootloader:
ModernFlashApp = ((LumiaPhoneInfoAppModel)CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
if (ModernFlashApp)
{
((LumiaPhoneInfoAppModel)CurrentModel).SwitchToBootManagerContext();
}
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
break;
case PhoneInterfaces.Lumia_PhoneInfo: // attempt to boot from limited phone info to full phone info
ModernFlashApp = ((LumiaPhoneInfoAppModel)CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
if (ModernFlashApp)
{
((LumiaPhoneInfoAppModel)CurrentModel).SwitchToPhoneInfoAppContext();
}
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Phone Info mode...", null);
LogFile.Log("Rebooting phone to Phone Info mode", LogType.FileAndConsole);
break;
case PhoneInterfaces.Lumia_Label:
SwitchFromPhoneInfoToLabelMode();
break;
case PhoneInterfaces.Lumia_Flash:
ModernFlashApp = ((LumiaPhoneInfoAppModel)CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
if (ModernFlashApp)
{
((LumiaPhoneInfoAppModel)CurrentModel).SwitchToFlashAppContext();
}
else
{
((LumiaPhoneInfoAppModel)CurrentModel).ContinueBoot();
}
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
break;
case PhoneInterfaces.Lumia_MassStorage:
SwitchFromPhoneInfoToMassStorageMode();
break;
case PhoneInterfaces.Qualcomm_Download:
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
RebootCommandResult = ((LumiaPhoneInfoAppModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
{
IsSwitchingInterface = false;
ModeSwitchErrorWrapper("Failed to switch to Qualcomm Download mode");
}
else
{
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Qualcomm Download mode...", null);
LogFile.Log("Rebooting phone to Qualcomm Download mode", LogType.FileAndConsole);
}
break;
default:
return;
}
break;
case PhoneInterfaces.Lumia_Bootloader:
IsSwitchingInterface = true;
switch (TargetMode)
{
case null:
((LumiaBootManagerAppModel)CurrentModel).Shutdown();
ModeSwitchProgressWrapper("Please disconnect your device. Waiting...", null);
LogFile.Log("Please disconnect your device. Waiting...", LogType.FileAndConsole);
new Thread(() =>
{
PhoneNotifier.WaitForRemoval().Wait();
ModeSwitchSuccessWrapper();
}).Start();
break;
case PhoneInterfaces.Lumia_Normal:
((LumiaBootManagerAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
break;
case PhoneInterfaces.Lumia_Bootloader:
((LumiaBootManagerAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived; PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
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);
@@ -332,7 +475,7 @@ namespace WPinternals
break; break;
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
byte[] RebootToFlashCommand = [0x4E, 0x4F, 0x4B, 0x53]; // NOKS byte[] RebootToFlashCommand = [0x4E, 0x4F, 0x4B, 0x53]; // NOKS
((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootToFlashCommand); ((LumiaBootManagerAppModel)CurrentModel).ExecuteRawVoidMethod(RebootToFlashCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived; PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
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);
@@ -341,8 +484,8 @@ namespace WPinternals
SwitchFromFlashToMassStorageMode(); SwitchFromFlashToMassStorageMode();
break; break;
case PhoneInterfaces.Qualcomm_Download: case PhoneInterfaces.Qualcomm_Download:
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE // TODO
RebootCommandResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand); RebootCommandResult = ((LumiaBootManagerAppModel)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;
@@ -423,6 +566,12 @@ namespace WPinternals
case PhoneInterfaces.Lumia_Flash: case PhoneInterfaces.Lumia_Flash:
ModeSwitchErrorWrapper("Failed to switch to Flash mode"); ModeSwitchErrorWrapper("Failed to switch to Flash mode");
break; break;
case PhoneInterfaces.Lumia_Bootloader:
ModeSwitchErrorWrapper("Failed to switch to Boot Manager mode");
break;
case PhoneInterfaces.Lumia_PhoneInfo:
ModeSwitchErrorWrapper("Failed to switch to Phone Info mode");
break;
case PhoneInterfaces.Lumia_Label: case PhoneInterfaces.Lumia_Label:
ModeSwitchErrorWrapper("Failed to switch to Label mode"); ModeSwitchErrorWrapper("Failed to switch to Label mode");
break; break;
@@ -443,6 +592,12 @@ namespace WPinternals
case PhoneInterfaces.Lumia_Flash: case PhoneInterfaces.Lumia_Flash:
ModeSwitchErrorWrapper("Failed to switch to Flash mode"); ModeSwitchErrorWrapper("Failed to switch to Flash mode");
break; break;
case PhoneInterfaces.Lumia_Bootloader:
ModeSwitchErrorWrapper("Failed to switch to Boot Manager mode");
break;
case PhoneInterfaces.Lumia_PhoneInfo:
ModeSwitchErrorWrapper("Failed to switch to Phone Info mode");
break;
case PhoneInterfaces.Lumia_Label: case PhoneInterfaces.Lumia_Label:
ModeSwitchErrorWrapper("Failed to switch to Label mode"); ModeSwitchErrorWrapper("Failed to switch to Label mode");
break; break;
@@ -471,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.
((NokiaFlashModel)CurrentModel).ResetPhoneToFlashMode(); ((LumiaBootManagerAppModel)CurrentModel).ResetPhoneToFlashMode();
CurrentMode = PhoneInterfaces.Lumia_Flash; CurrentMode = PhoneInterfaces.Lumia_Flash;
PhoneNotifier.NotifyArrival(); PhoneNotifier.NotifyArrival();
} }
@@ -511,7 +666,7 @@ namespace WPinternals
else if ((CurrentMode == PhoneInterfaces.Lumia_Flash) && (TargetMode == PhoneInterfaces.Qualcomm_Download)) else if ((CurrentMode == PhoneInterfaces.Lumia_Flash) && (TargetMode == PhoneInterfaces.Qualcomm_Download))
{ {
byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52]; byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52];
byte[] RebootToQualcommDownloadCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45]; // NOKXCBE 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)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
@@ -542,6 +697,12 @@ namespace WPinternals
case PhoneInterfaces.Lumia_Flash: case PhoneInterfaces.Lumia_Flash:
ModeSwitchErrorWrapper("Failed to switch to Flash mode"); ModeSwitchErrorWrapper("Failed to switch to Flash mode");
break; break;
case PhoneInterfaces.Lumia_Bootloader:
ModeSwitchErrorWrapper("Failed to switch to Boot Manager mode");
break;
case PhoneInterfaces.Lumia_PhoneInfo:
ModeSwitchErrorWrapper("Failed to switch to Phone Info mode");
break;
case PhoneInterfaces.Lumia_Label: case PhoneInterfaces.Lumia_Label:
ModeSwitchErrorWrapper("Failed to switch to Label mode"); ModeSwitchErrorWrapper("Failed to switch to Label mode");
break; break;
@@ -552,21 +713,14 @@ namespace WPinternals
} }
} }
private void SwitchFromFlashToLabelMode(bool Continuation = false) private async void SwitchFromPhoneInfoToLabelMode(bool Continuation = false)
{ {
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...";
NokiaFlashModel FlashModel = (NokiaFlashModel)CurrentModel;
if (CurrentMode == PhoneInterfaces.Lumia_Bootloader) ((LumiaBootManagerAppModel)CurrentModel).SwitchToFlashAppContext();
{ await PhoneNotifier.WaitForArrival();
try
{ LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)CurrentModel;
FlashModel.SwitchToFlashAppContext();
}
catch (Exception ex)
{
LogFile.LogException(ex, LogType.FileOnly);
}
}
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: true); PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: true);
if (Info.MmosOverUsbSupported) if (Info.MmosOverUsbSupported)
@@ -632,29 +786,306 @@ namespace WPinternals
byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52]; // NOKR byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52]; // NOKR
BootModeFlagCommand[0x0F] = 0x59; BootModeFlagCommand[0x0F] = 0x59;
((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(BootModeFlagCommand); ((LumiaFlashAppModel)CurrentModel).ExecuteRawMethod(BootModeFlagCommand);
((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand); ((LumiaFlashAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived; PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
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);
} }
} }
private void SwitchFromFlashToLabelMode(bool Continuation = false)
{
string ProgressText = Continuation ? "And now preparing to boot the phone to Label mode..." : "Preparing to boot the phone to Label mode...";
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)CurrentModel;
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: true);
if (Info.MmosOverUsbSupported)
{
new Thread(() =>
{
LogFile.BeginAction("SwitchToLabelMode");
try
{
ModeSwitchProgressWrapper(ProgressText, null);
string TempFolder = Environment.GetEnvironmentVariable("TEMP") + @"\WPInternals";
if (Info.Type == "RM-1152")
{
Info.Type = "RM-1151";
}
string ENOSWPackage = LumiaDownloadModel.SearchENOSW(Info.Type, Info.Firmware);
SetWorkingStatus("Downloading " + Info.Type + " Test Mode package...", MaxProgressValue: 100);
DownloadEntry downloadEntry = new(ENOSWPackage, TempFolder, null, null, null);
downloadEntry.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) =>
{
if (e.PropertyName == "Progress")
{
int progress = (sender as DownloadEntry)?.Progress ?? 0;
ulong.TryParse(progress.ToString(), out ulong progressret);
UpdateWorkingStatus(null, CurrentProgressValue: progressret);
if (progress == 100)
{
ModeSwitchProgressWrapper("Initializing Flash...", null);
string MMOSPath = TempFolder + "\\" + (sender as DownloadEntry)?.Name;
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
FileInfo info = new(MMOSPath);
uint length = uint.Parse(info.Length.ToString());
const int maximumbuffersize = 0x00240000;
uint totalcounts = (uint)Math.Truncate((decimal)length / maximumbuffersize);
SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100);
ProgressUpdater progressUpdater = new(totalcounts + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i));
FlashModel.FlashMMOS(MMOSPath, progressUpdater);
SetWorkingStatus("And now booting phone to MMOS...", "If the phone stays on the lightning cog screen for a while, you may need to unplug and replug the phone to continue the boot process.");
}
}
};
}
catch (Exception Ex)
{
LogFile.LogException(Ex);
ModeSwitchErrorWrapper(Ex.Message);
}
LogFile.EndAction("SwitchToLabelMode");
}).Start();
}
else
{
byte[] BootModeFlagCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x46, 0x57, 0x00, 0x55, 0x42, 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00]; // NOKFW UBF
byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52]; // NOKR
BootModeFlagCommand[0x0F] = 0x59;
((LumiaFlashAppModel)CurrentModel).ExecuteRawMethod(BootModeFlagCommand);
((LumiaFlashAppModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper("Rebooting phone to Label mode", null);
LogFile.Log("Rebooting phone to Label mode", LogType.FileAndConsole);
}
}
private async void SwitchFromPhoneInfoToMassStorageMode(bool Continuation = false)
{
string ProgressText = Continuation ? "And now rebooting phone to Mass Storage mode..." : "Rebooting phone to Mass Storage mode...";
((LumiaBootManagerAppModel)CurrentModel).SwitchToFlashAppContext();
await PhoneNotifier.WaitForArrival();
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)CurrentModel;
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
MassStorageWarning = null;
if (Info.FlashAppProtocolVersionMajor < 2)
{
MassStorageWarning = "Switching to Mass Storage mode should take about 10 seconds. The phone should be unlocked using an Engineering SBL3 to enable Mass Storage mode. When you unlocked the bootloader, but you did not use an Engineering SBL3, an attempt to boot to Mass Storage mode may result in an unresponsive state. Installing drivers for this interface may also cause to hang the PC. So when this switch is taking too long, you should reboot both the PC and the phone. To reboot the phone, you have to perform a soft-reset. Press and hold the volume-down-button and the power-button at the same time for at least 10 seconds. This will trigger a power-cycle and the phone will reboot. Once fully booted, the phone may show strange behavior, like complaining about mail-accounts, showing old text-messages, inability to load https-websites, etc. This is expected behavior, because the time-settings of the phone are incorrect. Just wait a few seconds for the phone to get a data-connection and have the date/time synced. After that the strange behavior will stop automatically and normal operation is resumed.";
}
else
{
MassStorageWarning = "When the screen of the phone is black for a while, it could be that the phone is already in Mass Storage Mode, but there is no drive-letter assigned. To resolve this issue, open Device Manager and manually assign a drive-letter to the MainOS partition of your phone, or open a command-prompt and type: diskpart automount enable.";
if (App.IsPnPEventLogMissing)
{
MassStorageWarning += " It is also possible that the phone is in Mass Storage mode, but the Mass Storage driver on this PC failed. Your PC does not have an eventlog to detect this misbehaviour. But in this case you will see a device with an exclamation mark in Device Manager and then you need to manually reset the phone by pressing and holding the power-button for at least 10 seconds until it vibrates and reboots. After that Windows Phone Internals will revert the changes. After the phone has rebooted to the OS, you can retry to unlock the bootloader.";
}
}
bool IsOldLumia = Info.FlashAppProtocolVersionMajor < 2;
bool IsNewLumia = Info.FlashAppProtocolVersionMajor >= 2;
bool IsUnlockedNew = false;
if (IsNewLumia)
{
GPT GPT = FlashModel.ReadGPT();
IsUnlockedNew = (GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null) || (GPT.GetPartition("BACKUP_BS_NV") != null);
}
bool IsOriginalEngineeringLumia = !Info.IsBootloaderSecure && !IsUnlockedNew;
if (IsOldLumia || IsOriginalEngineeringLumia)
{
byte[] BootModeFlagCommand = [0x4E, 0x4F, 0x4B, 0x58, 0x46, 0x57, 0x00, 0x55, 0x42, 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00]; // NOKFW UBF
byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52];
byte[] RebootToMassStorageCommand = [0x4E, 0x4F, 0x4B, 0x4D]; // NOKM
IsSwitchingInterface = true;
byte[] RebootCommandResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(RebootToMassStorageCommand);
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknown command)
{
BootModeFlagCommand[0x0F] = 0x4D;
byte[] BootFlagResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(BootModeFlagCommand);
UInt16 ResultCode = BitConverter.ToUInt16(BootFlagResult, 6);
if (ResultCode == 0)
{
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
LogFile.Log("Rebooting phone to Mass Storage mode");
}
else
{
ModeSwitchErrorWrapper("Failed to switch to Mass Storage mode");
IsSwitchingInterface = false;
}
}
else
{
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
LogFile.Log("Rebooting phone to Mass Storage mode");
}
}
else if (IsUnlockedNew)
{
new Thread(async () =>
{
LogFile.BeginAction("SwitchToMassStorageMode");
try
{
// Implementation of writing a partition with SecureBoot variable to the phone
ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
LogFile.Log("Preparing phone for Mass Storage Mode", LogType.FileAndConsole);
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
// Magic!
// The SBMSM resource is a compressed version of a raw NV-variable-partition.
// In this partition the SecureBoot variable is disabled and an extra variable is added which triggers Mass Storage Mode on next reboot.
// It overwrites the variable in a different NV-partition than where this variable is stored usually.
// This normally leads to endless-loops when the NV-variables are enumerated.
// But the partition contains an extra hack to break out the endless loops.
using (var stream = assembly.GetManifestResourceStream("WPinternals.SBMSM"))
{
using DecompressedStream dec = new(stream);
using MemoryStream SB = new(); // Must be a seekable stream!
dec.CopyTo(SB);
// We don't need to check for the BACKUP_BS_NV partition here,
// because the SecureBoot flag is disabled here.
// So either the NV was already backupped or already overwritten.
GPT GPT = FlashModel.ReadGPT();
Partition Target = GPT.GetPartition("UEFI_BS_NV");
// We've been reading the GPT, so we let the phone reset once more to be sure that memory maps are the same
WPinternalsStatus LastStatus = WPinternalsStatus.Undefined;
List<FlashPart> Parts = new();
FlashPart Part = new();
Part.StartSector = (uint)Target.FirstSector;
Part.Stream = SB;
Parts.Add(Part);
await LumiaV2UnlockBootViewModel.LumiaV2CustomFlash(PhoneNotifier, null, false, false, Parts, DoResetFirst: true, ClearFlashingStatusAtEnd: false, ShowProgress: false,
SetWorkingStatus: (m, s, v, a, st) =>
{
if (SetWorkingStatus != null)
{
if ((st == WPinternalsStatus.Scanning) || (st == WPinternalsStatus.WaitingForManualReset))
{
SetWorkingStatus(m, s, v, a, st);
}
else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
{
SetWorkingStatus(ProgressText, MassStorageWarning);
}
LastStatus = st;
}
},
UpdateWorkingStatus: (m, s, v, st) =>
{
if (UpdateWorkingStatus != null)
{
if ((st == WPinternalsStatus.Scanning) || (st == WPinternalsStatus.WaitingForManualReset))
{
UpdateWorkingStatus(m, s, v, st);
}
else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
{
SetWorkingStatus(ProgressText, MassStorageWarning);
}
LastStatus = st;
}
});
}
if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_BadMassStorage)
{
throw new WPinternalsException("Phone is in Mass Storage mode, but the driver on PC failed to start");
}
// Wait for bootloader
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_MassStorage)
{
LogFile.Log("Waiting for Mass Storage Mode (1)...", LogType.FileOnly);
await PhoneNotifier.WaitForArrival();
}
if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_BadMassStorage)
{
throw new WPinternalsException("Phone is in Mass Storage mode, but the driver on PC failed to start");
}
// Wait for mass storage mode
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_MassStorage)
{
LogFile.Log("Waiting for Mass Storage Mode (2)...", LogType.FileOnly);
await PhoneNotifier.WaitForArrival();
}
if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_BadMassStorage)
{
throw new WPinternalsException("Phone is in Mass Storage mode, but the driver on PC failed to start");
}
MassStorage Storage = null;
if (PhoneNotifier.CurrentModel is MassStorage)
{
Storage = (MassStorage)PhoneNotifier.CurrentModel;
}
if (Storage == null)
{
ModeSwitchErrorWrapper("Failed to switch to Mass Storage Mode");
}
else
{
ModeSwitchSuccessWrapper();
}
}
catch (Exception Ex)
{
LogFile.LogException(Ex);
ModeSwitchErrorWrapper(Ex.Message);
}
LogFile.EndAction("SwitchToMassStorageMode");
}).Start();
}
else
{
ModeSwitchErrorWrapper("Bootloader was not unlocked. First unlock bootloader before you try to switch to Mass Storage Mode.");
}
}
private void SwitchFromFlashToMassStorageMode(bool Continuation = false) private void SwitchFromFlashToMassStorageMode(bool Continuation = false)
{ {
string ProgressText = Continuation ? "And now rebooting phone to Mass Storage mode..." : "Rebooting phone to Mass Storage mode..."; string ProgressText = Continuation ? "And now rebooting phone to Mass Storage mode..." : "Rebooting phone to Mass Storage mode...";
NokiaFlashModel FlashModel = (NokiaFlashModel)CurrentModel;
if (CurrentMode == PhoneInterfaces.Lumia_Bootloader) if (CurrentMode == PhoneInterfaces.Lumia_Bootloader)
{ {
try try
{ {
FlashModel.SwitchToFlashAppContext(); ((LumiaBootManagerAppModel)CurrentModel).SwitchToFlashAppContext();
} }
catch (Exception ex) catch (Exception ex)
{ {
LogFile.LogException(ex, LogType.FileOnly); LogFile.LogException(ex, LogType.FileOnly);
} }
} }
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)CurrentModel;
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false); PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
MassStorageWarning = null; MassStorageWarning = null;
+32 -3
View File
@@ -99,9 +99,38 @@ DEALINGS IN THE SOFTWARE.
</StackPanel> </StackPanel>
</Border> </Border>
<Border BorderThickness="1" BorderBrush="#FFD4D4D4" HorizontalAlignment="Stretch" VerticalAlignment="Center" Padding="25" Margin="0,0,0,20"> <Border BorderThickness="1" BorderBrush="#FFD4D4D4" HorizontalAlignment="Stretch" VerticalAlignment="Center" Padding="25" Margin="0,0,0,20">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal"> <StackPanel>
<local:GifImage x:Name="GifImage" Stretch="None"/> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
<Label Content="Phone is booting..." FontSize="20" Margin="10,0,0,0" VerticalContentAlignment="Center"/> <local:GifImage x:Name="GifImage" Stretch="None"/>
<Label Content="Phone is booting..." FontSize="20" Margin="10,0,0,0" VerticalContentAlignment="Center"/>
</StackPanel>
<local:FlowDocumentScrollViewerNoMouseWheel Margin="20,0,20,0" VerticalScrollBarVisibility="Auto">
<FlowDocument FontFamily="Segoe UI" FontSize="12" Loaded="Document_Loaded">
<local:Paragraph TextAlignment="Center">
<Run Text="When you connect the phone, it can take a moment before it is recognized. If it still isn't recognized after a while, you might need to install the necessary drivers first. For more information about the drivers, read the " />
<Hyperlink NavigateUri="Getting started">Getting started</Hyperlink>
<Run Text=" section. If the drivers are installed, but the phone is still not recognized, then try to perform a soft-reset, while the USB of the phone is connected. On Lumia phones you have to press-and-hold the power-button and volume-down-button at the same time for at least 10 seconds. If the tool detects the bootloader of the phone it will try to connect to the phone at this early boot-stage." />
</local:Paragraph>
</FlowDocument>
</local:FlowDocumentScrollViewerNoMouseWheel>
<local:FlowDocumentScrollViewerNoMouseWheel Grid.Column="1" Margin="20,-20,20,0" VerticalScrollBarVisibility="Auto" Visibility="{Binding InterruptBoot, RelativeSource={RelativeSource AncestorType={x:Type local:NokiaBootloaderView}}, Converter={StaticResource InverseVisibilityConverter}}">
<FlowDocument FontFamily="Segoe UI" FontSize="12" Loaded="Document_Loaded">
<local:Paragraph TextAlignment="Center">
<Run Text="You can "/>
<Hyperlink NavigateUri="Interrupt boot">interrupt the boot-process</Hyperlink>
<Run Text=" as soon as the bootloader is detected. This allows you to configure the phone or flash a ROM before it boots to the OS. You can also try this when the phone is not booting properly. When you unlocked the bootloader and the phone boots to a Blue Screen, you can still enter Mass Storage Mode if you want. To boot properly again, restore the bootloader. You can update to a supported OS version and try again after that."/>
</local:Paragraph>
</FlowDocument>
</local:FlowDocumentScrollViewerNoMouseWheel>
<local:FlowDocumentScrollViewerNoMouseWheel Grid.Column="1" Margin="20,-20,20,0" VerticalScrollBarVisibility="Auto" Visibility="{Binding InterruptBoot, RelativeSource={RelativeSource AncestorType={x:Type local:NokiaBootloaderView}}, Converter={StaticResource VisibilityConverter}}">
<FlowDocument FontFamily="Segoe UI" FontSize="12" Loaded="Document_Loaded">
<local:Paragraph TextAlignment="Center">
<Run Text="Windows Phone Internals is set to interrupt the boot-process as soon as the bootloader is detected. You can also allow the phone to "/>
<Hyperlink NavigateUri="Normal boot">boot normally</Hyperlink>
<Run Text="."/>
</local:Paragraph>
</FlowDocument>
</local:FlowDocumentScrollViewerNoMouseWheel>
</StackPanel> </StackPanel>
</Border> </Border>
<Border BorderThickness="1" BorderBrush="#FFD4D4D4" HorizontalAlignment="Stretch" VerticalAlignment="Center" Padding="25"> <Border BorderThickness="1" BorderBrush="#FFD4D4D4" HorizontalAlignment="Stretch" VerticalAlignment="Center" Padding="25">
+85 -3
View File
@@ -18,9 +18,13 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System.Threading.Tasks;
using System.Threading;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Media;
using System;
namespace WPinternals namespace WPinternals
{ {
@@ -29,13 +33,41 @@ namespace WPinternals
/// </summary> /// </summary>
public partial class NokiaBootloaderView : UserControl public partial class NokiaBootloaderView : UserControl
{ {
private static PhoneNotifierViewModel PhoneNotifier;
private static SynchronizationContext UIContext;
public NokiaBootloaderView() public NokiaBootloaderView()
{ {
InitializeComponent(); InitializeComponent();
InterruptBoot = App.InterruptBoot;
UIContext = SynchronizationContext.Current;
// Setting these properties in XAML results in an error. Why? // Setting these properties in XAML results in an error. Why?
GifImage.GifSource = "/aerobusy.gif"; GifImage.GifSource = "/aerobusy.gif";
GifImage.AutoStart = true; GifImage.AutoStart = true;
Loaded += NokiaBootloaderView_Loaded;
Unloaded += NokiaBootloaderView_Unloaded;
}
private void NokiaBootloaderView_Unloaded(object sender, RoutedEventArgs e)
{
PhoneNotifier.NewDeviceArrived -= PhoneNotifier_NewDeviceArrived;
}
private void NokiaBootloaderView_Loaded(object sender, RoutedEventArgs e)
{
// Find the phone notifier
DependencyObject obj = (DependencyObject)sender;
while (!(obj is MainWindow))
{
obj = VisualTreeHelper.GetParent(obj);
}
PhoneNotifier = ((MainViewModel)((MainWindow)obj).DataContext).PhoneNotifier;
PhoneNotifier.NewDeviceArrived += PhoneNotifier_NewDeviceArrived;
} }
private void HandleHyperlinkClick(object sender, RoutedEventArgs args) private void HandleHyperlinkClick(object sender, RoutedEventArgs args)
@@ -43,10 +75,24 @@ namespace WPinternals
Hyperlink link = args.Source as Hyperlink; Hyperlink link = args.Source as Hyperlink;
if (link?.NavigateUri != null) if (link?.NavigateUri != null)
{ {
if (link.NavigateUri.ToString() == "GettingStarted") if (link.NavigateUri.ToString() == "Getting started")
{ {
(this.DataContext as NokiaBootloaderViewModel)?.SwitchToGettingStarted(); App.NavigateToGettingStarted();
} (this.DataContext as NokiaBootloaderViewModel)?.RebootTo(link.NavigateUri.ToString()); }
else if (link.NavigateUri.ToString() == "Unlock boot")
{
App.NavigateToUnlockBoot();
}
else if (link.NavigateUri.ToString() == "Interrupt boot")
{
InterruptBoot = true;
}
else if (link.NavigateUri.ToString() == "Normal boot")
{
InterruptBoot = false;
}
(this.DataContext as NokiaBootloaderViewModel)?.RebootTo(link.NavigateUri.ToString());
} }
} }
@@ -54,5 +100,41 @@ namespace WPinternals
{ {
(sender as FlowDocument)?.AddHandler(Hyperlink.ClickEvent, new RoutedEventHandler(HandleHyperlinkClick)); (sender as FlowDocument)?.AddHandler(Hyperlink.ClickEvent, new RoutedEventHandler(HandleHyperlinkClick));
} }
public static readonly DependencyProperty InterruptBootProperty =
DependencyProperty.Register("InterruptBoot", typeof(Boolean), typeof(NokiaBootloaderView), new FrameworkPropertyMetadata(InterruptBootChanged));
public bool InterruptBoot
{
get
{
return (bool)GetValue(InterruptBootProperty);
}
set
{
SetValue(InterruptBootProperty, value);
}
}
internal static void InterruptBootChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
App.InterruptBoot = (bool)e.NewValue;
if ((bool)e.NewValue && PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{
App.InterruptBoot = false;
LogFile.Log("Found Lumia BootMgr and user forced to interrupt the boot process. Force to Flash-mode.");
Task.Run(() => SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Lumia_Flash));
}
}
internal void PhoneNotifier_NewDeviceArrived(ArrivalEventArgs Args)
{
if (App.InterruptBoot && Args.NewInterface == PhoneInterfaces.Lumia_Bootloader)
{
App.InterruptBoot = false;
LogFile.Log("Found Lumia BootMgr and user forced to interrupt the boot process. Force to Flash-mode.");
Task.Run(() => SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Lumia_Flash));
}
}
} }
} }
+10
View File
@@ -58,6 +58,16 @@ DEALINGS IN THE SOFTWARE.
<Run Text="This will switch back to Windows Phone OS." /> <Run Text="This will switch back to Windows Phone OS." />
<LineBreak /> <LineBreak />
<LineBreak /> <LineBreak />
<Hyperlink NavigateUri="PhoneInfo">Switch to Phone-Info-mode</Hyperlink>
<LineBreak />
<Run Text="This will switch to Phone Info Mode." />
<LineBreak />
<LineBreak />
<Hyperlink NavigateUri="BootMgr">Switch to Boot-Manager-mode</Hyperlink>
<LineBreak />
<Run Text="This will switch to Boot Manager Mode." />
<LineBreak />
<LineBreak />
<Hyperlink NavigateUri="Label">Switch to Label-mode</Hyperlink> <Hyperlink NavigateUri="Label">Switch to Label-mode</Hyperlink>
<LineBreak /> <LineBreak />
<Run Text="This interface is meant for querying and provisioning the phone. This is normally used for configuring the phone during manufacturing." /> <Run Text="This interface is meant for querying and provisioning the phone. This is normally used for configuring the phone during manufacturing." />
@@ -58,6 +58,16 @@ DEALINGS IN THE SOFTWARE.
<Run Text="This will switch back to Windows Phone OS." /> <Run Text="This will switch back to Windows Phone OS." />
<LineBreak /> <LineBreak />
<LineBreak /> <LineBreak />
<Hyperlink NavigateUri="Flash">Switch to Flash-mode</Hyperlink>
<LineBreak />
<Run Text="This is the interface that can be used to flash a new ROM image. It can also be used to retrieve additional info and security status." />
<LineBreak />
<LineBreak />
<Hyperlink NavigateUri="BootMgr">Switch to Boot-Manager-mode</Hyperlink>
<LineBreak />
<Run Text="This will switch to Boot Manager Mode." />
<LineBreak />
<LineBreak />
<Hyperlink NavigateUri="Label">Switch to Label-mode</Hyperlink> <Hyperlink NavigateUri="Label">Switch to Label-mode</Hyperlink>
<LineBreak /> <LineBreak />
<Run Text="This interface is meant for querying and provisioning the phone. This is normally used for configuring the phone during manufacturing." /> <Run Text="This interface is meant for querying and provisioning the phone. This is normally used for configuring the phone during manufacturing." />
@@ -82,12 +82,6 @@ DEALINGS IN THE SOFTWARE.
</local:FlowDocumentScrollViewerNoMouseWheel> </local:FlowDocumentScrollViewerNoMouseWheel>
</StackPanel> </StackPanel>
</Border> </Border>
<Border BorderThickness="1" BorderBrush="#FFD4D4D4" HorizontalAlignment="Stretch" VerticalAlignment="Center" Padding="25" Margin="0,0,0,20">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
<local:GifImage x:Name="GifImage" Stretch="None"/>
<Label Content="Phone is booting..." FontSize="20" Margin="10,0,0,0" VerticalContentAlignment="Center"/>
</StackPanel>
</Border>
<Border BorderThickness="1" BorderBrush="#FFD4D4D4" HorizontalAlignment="Stretch" VerticalAlignment="Center" Padding="25"> <Border BorderThickness="1" BorderBrush="#FFD4D4D4" HorizontalAlignment="Stretch" VerticalAlignment="Center" Padding="25">
<Expander Header="Phone identity" HorizontalContentAlignment="Stretch" Template="{DynamicResource TopicExpanderTemplate}" Margin="20,0"> <Expander Header="Phone identity" HorizontalContentAlignment="Stretch" Template="{DynamicResource TopicExpanderTemplate}" Margin="20,0">
<local:FlowDocumentScrollViewerNoMouseWheel Grid.Column="1" VerticalScrollBarVisibility="Auto" > <local:FlowDocumentScrollViewerNoMouseWheel Grid.Column="1" VerticalScrollBarVisibility="Auto" >
@@ -32,10 +32,6 @@ namespace WPinternals
public NokiaPhoneInfoView() public NokiaPhoneInfoView()
{ {
InitializeComponent(); InitializeComponent();
// Setting these properties in XAML results in an error. Why?
GifImage.GifSource = "/aerobusy.gif";
GifImage.AutoStart = true;
} }
private void HandleHyperlinkClick(object sender, RoutedEventArgs args) private void HandleHyperlinkClick(object sender, RoutedEventArgs args)