internal static async Task RewriteParts(string PartPath) { PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel(); Notifier.Start(); await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage); MassStorage MassStorage = (MassStorage)Notifier.CurrentModel; foreach (var part in Directory.EnumerateFiles(PartPath)) { var partname = part.Split('\\').Last().Replace(".img", ""); try { LogFile.Log($"Writing {partname} to the device.", LogType.ConsoleOnly); LogFile.Log("", LogType.ConsoleOnly); MassStorage.RestorePartition(part, partname, (v, t) => { LogFile.Log("Progress: " + v + "%", LogType.ConsoleOnly); }); LogFile.Log("", LogType.ConsoleOnly); } catch { LogFile.Log("", LogType.ConsoleOnly); LogFile.Log($"Failed writing {partname} to the device.", LogType.ConsoleOnly); }; } }
internal static void InterruptBootChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { App.InterruptBoot = (bool)e.NewValue; if ((bool)e.NewValue && PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) { App.InterruptBoot = false; LogFile.Log("Found Lumia BootMgr and user forced to interrupt the boot process. Force to Flash-mode."); Task.Run(() => SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Lumia_Flash)); } }
internal static async Task RewriteGPT(string GPTPath) { PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel(); Notifier.Start(); await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage); MassStorage MassStorage = (MassStorage)Notifier.CurrentModel; LogFile.Log("Writing GPT to the device.", LogType.ConsoleOnly); MassStorage.WriteSectors(1, GPTPath); }
internal static async Task TestProgrammer(System.Threading.SynchronizationContext UIContext, string ProgrammerPath) { LogFile.BeginAction("TestProgrammer"); try { LogFile.Log("Starting Firehose Test", LogType.FileAndConsole); PhoneNotifierViewModel Notifier = new(); UIContext.Send(s => Notifier.Start(), null); if (Notifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download) { LogFile.Log("Phone found in emergency mode", LogType.FileAndConsole); } else { LogFile.Log("Phone needs to be switched to emergency mode.", LogType.FileAndConsole); await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); PhoneInfo Info = ((NokiaFlashModel)Notifier.CurrentModel).ReadPhoneInfo(); Info.Log(LogType.ConsoleOnly); await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Qualcomm_Download); if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download) { throw new WPinternalsException("Switching mode failed.", "Could not switch the phone to Qualcomm Emergency 9008."); } LogFile.Log("Phone is in emergency mode.", LogType.FileAndConsole); } // Send and start programmer QualcommSerial Serial = (QualcommSerial)Notifier.CurrentModel; QualcommSahara Sahara = new(Serial); if (await Sahara.Reset(ProgrammerPath)) { LogFile.Log("Emergency programmer test succeeded", LogType.FileAndConsole); } else { LogFile.Log("Emergency programmer test failed", LogType.FileAndConsole); } } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("TestProgrammer"); } }
void PhoneNotifier_NewDeviceArrived(ArrivalEventArgs Args) { PhoneInterfaces?PreviousInterface = LastInterface; LastInterface = Args.NewInterface; if (App.InterruptBoot && (Args.NewInterface == PhoneInterfaces.Lumia_Bootloader)) { App.InterruptBoot = false; LogFile.Log("Found Lumia BootMgr and user forced to interrupt the boot process. Force to Flash-mode."); Task.Run(() => SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Lumia_Flash)); } 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)) { // The current screen is marked as "Flash operation". // When the bootloader is detected at this stage, it means a phone is booting and // it is possible that the phone is in a non-booting stage (not possible to boot past UEFI). // We will try to boot straight to Flash-mode, so that it will be possible to flash a new ROM. LogFile.Log("Found Lumia BootMgr while mode is not being switched. Screen is marked as Flash Operation. Force to Flash-mode."); Task.Run(() => SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Lumia_Flash)); } } else { if ((!ContextViewModel.IsSwitchingInterface) && (Args.NewInterface != PhoneInterfaces.Lumia_Bootloader)) { ContextViewModel = InfoViewModel; } } } }
internal static async Task RewriteMBRGPT() { FFU FFU = new FFU(@"E:\Device Backups\Alpha\9200_1230.0025.9200.9825\RX100_9825.ffu"); string GPTPath = @"E:\Device Backups\Alpha\9200_1230.0025.9200.9825\CorrectGPT.bin"; PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel(); Notifier.Start(); await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage); MassStorage MassStorage = (MassStorage)Notifier.CurrentModel; byte[] MBR = FFU.GetSectors(0, 1); LogFile.Log("Writing MBR to the device.", LogType.ConsoleOnly); MassStorage.WriteSectors(0, MBR); LogFile.Log("Writing GPT to the device.", LogType.ConsoleOnly); MassStorage.WriteSectors(1, GPTPath); }
internal static void InterruptBootChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { App.InterruptBoot = (bool)e.NewValue; if ((bool)e.NewValue) { // Find the phone notifier DependencyObject obj = d; while (!(obj is MainWindow)) { obj = VisualTreeHelper.GetParent(obj); } PhoneNotifierViewModel PhoneNotifier = ((MainViewModel)(((MainWindow)obj).DataContext)).PhoneNotifier; if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) { App.InterruptBoot = false; LogFile.Log("Found Lumia BootMgr and user forced to interrupt the boot process. Force to Flash-mode."); Task.Run(() => SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Lumia_Flash)); } } }
internal void PhoneNotifier_NewDeviceArrived(ArrivalEventArgs Args) { if (App.InterruptBoot && Args.NewInterface == PhoneInterfaces.Lumia_Bootloader) { App.InterruptBoot = false; LogFile.Log("Found Lumia BootMgr and user forced to interrupt the boot process. Force to Flash-mode."); Task.Run(() => SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Lumia_Flash)); } UIContext.Send(s => { if (!App.InterruptBoot && Args.NewInterface == PhoneInterfaces.Lumia_Bootloader) { StatusText.Content = "Phone is booting..."; GifImage.Visibility = Visibility.Visible; } if (!App.InterruptBoot && Args.NewInterface != PhoneInterfaces.Lumia_Bootloader) { StatusText.Content = "Waiting for connection with phone..."; GifImage.Visibility = Visibility.Collapsed; } }, null); }
internal static async Task RecoverBadGPT(string GPTPath, string LoadersPath) { byte[] GPT = File.ReadAllBytes(GPTPath); PhoneNotifierViewModel PhoneNotifier = new PhoneNotifierViewModel(); PhoneNotifier.Start(); await SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Qualcomm_Download); byte[] RootKeyHash = null; if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download) { QualcommDownload Download2 = new QualcommDownload((QualcommSerial)PhoneNotifier.CurrentModel); RootKeyHash = Download2.GetRKH(); } List <QualcommPartition> PossibleLoaders = null; if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download) { try { PossibleLoaders = QualcommLoaders.GetPossibleLoadersForRootKeyHash(LoadersPath, RootKeyHash); if (PossibleLoaders.Count == 0) { throw new Exception("Error: No matching loaders found for RootKeyHash."); } } catch (Exception Ex) { LogFile.LogException(Ex); throw new Exception("Error: Unexpected error during scanning for loaders."); } } QualcommSerial Serial = (QualcommSerial)PhoneNotifier.CurrentModel; QualcommDownload Download = new QualcommDownload(Serial); if (Download.IsAlive()) { int Attempt = 1; bool Result = false; foreach (QualcommPartition Loader in PossibleLoaders) { LogFile.Log("Attempt " + Attempt.ToString(), LogType.ConsoleOnly); try { Download.SendToPhoneMemory(0x2A000000, Loader.Binary); Download.StartBootloader(0x2A000000); Result = true; LogFile.Log("Loader sent successfully", LogType.ConsoleOnly); } catch { } if (Result) { break; } Attempt++; } Serial.Close(); if (!Result) { LogFile.Log("Loader failed", LogType.ConsoleOnly); } } else { LogFile.Log("Failed to communicate to Qualcomm Emergency Download mode", LogType.ConsoleOnly); throw new BadConnectionException(); } if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash) { await PhoneNotifier.WaitForArrival(); } if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash) { throw new WPinternalsException("Phone failed to switch to emergency flash mode."); } // Flash bootloader QualcommSerial Serial2 = (QualcommSerial)PhoneNotifier.CurrentModel; Serial2.EncodeCommands = false; QualcommFlasher Flasher = new QualcommFlasher(Serial2); Flasher.Hello(); Flasher.SetSecurityMode(0); Flasher.OpenPartition(0x21); LogFile.Log("Partition opened.", LogType.ConsoleOnly); LogFile.Log("Flash GPT at 0x" + ((UInt32)0x200).ToString("X8"), LogType.ConsoleOnly); Flasher.Flash(0x200, GPT, 0, 0x41FF); // Bad bounds-check in the flash-loader prohibits to write the last byte. Flasher.ClosePartition(); LogFile.Log("Partition closed. Flashing ready. Rebooting."); Flasher.Reboot(); Flasher.CloseSerial(); }