mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-06-19 13:50:11 +10:00
Project Maintenance
This commit is contained in:
@@ -30,12 +30,12 @@ namespace WPinternals
|
||||
{
|
||||
internal class LumiaFlashRomViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
internal Action SwitchToUnlockBoot;
|
||||
internal Action SwitchToUnlockRoot;
|
||||
internal Action SwitchToDumpFFU;
|
||||
internal Action SwitchToBackup;
|
||||
private Action Callback;
|
||||
private readonly Action Callback;
|
||||
|
||||
internal LumiaFlashRomViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToUnlockRoot, Action SwitchToDumpFFU, Action SwitchToBackup, Action Callback)
|
||||
: base()
|
||||
@@ -54,10 +54,14 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SubContextViewModel == null)
|
||||
{
|
||||
ActivateSubContext(new LumiaFlashRomSourceSelectionViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToUnlockRoot, SwitchToDumpFFU, SwitchToBackup, FlashPartitions, FlashArchive, FlashFFU, FlashMMOS));
|
||||
}
|
||||
}
|
||||
|
||||
// Called from an event-handler. So, "async void" is valid here.
|
||||
@@ -70,9 +74,13 @@ namespace WPinternals
|
||||
(msg, sub) =>
|
||||
ActivateSubContext(new BusyViewModel(msg, sub)));
|
||||
if (((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: false).FlashAppProtocolVersionMajor < 2)
|
||||
{
|
||||
FlashPartitionsTask(EFIESPPath, MainOSPath, DataPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Run(async () => await LumiaV2UnlockBootViewModel.LumiaV2FlashPartitions(PhoneNotifier, EFIESPPath, MainOSPath, DataPath, SetWorkingStatus, UpdateWorkingStatus, ExitSuccess, ExitFailure));
|
||||
}
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
@@ -104,46 +112,40 @@ namespace WPinternals
|
||||
{
|
||||
if (EFIESPPath != null)
|
||||
{
|
||||
using (Stream Stream = new DecompressedStream(File.Open(EFIESPPath, FileMode.Open)))
|
||||
using Stream Stream = new DecompressedStream(File.Open(EFIESPPath, FileMode.Open));
|
||||
ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
|
||||
TotalSizeSectors += StreamLengthInSectors;
|
||||
PartitionCount++;
|
||||
Partition Partition = GPT.Partitions.Find(p => string.Compare(p.Name, "EFIESP", true) == 0);
|
||||
if (StreamLengthInSectors > Partition.SizeInSectors)
|
||||
{
|
||||
ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
|
||||
TotalSizeSectors += StreamLengthInSectors;
|
||||
PartitionCount++;
|
||||
Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, "EFIESP", true) == 0).FirstOrDefault();
|
||||
if (StreamLengthInSectors > Partition.SizeInSectors)
|
||||
{
|
||||
LogFile.Log("Flash failed! Size of partition 'EFIESP' is too big.");
|
||||
ExitFailure("Flash failed!", "Size of partition 'EFIESP' is too big.");
|
||||
return;
|
||||
}
|
||||
LogFile.Log("Flash failed! Size of partition 'EFIESP' is too big.");
|
||||
ExitFailure("Flash failed!", "Size of partition 'EFIESP' is too big.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MainOSPath != null)
|
||||
{
|
||||
using (Stream Stream = new DecompressedStream(File.Open(MainOSPath, FileMode.Open)))
|
||||
{
|
||||
ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
|
||||
TotalSizeSectors += StreamLengthInSectors;
|
||||
PartitionCount++;
|
||||
Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, "MainOS", true) == 0).FirstOrDefault();
|
||||
MainOSOldSectorCount = Partition.SizeInSectors;
|
||||
MainOSNewSectorCount = StreamLengthInSectors;
|
||||
FirstMainOSSector = Partition.FirstSector;
|
||||
}
|
||||
using Stream Stream = new DecompressedStream(File.Open(MainOSPath, FileMode.Open));
|
||||
ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
|
||||
TotalSizeSectors += StreamLengthInSectors;
|
||||
PartitionCount++;
|
||||
Partition Partition = GPT.Partitions.Find(p => string.Compare(p.Name, "MainOS", true) == 0);
|
||||
MainOSOldSectorCount = Partition.SizeInSectors;
|
||||
MainOSNewSectorCount = StreamLengthInSectors;
|
||||
FirstMainOSSector = Partition.FirstSector;
|
||||
}
|
||||
|
||||
if (DataPath != null)
|
||||
{
|
||||
using (Stream Stream = new DecompressedStream(File.Open(DataPath, FileMode.Open)))
|
||||
{
|
||||
ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
|
||||
TotalSizeSectors += StreamLengthInSectors;
|
||||
PartitionCount++;
|
||||
Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, "Data", true) == 0).FirstOrDefault();
|
||||
DataOldSectorCount = Partition.SizeInSectors;
|
||||
DataNewSectorCount = StreamLengthInSectors;
|
||||
}
|
||||
using Stream Stream = new DecompressedStream(File.Open(DataPath, FileMode.Open));
|
||||
ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
|
||||
TotalSizeSectors += StreamLengthInSectors;
|
||||
PartitionCount++;
|
||||
Partition Partition = GPT.Partitions.Find(p => string.Compare(p.Name, "Data", true) == 0);
|
||||
DataOldSectorCount = Partition.SizeInSectors;
|
||||
DataNewSectorCount = StreamLengthInSectors;
|
||||
}
|
||||
}
|
||||
catch (Exception Ex)
|
||||
@@ -160,8 +162,8 @@ namespace WPinternals
|
||||
if ((MainOSNewSectorCount + DataNewSectorCount) <= OSSpace)
|
||||
{
|
||||
// MainOS and Data partitions need to be re-aligned!
|
||||
Partition MainOSPartition = GPT.Partitions.Where(p => string.Compare(p.Name, "MainOS", true) == 0).Single();
|
||||
Partition DataPartition = GPT.Partitions.Where(p => string.Compare(p.Name, "Data", true) == 0).Single();
|
||||
Partition MainOSPartition = GPT.Partitions.Single(p => string.Compare(p.Name, "MainOS", true) == 0);
|
||||
Partition DataPartition = GPT.Partitions.Single(p => string.Compare(p.Name, "Data", true) == 0);
|
||||
MainOSPartition.LastSector = MainOSPartition.FirstSector + MainOSNewSectorCount - 1;
|
||||
DataPartition.FirstSector = MainOSPartition.LastSector + 1;
|
||||
DataPartition.LastSector = DataPartition.FirstSector + DataNewSectorCount - 1;
|
||||
@@ -188,7 +190,7 @@ namespace WPinternals
|
||||
return;
|
||||
}
|
||||
|
||||
BusyViewModel Busy = new BusyViewModel("Flashing...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
BusyViewModel Busy = new("Flashing...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
ProgressUpdater Updater = Busy.ProgressUpdater;
|
||||
ActivateSubContext(Busy);
|
||||
|
||||
@@ -200,7 +202,7 @@ namespace WPinternals
|
||||
if (EFIESPPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Flashing partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Flashing partition EFIESP (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.FlashRawPartition(EFIESPPath, "EFIESP", Updater);
|
||||
}
|
||||
}
|
||||
@@ -218,7 +220,7 @@ namespace WPinternals
|
||||
if (MainOSPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Flashing partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Flashing partition MainOS (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.FlashRawPartition(MainOSPath, "MainOS", Updater);
|
||||
}
|
||||
}
|
||||
@@ -236,7 +238,7 @@ namespace WPinternals
|
||||
if (DataPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Flashing partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Flashing partition Data (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.FlashRawPartition(DataPath, "Data", Updater);
|
||||
}
|
||||
}
|
||||
@@ -267,9 +269,13 @@ namespace WPinternals
|
||||
(msg, sub) =>
|
||||
ActivateSubContext(new BusyViewModel(msg, sub)));
|
||||
if (((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: false).FlashAppProtocolVersionMajor < 2)
|
||||
{
|
||||
FlashArchiveTask(ArchivePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Run(async () => await LumiaV2UnlockBootViewModel.LumiaV2FlashArchive(PhoneNotifier, ArchivePath, SetWorkingStatus, UpdateWorkingStatus, ExitSuccess, ExitFailure));
|
||||
}
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
@@ -298,159 +304,158 @@ namespace WPinternals
|
||||
{
|
||||
GPT GPT = Phone.ReadGPT();
|
||||
|
||||
using (FileStream FileStream = new FileStream(ArchivePath, FileMode.Open))
|
||||
using FileStream FileStream = new(ArchivePath, FileMode.Open);
|
||||
using ZipArchive Archive = new(FileStream, ZipArchiveMode.Read);
|
||||
foreach (ZipArchiveEntry Entry in Archive.Entries)
|
||||
{
|
||||
using (ZipArchive Archive = new ZipArchive(FileStream, ZipArchiveMode.Read))
|
||||
// Determine if there is a partition layout present
|
||||
ZipArchiveEntry PartitionEntry = Archive.GetEntry("Partitions.xml");
|
||||
if (PartitionEntry == null)
|
||||
{
|
||||
foreach (ZipArchiveEntry Entry in Archive.Entries)
|
||||
GPT.MergePartitions(null, false, Archive);
|
||||
GPTChanged |= GPT.HasChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
using Stream ZipStream = PartitionEntry.Open();
|
||||
using StreamReader ZipReader = new(ZipStream);
|
||||
string PartitionXml = ZipReader.ReadToEnd();
|
||||
GPT.MergePartitions(PartitionXml, false, Archive);
|
||||
GPTChanged |= GPT.HasChanged;
|
||||
}
|
||||
|
||||
// First determine if we need a new GPT!
|
||||
if (!Entry.FullName.Contains("/")) // No subfolders
|
||||
{
|
||||
string PartitionName = System.IO.Path.GetFileNameWithoutExtension(Entry.Name);
|
||||
int P = PartitionName.IndexOf('.');
|
||||
if (P >= 0)
|
||||
{
|
||||
// Determine if there is a partition layout present
|
||||
ZipArchiveEntry PartitionEntry = Archive.GetEntry("Partitions.xml");
|
||||
if (PartitionEntry == null)
|
||||
{
|
||||
GPT.MergePartitions(null, false, Archive);
|
||||
GPTChanged |= GPT.HasChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (Stream ZipStream = PartitionEntry.Open())
|
||||
{
|
||||
using (StreamReader ZipReader = new StreamReader(ZipStream))
|
||||
{
|
||||
string PartitionXml = ZipReader.ReadToEnd();
|
||||
GPT.MergePartitions(PartitionXml, false, Archive);
|
||||
GPTChanged |= GPT.HasChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First determine if we need a new GPT!
|
||||
if (!Entry.FullName.Contains("/")) // No subfolders
|
||||
{
|
||||
string PartitionName = System.IO.Path.GetFileNameWithoutExtension(Entry.Name);
|
||||
int P = PartitionName.IndexOf('.');
|
||||
if (P >= 0)
|
||||
PartitionName = PartitionName.Substring(0, P); // Example: Data.bin.gz -> Data
|
||||
Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, PartitionName, true) == 0).FirstOrDefault();
|
||||
if (Partition != null)
|
||||
{
|
||||
DecompressedStream DecompressedStream = new DecompressedStream(Entry.Open());
|
||||
ulong StreamLengthInSectors = (ulong)Entry.Length / 0x200;
|
||||
try
|
||||
{
|
||||
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
||||
}
|
||||
catch { }
|
||||
|
||||
TotalSizeSectors += StreamLengthInSectors;
|
||||
PartitionCount++;
|
||||
|
||||
if (string.Compare(PartitionName, "MainOS", true) == 0)
|
||||
{
|
||||
MainOSOldSectorCount = Partition.SizeInSectors;
|
||||
MainOSNewSectorCount = StreamLengthInSectors;
|
||||
FirstMainOSSector = Partition.FirstSector;
|
||||
}
|
||||
else if (string.Compare(PartitionName, "Data", true) == 0)
|
||||
{
|
||||
DataOldSectorCount = Partition.SizeInSectors;
|
||||
DataNewSectorCount = StreamLengthInSectors;
|
||||
}
|
||||
else if (StreamLengthInSectors > Partition.SizeInSectors)
|
||||
{
|
||||
LogFile.Log("Flash failed! Size of partition '" + PartitionName + "' is too big.");
|
||||
ExitFailure("Flash failed!", "Size of partition '" + PartitionName + "' is too big.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
PartitionName = PartitionName.Substring(0, P); // Example: Data.bin.gz -> Data
|
||||
}
|
||||
|
||||
if ((MainOSNewSectorCount > 0) && (DataNewSectorCount > 0))
|
||||
Partition Partition = GPT.Partitions.Find(p => string.Compare(p.Name, PartitionName, true) == 0);
|
||||
if (Partition != null)
|
||||
{
|
||||
if ((MainOSNewSectorCount > MainOSOldSectorCount) || (DataNewSectorCount > DataOldSectorCount))
|
||||
DecompressedStream DecompressedStream = new(Entry.Open());
|
||||
ulong StreamLengthInSectors = (ulong)Entry.Length / 0x200;
|
||||
try
|
||||
{
|
||||
UInt64 OSSpace = GPT.LastUsableSector - FirstMainOSSector + 1;
|
||||
if ((MainOSNewSectorCount + DataNewSectorCount) <= OSSpace)
|
||||
{
|
||||
// MainOS and Data partitions need to be re-aligned!
|
||||
Partition MainOSPartition = GPT.Partitions.Where(p => string.Compare(p.Name, "MainOS", true) == 0).Single();
|
||||
Partition DataPartition = GPT.Partitions.Where(p => string.Compare(p.Name, "Data", true) == 0).Single();
|
||||
MainOSPartition.LastSector = MainOSPartition.FirstSector + MainOSNewSectorCount - 1;
|
||||
DataPartition.FirstSector = MainOSPartition.LastSector + 1;
|
||||
DataPartition.LastSector = DataPartition.FirstSector + DataNewSectorCount - 1;
|
||||
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
||||
}
|
||||
catch { }
|
||||
|
||||
GPTChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Flash failed! Size of partitions 'MainOS' and 'Data' together are too big.");
|
||||
ExitFailure("Flash failed!", "Sizes of partitions 'MainOS' and 'Data' together are too big.");
|
||||
return;
|
||||
}
|
||||
TotalSizeSectors += StreamLengthInSectors;
|
||||
PartitionCount++;
|
||||
|
||||
if (string.Compare(PartitionName, "MainOS", true) == 0)
|
||||
{
|
||||
MainOSOldSectorCount = Partition.SizeInSectors;
|
||||
MainOSNewSectorCount = StreamLengthInSectors;
|
||||
FirstMainOSSector = Partition.FirstSector;
|
||||
}
|
||||
else if (string.Compare(PartitionName, "Data", true) == 0)
|
||||
{
|
||||
DataOldSectorCount = Partition.SizeInSectors;
|
||||
DataNewSectorCount = StreamLengthInSectors;
|
||||
}
|
||||
else if (StreamLengthInSectors > Partition.SizeInSectors)
|
||||
{
|
||||
LogFile.Log("Flash failed! Size of partition '" + PartitionName + "' is too big.");
|
||||
ExitFailure("Flash failed!", "Size of partition '" + PartitionName + "' is too big.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((MainOSNewSectorCount > 0) && (MainOSNewSectorCount > MainOSOldSectorCount))
|
||||
}
|
||||
}
|
||||
|
||||
if ((MainOSNewSectorCount > 0) && (DataNewSectorCount > 0))
|
||||
{
|
||||
if ((MainOSNewSectorCount > MainOSOldSectorCount) || (DataNewSectorCount > DataOldSectorCount))
|
||||
{
|
||||
UInt64 OSSpace = GPT.LastUsableSector - FirstMainOSSector + 1;
|
||||
if ((MainOSNewSectorCount + DataNewSectorCount) <= OSSpace)
|
||||
{
|
||||
LogFile.Log("Flash failed! Size of partition 'MainOS' is too big.");
|
||||
ExitFailure("Flash failed!", "Size of partition 'MainOS' is too big.");
|
||||
return;
|
||||
}
|
||||
else if ((DataNewSectorCount > 0) && (DataNewSectorCount > DataOldSectorCount))
|
||||
{
|
||||
LogFile.Log("Flash failed! Size of partition 'Data' is too big.");
|
||||
ExitFailure("Flash failed!", "Size of partition 'Data' is too big.");
|
||||
return;
|
||||
}
|
||||
// MainOS and Data partitions need to be re-aligned!
|
||||
Partition MainOSPartition = GPT.Partitions.Single(p => string.Compare(p.Name, "MainOS", true) == 0);
|
||||
Partition DataPartition = GPT.Partitions.Single(p => string.Compare(p.Name, "Data", true) == 0);
|
||||
MainOSPartition.LastSector = MainOSPartition.FirstSector + MainOSNewSectorCount - 1;
|
||||
DataPartition.FirstSector = MainOSPartition.LastSector + 1;
|
||||
DataPartition.LastSector = DataPartition.FirstSector + DataNewSectorCount - 1;
|
||||
|
||||
if (GPTChanged)
|
||||
Phone.WriteGPT(GPT);
|
||||
|
||||
if (PartitionCount > 0)
|
||||
{
|
||||
BusyViewModel Busy = new BusyViewModel("Flashing...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
ProgressUpdater Updater = Busy.ProgressUpdater;
|
||||
ActivateSubContext(Busy);
|
||||
|
||||
int i = 0;
|
||||
|
||||
foreach (ZipArchiveEntry Entry in Archive.Entries)
|
||||
{
|
||||
// "MainOS.bin.gz" => "MainOS"
|
||||
string PartitionName = Entry.Name;
|
||||
int Pos = PartitionName.IndexOf('.');
|
||||
if (Pos >= 0)
|
||||
PartitionName = PartitionName.Substring(0, Pos);
|
||||
|
||||
Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, PartitionName, true) == 0).FirstOrDefault();
|
||||
if (Partition != null)
|
||||
{
|
||||
Stream DecompressedStream = new DecompressedStream(Entry.Open());
|
||||
ulong StreamLengthInSectors = (ulong)Entry.Length / 0x200;
|
||||
try
|
||||
{
|
||||
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (StreamLengthInSectors <= Partition.SizeInSectors)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Flashing partition " + Partition.Name + " (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Phone.FlashRawPartition(DecompressedStream, Partition.Name, Updater);
|
||||
}
|
||||
DecompressedStream.Close();
|
||||
}
|
||||
}
|
||||
GPTChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Flash failed! No valid partitions found in the archive.");
|
||||
ExitFailure("Flash failed!", "No valid partitions found in the archive");
|
||||
LogFile.Log("Flash failed! Size of partitions 'MainOS' and 'Data' together are too big.");
|
||||
ExitFailure("Flash failed!", "Sizes of partitions 'MainOS' and 'Data' together are too big.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((MainOSNewSectorCount > 0) && (MainOSNewSectorCount > MainOSOldSectorCount))
|
||||
{
|
||||
LogFile.Log("Flash failed! Size of partition 'MainOS' is too big.");
|
||||
ExitFailure("Flash failed!", "Size of partition 'MainOS' is too big.");
|
||||
return;
|
||||
}
|
||||
else if ((DataNewSectorCount > 0) && (DataNewSectorCount > DataOldSectorCount))
|
||||
{
|
||||
LogFile.Log("Flash failed! Size of partition 'Data' is too big.");
|
||||
ExitFailure("Flash failed!", "Size of partition 'Data' is too big.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GPTChanged)
|
||||
{
|
||||
Phone.WriteGPT(GPT);
|
||||
}
|
||||
|
||||
if (PartitionCount > 0)
|
||||
{
|
||||
BusyViewModel Busy = new("Flashing...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
ProgressUpdater Updater = Busy.ProgressUpdater;
|
||||
ActivateSubContext(Busy);
|
||||
|
||||
int i = 0;
|
||||
|
||||
foreach (ZipArchiveEntry Entry in Archive.Entries)
|
||||
{
|
||||
// "MainOS.bin.gz" => "MainOS"
|
||||
string PartitionName = Entry.Name;
|
||||
int Pos = PartitionName.IndexOf('.');
|
||||
if (Pos >= 0)
|
||||
{
|
||||
PartitionName = PartitionName.Substring(0, Pos);
|
||||
}
|
||||
|
||||
Partition Partition = GPT.Partitions.Find(p => string.Compare(p.Name, PartitionName, true) == 0);
|
||||
if (Partition != null)
|
||||
{
|
||||
Stream DecompressedStream = new DecompressedStream(Entry.Open());
|
||||
ulong StreamLengthInSectors = (ulong)Entry.Length / 0x200;
|
||||
try
|
||||
{
|
||||
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (StreamLengthInSectors <= Partition.SizeInSectors)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Flashing partition " + Partition.Name + " (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.FlashRawPartition(DecompressedStream, Partition.Name, Updater);
|
||||
}
|
||||
DecompressedStream.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Flash failed! No valid partitions found in the archive.");
|
||||
ExitFailure("Flash failed!", "No valid partitions found in the archive");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
@@ -460,7 +465,10 @@ namespace WPinternals
|
||||
ExitFailure("Flash failed!", ((WPinternalsException)Ex).SubMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitFailure("Flash failed!", null);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -506,9 +514,9 @@ namespace WPinternals
|
||||
if (Info.FlashAppProtocolVersionMajor >= 2)
|
||||
{
|
||||
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(Phone, 0x20000); // TODO: Get proper profile FFU and get ChunkSizeInBytes
|
||||
GPT GPT = new GPT(GPTChunk);
|
||||
GPT GPT = new(GPTChunk);
|
||||
FlashPart Part;
|
||||
List<FlashPart> FlashParts = new List<FlashPart>();
|
||||
List<FlashPart> FlashParts = new();
|
||||
|
||||
Partition NvBackupPartition = GPT.GetPartition("BACKUP_BS_NV");
|
||||
if (NvBackupPartition != null)
|
||||
@@ -521,9 +529,11 @@ namespace WPinternals
|
||||
GPT.Partitions.Remove(NvPartition);
|
||||
|
||||
GPT.Rebuild();
|
||||
Part = new FlashPart();
|
||||
Part.StartSector = 0;
|
||||
Part.Stream = new MemoryStream(GPTChunk);
|
||||
Part = new FlashPart
|
||||
{
|
||||
StartSector = 0,
|
||||
Stream = new MemoryStream(GPTChunk)
|
||||
};
|
||||
FlashParts.Add(Part);
|
||||
}
|
||||
|
||||
@@ -550,26 +560,40 @@ namespace WPinternals
|
||||
SetWorkingStatus: (m, s, v, a, st) =>
|
||||
{
|
||||
if ((st == WPinternalsStatus.Scanning) || (st == WPinternalsStatus.WaitingForManualReset))
|
||||
{
|
||||
SetWorkingStatus(m, s, v, a, st);
|
||||
}
|
||||
else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
|
||||
{
|
||||
SetWorkingStatus("Restoring bootloader...", null, null, Status: WPinternalsStatus.Flashing);
|
||||
}
|
||||
|
||||
LastStatus = st;
|
||||
},
|
||||
UpdateWorkingStatus: (m, s, v, st) =>
|
||||
{
|
||||
if ((st == WPinternalsStatus.Scanning) || (st == WPinternalsStatus.WaitingForManualReset))
|
||||
{
|
||||
UpdateWorkingStatus(m, s, v, st);
|
||||
}
|
||||
else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
|
||||
{
|
||||
SetWorkingStatus("Restoring bootloader...", null, null, Status: WPinternalsStatus.Flashing);
|
||||
}
|
||||
|
||||
LastStatus = st;
|
||||
}
|
||||
).Wait();
|
||||
|
||||
if ((PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) && (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash))
|
||||
{
|
||||
PhoneNotifier.WaitForArrival().Wait();
|
||||
}
|
||||
|
||||
if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||
{
|
||||
((NokiaFlashModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,23 +607,28 @@ namespace WPinternals
|
||||
|
||||
try
|
||||
{
|
||||
FFU FFU = new FFU(FFUPath);
|
||||
BusyViewModel Busy = new BusyViewModel("Flashing original FFU...", MaxProgressValue: FFU.TotalChunkCount, UIContext: UIContext);
|
||||
FFU FFU = new(FFUPath);
|
||||
BusyViewModel Busy = new("Flashing original FFU...", MaxProgressValue: FFU.TotalChunkCount, UIContext: UIContext);
|
||||
ActivateSubContext(Busy);
|
||||
byte Options = 0;
|
||||
if (!Info.IsBootloaderSecure)
|
||||
{
|
||||
Options = (byte)((FlashOptions)Options | FlashOptions.SkipSignatureCheck);
|
||||
}
|
||||
|
||||
Phone.FlashFFU(FFU, Busy.ProgressUpdater, true, Options);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
if (Ex is WPinternalsException)
|
||||
{
|
||||
ErrorSubMessage = ((WPinternalsException)Ex).SubMessage;
|
||||
}
|
||||
|
||||
Result = false;
|
||||
}
|
||||
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
ExitFailure("Flash failed!", ErrorSubMessage);
|
||||
@@ -631,7 +660,9 @@ namespace WPinternals
|
||||
{
|
||||
NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;
|
||||
if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||
{
|
||||
Phone.SwitchToFlashAppContext();
|
||||
}
|
||||
|
||||
new Thread(() =>
|
||||
{
|
||||
@@ -643,11 +674,11 @@ namespace WPinternals
|
||||
|
||||
try
|
||||
{
|
||||
FileInfo info = new FileInfo(MMOSPath);
|
||||
FileInfo info = new(MMOSPath);
|
||||
uint length = uint.Parse(info.Length.ToString());
|
||||
int maximumbuffersize = 0x00240000;
|
||||
const int maximumbuffersize = 0x00240000;
|
||||
uint totalcounts = (uint)Math.Truncate((decimal)length / maximumbuffersize);
|
||||
BusyViewModel Busy = new BusyViewModel("Flashing Test Mode package...", MaxProgressValue: totalcounts, UIContext: UIContext);
|
||||
BusyViewModel Busy = new("Flashing Test Mode package...", MaxProgressValue: totalcounts, UIContext: UIContext);
|
||||
ActivateSubContext(Busy);
|
||||
|
||||
Phone.FlashMMOS(MMOSPath, Busy.ProgressUpdater);
|
||||
@@ -660,7 +691,10 @@ namespace WPinternals
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
if (Ex is WPinternalsException)
|
||||
{
|
||||
ErrorSubMessage = ((WPinternalsException)Ex).SubMessage;
|
||||
}
|
||||
|
||||
Result = false;
|
||||
}
|
||||
|
||||
@@ -713,7 +747,7 @@ namespace WPinternals
|
||||
|
||||
internal void ExitSuccess(string Message, string SubMessage)
|
||||
{
|
||||
MessageViewModel SuccessMessageViewModel = new MessageViewModel(Message, () =>
|
||||
MessageViewModel SuccessMessageViewModel = new(Message, () =>
|
||||
{
|
||||
// No need to call Exit() to go to normal mode, because it already switches to normal mode automatically.
|
||||
IsSwitchingInterface = false; // From here on a device will be forced to Flash mode again on this screen which is meant for flashing
|
||||
@@ -726,7 +760,7 @@ namespace WPinternals
|
||||
|
||||
internal void ExitFailure(string Message, string SubMessage)
|
||||
{
|
||||
MessageViewModel ErrorMessageViewModel = new MessageViewModel(Message, () =>
|
||||
MessageViewModel ErrorMessageViewModel = new(Message, () =>
|
||||
{
|
||||
IsSwitchingInterface = false;
|
||||
Callback();
|
||||
|
||||
Reference in New Issue
Block a user