From c269cfe839c54f64fdee56ddefa297838af604e3 Mon Sep 17 00:00:00 2001 From: Gustave Monce Date: Sat, 31 Aug 2024 19:45:24 +0200 Subject: [PATCH] Enable downloading ENOSW via Download Page --- WPinternals/Models/LumiaDownloadModel.cs | 79 +++++---- WPinternals/ViewModels/DownloadsViewModel.cs | 160 +++++++++++++++++- WPinternals/ViewModels/SwitchModeViewModel.cs | 92 +++++----- WPinternals/Views/LumiaDownloadView.xaml | 5 +- WPinternals/WPinternalsConfig.cs | 57 +++++++ 5 files changed, 299 insertions(+), 94 deletions(-) diff --git a/WPinternals/Models/LumiaDownloadModel.cs b/WPinternals/Models/LumiaDownloadModel.cs index a016b0b..8764076 100644 --- a/WPinternals/Models/LumiaDownloadModel.cs +++ b/WPinternals/Models/LumiaDownloadModel.cs @@ -158,7 +158,7 @@ namespace WPinternals return FfuUrl; } - internal static string SearchENOSW(string ProductType, string PhoneFirmwareRevision) + internal static (string SecureWIMUrl, string DPLUrl) SearchENOSW(string ProductType, string PhoneFirmwareRevision) { if (ProductType?.Length == 0) { @@ -182,6 +182,7 @@ namespace WPinternals packageClass = "Public", manufacturerHardwareModel = ProductType }; + DiscoveryParameters DiscoveryParams = new() { query = DiscoveryQueryParams @@ -212,16 +213,15 @@ namespace WPinternals } SoftwarePackage Package = null; - using (MemoryStream JsonResultStream = new(Encoding.UTF8.GetBytes(JsonResultString))) + using MemoryStream JsonResultStream = new(Encoding.UTF8.GetBytes(JsonResultString)); + DataContractJsonSerializer SoftwarePackagesJsonSerializer = new(typeof(SoftwarePackages)); + SoftwarePackages SoftwarePackages = (SoftwarePackages)SoftwarePackagesJsonSerializer.ReadObject(JsonResultStream); + + if (SoftwarePackages != null) { - DataContractJsonSerializer SoftwarePackagesJsonSerializer = new(typeof(SoftwarePackages)); - SoftwarePackages SoftwarePackages = (SoftwarePackages)SoftwarePackagesJsonSerializer.ReadObject(JsonResultStream); - if (SoftwarePackages != null) + foreach (SoftwarePackage pkg in SoftwarePackages.softwarePackages) { - foreach (SoftwarePackage pkg in SoftwarePackages.softwarePackages) - { - Package = SoftwarePackages.softwarePackages.FirstOrDefault(); - } + Package = SoftwarePackages.softwarePackages.FirstOrDefault(); } } @@ -230,41 +230,40 @@ namespace WPinternals throw new WPinternalsException("ENOSW package not found", "No ENOSW package has been found in the remote software repository for the requested model."); } - SoftwareFile FileInfo = Package.files.First(f => f.fileName.EndsWith(".secwim", StringComparison.OrdinalIgnoreCase)); + SoftwareFile SecureWimSoftwareFile = Package.files.First(f => f.fileName.EndsWith(".secwim", StringComparison.OrdinalIgnoreCase)); + SoftwareFile DPLSoftwareFile = Package.files.First(f => f.fileName.EndsWith(".dpl", StringComparison.OrdinalIgnoreCase)); - SoftwareFile DPLF = Package.files.First(f => f.fileName.EndsWith(".dpl", StringComparison.OrdinalIgnoreCase)); - Uri DPLUri = new("https://api.swrepository.com/rest-api/discovery/fileurl/1/" + Package.id + "/" + DPLF.fileName); - Task GetDPLTask = HttpClient.GetStringAsync(DPLUri); + Uri DPLFileUrlUri = new($"https://api.swrepository.com/rest-api/discovery/fileurl/1/{Package.id}/{DPLSoftwareFile.fileName}"); + + Task GetDPLTask = HttpClient.GetStringAsync(DPLFileUrlUri); GetDPLTask.Wait(); - string DPLString = GetDPLTask.Result; - string DPLUrl = ""; - FileUrlResult FileUrlDPL = null; - using (MemoryStream JsonStream3 = new(Encoding.UTF8.GetBytes(DPLString))) + string DPLFileUrlResultContent = GetDPLTask.Result; + FileUrlResult DPLFileUrlResult = null; + using MemoryStream DPLFileUrlResultStream = new(Encoding.UTF8.GetBytes(DPLFileUrlResultContent)); + DataContractJsonSerializer DPLFileUrlResultSerializer = new(typeof(FileUrlResult)); + DPLFileUrlResult = (FileUrlResult)DPLFileUrlResultSerializer.ReadObject(DPLFileUrlResultStream); + + string DPLFileUrl = ""; + + if (DPLFileUrlResult != null) { - DataContractJsonSerializer Serializer3 = new(typeof(FileUrlResult)); - FileUrlDPL = (FileUrlResult)Serializer3.ReadObject(JsonStream3); - if (FileUrlDPL != null) - { - DPLUrl = FileUrlDPL.url.Replace("sr.azureedge.net", "softwarerepo.blob.core.windows.net"); - } + DPLFileUrl = DPLFileUrlResult.url.Replace("sr.azureedge.net", "softwarerepo.blob.core.windows.net"); } - if (DPLUrl?.Length == 0) + if (DPLFileUrl?.Length == 0) { throw new WPinternalsException("DPL not found", "No DPL has been found in the remote software repository for the requested model."); } - Task GetDPLStrTask = HttpClient.GetStringAsync(DPLUrl); + Task GetDPLStrTask = HttpClient.GetStringAsync(DPLFileUrl); GetDPLStrTask.Wait(); string DPLStrString = GetDPLStrTask.Result; DPL.Package dpl; XmlSerializer serializer = new(typeof(DPL.Package)); - using (StringReader reader = new(DPLStrString.Replace("ft:", "").Replace("dpl:", "").Replace("typedes:", ""))) - { - dpl = (DPL.Package)serializer.Deserialize(reader); - } + using StringReader reader = new(DPLStrString.Replace("ft:", "").Replace("dpl:", "").Replace("typedes:", "")); + dpl = (DPL.Package)serializer.Deserialize(reader); foreach (DPL.File file in dpl.Content.Files.File) { @@ -274,30 +273,30 @@ namespace WPinternals if (IsFirmwareBetween(PhoneFirmwareRevision, range.From, range.To)) { - FileInfo = Package.files.First(f => f.fileName.EndsWith(name, StringComparison.OrdinalIgnoreCase)); + SecureWimSoftwareFile = Package.files.First(f => f.fileName.EndsWith(name, StringComparison.OrdinalIgnoreCase)); } } - Uri FileInfoUri = new("https://api.swrepository.com/rest-api/discovery/fileurl/1/" + Package.id + "/" + FileInfo.fileName); + Uri FileInfoUri = new("https://api.swrepository.com/rest-api/discovery/fileurl/1/" + Package.id + "/" + SecureWimSoftwareFile.fileName); Task GetFileInfoTask = HttpClient.GetStringAsync(FileInfoUri); GetFileInfoTask.Wait(); string FileInfoString = GetFileInfoTask.Result; - string ENOSWUrl = ""; + string ENOSWFileUrl = ""; + FileUrlResult FileUrl = null; - using (MemoryStream JsonStream3 = new(Encoding.UTF8.GetBytes(FileInfoString))) + + using MemoryStream JsonStream4 = new(Encoding.UTF8.GetBytes(FileInfoString)); + DataContractJsonSerializer Serializer4 = new(typeof(FileUrlResult)); + FileUrl = (FileUrlResult)Serializer4.ReadObject(JsonStream4); + if (FileUrl != null) { - DataContractJsonSerializer Serializer3 = new(typeof(FileUrlResult)); - FileUrl = (FileUrlResult)Serializer3.ReadObject(JsonStream3); - if (FileUrl != null) - { - ENOSWUrl = FileUrl.url.Replace("sr.azureedge.net", "softwarerepo.blob.core.windows.net"); - } + ENOSWFileUrl = FileUrl.url.Replace("sr.azureedge.net", "softwarerepo.blob.core.windows.net"); } HttpClient.Dispose(); - return ENOSWUrl; + return (ENOSWFileUrl, DPLFileUrl); } private static bool IsFirmwareBetween(string PhoneFirmwareRevision, string Limit1, string Limit2) diff --git a/WPinternals/ViewModels/DownloadsViewModel.cs b/WPinternals/ViewModels/DownloadsViewModel.cs index 07f9a76..f97e4d8 100644 --- a/WPinternals/ViewModels/DownloadsViewModel.cs +++ b/WPinternals/ViewModels/DownloadsViewModel.cs @@ -73,15 +73,15 @@ namespace WPinternals { App.Config.AddFfuToRepository(FFUPath); App.Config.WriteConfig(); - LastStatusText = "File \"" + FFUFile + "\" was added to the repository."; + LastStatusText = $"File \"{FFUFile}\" was added to the repository."; } catch (WPinternalsException Ex) { - LastStatusText = "Error: " + Ex.Message + ". File \"" + FFUFile + "\" was not added."; + LastStatusText = $"Error: {Ex.Message}. File \"{FFUFile}\" was not added."; } catch { - LastStatusText = "Error: File \"" + FFUFile + "\" was not added."; + LastStatusText = $"Error: File \"{FFUFile}\" was not added."; } } else @@ -174,6 +174,8 @@ namespace WPinternals { string FFUURL = null; string[] EmergencyURLs = null; + string SecureWIMURL = null; + try { string TempProductType = ProductType.ToUpper(); @@ -183,7 +185,17 @@ namespace WPinternals } ProductType = TempProductType; - FFUURL = LumiaDownloadModel.SearchFFU(ProductType, ProductCode, OperatorCode, out TempProductType); + + try + { + FFUURL = LumiaDownloadModel.SearchFFU(ProductType, ProductCode, OperatorCode, out TempProductType); + } + catch (WPinternalsException ex) + { + LogFile.LogException(ex, LogType.FileOnly); + FFUURL = LumiaDownloadModel.SearchFFU(ProductType, null, OperatorCode, out TempProductType); + } + if (TempProductType != null) { ProductType = TempProductType; @@ -193,6 +205,11 @@ namespace WPinternals { EmergencyURLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType); } + + if (ProductType != null && FirmwareVersion != null) + { + (SecureWIMURL, string _) = LumiaDownloadModel.SearchENOSW(ProductType, FirmwareVersion); + } } catch (Exception ex) { @@ -208,7 +225,12 @@ namespace WPinternals if (EmergencyURLs != null) { - SearchResultList.Add(new SearchResult(ProductType + " emergency-files", EmergencyURLs, ProductType, EmergencyDownloaded, ProductType)); + SearchResultList.Add(new SearchResult($"{ProductType} emergency-files", EmergencyURLs, ProductType, EmergencyDownloaded, ProductType)); + } + + if (SecureWIMURL != null) + { + SearchResultList.Add(new SearchResult($"{ProductType} ENOSW-files", SecureWIMURL, ProductType, ENOSWDownloaded, FirmwareVersion)); } }, null); @@ -239,6 +261,7 @@ namespace WPinternals { string FFUURL = null; string[] EmergencyURLs = null; + string SecureWIMURL = null; try { string TempProductType = ProductType.ToUpper(); @@ -258,6 +281,11 @@ namespace WPinternals { EmergencyURLs = LumiaDownloadModel.SearchEmergencyFiles(ProductType); } + + if (ProductType != null && FirmwareVersion != null) + { + (SecureWIMURL, string _) = LumiaDownloadModel.SearchENOSW(ProductType, FirmwareVersion); + } } catch (Exception ex) { @@ -275,6 +303,11 @@ namespace WPinternals { Download(EmergencyURLs, ProductType, EmergencyDownloaded, ProductType); } + + if (SecureWIMURL != null) + { + Download(SecureWIMURL, ProductType, ENOSWDownloaded, FirmwareVersion); + } }, null); }).Start(); } @@ -328,6 +361,12 @@ namespace WPinternals App.Config.AddEmergencyToRepository(Type, ProgrammerPath, PayloadPath); } } + + private void ENOSWDownloaded(string[] Files, object State) + { + App.Config.AddSecWimToRepository(Files[0], (string)State); + } + public ObservableCollection DownloadList { get; } = new(); public ObservableCollection SearchResultList { get; } = new(); @@ -442,6 +481,24 @@ namespace WPinternals } } + private string _FirmwareVersion = null; + public string FirmwareVersion + { + get + { + return _FirmwareVersion; + } + set + { + if (_FirmwareVersion != value) + { + _FirmwareVersion = value; + + OnPropertyChanged(nameof(FirmwareVersion)); + } + } + } + private string _OperatorCode = null; public string OperatorCode { @@ -460,8 +517,13 @@ namespace WPinternals } } - internal override void EvaluateViewState() + internal override async void EvaluateViewState() { + if (IsSwitchingInterface) + { + return; + } + if (!IsActive) { return; @@ -469,11 +531,81 @@ namespace WPinternals if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash) { - LumiaFlashAppModel LumiaFlashModel = (LumiaFlashAppModel)Notifier.CurrentModel; - PhoneInfo Info = LumiaFlashModel.ReadPhoneInfo(); + PhoneInfo FlashAppInfo = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true); + FirmwareVersion = FlashAppInfo.Firmware; + + IsSwitchingInterface = true; + + (Notifier.CurrentModel as LumiaFlashAppModel).SwitchToPhoneInfoAppContext(); + + if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo) + { + await Notifier.WaitForArrival(); + } + + if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo) + { + throw new WPinternalsException("Unexpected Mode"); + } + + LumiaPhoneInfoAppModel LumiaPhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel; + PhoneInfo Info = LumiaPhoneInfoModel.ReadPhoneInfo(); ProductType = Info.Type; OperatorCode = ""; ProductCode = Info.ProductCode; + + ((LumiaPhoneInfoAppModel)Notifier.CurrentModel).SwitchToFlashAppContext(); + + if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash) + { + await Notifier.WaitForArrival(); + } + + if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash) + { + throw new WPinternalsException("Unexpected Mode"); + } + + IsSwitchingInterface = false; + } + else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_PhoneInfo) + { + LumiaPhoneInfoAppModel LumiaPhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel; + PhoneInfo Info = LumiaPhoneInfoModel.ReadPhoneInfo(); + ProductType = Info.Type; + OperatorCode = ""; + ProductCode = Info.ProductCode; + + IsSwitchingInterface = true; + + ((LumiaPhoneInfoAppModel)Notifier.CurrentModel).SwitchToFlashAppContext(); + + if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash) + { + await Notifier.WaitForArrival(); + } + + if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash) + { + throw new WPinternalsException("Unexpected Mode"); + } + + PhoneInfo FlashAppInfo = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo(ExtendedInfo: true); + FirmwareVersion = FlashAppInfo.Firmware; + + (Notifier.CurrentModel as LumiaFlashAppModel).SwitchToPhoneInfoAppContext(); + + if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo) + { + await Notifier.WaitForArrival(); + } + + if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo) + { + throw new WPinternalsException("Unexpected Mode"); + } + + IsSwitchingInterface = false; } else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Normal) { @@ -724,6 +856,18 @@ namespace WPinternals GetSize(); } + internal SearchResult(string Name, string URL, string Category, Action Callback, object State) + { + UIContext = SynchronizationContext.Current; + URLs = new string[1]; + URLs[0] = URL; + this.Name = Name; + this.Callback = Callback; + this.State = State; + this.Category = Category; + GetSize(); + } + private void GetSize() { new Thread(() => diff --git a/WPinternals/ViewModels/SwitchModeViewModel.cs b/WPinternals/ViewModels/SwitchModeViewModel.cs index 7f80c0c..152575b 100644 --- a/WPinternals/ViewModels/SwitchModeViewModel.cs +++ b/WPinternals/ViewModels/SwitchModeViewModel.cs @@ -751,18 +751,39 @@ namespace WPinternals { ModeSwitchProgressWrapper(ProgressText, null); - string TempFolder = Environment.GetEnvironmentVariable("TEMP") + @"\WPInternals"; + string TempFolder = $@"{Environment.GetEnvironmentVariable("TEMP")}\WPInternals"; if (PhoneInfoAppInfo.Type == "RM-1152") { PhoneInfoAppInfo.Type = "RM-1151"; } - string ENOSWPackage = LumiaDownloadModel.SearchENOSW(PhoneInfoAppInfo.Type, Info.Firmware); + (string ENOSWFileUrl, string DPLFileUrl) = LumiaDownloadModel.SearchENOSW(PhoneInfoAppInfo.Type, Info.Firmware); SetWorkingStatus($"Downloading {Info.Type} Test Mode package...", MaxProgressValue: 100); - DownloadEntry downloadEntry = new(ENOSWPackage, TempFolder, null, null, null); + DownloadEntry downloadEntry = new(ENOSWFileUrl, TempFolder, null, (string[] Files, object State) => + { + App.Config.AddSecWimToRepository(ENOSWFileUrl, Info.Firmware); + + ModeSwitchProgressWrapper("Initializing Flash...", null); + + string MMOSPath = $"{TempFolder}\\{DownloadsViewModel.GetFileNameFromURL(ENOSWFileUrl)}"; + + PhoneNotifier.NewDeviceArrived += NewDeviceArrived; + FileInfo info = new(MMOSPath); + uint length = uint.Parse(info.Length.ToString()); + const int maximumbuffersize = 0x00240000; + uint totalcounts = (uint)Math.Truncate((decimal)length / maximumbuffersize); + + SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100); + + ProgressUpdater progressUpdater = new(totalcounts + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i)); + FlashModel.FlashMMOS(MMOSPath, progressUpdater); + + SetWorkingStatus("And now booting phone to MMOS...", "If the phone stays on the lightning cog screen for a while, you may need to unplug and replug the phone to continue the boot process."); + + }, null); downloadEntry.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => { @@ -771,26 +792,6 @@ namespace WPinternals int progress = (sender as DownloadEntry)?.Progress ?? 0; ulong.TryParse(progress.ToString(), out ulong progressret); UpdateWorkingStatus(null, CurrentProgressValue: progressret); - - if (progress == 100) - { - ModeSwitchProgressWrapper("Initializing Flash...", null); - - string MMOSPath = TempFolder + "\\" + (sender as DownloadEntry)?.Name; - - PhoneNotifier.NewDeviceArrived += NewDeviceArrived; - FileInfo info = new(MMOSPath); - uint length = uint.Parse(info.Length.ToString()); - const int maximumbuffersize = 0x00240000; - uint totalcounts = (uint)Math.Truncate((decimal)length / maximumbuffersize); - - SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100); - - ProgressUpdater progressUpdater = new(totalcounts + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i)); - FlashModel.FlashMMOS(MMOSPath, progressUpdater); - - SetWorkingStatus("And now booting phone to MMOS...", "If the phone stays on the lightning cog screen for a while, you may need to unplug and replug the phone to continue the boot process."); - } } }; } @@ -877,11 +878,32 @@ namespace WPinternals PhoneInfoAppInfo.Type = "RM-1151"; } - string ENOSWPackage = LumiaDownloadModel.SearchENOSW(PhoneInfoAppInfo.Type, Info.Firmware); + (string ENOSWFileUrl, string DPLFileUrl) = LumiaDownloadModel.SearchENOSW(PhoneInfoAppInfo.Type, Info.Firmware); SetWorkingStatus($"Downloading {PhoneInfoAppInfo.Type} Test Mode package...", MaxProgressValue: 100); - DownloadEntry downloadEntry = new(ENOSWPackage, TempFolder, null, null, null); + DownloadEntry downloadEntry = new(ENOSWFileUrl, TempFolder, null, (string[] Files, object State) => + { + App.Config.AddSecWimToRepository(ENOSWFileUrl, Info.Firmware); + + ModeSwitchProgressWrapper("Initializing Flash...", null); + + string MMOSPath = $"{TempFolder}\\{DownloadsViewModel.GetFileNameFromURL(ENOSWFileUrl)}"; + + PhoneNotifier.NewDeviceArrived += NewDeviceArrived; + FileInfo info = new(MMOSPath); + uint length = uint.Parse(info.Length.ToString()); + const int maximumbuffersize = 0x00240000; + uint totalcounts = (uint)Math.Truncate((decimal)length / maximumbuffersize); + + SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100); + + ProgressUpdater progressUpdater = new(totalcounts + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i)); + FlashModel.FlashMMOS(MMOSPath, progressUpdater); + + SetWorkingStatus("And now booting phone to MMOS...", "If the phone stays on the lightning cog screen for a while, you may need to unplug and replug the phone to continue the boot process."); + + }, null); downloadEntry.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => { @@ -890,26 +912,6 @@ namespace WPinternals int progress = (sender as DownloadEntry)?.Progress ?? 0; ulong.TryParse(progress.ToString(), out ulong progressret); UpdateWorkingStatus(null, CurrentProgressValue: progressret); - - if (progress == 100) - { - ModeSwitchProgressWrapper("Initializing Flash...", null); - - string MMOSPath = TempFolder + "\\" + (sender as DownloadEntry)?.Name; - - PhoneNotifier.NewDeviceArrived += NewDeviceArrived; - FileInfo info = new(MMOSPath); - uint length = uint.Parse(info.Length.ToString()); - const int maximumbuffersize = 0x00240000; - uint totalcounts = (uint)Math.Truncate((decimal)length / maximumbuffersize); - - SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100); - - ProgressUpdater progressUpdater = new(totalcounts + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i)); - FlashModel.FlashMMOS(MMOSPath, progressUpdater); - - SetWorkingStatus("And now booting phone to MMOS...", "If the phone stays on the lightning cog screen for a while, you may need to unplug and replug the phone to continue the boot process."); - } } }; } diff --git a/WPinternals/Views/LumiaDownloadView.xaml b/WPinternals/Views/LumiaDownloadView.xaml index eb7b5e9..82a7353 100644 --- a/WPinternals/Views/LumiaDownloadView.xaml +++ b/WPinternals/Views/LumiaDownloadView.xaml @@ -159,13 +159,16 @@ DEALINGS IN THE SOFTWARE. + Producttype Productcode Operatorcode + Firmwareversion - + +