internal void FlashMMOSTask(string MMOSPath)
        {
            NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;

            if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
            {
                Phone.SwitchToFlashAppContext();
            }

            new Thread(() =>
            {
                bool Result = true;

                ActivateSubContext(new BusyViewModel("Initializing flash..."));

                string ErrorSubMessage = null;

                try
                {
                    FileInfo info         = new FileInfo(MMOSPath);
                    uint length           = uint.Parse(info.Length.ToString());
                    int maximumbuffersize = 0x00240000;
                    uint totalcounts      = (uint)Math.Truncate((decimal)length / maximumbuffersize);
                    BusyViewModel Busy    = new BusyViewModel("Flashing Test Mode package...", MaxProgressValue: totalcounts, UIContext: UIContext);
                    ActivateSubContext(Busy);

                    Phone.FlashMMOS(MMOSPath, Busy.ProgressUpdater);

                    ActivateSubContext(new BusyViewModel("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."));

                    PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
                }
                catch (Exception Ex)
                {
                    LogFile.LogException(Ex);
                    if (Ex is WPinternalsException)
                    {
                        ErrorSubMessage = ((WPinternalsException)Ex).SubMessage;
                    }
                    Result = false;
                }

                if (!Result)
                {
                    ExitFailure("Flash failed!", ErrorSubMessage);
                    return;
                }
            }).Start();
        }
