コード例 #1
0
ファイル: TestCode.cs プロジェクト: mteletin/WPinternals
        internal static async Task RewriteParts(string PartPath)
        {
            PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel();

            Notifier.Start();
            await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage);

            MassStorage MassStorage = (MassStorage)Notifier.CurrentModel;

            foreach (var part in Directory.EnumerateFiles(PartPath))
            {
                var partname = part.Split('\\').Last().Replace(".img", "");
                try
                {
                    LogFile.Log($"Writing {partname} to the device.", LogType.ConsoleOnly);

                    LogFile.Log("", LogType.ConsoleOnly);

                    MassStorage.RestorePartition(part, partname, (v, t) =>
                    {
                        LogFile.Log("Progress: " + v + "%", LogType.ConsoleOnly);
                    });
                    LogFile.Log("", LogType.ConsoleOnly);
                }
                catch
                {
                    LogFile.Log("", LogType.ConsoleOnly);
                    LogFile.Log($"Failed writing {partname} to the device.", LogType.ConsoleOnly);
                };
            }
        }
コード例 #2
0
ファイル: TestCode.cs プロジェクト: mteletin/WPinternals
        internal static async Task RewriteGPT(string GPTPath)
        {
            PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel();

            Notifier.Start();
            await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage);

            MassStorage MassStorage = (MassStorage)Notifier.CurrentModel;

            LogFile.Log("Writing GPT to the device.", LogType.ConsoleOnly);
            MassStorage.WriteSectors(1, GPTPath);
        }
コード例 #3
0
        private bool HasV11PatchesFromMassStorage()
        {
            bool        Result = false;
            MassStorage Phone  = (MassStorage)PhoneNotifier.CurrentModel;

            Phone.OpenVolume(false);
            byte[]    GPTBuffer = Phone.ReadSectors(1, 33);
            GPT       GPT       = new WPinternals.GPT(GPTBuffer);
            Partition Partition = GPT.GetPartition("BACKUP_BS_NV");

            Result = Partition != null;
            Phone.CloseVolume();
            return(Result);
        }
コード例 #4
0
ファイル: TestCode.cs プロジェクト: mteletin/WPinternals
        internal static async Task RewriteMBRGPT()
        {
            FFU    FFU     = new FFU(@"E:\Device Backups\Alpha\9200_1230.0025.9200.9825\RX100_9825.ffu");
            string GPTPath = @"E:\Device Backups\Alpha\9200_1230.0025.9200.9825\CorrectGPT.bin";

            PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel();

            Notifier.Start();
            await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage);

            MassStorage MassStorage = (MassStorage)Notifier.CurrentModel;

            byte[] MBR = FFU.GetSectors(0, 1);
            LogFile.Log("Writing MBR to the device.", LogType.ConsoleOnly);
            MassStorage.WriteSectors(0, MBR);

            LogFile.Log("Writing GPT to the device.", LogType.ConsoleOnly);
            MassStorage.WriteSectors(1, GPTPath);
        }
コード例 #5
0
        private bool HasNewBootloaderFromMassStorage()
        {
            bool        Result = false;
            MassStorage Phone  = (MassStorage)PhoneNotifier.CurrentModel;

            Phone.OpenVolume(false);
            byte[]    GPTBuffer = Phone.ReadSectors(1, 33);
            GPT       GPT       = new WPinternals.GPT(GPTBuffer);
            Partition Partition = GPT.GetPartition("UEFI");

            byte[] UefiBuffer  = Phone.ReadSectors(Partition.FirstSector, Partition.LastSector - Partition.FirstSector + 1);
            UEFI   UEFI        = new UEFI(UefiBuffer);
            string BootMgrName = UEFI.EFIs.Where(efi => ((efi.Name != null) && ((efi.Name.Contains("BootMgrApp")) || (efi.Name.Contains("FlashApp"))))).First().Name;

            byte[] BootMgr = UEFI.GetFile(BootMgrName);
            // "Header V2"
            Result = (ByteOperations.FindAscii(BootMgr, "Header V2") != null);
            Phone.CloseVolume();
            return(Result);
        }
