mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-06-14 03:16:40 +10:00
Code update
- WPinternals is now a .NET Core 3.0 application - Implemented new unlock process for Spec A devices - Updated logic for unlocking Spec B devices - Implemented MMOS support for Spec B devices - Implemented battery status in Flash Mode - Implemented Fuse configuration information in Flash Mode - Implemented Reboot from mass storage for Spec A and some Spec B devices - Implemented shutdown from flash mode (preliminary) - Fixed label mode support for Spec B
This commit is contained in:
@@ -28,13 +28,14 @@ namespace WPinternals
|
||||
private PhoneNotifierViewModel PhoneNotifier;
|
||||
private Action<string, string, string> FlashPartitionsCallback;
|
||||
private Action<string> FlashFFUCallback;
|
||||
private Action<string> FlashMMOSCallback;
|
||||
private Action<string> FlashArchiveCallback;
|
||||
internal Action SwitchToUnlockBoot;
|
||||
internal Action SwitchToUnlockRoot;
|
||||
internal Action SwitchToDumpFFU;
|
||||
internal Action SwitchToBackup;
|
||||
|
||||
internal LumiaFlashRomSourceSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToUnlockRoot, Action SwitchToDumpFFU, Action SwitchToBackup, Action<string, string, string> FlashPartitionsCallback, Action<string> FlashArchiveCallback, Action<string> FlashFFUCallback)
|
||||
internal LumiaFlashRomSourceSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToUnlockRoot, Action SwitchToDumpFFU, Action SwitchToBackup, Action<string, string, string> FlashPartitionsCallback, Action<string> FlashArchiveCallback, Action<string> FlashFFUCallback, Action<string> FlashMMOSCallback)
|
||||
: base()
|
||||
{
|
||||
this.PhoneNotifier = PhoneNotifier;
|
||||
@@ -45,6 +46,7 @@ namespace WPinternals
|
||||
this.FlashPartitionsCallback = FlashPartitionsCallback;
|
||||
this.FlashArchiveCallback = FlashArchiveCallback;
|
||||
this.FlashFFUCallback = FlashFFUCallback;
|
||||
this.FlashMMOSCallback = FlashMMOSCallback;
|
||||
|
||||
this.PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||
this.PhoneNotifier.DeviceRemoved += DeviceRemoved;
|
||||
@@ -137,6 +139,23 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
private string _MMOSPath;
|
||||
public string MMOSPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return _MMOSPath;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _MMOSPath)
|
||||
{
|
||||
_MMOSPath = value;
|
||||
OnPropertyChanged("MMOSPath");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _IsPhoneDisconnected;
|
||||
public bool IsPhoneDisconnected
|
||||
{
|
||||
@@ -214,6 +233,19 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _FlashMMOSCommand;
|
||||
public DelegateCommand FlashMMOSCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_FlashMMOSCommand == null)
|
||||
{
|
||||
_FlashMMOSCommand = new DelegateCommand(() => { FlashMMOSCallback(MMOSPath); }, () => ((MMOSPath != null) && (PhoneNotifier.CurrentInterface != null)));
|
||||
}
|
||||
return _FlashMMOSCommand;
|
||||
}
|
||||
}
|
||||
|
||||
private DelegateCommand _FlashArchiveCommand;
|
||||
public DelegateCommand FlashArchiveCommand
|
||||
{
|
||||
@@ -257,6 +289,7 @@ namespace WPinternals
|
||||
FlashPartitionsCommand.RaiseCanExecuteChanged();
|
||||
FlashArchiveCommand.RaiseCanExecuteChanged();
|
||||
FlashFFUCommand.RaiseCanExecuteChanged();
|
||||
FlashMMOSCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace WPinternals
|
||||
return;
|
||||
|
||||
if (SubContextViewModel == null)
|
||||
ActivateSubContext(new LumiaFlashRomSourceSelectionViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToUnlockRoot, SwitchToDumpFFU, SwitchToBackup, FlashPartitions, FlashArchive, FlashFFU));
|
||||
ActivateSubContext(new LumiaFlashRomSourceSelectionViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToUnlockRoot, SwitchToDumpFFU, SwitchToBackup, FlashPartitions, FlashArchive, FlashFFU, FlashMMOS));
|
||||
}
|
||||
|
||||
// Called from an event-handler. So, "async void" is valid here.
|
||||
@@ -505,7 +505,7 @@ namespace WPinternals
|
||||
|
||||
if (Info.FlashAppProtocolVersionMajor >= 2)
|
||||
{
|
||||
byte[] GPTChunk = LumiaV2UnlockBootViewModel.GetGptChunk(Phone, 0x20000); // TODO: Get proper profile FFU and get ChunkSizeInBytes
|
||||
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>();
|
||||
@@ -606,6 +606,84 @@ namespace WPinternals
|
||||
}).Start();
|
||||
}
|
||||
|
||||
// Called from an event-handler. So, "async void" is valid here.
|
||||
internal async void FlashMMOS(string MMOSPath)
|
||||
{
|
||||
IsSwitchingInterface = true; // Prevents that a device is forced to Flash mode on this screen which is meant for flashing
|
||||
try
|
||||
{
|
||||
await SwitchModeViewModel.SwitchToWithProgress(PhoneNotifier, PhoneInterfaces.Lumia_Flash,
|
||||
(msg, sub) =>
|
||||
ActivateSubContext(new BusyViewModel(msg, sub)));
|
||||
FlashMMOSTask(MMOSPath);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
ActivateSubContext(new MessageViewModel(Ex.Message, Callback));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrived;
|
||||
|
||||
if (Args.NewInterface != PhoneInterfaces.Lumia_Label)
|
||||
{
|
||||
ExitFailure("Flash failed!", "Phone unexpectedly switched mode while booting MMOS image.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitSuccess("Flash successful!", null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Called from an event-handler. So, "async void" is valid here.
|
||||
internal async void Exit()
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace WPinternals
|
||||
ActivateSubContext(new NokiaModeLabelViewModel((NokiaPhoneModel)CurrentModel, OnModeSwitchRequested));
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_MassStorage:
|
||||
ActivateSubContext(new NokiaModeMassStorageViewModel(null));
|
||||
ActivateSubContext(new NokiaModeMassStorageViewModel((MassStorage)CurrentModel, OnModeSwitchRequested));
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -75,7 +75,10 @@ namespace WPinternals
|
||||
bool HasNewBootloader = HasNewBootloaderFromMassStorage();
|
||||
string EFIESPPath = HasNewBootloader ? null : ((MassStorage)PhoneNotifier.CurrentModel).Drive + @"\EFIESP\";
|
||||
string MainOSPath = ((MassStorage)PhoneNotifier.CurrentModel).Drive + @"\";
|
||||
StartPatch(EFIESPPath, MainOSPath, HasNewBootloader);
|
||||
|
||||
bool HasV11Patches = HasV11PatchesFromMassStorage();
|
||||
|
||||
StartPatch(EFIESPPath, MainOSPath, HasNewBootloader, HasV11Patches);
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
@@ -88,12 +91,12 @@ namespace WPinternals
|
||||
|
||||
internal void DoUnlockImage(string EFIESPMountPoint, string MainOSMountPoint)
|
||||
{
|
||||
StartPatch(EFIESPMountPoint, MainOSMountPoint, false); // Unlock image is only supported for Lumia's with bootloader Spec A. Due to complexity of Spec B bootloader hack, it cannot be applied on a mounted image.
|
||||
StartPatch(EFIESPMountPoint, MainOSMountPoint, false, false); // Unlock image is only supported for Lumia's with bootloader Spec A. Due to complexity of Spec B bootloader hack, it cannot be applied on a mounted image.
|
||||
}
|
||||
|
||||
// Magic!
|
||||
// Apply patches for Root Access
|
||||
private void StartPatch(string EFIESP, string MainOS, bool HasNewBootloader)
|
||||
private void StartPatch(string EFIESP, string MainOS, bool HasNewBootloader, bool HasV11Patches)
|
||||
{
|
||||
IsSwitchingInterface = false;
|
||||
new Thread(() =>
|
||||
@@ -105,7 +108,7 @@ namespace WPinternals
|
||||
|
||||
bool Result = false;
|
||||
|
||||
if (EFIESP != null)
|
||||
if (EFIESP != null && !HasV11Patches)
|
||||
{
|
||||
if (DoUnlock)
|
||||
ActivateSubContext(new BusyViewModel("Enable Root Access on EFIESP..."));
|
||||
@@ -239,5 +242,18 @@ namespace WPinternals
|
||||
Phone.CloseVolume();
|
||||
return Result;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -92,6 +92,22 @@ namespace WPinternals
|
||||
{
|
||||
SecurityFlags = (UInt32)CurrentModel.ReadSecurityFlags();
|
||||
LogFile.Log("Security flags: 0x" + SecurityFlags.ToString("X8"));
|
||||
|
||||
FinalConfigDakStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Dak);
|
||||
FinalConfigFastBootStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.FastBoot);
|
||||
FinalConfigFfuVerifyStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.FfuVerify);
|
||||
FinalConfigJtagStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Jtag);
|
||||
FinalConfigOemIdStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.OemId);
|
||||
FinalConfigProductionDoneStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.ProductionDone);
|
||||
FinalConfigPublicIdStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.PublicId);
|
||||
FinalConfigRkhStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Rkh);
|
||||
FinalConfigRpmWdogStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.RpmWdog);
|
||||
FinalConfigSecGenStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.SecGen);
|
||||
FinalConfigSecureBootStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.SecureBoot);
|
||||
FinalConfigShkStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Shk);
|
||||
FinalConfigSimlockStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Simlock);
|
||||
FinalConfigSpdmSecModeStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.SpdmSecMode);
|
||||
FinalConfigSsmStatus = CurrentModel.ReadFuseStatus(NokiaFlashModel.Fuse.Ssm);
|
||||
}
|
||||
else
|
||||
LogFile.Log("Security flags could not be read");
|
||||
@@ -173,6 +189,9 @@ namespace WPinternals
|
||||
eMMC = Manufacturer + " " + MemSizeDouble.ToString() + " GB";
|
||||
SamsungWarningVisible = (MID == 0x0015);
|
||||
|
||||
ChargingStatus = CurrentModel.ReadCurrentChargeLevel() + "% - " + CurrentModel.ReadCurrentChargeCurrent() + " mA";
|
||||
LogFile.Log("Charging status: " + ChargingStatus);
|
||||
|
||||
PhoneInfo Info = CurrentModel.ReadPhoneInfo(true);
|
||||
if (Info.FlashAppProtocolVersionMajor < 2)
|
||||
BootloaderDescription = "Lumia Bootloader Spec A";
|
||||
@@ -293,6 +312,20 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
private string _ChargingStatus = null;
|
||||
public string ChargingStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ChargingStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_ChargingStatus = value;
|
||||
OnPropertyChanged("ChargingStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool _SamsungWarningVisible = false;
|
||||
public bool SamsungWarningVisible
|
||||
{
|
||||
@@ -419,6 +452,218 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
#region Final Config
|
||||
private bool? _FinalConfigSecureBootStatus = null;
|
||||
public bool? FinalConfigSecureBootStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigSecureBootStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigSecureBootStatus = value;
|
||||
OnPropertyChanged("FinalConfigSecureBootStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigFfuVerifyStatus = null;
|
||||
public bool? FinalConfigFfuVerifyStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigFfuVerifyStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigFfuVerifyStatus = value;
|
||||
OnPropertyChanged("FinalConfigFfuVerifyStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigJtagStatus = null;
|
||||
public bool? FinalConfigJtagStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigJtagStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigJtagStatus = value;
|
||||
OnPropertyChanged("FinalConfigJtagStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigShkStatus = null;
|
||||
public bool? FinalConfigShkStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigShkStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigShkStatus = value;
|
||||
OnPropertyChanged("FinalConfigShkStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigSimlockStatus = null;
|
||||
public bool? FinalConfigSimlockStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigSimlockStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigSimlockStatus = value;
|
||||
OnPropertyChanged("FinalConfigSimlockStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigProductionDoneStatus = null;
|
||||
public bool? FinalConfigProductionDoneStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigProductionDoneStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigProductionDoneStatus = value;
|
||||
OnPropertyChanged("FinalConfigProductionDoneStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigRkhStatus = null;
|
||||
public bool? FinalConfigRkhStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigRkhStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigRkhStatus = value;
|
||||
OnPropertyChanged("FinalConfigRkhStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigPublicIdStatus = null;
|
||||
public bool? FinalConfigPublicIdStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigPublicIdStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigPublicIdStatus = value;
|
||||
OnPropertyChanged("FinalConfigPublicIdStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigDakStatus = null;
|
||||
public bool? FinalConfigDakStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigDakStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigDakStatus = value;
|
||||
OnPropertyChanged("FinalConfigDakStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigSecGenStatus = null;
|
||||
public bool? FinalConfigSecGenStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigSecGenStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigSecGenStatus = value;
|
||||
OnPropertyChanged("FinalConfigSecGenStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigOemIdStatus = null;
|
||||
public bool? FinalConfigOemIdStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigOemIdStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigOemIdStatus = value;
|
||||
OnPropertyChanged("FinalConfigOemIdStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigFastBootStatus = null;
|
||||
public bool? FinalConfigFastBootStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigFastBootStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigFastBootStatus = value;
|
||||
OnPropertyChanged("FinalConfigFastBootStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigSpdmSecModeStatus = null;
|
||||
public bool? FinalConfigSpdmSecModeStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigSpdmSecModeStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigSpdmSecModeStatus = value;
|
||||
OnPropertyChanged("FinalConfigSpdmSecModeStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigRpmWdogStatus = null;
|
||||
public bool? FinalConfigRpmWdogStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigRpmWdogStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigRpmWdogStatus = value;
|
||||
OnPropertyChanged("FinalConfigRpmWdogStatus");
|
||||
}
|
||||
}
|
||||
|
||||
private bool? _FinalConfigSsmStatus = null;
|
||||
public bool? FinalConfigSsmStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _FinalConfigSsmStatus;
|
||||
}
|
||||
set
|
||||
{
|
||||
_FinalConfigSsmStatus = value;
|
||||
OnPropertyChanged("FinalConfigSsmStatus");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
internal void RebootTo(string Mode)
|
||||
{
|
||||
switch (Mode)
|
||||
|
||||
@@ -18,46 +18,59 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WPinternals
|
||||
{
|
||||
internal class NokiaModeMassStorageViewModel : ContextViewModel
|
||||
{
|
||||
private NokiaPhoneModel CurrentModel;
|
||||
private MassStorage CurrentModel;
|
||||
private Action<PhoneInterfaces?> RequestModeSwitch;
|
||||
|
||||
internal NokiaModeMassStorageViewModel(NokiaPhoneModel CurrentModel)
|
||||
internal NokiaModeMassStorageViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
|
||||
: base()
|
||||
{
|
||||
this.CurrentModel = CurrentModel;
|
||||
this.CurrentModel = (MassStorage)CurrentModel;
|
||||
this.RequestModeSwitch = RequestModeSwitch;
|
||||
}
|
||||
|
||||
internal void RebootTo(string Mode)
|
||||
private bool _SupportsReboot = false;
|
||||
public bool SupportsReboot
|
||||
{
|
||||
string DeviceMode;
|
||||
get
|
||||
{
|
||||
return _SupportsReboot;
|
||||
}
|
||||
set
|
||||
{
|
||||
_SupportsReboot = value;
|
||||
OnPropertyChanged("SupportsReboot");
|
||||
}
|
||||
}
|
||||
|
||||
internal override void EvaluateViewState()
|
||||
{
|
||||
if (IsActive)
|
||||
SupportsReboot = CurrentModel.DoesDeviceSupportReboot();
|
||||
}
|
||||
|
||||
public void RebootTo(string Mode)
|
||||
{
|
||||
switch (Mode)
|
||||
{
|
||||
case "Flash":
|
||||
DeviceMode = "Flash";
|
||||
LogFile.Log("Reboot to Flash");
|
||||
case "Normal":
|
||||
RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
|
||||
break;
|
||||
case "Label":
|
||||
DeviceMode = "Test";
|
||||
LogFile.Log("Reboot to Label");
|
||||
RequestModeSwitch(PhoneInterfaces.Lumia_Label);
|
||||
break;
|
||||
case "MassStorage":
|
||||
DeviceMode = "Flash"; // TODO: implement folow-up
|
||||
LogFile.Log("Reboot to Mass Storage");
|
||||
case "Flash":
|
||||
RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, object> Params = new Dictionary<string, object>();
|
||||
Params.Add("DeviceMode", DeviceMode);
|
||||
Params.Add("ResetMethod", "HwReset");
|
||||
CurrentModel.ExecuteJsonMethodAsync("SetDeviceMode", Params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,15 +54,28 @@ namespace WPinternals
|
||||
LogFile.Log("Product Code: " + ProductCode);
|
||||
Firmware = CurrentModel.ExecuteJsonMethodAsString("ReadSwVersion", "SwVersion"); // 3051.40000.1349.0007
|
||||
LogFile.Log("Firmware: " + Firmware);
|
||||
HWID = CurrentModel.ExecuteJsonMethodAsString("ReadHwVersion", "HWVersion"); // 1002
|
||||
LogFile.Log("HWID: " + HWID);
|
||||
|
||||
IMEI = CurrentModel.ExecuteJsonMethodAsString("ReadSerialNumber", new System.Collections.Generic.Dictionary<string, object>() { { "SubscriptionId", 0 } }, "SerialNumber"); // IMEI
|
||||
string IMEI2 = CurrentModel.ExecuteJsonMethodAsString("ReadSerialNumber", new System.Collections.Generic.Dictionary<string, object>() { { "SubscriptionId", 1 } }, "SerialNumber"); // IMEI 2
|
||||
|
||||
if (!string.IsNullOrEmpty(IMEI2))
|
||||
IMEI += "\n" + IMEI2;
|
||||
|
||||
IMEI = CurrentModel.ExecuteJsonMethodAsString("ReadSerialNumber", "SerialNumber"); // IMEI
|
||||
LogFile.Log("IMEI: " + IMEI);
|
||||
PublicID = CurrentModel.ExecuteJsonMethodAsBytes("ReadPublicId", "PublicId"); // 0x14 bytes: a5 e5 ...
|
||||
LogFile.Log("Public ID: " + Converter.ConvertHexToString(PublicID, " "));
|
||||
BluetoothMac = CurrentModel.ExecuteJsonMethodAsBytes("ReadBtId", "BtId"); // 6 bytes: bc c6 ...
|
||||
LogFile.Log("Bluetooth MAC: " + Converter.ConvertHexToString(BluetoothMac, " "));
|
||||
WlanMac = CurrentModel.ExecuteJsonMethodAsBytes("ReadWlanMacAddress", "WlanMacAddress1"); // 6 bytes
|
||||
LogFile.Log("WLAN MAC: " + Converter.ConvertHexToString(WlanMac, " "));
|
||||
WlanMac1 = CurrentModel.ExecuteJsonMethodAsBytes("ReadWlanMacAddress", "WlanMacAddress1"); // 6 bytes
|
||||
LogFile.Log("WLAN MAC 1: " + Converter.ConvertHexToString(WlanMac1, " "));
|
||||
WlanMac2 = CurrentModel.ExecuteJsonMethodAsBytes("ReadWlanMacAddress", "WlanMacAddress2"); // 6 bytes
|
||||
LogFile.Log("WLAN MAC 2: " + Converter.ConvertHexToString(WlanMac2, " "));
|
||||
WlanMac3 = CurrentModel.ExecuteJsonMethodAsBytes("ReadWlanMacAddress", "WlanMacAddress3"); // 6 bytes
|
||||
LogFile.Log("WLAN MAC 3: " + Converter.ConvertHexToString(WlanMac3, " "));
|
||||
WlanMac4 = CurrentModel.ExecuteJsonMethodAsBytes("ReadWlanMacAddress", "WlanMacAddress4"); // 6 bytes
|
||||
LogFile.Log("WLAN MAC 4: " + Converter.ConvertHexToString(WlanMac4, " "));
|
||||
|
||||
bool? ProductionDone = CurrentModel.ExecuteJsonMethodAsBoolean("ReadProductionDoneState", "ProductionDone");
|
||||
if (ProductionDone == null)
|
||||
@@ -72,6 +85,23 @@ namespace WPinternals
|
||||
LogFile.Log("Bootloader Security: " + ((bool)IsBootloaderSecurityEnabled ? "Enabled" : "Disabled"));
|
||||
IsSimLocked = CurrentModel.ExecuteJsonMethodAsBoolean("ReadSimlockActive", "SimLockActive");
|
||||
LogFile.Log("Simlock: " + ((bool)IsSimLocked ? "Active" : "Unlocked"));
|
||||
|
||||
string BootPolicy = CurrentModel.ExecuteJsonMethodAsString("GetUefiCertificateStatus", "BootPolicy");
|
||||
string Db = CurrentModel.ExecuteJsonMethodAsString("GetUefiCertificateStatus", "Db");
|
||||
string Dbx = CurrentModel.ExecuteJsonMethodAsString("GetUefiCertificateStatus", "Dbx");
|
||||
string Kek = CurrentModel.ExecuteJsonMethodAsString("GetUefiCertificateStatus", "Kek");
|
||||
string Pk = CurrentModel.ExecuteJsonMethodAsString("GetUefiCertificateStatus", "Pk");
|
||||
|
||||
this.BootPolicy = BootPolicy;
|
||||
LogFile.Log("Boot policy: " + BootPolicy);
|
||||
this.Db = Db;
|
||||
LogFile.Log("DB: " + Db);
|
||||
this.Dbx = Dbx;
|
||||
LogFile.Log("DBX: " + Dbx);
|
||||
this.Kek = Kek;
|
||||
LogFile.Log("KEK: " + Kek);
|
||||
this.Pk = Pk;
|
||||
LogFile.Log("PK: " + Pk);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
@@ -132,6 +162,20 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
private string _HWID = null;
|
||||
public string HWID
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HWID;
|
||||
}
|
||||
set
|
||||
{
|
||||
_HWID = value;
|
||||
OnPropertyChanged("HWID");
|
||||
}
|
||||
}
|
||||
|
||||
private string _IMEI = null;
|
||||
public string IMEI
|
||||
{
|
||||
@@ -146,6 +190,80 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
private string _BootPolicy = null;
|
||||
public string BootPolicy
|
||||
{
|
||||
get
|
||||
{
|
||||
return _BootPolicy;
|
||||
}
|
||||
set
|
||||
{
|
||||
_BootPolicy = value;
|
||||
OnPropertyChanged("BootPolicy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _Db = null;
|
||||
public string Db
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Db;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Db = value;
|
||||
OnPropertyChanged("Db");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _Dbx = null;
|
||||
public string Dbx
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Dbx;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Dbx = value;
|
||||
OnPropertyChanged("Dbx");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _Kek = null;
|
||||
public string Kek
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Kek;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Kek = value;
|
||||
OnPropertyChanged("Kek");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _Pk = null;
|
||||
public string Pk
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Pk;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Pk = value;
|
||||
OnPropertyChanged("Pk");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] _PublicID = null;
|
||||
public byte[] PublicID
|
||||
{
|
||||
@@ -160,17 +278,59 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] _WlanMac = null;
|
||||
public byte[] WlanMac
|
||||
private byte[] _WlanMac1 = null;
|
||||
public byte[] WlanMac1
|
||||
{
|
||||
get
|
||||
{
|
||||
return _WlanMac;
|
||||
return _WlanMac1;
|
||||
}
|
||||
set
|
||||
{
|
||||
_WlanMac = value;
|
||||
OnPropertyChanged("WlanMac");
|
||||
_WlanMac1 = value;
|
||||
OnPropertyChanged("WlanMac1");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] _WlanMac2 = null;
|
||||
public byte[] WlanMac2
|
||||
{
|
||||
get
|
||||
{
|
||||
return _WlanMac2;
|
||||
}
|
||||
set
|
||||
{
|
||||
_WlanMac2 = value;
|
||||
OnPropertyChanged("WlanMac2");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] _WlanMac3 = null;
|
||||
public byte[] WlanMac3
|
||||
{
|
||||
get
|
||||
{
|
||||
return _WlanMac3;
|
||||
}
|
||||
set
|
||||
{
|
||||
_WlanMac3 = value;
|
||||
OnPropertyChanged("WlanMac3");
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] _WlanMac4 = null;
|
||||
public byte[] WlanMac4
|
||||
{
|
||||
get
|
||||
{
|
||||
return _WlanMac4;
|
||||
}
|
||||
set
|
||||
{
|
||||
_WlanMac4 = value;
|
||||
OnPropertyChanged("WlanMac4");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace WPinternals
|
||||
private USBNotifier StorageNotifier;
|
||||
private USBNotifier ComPortNotifier;
|
||||
private USBNotifier LumiaEmergencyNotifier;
|
||||
private USBNotifier LumiaLabelNotifier;
|
||||
|
||||
public PhoneInterfaces? CurrentInterface = null;
|
||||
private PhoneInterfaces? LastInterface = null;
|
||||
@@ -54,6 +55,7 @@ namespace WPinternals
|
||||
private Guid LumiaFlashInterfaceGuid = new Guid("{9e3bd5f7-9690-4fcc-8810-3e2650cd6ecc}");
|
||||
private Guid ComPortInterfaceGuid = new Guid("{86E0D1E0-8089-11D0-9CE4-08003E301F73}");
|
||||
private Guid LumiaEmergencyInterfaceGuid = new Guid("{71DE994D-8B7C-43DB-A27E-2AE7CD579A0C}");
|
||||
private Guid LumiaLabelInterfaceGuid = new Guid("{F4FE0C27-7304-4ED7-AAB5-130893B84B6F}");
|
||||
|
||||
private object ModelLock = new object();
|
||||
|
||||
@@ -61,6 +63,8 @@ namespace WPinternals
|
||||
|
||||
private EventLogWatcher LogWatcher;
|
||||
|
||||
private string Qcom9006DevicePath;
|
||||
|
||||
internal void Start()
|
||||
{
|
||||
LumiaOldCombiNotifier = new USBNotifier(OldCombiInterfaceGuid);
|
||||
@@ -91,6 +95,10 @@ namespace WPinternals
|
||||
LumiaEmergencyNotifier.Arrival += LumiaNotifier_Arrival;
|
||||
LumiaEmergencyNotifier.Removal += LumiaNotifier_Removal;
|
||||
|
||||
LumiaLabelNotifier = new USBNotifier(LumiaLabelInterfaceGuid);
|
||||
LumiaLabelNotifier.Arrival += LumiaNotifier_Arrival;
|
||||
LumiaLabelNotifier.Removal += LumiaNotifier_Removal;
|
||||
|
||||
try
|
||||
{
|
||||
EventLogQuery LogQuery = new EventLogQuery("Microsoft-Windows-Kernel-PnP/Configuration", PathType.LogName, "*[System[(EventID = 411)]]");
|
||||
@@ -143,7 +151,8 @@ namespace WPinternals
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.DevicePath.IndexOf("VID_0421&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
if ((e.DevicePath.IndexOf("VID_0421&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_0713&MI_04", StringComparison.OrdinalIgnoreCase) >= 0)) // for Spec B
|
||||
{
|
||||
CurrentInterface = PhoneInterfaces.Lumia_Label;
|
||||
CurrentModel = new NokiaPhoneModel(e.DevicePath);
|
||||
@@ -253,6 +262,10 @@ namespace WPinternals
|
||||
if (!(CurrentModel is MassStorage))
|
||||
{
|
||||
MassStorage NewModel = new MassStorage(e.DevicePath);
|
||||
|
||||
if (!string.IsNullOrEmpty(Qcom9006DevicePath))
|
||||
NewModel.AttachQualcommSerial(Qcom9006DevicePath);
|
||||
|
||||
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;
|
||||
@@ -284,6 +297,10 @@ namespace WPinternals
|
||||
if (!(CurrentModel is MassStorage))
|
||||
{
|
||||
MassStorage NewModel = new MassStorage(e.DevicePath);
|
||||
|
||||
if (!string.IsNullOrEmpty(Qcom9006DevicePath))
|
||||
NewModel.AttachQualcommSerial(Qcom9006DevicePath);
|
||||
|
||||
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;
|
||||
@@ -339,6 +356,8 @@ namespace WPinternals
|
||||
LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
|
||||
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
|
||||
LogFile.Log("Mode: Qualcomm Emergency 9006", LogType.FileAndConsole);
|
||||
|
||||
Qcom9006DevicePath = e.DevicePath;
|
||||
}
|
||||
}
|
||||
catch (Exception Ex)
|
||||
@@ -356,8 +375,14 @@ namespace WPinternals
|
||||
|
||||
void LumiaNotifier_Removal(object sender, USBEvent e)
|
||||
{
|
||||
if (e.DevicePath.IndexOf("VID_05C6&PID_9006", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
Qcom9006DevicePath = null;
|
||||
}
|
||||
|
||||
if (
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_0713&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_0661", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_06FC", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
(e.DevicePath.IndexOf("VID_0421&PID_066E", StringComparison.OrdinalIgnoreCase) >= 0) ||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -211,10 +212,10 @@ namespace WPinternals
|
||||
LogFile.Log("Rebooting phone to Flash mode", LogType.FileAndConsole);
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Label:
|
||||
DeviceMode = "Test";
|
||||
DeviceMode = "Flash";
|
||||
IsSwitchingInterface = true;
|
||||
ModeSwitchProgressWrapper("Rebooting phone to Label mode...", null);
|
||||
LogFile.Log("Rebooting phone to Label mode", LogType.FileAndConsole);
|
||||
ModeSwitchProgressWrapper("First rebooting phone to Flash mode...", null);
|
||||
LogFile.Log("First rebooting phone to Flash mode (then attempt Label mode)", LogType.FileAndConsole);
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_MassStorage:
|
||||
DeviceMode = "Flash";
|
||||
@@ -259,8 +260,11 @@ namespace WPinternals
|
||||
((NokiaFlashModel)CurrentModel).Shutdown();
|
||||
ModeSwitchProgressWrapper("Shutting down phone...", null);
|
||||
LogFile.Log("Shutting down phone", LogType.FileAndConsole);
|
||||
PhoneNotifier.WaitForRemoval().Wait();
|
||||
ModeSwitchSuccessWrapper();
|
||||
new Thread(() =>
|
||||
{
|
||||
PhoneNotifier.WaitForRemoval().Wait();
|
||||
//ModeSwitchSuccessWrapper(); TODO: Display UI
|
||||
}).Start();
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Normal:
|
||||
((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
||||
@@ -275,12 +279,7 @@ namespace WPinternals
|
||||
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Label:
|
||||
BootModeFlagCommand[0x0F] = 0x59;
|
||||
((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(BootModeFlagCommand);
|
||||
((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||
ModeSwitchProgressWrapper("Rebooting phone to Label mode...", null);
|
||||
LogFile.Log("Rebooting phone to Label mode", LogType.FileAndConsole);
|
||||
SwitchFromFlashToLabelMode();
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Flash: // attempt to boot from limited flash to full flash
|
||||
byte[] RebootToFlashCommand = new byte[] { 0x4E, 0x4F, 0x4B, 0x53 }; // NOKS
|
||||
@@ -312,7 +311,30 @@ namespace WPinternals
|
||||
}
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_MassStorage:
|
||||
// TODO: don't know how to switch from Mass Storage to other mode
|
||||
IsSwitchingInterface = true;
|
||||
switch (TargetMode)
|
||||
{
|
||||
case PhoneInterfaces.Lumia_Normal:
|
||||
((MassStorage)CurrentModel).Reboot();
|
||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||
ModeSwitchProgressWrapper("Rebooting phone to Normal mode...", null);
|
||||
LogFile.Log("Rebooting phone to Normal mode", LogType.FileAndConsole);
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Label:
|
||||
((MassStorage)CurrentModel).Reboot();
|
||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
|
||||
ModeSwitchProgressWrapper("Rebooting phone to Label mode...", null);
|
||||
LogFile.Log("Rebooting phone to Label mode...", LogType.FileAndConsole);
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Flash:
|
||||
((MassStorage)CurrentModel).Reboot();
|
||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
|
||||
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
|
||||
LogFile.Log("Rebooting phone to Flash mode...", LogType.FileAndConsole);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case PhoneInterfaces.Qualcomm_Download:
|
||||
// TODO: don't know how to switch from Qualcomm Download mode to other mode
|
||||
@@ -320,6 +342,59 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
private void NewDeviceArrivedFromMassStorageMode(ArrivalEventArgs Args)
|
||||
{
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrivedFromMassStorageMode;
|
||||
|
||||
CurrentModel = (IDisposable)Args.NewModel;
|
||||
CurrentMode = Args.NewInterface;
|
||||
|
||||
// After the mass storage mode reboot command, the phone must be in Bootloader mode.
|
||||
// If it isn't, something unexpected happened and the phone can't be switched.
|
||||
//
|
||||
if (CurrentMode == PhoneInterfaces.Lumia_Bootloader)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await SwitchToWithStatus(PhoneNotifier, TargetMode, SetWorkingStatus, UpdateWorkingStatus);
|
||||
ModeSwitchSuccessWrapper();
|
||||
}
|
||||
catch
|
||||
{
|
||||
switch (TargetMode)
|
||||
{
|
||||
case PhoneInterfaces.Lumia_Flash:
|
||||
ModeSwitchErrorWrapper("Failed to switch to Flash mode");
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Label:
|
||||
ModeSwitchErrorWrapper("Failed to switch to Label mode");
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Normal:
|
||||
ModeSwitchErrorWrapper("Failed to switch to Normal mode");
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (TargetMode)
|
||||
{
|
||||
case PhoneInterfaces.Lumia_Flash:
|
||||
ModeSwitchErrorWrapper("Failed to switch to Flash mode");
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Label:
|
||||
ModeSwitchErrorWrapper("Failed to switch to Label mode");
|
||||
break;
|
||||
case PhoneInterfaces.Lumia_Normal:
|
||||
ModeSwitchErrorWrapper("Failed to switch to Normal mode");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void NewDeviceArrived(ArrivalEventArgs Args)
|
||||
{
|
||||
PhoneNotifier.NewDeviceArrived -= NewDeviceArrived;
|
||||
@@ -363,6 +438,10 @@ namespace WPinternals
|
||||
{
|
||||
SwitchFromFlashToMassStorageMode(Continuation: true);
|
||||
}
|
||||
else if ((CurrentMode == PhoneInterfaces.Lumia_Flash) && (TargetMode == PhoneInterfaces.Lumia_Label))
|
||||
{
|
||||
SwitchFromFlashToLabelMode(Continuation: true);
|
||||
}
|
||||
else if ((CurrentMode == PhoneInterfaces.Lumia_Flash) && (TargetMode == PhoneInterfaces.Qualcomm_Download))
|
||||
{
|
||||
byte[] RebootCommand = new byte[] { 0x4E, 0x4F, 0x4B, 0x52 };
|
||||
@@ -407,6 +486,93 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
private void SwitchFromFlashToLabelMode(bool Continuation = false)
|
||||
{
|
||||
string ProgressText;
|
||||
if (Continuation)
|
||||
ProgressText = "And now preparing to boot the phone to Label mode...";
|
||||
else
|
||||
ProgressText = "Preparing to boot the phone to Label mode...";
|
||||
|
||||
NokiaFlashModel FlashModel = (NokiaFlashModel)CurrentModel;
|
||||
if (CurrentMode == PhoneInterfaces.Lumia_Bootloader)
|
||||
{
|
||||
try
|
||||
{
|
||||
FlashModel.SwitchToFlashAppContext();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
PhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: true);
|
||||
|
||||
if (Info.MmosOverUsbSupported)
|
||||
{
|
||||
new Thread(() =>
|
||||
{
|
||||
LogFile.BeginAction("SwitchToLabelMode");
|
||||
|
||||
try
|
||||
{
|
||||
ModeSwitchProgressWrapper(ProgressText, null);
|
||||
string TempFolder = Environment.GetEnvironmentVariable("TEMP") + @"\WPInternals";
|
||||
string ENOSWPackage = LumiaDownloadModel.SearchENOSW(Info.Type, Info.Firmware);
|
||||
SetWorkingStatus("Downloading " + Info.Type + " Test Mode package...", MaxProgressValue: 100);
|
||||
DownloadEntry downloadEntry = new DownloadEntry(ENOSWPackage, TempFolder, null, null, null);
|
||||
|
||||
downloadEntry.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) =>
|
||||
{
|
||||
if (e.PropertyName == "Progress")
|
||||
{
|
||||
int progress = (sender as DownloadEntry).Progress;
|
||||
ulong progressret;
|
||||
ulong.TryParse(progress.ToString(), out progressret);
|
||||
UpdateWorkingStatus(null, CurrentProgressValue: progressret);
|
||||
|
||||
if (progress == 100)
|
||||
{
|
||||
ModeSwitchProgressWrapper("Initializing Flash...", null);
|
||||
|
||||
string MMOSPath = TempFolder + "\\" + (sender as DownloadEntry).Name;
|
||||
|
||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||
FileInfo info = new FileInfo(MMOSPath);
|
||||
uint length = uint.Parse(info.Length.ToString());
|
||||
int maximumbuffersize = 0x00240000;
|
||||
uint totalcounts = (uint)Math.Truncate((decimal)length / maximumbuffersize);
|
||||
|
||||
SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100);
|
||||
|
||||
ProgressUpdater progressUpdater = new ProgressUpdater(totalcounts + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i));
|
||||
FlashModel.FlashMMOS(MMOSPath, progressUpdater);
|
||||
|
||||
SetWorkingStatus("And now booting phone to MMOS...", "If the phone stays on the lightning cog screen for a while, you may need to unplug and replug the phone to continue the boot process.");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception Ex)
|
||||
{
|
||||
LogFile.LogException(Ex);
|
||||
ModeSwitchErrorWrapper(Ex.Message);
|
||||
}
|
||||
|
||||
LogFile.EndAction("SwitchToLabelMode");
|
||||
}).Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
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 }; // NOKR
|
||||
|
||||
BootModeFlagCommand[0x0F] = 0x59;
|
||||
((NokiaPhoneModel)CurrentModel).ExecuteRawMethod(BootModeFlagCommand);
|
||||
((NokiaPhoneModel)CurrentModel).ExecuteRawVoidMethod(RebootCommand);
|
||||
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
|
||||
ModeSwitchProgressWrapper("Rebooting phone to Label mode", null);
|
||||
LogFile.Log("Rebooting phone to Label mode", LogType.FileAndConsole);
|
||||
}
|
||||
}
|
||||
|
||||
private void SwitchFromFlashToMassStorageMode(bool Continuation = false)
|
||||
{
|
||||
string ProgressText;
|
||||
@@ -442,7 +608,7 @@ namespace WPinternals
|
||||
if (IsNewLumia)
|
||||
{
|
||||
GPT GPT = FlashModel.ReadGPT();
|
||||
IsUnlockedNew = ((GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null));
|
||||
IsUnlockedNew = ((GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null) || (GPT.GetPartition("BACKUP_BS_NV") != null));
|
||||
}
|
||||
bool IsOriginalEngineeringLumia = ((!Info.SecureFfuEnabled || Info.Authenticated || Info.RdcPresent) && !IsUnlockedNew);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user