Exemple #2
0
 internal void UpdateWorkingStatus(string Message, string SubMessage, ulong?CurrentProgressValue, WPinternalsStatus Status = WPinternalsStatus.Undefined)
 {
     if (SubContextViewModel is BusyViewModel)
     {
         BusyViewModel Busy = (BusyViewModel)SubContextViewModel;
         if (Message != null)
         {
             Busy.Message    = Message;
             Busy.SubMessage = SubMessage;
         }
         if ((CurrentProgressValue != null) && (Busy.ProgressUpdater != null))
         {
             try
             {
                 Busy.ProgressUpdater.SetProgress((ulong)CurrentProgressValue);
             }
             catch (Exception Ex)
             {
                 LogFile.LogException(Ex);
             }
         }
     }
 }
        internal void FlashPartitionsTask(string EFIESPPath, string MainOSPath, string DataPath)
        {
            new Thread(() =>
            {
                bool Result = true;

                ActivateSubContext(new BusyViewModel("Initializing flash..."));

                NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;

                GPT GPT = Phone.ReadGPT();

                ulong TotalSizeSectors     = 0;
                int PartitionCount         = 0;
                ulong MainOSOldSectorCount = 0;
                ulong MainOSNewSectorCount = 0;
                ulong DataOldSectorCount   = 0;
                ulong DataNewSectorCount   = 0;
                ulong FirstMainOSSector    = 0;

                try
                {
                    if (EFIESPPath != null)
                    {
                        using (Stream Stream = new DecompressedStream(File.Open(EFIESPPath, FileMode.Open)))
                        {
                            ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
                            TotalSizeSectors           += StreamLengthInSectors;
                            PartitionCount++;
                            Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, "EFIESP", true) == 0).FirstOrDefault();
                            if (StreamLengthInSectors > Partition.SizeInSectors)
                            {
                                LogFile.Log("Flash failed! Size of partition 'EFIESP' is too big.");
                                ExitFailure("Flash failed!", "Size of partition 'EFIESP' is too big.");
                                return;
                            }
                        }
                    }

                    if (MainOSPath != null)
                    {
                        using (Stream Stream = new DecompressedStream(File.Open(MainOSPath, FileMode.Open)))
                        {
                            ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
                            TotalSizeSectors           += StreamLengthInSectors;
                            PartitionCount++;
                            Partition Partition  = GPT.Partitions.Where(p => string.Compare(p.Name, "MainOS", true) == 0).FirstOrDefault();
                            MainOSOldSectorCount = Partition.SizeInSectors;
                            MainOSNewSectorCount = StreamLengthInSectors;
                            FirstMainOSSector    = Partition.FirstSector;
                        }
                    }

                    if (DataPath != null)
                    {
                        using (Stream Stream = new DecompressedStream(File.Open(DataPath, FileMode.Open)))
                        {
                            ulong StreamLengthInSectors = (ulong)Stream.Length / 0x200;
                            TotalSizeSectors           += StreamLengthInSectors;
                            PartitionCount++;
                            Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, "Data", true) == 0).FirstOrDefault();
                            DataOldSectorCount  = Partition.SizeInSectors;
                            DataNewSectorCount  = StreamLengthInSectors;
                        }
                    }
                }
                catch (Exception Ex)
                {
                    LogFile.LogException(Ex);
                    Result = false;
                }

                if ((MainOSNewSectorCount > 0) && (DataNewSectorCount > 0))
                {
                    if ((MainOSNewSectorCount > MainOSOldSectorCount) || (DataNewSectorCount > DataOldSectorCount))
                    {
                        UInt64 OSSpace = GPT.LastUsableSector - FirstMainOSSector + 1;
                        if ((MainOSNewSectorCount + DataNewSectorCount) <= OSSpace)
                        {
                            // MainOS and Data partitions need to be re-aligned!
                            Partition MainOSPartition  = GPT.Partitions.Where(p => string.Compare(p.Name, "MainOS", true) == 0).Single();
                            Partition DataPartition    = GPT.Partitions.Where(p => string.Compare(p.Name, "Data", true) == 0).Single();
                            MainOSPartition.LastSector = MainOSPartition.FirstSector + MainOSNewSectorCount - 1;
                            DataPartition.FirstSector  = MainOSPartition.LastSector + 1;
                            DataPartition.LastSector   = DataPartition.FirstSector + DataNewSectorCount - 1;
                            Phone.WriteGPT(GPT);
                        }
                        else
                        {
                            LogFile.Log("Flash failed! Size of partitions 'MainOS' and 'Data' together are too big.");
                            ExitFailure("Flash failed!", "Sizes of partitions 'MainOS' and 'Data' together are too big.");
                            return;
                        }
                    }
                }
                else if ((MainOSNewSectorCount > 0) && (MainOSNewSectorCount > MainOSOldSectorCount))
                {
                    LogFile.Log("Flash failed! Size of partition 'MainOS' is too big.");
                    ExitFailure("Flash failed!", "Size of partition 'MainOS' is too big.");
                    return;
                }
                else if ((DataNewSectorCount > 0) && (DataNewSectorCount > DataOldSectorCount))
                {
                    LogFile.Log("Flash failed! Size of partition 'Data' is too big.");
                    ExitFailure("Flash failed!", "Size of partition 'Data' together is too big.");
                    return;
                }

                BusyViewModel Busy      = new BusyViewModel("Flashing...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
                ProgressUpdater Updater = Busy.ProgressUpdater;
                ActivateSubContext(Busy);

                int i = 0;
                if (Result)
                {
                    try
                    {
                        if (EFIESPPath != null)
                        {
                            i++;
                            Busy.Message = "Flashing partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.FlashRawPartition(EFIESPPath, "EFIESP", Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (Result)
                {
                    try
                    {
                        if (MainOSPath != null)
                        {
                            i++;
                            Busy.Message = "Flashing partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.FlashRawPartition(MainOSPath, "MainOS", Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (Result)
                {
                    try
                    {
                        if (DataPath != null)
                        {
                            i++;
                            Busy.Message = "Flashing partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.FlashRawPartition(DataPath, "Data", Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (!Result)
                {
                    ExitFailure("Flash failed!", null);
                    return;
                }

                ExitSuccess("Flash successful! Make sure you disable Windows Update on the phone!", null);
            }).Start();
        }
        internal void FlashFFUTask(string FFUPath)
        {
            new Thread(() =>
            {
                bool Result = true;

                NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;
                PhoneInfo Info        = Phone.ReadPhoneInfo(false);

                #region Remove bootloader changes

                // If necessary remove bootloader changes
                // In case the NV vars were redirected, and a stock FFU is flashed, then the IsFlashing flag will be cleared in the redirected NV vars
                // And after a reboot the original NV vars are active again, but the IsFlashing flag is still set from when the bootloader was unlocked
                // So we will first restore the GPT, so the original vars are active again.
                // Then IsFlashing is true and the phone boots forcibly to FlashApp again.
                // Then we start normal FFU flasing and at the end the IsFlashing flag is cleared in the original vars.

                if (Info.FlashAppProtocolVersionMajor >= 2)
                {
                    byte[] GPTChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(Phone, 0x20000); // TODO: Get proper profile FFU and get ChunkSizeInBytes
                    GPT GPT         = new GPT(GPTChunk);
                    FlashPart Part;
                    List <FlashPart> FlashParts = new List <FlashPart>();

                    Partition NvBackupPartition = GPT.GetPartition("BACKUP_BS_NV");
                    if (NvBackupPartition != null)
                    {
                        // This must be a left over of a half unlocked bootloader
                        Partition NvPartition               = GPT.GetPartition("UEFI_BS_NV");
                        NvBackupPartition.Name              = "UEFI_BS_NV";
                        NvBackupPartition.PartitionGuid     = NvPartition.PartitionGuid;
                        NvBackupPartition.PartitionTypeGuid = NvPartition.PartitionTypeGuid;
                        GPT.Partitions.Remove(NvPartition);

                        GPT.Rebuild();
                        Part             = new FlashPart();
                        Part.StartSector = 0;
                        Part.Stream      = new MemoryStream(GPTChunk);
                        FlashParts.Add(Part);
                    }

                    bool ClearFlashingStatus = true;

                    // We should only clear NV if there was no backup NV to be restored and the current NV contains the SB unlock.
                    if ((NvBackupPartition == null) && !Info.UefiSecureBootEnabled)
                    {
                        // ClearNV
                        Part             = new FlashPart();
                        Partition Target = GPT.GetPartition("UEFI_BS_NV");
                        Part.StartSector = (UInt32)Target.FirstSector;
                        Part.Stream      = new MemoryStream(new byte[0x40000]);
                        FlashParts.Add(Part);

                        ClearFlashingStatus = false;
                    }

                    if (FlashParts.Count > 0)
                    {
                        ActivateSubContext(new BusyViewModel("Restoring bootloader..."));
                        WPinternalsStatus LastStatus = WPinternalsStatus.Undefined;
                        LumiaV2UnlockBootViewModel.LumiaV2CustomFlash(PhoneNotifier, FFUPath, false, false, FlashParts, true, ClearFlashingStatusAtEnd: ClearFlashingStatus,
                                                                      SetWorkingStatus: (m, s, v, a, st) =>
                        {
                            if ((st == WPinternalsStatus.Scanning) || (st == WPinternalsStatus.WaitingForManualReset))
                            {
                                SetWorkingStatus(m, s, v, a, st);
                            }
                            else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
                            {
                                SetWorkingStatus("Restoring bootloader...", null, null, Status: WPinternalsStatus.Flashing);
                            }
                            LastStatus = st;
                        },
                                                                      UpdateWorkingStatus: (m, s, v, st) =>
                        {
                            if ((st == WPinternalsStatus.Scanning) || (st == WPinternalsStatus.WaitingForManualReset))
                            {
                                UpdateWorkingStatus(m, s, v, st);
                            }
                            else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
                            {
                                SetWorkingStatus("Restoring bootloader...", null, null, Status: WPinternalsStatus.Flashing);
                            }
                            LastStatus = st;
                        }
                                                                      ).Wait();

                        if ((PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) && (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash))
                        {
                            PhoneNotifier.WaitForArrival().Wait();
                        }

                        if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
                        {
                            ((NokiaFlashModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
                        }
                    }
                }

                #endregion

                Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;

                ActivateSubContext(new BusyViewModel("Initializing flash..."));

                string ErrorSubMessage = null;

                try
                {
                    FFU FFU            = new FFU(FFUPath);
                    BusyViewModel Busy = new BusyViewModel("Flashing original FFU...", MaxProgressValue: FFU.TotalChunkCount, UIContext: UIContext);
                    ActivateSubContext(Busy);
                    byte Options = 0;
                    if (!Info.IsBootloaderSecure)
                    {
                        Options = (byte)((FlashOptions)Options | FlashOptions.SkipSignatureCheck);
                    }
                    Phone.FlashFFU(FFU, Busy.ProgressUpdater, true, Options);
                }
                catch (Exception Ex)
                {
                    LogFile.LogException(Ex);
                    if (Ex is WPinternalsException)
                    {
                        ErrorSubMessage = ((WPinternalsException)Ex).SubMessage;
                    }
                    Result = false;
                }


                if (!Result)
                {
                    ExitFailure("Flash failed!", ErrorSubMessage);
                    return;
                }

                ExitSuccess("Flash successful!", null);
            }).Start();
        }
        internal void FlashArchiveTask(string ArchivePath)
        {
            new Thread(() =>
            {
                ActivateSubContext(new BusyViewModel("Initializing flash..."));

                NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;

                ulong TotalSizeSectors     = 0;
                int PartitionCount         = 0;
                ulong MainOSOldSectorCount = 0;
                ulong MainOSNewSectorCount = 0;
                ulong DataOldSectorCount   = 0;
                ulong DataNewSectorCount   = 0;
                ulong FirstMainOSSector    = 0;
                bool GPTChanged            = false;

                try
                {
                    GPT GPT = Phone.ReadGPT();

                    using (FileStream FileStream = new FileStream(ArchivePath, FileMode.Open))
                    {
                        using (ZipArchive Archive = new ZipArchive(FileStream, ZipArchiveMode.Read))
                        {
                            foreach (ZipArchiveEntry Entry in Archive.Entries)
                            {
                                // Determine if there is a partition layout present
                                ZipArchiveEntry PartitionEntry = Archive.GetEntry("Partitions.xml");
                                if (PartitionEntry == null)
                                {
                                    GPT.MergePartitions(null, false, Archive);
                                    GPTChanged |= GPT.HasChanged;
                                }
                                else
                                {
                                    using (Stream ZipStream = PartitionEntry.Open())
                                    {
                                        using (StreamReader ZipReader = new StreamReader(ZipStream))
                                        {
                                            string PartitionXml = ZipReader.ReadToEnd();
                                            GPT.MergePartitions(PartitionXml, false, Archive);
                                            GPTChanged |= GPT.HasChanged;
                                        }
                                    }
                                }

                                // First determine if we need a new GPT!
                                if (!Entry.FullName.Contains("/")) // No subfolders
                                {
                                    string PartitionName = System.IO.Path.GetFileNameWithoutExtension(Entry.Name);
                                    int P = PartitionName.IndexOf('.');
                                    if (P >= 0)
                                    {
                                        PartitionName = PartitionName.Substring(0, P); // Example: Data.bin.gz -> Data
                                    }
                                    Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, PartitionName, true) == 0).FirstOrDefault();
                                    if (Partition != null)
                                    {
                                        DecompressedStream DecompressedStream = new DecompressedStream(Entry.Open());
                                        ulong StreamLengthInSectors           = (ulong)Entry.Length / 0x200;
                                        try
                                        {
                                            StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
                                        }
                                        catch { }

                                        TotalSizeSectors += StreamLengthInSectors;
                                        PartitionCount++;

                                        if (string.Compare(PartitionName, "MainOS", true) == 0)
                                        {
                                            MainOSOldSectorCount = Partition.SizeInSectors;
                                            MainOSNewSectorCount = StreamLengthInSectors;
                                            FirstMainOSSector    = Partition.FirstSector;
                                        }
                                        else if (string.Compare(PartitionName, "Data", true) == 0)
                                        {
                                            DataOldSectorCount = Partition.SizeInSectors;
                                            DataNewSectorCount = StreamLengthInSectors;
                                        }
                                        else if (StreamLengthInSectors > Partition.SizeInSectors)
                                        {
                                            LogFile.Log("Flash failed! Size of partition '" + PartitionName + "' is too big.");
                                            ExitFailure("Flash failed!", "Size of partition '" + PartitionName + "' is too big.");
                                            return;
                                        }
                                    }
                                }
                            }

                            if ((MainOSNewSectorCount > 0) && (DataNewSectorCount > 0))
                            {
                                if ((MainOSNewSectorCount > MainOSOldSectorCount) || (DataNewSectorCount > DataOldSectorCount))
                                {
                                    UInt64 OSSpace = GPT.LastUsableSector - FirstMainOSSector + 1;
                                    if ((MainOSNewSectorCount + DataNewSectorCount) <= OSSpace)
                                    {
                                        // MainOS and Data partitions need to be re-aligned!
                                        Partition MainOSPartition  = GPT.Partitions.Where(p => string.Compare(p.Name, "MainOS", true) == 0).Single();
                                        Partition DataPartition    = GPT.Partitions.Where(p => string.Compare(p.Name, "Data", true) == 0).Single();
                                        MainOSPartition.LastSector = MainOSPartition.FirstSector + MainOSNewSectorCount - 1;
                                        DataPartition.FirstSector  = MainOSPartition.LastSector + 1;
                                        DataPartition.LastSector   = DataPartition.FirstSector + DataNewSectorCount - 1;

                                        GPTChanged = true;
                                    }
                                    else
                                    {
                                        LogFile.Log("Flash failed! Size of partitions 'MainOS' and 'Data' together are too big.");
                                        ExitFailure("Flash failed!", "Sizes of partitions 'MainOS' and 'Data' together are too big.");
                                        return;
                                    }
                                }
                            }
                            else if ((MainOSNewSectorCount > 0) && (MainOSNewSectorCount > MainOSOldSectorCount))
                            {
                                LogFile.Log("Flash failed! Size of partition 'MainOS' is too big.");
                                ExitFailure("Flash failed!", "Size of partition 'MainOS' is too big.");
                                return;
                            }
                            else if ((DataNewSectorCount > 0) && (DataNewSectorCount > DataOldSectorCount))
                            {
                                LogFile.Log("Flash failed! Size of partition 'Data' is too big.");
                                ExitFailure("Flash failed!", "Size of partition 'Data' is too big.");
                                return;
                            }

                            if (GPTChanged)
                            {
                                Phone.WriteGPT(GPT);
                            }

                            if (PartitionCount > 0)
                            {
                                BusyViewModel Busy      = new BusyViewModel("Flashing...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
                                ProgressUpdater Updater = Busy.ProgressUpdater;
                                ActivateSubContext(Busy);

                                int i = 0;

                                foreach (ZipArchiveEntry Entry in Archive.Entries)
                                {
                                    // "MainOS.bin.gz" => "MainOS"
                                    string PartitionName = Entry.Name;
                                    int Pos = PartitionName.IndexOf('.');
                                    if (Pos >= 0)
                                    {
                                        PartitionName = PartitionName.Substring(0, Pos);
                                    }

                                    Partition Partition = GPT.Partitions.Where(p => string.Compare(p.Name, PartitionName, true) == 0).FirstOrDefault();
                                    if (Partition != null)
                                    {
                                        Stream DecompressedStream   = new DecompressedStream(Entry.Open());
                                        ulong StreamLengthInSectors = (ulong)Entry.Length / 0x200;
                                        try
                                        {
                                            StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
                                        }
                                        catch { }

                                        if (StreamLengthInSectors <= Partition.SizeInSectors)
                                        {
                                            i++;
                                            Busy.Message = "Flashing partition " + Partition.Name + " (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                                            Phone.FlashRawPartition(DecompressedStream, Partition.Name, Updater);
                                        }
                                        DecompressedStream.Close();
                                    }
                                }
                            }
                            else
                            {
                                LogFile.Log("Flash failed! No valid partitions found in the archive.");
                                ExitFailure("Flash failed!", "No valid partitions found in the archive");
                                return;
                            }
                        }
                    }
                }
                catch (Exception Ex)
                {
                    LogFile.LogException(Ex);
                    if (Ex is WPinternalsException)
                    {
                        ExitFailure("Flash failed!", ((WPinternalsException)Ex).SubMessage);
                    }
                    else
                    {
                        ExitFailure("Flash failed!", null);
                    }
                    return;
                }

                ExitSuccess("Flash successful! Make sure you disable Windows Update on the phone!", null);
            }).Start();
        }
        internal void RestoreTask(string EFIESPPath, string MainOSPath, string DataPath)
        {
            new Thread(() =>
            {
                bool Result = true;

                ActivateSubContext(new BusyViewModel("Initializing restore..."));

                ulong TotalSizeSectors = 0;
                int PartitionCount     = 0;
                try
                {
                    if (EFIESPPath != null)
                    {
                        TotalSizeSectors += (ulong)new FileInfo(EFIESPPath).Length / 0x200;
                        PartitionCount++;
                    }

                    if (MainOSPath != null)
                    {
                        TotalSizeSectors += (ulong)new FileInfo(MainOSPath).Length / 0x200;
                        PartitionCount++;
                    }

                    if (DataPath != null)
                    {
                        TotalSizeSectors += (ulong)new FileInfo(DataPath).Length / 0x200;
                        PartitionCount++;
                    }
                }
                catch (Exception Ex)
                {
                    LogFile.LogException(Ex);
                    Result = false;
                }

                NokiaFlashModel Phone = (NokiaFlashModel)PhoneNotifier.CurrentModel;

                BusyViewModel Busy      = new BusyViewModel("Restoring...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
                ProgressUpdater Updater = Busy.ProgressUpdater;
                ActivateSubContext(Busy);

                int i = 0;
                if (Result)
                {
                    try
                    {
                        if (EFIESPPath != null)
                        {
                            i++;
                            Busy.Message = "Restoring partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.FlashRawPartition(EFIESPPath, "EFIESP", Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (Result)
                {
                    try
                    {
                        if (MainOSPath != null)
                        {
                            i++;
                            Busy.Message = "Restoring partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.FlashRawPartition(EFIESPPath, "MainOS", Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (Result)
                {
                    try
                    {
                        if (DataPath != null)
                        {
                            i++;
                            Busy.Message = "Restoring partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.FlashRawPartition(EFIESPPath, "Data", Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (!Result)
                {
                    ActivateSubContext(new MessageViewModel("Failed to restore!", Exit));
                    return;
                }

                ActivateSubContext(new MessageViewModel("Successfully restored!", Exit));
            }).Start();
        }
Exemple #7
0
        internal void BackupTask(string EFIESPPath, string MainOSPath, string DataPath)
        {
            IsSwitchingInterface = false;
            new Thread(() =>
            {
                bool Result = true;

                ActivateSubContext(new BusyViewModel("Initializing backup..."));

                ulong TotalSizeSectors = 0;
                int PartitionCount     = 0;

                MassStorage Phone = (MassStorage)PhoneNotifier.CurrentModel;

                Phone.OpenVolume(false);
                byte[] GPTBuffer = Phone.ReadSectors(1, 33);
                GPT GPT          = new WPinternals.GPT(GPTBuffer);
                Partition Partition;
                try
                {
                    if (EFIESPPath != null)
                    {
                        Partition         = GPT.Partitions.Where(p => p.Name == "EFIESP").First();
                        TotalSizeSectors += Partition.SizeInSectors;
                        PartitionCount++;
                    }

                    if (MainOSPath != null)
                    {
                        Partition         = GPT.Partitions.Where(p => p.Name == "MainOS").First();
                        TotalSizeSectors += Partition.SizeInSectors;
                        PartitionCount++;
                    }

                    if (DataPath != null)
                    {
                        Partition         = GPT.Partitions.Where(p => p.Name == "Data").First();
                        TotalSizeSectors += Partition.SizeInSectors;
                        PartitionCount++;
                    }
                }
                catch (Exception Ex)
                {
                    LogFile.LogException(Ex);
                    Result = false;
                }

                BusyViewModel Busy      = new BusyViewModel("Create backup...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
                ProgressUpdater Updater = Busy.ProgressUpdater;
                ActivateSubContext(Busy);

                int i = 0;
                if (Result)
                {
                    try
                    {
                        if (EFIESPPath != null)
                        {
                            i++;
                            Busy.Message = "Create backup of partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.BackupPartition("EFIESP", EFIESPPath, Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (Result)
                {
                    try
                    {
                        if (MainOSPath != null)
                        {
                            i++;
                            Busy.Message = "Create backup of partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.BackupPartition("MainOS", MainOSPath, Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (Result)
                {
                    try
                    {
                        if (DataPath != null)
                        {
                            i++;
                            Busy.Message = "Create backup of partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            Phone.BackupPartition("Data", DataPath, Updater);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                Phone.CloseVolume();

                if (!Result)
                {
                    ActivateSubContext(new MessageViewModel("Failed to create backup!", Exit));
                    return;
                }

                ActivateSubContext(new MessageViewModel("Successfully created a backup!", Exit));
            }).Start();
        }
Exemple #8
0
        internal void BackupArchiveTask(string ArchivePath)
        {
            IsSwitchingInterface = false;
            new Thread(() =>
            {
                bool Result = true;

                ActivateSubContext(new BusyViewModel("Initializing backup..."));

                ulong TotalSizeSectors = 0;
                int PartitionCount     = 3;

                MassStorage Phone = (MassStorage)PhoneNotifier.CurrentModel;

                try
                {
                    Phone.OpenVolume(false);
                    byte[] GPTBuffer = Phone.ReadSectors(1, 33);
                    GPT GPT          = new WPinternals.GPT(GPTBuffer);

                    Partition Partition;

                    try
                    {
                        Partition         = GPT.Partitions.Where(p => p.Name == "EFIESP").First();
                        TotalSizeSectors += Partition.SizeInSectors;

                        Partition         = GPT.Partitions.Where(p => p.Name == "MainOS").First();
                        TotalSizeSectors += Partition.SizeInSectors;

                        Partition         = GPT.Partitions.Where(p => p.Name == "Data").First();
                        TotalSizeSectors += Partition.SizeInSectors;
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }

                    BusyViewModel Busy      = new BusyViewModel("Create backup...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
                    ProgressUpdater Updater = Busy.ProgressUpdater;
                    ActivateSubContext(Busy);
                    ZipArchiveEntry Entry;
                    Stream EntryStream = null;

                    using (FileStream FileStream = new FileStream(ArchivePath, FileMode.Create))
                    {
                        using (ZipArchive Archive = new ZipArchive(FileStream, ZipArchiveMode.Create))
                        {
                            int i = 0;

                            if (Result)
                            {
                                try
                                {
                                    Entry       = Archive.CreateEntry("EFIESP.bin", CompressionLevel.Optimal);
                                    EntryStream = Entry.Open();
                                    i++;
                                    Busy.Message = "Create backup of partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                                    Phone.BackupPartition("EFIESP", EntryStream, Updater);
                                }
                                catch (Exception Ex)
                                {
                                    LogFile.LogException(Ex);
                                    Result = false;
                                }
                                finally
                                {
                                    if (EntryStream != null)
                                    {
                                        EntryStream.Close();
                                    }
                                    EntryStream = null;
                                }
                            }

                            if (Result)
                            {
                                try
                                {
                                    Entry       = Archive.CreateEntry("MainOS.bin", CompressionLevel.Optimal);
                                    EntryStream = Entry.Open();
                                    i++;
                                    Busy.Message = "Create backup of partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                                    Phone.BackupPartition("MainOS", EntryStream, Updater);
                                }
                                catch (Exception Ex)
                                {
                                    LogFile.LogException(Ex);
                                    Result = false;
                                }
                                finally
                                {
                                    if (EntryStream != null)
                                    {
                                        EntryStream.Close();
                                    }
                                    EntryStream = null;
                                }
                            }

                            if (Result)
                            {
                                try
                                {
                                    Entry       = Archive.CreateEntry("Data.bin", CompressionLevel.Optimal);
                                    EntryStream = Entry.Open();
                                    i++;
                                    Busy.Message = "Create backup of partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                                    Phone.BackupPartition("Data", EntryStream, Updater);
                                }
                                catch (Exception Ex)
                                {
                                    LogFile.LogException(Ex);
                                    Result = false;
                                }
                                finally
                                {
                                    if (EntryStream != null)
                                    {
                                        EntryStream.Close();
                                    }
                                    EntryStream = null;
                                }
                            }
                        }
                    }
                }
                catch { }
                finally
                {
                    Phone.CloseVolume();
                }

                if (!Result)
                {
                    ActivateSubContext(new MessageViewModel("Failed to create backup!", Exit));
                    return;
                }

                ActivateSubContext(new MessageViewModel("Successfully created a backup!", Exit));
            }).Start();
        }
        internal void DoDumpRom(string FFUPath, string EFIESPPath, bool CompressEFIESP, string MainOSPath, bool CompressMainOS, string DataPath, bool CompressData)
        {
            new Thread(() =>
            {
                bool Result = true;

                ActivateSubContext(new BusyViewModel("Initializing ROM dump..."));

                ulong TotalSizeSectors = 0;
                int PartitionCount     = 0;
                Partition Partition;
                FFU FFU = null;
                try
                {
                    FFU = new FFU(FFUPath);

                    if (EFIESPPath != null)
                    {
                        Partition         = FFU.GPT.Partitions.Where(p => p.Name == "EFIESP").First();
                        TotalSizeSectors += Partition.SizeInSectors;
                        PartitionCount++;
                    }

                    if (MainOSPath != null)
                    {
                        Partition         = FFU.GPT.Partitions.Where(p => p.Name == "MainOS").First();
                        TotalSizeSectors += Partition.SizeInSectors;
                        PartitionCount++;
                    }

                    if (DataPath != null)
                    {
                        Partition         = FFU.GPT.Partitions.Where(p => p.Name == "Data").First();
                        TotalSizeSectors += Partition.SizeInSectors;
                        PartitionCount++;
                    }
                }
                catch (Exception Ex)
                {
                    LogFile.LogException(Ex);
                    Result = false;
                }

                // We are on a worker thread!
                // So we must pass the SynchronizationContext of the UI thread
                BusyViewModel Busy      = new BusyViewModel("Dumping ROM...", MaxProgressValue: TotalSizeSectors, UIContext: UIContext);
                ProgressUpdater Updater = Busy.ProgressUpdater;
                ActivateSubContext(Busy);

                int i = 0;
                if (Result)
                {
                    try
                    {
                        if (EFIESPPath != null)
                        {
                            i++;
                            Busy.Message = "Dumping partition EFIESP (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            FFU.WritePartition("EFIESP", EFIESPPath, Updater, CompressEFIESP);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (Result)
                {
                    try
                    {
                        if (MainOSPath != null)
                        {
                            i++;
                            Busy.Message = "Dumping partition MainOS (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            FFU.WritePartition("MainOS", MainOSPath, Updater, CompressMainOS);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (Result)
                {
                    try
                    {
                        if (DataPath != null)
                        {
                            i++;
                            Busy.Message = "Dumping partition Data (" + i.ToString() + @"/" + PartitionCount.ToString() + ")";
                            FFU.WritePartition("Data", DataPath, Updater, CompressData);
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }
                }

                if (!Result)
                {
                    ActivateSubContext(new MessageViewModel("Failed to dump ROM partitions!", Restart));
                    return;
                }

                ActivateSubContext(new MessageViewModel("Successfully dumped ROM partitions!", Restart));
            }).Start();
        }