コード例 #6
0
        private void SwitchFromFlashToMassStorageMode(bool Continuation = false)
        {
            string ProgressText;

            if (Continuation)
            {
                ProgressText = "And now rebooting phone to Mass Storage mode...";
            }
            else
            {
                ProgressText = "Rebooting phone to Mass Storage mode...";
            }

            NokiaFlashModel FlashModel = (NokiaFlashModel)CurrentModel;

            if (CurrentMode == PhoneInterfaces.Lumia_Bootloader)
            {
                try
                {
                    FlashModel.SwitchToFlashAppContext();
                }
                catch { }
            }
            PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);

            MassStorageWarning = null;
            if (Info.FlashAppProtocolVersionMajor < 2)
            {
                MassStorageWarning = "Switching to Mass Storage mode should take about 10 seconds. The phone should be unlocked using an Engineering SBL3 to enable Mass Storage mode. When you unlocked the bootloader, but you did not use an Engineering SBL3, an attempt to boot to Mass Storage mode may result in an unresponsive state. Installing drivers for this interface may also cause to hang the PC. So when this switch is taking too long, you should reboot both the PC and the phone. To reboot the phone, you have to perform a soft-reset. Press and hold the volume-down-button and the power-button at the same time for at least 10 seconds. This will trigger a power-cycle and the phone will reboot. Once fully booted, the phone may show strange behavior, like complaining about mail-accounts, showing old text-messages, inability to load https-websites, etc. This is expected behavior, because the time-settings of the phone are incorrect. Just wait a few seconds for the phone to get a data-connection and have the date/time synced. After that the strange behavior will stop automatically and normal operation is resumed.";
            }
            else
            {
                MassStorageWarning = "When the screen of the phone is black for a while, it could be that the phone is already in Mass Storage Mode, but there is no drive-letter assigned. To resolve this issue, open Device Manager and manually assign a drive-letter to the MainOS partition of your phone, or open a command-prompt and type: diskpart automount enable.";
                if (App.IsPnPEventLogMissing)
                {
                    MassStorageWarning += " It is also possible that the phone is in Mass Storage mode, but the Mass Storage driver on this PC failed. Your PC does not have an eventlog to detect this misbehaviour. But in this case you will see a device with an exclamation mark in Device Manager and then you need to manually reset the phone by pressing and holding the power-button for at least 10 seconds until it vibrates and reboots. After that Windows Phone Internals will revert the changes. After the phone has rebooted to the OS, you can retry to unlock the bootloader.";
                }
            }

            bool IsOldLumia    = (Info.FlashAppProtocolVersionMajor < 2);
            bool IsNewLumia    = (Info.FlashAppProtocolVersionMajor >= 2);
            bool IsUnlockedNew = false;

            if (IsNewLumia)
            {
                GPT GPT = FlashModel.ReadGPT();
                IsUnlockedNew = ((GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null));
            }
            bool IsOriginalEngineeringLumia = ((!Info.SecureFfuEnabled || Info.Authenticated || Info.RdcPresent) && !IsUnlockedNew);

            if (IsOldLumia || IsOriginalEngineeringLumia)
            {
                byte[] BootModeFlagCommand        = new byte[] { 0x4E, 0x4F, 0x4B, 0x58, 0x46, 0x57, 0x00, 0x55, 0x42, 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 }; // NOKFW UBF
                byte[] RebootCommand              = new byte[] { 0x4E, 0x4F, 0x4B, 0x52 };
                byte[] RebootToMassStorageCommand = new byte[] { 0x4E, 0x4F, 0x4B, 0x4D };                                                                         // NOKM
                IsSwitchingInterface = true;
                byte[] RebootCommandResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(RebootToMassStorageCommand);
                if ((RebootCommandResult != null) && (RebootCommandResult.Length == 4)) // This means fail: NOKU (unknow command)
                {
                    BootModeFlagCommand[0x0F] = 0x4D;
                    byte[] BootFlagResult = ((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(BootModeFlagCommand);
                    UInt16 ResultCode     = BitConverter.ToUInt16(BootFlagResult, 6);
                    if (ResultCode == 0)
                    {
                        PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
                        ((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
                        ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
                        LogFile.Log("Rebooting phone to Mass Storage mode");
                    }
                    else
                    {
                        ModeSwitchErrorWrapper("Failed to switch to Mass Storage mode");
                        IsSwitchingInterface = false;
                    }
                }
                else
                {
                    PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
                    ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
                    LogFile.Log("Rebooting phone to Mass Storage mode");
                }
            }
            else if (IsUnlockedNew)
            {
                new Thread(async() =>
                {
                    LogFile.BeginAction("SwitchToMassStorageMode");

                    try
                    {
                        // Implementation of writing a partition with SecureBoot variable to the phone
                        ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
                        LogFile.Log("Preparing phone for Mass Storage Mode", LogType.FileAndConsole);
                        var assembly = System.Reflection.Assembly.GetExecutingAssembly();

                        // Magic!
                        // The SBMSM resource is a compressed version of a raw NV-variable-partition.
                        // In this partition the SecureBoot variable is disabled and an extra variable is added which triggers Mass Storage Mode on next reboot.
                        // It overwrites the variable in a different NV-partition than where this variable is stored usually.
                        // This normally leads to endless-loops when the NV-variables are enumerated.
                        // But the partition contains an extra hack to break out the endless loops.
                        using (var stream = assembly.GetManifestResourceStream("WPinternals.SBMSM"))
                        {
                            using (DecompressedStream dec = new DecompressedStream(stream))
                            {
                                using (System.IO.MemoryStream SB = new System.IO.MemoryStream()) // Must be a seekable stream!
                                {
                                    dec.CopyTo(SB);

                                    // We don't need to check for the BACKUP_BS_NV partition here,
                                    // because the SecureBoot flag is disabled here.
                                    // So either the NV was already backupped or already overwritten.

                                    GPT GPT          = FlashModel.ReadGPT();
                                    Partition Target = GPT.GetPartition("UEFI_BS_NV");

                                    // We've been reading the GPT, so we let the phone reset once more to be sure that memory maps are the same
                                    WPinternalsStatus LastStatus = WPinternalsStatus.Undefined;
                                    List <FlashPart> Parts       = new List <FlashPart>();
                                    FlashPart Part   = new FlashPart();
                                    Part.StartSector = (uint)Target.FirstSector;
                                    Part.Stream      = SB;
                                    Parts.Add(Part);
                                    await LumiaV2UnlockBootViewModel.LumiaV2CustomFlash(PhoneNotifier, null, false, false, Parts, DoResetFirst: true, ClearFlashingStatusAtEnd: false, ShowProgress: false,
                                                                                        SetWorkingStatus: (m, s, v, a, st) =>
                                    {
                                        if (SetWorkingStatus != null)
                                        {
                                            if ((st == WPinternalsStatus.Scanning) || (st == WPinternalsStatus.WaitingForManualReset))
                                            {
                                                SetWorkingStatus(m, s, v, a, st);
                                            }
                                            else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
                                            {
                                                SetWorkingStatus(ProgressText, MassStorageWarning);
                                            }
                                            LastStatus = st;
                                        }
                                    },
                                                                                        UpdateWorkingStatus: (m, s, v, st) =>
                                    {
                                        if (UpdateWorkingStatus != null)
                                        {
                                            if ((st == WPinternalsStatus.Scanning) || (st == WPinternalsStatus.WaitingForManualReset))
                                            {
                                                UpdateWorkingStatus(m, s, v, st);
                                            }
                                            else if ((LastStatus == WPinternalsStatus.Scanning) || (LastStatus == WPinternalsStatus.WaitingForManualReset))
                                            {
                                                SetWorkingStatus(ProgressText, MassStorageWarning);
                                            }
                                            LastStatus = st;
                                        }
                                    });
                                }
                            }
                        }

                        if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_BadMassStorage)
                        {
                            throw new WPinternalsException("Phone is in Mass Storage mode, but the driver on PC failed to start");
                        }

                        // Wait for bootloader
                        if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_MassStorage)
                        {
                            LogFile.Log("Waiting for Mass Storage Mode (1)...", LogType.FileOnly);
                            await PhoneNotifier.WaitForArrival();
                        }

                        if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_BadMassStorage)
                        {
                            throw new WPinternalsException("Phone is in Mass Storage mode, but the driver on PC failed to start");
                        }

                        // Wait for mass storage mode
                        if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_MassStorage)
                        {
                            LogFile.Log("Waiting for Mass Storage Mode (2)...", LogType.FileOnly);
                            await PhoneNotifier.WaitForArrival();
                        }

                        if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_BadMassStorage)
                        {
                            throw new WPinternalsException("Phone is in Mass Storage mode, but the driver on PC failed to start");
                        }

                        MassStorage Storage = null;
                        if (PhoneNotifier.CurrentModel is MassStorage)
                        {
                            Storage = (MassStorage)PhoneNotifier.CurrentModel;
                        }

                        if (Storage == null)
                        {
                            ModeSwitchErrorWrapper("Failed to switch to Mass Storage Mode");
                        }
                        else
                        {
                            ModeSwitchSuccessWrapper();
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        ModeSwitchErrorWrapper(Ex.Message);
                    }

                    LogFile.EndAction("SwitchToMassStorageMode");
                }).Start();
            }
            else
            {
                ModeSwitchErrorWrapper("Bootloader was not unlocked. First unlock bootloader before you try to switch to Mass Storage Mode.");
            }
        }
