// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace WPinternals { internal static class CommandLine { [DllImport("kernel32.dll", SetLastError = true)] static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool AttachConsole(int dwProcessId); [DllImport("kernel32.dll")] static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); private const UInt32 StdOutputHandle = 0xFFFFFFF5; [DllImport("kernel32.dll")] private static extern IntPtr GetStdHandle(UInt32 nStdHandle); [DllImport("kernel32.dll")] private static extern void SetStdHandle(UInt32 nStdHandle, IntPtr handle); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, uint lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, uint hTemplateFile); [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); const int SW_HIDE = 0; const int SW_SHOW = 5; private const int MY_CODE_PAGE = 437; private const uint GENERIC_WRITE = 0x40000000; private const uint FILE_SHARE_WRITE = 0x2; private const uint OPEN_EXISTING = 0x3; internal static bool IsConsoleVisible = false; internal static bool IsNewConsoleCreated = false; private static IntPtr hConsoleWnd; [DllImport("User32.Dll", EntryPoint = "PostMessageA")] private static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam); private const int VK_RETURN = 0x0D; private const int WM_KEYDOWN = 0x100; /// /// When the main window should not be shown, this function should call ExitProcess and it should not return. /// internal static async Task ParseCommandLine(System.Threading.SynchronizationContext UIContext) { FFU FFU = null; PhoneNotifierViewModel Notifier; NokiaFlashModel FlashModel; NokiaPhoneModel NormalModel; PhoneInfo Info; string ProductType; string ProductCode; string OperatorCode; string DownloadFolder; string FFUFilePath; string URL; string[] URLs; Uri URI; string FFUFileName; string EmergencyFileName; string EmergencyFilePath; string ProgrammerPath = ""; string PayloadPath = ""; string EfiEspImagePath = null; string MainOsImagePath = null; DiscUtils.Fat.FatFileSystem UnlockedEFIESPFileSystem; DiscUtils.Ntfs.NtfsFileSystem UnlockedMainOsFileSystem; bool PatchResult; try { string[] args = Environment.GetCommandLineArgs(); if (args.Length == 1) return; switch (args[1].ToLower().TrimStart(new char[] { '-', '/' })) { #if DEBUG case "test": LogFile.BeginAction("Test"); await TestCode.Test(UIContext); LogFile.EndAction("Test"); break; #endif case "flashpartition": if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -FlashPartition "); if (args.Length >= 5) await LumiaV2UnlockBootViewModel.LumiaV2FlashPartition(UIContext, args[4], args[2], args[3]); else await LumiaV2UnlockBootViewModel.LumiaV2FlashPartition(UIContext, null, args[2], args[3]); break; case "flashraw": if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -FlashRaw "); UInt64 StartSector = 0; try { if (args[2].StartsWith("0x", StringComparison.OrdinalIgnoreCase)) StartSector = Convert.ToUInt64(args[2].Substring(2), 16); else StartSector = Convert.ToUInt64(args[2], 10); } catch { LogFile.Log("Bad start sector", LogType.ConsoleOnly); break; } if (args.Length >= 5) await LumiaV2UnlockBootViewModel.LumiaV2FlashRaw(UIContext, StartSector, args[3], args[4]); else await LumiaV2UnlockBootViewModel.LumiaV2FlashRaw(UIContext, StartSector, args[3], null); break; case "flashpartitionimmediately": if (args.Length < 5) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -FlashPartition "); await LumiaV2UnlockBootViewModel.LumiaV2FlashPartition(UIContext, args[4], args[2], args[3], false); break; case "readgpt": LogFile.BeginAction("ReadGPT"); try { Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); FlashModel = (NokiaFlashModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader)); // This also works for Bootloader Spec A GPT GPT = FlashModel.ReadGPT(); // May throw NotSupportedException foreach (Partition Partition in GPT.Partitions) LogFile.Log(Partition.Name.PadRight(20) + "0x" + Partition.FirstSector.ToString("X8") + " - 0x" + Partition.LastSector.ToString("X8") + " " + Partition.Volume, LogType.ConsoleOnly); if (FlashModel.ReadPhoneInfo(false).FlashAppProtocolVersionMajor >= 2) FlashModel.SwitchToFlashAppContext(); else await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash); Notifier.Stop(); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("ReadGPT"); } break; case "backupgpt": if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -BackupGPT "); LogFile.BeginAction("BackupGPT"); try { Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); FlashModel = (NokiaFlashModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash)); GPT GPT = FlashModel.ReadGPT(); // May throw NotSupportedException System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(args[2])); GPT.WritePartitions(args[2]); FlashModel.SwitchToFlashAppContext(); Notifier.Stop(); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("BackupGPT"); } break; case "restoregpt": if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -RestoreGPT "); LogFile.BeginAction("RestoreGPT"); try { Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); FlashModel = (NokiaFlashModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash)); byte[] GptChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(FlashModel, 0x20000); GPT GPT = new GPT(GptChunk); string Xml = File.ReadAllText(args[2]); GPT.MergePartitions(Xml, false); GPT.Rebuild(); await LumiaV2UnlockBootViewModel.LumiaV2CustomFlash(Notifier, null, false, false, 0, GptChunk, true, true); FlashModel.SwitchToFlashAppContext(); Notifier.Stop(); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("RestoreGPT"); } break; case "mergegpt": if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -MergeGPT Or use: WPinternals.exe -MergeGPT "); LogFile.BeginAction("MergeGPT"); try { GPT GPT = GPT.ReadPartitions(args[2]); ZipArchive Archive = null; FileStream s = null; try { s = new FileStream(args[3], FileMode.Open, FileAccess.Read); Archive = new ZipArchive(s); } catch { } if (Archive == null) { if (s != null) s.Close(); // Assume Xml-file GPT.MergePartitionsFromFile(args[3], true); } else { ZipArchiveEntry PartitionEntry = Archive.GetEntry("Partitions.xml"); if (PartitionEntry == null) GPT.MergePartitions(null, true, Archive); else { using (Stream ZipStream = PartitionEntry.Open()) { using (StreamReader ZipReader = new StreamReader(ZipStream)) { string PartitionXml = ZipReader.ReadToEnd(); GPT.MergePartitions(PartitionXml, true, Archive); } } } } if (Archive != null) Archive.Dispose(); if (args.Count() >= 5) GPT.WritePartitions(args[4]); foreach (Partition Partition in GPT.Partitions) LogFile.Log(Partition.Name.PadRight(20) + "0x" + Partition.FirstSector.ToString("X8") + " - 0x" + Partition.LastSector.ToString("X8") + " " + Partition.Volume, LogType.ConsoleOnly); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("MergeGPT"); } break; case "dumpffu": if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -DumpFFU "); FFU = new FFU(args[2]); if (args.Length < 5) { foreach (Partition Partition in FFU.GPT.Partitions) { if (FFU.IsPartitionPresentInFFU(Partition.Name)) { FFU.WritePartition(Partition.Name, System.IO.Path.Combine(args[3], Partition.Name + ".bin")); } } } else { Partition Target = FFU.GPT.GetPartition(args[4]); if ((Target == null) || (!FFU.IsPartitionPresentInFFU(Target.Name))) throw new InvalidOperationException("Partition not found in FFU!"); FFU.WritePartition(Target.Name, System.IO.Path.Combine(args[3], Target.Name + ".bin")); } break; case "dumpuefi": if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -DumpUEFI "); byte[] UefiBinary; if (FFU.IsFFU(args[2])) { FFU = new FFU(args[2]); UefiBinary = FFU.GetPartition("UEFI"); } else { UefiBinary = File.ReadAllBytes(args[2]); } UEFI UEFI = new UEFI(UefiBinary); foreach (EFI Efi in UEFI.EFIs) { byte[] EfiBinary = UEFI.GetFile(Efi.Guid); string Name = Efi.Name; if (Name == null) Name = Efi.Guid.ToString(); if (!Name.Contains('.')) { switch (Efi.Type) { case 5: case 7: Name += ".dll"; break; case 9: Name += ".exe"; break; default: Name += ".bin"; break; } } string EfiPath = Path.Combine(args[3], Name); Directory.CreateDirectory(Path.GetDirectoryName(EfiPath)); File.WriteAllBytes(EfiPath, EfiBinary); } break; case "testprogrammer": if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -TestProgrammer "); await TestCode.TestProgrammer(UIContext, args[2]); break; case "findflashingprofile": Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); if (args.Length > 2) await LumiaV2UnlockBootViewModel.LumiaV2FindFlashingProfile(Notifier, args[2]); else await LumiaV2UnlockBootViewModel.LumiaV2FindFlashingProfile(Notifier, null); Notifier.Stop(); break; case "findflashingprofileexperimental": Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); if (args.Length > 2) await LumiaV2UnlockBootViewModel.LumiaV2FindFlashingProfile(Notifier, args[2], Experimental: true); else await LumiaV2UnlockBootViewModel.LumiaV2FindFlashingProfile(Notifier, null, Experimental: true); Notifier.Stop(); break; case "findflashingprofilenorestart": Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); if (args.Length > 2) await LumiaV2UnlockBootViewModel.LumiaV2FindFlashingProfile(Notifier, args[2], false); else await LumiaV2UnlockBootViewModel.LumiaV2FindFlashingProfile(Notifier, null, false); Notifier.Stop(); break; case "enabletestsigning": if (args.Length > 2) await LumiaV2UnlockBootViewModel.LumiaV2EnableTestSigning(UIContext, args[2]); else await LumiaV2UnlockBootViewModel.LumiaV2EnableTestSigning(UIContext, null); break; case "enabletestsigningnorestart": if (args.Length > 2) await LumiaV2UnlockBootViewModel.LumiaV2EnableTestSigning(UIContext, args[2], false); else await LumiaV2UnlockBootViewModel.LumiaV2EnableTestSigning(UIContext, null, false); break; case "clearnv": if (args.Length > 2) await LumiaV2UnlockBootViewModel.LumiaV2ClearNV(UIContext, args[2]); else await LumiaV2UnlockBootViewModel.LumiaV2ClearNV(UIContext, null); break; case "switchtomassstoragemode": LogFile.BeginAction("SwitchToMassStorageMode"); try { Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); LogFile.Log("Command: Switch to Mass Storage Mode", LogType.FileAndConsole); if (args.Length > 2) await LumiaV2UnlockBootViewModel.LumiaV2SwitchToMassStorageMode(Notifier, args[2]); else await LumiaV2UnlockBootViewModel.LumiaV2SwitchToMassStorageMode(Notifier, null); Notifier.Stop(); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("SwitchToMassStorageMode"); } break; case "relockphone": Notifier = new PhoneNotifierViewModel(); try { UIContext.Send(s => Notifier.Start(), null); FlashModel = (NokiaFlashModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash)); Info = FlashModel.ReadPhoneInfo(); Info.Log(LogType.ConsoleOnly); FFU ProfileFFU = null; FFU CurrentFFU; for (int i = 2; i <= 3; i++) { if (args.Length > i) { CurrentFFU = new FFU(args[i]); string CurrentVersion = CurrentFFU.GetOSVersion(); string PlatformID = CurrentFFU.PlatformID; // Check if the current FFU matches the connected phone, so that the FFU can be used for profiling. if (Info.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase)) ProfileFFU = CurrentFFU; } } if (ProfileFFU == null) { List FFUs = App.Config.FFURepository.Where(e => (Info.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists())).ToList(); if (FFUs.Count() > 0) ProfileFFU = new FFU(FFUs[0].Path); else throw new WPinternalsException("Profile FFU missing"); } LogFile.Log("Profile FFU: " + ProfileFFU.Path); UIContext.Send(s => Notifier.Start(), null); await LumiaUnlockBootloaderViewModel.LumiaRelockUEFI(Notifier, ProfileFFU.Path); } catch (Exception Ex) { LogFile.LogException(Ex); } Notifier.Stop(); break; case "addffu": if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -AddFFU "); App.Config.AddFfuToRepository(args[2]); break; case "removeffu": if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -RemoveFFU "); App.Config.RemoveFfuFromRepository(args[2]); break; case "addemergency": if (args.Length < 5) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -AddEmergnency "); App.Config.AddEmergencyToRepository(args[2], args[3], args[4]); break; case "removeemergency": if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -RemoveEmergency "); App.Config.RemoveEmergencyFromRepository(args[2]); break; case "listrepository": int Count = 0; LogFile.Log("", LogType.ConsoleOnly); LogFile.Log("FFU Repository:", LogType.ConsoleOnly); foreach (FFUEntry Entry in App.Config.FFURepository) { LogFile.Log("", LogType.ConsoleOnly); LogFile.Log("FFU " + Count.ToString() + ":", LogType.ConsoleOnly); LogFile.Log("File: " + Entry.Path + (Entry.Exists() ? "" : " (file is missing)"), LogType.ConsoleOnly); LogFile.Log("Platform ID: " + Entry.PlatformID, LogType.ConsoleOnly); if (Entry.FirmwareVersion != null) LogFile.Log("Firmware version: " + Entry.FirmwareVersion, LogType.ConsoleOnly); if (Entry.OSVersion != null) LogFile.Log("OS version: " + Entry.OSVersion, LogType.ConsoleOnly); Count++; } LogFile.Log("", LogType.ConsoleOnly); LogFile.Log("Emergency Repository:", LogType.ConsoleOnly); Count = 0; foreach (EmergencyFileEntry Entry in App.Config.EmergencyRepository) { LogFile.Log("", LogType.ConsoleOnly); LogFile.Log("Emergency " + Count.ToString() + ":", LogType.ConsoleOnly); LogFile.Log("Type: " + Entry.Type, LogType.ConsoleOnly); LogFile.Log("Programmer file: " + Entry.ProgrammerPath + (Entry.ProgrammerExists() ? "" : " (file is missing)"), LogType.ConsoleOnly); if (Entry.PayloadPath != null) LogFile.Log("Payload file: " + Entry.PayloadPath + (Entry.PayloadExists() ? "" : " (file is missing)"), LogType.ConsoleOnly); Count++; } break; case "showffu": if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -ShowFFU "); string FFUPath = args[2]; LogFile.Log("FFU: " + FFUPath, LogType.ConsoleOnly); FFU = new FFU(FFUPath); // Show basics LogFile.Log("Platform ID: " + FFU.PlatformID, LogType.ConsoleOnly); string Firmware = FFU.GetFirmwareVersion(); if (Firmware != null) LogFile.Log("Firmware version: " + Firmware, LogType.ConsoleOnly); string OSVersion = FFU.GetOSVersion(); if (OSVersion != null) LogFile.Log("OS version: " + OSVersion, LogType.ConsoleOnly); // Show partitions from GPT (also show which partitions are in the FFU payload) LogFile.Log("", LogType.ConsoleOnly); LogFile.Log("Partition table:", LogType.ConsoleOnly); LogFile.Log("Name".PadRight(20) + "Start-sector".PadRight(20) + "End-sector".PadRight(20) + "Present in FFU", LogType.ConsoleOnly); foreach (Partition p in FFU.GPT.Partitions) { LogFile.Log(p.Name.PadRight(20) + ("0x" + p.FirstSector.ToString("X16")).PadRight(20) + ("0x" + p.LastSector.ToString("X16")).PadRight(20) + (FFU.IsPartitionPresentInFFU(p.Name) ? "Yes" : "No"), LogType.ConsoleOnly); } break; case "showphoneinfo": LogFile.Log("Command: Show phone info", LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); FlashModel = (NokiaFlashModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash)); Info = FlashModel.ReadPhoneInfo(); Info.Log(LogType.ConsoleOnly); Notifier.Stop(); break; case "unlockbootloader": LogFile.BeginAction("UnlockBootloader"); try { LogFile.Log("Command: Unlock Bootloader", LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); FlashModel = (NokiaFlashModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash)); Info = FlashModel.ReadPhoneInfo(); Info.Log(LogType.ConsoleOnly); FFU ProfileFFU = null; FFU SupportedFFU = null; FFU CurrentFFU; for (int i = 2; i <= 3; i++) { if (args.Length > i) { CurrentFFU = new FFU(args[i]); string CurrentVersion = CurrentFFU.GetOSVersion(); string PlatformID = CurrentFFU.PlatformID; // Check if the current FFU matches the connected phone, so that the FFU can be used for profiling. if (Info.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase)) ProfileFFU = CurrentFFU; // Check if the current FFU is supported for unlocking. if (App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == CurrentVersion)) SupportedFFU = CurrentFFU; } } if (ProfileFFU == null) { List FFUs = App.Config.FFURepository.Where(e => (Info.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists())).ToList(); if (FFUs.Count() > 0) ProfileFFU = new FFU(FFUs[0].Path); else throw new WPinternalsException("Profile FFU missing"); } LogFile.Log("Profile FFU: " + ProfileFFU.Path); if (SupportedFFU == null) { List FFUs = App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).ToList(); if (FFUs.Count() > 0) SupportedFFU = new FFU(FFUs[0].Path); else throw new WPinternalsException("No donor-FFU found with supported OS version"); } await LumiaUnlockBootloaderViewModel.LumiaUnlockUEFI(Notifier, ProfileFFU.Path, null, SupportedFFU.Path); Notifier.Stop(); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("UnlockBootloader"); } break; case "flashcustomrom": LogFile.BeginAction("FlashCustomROM"); try { LogFile.Log("Command: Flash Custom ROM", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -FlashCustomROM "); string CustomRomPath = args[2]; LogFile.Log("Custom ROM: " + CustomRomPath, LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); FlashModel = (NokiaFlashModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash)); Info = FlashModel.ReadPhoneInfo(); Info.Log(LogType.ConsoleOnly); LogFile.Log("Preparing to flash Custom ROM", LogType.FileAndConsole); await LumiaV2UnlockBootViewModel.LumiaV2FlashArchive(Notifier, CustomRomPath); LogFile.Log("Custom ROM flashed successfully", LogType.FileAndConsole); Notifier.Stop(); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("FlashCustomROM"); } break; case "flashffu": LogFile.BeginAction("FlashFFU"); try { LogFile.Log("Command: Flash FFU", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -FlashFFU "); FFUPath = args[2]; LogFile.Log("FFU file: " + FFUPath, LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); FlashModel = (NokiaFlashModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash)); Info = FlashModel.ReadPhoneInfo(); Info.Log(LogType.ConsoleOnly); LogFile.Log("Flashing FFU...", LogType.FileAndConsole); await Task.Run(() => FlashModel.FlashFFU(new FFU(FFUPath), true, (byte)((Info.RdcPresent || !Info.SecureFfuEnabled || Info.Authenticated) ? FlashOptions.SkipSignatureCheck : 0))); LogFile.Log("FFU flashed successfully", LogType.FileAndConsole); Notifier.Stop(); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("FlashFFU"); } break; case "fixbootafterunlockingbootloader": LogFile.BeginAction("FixBoot"); try { LogFile.Log("Command: Fix boot after unlocking bootloader", LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); string Drive = await LumiaV2UnlockBootViewModel.LumiaV2SwitchToMassStorageMode(Notifier, null); Notifier.Stop(); App.PatchEngine.TargetPath = Drive + "\\"; PatchResult = App.PatchEngine.Patch("SecureBootHack-MainOS"); if (!PatchResult) throw new WPinternalsException("Patch failed"); LogFile.Log("Fixed bootloader", LogType.FileAndConsole); LogFile.Log("The phone is left in Mass Storage mode", LogType.FileAndConsole); LogFile.Log("Press and hold the power-button of the phone for at least 10 seconds to reset the phone", LogType.FileAndConsole); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("FixBoot"); } break; case "enablerootaccess": LogFile.BeginAction("EnableRootAccess"); try { LogFile.Log("Command: Enable root access on the phone", LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); string Drive = await LumiaV2UnlockBootViewModel.LumiaV2SwitchToMassStorageMode(Notifier, null); Notifier.Stop(); App.PatchEngine.TargetPath = Drive + "\\EFIESP\\"; PatchResult = App.PatchEngine.Patch("SecureBootHack-V2-EFIESP"); if (!PatchResult) throw new WPinternalsException("Patch failed"); App.PatchEngine.TargetPath = Drive + "\\"; PatchResult = App.PatchEngine.Patch("SecureBootHack-MainOS"); if (!PatchResult) throw new WPinternalsException("Patch failed"); PatchResult = App.PatchEngine.Patch("RootAccess-MainOS"); if (!PatchResult) throw new WPinternalsException("Patch failed"); LogFile.Log("Root Access enabled!", LogType.FileAndConsole); LogFile.Log("The phone is left in Mass Storage mode", LogType.FileAndConsole); LogFile.Log("Press and hold the power-button of the phone for at least 10 seconds to reset the phone", LogType.FileAndConsole); } catch (Exception Ex) { LogFile.LogException(Ex); } finally { LogFile.EndAction("EnableRootAccess"); } break; case "unlockbootloaderonimage": LogFile.Log("Command: Unlock bootloader on image", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -UnlockBootLoaderOnImage "); FFUFilePath = null; EfiEspImagePath = args[2]; if (args.Length > 3) { if (FFU.IsFFU(args[3])) FFUFilePath = args[3]; else MainOsImagePath = args[3]; } if (args.Length > 4) FFUFilePath = args[4]; using (FileStream FileSystemStream = new FileStream(EfiEspImagePath, FileMode.Open, FileAccess.ReadWrite)) { UnlockedEFIESPFileSystem = new DiscUtils.Fat.FatFileSystem(FileSystemStream); if (FFUFilePath != null) { FFU SupportedFFU = new FFU(FFUFilePath); LogFile.Log("Donor FFU: " + SupportedFFU.Path); byte[] SupportedEFIESP = SupportedFFU.GetPartition("EFIESP"); DiscUtils.Fat.FatFileSystem SupportedEFIESPFileSystem = new DiscUtils.Fat.FatFileSystem(new MemoryStream(SupportedEFIESP)); DiscUtils.SparseStream SupportedMobileStartupStream = SupportedEFIESPFileSystem.OpenFile(@"\Windows\System32\Boot\mobilestartup.efi", FileMode.Open); MemoryStream SupportedMobileStartupMemStream = new MemoryStream(); SupportedMobileStartupStream.CopyTo(SupportedMobileStartupMemStream); byte[] SupportedMobileStartup = SupportedMobileStartupMemStream.ToArray(); SupportedMobileStartupMemStream.Close(); SupportedMobileStartupStream.Close(); // Save supported mobilestartup.efi LogFile.Log("Taking mobilestartup.efi from donor-FFU"); Stream MobileStartupStream = UnlockedEFIESPFileSystem.OpenFile(@"Windows\System32\Boot\mobilestartup.efi", FileMode.Create, FileAccess.Write); MobileStartupStream.Write(SupportedMobileStartup, 0, SupportedMobileStartup.Length); MobileStartupStream.Close(); } App.PatchEngine.TargetImage = UnlockedEFIESPFileSystem; PatchResult = App.PatchEngine.Patch("SecureBootHack-V2-EFIESP"); if (!PatchResult) throw new WPinternalsException("Failed to patch bootloader"); // Edit BCD LogFile.Log("Edit BCD"); using (Stream BCDFileStream = UnlockedEFIESPFileSystem.OpenFile(@"efi\Microsoft\Boot\BCD", FileMode.Open, FileAccess.ReadWrite)) { using (DiscUtils.Registry.RegistryHive BCDHive = new DiscUtils.Registry.RegistryHive(BCDFileStream)) { DiscUtils.BootConfig.Store BCDStore = new DiscUtils.BootConfig.Store(BCDHive.Root); DiscUtils.BootConfig.BcdObject MobileStartupObject = BCDStore.GetObject(new Guid("{01de5a27-8705-40db-bad6-96fa5187d4a6}")); DiscUtils.BootConfig.Element NoCodeIntegrityElement = MobileStartupObject.GetElement(0x16000048); if (NoCodeIntegrityElement != null) NoCodeIntegrityElement.Value = DiscUtils.BootConfig.ElementValue.ForBoolean(true); else MobileStartupObject.AddElement(0x16000048, DiscUtils.BootConfig.ElementValue.ForBoolean(true)); DiscUtils.BootConfig.BcdObject WinLoadObject = BCDStore.GetObject(new Guid("{7619dcc9-fafe-11d9-b411-000476eba25f}")); NoCodeIntegrityElement = WinLoadObject.GetElement(0x16000048); if (NoCodeIntegrityElement != null) NoCodeIntegrityElement.Value = DiscUtils.BootConfig.ElementValue.ForBoolean(true); else WinLoadObject.AddElement(0x16000048, DiscUtils.BootConfig.ElementValue.ForBoolean(true)); } } } if (MainOsImagePath != null) { using (FileStream FileSystemStream = new FileStream(MainOsImagePath, FileMode.Open, FileAccess.ReadWrite)) { UnlockedMainOsFileSystem = new DiscUtils.Ntfs.NtfsFileSystem(FileSystemStream); App.PatchEngine.TargetImage = UnlockedMainOsFileSystem; PatchResult = App.PatchEngine.Patch("SecureBootHack-MainOS"); if (!PatchResult) throw new WPinternalsException("Failed to patch MainOS"); } } LogFile.Log("Bootloader unlocked on image", LogType.FileAndConsole); break; case "enablerootaccessonimage": LogFile.Log("Command: Enable root access on image", LogType.FileAndConsole); if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -EnableRootAccessOnImage "); FFUFilePath = null; EfiEspImagePath = args[2]; MainOsImagePath = args[3]; if (args.Length > 4) FFUFilePath = args[4]; using (FileStream FileSystemStream = new FileStream(EfiEspImagePath, FileMode.Open, FileAccess.ReadWrite)) { UnlockedEFIESPFileSystem = new DiscUtils.Fat.FatFileSystem(FileSystemStream); if (FFUFilePath != null) { FFU SupportedFFU = new FFU(FFUFilePath); LogFile.Log("Supported FFU: " + SupportedFFU.Path); byte[] SupportedEFIESP = SupportedFFU.GetPartition("EFIESP"); DiscUtils.Fat.FatFileSystem SupportedEFIESPFileSystem = new DiscUtils.Fat.FatFileSystem(new MemoryStream(SupportedEFIESP)); DiscUtils.SparseStream SupportedMobileStartupStream = SupportedEFIESPFileSystem.OpenFile(@"\Windows\System32\Boot\mobilestartup.efi", FileMode.Open); MemoryStream SupportedMobileStartupMemStream = new MemoryStream(); SupportedMobileStartupStream.CopyTo(SupportedMobileStartupMemStream); byte[] SupportedMobileStartup = SupportedMobileStartupMemStream.ToArray(); SupportedMobileStartupMemStream.Close(); SupportedMobileStartupStream.Close(); // Save supported mobilestartup.efi LogFile.Log("Taking mobilestartup.efi from donor-FFU"); Stream MobileStartupStream = UnlockedEFIESPFileSystem.OpenFile(@"Windows\System32\Boot\mobilestartup.efi", FileMode.Create, FileAccess.Write); MobileStartupStream.Write(SupportedMobileStartup, 0, SupportedMobileStartup.Length); MobileStartupStream.Close(); } App.PatchEngine.TargetImage = UnlockedEFIESPFileSystem; PatchResult = App.PatchEngine.Patch("SecureBootHack-V2-EFIESP"); if (!PatchResult) throw new WPinternalsException("Failed to patch bootloader"); // Edit BCD LogFile.Log("Edit BCD"); using (Stream BCDFileStream = UnlockedEFIESPFileSystem.OpenFile(@"efi\Microsoft\Boot\BCD", FileMode.Open, FileAccess.ReadWrite)) { using (DiscUtils.Registry.RegistryHive BCDHive = new DiscUtils.Registry.RegistryHive(BCDFileStream)) { DiscUtils.BootConfig.Store BCDStore = new DiscUtils.BootConfig.Store(BCDHive.Root); DiscUtils.BootConfig.BcdObject MobileStartupObject = BCDStore.GetObject(new Guid("{01de5a27-8705-40db-bad6-96fa5187d4a6}")); DiscUtils.BootConfig.Element NoCodeIntegrityElement = MobileStartupObject.GetElement(0x16000048); if (NoCodeIntegrityElement != null) NoCodeIntegrityElement.Value = DiscUtils.BootConfig.ElementValue.ForBoolean(true); else MobileStartupObject.AddElement(0x16000048, DiscUtils.BootConfig.ElementValue.ForBoolean(true)); DiscUtils.BootConfig.BcdObject WinLoadObject = BCDStore.GetObject(new Guid("{7619dcc9-fafe-11d9-b411-000476eba25f}")); NoCodeIntegrityElement = WinLoadObject.GetElement(0x16000048); if (NoCodeIntegrityElement != null) NoCodeIntegrityElement.Value = DiscUtils.BootConfig.ElementValue.ForBoolean(true); else WinLoadObject.AddElement(0x16000048, DiscUtils.BootConfig.ElementValue.ForBoolean(true)); } } } using (FileStream FileSystemStream = new FileStream(MainOsImagePath, FileMode.Open, FileAccess.ReadWrite)) { UnlockedMainOsFileSystem = new DiscUtils.Ntfs.NtfsFileSystem(FileSystemStream); App.PatchEngine.TargetImage = UnlockedMainOsFileSystem; PatchResult = App.PatchEngine.Patch("SecureBootHack-MainOS"); if (!PatchResult) throw new WPinternalsException("Failed to patch MainOS"); PatchResult = App.PatchEngine.Patch("RootAccess-MainOS"); if (!PatchResult) throw new WPinternalsException("Failed to patch MainOS"); } LogFile.Log("Root access enabled on image", LogType.FileAndConsole); break; case "unlockbootloaderonmountedimage": LogFile.Log("Command: Unlock bootloader on mounted image", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -UnlockBootLoaderOnMountedImage "); FFUFilePath = null; EfiEspImagePath = args[2]; if (args.Length > 3) { if (FFU.IsFFU(args[3])) FFUFilePath = args[3]; else MainOsImagePath = args[3]; } if (args.Length > 4) FFUFilePath = args[4]; if (FFUFilePath != null) { FFU SupportedFFU = new FFU(FFUFilePath); LogFile.Log("Donor-FFU: " + SupportedFFU.Path); byte[] SupportedEFIESP = SupportedFFU.GetPartition("EFIESP"); DiscUtils.Fat.FatFileSystem SupportedEFIESPFileSystem = new DiscUtils.Fat.FatFileSystem(new MemoryStream(SupportedEFIESP)); DiscUtils.SparseStream SupportedMobileStartupStream = SupportedEFIESPFileSystem.OpenFile(@"\Windows\System32\Boot\mobilestartup.efi", FileMode.Open); MemoryStream SupportedMobileStartupMemStream = new MemoryStream(); SupportedMobileStartupStream.CopyTo(SupportedMobileStartupMemStream); byte[] SupportedMobileStartup = SupportedMobileStartupMemStream.ToArray(); SupportedMobileStartupMemStream.Close(); SupportedMobileStartupStream.Close(); // Save supported mobilestartup.efi LogFile.Log("Taking mobilestartup.efi from donor-FFU"); Stream MobileStartupStream = File.Open(Path.Combine(EfiEspImagePath, @"Windows\System32\Boot\mobilestartup.efi"), FileMode.Create, FileAccess.Write); MobileStartupStream.Write(SupportedMobileStartup, 0, SupportedMobileStartup.Length); MobileStartupStream.Close(); } App.PatchEngine.TargetPath = EfiEspImagePath; PatchResult = App.PatchEngine.Patch("SecureBootHack-V2-EFIESP"); if (!PatchResult) throw new WPinternalsException("Failed to patch bootloader"); // Edit BCD LogFile.Log("Edit BCD"); using (Stream BCDFileStream = File.Open(Path.Combine(EfiEspImagePath, @"efi\Microsoft\Boot\BCD"), FileMode.Open, FileAccess.ReadWrite)) { using (DiscUtils.Registry.RegistryHive BCDHive = new DiscUtils.Registry.RegistryHive(BCDFileStream)) { DiscUtils.BootConfig.Store BCDStore = new DiscUtils.BootConfig.Store(BCDHive.Root); DiscUtils.BootConfig.BcdObject MobileStartupObject = BCDStore.GetObject(new Guid("{01de5a27-8705-40db-bad6-96fa5187d4a6}")); DiscUtils.BootConfig.Element NoCodeIntegrityElement = MobileStartupObject.GetElement(0x16000048); if (NoCodeIntegrityElement != null) NoCodeIntegrityElement.Value = DiscUtils.BootConfig.ElementValue.ForBoolean(true); else MobileStartupObject.AddElement(0x16000048, DiscUtils.BootConfig.ElementValue.ForBoolean(true)); DiscUtils.BootConfig.BcdObject WinLoadObject = BCDStore.GetObject(new Guid("{7619dcc9-fafe-11d9-b411-000476eba25f}")); NoCodeIntegrityElement = WinLoadObject.GetElement(0x16000048); if (NoCodeIntegrityElement != null) NoCodeIntegrityElement.Value = DiscUtils.BootConfig.ElementValue.ForBoolean(true); else WinLoadObject.AddElement(0x16000048, DiscUtils.BootConfig.ElementValue.ForBoolean(true)); } } if (MainOsImagePath != null) { App.PatchEngine.TargetPath = MainOsImagePath; PatchResult = App.PatchEngine.Patch("SecureBootHack-MainOS"); if (!PatchResult) throw new WPinternalsException("Failed to patch MainOS"); } LogFile.Log("Bootloader unlocked on image", LogType.FileAndConsole); break; case "enablerootaccessonmountedimage": LogFile.Log("Command: Enable root access on mounted image", LogType.FileAndConsole); if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -EnableRootAccessOnMountedImage "); FFUFilePath = null; EfiEspImagePath = args[2]; MainOsImagePath = args[3]; if (args.Length > 4) FFUFilePath = args[4]; if (FFUFilePath != null) { FFU SupportedFFU = new FFU(FFUFilePath); LogFile.Log("Supported FFU: " + SupportedFFU.Path); byte[] SupportedEFIESP = SupportedFFU.GetPartition("EFIESP"); DiscUtils.Fat.FatFileSystem SupportedEFIESPFileSystem = new DiscUtils.Fat.FatFileSystem(new MemoryStream(SupportedEFIESP)); DiscUtils.SparseStream SupportedMobileStartupStream = SupportedEFIESPFileSystem.OpenFile(@"\Windows\System32\Boot\mobilestartup.efi", FileMode.Open); MemoryStream SupportedMobileStartupMemStream = new MemoryStream(); SupportedMobileStartupStream.CopyTo(SupportedMobileStartupMemStream); byte[] SupportedMobileStartup = SupportedMobileStartupMemStream.ToArray(); SupportedMobileStartupMemStream.Close(); SupportedMobileStartupStream.Close(); // Save supported mobilestartup.efi LogFile.Log("Taking mobilestartup.efi from donor-FFU"); Stream MobileStartupStream = File.Open(Path.Combine(EfiEspImagePath, @"Windows\System32\Boot\mobilestartup.efi"), FileMode.Create, FileAccess.Write); MobileStartupStream.Write(SupportedMobileStartup, 0, SupportedMobileStartup.Length); MobileStartupStream.Close(); } App.PatchEngine.TargetPath = EfiEspImagePath; PatchResult = App.PatchEngine.Patch("SecureBootHack-V2-EFIESP"); if (!PatchResult) throw new WPinternalsException("Failed to patch bootloader"); // Edit BCD LogFile.Log("Edit BCD"); using (Stream BCDFileStream = File.Open(Path.Combine(EfiEspImagePath, @"efi\Microsoft\Boot\BCD"), FileMode.Open, FileAccess.ReadWrite)) { using (DiscUtils.Registry.RegistryHive BCDHive = new DiscUtils.Registry.RegistryHive(BCDFileStream)) { DiscUtils.BootConfig.Store BCDStore = new DiscUtils.BootConfig.Store(BCDHive.Root); DiscUtils.BootConfig.BcdObject MobileStartupObject = BCDStore.GetObject(new Guid("{01de5a27-8705-40db-bad6-96fa5187d4a6}")); DiscUtils.BootConfig.Element NoCodeIntegrityElement = MobileStartupObject.GetElement(0x16000048); if (NoCodeIntegrityElement != null) NoCodeIntegrityElement.Value = DiscUtils.BootConfig.ElementValue.ForBoolean(true); else MobileStartupObject.AddElement(0x16000048, DiscUtils.BootConfig.ElementValue.ForBoolean(true)); DiscUtils.BootConfig.BcdObject WinLoadObject = BCDStore.GetObject(new Guid("{7619dcc9-fafe-11d9-b411-000476eba25f}")); NoCodeIntegrityElement = WinLoadObject.GetElement(0x16000048); if (NoCodeIntegrityElement != null) NoCodeIntegrityElement.Value = DiscUtils.BootConfig.ElementValue.ForBoolean(true); else WinLoadObject.AddElement(0x16000048, DiscUtils.BootConfig.ElementValue.ForBoolean(true)); } } App.PatchEngine.TargetPath = MainOsImagePath; PatchResult = App.PatchEngine.Patch("SecureBootHack-MainOS"); if (!PatchResult) throw new WPinternalsException("Failed to patch MainOS"); PatchResult = App.PatchEngine.Patch("RootAccess-MainOS"); if (!PatchResult) throw new WPinternalsException("Failed to patch MainOS"); LogFile.Log("Root access enabled on image", LogType.FileAndConsole); break; case "downloadffu": LogFile.Log("Command: Download FFU", LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Normal) { NormalModel = (NokiaPhoneModel)Notifier.CurrentModel; ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); } else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)) { FlashModel = (NokiaFlashModel)Notifier.CurrentModel; Info = FlashModel.ReadPhoneInfo(); ProductCode = Info.ProductCode; } else { NormalModel = (NokiaPhoneModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal)); ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); } URL = LumiaDownloadModel.SearchFFU(null, ProductCode, null, out ProductType); if (args.Length >= 3) DownloadFolder = args[4]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); Notifier.Stop(); break; case "downloadffubyoperatorcode": LogFile.Log("Command: Download FFU by Operator Code", LogType.FileAndConsole); if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -DownloadFFUbyOperatorCode "); ProductType = args[2]; LogFile.Log("Product type: " + ProductType, LogType.FileAndConsole); OperatorCode = args[3]; LogFile.Log("Operator code: " + OperatorCode, LogType.FileAndConsole); if (args.Length >= 5) DownloadFolder = args[4]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); URL = LumiaDownloadModel.SearchFFU(ProductType, null, OperatorCode); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); break; case "downloadffubyproductcode": LogFile.Log("Command: Download FFU by Product Code", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -DownloadFFUbyProductCode "); ProductCode = args[2]; LogFile.Log("Product code: " + ProductCode, LogType.FileAndConsole); URL = LumiaDownloadModel.SearchFFU(null, ProductCode, null, out ProductType); if (args.Length >= 4) DownloadFolder = args[3]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); break; case "downloadffubyproducttype": LogFile.Log("Command: Download FFU by Product Type", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -DownloadFFUbyProductType "); ProductType = args[2]; LogFile.Log("Product type: " + ProductType, LogType.FileAndConsole); if (args.Length >= 4) DownloadFolder = args[3]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); URL = LumiaDownloadModel.SearchFFU(ProductType, null, null); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); break; case "searchffubyproducttype": LogFile.Log("Command: Search FFU by Product Type", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -SearchFFUbyProductType "); ProductType = args[2]; LogFile.Log("Lumia model: " + ProductType, LogType.FileAndConsole); URL = LumiaDownloadModel.SearchFFU(ProductType, null, null); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); break; case "downloademergency": LogFile.Log("Command: Download Emergency files", LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Normal) { NormalModel = (NokiaPhoneModel)Notifier.CurrentModel; ProductType = NormalModel.ExecuteJsonMethodAsString("ReadManufacturerModelName", "ManufacturerModelName"); if (ProductType.IndexOf('_') >= 0) ProductType = ProductType.Substring(0, ProductType.IndexOf('_')); } else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)) { FlashModel = (NokiaFlashModel)Notifier.CurrentModel; Info = FlashModel.ReadPhoneInfo(); ProductType = Info.Type; } else { NormalModel = (NokiaPhoneModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal)); ProductType = NormalModel.ExecuteJsonMethodAsString("ReadManufacturerModelName", "ManufacturerModelName"); if (ProductType.IndexOf('_') >= 0) ProductType = ProductType.Substring(0, ProductType.IndexOf('_')); } URLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType); if (URLs != null) { if (args.Length >= 3) DownloadFolder = args[2]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); for (int i = 0; i < URLs.Length; i++) { LogFile.Log("URL: " + URLs[i], LogType.FileAndConsole); URI = new Uri(URLs[i]); EmergencyFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + EmergencyFileName, LogType.FileAndConsole); EmergencyFilePath = Path.Combine(DownloadFolder, EmergencyFileName); if (i == 0) ProgrammerPath = EmergencyFilePath; else PayloadPath = EmergencyFilePath; LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URLs[i], EmergencyFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); } App.Config.AddEmergencyToRepository(ProductType, ProgrammerPath, PayloadPath); } Notifier.Stop(); break; case "downloademergencybyproducttype": LogFile.Log("Command: Download Emergency files", LogType.FileAndConsole); if (args.Length < 3) throw new WPinternalsException("Wrong number of arguments. Usage: WPinternals.exe -DownloadEmergencyByProductType "); ProductType = args[2]; URLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType); if (URLs != null) { if (args.Length >= 4) DownloadFolder = args[3]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); for (int i = 0; i < URLs.Length; i++) { LogFile.Log("URL: " + URLs[i], LogType.FileAndConsole); URI = new Uri(URLs[i]); EmergencyFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + EmergencyFileName, LogType.FileAndConsole); EmergencyFilePath = Path.Combine(DownloadFolder, EmergencyFileName); if (i == 0) ProgrammerPath = EmergencyFilePath; else PayloadPath = EmergencyFilePath; LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URLs[i], EmergencyFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); } App.Config.AddEmergencyToRepository(ProductType, ProgrammerPath, PayloadPath); } break; case "downloadall": LogFile.Log("Command: Download all", LogType.FileAndConsole); Notifier = new PhoneNotifierViewModel(); UIContext.Send(s => Notifier.Start(), null); if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Normal) { NormalModel = (NokiaPhoneModel)Notifier.CurrentModel; ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); } else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)) { FlashModel = (NokiaFlashModel)Notifier.CurrentModel; Info = FlashModel.ReadPhoneInfo(); ProductCode = Info.ProductCode; } else { NormalModel = (NokiaPhoneModel)(await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Normal)); ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode"); } URL = LumiaDownloadModel.SearchFFU(null, ProductCode, null, out ProductType); if (args.Length >= 3) DownloadFolder = args[2]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); URLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType); if (URLs != null) { for (int i = 0; i < URLs.Length; i++) { LogFile.Log("URL: " + URLs[i], LogType.FileAndConsole); URI = new Uri(URLs[i]); EmergencyFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + EmergencyFileName, LogType.FileAndConsole); EmergencyFilePath = Path.Combine(DownloadFolder, EmergencyFileName); if (i == 0) ProgrammerPath = EmergencyFilePath; else PayloadPath = EmergencyFilePath; LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URLs[i], EmergencyFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); } App.Config.AddEmergencyToRepository(ProductType, ProgrammerPath, PayloadPath); } if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0) { ProductType = "RM-1085"; URL = LumiaDownloadModel.SearchFFU(ProductType, null, null); if (args.Length >= 3) DownloadFolder = args[2]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0) throw new WPinternalsException("Unable to find compatible FFU"); } Notifier.Stop(); break; case "downloadallbyproducttype": LogFile.Log("Command: Download all by Product Type", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -DownloadAllByProductType "); ProductType = args[2]; LogFile.Log("Product type: " + ProductType, LogType.FileAndConsole); if (args.Length >= 4) DownloadFolder = args[3]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); URL = LumiaDownloadModel.SearchFFU(ProductType, null, null); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); URLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType); if (URLs != null) { for (int i = 0; i < URLs.Length; i++) { LogFile.Log("URL: " + URLs[i], LogType.FileAndConsole); URI = new Uri(URLs[i]); EmergencyFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + EmergencyFileName, LogType.FileAndConsole); EmergencyFilePath = Path.Combine(DownloadFolder, EmergencyFileName); if (i == 0) ProgrammerPath = EmergencyFilePath; else PayloadPath = EmergencyFilePath; LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URLs[i], EmergencyFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); } App.Config.AddEmergencyToRepository(ProductType, ProgrammerPath, PayloadPath); } if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0) { ProductType = "RM-1085"; URL = LumiaDownloadModel.SearchFFU(ProductType, null, null); if (args.Length >= 4) DownloadFolder = args[3]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0) throw new WPinternalsException("Unable to find compatible FFU"); } break; case "downloadallbyproductcode": LogFile.Log("Command: Download all by Product Code", LogType.FileAndConsole); if (args.Length < 3) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -DownloadAllByProductCode "); ProductCode = args[2]; LogFile.Log("Product code: " + ProductCode, LogType.FileAndConsole); URL = LumiaDownloadModel.SearchFFU(null, ProductCode, null, out ProductType); if (args.Length >= 4) DownloadFolder = args[3]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); URLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType); if (URLs != null) { for (int i = 0; i < URLs.Length; i++) { LogFile.Log("URL: " + URLs[i], LogType.FileAndConsole); URI = new Uri(URLs[i]); EmergencyFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + EmergencyFileName, LogType.FileAndConsole); EmergencyFilePath = Path.Combine(DownloadFolder, EmergencyFileName); if (i == 0) ProgrammerPath = EmergencyFilePath; else PayloadPath = EmergencyFilePath; LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URLs[i], EmergencyFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); } App.Config.AddEmergencyToRepository(ProductType, ProgrammerPath, PayloadPath); } if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0) { ProductType = "RM-1085"; URL = LumiaDownloadModel.SearchFFU(ProductType, null, null); if (args.Length >= 4) DownloadFolder = args[3]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0) throw new WPinternalsException("Unable to find compatible FFU"); } break; case "downloadallbyoperatorcode": LogFile.Log("Command: Download FFU by Operator Code", LogType.FileAndConsole); if (args.Length < 4) throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -DownloadFFUbyOperatorCode "); ProductType = args[2]; LogFile.Log("Product type: " + ProductType, LogType.FileAndConsole); OperatorCode = args[3]; LogFile.Log("Operator code: " + OperatorCode, LogType.FileAndConsole); if (args.Length >= 5) DownloadFolder = args[4]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); URL = LumiaDownloadModel.SearchFFU(ProductType, null, OperatorCode); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); URLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType); if (URLs != null) { for (int i = 0; i < URLs.Length; i++) { LogFile.Log("URL: " + URLs[i], LogType.FileAndConsole); URI = new Uri(URLs[i]); EmergencyFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + EmergencyFileName, LogType.FileAndConsole); EmergencyFilePath = Path.Combine(DownloadFolder, EmergencyFileName); if (i == 0) ProgrammerPath = EmergencyFilePath; else PayloadPath = EmergencyFilePath; LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URLs[i], EmergencyFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); } App.Config.AddEmergencyToRepository(ProductType, ProgrammerPath, PayloadPath); } if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0) { ProductType = "RM-1085"; URL = LumiaDownloadModel.SearchFFU(ProductType, null, null); if (args.Length >= 5) DownloadFolder = args[4]; else DownloadFolder = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%\\WPInternals\\Repository\\" + ProductType.ToUpper()); if (!Directory.Exists(DownloadFolder)) Directory.CreateDirectory(DownloadFolder); LogFile.Log("Download folder: " + DownloadFolder, LogType.FileAndConsole); LogFile.Log("URL: " + URL, LogType.FileAndConsole); URI = new Uri(URL); FFUFileName = System.IO.Path.GetFileName(URI.LocalPath); LogFile.Log("File: " + FFUFileName, LogType.FileAndConsole); FFUFilePath = Path.Combine(DownloadFolder, FFUFileName); LogFile.Log("Downloading...", LogType.FileAndConsole); using (System.Net.WebClient myWebClient = new System.Net.WebClient()) { await myWebClient.DownloadFileTaskAsync(URL, FFUFilePath); } LogFile.Log("Download finished", LogType.FileAndConsole); App.Config.AddFfuToRepository(FFUFilePath); if (App.Config.FFURepository.Where(e => App.PatchEngine.PatchDefinitions.Where(p => p.Name == "SecureBootHack-V2-EFIESP").First().TargetVersions.Any(v => v.Description == e.OSVersion)).Count() == 0) throw new WPinternalsException("Unable to find compatible FFU"); } break; default: LogFile.Log("", LogType.ConsoleOnly); LogFile.Log("WPinternals commandline usage:", LogType.ConsoleOnly); LogFile.Log("", LogType.ConsoleOnly); LogFile.Log("WPinternals -ShowPhoneInfo", LogType.ConsoleOnly); LogFile.Log("WPinternals -AddFFU ", LogType.ConsoleOnly); LogFile.Log("WPinternals -AddEmergency ", LogType.ConsoleOnly); LogFile.Log("WPinternals -RemoveFFU ", LogType.ConsoleOnly); LogFile.Log("WPinternals -RemoveEmergency ", LogType.ConsoleOnly); LogFile.Log("WPinternals -ListRepository", LogType.ConsoleOnly); LogFile.Log("WPinternals -FindFlashingProfile ", LogType.ConsoleOnly); LogFile.Log("WPinternals -UnlockBootloader", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -FixBootAfterUnlockingBootloader", LogType.ConsoleOnly); LogFile.Log("WPinternals -EnableRootAccess", LogType.ConsoleOnly); LogFile.Log("WPinternals -UnlockBootLoaderOnImage ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -EnableRootAccessOnImage ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -UnlockBootLoaderOnMountedImage ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -EnableRootAccessOnMountedImage ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -EnableTestSigning", LogType.ConsoleOnly); LogFile.Log("WPinternals -RelockPhone", LogType.ConsoleOnly); LogFile.Log("WPinternals -SwitchToMassStorageMode", LogType.ConsoleOnly); LogFile.Log("WPinternals -FlashFFU ", LogType.ConsoleOnly); LogFile.Log("WPinternals -FlashCustomROM ", LogType.ConsoleOnly); LogFile.Log("WPinternals -FlashPartition ", LogType.ConsoleOnly); LogFile.Log("WPinternals -FlashRaw ", LogType.ConsoleOnly); LogFile.Log("WPinternals -ClearNV", LogType.ConsoleOnly); LogFile.Log("WPinternals -ReadGPT", LogType.ConsoleOnly); LogFile.Log("WPinternals -BackupGPT ", LogType.ConsoleOnly); LogFile.Log("WPinternals -RestoreGPT ", LogType.ConsoleOnly); LogFile.Log("WPinternals -MergeGPT ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -MergeGPT ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -ShowFFU ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DumpFFU ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadFFU ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadFFUbyProductType ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadFFUbyProductCode ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadFFUbyOperatorCode ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadEmergency ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadEmergencyByProductType ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadAll ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadAllByProductType ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadAllByProductCode ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DownloadAllByOperatorCode ", LogType.ConsoleOnly); LogFile.Log(" ", LogType.ConsoleOnly); LogFile.Log("WPinternals -DumpUEFI ", LogType.ConsoleOnly); LogFile.Log("WPinternals -TestProgrammer ", LogType.ConsoleOnly); break; } } catch (Exception Ex) { LogFile.LogException(Ex); } if (Environment.GetCommandLineArgs().Count() > 1) CloseConsole(); } // http://stackoverflow.com/questions/472282/show-console-in-windows-application // https://stackoverflow.com/questions/807998/how-do-i-create-a-c-sharp-app-that-decides-itself-whether-to-show-as-a-console-o // http://www.csharp411.com/console-output-from-winforms-application/#comment-76 // https://stackoverflow.com/questions/1305257/using-attachconsole-user-must-hit-enter-to-get-regular-command-line internal static void OpenConsole() { if (IsConsoleVisible) return; if (AttachConsole(-1)) { Console.Write("\r" + new string(' ', Console.WindowWidth) + "\r"); // Prompt was already printed. Clear that line. /* Other possibility to clear line: System.Console.CursorLeft = 0; char[] bl = System.Linq.Enumerable.ToArray(System.Linq.Enumerable.Repeat(' ', System.Console.WindowWidth - 1)); System.Console.Write(bl); System.Console.CursorLeft = 0; */ hConsoleWnd = GetForegroundWindow(); } else { AllocConsole(); IsNewConsoleCreated = true; hConsoleWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle; // Support VS 2017 debugger without VS host process: try { // Console.OpenStandardOutput eventually calls into GetStdHandle. As per MSDN documentation of GetStdHandle: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231(v=vs.85).aspx will return the redirected handle and not the allocated console: // "The standard handles of a process may be redirected by a call to SetStdHandle, in which case GetStdHandle returns the redirected handle. If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile function to get a handle to a console's input buffer. Similarly, you can specify the CONOUT$ value to get a handle to a console's active screen buffer." // Get the handle to CONOUT$. IntPtr stdHandle = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); Microsoft.Win32.SafeHandles.SafeFileHandle safeFileHandle = new Microsoft.Win32.SafeHandles.SafeFileHandle(stdHandle, true); FileStream fileStream = new FileStream(safeFileHandle, FileAccess.Write); Encoding encoding = System.Text.Encoding.GetEncoding(MY_CODE_PAGE); StreamWriter standardOutput = new StreamWriter(fileStream, encoding); standardOutput.AutoFlush = true; Console.SetOut(standardOutput); } catch (Exception) { } } IsConsoleVisible = true; Console.CancelKeyPress += Console_CancelKeyPress; LogFile.LogApplicationVersion(); } private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e) { LogFile.Log("Operation canceled!", LogType.FileOnly); LogFile.EndAction(); #if PREVIEW Uploader.WaitForUploads(); #endif } internal static void CloseConsole(bool Exit = true) { if (IsConsoleVisible) { if (IsNewConsoleCreated) { Console.WriteLine("Press any key to close..."); Console.ReadKey(); } PostMessage(hConsoleWnd, WM_KEYDOWN, VK_RETURN, 0); IsConsoleVisible = false; if (Exit) { #if PREVIEW Uploader.WaitForUploads(); #endif Environment.Exit(0); } } } } }