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