コード例 #7
0
 internal NokiaModeMassStorageViewModel(NokiaPhoneModel CurrentModel, Action <PhoneInterfaces?> RequestModeSwitch)
     : base()
 {
     this.CurrentModel      = (MassStorage)CurrentModel;
     this.RequestModeSwitch = RequestModeSwitch;
 }
コード例 #8
0
        void LumiaNotifier_Arrival(object sender, USBEvent e)
        {
            try
            {
                if ((e.DevicePath.IndexOf("VID_0421&", StringComparison.OrdinalIgnoreCase) >= 0) ||
                    (e.DevicePath.IndexOf("VID_045E&", StringComparison.OrdinalIgnoreCase) >= 0))
                {
                    if ((e.DevicePath.IndexOf("&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
                        (e.DevicePath.IndexOf("&PID_0713&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) || // for Spec B
                        (e.DevicePath.IndexOf("&PID_0A01&MI_04", StringComparison.OrdinalIgnoreCase) >= 0))   // for Spec B (650)
                    {
                        CurrentInterface = PhoneInterfaces.Lumia_Label;
                        CurrentModel     = new NokiaPhoneModel(e.DevicePath);
                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                        LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                        LogFile.Log("Mode: Label", LogType.FileAndConsole);
                        NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                    }
                    else if ((e.DevicePath.IndexOf("&PID_0661", StringComparison.OrdinalIgnoreCase) >= 0) ||
                             (e.DevicePath.IndexOf("&PID_06FC", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_06FC is for Lumia 930
                             (e.DevicePath.IndexOf("&PID_0A00", StringComparison.OrdinalIgnoreCase) >= 0))   // vid_045e & pid_0a00 & mi_03 = Lumia 950 XL normal mode
                    {
                        if (((USBNotifier)sender).Guid == OldCombiInterfaceGuid)
                        {
                            NewInterfaceWaitHandle.Reset();
                            if (USBDevice.GetDevices(NewCombiInterfaceGuid).Count() > 0)
                            {
                                return;
                            }
                            else
                            {
                                // Old combi-interface was detected, but new combi-interface was not detected.
                                // This could mean 2 things:
                                // - It is a WP80 phone, which has only this old combi-interface to talk to.
                                // - It is a WP81 / W10M phone, which has an unresponsive old combi-interface and we need to wait for the new combi-interface to arrive.
                                // We will wait maximum 1 sec for the new interface. If it doesn't arrive we will start talking on this old interface.
                                // We will start a new thread, because if this thread is blocked, no new devices will arrive.
                                string DevicePath = e.DevicePath;
                                ThreadPool.QueueUserWorkItem(s =>
                                {
                                    if (!NewInterfaceWaitHandle.WaitOne(1000))
                                    {
                                        // Waithandle not set.
                                        // So new interface did not arrive.
                                        // So we assume we need to talk to this old interface.

                                        CurrentInterface = PhoneInterfaces.Lumia_Normal;
                                        CurrentModel     = new NokiaPhoneModel(DevicePath);
                                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                                        LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                                        LogFile.Log("Mode: Normal", LogType.FileAndConsole);
                                        NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                                    }
                                });
                            }
                        }
                        else
                        {
                            NewInterfaceWaitHandle.Set();

                            CurrentInterface = PhoneInterfaces.Lumia_Normal;
                            CurrentModel     = new NokiaPhoneModel(e.DevicePath);
                            LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                            LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                            LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                            LogFile.Log("Mode: Normal", LogType.FileAndConsole);
                            NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                        }
                    }
                    else if ((e.DevicePath.IndexOf("&PID_066E", StringComparison.OrdinalIgnoreCase) >= 0) ||
                             (e.DevicePath.IndexOf("&PID_0714", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_0714 is for Lumia 930
                             (e.DevicePath.IndexOf("&PID_0A02", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_045E&PID_0A02 is for Lumia 950
                             (e.DevicePath.IndexOf("&PID_05EE", StringComparison.OrdinalIgnoreCase) >= 0))   // VID_0421&PID_05EE is for early RX100
                    {
                        CurrentModel = new NokiaFlashModel(e.DevicePath);
                        ((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;

                        FlashAppType type = FlashAppType.FlashApp;
                        try
                        {
                            type = ((NokiaFlashModel)CurrentModel).GetFlashAppType();
                            LogFile.Log("Flash App Type: " + type.ToString(), LogType.FileOnly);
                        }
                        catch
                        {
                            LogFile.Log("Flash App Type could not be determined, assuming " + type.ToString(), LogType.FileOnly);
                        }

                        switch (type)
                        {
                        case FlashAppType.BootManager:
                        {
                            CurrentInterface = PhoneInterfaces.Lumia_Bootloader;
                            LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                            LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                            LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                            LogFile.Log("Mode: Bootloader", LogType.FileAndConsole);
                            NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                            break;
                        }

                        case FlashAppType.FlashApp:
                        {
                            ((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
                            CurrentInterface = PhoneInterfaces.Lumia_Flash;
                            LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                            LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                            LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                            LogFile.Log("Mode: Flash", LogType.FileAndConsole);
                            NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                            break;
                        }

                        case FlashAppType.PhoneInfoApp:
                        {
                            CurrentInterface = PhoneInterfaces.Lumia_Bootloader;
                            LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                            LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                            LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                            LogFile.Log("Mode: Bootloader (Phone Info)", LogType.FileAndConsole);
                            NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                            break;
                        }
                        }
                    }
                }
                else if ((e.DevicePath.IndexOf(@"DISK&VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.OrdinalIgnoreCase) >= 0) ||
                         (e.DevicePath.IndexOf(@"DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase) >= 0) ||
                         ((e.DevicePath.Length == @"\\.\E:".Length) && (e.DevicePath.StartsWith(@"\\.\")) && (e.DevicePath.EndsWith(":"))))
                {
#if DEBUG
                    LogFile.Log("Mass storage arrived: " + e.DevicePath, LogType.FileOnly);
                    LogFile.Log("Start new thread for getting metadata.", LogType.FileOnly);
#endif

                    // This function is possibly called by an USB notification WndProc.
                    // It is not possible to invoke COM objects from a WndProc.
                    // MassStorage uses ManagementObjectSearcher, which is a COM object.
                    // Therefore we use a new thread.
                    ThreadPool.QueueUserWorkItem(s =>
                    {
                        lock (ModelLock)
                        {
                            if (!(CurrentModel is MassStorage))
                            {
                                // Wait 1 second to make sure MainOS is loaded
                                // In case of multiple drive letters being assigned to the phone by the user
                                // MainOS may take a while to show up and we may accidentally catch up a letter that is
                                // not for MainOS.
                                Task.Delay(1000).Wait();

                                MassStorage NewModel = new MassStorage(e.DevicePath);

                                if (NewModel.Drive != null) // When logical drive is already known, we use this model. Or else we wait for the logical drive to arrive.
                                {
                                    CurrentInterface = PhoneInterfaces.Lumia_MassStorage;
                                    CurrentModel     = NewModel;
                                    LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                                    LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                                    LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                                    LogFile.Log("Mode: Mass storage mode", LogType.FileAndConsole);
                                    if (!string.IsNullOrEmpty(Qcom9006DevicePath))
                                    {
                                        LogFile.Log("Found 9006 device previously", LogType.FileOnly);
                                        LogFile.Log("Attaching 9006 device", LogType.FileOnly);
                                        NewModel.AttachQualcommSerial(Qcom9006DevicePath);
                                    }
                                    NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                                }
                            }
                        }
                    });
                }
                else if (e.DevicePath.IndexOf("VID_05C6&", StringComparison.OrdinalIgnoreCase) >= 0) // Qualcomm device
                {
                    if (e.DevicePath.IndexOf("&PID_9008", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        USBDeviceInfo DeviceInfo = USBDevice.GetDevices(((USBNotifier)sender).Guid).Where((d) => string.Compare(d.DevicePath, e.DevicePath, true) == 0).FirstOrDefault();

                        if ((DeviceInfo.BusName == "QHSUSB_DLOAD") || (DeviceInfo.BusName == "QHSUSB__BULK") || ((DeviceInfo.BusName == "") && (LastInterface != PhoneInterfaces.Qualcomm_Download))) // TODO: Separate for Sahara!
                        {
                            CurrentInterface = PhoneInterfaces.Qualcomm_Download;
                            CurrentModel     = new QualcommSerial(e.DevicePath);
                            NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                            LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                            LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                            LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                            if (DeviceInfo.BusName == "")
                            {
                                LogFile.Log("Driver does not show busname, assume mode: Qualcomm Emergency Download 9008", LogType.FileAndConsole);
                            }
                            else
                            {
                                LogFile.Log("Mode: Qualcomm Emergency Download 9008", LogType.FileAndConsole);
                            }
                        }
                        else if ((DeviceInfo.BusName == "QHSUSB_ARMPRG") || ((DeviceInfo.BusName == "") && (LastInterface == PhoneInterfaces.Qualcomm_Download)))
                        {
                            CurrentInterface = PhoneInterfaces.Qualcomm_Flash;
                            CurrentModel     = new QualcommSerial(e.DevicePath);
                            NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                            LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                            LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                            LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                            if (DeviceInfo.BusName == "")
                            {
                                LogFile.Log("Driver does not show busname, assume mode: Qualcomm Emergency Flash 9008", LogType.FileAndConsole);
                            }
                            else
                            {
                                LogFile.Log("Mode: Qualcomm Emergency Flash 9008", LogType.FileAndConsole);
                            }
                        }
                    }
                    else if (e.DevicePath.IndexOf("&PID_9006", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        // This is part of the Mass Storage inteface.
                        // It is a slightly different version of the Qualcomm Emergency interface, which is implemented in SBL3.
                        // One important difference is that the base address for sending a loader is not 0x2A000000, but it is 0x82F00000.

                        Qcom9006DevicePath = e.DevicePath;

                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                        LogFile.Log("Device path: " + Qcom9006DevicePath, LogType.FileOnly);
                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                        LogFile.Log("Mode: Qualcomm Emergency 9006", LogType.FileAndConsole);

                        if (CurrentModel is MassStorage)
                        {
                            LogFile.Log("Found Mass Storage device previously", LogType.FileOnly);
                            LogFile.Log("Attaching 9006 device", LogType.FileOnly);
                            ((MassStorage)CurrentModel).AttachQualcommSerial(Qcom9006DevicePath);
                        }
                    }
                    else if (e.DevicePath.IndexOf("&PID_F006", StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        // This is part of the charging inteface.

                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                        LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                        LogFile.Log("Mode: Qualcomm Emergency Charging F006", LogType.FileAndConsole);
                    }
                }
            }
            catch (Exception Ex)
            {
                LogFile.LogException(Ex);
                CurrentModel     = null;
                CurrentInterface = null;
            }
        }
コード例 #9
0
        void LumiaNotifier_Arrival(object sender, USBEvent e)
        {
            try
            {
                if (e.DevicePath.IndexOf("VID_0421&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    CurrentInterface = PhoneInterfaces.Lumia_Label;
                    CurrentModel     = new NokiaPhoneModel(e.DevicePath);
                    LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                    LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                    LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                    LogFile.Log("Mode: Label", LogType.FileAndConsole);
                    NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                }
                else if ((e.DevicePath.IndexOf("VID_0421&PID_0661", StringComparison.OrdinalIgnoreCase) >= 0) ||
                         (e.DevicePath.IndexOf("VID_0421&PID_06FC", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_06FC is for Lumia 930
                         (e.DevicePath.IndexOf("vid_045e&pid_0a00", StringComparison.OrdinalIgnoreCase) >= 0))   // vid_045e & pid_0a00 & mi_03 = Lumia 950 XL normal mode
                {
                    if (((USBNotifier)sender).Guid == OldCombiInterfaceGuid)
                    {
                        NewInterfaceWaitHandle.Reset();
                        if (USBDevice.GetDevices(NewCombiInterfaceGuid).Count() > 0)
                        {
                            return;
                        }
                        else
                        {
                            // Old combi-interface was detected, but new combi-interface was not detected.
                            // This could mean 2 things:
                            // - It is a WP80 phone, which has only this old combi-interface to talk to.
                            // - It is a WP81 / W10M phone, which has an unresponsive old combi-interface and we need to wait for the new combi-interface to arrive.
                            // We will wait maximum 1 sec for the new interface. If it doesn't arrive we will start talking on this old interface.
                            // We will start a new thread, because if this thread is blocked, no new devices will arrive.
                            string DevicePath = e.DevicePath;
                            ThreadPool.QueueUserWorkItem(s =>
                            {
                                if (!NewInterfaceWaitHandle.WaitOne(1000))
                                {
                                    // Waithandle not set.
                                    // So new interface did not arrive.
                                    // So we assume we need to talk to this old interface.

                                    CurrentInterface = PhoneInterfaces.Lumia_Normal;
                                    CurrentModel     = new NokiaPhoneModel(DevicePath);
                                    LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                                    LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                                    LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                                    LogFile.Log("Mode: Normal", LogType.FileAndConsole);
                                    NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                                }
                            });
                        }
                    }
                    else
                    {
                        NewInterfaceWaitHandle.Set();

                        CurrentInterface = PhoneInterfaces.Lumia_Normal;
                        CurrentModel     = new NokiaPhoneModel(e.DevicePath);
                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                        LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                        LogFile.Log("Mode: Normal", LogType.FileAndConsole);
                        NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                    }
                }
                else if ((e.DevicePath.IndexOf("VID_0421&PID_066E", StringComparison.OrdinalIgnoreCase) >= 0) ||
                         (e.DevicePath.IndexOf("VID_0421&PID_0714", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_0714 is for Lumia 930
                         (e.DevicePath.IndexOf("VID_045E&PID_0A02", StringComparison.OrdinalIgnoreCase) >= 0))   // VID_045E&PID_0A02 is for Lumia 950
                {
                    CurrentModel = new NokiaFlashModel(e.DevicePath);
                    ((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;

                    // Attempt to request a param.
                    // When it succeeds we have full Flash mode.
                    // When it fails we are in a limited Flash mode, like Bootmanager or Hardreset-screen.
                    // Limited Flash mode only supports boot-commands; not querying info.
                    byte[] QueryResult = ((NokiaFlashModel)CurrentModel).ReadParam("SS");
                    if (QueryResult == null)
                    {
                        CurrentInterface = PhoneInterfaces.Lumia_Bootloader;
                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                        LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                        LogFile.Log("Mode: Bootloader", LogType.FileAndConsole);
                        NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                    }
                    else
                    {
                        ((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
                        CurrentInterface = PhoneInterfaces.Lumia_Flash;
                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                        LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                        LogFile.Log("Mode: Flash", LogType.FileAndConsole);
                        NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                    }
                }
                else if ((e.DevicePath.IndexOf(@"disk&ven_qualcomm&prod_mmc_storage", StringComparison.OrdinalIgnoreCase) >= 0) ||
                         (e.DevicePath.IndexOf(@"DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase) >= 0))
                {
#if DEBUG
                    LogFile.Log("Mass storage arrived: " + e.DevicePath, LogType.FileOnly);
                    LogFile.Log("Start new thread for getting metadata.", LogType.FileOnly);
#endif

                    // This function is possibly called by an USB notification WndProc.
                    // It is not possible to invoke COM objects from a WndProc.
                    // MassStorage uses ManagementObjectSearcher, which is a COM object.
                    // Therefore we use a new thread.
                    ThreadPool.QueueUserWorkItem(s => {
                        lock (ModelLock)
                        {
                            if (!(CurrentModel is MassStorage))
                            {
                                MassStorage NewModel = new MassStorage(e.DevicePath);
                                if (NewModel.Drive != null) // When logical drive is already known, we use this model. Or else we wait for the logical drive to arrive.
                                {
                                    CurrentInterface = PhoneInterfaces.Lumia_MassStorage;
                                    CurrentModel     = NewModel;
                                    LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                                    LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                                    LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                                    LogFile.Log("Mode: Mass storage mode", LogType.FileAndConsole);
                                    NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                                }
                            }
                        }
                    });
                }
                else if ((e.DevicePath.Length == @"\\.\E:".Length) && (e.DevicePath.StartsWith(@"\\.\")) && (e.DevicePath.EndsWith(":")))
                {
#if DEBUG
                    LogFile.Log("Mass storage arrived: " + e.DevicePath, LogType.FileOnly);
                    LogFile.Log("Start new thread for getting metadata.", LogType.FileOnly);
#endif
                    // This function is possibly called by an USB notification WndProc.
                    // It is not possible to invoke COM objects from a WndProc.
                    // MassStorage uses ManagementObjectSearcher, which is a COM object.
                    // Therefore we use a new thread.
                    ThreadPool.QueueUserWorkItem(s =>
                    {
                        lock (ModelLock)
                        {
                            if (!(CurrentModel is MassStorage))
                            {
                                MassStorage NewModel = new MassStorage(e.DevicePath);
                                if (NewModel.Drive != null) // When logical drive is already known, we use this model. Or else we wait for the logical drive to arrive.
                                {
                                    CurrentInterface = PhoneInterfaces.Lumia_MassStorage;
                                    CurrentModel     = NewModel;
                                    LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                                    LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                                    LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                                    LogFile.Log("Mode: Mass storage mode", LogType.FileAndConsole);
                                    NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                                }
                            }
                        }
                    });
                }
                else if (e.DevicePath.IndexOf("VID_05C6&PID_9008", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    USBDeviceInfo DeviceInfo = USBDevice.GetDevices(((USBNotifier)sender).Guid).Where((d) => string.Compare(d.DevicePath, e.DevicePath, true) == 0).FirstOrDefault();

                    if ((DeviceInfo.BusName == "QHSUSB_DLOAD") || (DeviceInfo.BusName == "QHSUSB__BULK") || ((DeviceInfo.BusName == "") && (LastInterface != PhoneInterfaces.Qualcomm_Download))) // TODO: Separate for Sahara!
                    {
                        CurrentInterface = PhoneInterfaces.Qualcomm_Download;
                        CurrentModel     = new QualcommSerial(e.DevicePath);
                        NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                        LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                        if (DeviceInfo.BusName == "")
                        {
                            LogFile.Log("Driver does not show busname, assume mode: Qualcomm Emergency Download 9008", LogType.FileAndConsole);
                        }
                        else
                        {
                            LogFile.Log("Mode: Qualcomm Emergency Download 9008", LogType.FileAndConsole);
                        }
                    }
                    else if ((DeviceInfo.BusName == "QHSUSB_ARMPRG") || ((DeviceInfo.BusName == "") && (LastInterface == PhoneInterfaces.Qualcomm_Download)))
                    {
                        CurrentInterface = PhoneInterfaces.Qualcomm_Flash;
                        CurrentModel     = new QualcommSerial(e.DevicePath);
                        NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
                        LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                        LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                        LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                        if (DeviceInfo.BusName == "")
                        {
                            LogFile.Log("Driver does not show busname, assume mode: Qualcomm Emergency Flash 9008", LogType.FileAndConsole);
                        }
                        else
                        {
                            LogFile.Log("Mode: Qualcomm Emergency Flash 9008", LogType.FileAndConsole);
                        }
                    }
                }
                else if (e.DevicePath.IndexOf("VID_05C6&PID_9006", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    // This is part of the Mass Storage inteface.
                    // It is a slightly different version of the Qualcomm Emergency interface, which is implemented in SBL3.
                    // One important difference is that the base address for sending a loader is not 0x2A000000, but it is 0x82F00000.

                    LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
                    LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
                    LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
                    LogFile.Log("Mode: Qualcomm Emergency 9006", LogType.FileAndConsole);
                }
            }
            catch (Exception Ex)
            {
                LogFile.LogException(Ex);
                CurrentModel     = null;
                CurrentInterface = null;
            }
        }
コード例 #10
0
 internal NokiaMassStorageViewModel(MassStorage CurrentModel)
     : base()
 {
     this.CurrentModel = CurrentModel;
     _Drive            = CurrentModel.Drive;
 }
コード例 #11
0
        internal void BackupArchiveProvisioningTask(string ArchiveProvisioningPath)
        {
            IsSwitchingInterface = false;
            new Thread(() =>
            {
                bool Result = true;

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

                ulong TotalSizeSectors = 0;
                int PartitionCount     = 0;

                MassStorage Phone = (MassStorage)PhoneNotifier.CurrentModel;

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

                    Partition Partition;

                    try
                    {
                        foreach (string PartitionName in ProvisioningPartitions)
                        {
                            if (GPT.Partitions.Any(p => p.Name == PartitionName))
                            {
                                Partition = GPT.Partitions.First(p => p.Name == PartitionName);
                                if (PartitionName == "UEFI_BS_NV" && GPT.Partitions.Any(p => p.Name == "BACKUP_BS_NV"))
                                {
                                    Partition = GPT.Partitions.First(p => p.Name == "BACKUP_BS_NV");
                                }

                                TotalSizeSectors += Partition.SizeInSectors;
                                PartitionCount++;
                            }
                        }
                    }
                    catch (Exception Ex)
                    {
                        LogFile.LogException(Ex);
                        Result = false;
                    }

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

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

                    foreach (string PartitionName in ProvisioningPartitions)
                    {
                        if (GPT.Partitions.Any(p => p.Name == PartitionName) && Result)
                        {
                            try
                            {
                                Entry       = Archive.CreateEntry(PartitionName + ".bin", CompressionLevel.Optimal);
                                EntryStream = Entry.Open();
                                i++;
                                Busy.Message = "Create backup of partition " + PartitionName + " (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
                                if (PartitionName == "UEFI_BS_NV" && GPT.Partitions.Any(p => p.Name == "BACKUP_BS_NV"))
                                {
                                    Phone.BackupPartition("BACKUP_BS_NV", EntryStream, Updater);
                                }
                                else
                                {
                                    Phone.BackupPartition(PartitionName, EntryStream, Updater);
                                }
                            }
                            catch (Exception Ex)
                            {
                                LogFile.LogException(Ex);
                                Result = false;
                            }
                            finally
                            {
                                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();
        }
コード例 #12
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(GPTBuffer);
                Partition Partition;
                try
                {
                    if (EFIESPPath != null)
                    {
                        Partition         = GPT.Partitions.First(p => p.Name == "EFIESP");
                        TotalSizeSectors += Partition.SizeInSectors;
                        PartitionCount++;
                    }

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

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

                BusyViewModel Busy      = new("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();
        }
コード例 #13
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();
        }