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:
Gus
2019-07-26 17:15:20 +02:00
parent b062efab52
commit 5dae1da560
58 changed files with 5522 additions and 66864 deletions
@@ -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();
}
}
}
+80 -2
View File
@@ -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()
{
+1 -1
View File
@@ -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
+20 -4
View File
@@ -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
+245
View File
@@ -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)
+31 -18
View File
@@ -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);
}
}
}
+168 -8
View File
@@ -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");
}
}
+26 -1
View File
@@ -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) ||
+179 -13
View File
@@ -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);