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 0000000..ed8cd4a Binary files /dev/null and b/PhoneReboot.png differ 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