mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-06-16 04:10:11 +10:00
Project Maintenance
This commit is contained in:
@@ -25,10 +25,10 @@ namespace WPinternals
|
||||
{
|
||||
internal class BackupTargetSelectionViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action<string, string, string> BackupCallback;
|
||||
private Action<string> BackupArchiveCallback;
|
||||
private Action<string> BackupArchiveProvisioningCallback;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly Action<string, string, string> BackupCallback;
|
||||
private readonly Action<string> BackupArchiveCallback;
|
||||
private readonly Action<string> BackupArchiveProvisioningCallback;
|
||||
internal Action SwitchToUnlockBoot;
|
||||
|
||||
internal BackupTargetSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action<string> BackupArchiveCallback, Action<string, string, string> BackupCallback, Action<string> BackupArchiveProvisioningCallback)
|
||||
@@ -58,7 +58,7 @@ namespace WPinternals
|
||||
if (value != _ArchivePath)
|
||||
{
|
||||
_ArchivePath = value;
|
||||
OnPropertyChanged("ArchivePath");
|
||||
OnPropertyChanged(nameof(ArchivePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ namespace WPinternals
|
||||
if (value != _EFIESPPath)
|
||||
{
|
||||
_EFIESPPath = value;
|
||||
OnPropertyChanged("EFIESPPath");
|
||||
OnPropertyChanged(nameof(EFIESPPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ namespace WPinternals
|
||||
if (value != _MainOSPath)
|
||||
{
|
||||
_MainOSPath = value;
|
||||
OnPropertyChanged("MainOSPath");
|
||||
OnPropertyChanged(nameof(MainOSPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,7 @@ namespace WPinternals
|
||||
if (value != _DataPath)
|
||||
{
|
||||
_DataPath = value;
|
||||
OnPropertyChanged("DataPath");
|
||||
OnPropertyChanged(nameof(DataPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,7 @@ namespace WPinternals
|
||||
if (value != _ArchiveProvisioningPath)
|
||||
{
|
||||
_ArchiveProvisioningPath = value;
|
||||
OnPropertyChanged("ArchiveProvisioningPath");
|
||||
OnPropertyChanged(nameof(ArchiveProvisioningPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneDisconnected)
|
||||
{
|
||||
_IsPhoneDisconnected = value;
|
||||
OnPropertyChanged("IsPhoneDisconnected");
|
||||
OnPropertyChanged(nameof(IsPhoneDisconnected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,7 +160,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInMassStorage)
|
||||
{
|
||||
_IsPhoneInMassStorage = value;
|
||||
OnPropertyChanged("IsPhoneInMassStorage");
|
||||
OnPropertyChanged(nameof(IsPhoneInMassStorage));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,7 +177,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInOtherMode)
|
||||
{
|
||||
_IsPhoneInOtherMode = value;
|
||||
OnPropertyChanged("IsPhoneInOtherMode");
|
||||
OnPropertyChanged(nameof(IsPhoneInOtherMode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,11 +187,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_BackupArchiveCommand == null)
|
||||
{
|
||||
_BackupArchiveCommand = new DelegateCommand(() => { BackupArchiveCallback(ArchivePath); }, () => ((ArchivePath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _BackupArchiveCommand;
|
||||
return _BackupArchiveCommand ??= new DelegateCommand(() => BackupArchiveCallback(ArchivePath), () => ((ArchivePath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,11 +196,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_BackupCommand == null)
|
||||
{
|
||||
_BackupCommand = new DelegateCommand(() => { BackupCallback(EFIESPPath, MainOSPath, DataPath); }, () => (((EFIESPPath != null) || (MainOSPath != null) || (DataPath != null)) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _BackupCommand;
|
||||
return _BackupCommand ??= new DelegateCommand(() => BackupCallback(EFIESPPath, MainOSPath, DataPath), () => (((EFIESPPath != null) || (MainOSPath != null) || (DataPath != null)) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,11 +205,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_BackupArchiveProvisioningCommand == null)
|
||||
{
|
||||
_BackupArchiveProvisioningCommand = new DelegateCommand(() => { BackupArchiveProvisioningCallback(ArchiveProvisioningPath); }, () => ((ArchiveProvisioningPath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _BackupArchiveProvisioningCommand;
|
||||
return _BackupArchiveProvisioningCommand ??= new DelegateCommand(() => BackupArchiveProvisioningCallback(ArchiveProvisioningPath), () => ((ArchiveProvisioningPath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,12 +214,12 @@ namespace WPinternals
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrived;
|
||||
}
|
||||
|
||||
void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
new Thread(() => EvaluateViewState()).Start();
|
||||
}
|
||||
|
||||
void DeviceRemoved()
|
||||
private void DeviceRemoved()
|
||||
{
|
||||
new Thread(() => EvaluateViewState()).Start();
|
||||
}
|
||||
|
||||
+117
-125
@@ -28,9 +28,9 @@ namespace WPinternals
|
||||
{
|
||||
internal class BackupViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action Callback;
|
||||
private Action SwitchToUnlockBoot;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly Action Callback;
|
||||
private readonly Action SwitchToUnlockBoot;
|
||||
|
||||
internal BackupViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action Callback)
|
||||
: base()
|
||||
@@ -45,7 +45,9 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SubContextViewModel == null)
|
||||
{
|
||||
@@ -54,7 +56,9 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
if (SubContextViewModel is BackupTargetSelectionViewModel)
|
||||
{
|
||||
((BackupTargetSelectionViewModel)SubContextViewModel).EvaluateViewState();
|
||||
}
|
||||
}
|
||||
|
||||
internal async void DoBackup(string EFIESPPath, string MainOSPath, string DataPath)
|
||||
@@ -118,27 +122,27 @@ namespace WPinternals
|
||||
|
||||
Phone.OpenVolume(false);
|
||||
byte[] GPTBuffer = Phone.ReadSectors(1, 33);
|
||||
GPT GPT = new WPinternals.GPT(GPTBuffer);
|
||||
GPT GPT = new(GPTBuffer);
|
||||
Partition Partition;
|
||||
try
|
||||
{
|
||||
if (EFIESPPath != null)
|
||||
{
|
||||
Partition = GPT.Partitions.Where(p => p.Name == "EFIESP").First();
|
||||
Partition = GPT.Partitions.First(p => p.Name == "EFIESP");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
PartitionCount++;
|
||||
}
|
||||
|
||||
if (MainOSPath != null)
|
||||
{
|
||||
Partition = GPT.Partitions.Where(p => p.Name == "MainOS").First();
|
||||
Partition = GPT.Partitions.First(p => p.Name == "MainOS");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
PartitionCount++;
|
||||
}
|
||||
|
||||
if (DataPath != null)
|
||||
{
|
||||
Partition = GPT.Partitions.Where(p => p.Name == "Data").First();
|
||||
Partition = GPT.Partitions.First(p => p.Name == "Data");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
PartitionCount++;
|
||||
}
|
||||
@@ -149,7 +153,7 @@ namespace WPinternals
|
||||
Result = false;
|
||||
}
|
||||
|
||||
BusyViewModel Busy = new BusyViewModel("Create backup...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
BusyViewModel Busy = new("Create backup...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
ProgressUpdater Updater = Busy.ProgressUpdater;
|
||||
ActivateSubContext(Busy);
|
||||
|
||||
@@ -161,7 +165,7 @@ namespace WPinternals
|
||||
if (EFIESPPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Create backup of partition EFIESP (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("EFIESP", EFIESPPath, Updater);
|
||||
}
|
||||
}
|
||||
@@ -179,7 +183,7 @@ namespace WPinternals
|
||||
if (MainOSPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Create backup of partition MainOS (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("MainOS", MainOSPath, Updater);
|
||||
}
|
||||
}
|
||||
@@ -197,7 +201,7 @@ namespace WPinternals
|
||||
if (DataPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Create backup of partition Data (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("Data", DataPath, Updater);
|
||||
}
|
||||
}
|
||||
@@ -230,7 +234,7 @@ namespace WPinternals
|
||||
ActivateSubContext(new BusyViewModel("Initializing backup..."));
|
||||
|
||||
ulong TotalSizeSectors = 0;
|
||||
int PartitionCount = 3;
|
||||
const int PartitionCount = 3;
|
||||
|
||||
MassStorage Phone = (MassStorage)PhoneNotifier.CurrentModel;
|
||||
|
||||
@@ -238,19 +242,19 @@ namespace WPinternals
|
||||
{
|
||||
Phone.OpenVolume(false);
|
||||
byte[] GPTBuffer = Phone.ReadSectors(1, 33);
|
||||
GPT GPT = new WPinternals.GPT(GPTBuffer);
|
||||
GPT GPT = new(GPTBuffer);
|
||||
|
||||
Partition Partition;
|
||||
|
||||
try
|
||||
{
|
||||
Partition = GPT.Partitions.Where(p => p.Name == "EFIESP").First();
|
||||
Partition = GPT.Partitions.First(p => p.Name == "EFIESP");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
|
||||
Partition = GPT.Partitions.Where(p => p.Name == "MainOS").First();
|
||||
Partition = GPT.Partitions.First(p => p.Name == "MainOS");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
|
||||
Partition = GPT.Partitions.Where(p => p.Name == "Data").First();
|
||||
Partition = GPT.Partitions.First(p => p.Name == "Data");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
}
|
||||
catch (Exception Ex)
|
||||
@@ -259,86 +263,79 @@ namespace WPinternals
|
||||
Result = false;
|
||||
}
|
||||
|
||||
BusyViewModel Busy = new BusyViewModel("Create backup...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
BusyViewModel Busy = new("Create backup...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
ProgressUpdater Updater = Busy.ProgressUpdater;
|
||||
ActivateSubContext(Busy);
|
||||
ZipArchiveEntry Entry;
|
||||
Stream EntryStream = null;
|
||||
|
||||
using (FileStream FileStream = new FileStream(ArchivePath, FileMode.Create))
|
||||
using FileStream FileStream = new(ArchivePath, FileMode.Create);
|
||||
using ZipArchive Archive = new(FileStream, ZipArchiveMode.Create);
|
||||
int i = 0;
|
||||
|
||||
if (Result)
|
||||
{
|
||||
using (ZipArchive Archive = new ZipArchive(FileStream, ZipArchiveMode.Create))
|
||||
try
|
||||
{
|
||||
int i = 0;
|
||||
Entry = Archive.CreateEntry("EFIESP.bin", CompressionLevel.Optimal);
|
||||
EntryStream = Entry.Open();
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition EFIESP (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("EFIESP", EntryStream, Updater);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
Result = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
EntryStream?.Close();
|
||||
EntryStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (Result)
|
||||
{
|
||||
try
|
||||
{
|
||||
Entry = Archive.CreateEntry("EFIESP.bin", CompressionLevel.Optimal);
|
||||
EntryStream = Entry.Open();
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("EFIESP", EntryStream, Updater);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
Result = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (EntryStream != null)
|
||||
EntryStream.Close();
|
||||
EntryStream = null;
|
||||
}
|
||||
}
|
||||
if (Result)
|
||||
{
|
||||
try
|
||||
{
|
||||
Entry = Archive.CreateEntry("MainOS.bin", CompressionLevel.Optimal);
|
||||
EntryStream = Entry.Open();
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition MainOS (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("MainOS", EntryStream, Updater);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
Result = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
EntryStream?.Close();
|
||||
EntryStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (Result)
|
||||
{
|
||||
try
|
||||
{
|
||||
Entry = Archive.CreateEntry("MainOS.bin", CompressionLevel.Optimal);
|
||||
EntryStream = Entry.Open();
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("MainOS", EntryStream, Updater);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
Result = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (EntryStream != null)
|
||||
EntryStream.Close();
|
||||
EntryStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (Result)
|
||||
{
|
||||
try
|
||||
{
|
||||
Entry = Archive.CreateEntry("Data.bin", CompressionLevel.Optimal);
|
||||
EntryStream = Entry.Open();
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("Data", EntryStream, Updater);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
Result = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (EntryStream != null)
|
||||
EntryStream.Close();
|
||||
EntryStream = null;
|
||||
}
|
||||
}
|
||||
if (Result)
|
||||
{
|
||||
try
|
||||
{
|
||||
Entry = Archive.CreateEntry("Data.bin", CompressionLevel.Optimal);
|
||||
EntryStream = Entry.Open();
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition Data (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.BackupPartition("Data", EntryStream, Updater);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
Result = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
EntryStream?.Close();
|
||||
EntryStream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,7 +395,7 @@ namespace WPinternals
|
||||
{
|
||||
Phone.OpenVolume(false);
|
||||
byte[] GPTBuffer = Phone.ReadSectors(1, 33);
|
||||
GPT GPT = new WPinternals.GPT(GPTBuffer);
|
||||
GPT GPT = new(GPTBuffer);
|
||||
|
||||
Partition Partition;
|
||||
|
||||
@@ -408,10 +405,10 @@ namespace WPinternals
|
||||
{
|
||||
if (GPT.Partitions.Any(p => p.Name == PartitionName))
|
||||
{
|
||||
Partition = GPT.Partitions.Where(p => p.Name == PartitionName).First();
|
||||
Partition = GPT.Partitions.First(p => p.Name == PartitionName);
|
||||
if (PartitionName == "UEFI_BS_NV" && GPT.Partitions.Any(p => p.Name == "BACKUP_BS_NV"))
|
||||
{
|
||||
Partition = GPT.Partitions.Where(p => p.Name == "BACKUP_BS_NV").First();
|
||||
Partition = GPT.Partitions.First(p => p.Name == "BACKUP_BS_NV");
|
||||
}
|
||||
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
@@ -425,51 +422,46 @@ namespace WPinternals
|
||||
Result = false;
|
||||
}
|
||||
|
||||
BusyViewModel Busy = new BusyViewModel("Create backup...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
BusyViewModel Busy = new("Create backup...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
ProgressUpdater Updater = Busy.ProgressUpdater;
|
||||
ActivateSubContext(Busy);
|
||||
ZipArchiveEntry Entry;
|
||||
Stream EntryStream = null;
|
||||
|
||||
using (FileStream FileStream = new FileStream(ArchiveProvisioningPath, FileMode.Create))
|
||||
{
|
||||
using (ZipArchive Archive = new ZipArchive(FileStream, ZipArchiveMode.Create))
|
||||
{
|
||||
int i = 0;
|
||||
using FileStream FileStream = new(ArchiveProvisioningPath, FileMode.Create);
|
||||
using ZipArchive Archive = new(FileStream, ZipArchiveMode.Create);
|
||||
int i = 0;
|
||||
|
||||
foreach (string PartitionName in ProvisioningPartitions)
|
||||
foreach (string PartitionName in ProvisioningPartitions)
|
||||
{
|
||||
if (GPT.Partitions.Any(p => p.Name == PartitionName))
|
||||
{
|
||||
if (Result)
|
||||
{
|
||||
if (GPT.Partitions.Any(p => p.Name == PartitionName))
|
||||
try
|
||||
{
|
||||
if (Result)
|
||||
Entry = Archive.CreateEntry(PartitionName + ".bin", CompressionLevel.Optimal);
|
||||
EntryStream = Entry.Open();
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition " + PartitionName + " (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
if (PartitionName == "UEFI_BS_NV" && GPT.Partitions.Any(p => p.Name == "BACKUP_BS_NV"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Entry = Archive.CreateEntry(PartitionName + ".bin", CompressionLevel.Optimal);
|
||||
EntryStream = Entry.Open();
|
||||
i++;
|
||||
Busy.Message = "Create backup of partition " + PartitionName + " (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
if (PartitionName == "UEFI_BS_NV" && GPT.Partitions.Any(p => p.Name == "BACKUP_BS_NV"))
|
||||
{
|
||||
Phone.BackupPartition("BACKUP_BS_NV", EntryStream, Updater);
|
||||
}
|
||||
else
|
||||
{
|
||||
Phone.BackupPartition(PartitionName, EntryStream, Updater);
|
||||
}
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
Result = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (EntryStream != null)
|
||||
EntryStream.Close();
|
||||
EntryStream = null;
|
||||
}
|
||||
Phone.BackupPartition("BACKUP_BS_NV", EntryStream, Updater);
|
||||
}
|
||||
else
|
||||
{
|
||||
Phone.BackupPartition(PartitionName, EntryStream, Updater);
|
||||
}
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
Result = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
EntryStream?.Close();
|
||||
EntryStream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-14
@@ -25,7 +25,7 @@ namespace WPinternals
|
||||
{
|
||||
internal class BusyViewModel : ContextViewModel
|
||||
{
|
||||
private ulong MaxProgressValue = 0;
|
||||
private readonly ulong MaxProgressValue = 0;
|
||||
internal ProgressUpdater ProgressUpdater = null;
|
||||
|
||||
// UIContext can be passed to BusyViewModel, when it needs to update progress-controls and it is created on a worker-thread.
|
||||
@@ -33,10 +33,7 @@ namespace WPinternals
|
||||
{
|
||||
LogFile.Log(Message);
|
||||
|
||||
if (UIContext == null)
|
||||
this.UIContext = SynchronizationContext.Current;
|
||||
else
|
||||
this.UIContext = UIContext;
|
||||
this.UIContext = UIContext ?? SynchronizationContext.Current;
|
||||
|
||||
this.Message = Message;
|
||||
this.SubMessage = SubMessage;
|
||||
@@ -73,7 +70,9 @@ namespace WPinternals
|
||||
internal void SetProgress(ulong Value)
|
||||
{
|
||||
if (ProgressUpdater != null)
|
||||
UIContext.Post((s) => { ProgressUpdater.SetProgress(Value); }, null);
|
||||
{
|
||||
UIContext.Post((s) => ProgressUpdater.SetProgress(Value), null);
|
||||
}
|
||||
}
|
||||
|
||||
private string _Message = null;
|
||||
@@ -86,7 +85,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Message = value;
|
||||
OnPropertyChanged("Message");
|
||||
OnPropertyChanged(nameof(Message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +99,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_SubMessage = value;
|
||||
OnPropertyChanged("SubMessage");
|
||||
OnPropertyChanged(nameof(SubMessage));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,8 +115,8 @@ namespace WPinternals
|
||||
if (_ProgressPercentage != value)
|
||||
{
|
||||
_ProgressPercentage = value;
|
||||
OnPropertyChanged("ProgressPercentage");
|
||||
OnPropertyChanged("ShowAnimation");
|
||||
OnPropertyChanged(nameof(ProgressPercentage));
|
||||
OnPropertyChanged(nameof(ShowAnimation));
|
||||
UpdateProgressText();
|
||||
}
|
||||
}
|
||||
@@ -135,7 +134,7 @@ namespace WPinternals
|
||||
if (_TimeRemaining != value)
|
||||
{
|
||||
_TimeRemaining = value;
|
||||
OnPropertyChanged("TimeRemaining");
|
||||
OnPropertyChanged(nameof(TimeRemaining));
|
||||
UpdateProgressText();
|
||||
}
|
||||
}
|
||||
@@ -151,9 +150,13 @@ namespace WPinternals
|
||||
if (TimeRemaining != null)
|
||||
{
|
||||
if (NewText == null)
|
||||
{
|
||||
NewText = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
NewText += " - ";
|
||||
}
|
||||
|
||||
NewText += "Estimated time remaining: " + ((TimeSpan)TimeRemaining).ToString(@"h\:mm\:ss");
|
||||
}
|
||||
@@ -172,7 +175,7 @@ namespace WPinternals
|
||||
if (_ProgressText != value)
|
||||
{
|
||||
_ProgressText = value;
|
||||
OnPropertyChanged("ProgressText");
|
||||
OnPropertyChanged(nameof(ProgressText));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +192,7 @@ namespace WPinternals
|
||||
if (_ShowAnimation != value)
|
||||
{
|
||||
_ShowAnimation = value;
|
||||
OnPropertyChanged("ShowAnimation");
|
||||
OnPropertyChanged(nameof(ShowAnimation));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -206,7 +209,7 @@ namespace WPinternals
|
||||
if (_ShowRebootHelp != value)
|
||||
{
|
||||
_ShowRebootHelp = value;
|
||||
OnPropertyChanged("ShowRebootHelp");
|
||||
OnPropertyChanged(nameof(ShowRebootHelp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,19 +30,22 @@ namespace WPinternals
|
||||
|
||||
public bool IsSwitchingInterface = false;
|
||||
public bool IsFlashModeOperation = false;
|
||||
private bool _IsActive = false;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged = delegate { };
|
||||
|
||||
protected void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
if ((UIContext == null) && (SynchronizationContext.Current != null))
|
||||
{
|
||||
UIContext = SynchronizationContext.Current;
|
||||
}
|
||||
|
||||
if (this.PropertyChanged != null)
|
||||
{
|
||||
if (SynchronizationContext.Current == UIContext)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
else
|
||||
{
|
||||
UIContext.Post((s) => PropertyChanged(this, new PropertyChangedEventArgs(propertyName)), null);
|
||||
@@ -60,11 +63,17 @@ namespace WPinternals
|
||||
private set
|
||||
{
|
||||
if (_SubContextViewModel != null)
|
||||
{
|
||||
_SubContextViewModel.IsActive = false;
|
||||
}
|
||||
|
||||
_SubContextViewModel = value;
|
||||
if (_SubContextViewModel != null)
|
||||
{
|
||||
_SubContextViewModel.IsActive = IsActive;
|
||||
OnPropertyChanged("SubContextViewModel");
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(SubContextViewModel));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,41 +91,36 @@ namespace WPinternals
|
||||
SubContextViewModel = SubContext;
|
||||
}
|
||||
|
||||
internal bool IsActive
|
||||
{
|
||||
get
|
||||
{
|
||||
return _IsActive;
|
||||
}
|
||||
set
|
||||
{
|
||||
_IsActive = value;
|
||||
}
|
||||
}
|
||||
internal bool IsActive { get; set; } = false;
|
||||
|
||||
internal virtual void EvaluateViewState()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal void Activate()
|
||||
{
|
||||
IsActive = true;
|
||||
EvaluateViewState();
|
||||
if (SubContextViewModel != null)
|
||||
SubContextViewModel.Activate();
|
||||
SubContextViewModel?.Activate();
|
||||
}
|
||||
|
||||
internal void ActivateSubContext(ContextViewModel NewSubContext)
|
||||
{
|
||||
if (_SubContextViewModel != null)
|
||||
{
|
||||
_SubContextViewModel.IsActive = false;
|
||||
}
|
||||
|
||||
if (NewSubContext != null)
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
NewSubContext.Activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
NewSubContext.IsActive = false;
|
||||
}
|
||||
}
|
||||
SubContextViewModel = NewSubContext;
|
||||
}
|
||||
@@ -128,9 +132,8 @@ namespace WPinternals
|
||||
|
||||
internal void UpdateWorkingStatus(string Message, string SubMessage, ulong? CurrentProgressValue, WPinternalsStatus Status = WPinternalsStatus.Undefined)
|
||||
{
|
||||
if (SubContextViewModel is BusyViewModel)
|
||||
if (SubContextViewModel is BusyViewModel Busy)
|
||||
{
|
||||
BusyViewModel Busy = (BusyViewModel)SubContextViewModel;
|
||||
if (Message != null)
|
||||
{
|
||||
Busy.Message = Message;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace WPinternals
|
||||
{
|
||||
internal class DisclaimerAndNdaViewModel : ContextViewModel
|
||||
{
|
||||
Action Accepted;
|
||||
private readonly Action Accepted;
|
||||
|
||||
internal DisclaimerAndNdaViewModel(Action Accepted)
|
||||
: base()
|
||||
@@ -39,14 +39,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ExitCommand == null)
|
||||
{
|
||||
_ExitCommand = new DelegateCommand(() =>
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
});
|
||||
}
|
||||
return _ExitCommand;
|
||||
return _ExitCommand ??= new DelegateCommand(() => Application.Current.Shutdown());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,16 +48,12 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ContinueCommand == null)
|
||||
{
|
||||
_ContinueCommand = new DelegateCommand(() =>
|
||||
return _ContinueCommand ??= new DelegateCommand(() =>
|
||||
{
|
||||
Registry.CurrentUser.OpenSubKey("Software\\WPInternals", true).SetValue("DisclaimerAccepted", 1, RegistryValueKind.DWord);
|
||||
Registry.CurrentUser.OpenSubKey("Software\\WPInternals", true).SetValue("NdaAccepted", 1, RegistryValueKind.DWord);
|
||||
Accepted();
|
||||
});
|
||||
}
|
||||
return _ContinueCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace WPinternals
|
||||
|
||||
internal class DisclaimerViewModel : ContextViewModel
|
||||
{
|
||||
Action Accepted;
|
||||
private readonly Action Accepted;
|
||||
|
||||
internal DisclaimerViewModel(Action Accepted)
|
||||
: base()
|
||||
@@ -41,14 +41,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ExitCommand == null)
|
||||
{
|
||||
_ExitCommand = new DelegateCommand(() =>
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
});
|
||||
}
|
||||
return _ExitCommand;
|
||||
return _ExitCommand ??= new DelegateCommand(() => Application.Current.Shutdown());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,15 +50,11 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ContinueCommand == null)
|
||||
{
|
||||
_ContinueCommand = new DelegateCommand(() =>
|
||||
return _ContinueCommand ??= new DelegateCommand(() =>
|
||||
{
|
||||
Registry.CurrentUser.OpenSubKey("Software\\WPInternals", true).SetValue("DisclaimerAccepted", 1, RegistryValueKind.DWord);
|
||||
Accepted();
|
||||
});
|
||||
}
|
||||
return _ContinueCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+116
-110
@@ -34,8 +34,8 @@ namespace WPinternals
|
||||
{
|
||||
internal class DownloadsViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel Notifier;
|
||||
private Timer SpeedTimer;
|
||||
private readonly PhoneNotifierViewModel Notifier;
|
||||
private readonly Timer SpeedTimer;
|
||||
private bool IsSearching = false;
|
||||
|
||||
internal DownloadsViewModel(PhoneNotifierViewModel Notifier)
|
||||
@@ -45,9 +45,8 @@ namespace WPinternals
|
||||
this.Notifier = Notifier;
|
||||
Notifier.NewDeviceArrived += Notifier_NewDeviceArrived;
|
||||
|
||||
RegistryKey Key = Registry.CurrentUser.OpenSubKey(@"Software\WPInternals", true);
|
||||
if (Key == null)
|
||||
Key = Registry.CurrentUser.CreateSubKey(@"Software\WPInternals");
|
||||
RegistryKey Key = Registry.CurrentUser.OpenSubKey(@"Software\WPInternals", true) ?? Registry.CurrentUser.CreateSubKey(@"Software\WPInternals");
|
||||
|
||||
DownloadFolder = (string)Key.GetValue("DownloadFolder", @"C:\ProgramData\WPinternals\Repository");
|
||||
Key.Close();
|
||||
|
||||
@@ -57,7 +56,7 @@ namespace WPinternals
|
||||
{
|
||||
string FFUPath = null;
|
||||
|
||||
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
|
||||
OpenFileDialog dlg = new();
|
||||
dlg.DefaultExt = ".ffu"; // Default file extension
|
||||
dlg.Filter = "ROM images (.ffu)|*.ffu"; // Filter files by extension
|
||||
|
||||
@@ -82,7 +81,6 @@ namespace WPinternals
|
||||
{
|
||||
LastStatusText = "Error: File \"" + FFUFile + "\" was not added.";
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -101,7 +99,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_LastStatusText = value;
|
||||
OnPropertyChanged("LastStatusText");
|
||||
OnPropertyChanged(nameof(LastStatusText));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,12 +114,12 @@ namespace WPinternals
|
||||
int Count = (int)((Entry.SpeedIndex + 1) > 10 ? 10 : (Entry.SpeedIndex + 1));
|
||||
long Sum = 0;
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
Sum += Entry.Speeds[i];
|
||||
}
|
||||
|
||||
Entry.Speed = Sum / Count;
|
||||
if (Entry.Speed < 1000)
|
||||
Entry.TimeLeft = Timeout.InfiniteTimeSpan;
|
||||
else
|
||||
Entry.TimeLeft = TimeSpan.FromSeconds((Entry.Size - Entry.BytesReceived) / Entry.Speed);
|
||||
Entry.TimeLeft = Entry.Speed < 1000 ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds((Entry.Size - Entry.BytesReceived) / Entry.Speed);
|
||||
}
|
||||
Entry.LastBytesReceived = Entry.BytesReceived;
|
||||
Entry.SpeedIndex++;
|
||||
@@ -139,7 +137,7 @@ namespace WPinternals
|
||||
HttpWebRequest req = (HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
|
||||
req.Method = "HEAD";
|
||||
req.ServicePoint.ConnectionLimit = 10;
|
||||
using (System.Net.WebResponse resp = req.GetResponse())
|
||||
using (WebResponse resp = req.GetResponse())
|
||||
{
|
||||
long.TryParse(resp.Headers.Get("Content-Length"), out Length);
|
||||
}
|
||||
@@ -151,14 +149,19 @@ namespace WPinternals
|
||||
string FileName = System.IO.Path.GetFileName(URL);
|
||||
int End = FileName.IndexOf('?');
|
||||
if (End >= 0)
|
||||
{
|
||||
FileName = FileName.Substring(0, End);
|
||||
}
|
||||
|
||||
return FileName;
|
||||
}
|
||||
|
||||
private void Search()
|
||||
{
|
||||
if (IsSearching)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IsSearching = true;
|
||||
|
||||
@@ -172,23 +175,36 @@ namespace WPinternals
|
||||
try
|
||||
{
|
||||
string TempProductType = ProductType.ToUpper();
|
||||
if ((TempProductType != null) && TempProductType.StartsWith("RM") && !TempProductType.StartsWith("RM-"))
|
||||
TempProductType = "RM-" + TempProductType.Substring(2);
|
||||
if ((TempProductType?.StartsWith("RM") == true) && !TempProductType.StartsWith("RM-"))
|
||||
{
|
||||
TempProductType = "RM-" + TempProductType[2..];
|
||||
}
|
||||
|
||||
ProductType = TempProductType;
|
||||
FFUURL = LumiaDownloadModel.SearchFFU(ProductType, ProductCode, OperatorCode, out TempProductType);
|
||||
if (TempProductType != null)
|
||||
{
|
||||
ProductType = TempProductType;
|
||||
}
|
||||
|
||||
if (ProductType != null)
|
||||
{
|
||||
EmergencyURLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
UIContext.Post(s =>
|
||||
{
|
||||
if (FFUURL != null)
|
||||
{
|
||||
SearchResultList.Add(new SearchResult(FFUURL, ProductType, FFUDownloaded, null));
|
||||
}
|
||||
|
||||
if (EmergencyURLs != null)
|
||||
{
|
||||
SearchResultList.Add(new SearchResult(ProductType + " emergency-files", EmergencyURLs, ProductType, EmergencyDownloaded, ProductType));
|
||||
}
|
||||
}, null);
|
||||
|
||||
IsSearching = false;
|
||||
@@ -197,23 +213,17 @@ namespace WPinternals
|
||||
|
||||
internal void Download(string URL, string Category, Action<string[], object> Callback, object State = null)
|
||||
{
|
||||
string Folder;
|
||||
if (Category == null)
|
||||
Folder = DownloadFolder;
|
||||
else
|
||||
Folder = Path.Combine(DownloadFolder, Category);
|
||||
string Folder = Category == null ? DownloadFolder : Path.Combine(DownloadFolder, Category);
|
||||
DownloadList.Add(new DownloadEntry(URL, Folder, null, Callback, State));
|
||||
}
|
||||
|
||||
internal void Download(string[] URLs, string Category, Action<string[], object> Callback, object State = null)
|
||||
{
|
||||
string Folder;
|
||||
if (Category == null)
|
||||
Folder = DownloadFolder;
|
||||
else
|
||||
Folder = Path.Combine(DownloadFolder, Category);
|
||||
string Folder = Category == null ? DownloadFolder : Path.Combine(DownloadFolder, Category);
|
||||
foreach (string URL in URLs)
|
||||
{
|
||||
DownloadList.Add(new DownloadEntry(URL, Folder, URLs, Callback, State));
|
||||
}
|
||||
}
|
||||
|
||||
private void DownloadAll()
|
||||
@@ -227,23 +237,36 @@ namespace WPinternals
|
||||
try
|
||||
{
|
||||
string TempProductType = ProductType.ToUpper();
|
||||
if ((TempProductType != null) && TempProductType.StartsWith("RM") && !TempProductType.StartsWith("RM-"))
|
||||
TempProductType = "RM-" + TempProductType.Substring(2);
|
||||
if ((TempProductType?.StartsWith("RM") == true) && !TempProductType.StartsWith("RM-"))
|
||||
{
|
||||
TempProductType = "RM-" + TempProductType[2..];
|
||||
}
|
||||
|
||||
ProductType = TempProductType;
|
||||
FFUURL = LumiaDownloadModel.SearchFFU(ProductType, ProductCode, OperatorCode, out TempProductType);
|
||||
if (TempProductType != null)
|
||||
{
|
||||
ProductType = TempProductType;
|
||||
}
|
||||
|
||||
if (ProductType != null)
|
||||
{
|
||||
EmergencyURLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
UIContext.Post(s =>
|
||||
{
|
||||
if (FFUURL != null)
|
||||
{
|
||||
Download(FFUURL, ProductType, FFUDownloadedAndCheckSupported, null);
|
||||
}
|
||||
|
||||
if (EmergencyURLs != null)
|
||||
{
|
||||
Download(EmergencyURLs, ProductType, EmergencyDownloaded, ProductType);
|
||||
}
|
||||
}, null);
|
||||
}).Start();
|
||||
}
|
||||
@@ -252,7 +275,9 @@ namespace WPinternals
|
||||
{
|
||||
IEnumerable<SearchResult> Selection = SearchResultList.Where(r => r.IsSelected);
|
||||
foreach (SearchResult Result in Selection)
|
||||
{
|
||||
App.DownloadManager.Download(Result.URLs, Result.Category, Result.Callback, Result.State);
|
||||
}
|
||||
}
|
||||
|
||||
private void FFUDownloaded(string[] Files, object State)
|
||||
@@ -264,9 +289,9 @@ namespace WPinternals
|
||||
{
|
||||
App.Config.AddFfuToRepository(Files[0]);
|
||||
|
||||
if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0)
|
||||
if (!App.Config.FFURepository.Any(e => App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V2-EFIESP").TargetVersions.Any(v => v.Description == e.OSVersion)))
|
||||
{
|
||||
string ProductType2 = "RM-1085";
|
||||
const string ProductType2 = "RM-1085";
|
||||
string URL = LumiaDownloadModel.SearchFFU(ProductType2, null, null);
|
||||
Download(URL, ProductType2, FFUDownloaded, null);
|
||||
}
|
||||
@@ -281,46 +306,30 @@ namespace WPinternals
|
||||
for (int i = 0; i < Files.Length; i++)
|
||||
{
|
||||
if (Files[i].EndsWith(".ede", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
ProgrammerPath = Files[i];
|
||||
}
|
||||
|
||||
if (Files[i].EndsWith(".edp", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
PayloadPath = Files[i];
|
||||
}
|
||||
}
|
||||
|
||||
if ((Type != null) && (ProgrammerPath != null) && (PayloadPath != null))
|
||||
{
|
||||
App.Config.AddEmergencyToRepository(Type, ProgrammerPath, PayloadPath);
|
||||
}
|
||||
|
||||
private ObservableCollection<DownloadEntry> _DownloadList = new ObservableCollection<DownloadEntry>();
|
||||
public ObservableCollection<DownloadEntry> DownloadList
|
||||
{
|
||||
get
|
||||
{
|
||||
return _DownloadList;
|
||||
}
|
||||
}
|
||||
|
||||
private ObservableCollection<SearchResult> _SearchResultList = new ObservableCollection<SearchResult>();
|
||||
public ObservableCollection<SearchResult> SearchResultList
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SearchResultList;
|
||||
}
|
||||
}
|
||||
public ObservableCollection<DownloadEntry> DownloadList { get; } = new();
|
||||
public ObservableCollection<SearchResult> SearchResultList { get; } = new();
|
||||
|
||||
private DelegateCommand _DownloadSelectedCommand = null;
|
||||
public DelegateCommand DownloadSelectedCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DownloadSelectedCommand == null)
|
||||
{
|
||||
_DownloadSelectedCommand = new DelegateCommand(() =>
|
||||
{
|
||||
DownloadSelected();
|
||||
});
|
||||
}
|
||||
return _DownloadSelectedCommand;
|
||||
return _DownloadSelectedCommand ??= new DelegateCommand(() => DownloadSelected());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,14 +338,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_SearchCommand == null)
|
||||
{
|
||||
_SearchCommand = new DelegateCommand(() =>
|
||||
{
|
||||
Search();
|
||||
});
|
||||
}
|
||||
return _SearchCommand;
|
||||
return _SearchCommand ??= new DelegateCommand(() => Search());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,14 +347,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DownloadAllCommand == null)
|
||||
{
|
||||
_DownloadAllCommand = new DelegateCommand(() =>
|
||||
{
|
||||
DownloadAll();
|
||||
});
|
||||
}
|
||||
return _DownloadAllCommand;
|
||||
return _DownloadAllCommand ??= new DelegateCommand(() => DownloadAll());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,14 +380,18 @@ namespace WPinternals
|
||||
if (_DownloadFolder == null)
|
||||
{
|
||||
if (Key.GetValue("DownloadFolder") != null)
|
||||
{
|
||||
Key.DeleteValue("DownloadFolder");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("DownloadFolder", _DownloadFolder);
|
||||
}
|
||||
|
||||
Key.Close();
|
||||
|
||||
OnPropertyChanged("DownloadFolder");
|
||||
OnPropertyChanged(nameof(DownloadFolder));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -410,7 +409,7 @@ namespace WPinternals
|
||||
{
|
||||
_ProductCode = value;
|
||||
|
||||
OnPropertyChanged("ProductCode");
|
||||
OnPropertyChanged(nameof(ProductCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,7 +427,7 @@ namespace WPinternals
|
||||
{
|
||||
_ProductType = value;
|
||||
|
||||
OnPropertyChanged("ProductType");
|
||||
OnPropertyChanged(nameof(ProductType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,7 +445,7 @@ namespace WPinternals
|
||||
{
|
||||
_OperatorCode = value;
|
||||
|
||||
OnPropertyChanged("OperatorCode");
|
||||
OnPropertyChanged(nameof(OperatorCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -454,9 +453,11 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash))
|
||||
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
||||
{
|
||||
NokiaFlashModel LumiaFlashModel = (NokiaFlashModel)Notifier.CurrentModel;
|
||||
PhoneInfo Info = LumiaFlashModel.ReadPhoneInfo();
|
||||
@@ -469,24 +470,16 @@ namespace WPinternals
|
||||
NokiaPhoneModel LumiaNormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
||||
OperatorCode = LumiaNormalModel.ExecuteJsonMethodAsString("ReadOperatorName", "OperatorName"); // Example: 000-NL
|
||||
string TempProductType = LumiaNormalModel.ExecuteJsonMethodAsString("ReadManufacturerModelName", "ManufacturerModelName"); // RM-821_eu_denmark_251
|
||||
if (TempProductType.IndexOf('_') >= 0) TempProductType = TempProductType.Substring(0, TempProductType.IndexOf('_'));
|
||||
if (TempProductType.Contains('_'))
|
||||
{
|
||||
TempProductType = TempProductType.Substring(0, TempProductType.IndexOf('_'));
|
||||
}
|
||||
|
||||
ProductType = TempProductType;
|
||||
ProductCode = LumiaNormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); // 059Q9D7
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _AddFFUCommand = null;
|
||||
public DelegateCommand AddFFUCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _AddFFUCommand;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_AddFFUCommand = value;
|
||||
}
|
||||
}
|
||||
public DelegateCommand AddFFUCommand { get; } = null;
|
||||
}
|
||||
|
||||
internal enum DownloadStatus
|
||||
@@ -498,7 +491,7 @@ namespace WPinternals
|
||||
|
||||
internal class DownloadEntry : INotifyPropertyChanged
|
||||
{
|
||||
private SynchronizationContext UIContext;
|
||||
private readonly SynchronizationContext UIContext;
|
||||
public event PropertyChangedEventHandler PropertyChanged = delegate { };
|
||||
internal Action<string[], object> Callback;
|
||||
internal object State;
|
||||
@@ -521,7 +514,7 @@ namespace WPinternals
|
||||
this.Folder = Folder;
|
||||
Directory.CreateDirectory(Folder);
|
||||
Name = DownloadsViewModel.GetFileNameFromURL(URL);
|
||||
Uri Uri = new Uri(URL);
|
||||
Uri Uri = new(URL);
|
||||
Status = DownloadStatus.Downloading;
|
||||
new Thread(() =>
|
||||
{
|
||||
@@ -536,14 +529,13 @@ namespace WPinternals
|
||||
|
||||
private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
|
||||
Action Finish = () =>
|
||||
void Finish()
|
||||
{
|
||||
Status = e.Error == null ? DownloadStatus.Ready : DownloadStatus.Failed;
|
||||
App.DownloadManager.DownloadList.Remove(this);
|
||||
if (Status == DownloadStatus.Ready)
|
||||
{
|
||||
if ((URLCollection == null) || (!URLCollection.Any(c => App.DownloadManager.DownloadList.Any(d => d.URL == c)))) // if there are no files left to download from this collection, then call the callback-function.
|
||||
if (URLCollection?.Any(c => App.DownloadManager.DownloadList.Any(d => d.URL == c)) != true) // if there are no files left to download from this collection, then call the callback-function.
|
||||
{
|
||||
string[] Files;
|
||||
if (URLCollection == null)
|
||||
@@ -555,16 +547,17 @@ namespace WPinternals
|
||||
{
|
||||
Files = new string[URLCollection.Length];
|
||||
for (int i = 0; i < URLCollection.Length; i++)
|
||||
{
|
||||
Files[i] = System.IO.Path.Combine(Folder, DownloadsViewModel.GetFileNameFromURL(URLCollection[i]));
|
||||
}
|
||||
}
|
||||
|
||||
Callback(Files, State);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (UIContext != null)
|
||||
UIContext.Post(d => Finish(), null);
|
||||
UIContext?.Post(d => Finish(), null);
|
||||
}
|
||||
|
||||
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
||||
@@ -578,7 +571,9 @@ namespace WPinternals
|
||||
if (this.PropertyChanged != null)
|
||||
{
|
||||
if (SynchronizationContext.Current == UIContext)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
else
|
||||
{
|
||||
UIContext.Post((s) => PropertyChanged(this, new PropertyChangedEventArgs(propertyName)), null);
|
||||
@@ -598,7 +593,7 @@ namespace WPinternals
|
||||
if (_Status != value)
|
||||
{
|
||||
_Status = value;
|
||||
OnPropertyChanged("Status");
|
||||
OnPropertyChanged(nameof(Status));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -615,7 +610,7 @@ namespace WPinternals
|
||||
if (_Name != value)
|
||||
{
|
||||
_Name = value;
|
||||
OnPropertyChanged("Name");
|
||||
OnPropertyChanged(nameof(Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -632,7 +627,7 @@ namespace WPinternals
|
||||
if (_Size != value)
|
||||
{
|
||||
_Size = value;
|
||||
OnPropertyChanged("Size");
|
||||
OnPropertyChanged(nameof(Size));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -649,7 +644,7 @@ namespace WPinternals
|
||||
if (_TimeLeft != value)
|
||||
{
|
||||
_TimeLeft = value;
|
||||
OnPropertyChanged("TimeLeft");
|
||||
OnPropertyChanged(nameof(TimeLeft));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -666,7 +661,7 @@ namespace WPinternals
|
||||
if (_Speed != value)
|
||||
{
|
||||
_Speed = value;
|
||||
OnPropertyChanged("Speed");
|
||||
OnPropertyChanged(nameof(Speed));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -683,7 +678,7 @@ namespace WPinternals
|
||||
if (_Progress != value)
|
||||
{
|
||||
_Progress = value;
|
||||
OnPropertyChanged("Progress");
|
||||
OnPropertyChanged(nameof(Progress));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -691,7 +686,7 @@ namespace WPinternals
|
||||
|
||||
internal class SearchResult : INotifyPropertyChanged
|
||||
{
|
||||
private SynchronizationContext UIContext;
|
||||
private readonly SynchronizationContext UIContext;
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
internal string[] URLs;
|
||||
internal Action<string[], object> Callback;
|
||||
@@ -739,7 +734,9 @@ namespace WPinternals
|
||||
if (this.PropertyChanged != null)
|
||||
{
|
||||
if (SynchronizationContext.Current == UIContext)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
else
|
||||
{
|
||||
UIContext.Post((s) => PropertyChanged(this, new PropertyChangedEventArgs(propertyName)), null);
|
||||
@@ -759,7 +756,7 @@ namespace WPinternals
|
||||
if (_Name != value)
|
||||
{
|
||||
_Name = value;
|
||||
OnPropertyChanged("Name");
|
||||
OnPropertyChanged(nameof(Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -776,7 +773,7 @@ namespace WPinternals
|
||||
if (_Size != value)
|
||||
{
|
||||
_Size = value;
|
||||
OnPropertyChanged("Size");
|
||||
OnPropertyChanged(nameof(Size));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -793,7 +790,7 @@ namespace WPinternals
|
||||
if (_IsSelected != value)
|
||||
{
|
||||
_IsSelected = value;
|
||||
OnPropertyChanged("IsSelected");
|
||||
OnPropertyChanged(nameof(IsSelected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -805,7 +802,7 @@ namespace WPinternals
|
||||
{
|
||||
HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(address);
|
||||
req.ServicePoint.ConnectionLimit = 10;
|
||||
return (WebRequest)req;
|
||||
return req;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,10 +828,16 @@ namespace WPinternals
|
||||
{
|
||||
long? Size = value as long?;
|
||||
if (Size < 1024)
|
||||
{
|
||||
return Size + " B";
|
||||
}
|
||||
|
||||
if (Size < (1024 * 1024))
|
||||
return Math.Round(((double)Size / 1024), 0) + " KB";
|
||||
return Math.Round(((double)Size / 1024 / 1024), 0) + " MB";
|
||||
{
|
||||
return Math.Round((double)Size / 1024, 0) + " KB";
|
||||
}
|
||||
|
||||
return Math.Round((double)Size / 1024 / 1024, 0) + " MB";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType,
|
||||
@@ -866,7 +869,10 @@ namespace WPinternals
|
||||
{
|
||||
TimeSpan TimeLeft = (TimeSpan)value;
|
||||
if (TimeLeft == Timeout.InfiniteTimeSpan)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return TimeLeft.ToString(@"h\:mm\:ss");
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace WPinternals
|
||||
{
|
||||
internal class DumpRomTargetSelectionViewModel : ContextViewModel
|
||||
{
|
||||
private Action<string, string, bool, string, bool, string, bool> DumpCallback;
|
||||
private readonly Action<string, string, bool, string, bool, string, bool> DumpCallback;
|
||||
internal Action SwitchToUnlockBoot;
|
||||
internal Action SwitchToUnlockRoot;
|
||||
internal Action SwitchToFlashRom;
|
||||
@@ -53,7 +53,7 @@ namespace WPinternals
|
||||
if (value != _FFUPath)
|
||||
{
|
||||
_FFUPath = value;
|
||||
OnPropertyChanged("FFUPath");
|
||||
OnPropertyChanged(nameof(FFUPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace WPinternals
|
||||
if (value != _EFIESPPath)
|
||||
{
|
||||
_EFIESPPath = value;
|
||||
OnPropertyChanged("EFIESPPath");
|
||||
OnPropertyChanged(nameof(EFIESPPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ namespace WPinternals
|
||||
if (value != _CompressEFIESP)
|
||||
{
|
||||
_CompressEFIESP = value;
|
||||
OnPropertyChanged("CompressEFIESP");
|
||||
OnPropertyChanged(nameof(CompressEFIESP));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace WPinternals
|
||||
if (value != _MainOSPath)
|
||||
{
|
||||
_MainOSPath = value;
|
||||
OnPropertyChanged("MainOSPath");
|
||||
OnPropertyChanged(nameof(MainOSPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ namespace WPinternals
|
||||
if (value != _CompressMainOS)
|
||||
{
|
||||
_CompressMainOS = value;
|
||||
OnPropertyChanged("CompressMainOS");
|
||||
OnPropertyChanged(nameof(CompressMainOS));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,7 @@ namespace WPinternals
|
||||
if (value != _DataPath)
|
||||
{
|
||||
_DataPath = value;
|
||||
OnPropertyChanged("DataPath");
|
||||
OnPropertyChanged(nameof(DataPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +155,7 @@ namespace WPinternals
|
||||
if (value != _CompressData)
|
||||
{
|
||||
_CompressData = value;
|
||||
OnPropertyChanged("CompressData");
|
||||
OnPropertyChanged(nameof(CompressData));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,7 +172,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneDisconnected)
|
||||
{
|
||||
_IsPhoneDisconnected = value;
|
||||
OnPropertyChanged("IsPhoneDisconnected");
|
||||
OnPropertyChanged(nameof(IsPhoneDisconnected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInMassStorage)
|
||||
{
|
||||
_IsPhoneInMassStorage = value;
|
||||
OnPropertyChanged("IsPhoneInMassStorage");
|
||||
OnPropertyChanged(nameof(IsPhoneInMassStorage));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -206,7 +206,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInOtherMode)
|
||||
{
|
||||
_IsPhoneInOtherMode = value;
|
||||
OnPropertyChanged("IsPhoneInOtherMode");
|
||||
OnPropertyChanged(nameof(IsPhoneInOtherMode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,11 +216,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DumpCommand == null)
|
||||
{
|
||||
_DumpCommand = new DelegateCommand(() => { DumpCallback(FFUPath, EFIESPPath, CompressEFIESP, MainOSPath, CompressMainOS, DataPath, CompressData); }, () => ((FFUPath != null) && ((EFIESPPath != null) || (MainOSPath != null) || (DataPath != null))));
|
||||
}
|
||||
return _DumpCommand;
|
||||
return _DumpCommand ??= new DelegateCommand(() => DumpCallback(FFUPath, EFIESPPath, CompressEFIESP, MainOSPath, CompressMainOS, DataPath, CompressData), () => ((FFUPath != null) && ((EFIESPPath != null) || (MainOSPath != null) || (DataPath != null))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ namespace WPinternals
|
||||
{
|
||||
internal class DumpRomViewModel : ContextViewModel
|
||||
{
|
||||
private Action SwitchToUnlockBoot;
|
||||
private Action SwitchToUnlockRoot;
|
||||
private Action SwitchToFlashRom;
|
||||
private readonly Action SwitchToUnlockBoot;
|
||||
private readonly Action SwitchToUnlockRoot;
|
||||
private readonly Action SwitchToFlashRom;
|
||||
|
||||
internal DumpRomViewModel(Action SwitchToUnlockBoot, Action SwitchToUnlockRoot, Action SwitchToFlashRom)
|
||||
: base()
|
||||
@@ -41,10 +41,14 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SubContextViewModel == null)
|
||||
{
|
||||
ActivateSubContext(new DumpRomTargetSelectionViewModel(SwitchToUnlockBoot, SwitchToUnlockRoot, SwitchToFlashRom, DoDumpRom));
|
||||
}
|
||||
}
|
||||
|
||||
internal void DoDumpRom(string FFUPath, string EFIESPPath, bool CompressEFIESP, string MainOSPath, bool CompressMainOS, string DataPath, bool CompressData)
|
||||
@@ -65,21 +69,21 @@ namespace WPinternals
|
||||
|
||||
if (EFIESPPath != null)
|
||||
{
|
||||
Partition = FFU.GPT.Partitions.Where(p => p.Name == "EFIESP").First();
|
||||
Partition = FFU.GPT.Partitions.First(p => p.Name == "EFIESP");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
PartitionCount++;
|
||||
}
|
||||
|
||||
if (MainOSPath != null)
|
||||
{
|
||||
Partition = FFU.GPT.Partitions.Where(p => p.Name == "MainOS").First();
|
||||
Partition = FFU.GPT.Partitions.First(p => p.Name == "MainOS");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
PartitionCount++;
|
||||
}
|
||||
|
||||
if (DataPath != null)
|
||||
{
|
||||
Partition = FFU.GPT.Partitions.Where(p => p.Name == "Data").First();
|
||||
Partition = FFU.GPT.Partitions.First(p => p.Name == "Data");
|
||||
TotalSizeSectors += Partition.SizeInSectors;
|
||||
PartitionCount++;
|
||||
}
|
||||
@@ -92,7 +96,7 @@ namespace WPinternals
|
||||
|
||||
// We are on a worker thread!
|
||||
// So we must pass the SynchronizationContext of the UI thread
|
||||
BusyViewModel Busy = new BusyViewModel("Dumping ROM...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
BusyViewModel Busy = new("Dumping ROM...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
ProgressUpdater Updater = Busy.ProgressUpdater;
|
||||
ActivateSubContext(Busy);
|
||||
|
||||
@@ -104,7 +108,7 @@ namespace WPinternals
|
||||
if (EFIESPPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Dumping partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Dumping partition EFIESP (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
FFU.WritePartition("EFIESP", EFIESPPath, Updater, CompressEFIESP);
|
||||
}
|
||||
}
|
||||
@@ -122,7 +126,7 @@ namespace WPinternals
|
||||
if (MainOSPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Dumping partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Dumping partition MainOS (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
FFU.WritePartition("MainOS", MainOSPath, Updater, CompressMainOS);
|
||||
}
|
||||
}
|
||||
@@ -140,7 +144,7 @@ namespace WPinternals
|
||||
if (DataPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Dumping partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Dumping partition Data (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
FFU.WritePartition("Data", DataPath, Updater, CompressData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ namespace WPinternals
|
||||
{
|
||||
internal class LumiaFlashRomSourceSelectionViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action<string, string, string> FlashPartitionsCallback;
|
||||
private Action<string> FlashFFUCallback;
|
||||
private Action<string> FlashMMOSCallback;
|
||||
private Action<string> FlashArchiveCallback;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly Action<string, string, string> FlashPartitionsCallback;
|
||||
private readonly Action<string> FlashFFUCallback;
|
||||
private readonly Action<string> FlashMMOSCallback;
|
||||
private readonly Action<string> FlashArchiveCallback;
|
||||
internal Action SwitchToUnlockBoot;
|
||||
internal Action SwitchToUnlockRoot;
|
||||
internal Action SwitchToDumpFFU;
|
||||
@@ -66,7 +66,7 @@ namespace WPinternals
|
||||
if (value != _EFIESPPath)
|
||||
{
|
||||
_EFIESPPath = value;
|
||||
OnPropertyChanged("EFIESPPath");
|
||||
OnPropertyChanged(nameof(EFIESPPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ namespace WPinternals
|
||||
if (value != _MainOSPath)
|
||||
{
|
||||
_MainOSPath = value;
|
||||
OnPropertyChanged("MainOSPath");
|
||||
OnPropertyChanged(nameof(MainOSPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,7 @@ namespace WPinternals
|
||||
if (value != _DataPath)
|
||||
{
|
||||
_DataPath = value;
|
||||
OnPropertyChanged("DataPath");
|
||||
OnPropertyChanged(nameof(DataPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,7 @@ namespace WPinternals
|
||||
if (value != _ArchivePath)
|
||||
{
|
||||
_ArchivePath = value;
|
||||
OnPropertyChanged("ArchivePath");
|
||||
OnPropertyChanged(nameof(ArchivePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ namespace WPinternals
|
||||
if (value != _FFUPath)
|
||||
{
|
||||
_FFUPath = value;
|
||||
OnPropertyChanged("FFUPath");
|
||||
OnPropertyChanged(nameof(FFUPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ namespace WPinternals
|
||||
if (value != _MMOSPath)
|
||||
{
|
||||
_MMOSPath = value;
|
||||
OnPropertyChanged("MMOSPath");
|
||||
OnPropertyChanged(nameof(MMOSPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneDisconnected)
|
||||
{
|
||||
_IsPhoneDisconnected = value;
|
||||
OnPropertyChanged("IsPhoneDisconnected");
|
||||
OnPropertyChanged(nameof(IsPhoneDisconnected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,7 +185,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInFlashMode)
|
||||
{
|
||||
_IsPhoneInFlashMode = value;
|
||||
OnPropertyChanged("IsPhoneInFlashMode");
|
||||
OnPropertyChanged(nameof(IsPhoneInFlashMode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInOtherMode)
|
||||
{
|
||||
_IsPhoneInOtherMode = value;
|
||||
OnPropertyChanged("IsPhoneInOtherMode");
|
||||
OnPropertyChanged(nameof(IsPhoneInOtherMode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,11 +212,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_FlashPartitionsCommand == null)
|
||||
{
|
||||
_FlashPartitionsCommand = new DelegateCommand(() => { FlashPartitionsCallback(EFIESPPath, MainOSPath, DataPath); }, () => (((EFIESPPath != null) || (MainOSPath != null) || (DataPath != null)) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _FlashPartitionsCommand;
|
||||
return _FlashPartitionsCommand ??= new DelegateCommand(() => FlashPartitionsCallback(EFIESPPath, MainOSPath, DataPath), () => (((EFIESPPath != null) || (MainOSPath != null) || (DataPath != null)) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,11 +221,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_FlashFFUCommand == null)
|
||||
{
|
||||
_FlashFFUCommand = new DelegateCommand(() => { FlashFFUCallback(FFUPath); }, () => ((FFUPath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _FlashFFUCommand;
|
||||
return _FlashFFUCommand ??= new DelegateCommand(() => FlashFFUCallback(FFUPath), () => ((FFUPath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,11 +230,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_FlashMMOSCommand == null)
|
||||
{
|
||||
_FlashMMOSCommand = new DelegateCommand(() => { FlashMMOSCallback(MMOSPath); }, () => ((MMOSPath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _FlashMMOSCommand;
|
||||
return _FlashMMOSCommand ??= new DelegateCommand(() => FlashMMOSCallback(MMOSPath), () => ((MMOSPath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,11 +239,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_FlashArchiveCommand == null)
|
||||
{
|
||||
_FlashArchiveCommand = new DelegateCommand(() => { FlashArchiveCallback(ArchivePath); }, () => ((ArchivePath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _FlashArchiveCommand;
|
||||
return _FlashArchiveCommand ??= new DelegateCommand(() => FlashArchiveCallback(ArchivePath), () => ((ArchivePath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +248,7 @@ namespace WPinternals
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrived;
|
||||
}
|
||||
|
||||
void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
new Thread(() =>
|
||||
{
|
||||
@@ -276,7 +260,7 @@ namespace WPinternals
|
||||
}).Start();
|
||||
}
|
||||
|
||||
void DeviceRemoved()
|
||||
private void DeviceRemoved()
|
||||
{
|
||||
new Thread(() => EvaluateViewState()).Start();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace WPinternals
|
||||
internal PhoneInterfaces? CurrentInterface;
|
||||
internal IDisposable CurrentModel;
|
||||
internal PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action<PhoneInterfaces> ModeSwitchRequestCallback;
|
||||
private Action SwitchToGettingStarted;
|
||||
private readonly Action<PhoneInterfaces> ModeSwitchRequestCallback;
|
||||
private readonly Action SwitchToGettingStarted;
|
||||
|
||||
internal LumiaInfoViewModel(PhoneNotifierViewModel PhoneNotifier, Action<PhoneInterfaces> ModeSwitchRequestCallback, Action SwitchToGettingStarted)
|
||||
: base()
|
||||
@@ -50,14 +50,14 @@ namespace WPinternals
|
||||
PhoneNotifier.DeviceRemoved -= DeviceRemoved;
|
||||
}
|
||||
|
||||
void DeviceRemoved()
|
||||
private void DeviceRemoved()
|
||||
{
|
||||
CurrentInterface = null;
|
||||
CurrentModel = null;
|
||||
ActivateSubContext(null);
|
||||
}
|
||||
|
||||
void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
CurrentInterface = Args.NewInterface;
|
||||
CurrentModel = Args.NewModel;
|
||||
@@ -82,7 +82,7 @@ namespace WPinternals
|
||||
case PhoneInterfaces.Lumia_MassStorage:
|
||||
ActivateSubContext(new NokiaMassStorageViewModel((MassStorage)CurrentModel));
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace WPinternals
|
||||
internal PhoneInterfaces? CurrentInterface;
|
||||
internal IDisposable CurrentModel;
|
||||
internal PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action Callback;
|
||||
private readonly Action Callback;
|
||||
|
||||
internal LumiaModeViewModel(PhoneNotifierViewModel PhoneNotifier, Action Callback)
|
||||
: base()
|
||||
@@ -48,28 +48,34 @@ namespace WPinternals
|
||||
PhoneNotifier.DeviceRemoved -= DeviceRemoved;
|
||||
}
|
||||
|
||||
void DeviceRemoved()
|
||||
private void DeviceRemoved()
|
||||
{
|
||||
CurrentInterface = null;
|
||||
CurrentModel = null;
|
||||
|
||||
if (!IsSwitchingInterface)
|
||||
{
|
||||
ActivateSubContext(null);
|
||||
}
|
||||
}
|
||||
|
||||
void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
CurrentInterface = Args.NewInterface;
|
||||
CurrentModel = Args.NewModel;
|
||||
|
||||
if (!IsSwitchingInterface && IsActive)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (!IsSwitchingInterface && IsActive)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
@@ -96,7 +102,7 @@ namespace WPinternals
|
||||
case PhoneInterfaces.Lumia_MassStorage:
|
||||
ActivateSubContext(new NokiaModeMassStorageViewModel((MassStorage)CurrentModel, OnModeSwitchRequested));
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Called from eventhandler, so "async void" is valid here.
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace WPinternals
|
||||
|
||||
internal class LumiaUnlockBootViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action Callback;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly Action Callback;
|
||||
private string FFUPath;
|
||||
private string LoadersPath;
|
||||
private string SBL3Path;
|
||||
@@ -50,12 +50,12 @@ namespace WPinternals
|
||||
private string SupportedFFUPath;
|
||||
private bool IsBootLoaderUnlocked;
|
||||
private byte[] RootKeyHash = null;
|
||||
private Action SwitchToFlashRom;
|
||||
private Action SwitchToUndoRoot;
|
||||
private Action SwitchToDownload;
|
||||
private bool DoUnlock;
|
||||
private readonly Action SwitchToFlashRom;
|
||||
private readonly Action SwitchToUndoRoot;
|
||||
private readonly Action SwitchToDownload;
|
||||
private readonly bool DoUnlock;
|
||||
private MachineState State;
|
||||
private object EvaluateViewStateLockObject = new object();
|
||||
private readonly object EvaluateViewStateLockObject = new();
|
||||
|
||||
internal LumiaUnlockBootViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToFlashRom, Action SwitchToUndoRoot, Action SwitchToDownload, bool DoUnlock, Action Callback)
|
||||
: base()
|
||||
@@ -86,10 +86,14 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (State == MachineState.LumiaUnlockBoot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (EvaluateViewStateLockObject)
|
||||
{
|
||||
@@ -135,20 +139,21 @@ namespace WPinternals
|
||||
|
||||
UefiSecurityStatusResponse SecurityStatus = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadSecurityStatus();
|
||||
if (SecurityStatus != null)
|
||||
{
|
||||
IsBootLoaderUnlocked = (SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus);
|
||||
}
|
||||
|
||||
TestPos = 2;
|
||||
|
||||
PhoneInfo Info = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo();
|
||||
if (SecurityStatus == null)
|
||||
{
|
||||
IsBootLoaderUnlocked = !Info.IsBootloaderSecure;
|
||||
}
|
||||
|
||||
if (RootKeyHash == null)
|
||||
{
|
||||
RootKeyHash = Info.RKH;
|
||||
|
||||
if (RootKeyHash == null)
|
||||
RootKeyHash = new byte[32];
|
||||
RootKeyHash = Info.RKH ?? (new byte[32]);
|
||||
}
|
||||
|
||||
TestPos = 3;
|
||||
@@ -156,7 +161,7 @@ namespace WPinternals
|
||||
if (Info.FlashAppProtocolVersionMajor < 2)
|
||||
{
|
||||
// This action is executed after the resources are selected by the user.
|
||||
Action<string, string, string, string, string, string, bool> ReturnFunction = (FFUPath, LoadersPath, SBL3Path, ProfileFFUPath, EDEPath, SupportedFFUPath, DoFixBoot) =>
|
||||
void ReturnFunction(string FFUPath, string LoadersPath, string SBL3Path, string ProfileFFUPath, string EDEPath, string SupportedFFUPath, bool DoFixBoot)
|
||||
{
|
||||
// Stop responding to device arrival here, because all connections are handled by subfunctions, not here.
|
||||
IsSwitchingInterface = true;
|
||||
@@ -174,36 +179,38 @@ namespace WPinternals
|
||||
LogFile.Log("FFU: " + FFUPath);
|
||||
LogFile.Log("Loaders: " + LoadersPath);
|
||||
if (SBL3Path == null)
|
||||
{
|
||||
LogFile.Log("No SBL3 specified");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("SBL3: " + SBL3Path);
|
||||
}
|
||||
|
||||
ActivateSubContext(new BusyViewModel("Processing resources..."));
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV1UnlockFirmware(PhoneNotifier, FFUPath, LoadersPath, SBL3Path, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
});
|
||||
Task.Run(async () => await LumiaUnlockBootloaderViewModel.LumiaV1UnlockFirmware(PhoneNotifier, FFUPath, LoadersPath, SBL3Path, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage));
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV1RelockFirmware(PhoneNotifier, FFUPath, LoadersPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
});
|
||||
Task.Run(async () => await LumiaUnlockBootloaderViewModel.LumiaV1RelockFirmware(PhoneNotifier, FFUPath, LoadersPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
ActivateSubContext(new BootUnlockResourcesViewModel("Lumia Flash mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunction, Abort, IsBootLoaderUnlocked, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSubContext(new BootRestoreResourcesViewModel("Lumia Flash mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunction, Abort, IsBootLoaderUnlocked, false));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool AlreadyUnlocked = false;
|
||||
const bool AlreadyUnlocked = false;
|
||||
if (DoUnlock)
|
||||
{
|
||||
NokiaFlashModel FlashModel = (NokiaFlashModel)PhoneNotifier.CurrentModel;
|
||||
@@ -222,7 +229,7 @@ namespace WPinternals
|
||||
IsSwitchingInterface = true;
|
||||
|
||||
// This action is executed after the resources are selected by the user.
|
||||
Action<string, string, string, string, string, string, bool> ReturnFunction = (FFUPath, LoadersPath, SBL3Path, ProfileFFUPath, EDEPath, SupportedFFUPath, DoFixBoot) =>
|
||||
void ReturnFunction(string FFUPath, string LoadersPath, string SBL3Path, string ProfileFFUPath, string EDEPath, string SupportedFFUPath, bool DoFixBoot)
|
||||
{
|
||||
IsSwitchingInterface = true;
|
||||
State = MachineState.LumiaUnlockBoot;
|
||||
@@ -236,24 +243,36 @@ namespace WPinternals
|
||||
StorePaths();
|
||||
|
||||
if (DoFixBoot)
|
||||
{
|
||||
LogFile.Log("Fix Boot");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Unlock Bootloader");
|
||||
}
|
||||
|
||||
LogFile.Log("Processing resources:");
|
||||
LogFile.Log("Profile FFU: " + ProfileFFUPath);
|
||||
LogFile.Log("EDE file: " + EDEPath);
|
||||
if (SupportedFFUPath != null)
|
||||
{
|
||||
LogFile.Log("Donor-FFU with supported OS version: " + SupportedFFUPath);
|
||||
}
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
if (DoFixBoot)
|
||||
{
|
||||
await LumiaV2UnlockBootViewModel.LumiaV2FixBoot(PhoneNotifier, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
}
|
||||
else if (!AlreadyUnlocked)
|
||||
{
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV2UnlockUEFI(PhoneNotifier, ProfileFFUPath, EDEPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV2UnlockUEFI(PhoneNotifier, ProfileFFUPath, EDEPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -263,24 +282,27 @@ namespace WPinternals
|
||||
FFU ProfileFFU = null;
|
||||
|
||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => (Info.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists())).ToList();
|
||||
if (FFUs.Count() > 0)
|
||||
ProfileFFU = new FFU(FFUs[0].Path);
|
||||
else
|
||||
throw new WPinternalsException("Profile FFU missing", "No profile FFU has been found in the repository for your device. You can add a profile FFU within the download section of the tool or by using the command line.");
|
||||
ProfileFFU = FFUs.Count > 0
|
||||
? new FFU(FFUs[0].Path)
|
||||
: throw new WPinternalsException("Profile FFU missing", "No profile FFU has been found in the repository for your device. You can add a profile FFU within the download section of the tool or by using the command line.");
|
||||
|
||||
LogFile.Log("Profile FFU: " + ProfileFFU.Path);
|
||||
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV2RelockUEFI(PhoneNotifier, ProfileFFU.Path, true, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TestPos = 5;
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
ActivateSubContext(new BootUnlockResourcesViewModel("Lumia Flash mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunction, Abort, IsBootLoaderUnlocked, true, Info.PlatformID, Info.Type));
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSubContext(new BootRestoreResourcesViewModel("Lumia Flash mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunction, Abort, IsBootLoaderUnlocked, true, Info.PlatformID, Info.Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception Ex)
|
||||
@@ -292,7 +314,7 @@ namespace WPinternals
|
||||
IsSwitchingInterface = false;
|
||||
|
||||
// If resources are not confirmed yet, then display view with device info and request for resources.
|
||||
QualcommDownload Download = new QualcommDownload((QualcommSerial)PhoneNotifier.CurrentModel);
|
||||
QualcommDownload Download = new((QualcommSerial)PhoneNotifier.CurrentModel);
|
||||
byte[] QualcommRootKeyHash;
|
||||
|
||||
try
|
||||
@@ -306,7 +328,9 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
if (RootKeyHash == null)
|
||||
{
|
||||
RootKeyHash = QualcommRootKeyHash;
|
||||
}
|
||||
else if (!StructuralComparisons.StructuralEqualityComparer.Equals(RootKeyHash, QualcommRootKeyHash))
|
||||
{
|
||||
LogFile.Log("Error: Root Key Hash in Qualcomm Emergency mode does not match!");
|
||||
@@ -330,32 +354,34 @@ namespace WPinternals
|
||||
LogFile.Log("FFU: " + FFUPath);
|
||||
LogFile.Log("Loaders: " + LoadersPath);
|
||||
if (SBL3Path == null)
|
||||
{
|
||||
LogFile.Log("No SBL3 specified");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("SBL3: " + SBL3Path);
|
||||
}
|
||||
|
||||
ActivateSubContext(new BusyViewModel("Processing resources..."));
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV1UnlockFirmware(PhoneNotifier, FFUPath, LoadersPath, SBL3Path, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
});
|
||||
Task.Run(async () => await LumiaUnlockBootloaderViewModel.LumiaV1UnlockFirmware(PhoneNotifier, FFUPath, LoadersPath, SBL3Path, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage));
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV1RelockFirmware(PhoneNotifier, FFUPath, LoadersPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
});
|
||||
Task.Run(async () => await LumiaUnlockBootloaderViewModel.LumiaV1RelockFirmware(PhoneNotifier, FFUPath, LoadersPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage));
|
||||
}
|
||||
};
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
ActivateSubContext(new BootUnlockResourcesViewModel("Qualcomm Emergency Download mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunctionD, Abort, IsBootLoaderUnlocked, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSubContext(new BootRestoreResourcesViewModel("Qualcomm Emergency Download mode", RootKeyHash, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, ReturnFunctionD, Abort, IsBootLoaderUnlocked, false));
|
||||
}
|
||||
|
||||
break;
|
||||
case PhoneInterfaces.Qualcomm_Flash:
|
||||
@@ -371,24 +397,15 @@ namespace WPinternals
|
||||
FFUPath = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\WPInternals", "FFUPath", null);
|
||||
SupportedFFUPath = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\WPInternals", "SupportedFFUPath", null);
|
||||
LoadersPath = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\WPInternals", "LoadersPath", null);
|
||||
if (DoUnlock)
|
||||
SBL3Path = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\WPInternals", "SBL3Path", null);
|
||||
else
|
||||
SBL3Path = null;
|
||||
SBL3Path = DoUnlock ? (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\WPInternals", "SBL3Path", null) : null;
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV1UnlockFirmware(PhoneNotifier, FFUPath, LoadersPath, SBL3Path, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
});
|
||||
Task.Run(async () => await LumiaUnlockBootloaderViewModel.LumiaV1UnlockFirmware(PhoneNotifier, FFUPath, LoadersPath, SBL3Path, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage));
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await LumiaUnlockBootloaderViewModel.LumiaV1RelockFirmware(PhoneNotifier, FFUPath, LoadersPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
|
||||
});
|
||||
Task.Run(async () => await LumiaUnlockBootloaderViewModel.LumiaV1RelockFirmware(PhoneNotifier, FFUPath, LoadersPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -436,41 +453,53 @@ namespace WPinternals
|
||||
|
||||
private void StorePaths()
|
||||
{
|
||||
RegistryKey Key = Registry.CurrentUser.OpenSubKey(@"Software\WPInternals", true);
|
||||
if (Key == null)
|
||||
Key = Registry.CurrentUser.CreateSubKey(@"Software\WPInternals");
|
||||
RegistryKey Key = Registry.CurrentUser.OpenSubKey(@"Software\WPInternals", true) ?? Registry.CurrentUser.CreateSubKey(@"Software\WPInternals");
|
||||
|
||||
if (FFUPath == null)
|
||||
{
|
||||
if (Key.GetValue("FFUPath") != null)
|
||||
{
|
||||
Key.DeleteValue("FFUPath");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("FFUPath", FFUPath);
|
||||
}
|
||||
|
||||
if (LoadersPath == null)
|
||||
{
|
||||
if (Key.GetValue("LoadersPath") != null)
|
||||
{
|
||||
Key.DeleteValue("LoadersPath");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("LoadersPath", LoadersPath);
|
||||
}
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
if (SBL3Path == null)
|
||||
{
|
||||
if (Key.GetValue("SBL3Path") != null)
|
||||
{
|
||||
Key.DeleteValue("SBL3Path");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Key.SetValue("SBL3Path", SBL3Path);
|
||||
}
|
||||
}
|
||||
|
||||
if (ProfileFFUPath == null)
|
||||
{
|
||||
if (Key.GetValue("ProfileFFUPath") != null)
|
||||
{
|
||||
Key.DeleteValue("ProfileFFUPath");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -487,7 +516,9 @@ namespace WPinternals
|
||||
if (EDEPath == null)
|
||||
{
|
||||
if (Key.GetValue("EDEPath") != null)
|
||||
{
|
||||
Key.DeleteValue("EDEPath");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -522,7 +553,7 @@ namespace WPinternals
|
||||
internal void ExitMessage(string Message, string SubMessage)
|
||||
{
|
||||
// SecureBoot Unlock v2 is done. Reactivate phone arrival events.
|
||||
MessageViewModel SuccessMessageViewModel = new MessageViewModel(Message, () =>
|
||||
MessageViewModel SuccessMessageViewModel = new(Message, () =>
|
||||
{
|
||||
State = MachineState.Default;
|
||||
Exit();
|
||||
@@ -531,7 +562,7 @@ namespace WPinternals
|
||||
ActivateSubContext(SuccessMessageViewModel);
|
||||
}
|
||||
|
||||
void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
// Do not start on a new thread, because EvaluateViewState will also create new ViewModels and those should be created on the UI thread.
|
||||
EvaluateViewState();
|
||||
@@ -561,8 +592,8 @@ namespace WPinternals
|
||||
internal Action SwitchToFlashRom;
|
||||
internal Action SwitchToUndoRoot;
|
||||
internal Action SwitchToDownload;
|
||||
private string PlatformID;
|
||||
private string ProductType;
|
||||
private readonly string PlatformID;
|
||||
private readonly string ProductType;
|
||||
private string ValidatedSupportedFfuPath = null;
|
||||
|
||||
internal FlashResourcesViewModel(string CurrentMode, byte[] RootKeyHash, Action SwitchToFlashRom, Action SwitchToUndoRoot, Action SwitchToDownload, Action<string, string, string, string, string, string, bool> Result, Action Abort, bool IsBootLoaderUnlocked, bool TargetHasNewFlashProtocol, string PlatformID = null, string ProductType = null) : base()
|
||||
@@ -577,7 +608,7 @@ namespace WPinternals
|
||||
this.SwitchToDownload = SwitchToDownload;
|
||||
this.IsBootLoaderUnlocked = IsBootLoaderUnlocked;
|
||||
OkCommand = new DelegateCommand(() => Result(FFUPath, LoadersPath, SBL3Path, ProfileFFUPath, EDEPath, IsSupportedFfuNeeded ? SupportedFFUPath : null, false),
|
||||
() => (!TargetHasNewFlashProtocol && (!IsSupportedFfuNeeded || (IsSupportedFfuValid && (SupportedFFUPath != null))) || ((ProfileFFUPath != null) && (!IsSupportedFfuNeeded || (IsSupportedFfuValid && (SupportedFFUPath != null))))));
|
||||
() => ((!TargetHasNewFlashProtocol && (!IsSupportedFfuNeeded || (IsSupportedFfuValid && (SupportedFFUPath != null)))) || ((ProfileFFUPath != null) && (!IsSupportedFfuNeeded || (IsSupportedFfuValid && (SupportedFFUPath != null))))));
|
||||
FixCommand = new DelegateCommand(() => Result(null, null, null, null, null, null, true));
|
||||
CancelCommand = new DelegateCommand(Abort);
|
||||
this.TargetHasNewFlashProtocol = TargetHasNewFlashProtocol;
|
||||
@@ -630,13 +661,15 @@ namespace WPinternals
|
||||
catch { }
|
||||
|
||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => (PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists())).ToList();
|
||||
if (FFUs.Count() > 0)
|
||||
if (FFUs.Count > 0)
|
||||
{
|
||||
IsProfileFfuValid = true;
|
||||
ProfileFFUPath = FFUs[0].Path;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsProfileFfuValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetEDEPath()
|
||||
@@ -650,7 +683,9 @@ namespace WPinternals
|
||||
{
|
||||
Programmer = new QualcommPartition(_EDEPath);
|
||||
if (ByteOperations.Compare(Programmer.RootKeyHash, RootKeyHash))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
@@ -694,8 +729,8 @@ namespace WPinternals
|
||||
|
||||
try
|
||||
{
|
||||
FFU FFU = new FFU(_FFUPath);
|
||||
IsSupportedFfuNeeded = !(App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V1.1-EFIESP").First().TargetVersions.Any(v => v.Description == FFU.GetOSVersion()));
|
||||
FFU FFU = new(_FFUPath);
|
||||
IsSupportedFfuNeeded = !App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V1.1-EFIESP").TargetVersions.Any(v => v.Description == FFU.GetOSVersion());
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -712,8 +747,10 @@ namespace WPinternals
|
||||
if (_SupportedFFUPath != null)
|
||||
{
|
||||
SupportedFFU = new FFU(_SupportedFFUPath);
|
||||
if (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V1.1-EFIESP").First().TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
if (App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V1.1-EFIESP").TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
@@ -724,7 +761,7 @@ namespace WPinternals
|
||||
if (TempSupportedFFUPath != null)
|
||||
{
|
||||
SupportedFFU = new FFU(TempSupportedFFUPath);
|
||||
if (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V1.1-EFIESP").First().TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
if (App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V1.1-EFIESP").TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
{
|
||||
ValidatedSupportedFfuPath = TempSupportedFFUPath;
|
||||
SupportedFFUPath = TempSupportedFFUPath;
|
||||
@@ -735,8 +772,8 @@ namespace WPinternals
|
||||
}
|
||||
catch { }
|
||||
|
||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V1.1-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).ToList();
|
||||
if (FFUs.Count() > 0)
|
||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V1.1-EFIESP").TargetVersions.Any(v => v.Description == e.OSVersion)).ToList();
|
||||
if (FFUs.Count > 0)
|
||||
{
|
||||
ValidatedSupportedFfuPath = FFUs[0].Path;
|
||||
SupportedFFUPath = FFUs[0].Path;
|
||||
@@ -754,8 +791,8 @@ namespace WPinternals
|
||||
|
||||
try
|
||||
{
|
||||
FFU ProfileFFU = new FFU(_ProfileFFUPath);
|
||||
IsSupportedFfuNeeded = !(App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == ProfileFFU.GetOSVersion()));
|
||||
FFU ProfileFFU = new(_ProfileFFUPath);
|
||||
IsSupportedFfuNeeded = !App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V2-EFIESP").TargetVersions.Any(v => v.Description == ProfileFFU.GetOSVersion());
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -772,8 +809,10 @@ namespace WPinternals
|
||||
if (_SupportedFFUPath != null)
|
||||
{
|
||||
SupportedFFU = new FFU(_SupportedFFUPath);
|
||||
if (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
if (App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V2-EFIESP").TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
@@ -784,7 +823,7 @@ namespace WPinternals
|
||||
if (TempSupportedFFUPath != null)
|
||||
{
|
||||
SupportedFFU = new FFU(TempSupportedFFUPath);
|
||||
if (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
if (App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V2-EFIESP").TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
{
|
||||
ValidatedSupportedFfuPath = TempSupportedFFUPath;
|
||||
SupportedFFUPath = TempSupportedFFUPath;
|
||||
@@ -795,8 +834,8 @@ namespace WPinternals
|
||||
}
|
||||
catch { }
|
||||
|
||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).ToList();
|
||||
if (FFUs.Count() > 0)
|
||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V2-EFIESP").TargetVersions.Any(v => v.Description == e.OSVersion)).ToList();
|
||||
if (FFUs.Count > 0)
|
||||
{
|
||||
ValidatedSupportedFfuPath = FFUs[0].Path;
|
||||
SupportedFFUPath = FFUs[0].Path;
|
||||
@@ -818,43 +857,28 @@ namespace WPinternals
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (!TargetHasNewFlashProtocol)
|
||||
{
|
||||
if (App.Config.FFURepository.Any(e => ((e.Path == SupportedFFUPath) && (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V1.1-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)))))
|
||||
if (App.Config.FFURepository.Any(e => ((e.Path == SupportedFFUPath) && (App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V1.1-EFIESP").TargetVersions.Any(v => v.Description == e.OSVersion)))))
|
||||
{
|
||||
IsSupportedFfuValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FFU SupportedFFU = new FFU(SupportedFFUPath);
|
||||
if (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V1.1-EFIESP").First().TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
{
|
||||
IsSupportedFfuValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsSupportedFfuValid = false;
|
||||
}
|
||||
FFU SupportedFFU = new(SupportedFFUPath);
|
||||
IsSupportedFfuValid = App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V1.1-EFIESP").TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (App.Config.FFURepository.Any(e => ((e.Path == SupportedFFUPath) && (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)))))
|
||||
if (App.Config.FFURepository.Any(e => ((e.Path == SupportedFFUPath) && (App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V2-EFIESP").TargetVersions.Any(v => v.Description == e.OSVersion)))))
|
||||
{
|
||||
IsSupportedFfuValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FFU SupportedFFU = new FFU(SupportedFFUPath);
|
||||
if (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion()))
|
||||
{
|
||||
IsSupportedFfuValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsSupportedFfuValid = false;
|
||||
}
|
||||
FFU SupportedFFU = new(SupportedFFUPath);
|
||||
IsSupportedFfuValid = App.PatchEngine.PatchDefinitions.First(p => p.Name == "SecureBootHack-V2-EFIESP").TargetVersions.Any(v => v.Description == SupportedFFU.GetOSVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -865,7 +889,9 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
if (IsSupportedFfuValid && (SupportedFFUPath != null))
|
||||
{
|
||||
ValidatedSupportedFfuPath = SupportedFFUPath;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -883,7 +909,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsSupportedFfuNeeded = value;
|
||||
OnPropertyChanged("IsSupportedFfuNeeded");
|
||||
OnPropertyChanged(nameof(IsSupportedFfuNeeded));
|
||||
OkCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
@@ -898,7 +924,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsSupportedFfuValid = value;
|
||||
OnPropertyChanged("IsSupportedFfuValid");
|
||||
OnPropertyChanged(nameof(IsSupportedFfuValid));
|
||||
OkCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
@@ -913,7 +939,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsProfileFfuValid = value;
|
||||
OnPropertyChanged("IsProfileFfuValid");
|
||||
OnPropertyChanged(nameof(IsProfileFfuValid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -927,7 +953,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_TargetHasNewFlashProtocol = value;
|
||||
OnPropertyChanged("TargetHasNewFlashProtocol");
|
||||
OnPropertyChanged(nameof(TargetHasNewFlashProtocol));
|
||||
OkCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
@@ -942,7 +968,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsBootLoaderUnlocked = value;
|
||||
OnPropertyChanged("IsBootLoaderUnlocked");
|
||||
OnPropertyChanged(nameof(IsBootLoaderUnlocked));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -956,7 +982,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FFUPath = value;
|
||||
OnPropertyChanged("FFUPath");
|
||||
OnPropertyChanged(nameof(FFUPath));
|
||||
SetSupportedFFUPath();
|
||||
OkCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
@@ -974,7 +1000,7 @@ namespace WPinternals
|
||||
if (_ProfileFFUPath != value)
|
||||
{
|
||||
_ProfileFFUPath = value;
|
||||
OnPropertyChanged("ProfileFFUPath");
|
||||
OnPropertyChanged(nameof(ProfileFFUPath));
|
||||
SetSupportedFFUPath();
|
||||
OkCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
@@ -993,10 +1019,12 @@ namespace WPinternals
|
||||
if (_SupportedFFUPath != value)
|
||||
{
|
||||
_SupportedFFUPath = value;
|
||||
OnPropertyChanged("SupportedFFUPath");
|
||||
OnPropertyChanged(nameof(SupportedFFUPath));
|
||||
|
||||
if (value != ValidatedSupportedFfuPath)
|
||||
{
|
||||
ValidateSupportedFfuPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1011,7 +1039,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_LoadersPath = value;
|
||||
OnPropertyChanged("LoadersPath");
|
||||
OnPropertyChanged(nameof(LoadersPath));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,7 +1053,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_EDEPath = value;
|
||||
OnPropertyChanged("EDEPath");
|
||||
OnPropertyChanged(nameof(EDEPath));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1039,7 +1067,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_SBL3Path = value;
|
||||
OnPropertyChanged("SBL3Path");
|
||||
OnPropertyChanged(nameof(SBL3Path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1053,7 +1081,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_CurrentMode = value;
|
||||
OnPropertyChanged("CurrentMode");
|
||||
OnPropertyChanged(nameof(CurrentMode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1067,47 +1095,11 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_RootKeyHash = value;
|
||||
OnPropertyChanged("RootKeyHash");
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _OkCommand = null;
|
||||
public DelegateCommand OkCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _OkCommand;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_OkCommand = value;
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _CancelCommand = null;
|
||||
public DelegateCommand CancelCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CancelCommand;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_CancelCommand = value;
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _FixCommand = null;
|
||||
public DelegateCommand FixCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FixCommand;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_FixCommand = value;
|
||||
OnPropertyChanged(nameof(RootKeyHash));
|
||||
}
|
||||
}
|
||||
public DelegateCommand OkCommand { get; } = null;
|
||||
public DelegateCommand CancelCommand { get; } = null;
|
||||
public DelegateCommand FixCommand { get; } = null;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,12 +37,12 @@ namespace WPinternals
|
||||
|
||||
internal class LumiaRootAccessTargetSelectionViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
internal Action SwitchToUnlockBoot;
|
||||
internal Action SwitchToDumpRom;
|
||||
internal Action SwitchToFlashRom;
|
||||
private Action UnlockPhoneCallback;
|
||||
private Action<string, string> UnlockImageCallback;
|
||||
private readonly Action UnlockPhoneCallback;
|
||||
private readonly Action<string, string> UnlockImageCallback;
|
||||
|
||||
internal LumiaRootAccessTargetSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToDumpRom, Action SwitchToFlashRom, Action UnlockPhoneCallback, Action<string, string> UnlockImageCallback)
|
||||
: base()
|
||||
@@ -72,7 +72,7 @@ namespace WPinternals
|
||||
if (value != _EFIESPMountPoint)
|
||||
{
|
||||
_EFIESPMountPoint = value;
|
||||
OnPropertyChanged("EFIESPMountPoint");
|
||||
OnPropertyChanged(nameof(EFIESPMountPoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ namespace WPinternals
|
||||
if (value != _MainOSMountPoint)
|
||||
{
|
||||
_MainOSMountPoint = value;
|
||||
OnPropertyChanged("MainOSMountPoint");
|
||||
OnPropertyChanged(nameof(MainOSMountPoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneDisconnected)
|
||||
{
|
||||
_IsPhoneDisconnected = value;
|
||||
OnPropertyChanged("IsPhoneDisconnected");
|
||||
OnPropertyChanged(nameof(IsPhoneDisconnected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInMassStorage)
|
||||
{
|
||||
_IsPhoneInMassStorage = value;
|
||||
OnPropertyChanged("IsPhoneInMassStorage");
|
||||
OnPropertyChanged(nameof(IsPhoneInMassStorage));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,7 +140,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInOtherMode)
|
||||
{
|
||||
_IsPhoneInOtherMode = value;
|
||||
OnPropertyChanged("IsPhoneInOtherMode");
|
||||
OnPropertyChanged(nameof(IsPhoneInOtherMode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,11 +150,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_UnlockPhoneCommand == null)
|
||||
{
|
||||
_UnlockPhoneCommand = new DelegateCommand(() => { UnlockPhoneCallback(); }, () => !IsPhoneDisconnected);
|
||||
}
|
||||
return _UnlockPhoneCommand;
|
||||
return _UnlockPhoneCommand ??= new DelegateCommand(() => UnlockPhoneCallback(), () => !IsPhoneDisconnected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,11 +159,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_UnlockImageCommand == null)
|
||||
{
|
||||
_UnlockImageCommand = new DelegateCommand(() => { UnlockImageCallback(EFIESPMountPoint, MainOSMountPoint); }, () => ((EFIESPMountPoint != null) || (MainOSMountPoint != null)));
|
||||
}
|
||||
return _UnlockImageCommand;
|
||||
return _UnlockImageCommand ??= new DelegateCommand(() => UnlockImageCallback(EFIESPMountPoint, MainOSMountPoint), () => ((EFIESPMountPoint != null) || (MainOSMountPoint != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,12 +168,12 @@ namespace WPinternals
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrived;
|
||||
}
|
||||
|
||||
void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
new Thread(() => EvaluateViewState()).Start();
|
||||
}
|
||||
|
||||
void DeviceRemoved()
|
||||
private void DeviceRemoved()
|
||||
{
|
||||
new Thread(() => EvaluateViewState()).Start();
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ namespace WPinternals
|
||||
{
|
||||
internal class LumiaUnlockRootViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action SwitchToUnlockBoot;
|
||||
private Action SwitchToDumpRom;
|
||||
private Action SwitchToFlashRom;
|
||||
private Action Callback;
|
||||
private bool DoUnlock;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly Action SwitchToUnlockBoot;
|
||||
private readonly Action SwitchToDumpRom;
|
||||
private readonly Action SwitchToFlashRom;
|
||||
private readonly Action Callback;
|
||||
private readonly bool DoUnlock;
|
||||
|
||||
internal LumiaUnlockRootViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToDumpRom, Action SwitchToFlashRom, bool DoUnlock, Action Callback)
|
||||
: base()
|
||||
@@ -50,17 +50,23 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
if ((SubContextViewModel == null) || (SubContextViewModel is LumiaUndoRootTargetSelectionViewModel))
|
||||
{
|
||||
ActivateSubContext(new LumiaUnlockRootTargetSelectionViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToDumpRom, SwitchToFlashRom, DoUnlockPhone, DoUnlockImage));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((SubContextViewModel == null) || (SubContextViewModel is LumiaUnlockRootTargetSelectionViewModel))
|
||||
{
|
||||
ActivateSubContext(new LumiaUndoRootTargetSelectionViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToDumpRom, SwitchToFlashRom, DoUnlockPhone, DoUnlockImage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,18 +109,26 @@ namespace WPinternals
|
||||
new Thread(() =>
|
||||
{
|
||||
if (DoUnlock)
|
||||
{
|
||||
LogFile.BeginAction("EnableRootAccess");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.BeginAction("DisableRootAccess");
|
||||
}
|
||||
|
||||
bool Result = false;
|
||||
|
||||
if (EFIESP != null && !HasV11Patches)
|
||||
{
|
||||
if (DoUnlock)
|
||||
{
|
||||
ActivateSubContext(new BusyViewModel("Enable Root Access on EFIESP..."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSubContext(new BusyViewModel("Disable Root Access on EFIESP..."));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -157,9 +171,13 @@ namespace WPinternals
|
||||
if (MainOS != null)
|
||||
{
|
||||
if (DoUnlock)
|
||||
{
|
||||
ActivateSubContext(new BusyViewModel("Enable Root Access on MainOS..."));
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSubContext(new BusyViewModel("Disable Root Access on MainOS..."));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -169,7 +187,9 @@ namespace WPinternals
|
||||
Result = App.PatchEngine.Patch("RootAccess-MainOS");
|
||||
|
||||
if (Result)
|
||||
{
|
||||
Result = App.PatchEngine.Patch("SecureBootHack-MainOS");
|
||||
}
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
@@ -182,7 +202,9 @@ namespace WPinternals
|
||||
App.PatchEngine.Restore("RootAccess-MainOS");
|
||||
|
||||
if (!HasNewBootloader)
|
||||
{
|
||||
App.PatchEngine.Restore("SecureBootHack-MainOS");
|
||||
}
|
||||
|
||||
Result = true;
|
||||
}
|
||||
@@ -206,16 +228,24 @@ namespace WPinternals
|
||||
else
|
||||
{
|
||||
if (DoUnlock)
|
||||
{
|
||||
ActivateSubContext(new MessageViewModel("Root Access successfully enabled!", Exit));
|
||||
}
|
||||
else
|
||||
{
|
||||
ActivateSubContext(new MessageViewModel("Root Access successfully disabled!", Exit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DoUnlock)
|
||||
{
|
||||
LogFile.EndAction("EnableRootAccess");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.EndAction("DisableRootAccess");
|
||||
}
|
||||
}).Start();
|
||||
}
|
||||
|
||||
@@ -232,11 +262,11 @@ namespace WPinternals
|
||||
MassStorage Phone = (MassStorage)PhoneNotifier.CurrentModel;
|
||||
Phone.OpenVolume(false);
|
||||
byte[] GPTBuffer = Phone.ReadSectors(1, 33);
|
||||
GPT GPT = new WPinternals.GPT(GPTBuffer);
|
||||
GPT GPT = new(GPTBuffer);
|
||||
Partition Partition = GPT.GetPartition("UEFI");
|
||||
byte[] UefiBuffer = Phone.ReadSectors(Partition.FirstSector, Partition.LastSector - Partition.FirstSector + 1);
|
||||
UEFI UEFI = new UEFI(UefiBuffer);
|
||||
string BootMgrName = UEFI.EFIs.Where(efi => ((efi.Name != null) && ((efi.Name.Contains("BootMgrApp")) || (efi.Name.Contains("FlashApp"))))).First().Name;
|
||||
UEFI UEFI = new(UefiBuffer);
|
||||
string BootMgrName = UEFI.EFIs.First(efi => ((efi.Name != null) && ((efi.Name.Contains("BootMgrApp")) || (efi.Name.Contains("FlashApp"))))).Name;
|
||||
byte[] BootMgr = UEFI.GetFile(BootMgrName);
|
||||
// "Header V2"
|
||||
Result = (ByteOperations.FindAscii(BootMgr, "Header V2") != null);
|
||||
@@ -250,7 +280,7 @@ namespace WPinternals
|
||||
MassStorage Phone = (MassStorage)PhoneNotifier.CurrentModel;
|
||||
Phone.OpenVolume(false);
|
||||
byte[] GPTBuffer = Phone.ReadSectors(1, 33);
|
||||
GPT GPT = new WPinternals.GPT(GPTBuffer);
|
||||
GPT GPT = new(GPTBuffer);
|
||||
Partition Partition = GPT.GetPartition("BACKUP_BS_NV");
|
||||
Result = Partition != null;
|
||||
Phone.CloseVolume();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,15 +70,29 @@ namespace WPinternals
|
||||
{
|
||||
string Manifest = "[FullFlash]\r\n";
|
||||
if (!string.IsNullOrEmpty(fullFlash.AntiTheftVersion))
|
||||
{
|
||||
Manifest += "AntiTheftVersion = " + fullFlash.AntiTheftVersion + "\r\n";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(fullFlash.OSVersion))
|
||||
{
|
||||
Manifest += "OSVersion = " + fullFlash.OSVersion + "\r\n";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(fullFlash.Description))
|
||||
{
|
||||
Manifest += "Description = " + fullFlash.Description + "\r\n";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(fullFlash.Version))
|
||||
{
|
||||
Manifest += "Version = " + fullFlash.Version + "\r\n";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(fullFlash.DevicePlatformId0))
|
||||
{
|
||||
Manifest += "DevicePlatformId0 = " + fullFlash.DevicePlatformId0 + "\r\n";
|
||||
}
|
||||
|
||||
Manifest += "\r\n[Store]\r\n";
|
||||
Manifest += "SectorSize = " + store.SectorSize + "\r\n";
|
||||
@@ -127,28 +141,54 @@ namespace WPinternals
|
||||
//
|
||||
internal async static Task LumiaV3CustomFlash(PhoneNotifierViewModel Notifier, List<FlashPart> FlashParts, bool CheckSectorAlignment = true, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null)
|
||||
{
|
||||
if (SetWorkingStatus == null) SetWorkingStatus = (m, s, v, a, st) => { };
|
||||
if (UpdateWorkingStatus == null) UpdateWorkingStatus = (m, s, v, st) => { };
|
||||
if (ExitSuccess == null) ExitSuccess = (m, s) => { };
|
||||
if (ExitFailure == null) ExitFailure = (m, s) => { };
|
||||
if (SetWorkingStatus == null)
|
||||
{
|
||||
SetWorkingStatus = (m, s, v, a, st) => { };
|
||||
}
|
||||
|
||||
uint chunkSize = 131072u;
|
||||
int chunkSizes = 131072;
|
||||
if (UpdateWorkingStatus == null)
|
||||
{
|
||||
UpdateWorkingStatus = (m, s, v, st) => { };
|
||||
}
|
||||
|
||||
if (ExitSuccess == null)
|
||||
{
|
||||
ExitSuccess = (m, s) => { };
|
||||
}
|
||||
|
||||
if (ExitFailure == null)
|
||||
{
|
||||
ExitFailure = (m, s) => { };
|
||||
}
|
||||
|
||||
const uint chunkSize = 131072u;
|
||||
const int chunkSizes = 131072;
|
||||
|
||||
if (FlashParts != null)
|
||||
{
|
||||
foreach (FlashPart Part in FlashParts)
|
||||
{
|
||||
if (Part.Stream == null)
|
||||
{
|
||||
throw new ArgumentException("Stream is null");
|
||||
}
|
||||
|
||||
if (!Part.Stream.CanSeek)
|
||||
{
|
||||
throw new ArgumentException("Streams must be seekable");
|
||||
}
|
||||
|
||||
if (((Part.StartSector * 0x200) % chunkSize) != 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid StartSector alignment");
|
||||
}
|
||||
|
||||
if (CheckSectorAlignment)
|
||||
{
|
||||
if ((Part.Stream.Length % chunkSize) != 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid Data length");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,12 +199,19 @@ namespace WPinternals
|
||||
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.
|
||||
{
|
||||
throw new WPinternalsException("Flash failed!", "Protocols not supported. The phone reports that it does not support the Protocol Sync V2.");
|
||||
}
|
||||
|
||||
if (Info.FlashAppProtocolVersionMajor < 2) // Old phones do not support the hack. These phones have Flash protocol 1.x.
|
||||
{
|
||||
throw new WPinternalsException("Flash failed!", "Protocols not supported. The phone reports that Flash App communication protocol is lower than 2. Reported version by the phone: " + Info.FlashAppProtocolVersionMajor + ".");
|
||||
}
|
||||
|
||||
if (Info.UefiSecureBootEnabled)
|
||||
{
|
||||
throw new WPinternalsException("Flash failed!", "UEFI Secureboot must be disabled for the Flash V3 exploit to work.");
|
||||
}
|
||||
|
||||
// The payloads must be ordered by the number of locations
|
||||
//
|
||||
@@ -174,20 +221,20 @@ namespace WPinternals
|
||||
//
|
||||
// If you do not order payloads like this, you will get an error, most likely hash mismatch
|
||||
//
|
||||
LumiaV2UnlockBootViewModel.FlashingPayload[] payloads = new LumiaV2UnlockBootViewModel.FlashingPayload[0];
|
||||
LumiaV2UnlockBootViewModel.FlashingPayload[] payloads = Array.Empty<LumiaV2UnlockBootViewModel.FlashingPayload>();
|
||||
if (FlashParts != null)
|
||||
{
|
||||
payloads = LumiaV2UnlockBootViewModel.GetNonOptimizedPayloads(FlashParts, chunkSizes, (uint)(Info.WriteBufferSize / chunkSize), SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Count()).ToArray();
|
||||
payloads = LumiaV2UnlockBootViewModel.GetNonOptimizedPayloads(FlashParts, chunkSizes, Info.WriteBufferSize / chunkSize, SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Length).ToArray();
|
||||
}
|
||||
|
||||
MemoryStream Headerstream1 = new MemoryStream();
|
||||
MemoryStream Headerstream1 = new();
|
||||
|
||||
// ==============================
|
||||
// Header 1 start
|
||||
|
||||
ImageHeader image = new ImageHeader();
|
||||
FullFlash ffimage = new FullFlash();
|
||||
Store simage = new Store();
|
||||
ImageHeader image = new();
|
||||
FullFlash ffimage = new();
|
||||
Store simage = new();
|
||||
|
||||
// Todo make this read the image itself
|
||||
ffimage.OSVersion = "10.0.11111.0";
|
||||
@@ -219,15 +266,15 @@ namespace WPinternals
|
||||
// Header 1 stop + round
|
||||
// ==============================
|
||||
|
||||
MemoryStream Headerstream2 = new MemoryStream();
|
||||
MemoryStream Headerstream2 = new();
|
||||
|
||||
// ==============================
|
||||
// Header 2 start
|
||||
|
||||
StoreHeader store = new StoreHeader();
|
||||
StoreHeader store = new();
|
||||
|
||||
store.WriteDescriptorCount = (UInt32)payloads.Count();
|
||||
store.FinalTableIndex = (UInt32)payloads.Count() - store.FinalTableCount;
|
||||
store.WriteDescriptorCount = (UInt32)payloads.Length;
|
||||
store.FinalTableIndex = (UInt32)payloads.Length - store.FinalTableCount;
|
||||
store.PlatformId = Info.PlatformID;
|
||||
|
||||
foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
|
||||
@@ -236,7 +283,7 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(Model, 0x20000);
|
||||
GPT GPT = new GPT(GPTChunk);
|
||||
GPT GPT = new(GPTChunk);
|
||||
UInt64 PlatEnd = 0;
|
||||
if (GPT.Partitions.Any(x => x.Name == "PLAT"))
|
||||
{
|
||||
@@ -245,9 +292,12 @@ namespace WPinternals
|
||||
|
||||
foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
|
||||
{
|
||||
if (payload.TargetLocations.First() > PlatEnd)
|
||||
if (payload.TargetLocations[0] > PlatEnd)
|
||||
{
|
||||
break;
|
||||
store.FlashOnlyTableIndex += 1;
|
||||
}
|
||||
|
||||
store.FlashOnlyTableIndex++;
|
||||
}
|
||||
|
||||
byte[] StoreHeaderBuffer = new byte[0xF8];
|
||||
@@ -275,7 +325,7 @@ namespace WPinternals
|
||||
UInt32 NewWriteDescriptorOffset = 0;
|
||||
foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
|
||||
{
|
||||
ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x00, (UInt32)payload.TargetLocations.Count()); // Location count
|
||||
ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x00, (UInt32)payload.TargetLocations.Length); // Location count
|
||||
ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x04, payload.ChunkCount); // Chunk count
|
||||
NewWriteDescriptorOffset += 0x08;
|
||||
|
||||
@@ -294,7 +344,7 @@ namespace WPinternals
|
||||
// Header 2 stop + round
|
||||
// ==============================
|
||||
|
||||
SecurityHeader security = new SecurityHeader();
|
||||
SecurityHeader security = new();
|
||||
|
||||
Headerstream1.Seek(0, SeekOrigin.Begin);
|
||||
Headerstream2.Seek(0, SeekOrigin.Begin);
|
||||
@@ -307,7 +357,7 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
byte[] HashTable = new byte[security.HashTableSize];
|
||||
BinaryWriter bw = new BinaryWriter(new MemoryStream(HashTable));
|
||||
BinaryWriter bw = new(new MemoryStream(HashTable));
|
||||
|
||||
SHA256 crypto = SHA256.Create();
|
||||
for (Int32 i = 0; i < Headerstream1.Length / chunkSize; i++)
|
||||
@@ -347,7 +397,7 @@ namespace WPinternals
|
||||
ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x18, security.CatalogSize);
|
||||
ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x1C, security.HashTableSize);
|
||||
|
||||
MemoryStream retstream = new MemoryStream();
|
||||
MemoryStream retstream = new();
|
||||
|
||||
retstream.Write(SecurityHeaderBuffer, 0, 0x20);
|
||||
|
||||
@@ -384,10 +434,12 @@ namespace WPinternals
|
||||
|
||||
Byte Options = 0;
|
||||
if (!Info.IsBootloaderSecure)
|
||||
{
|
||||
Options = (Byte)((FlashOptions)Options | FlashOptions.SkipSignatureCheck);
|
||||
}
|
||||
|
||||
LogFile.Log("Flash in progress...", LogType.ConsoleOnly);
|
||||
SetWorkingStatus("Flashing...", null, (UInt64?)payloads.Count(), Status: WPinternalsStatus.Flashing);
|
||||
SetWorkingStatus("Flashing...", null, (UInt64?)payloads.Length, Status: WPinternalsStatus.Flashing);
|
||||
|
||||
Model.SendFfuHeaderV1(FfuHeader, Options);
|
||||
|
||||
@@ -400,11 +452,11 @@ namespace WPinternals
|
||||
|
||||
byte[] payloadBuffer;
|
||||
|
||||
for (Int32 i = 0; i < payloads.Count(); i+= numberOfPayloadsToSendAtOnce)
|
||||
for (Int32 i = 0; i < payloads.Length; i+= numberOfPayloadsToSendAtOnce)
|
||||
{
|
||||
if (i + numberOfPayloadsToSendAtOnce - 1 >= payloads.Count())
|
||||
if (i + numberOfPayloadsToSendAtOnce - 1 >= payloads.Length)
|
||||
{
|
||||
numberOfPayloadsToSendAtOnce = payloads.Count() - i;
|
||||
numberOfPayloadsToSendAtOnce = payloads.Length - i;
|
||||
}
|
||||
|
||||
payloadBuffer = new byte[numberOfPayloadsToSendAtOnce * chunkSizes];
|
||||
@@ -415,25 +467,27 @@ namespace WPinternals
|
||||
{
|
||||
LumiaV2UnlockBootViewModel.FlashingPayload payload = payloads[i + j];
|
||||
|
||||
UInt32 StreamIndex = payload.StreamIndexes.First();
|
||||
UInt32 StreamIndex = payload.StreamIndexes[0];
|
||||
FlashPart flashPart = FlashParts[(Int32)StreamIndex];
|
||||
|
||||
if (flashPart.ProgressText != null)
|
||||
{
|
||||
ProgressText = flashPart.ProgressText;
|
||||
}
|
||||
|
||||
Stream Stream = flashPart.Stream;
|
||||
Stream.Seek(payload.StreamLocations.First(), SeekOrigin.Begin);
|
||||
Stream.Seek(payload.StreamLocations[0], SeekOrigin.Begin);
|
||||
Stream.Read(payloadBuffer, j * chunkSizes, chunkSizes);
|
||||
counter++;
|
||||
}
|
||||
|
||||
if ((Info.SecureFfuSupportedProtocolMask & (ushort)FfuProtocol.ProtocolSyncV2) != 0)
|
||||
{
|
||||
Model.SendFfuPayloadV2(payloadBuffer, Int32.Parse((counter * 100 / (UInt64)payloads.Count()).ToString()));
|
||||
Model.SendFfuPayloadV2(payloadBuffer, Int32.Parse((counter * 100 / (UInt64)payloads.Length).ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Model.SendFfuPayloadV1(payloadBuffer, Int32.Parse((counter * 100 / (UInt64)payloads.Count()).ToString()));
|
||||
Model.SendFfuPayloadV1(payloadBuffer, Int32.Parse((counter * 100 / (UInt64)payloads.Length).ToString()));
|
||||
}
|
||||
|
||||
UpdateWorkingStatus(ProgressText, null, counter, WPinternalsStatus.Flashing);
|
||||
|
||||
+46
-138
@@ -77,9 +77,13 @@ namespace WPinternals
|
||||
if (this.PropertyChanged != null)
|
||||
{
|
||||
if (MainSyncContext == SynchronizationContext.Current)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
else
|
||||
{
|
||||
MainSyncContext.Post(s => PropertyChanged(this, new PropertyChangedEventArgs(propertyName)), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,19 +98,19 @@ namespace WPinternals
|
||||
{
|
||||
if (_ContextViewModel != value)
|
||||
{
|
||||
if (_ContextViewModel != null)
|
||||
_ContextViewModel.IsActive = false;
|
||||
_ContextViewModel = value;
|
||||
if (_ContextViewModel != null)
|
||||
{
|
||||
_ContextViewModel.Activate();
|
||||
_ContextViewModel.IsActive = false;
|
||||
}
|
||||
OnPropertyChanged("ContextViewModel");
|
||||
|
||||
_ContextViewModel = value;
|
||||
_ContextViewModel?.Activate();
|
||||
OnPropertyChanged(nameof(ContextViewModel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SynchronizationContext MainSyncContext;
|
||||
private readonly SynchronizationContext MainSyncContext;
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
@@ -115,11 +119,13 @@ namespace WPinternals
|
||||
LogFile.LogApplicationVersion();
|
||||
|
||||
// Set global callback for cases where Dependency Injection is not possible.
|
||||
App.NavigateToGettingStarted = () => { GettingStartedCommand.Execute(null); };
|
||||
App.NavigateToUnlockBoot = () => { BootUnlockCommand.Execute(null); };
|
||||
App.NavigateToGettingStarted = () => GettingStartedCommand.Execute(null);
|
||||
App.NavigateToUnlockBoot = () => BootUnlockCommand.Execute(null);
|
||||
|
||||
if (Registry.CurrentUser.OpenSubKey("Software\\WPInternals") == null)
|
||||
{
|
||||
Registry.CurrentUser.OpenSubKey("Software", true).CreateSubKey("WPInternals");
|
||||
}
|
||||
|
||||
if ((Registration.IsPrerelease) && (Registry.CurrentUser.OpenSubKey("Software\\WPInternals").GetValue("NdaAccepted") == null))
|
||||
{
|
||||
@@ -134,10 +140,12 @@ namespace WPinternals
|
||||
ContextViewModel = new RegistrationViewModel(Registration_Completed, Registration_Failed);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartOperation();
|
||||
}
|
||||
}
|
||||
|
||||
void Disclaimer_Accepted()
|
||||
private void Disclaimer_Accepted()
|
||||
{
|
||||
ContextViewModel = null;
|
||||
|
||||
@@ -146,16 +154,18 @@ namespace WPinternals
|
||||
ContextViewModel = new RegistrationViewModel(Registration_Completed, Registration_Failed);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartOperation();
|
||||
}
|
||||
}
|
||||
|
||||
void Registration_Completed()
|
||||
private void Registration_Completed()
|
||||
{
|
||||
ContextViewModel = null;
|
||||
StartOperation();
|
||||
}
|
||||
|
||||
void Registration_Failed()
|
||||
private void Registration_Failed()
|
||||
{
|
||||
ContextViewModel = new MessageViewModel("Registration failed", () => Environment.Exit(0));
|
||||
((MessageViewModel)ContextViewModel).SubMessage = "Check your filewall settings";
|
||||
@@ -190,10 +200,7 @@ namespace WPinternals
|
||||
ModeViewModel.OnModeSwitchRequested(TargetInterface);
|
||||
ContextViewModel = ModeViewModel;
|
||||
},
|
||||
() =>
|
||||
{
|
||||
ContextViewModel = _GettingStartedViewModel;
|
||||
});
|
||||
() => ContextViewModel = _GettingStartedViewModel);
|
||||
InfoViewModel.ActivateSubContext(null);
|
||||
|
||||
ModeViewModel = new LumiaModeViewModel(PhoneNotifier, SwitchToInfoViewModel);
|
||||
@@ -280,12 +287,12 @@ namespace WPinternals
|
||||
ContextViewModel = ModeViewModel;
|
||||
}
|
||||
|
||||
void PhoneNotifier_DeviceRemoved()
|
||||
private void PhoneNotifier_DeviceRemoved()
|
||||
{
|
||||
InfoViewModel.ActivateSubContext(null);
|
||||
}
|
||||
|
||||
void PhoneNotifier_NewDeviceArrived(ArrivalEventArgs Args)
|
||||
private void PhoneNotifier_NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
PhoneInterfaces? PreviousInterface = LastInterface;
|
||||
LastInterface = Args.NewInterface;
|
||||
@@ -299,10 +306,14 @@ namespace WPinternals
|
||||
else
|
||||
{
|
||||
if (Args.NewInterface != PhoneInterfaces.Qualcomm_Download)
|
||||
{
|
||||
App.InterruptBoot = false;
|
||||
}
|
||||
|
||||
if (ContextViewModel == null)
|
||||
{
|
||||
ContextViewModel = InfoViewModel;
|
||||
}
|
||||
else if (ContextViewModel.IsFlashModeOperation)
|
||||
{
|
||||
if ((!ContextViewModel.IsSwitchingInterface) && (Args.NewInterface == PhoneInterfaces.Lumia_Bootloader))
|
||||
@@ -318,7 +329,9 @@ namespace WPinternals
|
||||
else
|
||||
{
|
||||
if ((!ContextViewModel.IsSwitchingInterface) && (Args.NewInterface != PhoneInterfaces.Lumia_Bootloader))
|
||||
{
|
||||
ContextViewModel = InfoViewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,14 +341,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_InfoCommand == null)
|
||||
{
|
||||
_InfoCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = InfoViewModel;
|
||||
});
|
||||
}
|
||||
return _InfoCommand;
|
||||
return _InfoCommand ??= new DelegateCommand(() => ContextViewModel = InfoViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,14 +350,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ModeCommand == null)
|
||||
{
|
||||
_ModeCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = ModeViewModel;
|
||||
});
|
||||
}
|
||||
return _ModeCommand;
|
||||
return _ModeCommand ??= new DelegateCommand(() => ContextViewModel = ModeViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,14 +359,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_BootUnlockCommand == null)
|
||||
{
|
||||
_BootUnlockCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = BootUnlockViewModel;
|
||||
});
|
||||
}
|
||||
return _BootUnlockCommand;
|
||||
return _BootUnlockCommand ??= new DelegateCommand(() => ContextViewModel = BootUnlockViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,14 +368,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_BootRestoreCommand == null)
|
||||
{
|
||||
_BootRestoreCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = BootRestoreViewModel;
|
||||
});
|
||||
}
|
||||
return _BootRestoreCommand;
|
||||
return _BootRestoreCommand ??= new DelegateCommand(() => ContextViewModel = BootRestoreViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,14 +377,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_RootUnlockCommand == null)
|
||||
{
|
||||
_RootUnlockCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = RootUnlockViewModel;
|
||||
});
|
||||
}
|
||||
return _RootUnlockCommand;
|
||||
return _RootUnlockCommand ??= new DelegateCommand(() => ContextViewModel = RootUnlockViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,14 +386,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_RootUndoCommand == null)
|
||||
{
|
||||
_RootUndoCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = RootRestoreViewModel;
|
||||
});
|
||||
}
|
||||
return _RootUndoCommand;
|
||||
return _RootUndoCommand ??= new DelegateCommand(() => ContextViewModel = RootRestoreViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,14 +395,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_BackupCommand == null)
|
||||
{
|
||||
_BackupCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = BackupViewModel;
|
||||
});
|
||||
}
|
||||
return _BackupCommand;
|
||||
return _BackupCommand ??= new DelegateCommand(() => ContextViewModel = BackupViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,14 +404,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_RestoreCommand == null)
|
||||
{
|
||||
_RestoreCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = RestoreViewModel;
|
||||
});
|
||||
}
|
||||
return _RestoreCommand;
|
||||
return _RestoreCommand ??= new DelegateCommand(() => ContextViewModel = RestoreViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,14 +413,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_LumiaFlashRomCommand == null)
|
||||
{
|
||||
_LumiaFlashRomCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = LumiaFlashRomViewModel;
|
||||
});
|
||||
}
|
||||
return _LumiaFlashRomCommand;
|
||||
return _LumiaFlashRomCommand ??= new DelegateCommand(() => ContextViewModel = LumiaFlashRomViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,14 +422,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DumpRomCommand == null)
|
||||
{
|
||||
_DumpRomCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = DumpRomViewModel;
|
||||
});
|
||||
}
|
||||
return _DumpRomCommand;
|
||||
return _DumpRomCommand ??= new DelegateCommand(() => ContextViewModel = DumpRomViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,14 +431,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_AboutCommand == null)
|
||||
{
|
||||
_AboutCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = new AboutViewModel();
|
||||
});
|
||||
}
|
||||
return _AboutCommand;
|
||||
return _AboutCommand ??= new DelegateCommand(() => ContextViewModel = new AboutViewModel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,14 +440,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_OpenWebSiteCommand == null)
|
||||
{
|
||||
_OpenWebSiteCommand = new DelegateCommand(() =>
|
||||
{
|
||||
Process.Start("www.wpinternals.net");
|
||||
});
|
||||
}
|
||||
return _OpenWebSiteCommand;
|
||||
return _OpenWebSiteCommand ??= new DelegateCommand(() => Process.Start("www.wpinternals.net"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,14 +449,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DonateCommand == null)
|
||||
{
|
||||
_DonateCommand = new DelegateCommand(() =>
|
||||
{
|
||||
Process.Start("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VY8N7BCBT9CS4");
|
||||
});
|
||||
}
|
||||
return _DonateCommand;
|
||||
return _DonateCommand ??= new DelegateCommand(() => Process.Start("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VY8N7BCBT9CS4"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,14 +458,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_GettingStartedCommand == null)
|
||||
{
|
||||
_GettingStartedCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = _GettingStartedViewModel;
|
||||
});
|
||||
}
|
||||
return _GettingStartedCommand;
|
||||
return _GettingStartedCommand ??= new DelegateCommand(() => ContextViewModel = _GettingStartedViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,14 +467,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DownloadCommand == null)
|
||||
{
|
||||
_DownloadCommand = new DelegateCommand(() =>
|
||||
{
|
||||
ContextViewModel = DownloadsViewModel;
|
||||
});
|
||||
}
|
||||
return _DownloadCommand;
|
||||
return _DownloadCommand ??= new DelegateCommand(() => ContextViewModel = DownloadsViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -573,7 +481,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsMenuEnabled = value;
|
||||
OnPropertyChanged("IsMenuEnabled");
|
||||
OnPropertyChanged(nameof(IsMenuEnabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,15 @@ namespace WPinternals
|
||||
LogFile.Log(Message);
|
||||
|
||||
if (OkAction != null)
|
||||
{
|
||||
this.OkCommand = new DelegateCommand(OkAction);
|
||||
}
|
||||
|
||||
if (CancelAction != null)
|
||||
{
|
||||
this.CancelCommand = new DelegateCommand(CancelAction);
|
||||
}
|
||||
|
||||
this.Message = Message;
|
||||
}
|
||||
|
||||
@@ -46,7 +52,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Message = value;
|
||||
OnPropertyChanged("Message");
|
||||
OnPropertyChanged(nameof(Message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,34 +66,10 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_SubMessage = value;
|
||||
OnPropertyChanged("SubMessage");
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _OkCommand = null;
|
||||
public DelegateCommand OkCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _OkCommand;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_OkCommand = value;
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _CancelCommand = null;
|
||||
public DelegateCommand CancelCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CancelCommand;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_CancelCommand = value;
|
||||
OnPropertyChanged(nameof(SubMessage));
|
||||
}
|
||||
}
|
||||
public DelegateCommand OkCommand { get; } = null;
|
||||
public DelegateCommand CancelCommand { get; } = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ namespace WPinternals
|
||||
|
||||
internal class NokiaBootloaderViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaFlashModel CurrentModel;
|
||||
private Action<PhoneInterfaces> RequestModeSwitch;
|
||||
private readonly NokiaFlashModel CurrentModel;
|
||||
private readonly Action<PhoneInterfaces> RequestModeSwitch;
|
||||
internal Action SwitchToGettingStarted;
|
||||
private object LockDeviceInfo = new object();
|
||||
private readonly object LockDeviceInfo = new();
|
||||
|
||||
internal NokiaBootloaderViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted)
|
||||
: base()
|
||||
@@ -47,12 +47,13 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
new Thread(() => StartLoadDeviceInfo()).Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartLoadDeviceInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal void RebootTo(string Mode)
|
||||
|
||||
@@ -30,11 +30,11 @@ namespace WPinternals
|
||||
|
||||
internal class NokiaFlashViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaFlashModel CurrentModel;
|
||||
private Action<PhoneInterfaces> RequestModeSwitch;
|
||||
private readonly NokiaFlashModel CurrentModel;
|
||||
private readonly Action<PhoneInterfaces> RequestModeSwitch;
|
||||
internal Action SwitchToGettingStarted;
|
||||
private object LockDeviceInfo = new object();
|
||||
bool DeviceInfoLoaded = false;
|
||||
private readonly object LockDeviceInfo = new();
|
||||
private bool DeviceInfoLoaded = false;
|
||||
|
||||
internal NokiaFlashViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted)
|
||||
: base()
|
||||
@@ -48,7 +48,9 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
new Thread(() => StartLoadDeviceInfo()).Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void StartLoadDeviceInfo()
|
||||
@@ -110,7 +112,9 @@ namespace WPinternals
|
||||
FinalConfigSsmStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Ssm);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Security flags could not be read");
|
||||
}
|
||||
|
||||
PlatformName = CurrentModel.ReadStringParam("DPI");
|
||||
LogFile.Log("Platform Name: " + PlatformName);
|
||||
@@ -119,7 +123,7 @@ namespace WPinternals
|
||||
// Instead read param RRKH to get the RKH.
|
||||
PublicID = null;
|
||||
byte[] RawPublicID = CurrentModel.ReadParam("PID");
|
||||
if ((RawPublicID != null) && (RawPublicID.Length > 4))
|
||||
if (RawPublicID?.Length > 4)
|
||||
{
|
||||
PublicID = new byte[RawPublicID.Length - 4];
|
||||
Array.Copy(RawPublicID, 4, PublicID, 0, RawPublicID.Length - 4);
|
||||
@@ -132,7 +136,9 @@ namespace WPinternals
|
||||
}
|
||||
RootKeyHash = CurrentModel.ReadParam("RRKH");
|
||||
if (RootKeyHash != null)
|
||||
{
|
||||
LogFile.Log("Root Key Hash: " + Converter.ConvertHexToString(RootKeyHash, " "));
|
||||
}
|
||||
|
||||
if (SecurityStatus != null)
|
||||
{
|
||||
@@ -160,7 +166,7 @@ namespace WPinternals
|
||||
byte[] EMS = CurrentModel.ReadParam("EMS");
|
||||
if (CID != null && EMS != null)
|
||||
{
|
||||
UInt16 MID = (UInt16)(((UInt16)CID[0] << 8) + CID[1]);
|
||||
UInt16 MID = (UInt16)((CID[0] << 8) + CID[1]);
|
||||
UInt64 MemSize = (UInt64)(((UInt32)EMS[0] << 24) + ((UInt32)EMS[1] << 16) + ((UInt32)EMS[2] << 8) + EMS[3]) * 0x200;
|
||||
double MemSizeDouble = (double)MemSize / 1024 / 1024 / 1024;
|
||||
MemSizeDouble = (double)(int)(MemSizeDouble * 10) / 10;
|
||||
@@ -190,10 +196,8 @@ namespace WPinternals
|
||||
Manufacturer = "GigaDevice";
|
||||
break;
|
||||
}
|
||||
if (Manufacturer == null)
|
||||
eMMC = MemSizeDouble.ToString() + " GB";
|
||||
else
|
||||
eMMC = Manufacturer + " " + MemSizeDouble.ToString() + " GB";
|
||||
eMMC = Manufacturer == null ? MemSizeDouble.ToString() + " GB" : Manufacturer + " " + MemSizeDouble.ToString() + " GB";
|
||||
|
||||
SamsungWarningVisible = (MID == 0x0015);
|
||||
}
|
||||
else
|
||||
@@ -206,10 +210,9 @@ namespace WPinternals
|
||||
|
||||
if (chargecurrent.HasValue)
|
||||
{
|
||||
if (chargecurrent < 0)
|
||||
ChargingStatus = CurrentModel.ReadCurrentChargeLevel() + "% - " + ((-1) * CurrentModel.ReadCurrentChargeCurrent()) + " mA (discharging)";
|
||||
else
|
||||
ChargingStatus = CurrentModel.ReadCurrentChargeLevel() + "% - " + CurrentModel.ReadCurrentChargeCurrent() + " mA (charging)";
|
||||
ChargingStatus = chargecurrent < 0
|
||||
? CurrentModel.ReadCurrentChargeLevel() + "% - " + ((-1) * CurrentModel.ReadCurrentChargeCurrent()) + " mA (discharging)"
|
||||
: CurrentModel.ReadCurrentChargeLevel() + "% - " + CurrentModel.ReadCurrentChargeCurrent() + " mA (charging)";
|
||||
|
||||
LogFile.Log("Charging status: " + ChargingStatus);
|
||||
}
|
||||
@@ -220,10 +223,8 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
PhoneInfo Info = CurrentModel.ReadPhoneInfo(true);
|
||||
if (Info.FlashAppProtocolVersionMajor < 2)
|
||||
BootloaderDescription = "Lumia Bootloader Spec A";
|
||||
else
|
||||
BootloaderDescription = "Lumia Bootloader Spec B";
|
||||
BootloaderDescription = Info.FlashAppProtocolVersionMajor < 2 ? "Lumia Bootloader Spec A" : "Lumia Bootloader Spec B";
|
||||
|
||||
LogFile.Log("Bootloader: " + BootloaderDescription);
|
||||
|
||||
ProductCode = Info.ProductCode;
|
||||
@@ -239,7 +240,9 @@ namespace WPinternals
|
||||
RootKeyHash = Info.RKH;
|
||||
|
||||
if (RootKeyHash != null)
|
||||
{
|
||||
LogFile.Log("Root Key Hash: " + Converter.ConvertHexToString(RootKeyHash, " "));
|
||||
}
|
||||
else
|
||||
{
|
||||
RootKeyHash = new byte[32];
|
||||
@@ -298,7 +301,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_PublicID = value;
|
||||
OnPropertyChanged("PublicID");
|
||||
OnPropertyChanged(nameof(PublicID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +315,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_RootKeyHash = value;
|
||||
OnPropertyChanged("RootKeyHash");
|
||||
OnPropertyChanged(nameof(RootKeyHash));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +329,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_PlatformName = value;
|
||||
OnPropertyChanged("PlatformName");
|
||||
OnPropertyChanged(nameof(PlatformName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +343,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_ProductType = value;
|
||||
OnPropertyChanged("ProductType");
|
||||
OnPropertyChanged(nameof(ProductType));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +357,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_ProductCode = value;
|
||||
OnPropertyChanged("ProductCode");
|
||||
OnPropertyChanged(nameof(ProductCode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +371,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_eMMC = value;
|
||||
OnPropertyChanged("eMMC");
|
||||
OnPropertyChanged(nameof(eMMC));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +385,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_BootloaderDescription = value;
|
||||
OnPropertyChanged("BootloaderDescription");
|
||||
OnPropertyChanged(nameof(BootloaderDescription));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,7 +399,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_ChargingStatus = value;
|
||||
OnPropertyChanged("ChargingStatus");
|
||||
OnPropertyChanged(nameof(ChargingStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,7 +413,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_SamsungWarningVisible = value;
|
||||
OnPropertyChanged("SamsungWarningVisible");
|
||||
OnPropertyChanged(nameof(SamsungWarningVisible));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,7 +427,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_PlatformSecureBootStatus = value;
|
||||
OnPropertyChanged("PlatformSecureBootStatus");
|
||||
OnPropertyChanged(nameof(PlatformSecureBootStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,7 +441,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_BootloaderSecurityQfuseStatus = value;
|
||||
OnPropertyChanged("BootloaderSecurityQfuseStatus");
|
||||
OnPropertyChanged(nameof(BootloaderSecurityQfuseStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,7 +455,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_BootloaderSecurityRdcStatus = value;
|
||||
OnPropertyChanged("BootloaderSecurityRdcStatus");
|
||||
OnPropertyChanged(nameof(BootloaderSecurityRdcStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +469,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_BootloaderSecurityAuthenticationStatus = value;
|
||||
OnPropertyChanged("BootloaderSecurityAuthenticationStatus");
|
||||
OnPropertyChanged(nameof(BootloaderSecurityAuthenticationStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,7 +483,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_UefiSecureBootStatus = value;
|
||||
OnPropertyChanged("UefiSecureBootStatus");
|
||||
OnPropertyChanged(nameof(UefiSecureBootStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,7 +497,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_EffectiveSecureBootStatus = value;
|
||||
OnPropertyChanged("EffectiveSecureBootStatus");
|
||||
OnPropertyChanged(nameof(EffectiveSecureBootStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,7 +511,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_EffectiveBootloaderSecurityStatus = value;
|
||||
OnPropertyChanged("EffectiveBootloaderSecurityStatus");
|
||||
OnPropertyChanged(nameof(EffectiveBootloaderSecurityStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +525,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_NativeDebugStatus = value;
|
||||
OnPropertyChanged("NativeDebugStatus");
|
||||
OnPropertyChanged(nameof(NativeDebugStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,7 +540,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigSecureBootStatus = value;
|
||||
OnPropertyChanged("FinalConfigSecureBootStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigSecureBootStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,7 +554,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigFfuVerifyStatus = value;
|
||||
OnPropertyChanged("FinalConfigFfuVerifyStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigFfuVerifyStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +568,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigJtagStatus = value;
|
||||
OnPropertyChanged("FinalConfigJtagStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigJtagStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,7 +582,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigShkStatus = value;
|
||||
OnPropertyChanged("FinalConfigShkStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigShkStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,7 +596,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigSimlockStatus = value;
|
||||
OnPropertyChanged("FinalConfigSimlockStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigSimlockStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,7 +610,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigProductionDoneStatus = value;
|
||||
OnPropertyChanged("FinalConfigProductionDoneStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigProductionDoneStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,7 +624,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigRkhStatus = value;
|
||||
OnPropertyChanged("FinalConfigRkhStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigRkhStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,7 +638,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigPublicIdStatus = value;
|
||||
OnPropertyChanged("FinalConfigPublicIdStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigPublicIdStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,7 +652,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigDakStatus = value;
|
||||
OnPropertyChanged("FinalConfigDakStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigDakStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,7 +666,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigSecGenStatus = value;
|
||||
OnPropertyChanged("FinalConfigSecGenStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigSecGenStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,7 +680,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigOemIdStatus = value;
|
||||
OnPropertyChanged("FinalConfigOemIdStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigOemIdStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,7 +694,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigFastBootStatus = value;
|
||||
OnPropertyChanged("FinalConfigFastBootStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigFastBootStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,7 +708,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigSpdmSecModeStatus = value;
|
||||
OnPropertyChanged("FinalConfigSpdmSecModeStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigSpdmSecModeStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,7 +722,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigRpmWdogStatus = value;
|
||||
OnPropertyChanged("FinalConfigRpmWdogStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigRpmWdogStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -733,7 +736,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_FinalConfigSsmStatus = value;
|
||||
OnPropertyChanged("FinalConfigSsmStatus");
|
||||
OnPropertyChanged(nameof(FinalConfigSsmStatus));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace WPinternals
|
||||
|
||||
internal class NokiaLabelViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaPhoneModel CurrentModel;
|
||||
private Action<PhoneInterfaces> RequestModeSwitch;
|
||||
private readonly NokiaPhoneModel CurrentModel;
|
||||
private readonly Action<PhoneInterfaces> RequestModeSwitch;
|
||||
|
||||
internal NokiaLabelViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch)
|
||||
: base()
|
||||
@@ -74,7 +74,7 @@ namespace WPinternals
|
||||
|
||||
byte[] AsskMask = new byte[0x10] { 1, 0, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64 };
|
||||
byte[] Challenge = new byte[0x88];
|
||||
Dictionary<string, object> Params = new Dictionary<string, object>();
|
||||
Dictionary<string, object> Params = new();
|
||||
Params.Add("AsskMask", AsskMask);
|
||||
Params.Add("Challenge", Challenge);
|
||||
Params.Add("AsicIndex", 0);
|
||||
@@ -108,13 +108,17 @@ namespace WPinternals
|
||||
IsBootloaderSecurityEnabled = (bool)CurrentModel.ExecuteJsonMethodAsBoolean("ReadProductionDoneState", "ProductionDone");
|
||||
LogFile.Log("Bootloader Security: " + ((bool)IsBootloaderSecurityEnabled ? "Enabled" : "Disabled"));
|
||||
|
||||
Params = new Dictionary<string, object>();
|
||||
Params.Add("ID", 3534);
|
||||
Params.Add("NVData", new byte[] { 0 });
|
||||
Params = new Dictionary<string, object>
|
||||
{
|
||||
{ "ID", 3534 },
|
||||
{ "NVData", new byte[] { 0 } }
|
||||
};
|
||||
CurrentModel.ExecuteJsonMethod("WriteNVData", Params); // Error: 150
|
||||
|
||||
Params = new Dictionary<string, object>();
|
||||
Params.Add("ID", 3534);
|
||||
Params = new Dictionary<string, object>
|
||||
{
|
||||
{ "ID", 3534 }
|
||||
};
|
||||
byte[] NV3534 = CurrentModel.ExecuteJsonMethodAsBytes("ReadNVData", Params, "NVData"); // Error: value not written
|
||||
}
|
||||
|
||||
@@ -128,7 +132,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_ProductCode = value;
|
||||
OnPropertyChanged("ProductCode");
|
||||
OnPropertyChanged(nameof(ProductCode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +146,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_ManufacturerModelName = value;
|
||||
OnPropertyChanged("ManufacturerModelName");
|
||||
OnPropertyChanged(nameof(ManufacturerModelName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +160,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Operator = value;
|
||||
OnPropertyChanged("Operator");
|
||||
OnPropertyChanged(nameof(Operator));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +174,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Firmware = value;
|
||||
OnPropertyChanged("Firmware");
|
||||
OnPropertyChanged(nameof(Firmware));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +188,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IMEI = value;
|
||||
OnPropertyChanged("IMEI");
|
||||
OnPropertyChanged(nameof(IMEI));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +202,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_PublicID = value;
|
||||
OnPropertyChanged("PublicID");
|
||||
OnPropertyChanged(nameof(PublicID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +216,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_RootKeyHash = value;
|
||||
OnPropertyChanged("RootKeyHash");
|
||||
OnPropertyChanged(nameof(RootKeyHash));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +230,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_WlanMac = value;
|
||||
OnPropertyChanged("WlanMac");
|
||||
OnPropertyChanged(nameof(WlanMac));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +244,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_BluetoothMac = value;
|
||||
OnPropertyChanged("BluetoothMac");
|
||||
OnPropertyChanged(nameof(BluetoothMac));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +258,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsBootloaderSecurityEnabled = value;
|
||||
OnPropertyChanged("IsBootloaderSecurityEnabled");
|
||||
OnPropertyChanged(nameof(IsBootloaderSecurityEnabled));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +272,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsSimLocked = value;
|
||||
OnPropertyChanged("IsSimLocked");
|
||||
OnPropertyChanged(nameof(IsSimLocked));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,22 +22,14 @@ namespace WPinternals
|
||||
{
|
||||
internal class NokiaMassStorageViewModel : ContextViewModel
|
||||
{
|
||||
private MassStorage CurrentModel;
|
||||
private readonly MassStorage CurrentModel;
|
||||
|
||||
internal NokiaMassStorageViewModel(MassStorage CurrentModel)
|
||||
: base()
|
||||
{
|
||||
this.CurrentModel = CurrentModel;
|
||||
_Drive = CurrentModel.Drive;
|
||||
}
|
||||
|
||||
private string _Drive = null;
|
||||
public string Drive
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Drive;
|
||||
}
|
||||
Drive = CurrentModel.Drive;
|
||||
}
|
||||
public string Drive { get; } = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,10 @@ namespace WPinternals
|
||||
{
|
||||
internal class NokiaModeBootloaderViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaFlashModel CurrentModel;
|
||||
Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
private object LockDeviceInfo = new object();
|
||||
bool DeviceInfoLoaded = false;
|
||||
private readonly NokiaFlashModel CurrentModel;
|
||||
private readonly Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
private readonly object LockDeviceInfo = new();
|
||||
private bool DeviceInfoLoaded = false;
|
||||
|
||||
internal NokiaModeBootloaderViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
|
||||
: base()
|
||||
@@ -40,7 +40,9 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
new Thread(() => StartLoadDeviceInfo()).Start();
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _EffectiveBootloaderSecurityStatus = null;
|
||||
@@ -53,7 +55,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_EffectiveBootloaderSecurityStatus = value;
|
||||
OnPropertyChanged("EffectiveBootloaderSecurityStatus");
|
||||
OnPropertyChanged(nameof(EffectiveBootloaderSecurityStatus));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@ namespace WPinternals
|
||||
{
|
||||
internal class NokiaModeFlashViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaFlashModel CurrentModel;
|
||||
Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
private object LockDeviceInfo = new object();
|
||||
bool DeviceInfoLoaded = false;
|
||||
private readonly NokiaFlashModel CurrentModel;
|
||||
private readonly Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
private readonly object LockDeviceInfo = new();
|
||||
private bool DeviceInfoLoaded = false;
|
||||
|
||||
internal NokiaModeFlashViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
|
||||
: base()
|
||||
@@ -40,7 +40,9 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
new Thread(() => StartLoadDeviceInfo()).Start();
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _EffectiveBootloaderSecurityStatus = null;
|
||||
@@ -53,7 +55,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_EffectiveBootloaderSecurityStatus = value;
|
||||
OnPropertyChanged("EffectiveBootloaderSecurityStatus");
|
||||
OnPropertyChanged(nameof(EffectiveBootloaderSecurityStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,14 +73,9 @@ namespace WPinternals
|
||||
{
|
||||
UefiSecurityStatusResponse SecurityStatus = CurrentModel.ReadSecurityStatus();
|
||||
|
||||
if (SecurityStatus != null)
|
||||
{
|
||||
EffectiveBootloaderSecurityStatus = SecurityStatus.SecureFfuEfuseStatus && !SecurityStatus.AuthenticationStatus && !SecurityStatus.RdcStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
EffectiveBootloaderSecurityStatus = !Info.IsBootloaderSecure;
|
||||
}
|
||||
EffectiveBootloaderSecurityStatus = SecurityStatus != null
|
||||
? SecurityStatus.SecureFfuEfuseStatus && !SecurityStatus.AuthenticationStatus && !SecurityStatus.RdcStatus
|
||||
: !Info.IsBootloaderSecure;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace WPinternals
|
||||
{
|
||||
internal class NokiaModeLabelViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaPhoneModel CurrentModel;
|
||||
private Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
private readonly NokiaPhoneModel CurrentModel;
|
||||
private readonly Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
|
||||
internal NokiaModeLabelViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
|
||||
: base()
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace WPinternals
|
||||
{
|
||||
internal class NokiaModeMassStorageViewModel : ContextViewModel
|
||||
{
|
||||
private MassStorage CurrentModel;
|
||||
private Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
private readonly MassStorage CurrentModel;
|
||||
private readonly Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
|
||||
internal NokiaModeMassStorageViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
|
||||
: base()
|
||||
@@ -44,14 +44,16 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_SupportsReboot = value;
|
||||
OnPropertyChanged("SupportsReboot");
|
||||
OnPropertyChanged(nameof(SupportsReboot));
|
||||
}
|
||||
}
|
||||
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
SupportsReboot = CurrentModel.DoesDeviceSupportReboot();
|
||||
}
|
||||
}
|
||||
|
||||
public void RebootTo(string Mode)
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace WPinternals
|
||||
{
|
||||
internal class NokiaModeNormalViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaPhoneModel CurrentModel;
|
||||
private Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
private readonly NokiaPhoneModel CurrentModel;
|
||||
private readonly Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
|
||||
internal NokiaModeNormalViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
|
||||
: base()
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace WPinternals
|
||||
|
||||
internal class NokiaNormalViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaPhoneModel CurrentModel;
|
||||
private Action<PhoneInterfaces> RequestModeSwitch;
|
||||
private readonly NokiaPhoneModel CurrentModel;
|
||||
private readonly Action<PhoneInterfaces> RequestModeSwitch;
|
||||
|
||||
internal NokiaNormalViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch)
|
||||
: base()
|
||||
@@ -61,7 +61,9 @@ namespace WPinternals
|
||||
string IMEI2 = CurrentModel.ExecuteJsonMethodAsString("ReadSerialNumber", new System.Collections.Generic.Dictionary<string, object>() { { "SubscriptionId", 1 } }, "SerialNumber"); // IMEI 2
|
||||
|
||||
if (!string.IsNullOrEmpty(IMEI2))
|
||||
{
|
||||
IMEI += "\n" + IMEI2;
|
||||
}
|
||||
|
||||
LogFile.Log("IMEI: " + IMEI);
|
||||
PublicID = CurrentModel.ExecuteJsonMethodAsBytes("ReadPublicId", "PublicId"); // 0x14 bytes: a5 e5 ...
|
||||
@@ -78,10 +80,10 @@ namespace WPinternals
|
||||
LogFile.Log("WLAN MAC 4: " + Converter.ConvertHexToString(WlanMac4, " "));
|
||||
|
||||
bool? ProductionDone = CurrentModel.ExecuteJsonMethodAsBoolean("ReadProductionDoneState", "ProductionDone");
|
||||
if (ProductionDone == null)
|
||||
IsBootloaderSecurityEnabled = (CurrentModel.ExecuteJsonMethodAsString("GetSecurityMode", "SecMode").IndexOf("Restricted", StringComparison.OrdinalIgnoreCase) >= 0);
|
||||
else
|
||||
IsBootloaderSecurityEnabled = ((CurrentModel.ExecuteJsonMethodAsString("GetSecurityMode", "SecMode").IndexOf("Restricted", StringComparison.OrdinalIgnoreCase) >= 0) && (bool)CurrentModel.ExecuteJsonMethodAsBoolean("ReadProductionDoneState", "ProductionDone"));
|
||||
IsBootloaderSecurityEnabled = ProductionDone == null
|
||||
? CurrentModel.ExecuteJsonMethodAsString("GetSecurityMode", "SecMode").Contains("Restricted", StringComparison.OrdinalIgnoreCase)
|
||||
: (CurrentModel.ExecuteJsonMethodAsString("GetSecurityMode", "SecMode").Contains("Restricted", StringComparison.OrdinalIgnoreCase)) && (bool)CurrentModel.ExecuteJsonMethodAsBoolean("ReadProductionDoneState", "ProductionDone");
|
||||
|
||||
LogFile.Log("Bootloader Security: " + ((bool)IsBootloaderSecurityEnabled ? "Enabled" : "Disabled"));
|
||||
IsSimLocked = CurrentModel.ExecuteJsonMethodAsBoolean("ReadSimlockActive", "SimLockActive");
|
||||
LogFile.Log("Simlock: " + ((bool)IsSimLocked ? "Active" : "Unlocked"));
|
||||
@@ -116,7 +118,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_ProductCode = value;
|
||||
OnPropertyChanged("ProductCode");
|
||||
OnPropertyChanged(nameof(ProductCode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +132,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_ManufacturerModelName = value;
|
||||
OnPropertyChanged("ManufacturerModelName");
|
||||
OnPropertyChanged(nameof(ManufacturerModelName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +146,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Operator = value;
|
||||
OnPropertyChanged("Operator");
|
||||
OnPropertyChanged(nameof(Operator));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +160,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Firmware = value;
|
||||
OnPropertyChanged("Firmware");
|
||||
OnPropertyChanged(nameof(Firmware));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +174,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_HWID = value;
|
||||
OnPropertyChanged("HWID");
|
||||
OnPropertyChanged(nameof(HWID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +188,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IMEI = value;
|
||||
OnPropertyChanged("IMEI");
|
||||
OnPropertyChanged(nameof(IMEI));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,11 +202,10 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_BootPolicy = value;
|
||||
OnPropertyChanged("BootPolicy");
|
||||
OnPropertyChanged(nameof(BootPolicy));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _Db = null;
|
||||
public string Db
|
||||
{
|
||||
@@ -215,11 +216,10 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Db = value;
|
||||
OnPropertyChanged("Db");
|
||||
OnPropertyChanged(nameof(Db));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _Dbx = null;
|
||||
public string Dbx
|
||||
{
|
||||
@@ -230,11 +230,10 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Dbx = value;
|
||||
OnPropertyChanged("Dbx");
|
||||
OnPropertyChanged(nameof(Dbx));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _Kek = null;
|
||||
public string Kek
|
||||
{
|
||||
@@ -245,11 +244,10 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Kek = value;
|
||||
OnPropertyChanged("Kek");
|
||||
OnPropertyChanged(nameof(Kek));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _Pk = null;
|
||||
public string Pk
|
||||
{
|
||||
@@ -260,7 +258,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Pk = value;
|
||||
OnPropertyChanged("Pk");
|
||||
OnPropertyChanged(nameof(Pk));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +272,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_PublicID = value;
|
||||
OnPropertyChanged("PublicID");
|
||||
OnPropertyChanged(nameof(PublicID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +286,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_WlanMac1 = value;
|
||||
OnPropertyChanged("WlanMac1");
|
||||
OnPropertyChanged(nameof(WlanMac1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +300,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_WlanMac2 = value;
|
||||
OnPropertyChanged("WlanMac2");
|
||||
OnPropertyChanged(nameof(WlanMac2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +314,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_WlanMac3 = value;
|
||||
OnPropertyChanged("WlanMac3");
|
||||
OnPropertyChanged(nameof(WlanMac3));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,7 +328,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_WlanMac4 = value;
|
||||
OnPropertyChanged("WlanMac4");
|
||||
OnPropertyChanged(nameof(WlanMac4));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +342,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_BluetoothMac = value;
|
||||
OnPropertyChanged("BluetoothMac");
|
||||
OnPropertyChanged(nameof(BluetoothMac));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,7 +356,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsBootloaderSecurityEnabled = value;
|
||||
OnPropertyChanged("IsBootloaderSecurityEnabled");
|
||||
OnPropertyChanged(nameof(IsBootloaderSecurityEnabled));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +370,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_IsSimLocked = value;
|
||||
OnPropertyChanged("IsSimLocked");
|
||||
OnPropertyChanged(nameof(IsSimLocked));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,23 +49,21 @@ namespace WPinternals
|
||||
public event NewDeviceArrivedEvent NewDeviceArrived = delegate { };
|
||||
public event DeviceRemovedEvent DeviceRemoved = delegate { };
|
||||
|
||||
private Guid OldCombiInterfaceGuid = new("{0FD3B15C-D457-45d8-A779-C2B2C9F9D0FD}");
|
||||
private Guid NewCombiInterfaceGuid = new("{7eaff726-34cc-4204-b09d-f95471b873cf}");
|
||||
|
||||
private Guid OldCombiInterfaceGuid = new Guid("{0FD3B15C-D457-45d8-A779-C2B2C9F9D0FD}");
|
||||
private Guid NewCombiInterfaceGuid = new Guid("{7eaff726-34cc-4204-b09d-f95471b873cf}");
|
||||
private Guid MassStorageInterfaceGuid = new("{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}");
|
||||
private Guid ComPortInterfaceGuid = new("{86E0D1E0-8089-11D0-9CE4-08003E301F73}");
|
||||
private Guid HidInterfaceGuid = new("{4D1E55B2-F16F-11CF-88CB-001111000030}");
|
||||
|
||||
private Guid MassStorageInterfaceGuid = new Guid("{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}");
|
||||
private Guid ComPortInterfaceGuid = new Guid("{86E0D1E0-8089-11D0-9CE4-08003E301F73}");
|
||||
private Guid HidInterfaceGuid = new Guid("{4D1E55B2-F16F-11CF-88CB-001111000030}");
|
||||
private Guid LumiaNormalInterfaceGuid = new("{08324F9C-B621-435C-859B-AE4652481B7C}");
|
||||
private Guid LumiaLabelInterfaceGuid = new("{F4FE0C27-7304-4ED7-AAB5-130893B84B6F}");
|
||||
private Guid LumiaFlashInterfaceGuid = new("{9e3bd5f7-9690-4fcc-8810-3e2650cd6ecc}");
|
||||
private Guid LumiaEmergencyInterfaceGuid = new("{71DE994D-8B7C-43DB-A27E-2AE7CD579A0C}");
|
||||
|
||||
private Guid LumiaNormalInterfaceGuid = new Guid("{08324F9C-B621-435C-859B-AE4652481B7C}");
|
||||
private Guid LumiaLabelInterfaceGuid = new Guid("{F4FE0C27-7304-4ED7-AAB5-130893B84B6F}");
|
||||
private Guid LumiaFlashInterfaceGuid = new Guid("{9e3bd5f7-9690-4fcc-8810-3e2650cd6ecc}");
|
||||
private Guid LumiaEmergencyInterfaceGuid = new Guid("{71DE994D-8B7C-43DB-A27E-2AE7CD579A0C}");
|
||||
private readonly object ModelLock = new();
|
||||
|
||||
|
||||
private object ModelLock = new object();
|
||||
|
||||
private EventWaitHandle NewInterfaceWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||
private readonly EventWaitHandle NewInterfaceWaitHandle = new(false, EventResetMode.AutoReset);
|
||||
|
||||
private EventLogWatcher LogWatcher;
|
||||
|
||||
@@ -111,9 +109,9 @@ namespace WPinternals
|
||||
|
||||
try
|
||||
{
|
||||
EventLogQuery LogQuery = new EventLogQuery("Microsoft-Windows-Kernel-PnP/Configuration", PathType.LogName, "*[System[(EventID = 411)]]");
|
||||
EventLogQuery LogQuery = new("Microsoft-Windows-Kernel-PnP/Configuration", PathType.LogName, "*[System[(EventID = 411)]]");
|
||||
LogWatcher = new EventLogWatcher(LogQuery);
|
||||
LogWatcher.EventRecordWritten += new EventHandler<EventRecordWrittenEventArgs>(PnPEventWritten);
|
||||
LogWatcher.EventRecordWritten += PnPEventWritten;
|
||||
LogWatcher.Enabled = true;
|
||||
App.IsPnPEventLogMissing = false;
|
||||
}
|
||||
@@ -155,19 +153,21 @@ namespace WPinternals
|
||||
internal void NotifyArrival()
|
||||
{
|
||||
if (CurrentInterface != null)
|
||||
{
|
||||
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
|
||||
}
|
||||
}
|
||||
|
||||
void LumiaNotifier_Arrival(object sender, USBEvent e)
|
||||
private void LumiaNotifier_Arrival(object sender, USBEvent e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((e.DevicePath.IndexOf("VID_0421&", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_045E&", StringComparison.OrdinalIgnoreCase) >= 0))
|
||||
if ((e.DevicePath.Contains("VID_0421&", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_045E&", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
if ((e.DevicePath.IndexOf("&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("&PID_0713&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) || // for Spec B
|
||||
(e.DevicePath.IndexOf("&PID_0A01&MI_04", StringComparison.OrdinalIgnoreCase) >= 0)) // for Spec B (650)
|
||||
if ((e.DevicePath.Contains("&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("&PID_0713&MI_04", StringComparison.OrdinalIgnoreCase)) || // for Spec B
|
||||
(e.DevicePath.Contains("&PID_0A01&MI_04", StringComparison.OrdinalIgnoreCase))) // for Spec B (650)
|
||||
{
|
||||
CurrentInterface = PhoneInterfaces.Lumia_Label;
|
||||
CurrentModel = new NokiaPhoneModel(e.DevicePath);
|
||||
@@ -177,15 +177,17 @@ namespace WPinternals
|
||||
LogFile.Log("Mode: Label", LogType.FileAndConsole);
|
||||
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
|
||||
}
|
||||
else if ((e.DevicePath.IndexOf("&PID_0661", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("&PID_06FC", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_06FC is for Lumia 930
|
||||
(e.DevicePath.IndexOf("&PID_0A00", StringComparison.OrdinalIgnoreCase) >= 0)) // vid_045e & pid_0a00 & mi_03 = Lumia 950 XL normal mode
|
||||
else if ((e.DevicePath.Contains("&PID_0661", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("&PID_06FC", StringComparison.OrdinalIgnoreCase)) || // VID_0421&PID_06FC is for Lumia 930
|
||||
(e.DevicePath.Contains("&PID_0A00", StringComparison.OrdinalIgnoreCase))) // vid_045e & pid_0a00 & mi_03 = Lumia 950 XL normal mode
|
||||
{
|
||||
if (((USBNotifier)sender).Guid == OldCombiInterfaceGuid)
|
||||
{
|
||||
NewInterfaceWaitHandle.Reset();
|
||||
if (USBDevice.GetDevices(NewCombiInterfaceGuid).Count() > 0)
|
||||
if (USBDevice.GetDevices(NewCombiInterfaceGuid).Length > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Old combi-interface was detected, but new combi-interface was not detected.
|
||||
@@ -227,10 +229,10 @@ namespace WPinternals
|
||||
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
|
||||
}
|
||||
}
|
||||
else if ((e.DevicePath.IndexOf("&PID_066E", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("&PID_0714", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_0714 is for Lumia 930
|
||||
(e.DevicePath.IndexOf("&PID_0A02", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_045E&PID_0A02 is for Lumia 950
|
||||
(e.DevicePath.IndexOf("&PID_05EE", StringComparison.OrdinalIgnoreCase) >= 0)) // VID_0421&PID_05EE is for early RX100
|
||||
else if ((e.DevicePath.Contains("&PID_066E", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("&PID_0714", StringComparison.OrdinalIgnoreCase)) || // VID_0421&PID_0714 is for Lumia 930
|
||||
(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
|
||||
{
|
||||
CurrentModel = new NokiaFlashModel(e.DevicePath);
|
||||
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
|
||||
@@ -282,8 +284,8 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((e.DevicePath.IndexOf(@"DISK&VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf(@"DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
else if ((e.DevicePath.Contains("DISK&VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase)) ||
|
||||
((e.DevicePath.Length == @"\\.\E:".Length) && (e.DevicePath.StartsWith(@"\\.\")) && (e.DevicePath.EndsWith(":"))))
|
||||
{
|
||||
#if DEBUG
|
||||
@@ -307,7 +309,7 @@ namespace WPinternals
|
||||
// not for MainOS.
|
||||
Task.Delay(1000).Wait();
|
||||
|
||||
MassStorage NewModel = new MassStorage(e.DevicePath);
|
||||
MassStorage NewModel = new(e.DevicePath);
|
||||
|
||||
if (NewModel.Drive != null) // When logical drive is already known, we use this model. Or else we wait for the logical drive to arrive.
|
||||
{
|
||||
@@ -329,13 +331,13 @@ namespace WPinternals
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (e.DevicePath.IndexOf("VID_05C6&", StringComparison.OrdinalIgnoreCase) >= 0) // Qualcomm device
|
||||
else if (e.DevicePath.Contains("VID_05C6&", StringComparison.OrdinalIgnoreCase)) // Qualcomm device
|
||||
{
|
||||
if (e.DevicePath.IndexOf("&PID_9008", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
if (e.DevicePath.Contains("&PID_9008", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
USBDeviceInfo DeviceInfo = USBDevice.GetDevices(((USBNotifier)sender).Guid).Where((d) => string.Compare(d.DevicePath, e.DevicePath, true) == 0).FirstOrDefault();
|
||||
USBDeviceInfo DeviceInfo = Array.Find(USBDevice.GetDevices(((USBNotifier)sender).Guid), (d) => string.Compare(d.DevicePath, e.DevicePath, true) == 0);
|
||||
|
||||
if ((DeviceInfo.BusName == "QHSUSB_DLOAD") || (DeviceInfo.BusName == "QHSUSB__BULK") || ((DeviceInfo.BusName == "") && (LastInterface != PhoneInterfaces.Qualcomm_Download))) // TODO: Separate for Sahara!
|
||||
if ((DeviceInfo.BusName == "QHSUSB_DLOAD") || (DeviceInfo.BusName == "QHSUSB__BULK") || ((DeviceInfo.BusName?.Length == 0) && (LastInterface != PhoneInterfaces.Qualcomm_Download))) // TODO: Separate for Sahara!
|
||||
{
|
||||
CurrentInterface = PhoneInterfaces.Qualcomm_Download;
|
||||
CurrentModel = new QualcommSerial(e.DevicePath);
|
||||
@@ -343,12 +345,16 @@ namespace WPinternals
|
||||
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
|
||||
LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
|
||||
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
|
||||
if (DeviceInfo.BusName == "")
|
||||
if (DeviceInfo.BusName?.Length == 0)
|
||||
{
|
||||
LogFile.Log("Driver does not show busname, assume mode: Qualcomm Emergency Download 9008", LogType.FileAndConsole);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Mode: Qualcomm Emergency Download 9008", LogType.FileAndConsole);
|
||||
}
|
||||
}
|
||||
else if ((DeviceInfo.BusName == "QHSUSB_ARMPRG") || ((DeviceInfo.BusName == "") && (LastInterface == PhoneInterfaces.Qualcomm_Download)))
|
||||
else if ((DeviceInfo.BusName == "QHSUSB_ARMPRG") || ((DeviceInfo.BusName?.Length == 0) && (LastInterface == PhoneInterfaces.Qualcomm_Download)))
|
||||
{
|
||||
CurrentInterface = PhoneInterfaces.Qualcomm_Flash;
|
||||
CurrentModel = new QualcommSerial(e.DevicePath);
|
||||
@@ -356,13 +362,17 @@ namespace WPinternals
|
||||
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
|
||||
LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
|
||||
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
|
||||
if (DeviceInfo.BusName == "")
|
||||
if (DeviceInfo.BusName?.Length == 0)
|
||||
{
|
||||
LogFile.Log("Driver does not show busname, assume mode: Qualcomm Emergency Flash 9008", LogType.FileAndConsole);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Mode: Qualcomm Emergency Flash 9008", LogType.FileAndConsole);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (e.DevicePath.IndexOf("&PID_9006", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
else if (e.DevicePath.Contains("&PID_9006", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// This is part of the Mass Storage inteface.
|
||||
// It is a slightly different version of the Qualcomm Emergency interface, which is implemented in SBL3.
|
||||
@@ -382,7 +392,7 @@ namespace WPinternals
|
||||
((MassStorage)CurrentModel).AttachQualcommSerial(Qcom9006DevicePath);
|
||||
}
|
||||
}
|
||||
else if (e.DevicePath.IndexOf("&PID_F006", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
else if (e.DevicePath.Contains("&PID_F006", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// This is part of the charging inteface.
|
||||
|
||||
@@ -406,31 +416,34 @@ namespace WPinternals
|
||||
CurrentInterface = NewInterface;
|
||||
}
|
||||
|
||||
void LumiaNotifier_Removal(object sender, USBEvent e)
|
||||
private void LumiaNotifier_Removal(object sender, USBEvent e)
|
||||
{
|
||||
if (e.DevicePath.IndexOf("VID_05C6&PID_9006", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
if (e.DevicePath.Contains("VID_05C6&PID_9006", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Qcom9006DevicePath = null;
|
||||
}
|
||||
|
||||
if (
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_0713&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_045E&PID_0A01&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_0661", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_06FC", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_066E", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_0714", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_05EE", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_045E&PID_0A00", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_045E&PID_0A02", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_05C6&PID_9008", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf(@"DISK&VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf(@"DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
(e.DevicePath.Contains("VID_0421&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_0421&PID_0713&MI_04", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_045E&PID_0A01&MI_04", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_0421&PID_0661", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_0421&PID_06FC", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_0421&PID_066E", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_0421&PID_0714", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_0421&PID_05EE", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_045E&PID_0A00", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_045E&PID_0A02", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("VID_05C6&PID_9008", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("DISK&VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.OrdinalIgnoreCase)) ||
|
||||
(e.DevicePath.Contains("DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase))
|
||||
)
|
||||
{
|
||||
if (CurrentInterface != null)
|
||||
{
|
||||
LastInterface = CurrentInterface;
|
||||
}
|
||||
|
||||
CurrentInterface = null;
|
||||
if (CurrentModel != null)
|
||||
{
|
||||
@@ -447,16 +460,18 @@ namespace WPinternals
|
||||
IDisposable Result = null;
|
||||
|
||||
if (CurrentInterface == null)
|
||||
{
|
||||
LogFile.Log("Waiting for phone to connect...", LogType.FileOnly);
|
||||
}
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
System.Threading.AutoResetEvent e = new System.Threading.AutoResetEvent(false);
|
||||
NewDeviceArrivedEvent Arrived = (a) =>
|
||||
{
|
||||
e.Set();
|
||||
Result = a.NewModel;
|
||||
};
|
||||
AutoResetEvent e = new(false);
|
||||
void Arrived(ArrivalEventArgs a)
|
||||
{
|
||||
e.Set();
|
||||
Result = a.NewModel;
|
||||
}
|
||||
NewDeviceArrived += Arrived;
|
||||
e.WaitOne();
|
||||
NewDeviceArrived -= Arrived;
|
||||
@@ -471,11 +486,8 @@ namespace WPinternals
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
System.Threading.AutoResetEvent e = new System.Threading.AutoResetEvent(false);
|
||||
DeviceRemovedEvent Removed = () =>
|
||||
{
|
||||
e.Set();
|
||||
};
|
||||
AutoResetEvent e = new(false);
|
||||
void Removed() => e.Set();
|
||||
DeviceRemoved += Removed;
|
||||
e.WaitOne();
|
||||
DeviceRemoved -= Removed;
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace WPinternals
|
||||
{
|
||||
internal class RegistrationViewModel : ContextViewModel
|
||||
{
|
||||
Action Completed;
|
||||
Action Failed;
|
||||
private readonly Action Completed;
|
||||
private readonly Action Failed;
|
||||
|
||||
internal RegistrationViewModel(Action Completed, Action Failed)
|
||||
: base()
|
||||
@@ -40,14 +40,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ExitCommand == null)
|
||||
{
|
||||
_ExitCommand = new DelegateCommand(() =>
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
});
|
||||
}
|
||||
return _ExitCommand;
|
||||
return _ExitCommand ??= new DelegateCommand(() => Application.Current.Shutdown());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,9 +49,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ContinueCommand == null)
|
||||
{
|
||||
_ContinueCommand = new DelegateCommand(() =>
|
||||
return _ContinueCommand ??= new DelegateCommand(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -80,8 +71,6 @@ namespace WPinternals
|
||||
Failed();
|
||||
}
|
||||
});
|
||||
}
|
||||
return _ContinueCommand;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +78,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((_Name != null) && (_Name.Length >= 2) && (_Email != null) && (_Email.Length >= 5));
|
||||
return (_Name?.Length >= 2) && (_Email?.Length >= 5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,8 +92,8 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Name = value;
|
||||
OnPropertyChanged("Name");
|
||||
OnPropertyChanged("IsRegistrationComplete");
|
||||
OnPropertyChanged(nameof(Name));
|
||||
OnPropertyChanged(nameof(IsRegistrationComplete));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +107,8 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_Email = value;
|
||||
OnPropertyChanged("Email");
|
||||
OnPropertyChanged("IsRegistrationComplete");
|
||||
OnPropertyChanged(nameof(Email));
|
||||
OnPropertyChanged(nameof(IsRegistrationComplete));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +122,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_SkypeID = value;
|
||||
OnPropertyChanged("SkypeID");
|
||||
OnPropertyChanged(nameof(SkypeID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +136,7 @@ namespace WPinternals
|
||||
set
|
||||
{
|
||||
_TelegramID = value;
|
||||
OnPropertyChanged("TelegramID");
|
||||
OnPropertyChanged(nameof(TelegramID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace WPinternals
|
||||
{
|
||||
internal class RestoreSourceSelectionViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action<string, string, string> RestoreCallback;
|
||||
private Action<PhoneInterfaces> RequestModeSwitch;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly Action<string, string, string> RestoreCallback;
|
||||
private readonly Action<PhoneInterfaces> RequestModeSwitch;
|
||||
internal Action SwitchToUnlockBoot;
|
||||
internal Action SwitchToFlashRom;
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace WPinternals
|
||||
if (value != _EFIESPPath)
|
||||
{
|
||||
_EFIESPPath = value;
|
||||
OnPropertyChanged("EFIESPPath");
|
||||
OnPropertyChanged(nameof(EFIESPPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ namespace WPinternals
|
||||
if (value != _MainOSPath)
|
||||
{
|
||||
_MainOSPath = value;
|
||||
OnPropertyChanged("MainOSPath");
|
||||
OnPropertyChanged(nameof(MainOSPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ namespace WPinternals
|
||||
if (value != _DataPath)
|
||||
{
|
||||
_DataPath = value;
|
||||
OnPropertyChanged("DataPath");
|
||||
OnPropertyChanged(nameof(DataPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneDisconnected)
|
||||
{
|
||||
_IsPhoneDisconnected = value;
|
||||
OnPropertyChanged("IsPhoneDisconnected");
|
||||
OnPropertyChanged(nameof(IsPhoneDisconnected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInFlashMode)
|
||||
{
|
||||
_IsPhoneInFlashMode = value;
|
||||
OnPropertyChanged("IsPhoneInFlashMode");
|
||||
OnPropertyChanged(nameof(IsPhoneInFlashMode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,7 @@ namespace WPinternals
|
||||
if (value != _IsPhoneInOtherMode)
|
||||
{
|
||||
_IsPhoneInOtherMode = value;
|
||||
OnPropertyChanged("IsPhoneInOtherMode");
|
||||
OnPropertyChanged(nameof(IsPhoneInOtherMode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,11 +153,7 @@ namespace WPinternals
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_RestoreCommand == null)
|
||||
{
|
||||
_RestoreCommand = new DelegateCommand(() => { RestoreCallback(EFIESPPath, MainOSPath, DataPath); }, () => (((EFIESPPath != null) || (MainOSPath != null) || (DataPath != null)) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _RestoreCommand;
|
||||
return _RestoreCommand ??= new DelegateCommand(() => RestoreCallback(EFIESPPath, MainOSPath, DataPath), () => (((EFIESPPath != null) || (MainOSPath != null) || (DataPath != null)) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,12 +162,12 @@ namespace WPinternals
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrived;
|
||||
}
|
||||
|
||||
void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
new Thread(() => EvaluateViewState()).Start();
|
||||
}
|
||||
|
||||
void DeviceRemoved()
|
||||
private void DeviceRemoved()
|
||||
{
|
||||
new Thread(() => EvaluateViewState()).Start();
|
||||
}
|
||||
|
||||
@@ -26,11 +26,11 @@ namespace WPinternals
|
||||
{
|
||||
internal class RestoreViewModel : ContextViewModel
|
||||
{
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action Callback;
|
||||
private Action<PhoneInterfaces> RequestModeSwitch;
|
||||
private Action SwitchToUnlockBoot;
|
||||
private Action SwitchToFlashRom;
|
||||
private readonly PhoneNotifierViewModel PhoneNotifier;
|
||||
private readonly Action Callback;
|
||||
private readonly Action<PhoneInterfaces> RequestModeSwitch;
|
||||
private readonly Action SwitchToUnlockBoot;
|
||||
private readonly Action SwitchToFlashRom;
|
||||
|
||||
internal RestoreViewModel(PhoneNotifierViewModel PhoneNotifier, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToUnlockBoot, Action SwitchToFlashRom, Action Callback)
|
||||
: base()
|
||||
@@ -47,13 +47,19 @@ namespace WPinternals
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SubContextViewModel == null)
|
||||
{
|
||||
ActivateSubContext(new RestoreSourceSelectionViewModel(PhoneNotifier, RequestModeSwitch, SwitchToUnlockBoot, SwitchToFlashRom, DoRestore));
|
||||
}
|
||||
|
||||
if (SubContextViewModel is RestoreSourceSelectionViewModel)
|
||||
{
|
||||
((RestoreSourceSelectionViewModel)SubContextViewModel).EvaluateViewState();
|
||||
}
|
||||
}
|
||||
|
||||
internal async void DoRestore(string EFIESPPath, string MainOSPath, string DataPath)
|
||||
@@ -109,7 +115,7 @@ namespace WPinternals
|
||||
|
||||
NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;
|
||||
|
||||
BusyViewModel Busy = new BusyViewModel("Restoring...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
BusyViewModel Busy = new("Restoring...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
|
||||
ProgressUpdater Updater = Busy.ProgressUpdater;
|
||||
ActivateSubContext(Busy);
|
||||
|
||||
@@ -121,7 +127,7 @@ namespace WPinternals
|
||||
if (EFIESPPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Restoring partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Restoring partition EFIESP (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.FlashRawPartition(EFIESPPath, "EFIESP", Updater);
|
||||
}
|
||||
}
|
||||
@@ -139,7 +145,7 @@ namespace WPinternals
|
||||
if (MainOSPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Restoring partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Restoring partition MainOS (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.FlashRawPartition(EFIESPPath, "MainOS", Updater);
|
||||
}
|
||||
}
|
||||
@@ -157,7 +163,7 @@ namespace WPinternals
|
||||
if (DataPath != null)
|
||||
{
|
||||
i++;
|
||||
Busy.Message = "Restoring partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
|
||||
Busy.Message = "Restoring partition Data (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
|
||||
Phone.FlashRawPartition(EFIESPPath, "Data", Updater);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,9 @@ namespace WPinternals
|
||||
: base()
|
||||
{
|
||||
if ((PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash) && (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) && (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Label) && (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Normal))
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
this.PhoneNotifier = PhoneNotifier;
|
||||
this.CurrentModel = (NokiaPhoneModel)PhoneNotifier.CurrentModel;
|
||||
@@ -65,13 +67,12 @@ namespace WPinternals
|
||||
// Make sure this ViewModel has its View loaded before we continue,
|
||||
// or else loading of Views can get mixed up.
|
||||
if (SynchronizationContext.Current == null)
|
||||
{
|
||||
StartSwitch();
|
||||
}
|
||||
else
|
||||
{
|
||||
SynchronizationContext.Current.Post((s) =>
|
||||
{
|
||||
((SwitchModeViewModel)s).StartSwitch();
|
||||
}, this);
|
||||
SynchronizationContext.Current.Post((s) => ((SwitchModeViewModel)s).StartSwitch(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,18 +106,39 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
if (PhoneNotifier.CurrentInterface == TargetMode)
|
||||
{
|
||||
ModeSwitchSuccess(PhoneNotifier.CurrentModel, (PhoneInterfaces)PhoneNotifier.CurrentInterface);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.PhoneNotifier = PhoneNotifier;
|
||||
this.CurrentModel = (NokiaPhoneModel)PhoneNotifier.CurrentModel;
|
||||
this.CurrentMode = PhoneNotifier.CurrentInterface;
|
||||
this.TargetMode = TargetMode;
|
||||
if (ModeSwitchProgress != null) this.ModeSwitchProgress += ModeSwitchProgress;
|
||||
if (ModeSwitchError != null) this.ModeSwitchError += ModeSwitchError;
|
||||
if (ModeSwitchSuccess != null) this.ModeSwitchSuccess += ModeSwitchSuccess;
|
||||
if (SetWorkingStatus != null) this.SetWorkingStatus = SetWorkingStatus;
|
||||
if (UpdateWorkingStatus != null) this.UpdateWorkingStatus = UpdateWorkingStatus;
|
||||
if (ModeSwitchProgress != null)
|
||||
{
|
||||
this.ModeSwitchProgress += ModeSwitchProgress;
|
||||
}
|
||||
|
||||
if (ModeSwitchError != null)
|
||||
{
|
||||
this.ModeSwitchError += ModeSwitchError;
|
||||
}
|
||||
|
||||
if (ModeSwitchSuccess != null)
|
||||
{
|
||||
this.ModeSwitchSuccess += ModeSwitchSuccess;
|
||||
}
|
||||
|
||||
if (SetWorkingStatus != null)
|
||||
{
|
||||
this.SetWorkingStatus = SetWorkingStatus;
|
||||
}
|
||||
|
||||
if (UpdateWorkingStatus != null)
|
||||
{
|
||||
this.UpdateWorkingStatus = UpdateWorkingStatus;
|
||||
}
|
||||
|
||||
if (this.CurrentMode == null)
|
||||
{
|
||||
@@ -128,13 +150,12 @@ namespace WPinternals
|
||||
// Make sure this ViewModel has its View loaded before we continue,
|
||||
// or else loading of Views can get mixed up.
|
||||
if (SynchronizationContext.Current == null)
|
||||
{
|
||||
StartSwitch();
|
||||
}
|
||||
else
|
||||
{
|
||||
SynchronizationContext.Current.Post((s) =>
|
||||
{
|
||||
((SwitchModeViewModel)s).StartSwitch();
|
||||
}, this);
|
||||
SynchronizationContext.Current.Post((s) => ((SwitchModeViewModel)s).StartSwitch(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,9 +182,13 @@ namespace WPinternals
|
||||
{
|
||||
IsSwitching = false;
|
||||
if ((UIContext == null) || (SynchronizationContext.Current == UIContext))
|
||||
{
|
||||
ModeSwitchError(Message);
|
||||
}
|
||||
else
|
||||
UIContext.Post(s => { ModeSwitchError(Message); }, null);
|
||||
{
|
||||
UIContext.Post(s => ModeSwitchError(Message), null);
|
||||
}
|
||||
}
|
||||
|
||||
private void ModeSwitchSuccessWrapper()
|
||||
@@ -176,23 +201,29 @@ namespace WPinternals
|
||||
ModeSwitchErrorWrapper("Phone disconnected");
|
||||
}
|
||||
else
|
||||
ModeSwitchSuccess((IDisposable)PhoneNotifier.CurrentModel, (PhoneInterfaces)PhoneNotifier.CurrentInterface);
|
||||
}
|
||||
{
|
||||
ModeSwitchSuccess(PhoneNotifier.CurrentModel, (PhoneInterfaces)PhoneNotifier.CurrentInterface);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PhoneNotifier.CurrentInterface == null)
|
||||
{
|
||||
UIContext.Post(s => { ModeSwitchErrorWrapper("Phone disconnected"); }, null);
|
||||
UIContext.Post(s => ModeSwitchErrorWrapper("Phone disconnected"), null);
|
||||
}
|
||||
else
|
||||
UIContext.Post(s => { ModeSwitchSuccess((IDisposable)PhoneNotifier.CurrentModel, (PhoneInterfaces)PhoneNotifier.CurrentInterface); }, null);
|
||||
{
|
||||
UIContext.Post(s => ModeSwitchSuccess(PhoneNotifier.CurrentModel, (PhoneInterfaces)PhoneNotifier.CurrentInterface), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~SwitchModeViewModel()
|
||||
{
|
||||
if (PhoneNotifier != null)
|
||||
{
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrived;
|
||||
}
|
||||
}
|
||||
|
||||
internal void StartSwitch()
|
||||
@@ -248,7 +279,7 @@ namespace WPinternals
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, object> Params = new Dictionary<string, object>();
|
||||
Dictionary<string, object> Params = new();
|
||||
Params.Add("DeviceMode", DeviceMode);
|
||||
Params.Add("ResetMethod", "HwReset");
|
||||
try
|
||||
@@ -309,7 +340,7 @@ namespace WPinternals
|
||||
case PhoneInterfaces.Qualcomm_Download:
|
||||
byte[] RebootToQualcommDownloadCommand = new byte[] { 0x4E, 0x4F, 0x4B, 0x58, 0x43, 0x42, 0x45 }; // NOKXCBE
|
||||
RebootCommandResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
||||
if ((RebootCommandResult != null) && (RebootCommandResult.Length == 4)) // This means fail: NOKU (unknow command)
|
||||
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
|
||||
{
|
||||
IsSwitchingInterface = false;
|
||||
ModeSwitchErrorWrapper("Failed to switch to Qualcomm Download mode");
|
||||
@@ -367,7 +398,7 @@ namespace WPinternals
|
||||
{
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrivedFromMassStorageMode;
|
||||
|
||||
CurrentModel = (IDisposable)Args.NewModel;
|
||||
CurrentModel = Args.NewModel;
|
||||
CurrentMode = Args.NewInterface;
|
||||
|
||||
// After the mass storage mode reboot command, the phone must be in Bootloader mode.
|
||||
@@ -426,7 +457,7 @@ namespace WPinternals
|
||||
{
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrived;
|
||||
|
||||
CurrentModel = (IDisposable)Args.NewModel;
|
||||
CurrentModel = Args.NewModel;
|
||||
CurrentMode = Args.NewInterface;
|
||||
|
||||
if ((CurrentMode == PhoneInterfaces.Lumia_Bootloader) && (TargetMode == PhoneInterfaces.Lumia_Flash))
|
||||
@@ -447,7 +478,9 @@ namespace WPinternals
|
||||
if (CurrentMode == TargetMode)
|
||||
{
|
||||
if (TargetMode == PhoneInterfaces.Lumia_Bootloader)
|
||||
{
|
||||
((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
|
||||
}
|
||||
|
||||
ModeSwitchSuccessWrapper();
|
||||
}
|
||||
@@ -476,12 +509,12 @@ namespace WPinternals
|
||||
IsSwitchingInterface = true;
|
||||
LogFile.Log("Sending command for rebooting to Emergency Download mode");
|
||||
byte[] RebootCommandResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(RebootToQualcommDownloadCommand);
|
||||
if ((RebootCommandResult != null) && (RebootCommandResult.Length >= 8))
|
||||
if (RebootCommandResult?.Length >= 8)
|
||||
{
|
||||
int ResultCode = (RebootCommandResult[6] << 8) + RebootCommandResult[7];
|
||||
LogFile.Log("Resultcode: 0x" + ResultCode.ToString("X4"));
|
||||
}
|
||||
if ((RebootCommandResult != null) && (RebootCommandResult.Length == 4)) // This means fail: NOKU (unknow command)
|
||||
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknow command)
|
||||
{
|
||||
ModeSwitchErrorWrapper("Failed to switch to Qualcomm Download mode");
|
||||
IsSwitchingInterface = false;
|
||||
@@ -515,12 +548,7 @@ namespace WPinternals
|
||||
|
||||
private void SwitchFromFlashToLabelMode(bool Continuation = false)
|
||||
{
|
||||
string ProgressText;
|
||||
if (Continuation)
|
||||
ProgressText = "And now preparing to boot the phone to Label mode...";
|
||||
else
|
||||
ProgressText = "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)
|
||||
{
|
||||
@@ -548,32 +576,31 @@ namespace WPinternals
|
||||
}
|
||||
string ENOSWPackage = LumiaDownloadModel.SearchENOSW(Info.Type, Info.Firmware);
|
||||
SetWorkingStatus("Downloading " + Info.Type + " Test Mode package...", MaxProgressValue: 100);
|
||||
DownloadEntry downloadEntry = new DownloadEntry(ENOSWPackage, TempFolder, null, null, null);
|
||||
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;
|
||||
ulong progressret;
|
||||
ulong.TryParse(progress.ToString(), out progressret);
|
||||
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;
|
||||
string MMOSPath = TempFolder + "\\" + (sender as DownloadEntry)?.Name;
|
||||
|
||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||
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);
|
||||
|
||||
SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100);
|
||||
|
||||
ProgressUpdater progressUpdater = new ProgressUpdater(totalcounts + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i));
|
||||
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.");
|
||||
@@ -606,12 +633,7 @@ namespace WPinternals
|
||||
|
||||
private void SwitchFromFlashToMassStorageMode(bool Continuation = false)
|
||||
{
|
||||
string ProgressText;
|
||||
if (Continuation)
|
||||
ProgressText = "And now rebooting phone to Mass Storage mode...";
|
||||
else
|
||||
ProgressText = "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)
|
||||
{
|
||||
@@ -625,12 +647,16 @@ namespace WPinternals
|
||||
|
||||
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);
|
||||
@@ -650,7 +676,7 @@ namespace WPinternals
|
||||
byte[] RebootToMassStorageCommand = new byte[] { 0x4E, 0x4F, 0x4B, 0x4D }; // NOKM
|
||||
IsSwitchingInterface = true;
|
||||
byte[] RebootCommandResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(RebootToMassStorageCommand);
|
||||
if ((RebootCommandResult != null) && (RebootCommandResult.Length == 4)) // This means fail: NOKU (unknown command)
|
||||
if (RebootCommandResult?.Length == 4) // This means fail: NOKU (unknown command)
|
||||
{
|
||||
BootModeFlagCommand[0x0F] = 0x4D;
|
||||
byte[] BootFlagResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(BootModeFlagCommand);
|
||||
@@ -696,55 +722,63 @@ namespace WPinternals
|
||||
// But the partition contains an extra hack to break out the endless loops.
|
||||
using (var stream = assembly.GetManifestResourceStream("WPinternals.SBMSM"))
|
||||
{
|
||||
using (DecompressedStream dec = new DecompressedStream(stream))
|
||||
{
|
||||
using (System.IO.MemoryStream SB = new System.IO.MemoryStream()) // Must be a seekable stream!
|
||||
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) =>
|
||||
{
|
||||
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 List<FlashPart>();
|
||||
FlashPart Part = new FlashPart();
|
||||
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))
|
||||
{
|
||||
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) =>
|
||||
SetWorkingStatus(m, s, v, a, st);
|
||||
}
|
||||
else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
|
||||
{
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
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)
|
||||
@@ -754,7 +788,9 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -764,16 +800,24 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -798,14 +842,16 @@ namespace WPinternals
|
||||
internal async static Task<IDisposable> SwitchToWithProgress(PhoneNotifierViewModel Notifier, PhoneInterfaces? TargetMode, ModeSwitchProgressHandler ModeSwitchProgress, string RequestedVolumeForMassStorage = "MainOS")
|
||||
{
|
||||
if (Notifier.CurrentInterface == TargetMode)
|
||||
{
|
||||
return Notifier.CurrentModel;
|
||||
}
|
||||
|
||||
IDisposable Result = null;
|
||||
string LocalErrorMessage = null;
|
||||
|
||||
AsyncAutoResetEvent Event = new AsyncAutoResetEvent(false);
|
||||
AsyncAutoResetEvent Event = new(false);
|
||||
|
||||
SwitchModeViewModel Switch = new SwitchModeViewModel(
|
||||
SwitchModeViewModel Switch = new(
|
||||
Notifier,
|
||||
TargetMode,
|
||||
ModeSwitchProgress,
|
||||
@@ -824,7 +870,9 @@ namespace WPinternals
|
||||
await Event.WaitAsync(Timeout.InfiniteTimeSpan);
|
||||
|
||||
if (LocalErrorMessage != null)
|
||||
{
|
||||
throw new WPinternalsException(LocalErrorMessage);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
@@ -832,14 +880,16 @@ namespace WPinternals
|
||||
internal async static Task<IDisposable> SwitchToWithStatus(PhoneNotifierViewModel Notifier, PhoneInterfaces? TargetMode, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, string RequestedVolumeForMassStorage = "MainOS")
|
||||
{
|
||||
if (Notifier.CurrentInterface == TargetMode)
|
||||
{
|
||||
return Notifier.CurrentModel;
|
||||
}
|
||||
|
||||
IDisposable Result = null;
|
||||
string LocalErrorMessage = null;
|
||||
|
||||
AsyncAutoResetEvent Event = new AsyncAutoResetEvent(false);
|
||||
AsyncAutoResetEvent Event = new(false);
|
||||
|
||||
SwitchModeViewModel Switch = new SwitchModeViewModel(
|
||||
SwitchModeViewModel Switch = new(
|
||||
Notifier,
|
||||
TargetMode,
|
||||
null,
|
||||
@@ -858,7 +908,9 @@ namespace WPinternals
|
||||
await Event.WaitAsync(Timeout.InfiniteTimeSpan);
|
||||
|
||||
if (LocalErrorMessage != null)
|
||||
{
|
||||
throw new WPinternalsException(LocalErrorMessage);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user