From 0e6f9058090717d670eba4a2eb1c1785eb6097d6 Mon Sep 17 00:00:00 2001 From: Gustave Monce Date: Sun, 22 Dec 2019 12:23:46 +0100 Subject: [PATCH] Implement the ability to re-unlock an already unlocked phone + Start to work on a better UI for reset --- Models/QualcommSahara.cs | 21 ++- PhoneReboot.png | Bin 0 -> 51139 bytes ViewModels/BusyViewModel.cs | 24 ++- ViewModels/ContextViewModel.cs | 3 +- ViewModels/LumiaUnlockBootViewModel.cs | 23 ++- ViewModels/LumiaUnlockBootloaderViewModel.cs | 161 ++++++++++++++++-- ViewModels/LumiaV2UnlockBootViewModel.cs | 170 +++++++++++++++---- Views/BusyView.xaml | 10 ++ WPinternals.Core.csproj | 5 + WPinternals.Core.csproj.user | 2 +- 10 files changed, 361 insertions(+), 58 deletions(-) create mode 100644 PhoneReboot.png diff --git a/Models/QualcommSahara.cs b/Models/QualcommSahara.cs index 4f8c213..6015005 100644 --- a/Models/QualcommSahara.cs +++ b/Models/QualcommSahara.cs @@ -306,7 +306,26 @@ namespace WPinternals { LogFile.Log("Starting programmer", LogType.FileAndConsole); byte[] DoneCommand = new byte[] { 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 }; - byte[] DoneResponse = Serial.SendCommand(DoneCommand, new byte[] { 0x06, 0x00, 0x00, 0x00 }); + bool Started = false; + int count = 0; + do + { + try + { + count++; + byte[] DoneResponse = Serial.SendCommand(DoneCommand, new byte[] { 0x06, 0x00, 0x00, 0x00 }); + Started = true; + } + catch (BadConnectionException) + { + LogFile.Log("Problem while starting programmer. Attempting again.", LogType.FileAndConsole); + } + } while (!Started || count >= 3); + if (count >= 3 && !Started) + { + LogFile.Log("Maximum number of attempts to start the programmer exceeded.", LogType.FileAndConsole); + throw new BadConnectionException(); + } LogFile.Log("Programmer being launched on phone", LogType.FileOnly); } } diff --git a/PhoneReboot.png b/PhoneReboot.png new file mode 100644 index 0000000000000000000000000000000000000000..ed8cd4a354c1e03aab0809684fa8314de3267c64 GIT binary patch literal 51139 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 literal 0 HcmV?d00001 diff --git a/ViewModels/BusyViewModel.cs b/ViewModels/BusyViewModel.cs index db5760d..849eac4 100644 --- a/ViewModels/BusyViewModel.cs +++ b/ViewModels/BusyViewModel.cs @@ -29,7 +29,7 @@ namespace WPinternals 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. - internal BusyViewModel(string Message, string SubMessage = null, ulong? MaxProgressValue = null, SynchronizationContext UIContext = null, bool ShowAnimation = true) + internal BusyViewModel(string Message, string SubMessage = null, ulong? MaxProgressValue = null, SynchronizationContext UIContext = null, bool ShowAnimation = true, bool ShowRebootHelp = false) { LogFile.Log(Message); @@ -41,6 +41,7 @@ namespace WPinternals this.Message = Message; this.SubMessage = SubMessage; this.ShowAnimation = ShowAnimation; + this.ShowRebootHelp = ShowRebootHelp; if (MaxProgressValue != null) { ProgressPercentage = 0; @@ -64,6 +65,11 @@ namespace WPinternals } } + internal void SetShowRebootHelp(bool Value) + { + ShowRebootHelp = Value; + } + internal void SetProgress(ulong Value) { if (ProgressUpdater != null) @@ -188,5 +194,21 @@ namespace WPinternals } } + private bool _ShowRebootHelp = false; + public bool ShowRebootHelp + { + get + { + return _ShowRebootHelp; + } + set + { + if (_ShowRebootHelp != value) + { + _ShowRebootHelp = value; + OnPropertyChanged("ShowRebootHelp"); + } + } + } } } diff --git a/ViewModels/ContextViewModel.cs b/ViewModels/ContextViewModel.cs index c7c0f47..970c379 100644 --- a/ViewModels/ContextViewModel.cs +++ b/ViewModels/ContextViewModel.cs @@ -123,7 +123,7 @@ namespace WPinternals internal void SetWorkingStatus(string Message, string SubMessage, ulong? MaxProgressValue, bool ShowAnimation = true, WPinternalsStatus Status = WPinternalsStatus.Undefined) { - ActivateSubContext(new BusyViewModel(Message, SubMessage, MaxProgressValue, UIContext: UIContext, ShowAnimation: ShowAnimation)); + ActivateSubContext(new BusyViewModel(Message, SubMessage, MaxProgressValue, UIContext: UIContext, ShowAnimation: ShowAnimation, ShowRebootHelp: Status == WPinternalsStatus.WaitingForManualReset)); } internal void UpdateWorkingStatus(string Message, string SubMessage, ulong? CurrentProgressValue, WPinternalsStatus Status = WPinternalsStatus.Undefined) @@ -147,6 +147,7 @@ namespace WPinternals LogFile.LogException(Ex); } } + Busy.SetShowRebootHelp(Status == WPinternalsStatus.WaitingForManualReset); } } } diff --git a/ViewModels/LumiaUnlockBootViewModel.cs b/ViewModels/LumiaUnlockBootViewModel.cs index c97d756..a529199 100644 --- a/ViewModels/LumiaUnlockBootViewModel.cs +++ b/ViewModels/LumiaUnlockBootViewModel.cs @@ -192,14 +192,16 @@ namespace WPinternals } else { + bool AlreadyUnlocked = false; if (DoUnlock) { NokiaFlashModel FlashModel = (NokiaFlashModel)PhoneNotifier.CurrentModel; GPT GPT = FlashModel.ReadGPT(); if ((GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null)) { - ExitMessage("Phone is already unlocked", null); - return; + //ExitMessage("Phone is already unlocked", null); + //return; + AlreadyUnlocked = true; } } @@ -237,8 +239,10 @@ namespace WPinternals { if (DoFixBoot) await LumiaV2UnlockBootViewModel.LumiaV2FixBoot(PhoneNotifier, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage); - else + 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 @@ -278,7 +282,18 @@ namespace WPinternals // If resources are not confirmed yet, then display view with device info and request for resources. QualcommDownload Download = new QualcommDownload((QualcommSerial)PhoneNotifier.CurrentModel); - byte[] QualcommRootKeyHash = Download.GetRKH(); + byte[] QualcommRootKeyHash; + + try + { + QualcommRootKeyHash = Download.GetRKH(); + } + catch (BadConnectionException) + { + // This is a Spec B device + break; + } + if (RootKeyHash == null) RootKeyHash = QualcommRootKeyHash; else if (!StructuralComparisons.StructuralEqualityComparer.Equals(RootKeyHash, QualcommRootKeyHash)) diff --git a/ViewModels/LumiaUnlockBootloaderViewModel.cs b/ViewModels/LumiaUnlockBootloaderViewModel.cs index 7ea5b1c..c4eae1e 100644 --- a/ViewModels/LumiaUnlockBootloaderViewModel.cs +++ b/ViewModels/LumiaUnlockBootloaderViewModel.cs @@ -133,14 +133,14 @@ namespace WPinternals ExitSuccess("Bootloader restored successfully!"); } - internal static async Task LumiaV2UnlockUEFI(PhoneNotifierViewModel Notifier, string ProfileFFUPath, string EDEPath, string SupportedFFUPath, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null) + internal static async Task LumiaV2UnlockUEFI(PhoneNotifierViewModel Notifier, string ProfileFFUPath, string EDEPath, string SupportedFFUPath, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, bool ReUnlockDevice = false) { 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) => { }; - await LumiaUnlockBootloaderViewModel.LumiaUnlockUEFI(Notifier, ProfileFFUPath, EDEPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitSuccess, ExitFailure); + await LumiaUnlockBootloaderViewModel.LumiaUnlockUEFI(Notifier, ProfileFFUPath, EDEPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitSuccess, ExitFailure, ReUnlockDevice: ReUnlockDevice); SetWorkingStatus("Booting phone..."); await Notifier.WaitForArrival(); @@ -1625,7 +1625,7 @@ namespace WPinternals // // Assumes phone in Flash mode // - internal static async Task LumiaUnlockUEFI(PhoneNotifierViewModel Notifier, string ProfileFFUPath, string EDEPath, string SupportedFFUPath, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, bool ExperimentalSpecBEFIESPUnlock = false, bool ExperimentalSpecAEFIESPUnlock = true) + internal static async Task LumiaUnlockUEFI(PhoneNotifierViewModel Notifier, string ProfileFFUPath, string EDEPath, string SupportedFFUPath, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, bool ExperimentalSpecBEFIESPUnlock = false, bool ExperimentalSpecAEFIESPUnlock = true, bool ReUnlockDevice = false) { LogFile.BeginAction("UnlockBootloader"); NokiaFlashModel FlashModel = (NokiaFlashModel)Notifier.CurrentModel; @@ -1705,8 +1705,30 @@ namespace WPinternals Partition BACKUP_EFIESP = GPT.GetPartition("BACKUP_EFIESP"); Partition EFIESP; - if (BACKUP_EFIESP == null) + if (BACKUP_EFIESP == null && !ReUnlockDevice) { + /* + * Before: + * + * ___________________________________________ + * | | + * | EFIESP | + * | Original | + * |___________________________________________| + * + */ + + /* + * After: + * + * ___________________________________________ + * | | | + * | BACKUP_EFIESP | EFIESP | + * | Original | Unlocked | + * |____________________|______________________| + * + */ + BACKUP_EFIESP = GPT.GetPartition("EFIESP"); Guid OriginalPartitionTypeGuid = BACKUP_EFIESP.PartitionTypeGuid; Guid OriginalPartitionGuid = BACKUP_EFIESP.PartitionGuid; @@ -1724,6 +1746,43 @@ namespace WPinternals GPT.Partitions.Add(EFIESP); GPTChanged = true; } + if (BACKUP_EFIESP == null && ReUnlockDevice) + { + /* + * Before: + * + * ___________________________________________ + * | | | + * | EFIESP BACKUP_EFIESP | + * | Unlocked Original | + * |____________________|______________________| + * + */ + + /* + * After: + * + * ___________________________________________ + * | | | + * | EFIESP | BACKUP_EFIESP | + * | Unlocked | Original | + * |____________________|______________________| + * + */ + + EFIESP = GPT.GetPartition("EFIESP"); + EFIESP.LastSector = EFIESP.FirstSector + ((OriginalEfiespSizeInSectors) / 2) - 1; // Original is 0x10000 + + BACKUP_EFIESP = new Partition(); + BACKUP_EFIESP.Name = "BACKUP_EFIESP"; + BACKUP_EFIESP.Attributes = EFIESP.Attributes; + BACKUP_EFIESP.PartitionGuid = Guid.NewGuid(); + BACKUP_EFIESP.PartitionTypeGuid = Guid.NewGuid(); + BACKUP_EFIESP.FirstSector = EFIESP.LastSector + 1; + BACKUP_EFIESP.LastSector = BACKUP_EFIESP.FirstSector + ((OriginalEfiespSizeInSectors) / 2) - 1; // Original is 0x10000 + GPT.Partitions.Add(BACKUP_EFIESP); + GPTChanged = true; + } EFIESP = GPT.GetPartition("EFIESP"); if ((UInt64)UnlockedEFIESP.Length > (EFIESP.SizeInSectors * 0x200)) { @@ -1896,7 +1955,24 @@ namespace WPinternals byte[] BackupUnlockedEFIESP = new byte[UnlockedEFIESP.Length]; Buffer.BlockCopy(BackupEFIESP, 0, BackupUnlockedEFIESP, 0, BackupEFIESP.Length); - LumiaUnlockBootloaderViewModel.LumiaPatchEFIESP(SupportedFFU, BackupUnlockedEFIESP, IsSpecB); + try + { + LumiaUnlockBootloaderViewModel.LumiaPatchEFIESP(SupportedFFU, BackupUnlockedEFIESP, IsSpecB); + } + catch (Exception ex) + { + LogFile.Log("Exception: " + ex.GetType().ToString(), LogType.FileOnly); + LogFile.Log("It seems that the backed up EFIESP partition is invalid.", LogType.FileOnly); + LogFile.Log("Using the FFU partition as a failsafe.", LogType.FileOnly); + + BackupEFIESP = ProfileFFU.GetPartition("EFIESP"); + + // Copy the backed up unlocked EFIESP for future use + BackupUnlockedEFIESP = new byte[UnlockedEFIESP.Length]; + Buffer.BlockCopy(BackupEFIESP, 0, BackupUnlockedEFIESP, 0, BackupEFIESP.Length); + + LumiaUnlockBootloaderViewModel.LumiaPatchEFIESP(SupportedFFU, BackupUnlockedEFIESP, IsSpecB); + } SetWorkingStatus("Boot optimization...", null, null); @@ -1922,15 +1998,72 @@ namespace WPinternals ((NokiaFlashModel)Notifier.CurrentModel).SwitchToFlashAppContext(); - // EFIESP is appended at the end of the GPT - // BACKUP_EFIESP is at original location in GPT - Partition EFIESP = GPT.GetPartition("EFIESP"); - UInt32 OriginalEfiespFirstSector = (UInt32)BACKUP_EFIESP.FirstSector; - BACKUP_EFIESP.Name = "EFIESP"; - BACKUP_EFIESP.LastSector = OriginalEfiespLastSector; - BACKUP_EFIESP.PartitionGuid = EFIESP.PartitionGuid; - BACKUP_EFIESP.PartitionTypeGuid = EFIESP.PartitionTypeGuid; - GPT.Partitions.Remove(EFIESP); + UInt32 OriginalEfiespFirstSector; + if (!ReUnlockDevice) + { + /* + * Before: + * + * ___________________________________________ + * | | | + * | BACKUP_EFIESP | EFIESP | + * | Original | Unlocked | + * |____________________|______________________| + * + */ + + /* + * After: + * + * ___________________________________________ + * | | | + * | EFIESP BACKUP_EFIESP | + * | Unlocked Original | + * |____________________|______________________| + * + */ + + // EFIESP is appended at the end of the GPT + // BACKUP_EFIESP is at original location in GPT + Partition EFIESP = GPT.GetPartition("EFIESP"); + OriginalEfiespFirstSector = (UInt32)BACKUP_EFIESP.FirstSector; + BACKUP_EFIESP.Name = "EFIESP"; + BACKUP_EFIESP.LastSector = OriginalEfiespLastSector; + BACKUP_EFIESP.PartitionGuid = EFIESP.PartitionGuid; + BACKUP_EFIESP.PartitionTypeGuid = EFIESP.PartitionTypeGuid; + GPT.Partitions.Remove(EFIESP); + } + else + { + /* + * Before: + * + * ___________________________________________ + * | | | + * | EFIESP | BACKUP_EFIESP | + * | Unlocked | Original | + * |____________________|______________________| + * + */ + + /* + * After: + * + * ___________________________________________ + * | | | + * | EFIESP BACKUP_EFIESP | + * | Unlocked Original | + * |____________________|______________________| + * + */ + + // EFIESP is expended to its full size + // BACKUP_EFIESP is removed + Partition EFIESP = GPT.GetPartition("EFIESP"); + OriginalEfiespFirstSector = (UInt32)EFIESP.FirstSector; + EFIESP.LastSector = OriginalEfiespLastSector; + GPT.Partitions.Remove(BACKUP_EFIESP); + } Partition IsUnlockedFlag = GPT.GetPartition("IS_UNLOCKED"); if (IsUnlockedFlag == null) diff --git a/ViewModels/LumiaV2UnlockBootViewModel.cs b/ViewModels/LumiaV2UnlockBootViewModel.cs index 68ad50d..3e0a830 100644 --- a/ViewModels/LumiaV2UnlockBootViewModel.cs +++ b/ViewModels/LumiaV2UnlockBootViewModel.cs @@ -407,7 +407,7 @@ namespace WPinternals PhoneInfo Info = FlashModel.ReadPhoneInfo(); byte[] Data = System.IO.File.ReadAllBytes(DataPath); - + await LumiaV2CustomFlash(Notifier, FFUPath, false, false, (UInt32)StartSector, Data, DoResetFirst); Notifier.Stop(); } @@ -597,13 +597,22 @@ namespace WPinternals } if (Notifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download) { + bool FailedToStartProgrammer = false; if (ProgrammerPath != null) { QualcommSahara Sahara = new QualcommSahara((QualcommSerial)Notifier.CurrentModel); - await Sahara.Reset(ProgrammerPath); - await Notifier.WaitForArrival(); + try + { + await Sahara.Reset(ProgrammerPath); + await Notifier.WaitForArrival(); + } + catch (BadConnectionException) + { + FailedToStartProgrammer = true; + } } - else + + if (ProgrammerPath == null || FailedToStartProgrammer) { ((QualcommSerial)Notifier.CurrentModel).Close(); // Prevent "Resource in use"; @@ -623,16 +632,39 @@ namespace WPinternals { AutoEmergencyReset = false; - LogFile.Log("The phone is in emergency mode and you didn't provide an emergency programmer", LogType.ConsoleOnly); - LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); - LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); - LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); - LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); - LogFile.Log("To prevent this, provide an emergency programmer next time you will unlock a bootloader", LogType.ConsoleOnly); - LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); + if (!FailedToStartProgrammer) + { + LogFile.Log("The phone is in emergency mode and you didn't provide an emergency programmer", LogType.ConsoleOnly); + LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); + LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); + LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); + LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); + LogFile.Log("To prevent this, provide an emergency programmer next time you will unlock a bootloader", LogType.ConsoleOnly); + LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); - SetWorkingStatus("You need to manually reset your phone now!", "The phone is in emergency mode and you didn't provide an emergency programmer. This phone also doesn't seem to reboot after a timeout, so you got to help a bit. Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates. The unlock-sequence will resume automatically. To prevent this, provide an emergency programmer next time you will unlock a bootloader.", null, false, WPinternalsStatus.WaitingForManualReset); + SetWorkingStatus("You need to manually reset your phone now!", + "The phone is in emergency mode and you didn't provide an emergency programmer." + + " This phone also doesn't seem to reboot after a timeout, so you got to help a bit." + + " Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates." + + " The unlock-sequence will resume automatically. To prevent this, provide an emergency programmer next time you will unlock a bootloader.", + null, false, WPinternalsStatus.WaitingForManualReset); + } + else + { + LogFile.Log("The phone is in emergency mode and we couldn't start the emergency programmer", LogType.ConsoleOnly); + LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); + LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); + LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); + LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); + LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); + SetWorkingStatus("You need to manually reset your phone now!", + "The phone is in emergency mode and we couldn't start the emergency programmer." + + " This phone also doesn't seem to reboot after a timeout, so you got to help a bit." + + " Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates." + + " The unlock-sequence will resume automatically.", + null, false, WPinternalsStatus.WaitingForManualReset); + } await Notifier.WaitForRemoval(); UpdateWorkingStatus("Initializing flash...", null, null); @@ -1082,12 +1114,12 @@ namespace WPinternals Step = 8; // This may fail. Normally with WPinternalsException for Invalid Hash or Data not aligned. // Or it may fail with a BadConnectionException when the phone crashes and drops the connection. - + payloadCount++; } UpdateWorkingStatus(NewProgressText, null, (UInt64?)(FlashingPhaseStartPayloadIndex + i + 1), WPinternalsStatus.Flashing); - + if (i != -1 && sendPayload) { // This fails when sending multiple chunks per payload with 0x1003: Hash mismatch @@ -1221,13 +1253,22 @@ namespace WPinternals } if (Notifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download) { + bool FailedToStartProgrammer = false; if (ProgrammerPath != null) { QualcommSahara Sahara = new QualcommSahara((QualcommSerial)Notifier.CurrentModel); - await Sahara.Reset(ProgrammerPath); - await Notifier.WaitForArrival(); + try + { + await Sahara.Reset(ProgrammerPath); + await Notifier.WaitForArrival(); + } + catch (BadConnectionException) + { + FailedToStartProgrammer = true; + } } - else + + if (ProgrammerPath == null || FailedToStartProgrammer) { ((QualcommSerial)Notifier.CurrentModel).Close(); // Prevent "Resource in use"; @@ -1246,16 +1287,39 @@ namespace WPinternals if (!AutoEmergencyReset || Timeout) { AutoEmergencyReset = false; + if (!FailedToStartProgrammer) + { + LogFile.Log("The phone is in emergency mode and you didn't provide an emergency programmer", LogType.ConsoleOnly); + LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); + LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); + LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); + LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); + LogFile.Log("To prevent this, provide an emergency programmer next time you will unlock a bootloader", LogType.ConsoleOnly); + LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); - LogFile.Log("The phone is in emergency mode and you didn't provide an emergency programmer", LogType.ConsoleOnly); - LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); - LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); - LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); - LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); - LogFile.Log("To prevent this, provide an emergency programmer next time you will unlock a bootloader", LogType.ConsoleOnly); - LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); + SetWorkingStatus("You need to manually reset your phone now!", + "The phone is in emergency mode and you didn't provide an emergency programmer." + + " This phone also doesn't seem to reboot after a timeout, so you got to help a bit." + + " Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates." + + " The unlock-sequence will resume automatically. To prevent this, provide an emergency programmer next time you will unlock a bootloader.", + null, false, WPinternalsStatus.WaitingForManualReset); + } + else + { + LogFile.Log("The phone is in emergency mode and we couldn't start the emergency programmer", LogType.ConsoleOnly); + LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); + LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); + LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); + LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); + LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); - UpdateWorkingStatus("You need to manually reset your phone now!", "The phone is in emergency mode and you didn't provide an emergency programmer. This phone also doesn't seem to reboot after a timeout, so you got to help a bit. Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates. The unlock-sequence will resume automatically. To prevent this, provide an emergency programmer next time you will unlock a bootloader.", null, WPinternalsStatus.WaitingForManualReset); + SetWorkingStatus("You need to manually reset your phone now!", + "The phone is in emergency mode and we couldn't start the emergency programmer." + + " This phone also doesn't seem to reboot after a timeout, so you got to help a bit." + + " Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates." + + " The unlock-sequence will resume automatically.", + null, false, WPinternalsStatus.WaitingForManualReset); + } await Notifier.WaitForRemoval(); @@ -1442,12 +1506,22 @@ namespace WPinternals } if (Notifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download) { + bool FailedToStartProgrammer = false; if (ProgrammerPath != null) { QualcommSahara Sahara = new QualcommSahara((QualcommSerial)Notifier.CurrentModel); - await Sahara.Reset(ProgrammerPath); + try + { + await Sahara.Reset(ProgrammerPath); + await Notifier.WaitForArrival(); + } + catch (BadConnectionException) + { + FailedToStartProgrammer = true; + } } - else + + if (ProgrammerPath == null || FailedToStartProgrammer) { ((QualcommSerial)Notifier.CurrentModel).Close(); // Prevent "Resource in use"; @@ -1467,15 +1541,39 @@ namespace WPinternals { AutoEmergencyReset = false; - LogFile.Log("The phone is in emergency mode and you didn't provide an emergency programmer", LogType.ConsoleOnly); - LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); - LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); - LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); - LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); - LogFile.Log("To prevent this, provide an emergency programmer next time you will unlock a bootloader", LogType.ConsoleOnly); - LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); + if (!FailedToStartProgrammer) + { + LogFile.Log("The phone is in emergency mode and you didn't provide an emergency programmer", LogType.ConsoleOnly); + LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); + LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); + LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); + LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); + LogFile.Log("To prevent this, provide an emergency programmer next time you will unlock a bootloader", LogType.ConsoleOnly); + LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); - SetWorkingStatus("You need to manually reset your phone now!", "The phone is in emergency mode and you didn't provide an emergency programmer. This phone also doesn't seem to reboot after a timeout, so you got to help a bit. Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates. The unlock-sequence will resume automatically. To prevent this, provide an emergency programmer next time you will unlock a bootloader.", null, false, WPinternalsStatus.WaitingForManualReset); + SetWorkingStatus("You need to manually reset your phone now!", + "The phone is in emergency mode and you didn't provide an emergency programmer." + + " This phone also doesn't seem to reboot after a timeout, so you got to help a bit." + + " Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates." + + " The unlock-sequence will resume automatically. To prevent this, provide an emergency programmer next time you will unlock a bootloader.", + null, false, WPinternalsStatus.WaitingForManualReset); + } + else + { + LogFile.Log("The phone is in emergency mode and we couldn't start the emergency programmer", LogType.ConsoleOnly); + LogFile.Log("This phone also doesn't seem to reboot after a timeout, so you got to help a bit", LogType.ConsoleOnly); + LogFile.Log("Keep the phone connected to the PC", LogType.ConsoleOnly); + LogFile.Log("Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates", LogType.ConsoleOnly); + LogFile.Log("The unlock-sequence will resume automatically", LogType.ConsoleOnly); + LogFile.Log("Waiting for manual reset of the phone...", LogType.ConsoleOnly); + + SetWorkingStatus("You need to manually reset your phone now!", + "The phone is in emergency mode and we couldn't start the emergency programmer." + + " This phone also doesn't seem to reboot after a timeout, so you got to help a bit." + + " Keep the phone connected to the PC. Reboot the phone manually by pressing and holding the power-button of the phone for about 10 seconds until it vibrates." + + " The unlock-sequence will resume automatically.", + null, false, WPinternalsStatus.WaitingForManualReset); + } await Notifier.WaitForRemoval(); @@ -1527,7 +1625,7 @@ namespace WPinternals return 0x08 * ((UInt32)TargetLocations.Count() + 1); } } - + // // Function to fall back into the legacy implementation of custom flash, to test the modifications done in the custom flash function // in LumiaV2UnlockBootViewModel diff --git a/Views/BusyView.xaml b/Views/BusyView.xaml index 55a1313..645f600 100644 --- a/Views/BusyView.xaml +++ b/Views/BusyView.xaml @@ -48,6 +48,16 @@ DEALINGS IN THE SOFTWARE. + + + + + + + + + + diff --git a/WPinternals.Core.csproj b/WPinternals.Core.csproj index 72ec881..358dace 100644 --- a/WPinternals.Core.csproj +++ b/WPinternals.Core.csproj @@ -25,6 +25,7 @@ + @@ -44,6 +45,10 @@ + + + + diff --git a/WPinternals.Core.csproj.user b/WPinternals.Core.csproj.user index 9e435b3..fd91379 100644 --- a/WPinternals.Core.csproj.user +++ b/WPinternals.Core.csproj.user @@ -1,7 +1,7 @@  - <_LastSelectedProfileId>G:\Projects\Misc\WPinternals\Properties\PublishProfiles\FolderProfile.pubxml + <_LastSelectedProfileId>G:\Projects\WPinternals\Properties\PublishProfiles\FolderProfile.pubxml