Some cleanup

This commit is contained in:
Gustave Monce
2024-10-12 17:20:54 +02:00
parent d700ae5911
commit 303c2d4b5a
18 changed files with 638 additions and 535 deletions
+9 -10
View File
@@ -185,10 +185,8 @@ namespace WPinternals
{
Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null);
BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader); // This also works for Bootloader Spec A
GPT GPT = BootMgrModel.ReadGPT(); // May throw NotSupportedException
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader);
GPT GPT = await LumiaUnlockBootloaderViewModel.ReadGPTFromFlashOrBootMgr(Notifier);
foreach (Partition Partition in GPT.Partitions)
{
LogFile.Log(Partition.Name.PadRight(20) + "0x" + Partition.FirstSector.ToString("X8") + " - 0x" + Partition.LastSector.ToString("X8") + " " + Partition.Volume, LogType.ConsoleOnly);
@@ -216,8 +214,8 @@ namespace WPinternals
{
Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null);
BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader);
GPT GPT = BootMgrModel.ReadGPT(); // May throw NotSupportedException
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader);
GPT GPT = await LumiaUnlockBootloaderViewModel.ReadGPTFromFlashOrBootMgr(Notifier);
string DirPath = Path.GetDirectoryName(args[2]);
if (!string.IsNullOrEmpty(DirPath) && !Directory.Exists(DirPath))
{
@@ -275,8 +273,7 @@ namespace WPinternals
{
Notifier = new PhoneNotifierViewModel();
UIContext.Send(s => Notifier.Start(), null);
BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader);
byte[] GptChunk = BootMgrModel.GetGptChunk(0x20000);
byte[] GptChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, 0x20000);
GPT GPT = new(GptChunk);
string Xml = File.ReadAllText(args[2]);
GPT.MergePartitions(Xml, false);
@@ -1671,8 +1668,10 @@ namespace WPinternals
Microsoft.Win32.SafeHandles.SafeFileHandle safeFileHandle = new(stdHandle, true);
FileStream fileStream = new(safeFileHandle, FileAccess.Write);
Encoding encoding = Encoding.GetEncoding(MY_CODE_PAGE);
StreamWriter standardOutput = new(fileStream, encoding);
standardOutput.AutoFlush = true;
StreamWriter standardOutput = new(fileStream, encoding)
{
AutoFlush = true
};
Console.SetOut(standardOutput);
}
catch
+8 -6
View File
@@ -430,9 +430,10 @@ namespace WPinternals
if (SaveDialog)
{
Microsoft.Win32.SaveFileDialog savedlg = new();
savedlg.FileName = Path ?? DefaultFileName;
Microsoft.Win32.SaveFileDialog savedlg = new()
{
FileName = Path ?? DefaultFileName
};
// Show open file dialog box
result = savedlg.ShowDialog();
@@ -447,9 +448,10 @@ namespace WPinternals
else
{
// Select file
Microsoft.Win32.OpenFileDialog dlg = new();
dlg.FileName = Path ?? DefaultFileName;
Microsoft.Win32.OpenFileDialog dlg = new()
{
FileName = Path ?? DefaultFileName
};
// Show open file dialog box
result = dlg.ShowDialog();
+9 -7
View File
@@ -81,13 +81,15 @@ namespace WPinternals
break;
}
Partition CurrentPartition = new();
CurrentPartition.Name = Name;
CurrentPartition.FirstSector = ByteOperations.ReadUInt64(GPTBuffer, PartitionOffset + 0x20);
CurrentPartition.LastSector = ByteOperations.ReadUInt64(GPTBuffer, PartitionOffset + 0x28);
CurrentPartition.PartitionTypeGuid = ByteOperations.ReadGuid(GPTBuffer, PartitionOffset + 0x00);
CurrentPartition.PartitionGuid = ByteOperations.ReadGuid(GPTBuffer, PartitionOffset + 0x10);
CurrentPartition.Attributes = ByteOperations.ReadUInt64(GPTBuffer, PartitionOffset + 0x30);
Partition CurrentPartition = new()
{
Name = Name,
FirstSector = ByteOperations.ReadUInt64(GPTBuffer, PartitionOffset + 0x20),
LastSector = ByteOperations.ReadUInt64(GPTBuffer, PartitionOffset + 0x28),
PartitionTypeGuid = ByteOperations.ReadGuid(GPTBuffer, PartitionOffset + 0x00),
PartitionGuid = ByteOperations.ReadGuid(GPTBuffer, PartitionOffset + 0x10),
Attributes = ByteOperations.ReadUInt64(GPTBuffer, PartitionOffset + 0x30)
};
Partitions.Add(CurrentPartition);
PartitionOffset += PartitionEntrySize;
}
@@ -51,7 +51,7 @@ namespace WPinternals.Models.Lumia.MSR
string Config = null;
try
{
Config = Client.DownloadString("https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/" + ProductType + "/emergency_flash_config.xml");
Config = Client.DownloadString($"https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/{ProductType}/emergency_flash_config.xml");
}
catch
{
@@ -68,7 +68,7 @@ namespace WPinternals.Models.Lumia.MSR
if (Node != null)
{
FileName = Node.Attributes["image_path"].InnerText;
Src = "https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/" + ProductType + "/" + FileName;
Src = $"https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/{ProductType}/{FileName}";
LogFile.Log("Hex-file: " + Src);
Result.Add(Src);
}
@@ -78,7 +78,7 @@ namespace WPinternals.Models.Lumia.MSR
if (Node != null)
{
FileName = Node.Attributes["image_path"].InnerText;
Src = "https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/" + ProductType + "/" + FileName;
Src = $"https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/{ProductType}/{FileName}";
LogFile.Log("Mbn-file: " + Src);
Result.Add(Src);
}
@@ -87,7 +87,7 @@ namespace WPinternals.Models.Lumia.MSR
foreach (XmlNode SubNode in Doc.SelectNodes("//emergency_flash_config/first_boot_images/first_boot_image"))
{
FileName = SubNode.Attributes["image_path"].InnerText;
Src = "https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/" + ProductType + "/" + FileName;
Src = $"https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/{ProductType}/{FileName}";
LogFile.Log("Firehose-programmer-file: " + Src);
Result.Add(Src);
}
@@ -96,7 +96,7 @@ namespace WPinternals.Models.Lumia.MSR
foreach (XmlNode SubNode in Doc.SelectNodes("//emergency_flash_config/second_boot_firehose_single_image/firehose_image"))
{
FileName = SubNode.Attributes["image_path"].InnerText;
Src = "https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/" + ProductType + "/" + FileName;
Src = $"https://repairavoidance.blob.core.windows.net/packages/EmergencyFlash/{ProductType}/{FileName}";
LogFile.Log("Firehose-payload-file: " + Src);
Result.Add(Src);
}
@@ -323,8 +323,10 @@ namespace WPinternals.Models.UEFIApps.BootMgr
0x0002 => "Flash read failed",
_ => "Unknown error",
};
WPinternalsException Ex = new("Flash failed!");
Ex.SubMessage = "Error 0x" + ErrorCode.ToString("X4") + ": " + SubMessage;
WPinternalsException Ex = new("Flash failed!")
{
SubMessage = "Error 0x" + ErrorCode.ToString("X4") + ": " + SubMessage
};
throw Ex;
}
@@ -161,6 +161,12 @@ namespace WPinternals.Models.UEFIApps.Flash
byte[] Response = ExecuteRawMethod(Request);
if (Response == null)
{
// Succeeded
return;
}
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
{
throw new NotSupportedException();
@@ -186,11 +192,8 @@ namespace WPinternals.Models.UEFIApps.Flash
if (ExtendedInfo && Result.State == PhoneInfoState.Basic)
{
if (Result.App == FlashAppType.FlashApp)
{
Result.Firmware = ReadStringParam("FVER");
Result.RKH = ReadParam("RRKH");
}
Result.Firmware = ReadStringParam("FVER");
Result.RKH = ReadParam("RRKH");
Result.State = PhoneInfoState.Extended;
}
@@ -294,6 +297,13 @@ namespace WPinternals.Models.UEFIApps.Flash
return Result;
}
internal bool CanReadGPT()
{
LumiaFlashAppPhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
FlashAppType OriginalAppType = Info.App;
return Info.IsBootloaderSecure;
}
internal GPT ReadGPT()
{
// If this function is used with a locked BootMgr v1,
@@ -302,10 +312,7 @@ namespace WPinternals.Models.UEFIApps.Flash
// Only works in BootLoader-mode or on unlocked bootloaders in Flash-mode!!
LumiaFlashAppPhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
FlashAppType OriginalAppType = Info.App;
bool Switch = Info.IsBootloaderSecure;
if (Switch)
if (CanReadGPT())
{
throw new InvalidOperationException("Bootloader is not unlocked!");
}
@@ -324,7 +331,8 @@ namespace WPinternals.Models.UEFIApps.Flash
ushort Error = (ushort)((Buffer[6] << 8) + Buffer[7]);
if (Error > 0)
{
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
ThrowFlashError(Error);
//throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
}
byte[] GPTBuffer = new byte[Buffer.Length - 0x208];
@@ -333,20 +341,23 @@ namespace WPinternals.Models.UEFIApps.Flash
return new GPT(GPTBuffer); // NOKT message header and MBR are ignored
}
internal byte[] GetGptChunk(uint Size) // TODO!
internal byte[] GetGptChunk(uint Size)
{
// This function is also used to generate a dummy chunk to flash for testing.
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
byte[] GPTChunk = new byte[Size];
// If this function is used with a locked BootMgr v1,
// then the mode-switching should be done outside this function,
// because the context-switches that are used here are not supported on BootMgr v1.
LumiaFlashAppPhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
FlashAppType OriginalAppType = Info.App;
bool Switch = Info.IsBootloaderSecure;
if (Switch)
// Only works in BootLoader-mode or on unlocked bootloaders in Flash-mode!!
if (CanReadGPT())
{
throw new InvalidOperationException("Bootloader is not unlocked!");
}
// This function is also used to generate a dummy chunk to flash for testing.
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
byte[] GPTChunk = new byte[Size];
byte[] Request = new byte[0x04];
const string Header = "NOKT";
@@ -449,16 +460,17 @@ namespace WPinternals.Models.UEFIApps.Flash
return null;
}
UefiSecurityStatusResponse Result = new();
Result.IsTestDevice = Response[0];
Result.PlatformSecureBootStatus = Convert.ToBoolean(Response[1]);
Result.SecureFfuEfuseStatus = Convert.ToBoolean(Response[2]);
Result.DebugStatus = Convert.ToBoolean(Response[3]);
Result.RdcStatus = Convert.ToBoolean(Response[4]);
Result.AuthenticationStatus = Convert.ToBoolean(Response[5]);
Result.UefiSecureBootStatus = Convert.ToBoolean(Response[6]);
Result.CryptoHardwareKey = Convert.ToBoolean(Response[7]);
UefiSecurityStatusResponse Result = new()
{
IsTestDevice = Response[0],
PlatformSecureBootStatus = Convert.ToBoolean(Response[1]),
SecureFfuEfuseStatus = Convert.ToBoolean(Response[2]),
DebugStatus = Convert.ToBoolean(Response[3]),
RdcStatus = Convert.ToBoolean(Response[4]),
AuthenticationStatus = Convert.ToBoolean(Response[5]),
UefiSecureBootStatus = Convert.ToBoolean(Response[6]),
CryptoHardwareKey = Convert.ToBoolean(Response[7])
};
_SecurityStatus = Result;
@@ -473,12 +485,13 @@ namespace WPinternals.Models.UEFIApps.Flash
return null;
}
FlashVersion Result = new();
Result.ProtocolMajor = Response[1];
Result.ProtocolMinor = Response[2];
Result.ApplicationMajor = Response[3];
Result.ApplicationMinor = Response[4];
FlashVersion Result = new()
{
ProtocolMajor = Response[1],
ProtocolMinor = Response[2],
ApplicationMajor = Response[3],
ApplicationMinor = Response[4]
};
return Result;
}
@@ -830,8 +843,10 @@ namespace WPinternals.Models.UEFIApps.Flash
0x0002 => "Flash read failed",
_ => "Unknown error",
};
WPinternalsException Ex = new("Flash failed!");
Ex.SubMessage = "Error 0x" + ErrorCode.ToString("X4") + ": " + SubMessage;
WPinternalsException Ex = new("Flash failed!")
{
SubMessage = "Error 0x" + ErrorCode.ToString("X4") + ": " + SubMessage
};
throw Ex;
}
@@ -1112,7 +1127,7 @@ namespace WPinternals.Models.UEFIApps.Flash
private void FlashRawPartition(string Path, Stream Stream, string PartitionName, Action<int, TimeSpan?> ProgressUpdateCallback, ProgressUpdater UpdaterPerSector)
{
GPT GPT = ReadGPT();
FlashRawPartition(Path, Stream, PartitionName, ProgressUpdateCallback, UpdaterPerSector);
FlashRawPartition(GPT, Path, Stream, PartitionName, ProgressUpdateCallback, UpdaterPerSector);
}
private void FlashRawPartition(GPT GPT, string Path, Stream Stream, string PartitionName, Action<int, TimeSpan?> ProgressUpdateCallback, ProgressUpdater UpdaterPerSector)
+4 -3
View File
@@ -111,9 +111,10 @@ namespace WPinternals
try
{
QualcommSerial SerialDevice = new(Serial);
SerialDevice.EncodeCommands = false;
QualcommSerial SerialDevice = new(Serial)
{
EncodeCommands = false
};
// This will succeed on new models
SerialDevice.SendData([0x7, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0]);
+8 -4
View File
@@ -415,8 +415,10 @@ namespace WPinternals
(this.tlsContents.ReferenceCountValue > 1 ||
!this.tlsContents.IsImpersonating))
{
NativeMethods.TOKEN_PRIVILEGE newState = new();
newState.PrivilegeCount = 1;
NativeMethods.TOKEN_PRIVILEGE newState = new()
{
PrivilegeCount = 1
};
newState.Privilege.Luid = this.luid;
newState.Privilege.Attributes = this.initialState ? NativeMethods.SE_PRIVILEGE_ENABLED : NativeMethods.SE_PRIVILEGE_DISABLED;
@@ -544,8 +546,10 @@ namespace WPinternals
this.tlsContents.IncrementReferenceCount();
}
NativeMethods.TOKEN_PRIVILEGE newState = new();
newState.PrivilegeCount = 1;
NativeMethods.TOKEN_PRIVILEGE newState = new()
{
PrivilegeCount = 1
};
newState.Privilege.Luid = this.luid;
newState.Privilege.Attributes = enable ? NativeMethods.SE_PRIVILEGE_ENABLED : NativeMethods.SE_PRIVILEGE_DISABLED;
+10 -6
View File
@@ -59,9 +59,11 @@ namespace WPinternals
{
string FFUPath = null;
OpenFileDialog dlg = new();
dlg.DefaultExt = ".ffu"; // Default file extension
dlg.Filter = "ROM images (.ffu)|*.ffu"; // Filter files by extension
OpenFileDialog dlg = new()
{
DefaultExt = ".ffu", // Default file extension
Filter = "ROM images (.ffu)|*.ffu" // Filter files by extension
};
bool? result = dlg.ShowDialog();
@@ -95,9 +97,11 @@ namespace WPinternals
{
string SecWIMPath = null;
OpenFileDialog dlg = new();
dlg.DefaultExt = ".secwim"; // Default file extension
dlg.Filter = "Secure WIM images (.secwim)|*.secwim"; // Filter files by extension
OpenFileDialog dlg = new()
{
DefaultExt = ".secwim", // Default file extension
Filter = "Secure WIM images (.secwim)|*.secwim" // Filter files by extension
};
bool? result = dlg.ShowDialog();
@@ -93,15 +93,13 @@ namespace WPinternals
internal void FlashPartitionsTask(string EFIESPPath, string MainOSPath, string DataPath)
{
new Thread(() =>
new Thread(async () =>
{
bool Result = true;
ActivateSubContext(new BusyViewModel("Initializing flash..."));
LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
GPT GPT = Phone.ReadGPT();
GPT GPT = await LumiaUnlockBootloaderViewModel.ReadGPTFromFlashOrBootMgr(PhoneNotifier);
ulong TotalSizeSectors = 0;
int PartitionCount = 0;
@@ -157,6 +155,8 @@ namespace WPinternals
Result = false;
}
LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
if ((MainOSNewSectorCount > 0) && (DataNewSectorCount > 0))
{
if ((MainOSNewSectorCount > MainOSOldSectorCount) || (DataNewSectorCount > DataOldSectorCount))
@@ -206,7 +206,7 @@ namespace WPinternals
{
i++;
Busy.Message = "Flashing partition EFIESP (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
Phone.FlashRawPartition(EFIESPPath, "EFIESP", Updater);
Phone.FlashRawPartition(GPT, EFIESPPath, "EFIESP", Updater);
}
}
catch (Exception Ex)
@@ -224,7 +224,7 @@ namespace WPinternals
{
i++;
Busy.Message = "Flashing partition MainOS (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
Phone.FlashRawPartition(MainOSPath, "MainOS", Updater);
Phone.FlashRawPartition(GPT, MainOSPath, "MainOS", Updater);
}
}
catch (Exception Ex)
@@ -242,7 +242,7 @@ namespace WPinternals
{
i++;
Busy.Message = "Flashing partition Data (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
Phone.FlashRawPartition(DataPath, "Data", Updater);
Phone.FlashRawPartition(GPT, DataPath, "Data", Updater);
}
}
catch (Exception Ex)
@@ -288,12 +288,10 @@ namespace WPinternals
internal void FlashArchiveTask(string ArchivePath)
{
new Thread(() =>
new Thread(async () =>
{
ActivateSubContext(new BusyViewModel("Initializing flash..."));
LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
ulong TotalSizeSectors = 0;
int PartitionCount = 0;
ulong MainOSOldSectorCount = 0;
@@ -305,7 +303,7 @@ namespace WPinternals
try
{
GPT GPT = Phone.ReadGPT();
GPT GPT = await LumiaUnlockBootloaderViewModel.ReadGPTFromFlashOrBootMgr(PhoneNotifier);
using FileStream FileStream = new(ArchivePath, FileMode.Open);
using ZipArchive Archive = new(FileStream, ZipArchiveMode.Read);
@@ -412,6 +410,8 @@ namespace WPinternals
return;
}
LumiaFlashAppModel Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
if (GPTChanged)
{
Phone.WriteGPT(GPT);
@@ -453,7 +453,7 @@ namespace WPinternals
{
i++;
Busy.Message = "Flashing partition " + Partition.Name + " (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
Phone.FlashRawPartition(DecompressedStream, Partition.Name, Updater);
Phone.FlashRawPartition(GPT, DecompressedStream, Partition.Name, Updater);
}
DecompressedStream.Close();
}
@@ -522,33 +522,9 @@ namespace WPinternals
if (Info.FlashAppProtocolVersionMajor >= 2)
{
Phone.SwitchToBootManagerContext();
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
await PhoneNotifier.WaitForArrival();
}
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
throw new WPinternalsException("Unexpected Mode");
}
byte[] GPTChunk = ((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).GetGptChunk(0x20000); // TODO: Get proper profile FFU and get ChunkSizeInBytes
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(PhoneNotifier, 0x20000); // TODO: Get proper profile FFU and get ChunkSizeInBytes
GPT GPT = new(GPTChunk);
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
await PhoneNotifier.WaitForArrival();
}
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
throw new WPinternalsException("Unexpected Mode");
}
Phone = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
FlashPart Part;
@@ -790,8 +766,10 @@ namespace WPinternals
IsSwitchingInterface = false; // From here on a device will be forced to Flash mode again on this screen which is meant for flashing
Callback();
ActivateSubContext(null);
});
SuccessMessageViewModel.SubMessage = SubMessage;
})
{
SubMessage = SubMessage
};
ActivateSubContext(SuccessMessageViewModel);
}
@@ -802,8 +780,10 @@ namespace WPinternals
IsSwitchingInterface = false;
Callback();
ActivateSubContext(null);
});
ErrorMessageViewModel.SubMessage = SubMessage;
})
{
SubMessage = SubMessage
};
ActivateSubContext(ErrorMessageViewModel);
}
}
@@ -221,19 +221,6 @@ namespace WPinternals
}
else
{
bool AlreadyUnlocked = false;
if (DoUnlock)
{
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
GPT GPT = FlashModel.ReadGPT();
if ((GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null))
{
//ExitMessage("Phone is already unlocked", null);
//return;
AlreadyUnlocked = true;
}
}
TestPos = 4;
// Stop responding to device arrival here, because all connections are handled by subfunctions, not here.
@@ -271,20 +258,28 @@ namespace WPinternals
}
Task.Run(async () =>
{
bool AlreadyUnlocked = false;
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
GPT GPT = await LumiaUnlockBootloaderViewModel.ReadGPTFromFlashOrBootMgr(PhoneNotifier);
if ((GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null))
{
if (DoFixBoot)
{
await LumiaV2UnlockBootViewModel.LumiaV2FixBoot(PhoneNotifier, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
}
else if (!AlreadyUnlocked)
{
await LumiaUnlockBootloaderViewModel.LumiaV2UnlockUEFI(PhoneNotifier, ProfileFFUPath, EDEPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
}
else
{
await LumiaUnlockBootloaderViewModel.LumiaV2UnlockUEFI(PhoneNotifier, ProfileFFUPath, EDEPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage, true);
}
});
AlreadyUnlocked = true;
}
if (DoFixBoot)
{
await LumiaV2UnlockBootViewModel.LumiaV2FixBoot(PhoneNotifier, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
}
else if (!AlreadyUnlocked)
{
await LumiaUnlockBootloaderViewModel.LumiaV2UnlockUEFI(PhoneNotifier, ProfileFFUPath, EDEPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage);
}
else
{
await LumiaUnlockBootloaderViewModel.LumiaV2UnlockUEFI(PhoneNotifier, ProfileFFUPath, EDEPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, ExitMessage, ExitMessage, true);
}
});
}
else
{
@@ -666,8 +661,10 @@ namespace WPinternals
{
State = MachineState.Default;
Exit();
});
SuccessMessageViewModel.SubMessage = SubMessage;
})
{
SubMessage = SubMessage
};
ActivateSubContext(SuccessMessageViewModel);
}
@@ -35,6 +35,126 @@ namespace WPinternals
{
internal static class LumiaUnlockBootloaderViewModel
{
/// <summary>
/// This function reads GPT from the device, while preserving the current application running.
/// This works whenever the device is unlocked or not, from Flash or Bootloader apps
/// </summary>
/// <returns></returns>
/// <exception cref="WPinternalsException">The device entered an unexpected mode.</exception>
public static async Task<GPT> ReadGPTFromFlashOrBootMgr(PhoneNotifierViewModel Notifier)
{
switch (Notifier.CurrentInterface)
{
case PhoneInterfaces.Lumia_Bootloader:
{
return ((LumiaBootManagerAppModel)Notifier.CurrentModel).ReadGPT();
}
case PhoneInterfaces.Lumia_Flash:
{
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
if (FlashModel.CanReadGPT())
{
FlashModel.SwitchToBootManagerContext();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
throw new WPinternalsException("Unexpected Mode");
}
GPT GPT = ((LumiaBootManagerAppModel)Notifier.CurrentModel).ReadGPT();
((LumiaBootManagerAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
throw new WPinternalsException("Unexpected Mode");
}
return GPT;
}
else
{
return FlashModel.ReadGPT();
}
}
default:
{
throw new WPinternalsException("Unexpected Mode");
}
}
}
/// <summary>
/// This function reads GPT from the device, while preserving the current application running.
/// This works whenever the device is unlocked or not, from Flash or Bootloader apps
/// </summary>
/// <returns></returns>
/// <exception cref="WPinternalsException">The device entered an unexpected mode.</exception>
public static async Task<byte[]> GetGptChunkFromFlashOrBootMgr(PhoneNotifierViewModel Notifier, uint Size)
{
switch (Notifier.CurrentInterface)
{
case PhoneInterfaces.Lumia_Bootloader:
{
return ((LumiaBootManagerAppModel)Notifier.CurrentModel).GetGptChunk(Size);
}
case PhoneInterfaces.Lumia_Flash:
{
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
if (FlashModel.CanReadGPT())
{
FlashModel.SwitchToBootManagerContext();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
throw new WPinternalsException("Unexpected Mode");
}
byte[] GPT = ((LumiaBootManagerAppModel)Notifier.CurrentModel).GetGptChunk(Size);
((LumiaBootManagerAppModel)Notifier.CurrentModel).SwitchToFlashAppContext();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
throw new WPinternalsException("Unexpected Mode");
}
return GPT;
}
else
{
return FlashModel.GetGptChunk(Size);
}
}
default:
{
throw new WPinternalsException("Unexpected Mode");
}
}
}
// TODO: Add logging
private static void PerformSoftBrick(PhoneNotifierViewModel Notifier, FFU FFU)
{
@@ -353,33 +473,9 @@ namespace WPinternals
#endif
GPT NewGPT = null;
if (Notifier.CurrentModel is LumiaFlashAppModel)
if (Notifier.CurrentModel is LumiaFlashAppModel or LumiaBootManagerAppModel)
{
((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
NewGPT = ((LumiaBootManagerAppModel)Notifier.CurrentModel).ReadGPT();
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
NewGPT = await ReadGPTFromFlashOrBootMgr(Notifier);
}
else
{
@@ -592,11 +688,11 @@ namespace WPinternals
Progress.SetProgress(0x21);
LogFile.Log("Flash SBL2 at 0x" + ((UInt32)NewGPT.GetPartition("SBL2").FirstSector * 0x200).ToString("X8"));
CurrentModel.FlashRawPartition(SBL2, "SBL2", Progress);
CurrentModel.FlashRawPartition(NewGPT, SBL2, "SBL2", Progress);
LogFile.Log("Flash SBL3 at 0x" + ((UInt32)NewGPT.GetPartition("SBL3").FirstSector * 0x200).ToString("X8"));
CurrentModel.FlashRawPartition(SBL3, "SBL3", Progress);
CurrentModel.FlashRawPartition(NewGPT, SBL3, "SBL3", Progress);
LogFile.Log("Flash UEFI at 0x" + ((UInt32)NewGPT.GetPartition("UEFI").FirstSector * 0x200).ToString("X8"));
CurrentModel.FlashRawPartition(UEFI, "UEFI", Progress);
CurrentModel.FlashRawPartition(NewGPT, UEFI, "UEFI", Progress);
// phone is in flash mode, we can exit
}
@@ -907,33 +1003,9 @@ namespace WPinternals
#endif
GPT NewGPT = null;
if (Notifier.CurrentModel is LumiaFlashAppModel)
if (Notifier.CurrentModel is LumiaFlashAppModel or LumiaBootManagerAppModel)
{
((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
NewGPT = ((LumiaBootManagerAppModel)Notifier.CurrentModel).ReadGPT();
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
NewGPT = await ReadGPTFromFlashOrBootMgr(Notifier);
}
else
{
@@ -1273,15 +1345,15 @@ namespace WPinternals
if (ExtraSector != null)
{
LogFile.Log("Flash EXT at 0x" + ((UInt32)NewGPT.GetPartition("HACK").FirstSector * 0x200).ToString("X8"));
CurrentModel.FlashRawPartition(ExtraSector, "HACK", Progress);
CurrentModel.FlashRawPartition(NewGPT, ExtraSector, "HACK", Progress);
}
LogFile.Log("Flash SBL2 at 0x" + ((UInt32)NewGPT.GetPartition("SBL2").FirstSector * 0x200).ToString("X8"));
CurrentModel.FlashRawPartition(SBL2, "SBL2", Progress);
CurrentModel.FlashRawPartition(NewGPT, SBL2, "SBL2", Progress);
LogFile.Log("Flash SBL3 at 0x" + ((UInt32)NewGPT.GetPartition("SBL3").FirstSector * 0x200).ToString("X8"));
CurrentModel.FlashRawPartition(SBL3, "SBL3", Progress);
CurrentModel.FlashRawPartition(NewGPT, SBL3, "SBL3", Progress);
LogFile.Log("Flash UEFI at 0x" + ((UInt32)NewGPT.GetPartition("UEFI").FirstSector * 0x200).ToString("X8"));
CurrentModel.FlashRawPartition(UEFI, "UEFI", Progress);
CurrentModel.FlashRawPartition(NewGPT, UEFI, "UEFI", Progress);
// phone is in flash mode, we can exit
}
@@ -1517,31 +1589,7 @@ namespace WPinternals
bool IsSpecB = Info.FlashAppProtocolVersionMajor >= 2;
bool UndoEFIESPPadding = false;
byte[] GPTChunk;
if (!IsSpecB)
{
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
((LumiaFlashAppModel)Notifier.CurrentModel).ResetPhone();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
await Notifier.WaitForArrival();
}
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
{
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
GPTChunk = ((LumiaBootManagerAppModel)Notifier.CurrentModel).GetGptChunk(0x20000);
}
else
{
GPTChunk = ((LumiaFlashAppModel)Notifier.CurrentModel).GetGptChunk(0x20000);
}
byte[] GPTChunk = await GetGptChunkFromFlashOrBootMgr(Notifier, 0x20000);
GPT = new GPT(GPTChunk);
bool GPTChanged = false;
@@ -1579,7 +1627,7 @@ namespace WPinternals
await SwitchModeViewModel.SwitchToWithStatus(Notifier, PhoneInterfaces.Lumia_MassStorage, SetWorkingStatus, UpdateWorkingStatus);
}
if (!(Notifier.CurrentModel is MassStorage))
if (Notifier.CurrentModel is not MassStorage)
{
throw new WPinternalsException("Failed to switch to Mass Storage mode");
}
@@ -1922,7 +1970,7 @@ namespace WPinternals
LumiaPatchEFIESP(SupportedFFU, UnlockedEFIESP, IsSpecB);
byte[] GPTChunk = FlashModel.GetGptChunk((UInt32)ProfileFFU.ChunkSize);
byte[] GPTChunk = await GetGptChunkFromFlashOrBootMgr(Notifier, (UInt32)ProfileFFU.ChunkSize);
byte[] GPTChunkBackup = new byte[GPTChunk.Length];
Buffer.BlockCopy(GPTChunk, 0, GPTChunkBackup, 0, GPTChunk.Length);
GPT GPT = new(GPTChunk);
@@ -2533,9 +2581,11 @@ namespace WPinternals
List<FlashPart> Parts = [];
FlashPart Part = new();
Part.StartSector = (uint)EFIESP.FirstSector;
Part.Stream = new MemoryStream(FirstSector);
FlashPart Part = new()
{
StartSector = (uint)EFIESP.FirstSector,
Stream = new MemoryStream(FirstSector)
};
Parts.Add(Part);
Part = new FlashPart
@@ -2564,9 +2614,11 @@ namespace WPinternals
List<FlashPart> Parts = [];
FlashPart Part = new();
Part.StartSector = (uint)EFIESP.FirstSector;
Part.Stream = new MemoryStream(FirstSector);
FlashPart Part = new()
{
StartSector = (uint)EFIESP.FirstSector,
Stream = new MemoryStream(FirstSector)
};
Parts.Add(Part);
return Parts;
@@ -138,7 +138,7 @@ namespace WPinternals
// Use GetGptChunk() here instead of ReadGPT(), because ReadGPT() skips the first sector.
// We need the fist sector if we want to write back the GPT.
byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, 0x20000);
GPT GPT = new(GPTChunk);
bool GPTChanged = false;
@@ -271,7 +271,7 @@ namespace WPinternals
// Use GetGptChunk() here instead of ReadGPT(), because ReadGPT() skips the first sector.
// We need the fist sector if we want to write back the GPT.
byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, 0x20000);
GPT GPT = new(GPTChunk);
bool GPTChanged = false;
Partition BACKUP_BS_NV = GPT.GetPartition("BACKUP_BS_NV");
@@ -299,9 +299,11 @@ namespace WPinternals
if (GPTChanged)
{
GPT.Rebuild();
FlashPart Part = new();
Part.StartSector = 0;
Part.Stream = new MemoryStream(GPTChunk);
FlashPart Part = new()
{
StartSector = 0,
Stream = new MemoryStream(GPTChunk)
};
Parts.Add(Part);
}
@@ -348,7 +350,7 @@ namespace WPinternals
// Use GetGptChunk() here instead of ReadGPT(), because ReadGPT() skips the first sector.
// We need the fist sector if we want to write back the GPT.
byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, 0x20000);
GPT GPT = new(GPTChunk);
Partition TargetPartition = GPT.GetPartition(PartitionName);
@@ -487,11 +489,11 @@ namespace WPinternals
internal async static Task LumiaV2CustomFlash(PhoneNotifierViewModel Notifier, string FFUPath, bool PerformFullFlashFirst, bool SkipWrite, List<FlashPart> FlashParts, bool DoResetFirst = true, bool ClearFlashingStatusAtEnd = true, bool CheckSectorAlignment = true, bool ShowProgress = true, bool Experimental = false, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null, string ProgrammerPath = null)
{
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, 131072u);
LumiaFlashAppModel Model = (LumiaFlashAppModel)Notifier.CurrentModel;
LumiaFlashAppPhoneInfo Info = Model.ReadPhoneInfo();
byte[] GPTChunk = Model.GetGptChunk(131072u);
GPT GPT = new(GPTChunk);
Partition UefiBSNV = GPT.GetPartition("UEFI_BS_NV");
@@ -719,7 +721,7 @@ namespace WPinternals
MaximumAttempts = (int)(((MaximumGapFill / FFU.ChunkSize) + 1) * 8);
}
byte[] GPTChunk = ((LumiaFlashAppModel)Notifier.CurrentModel).GetGptChunk((UInt32)FFU.ChunkSize);
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, (UInt32)FFU.ChunkSize);
// Start with a reset
if (DoResetFirst)
@@ -2012,7 +2014,7 @@ namespace WPinternals
// Use GetGptChunk() here instead of ReadGPT(), because ReadGPT() skips the first sector.
// We need the fist sector if we want to write back the GPT.
byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, 0x20000);
GPT GPT = new(GPTChunk);
Partition Target;
@@ -2405,7 +2407,7 @@ namespace WPinternals
// Use GetGptChunk() here instead of ReadGPT(), because ReadGPT() skips the first sector.
// We need the fist sector if we want to write back the GPT.
byte[] GPTChunk = FlashModel.GetGptChunk(0x20000);
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, 0x20000);
GPT GPT = new(GPTChunk);
Partition Target;
@@ -2956,9 +2958,11 @@ namespace WPinternals
}
else
{
FreeMemRange NewFreeRange = new();
NewFreeRange.Start = Allocation.TotalStart;
NewFreeRange.End = Allocation.TotalEnd;
FreeMemRange NewFreeRange = new()
{
Start = Allocation.TotalStart,
End = Allocation.TotalEnd
};
bool Added = false;
int i;
@@ -272,9 +272,10 @@ namespace WPinternals
// ==============================
// Header 2 start
StoreHeader store = new();
store.WriteDescriptorCount = (UInt32)payloads.Length;
StoreHeader store = new()
{
WriteDescriptorCount = (UInt32)payloads.Length
};
store.FinalTableIndex = (UInt32)payloads.Length - store.FinalTableCount;
store.PlatformId = Info.PlatformID;
@@ -283,7 +284,7 @@ namespace WPinternals
store.WriteDescriptorLength += payload.GetStoreHeaderSize();
}
byte[] GPTChunk = Model.GetGptChunk(0x20000);
byte[] GPTChunk = await LumiaUnlockBootloaderViewModel.GetGptChunkFromFlashOrBootMgr(Notifier, 0x20000);
GPT GPT = new(GPTChunk);
UInt64 PlatEnd = 0;
if (GPT.Partitions.Any(x => x.Name == "PLAT"))
+6 -4
View File
@@ -81,7 +81,7 @@ namespace WPinternals
internal void RestoreTask(string EFIESPPath, string MainOSPath, string DataPath)
{
new Thread(() =>
new Thread(async () =>
{
bool Result = true;
@@ -121,6 +121,8 @@ namespace WPinternals
ProgressUpdater Updater = Busy.ProgressUpdater;
ActivateSubContext(Busy);
GPT GPT = await LumiaUnlockBootloaderViewModel.ReadGPTFromFlashOrBootMgr(PhoneNotifier);
int i = 0;
if (Result)
{
@@ -130,7 +132,7 @@ namespace WPinternals
{
i++;
Busy.Message = "Restoring partition EFIESP (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
Phone.FlashRawPartition(EFIESPPath, "EFIESP", Updater);
Phone.FlashRawPartition(GPT, EFIESPPath, "EFIESP", Updater);
}
}
catch (Exception Ex)
@@ -148,7 +150,7 @@ namespace WPinternals
{
i++;
Busy.Message = "Restoring partition MainOS (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
Phone.FlashRawPartition(EFIESPPath, "MainOS", Updater);
Phone.FlashRawPartition(GPT, EFIESPPath, "MainOS", Updater);
}
}
catch (Exception Ex)
@@ -166,7 +168,7 @@ namespace WPinternals
{
i++;
Busy.Message = "Restoring partition Data (" + i.ToString() + "/" + PartitionCount.ToString() + ")";
Phone.FlashRawPartition(EFIESPPath, "Data", Updater);
Phone.FlashRawPartition(GPT, EFIESPPath, "Data", Updater);
}
}
catch (Exception Ex)
+290 -259
View File
@@ -240,8 +240,6 @@ namespace WPinternals
{
IsSwitching = true;
byte[] RebootCommandResult;
bool ModernFlashApp;
// Make switch and set message or navigate to error
@@ -338,7 +336,7 @@ namespace WPinternals
break;
case PhoneInterfaces.Lumia_Bootloader:
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).ResetPhone();
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ResetPhone();
ModeSwitchProgressWrapper("Rebooting phone to Bootloader mode...", null);
LogFile.Log("Rebooting phone to Bootloader mode", LogType.FileAndConsole);
break;
@@ -664,7 +662,6 @@ namespace WPinternals
}
else if ((CurrentMode == PhoneInterfaces.Lumia_Flash) && (TargetMode == PhoneInterfaces.Qualcomm_Download))
{
byte[] RebootCommand = [0x4E, 0x4F, 0x4B, 0x52];
IsSwitchingInterface = true;
LogFile.Log("Sending command for rebooting to Emergency Download mode");
try
@@ -884,65 +881,73 @@ namespace WPinternals
});
}
private void ENOSWDownloadCompleted(string[] URLs, object State)
public void BootMMOS(string MMOSPath)
{
string Firmware = (string)State;
string ENOSWFileUrl = URLs[0];
string Name = DownloadsViewModel.GetFileNameFromURL(ENOSWFileUrl);
string TempFolder = $@"{Environment.GetEnvironmentVariable("TEMP")}\WPInternals";
ModeSwitchProgressWrapper("Initializing Flash...", null);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo();
Task.Run(() =>
{
ModeSwitchProgressWrapper("Initializing Flash...", null);
FileInfo info = new(MMOSPath);
uint length = uint.Parse(info.Length.ToString());
string MMOSPath = Path.Combine(TempFolder, Name);
int maximumBufferSize = (int)Info.WriteBufferSize;
App.Config.AddSecWimToRepository(MMOSPath, Firmware);
uint chunkCount = (uint)Math.Truncate((decimal)length / maximumBufferSize);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
UIContext?.Post(d => SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100), null);
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo();
ProgressUpdater progressUpdater = new(chunkCount + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i));
FileInfo info = new(MMOSPath);
uint length = uint.Parse(info.Length.ToString());
FlashModel.FlashMMOS(MMOSPath, progressUpdater);
int maximumBufferSize = (int)Info.WriteBufferSize;
uint chunkCount = (uint)Math.Truncate((decimal)length / maximumBufferSize);
UIContext?.Post(d => SetWorkingStatus("Flashing Test Mode package...", MaxProgressValue: 100), null);
ProgressUpdater progressUpdater = new(chunkCount + 1, (int i, TimeSpan? time) => UpdateWorkingStatus(null, CurrentProgressValue: (ulong)i));
FlashModel.FlashMMOS(MMOSPath, progressUpdater);
ModeSwitchProgressWrapper("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.");
});
ModeSwitchProgressWrapper("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.");
}
private void SwitchFromPhoneInfoToMassStorageMode(bool Continuation = false)
{
string ProgressText = Continuation ? "And now rebooting phone to Mass Storage mode..." : "Rebooting phone to Mass Storage mode...";
bool ModernFlashApp = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
if (ModernFlashApp)
{
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
}
else
{
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ContinueBoot();
}
new Thread(async () =>
{
bool ModernFlashApp = ((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ReadPhoneInfo().PhoneInfoAppVersionMajor >= 2;
if (ModernFlashApp)
{
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
}
else
{
((LumiaPhoneInfoAppModel)PhoneNotifier.CurrentModel).ContinueBoot();
}
await PhoneNotifier.WaitForArrival();
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
bool IsModernFlashApp = false;
switch (CurrentMode)
{
case PhoneInterfaces.Lumia_Flash:
{
LumiaFlashAppModel _FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
LumiaFlashAppPhoneInfo _Info = _FlashModel.ReadPhoneInfo(ExtendedInfo: false);
IsModernFlashApp = _Info.FlashAppProtocolVersionMajor >= 2;
break;
}
case PhoneInterfaces.Lumia_Bootloader:
{
LumiaBootManagerAppModel _FlashModel = (LumiaBootManagerAppModel)PhoneNotifier.CurrentModel;
LumiaBootManagerPhoneInfo _Info = _FlashModel.ReadPhoneInfo(ExtendedInfo: false);
IsModernFlashApp = _Info.BootManagerProtocolVersionMajor >= 2;
break;
}
}
MassStorageWarning = null;
if (Info.FlashAppProtocolVersionMajor < 2)
if (!IsModernFlashApp)
{
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.";
}
@@ -955,17 +960,36 @@ namespace WPinternals
}
}
bool IsOldLumia = Info.FlashAppProtocolVersionMajor < 2;
bool IsNewLumia = Info.FlashAppProtocolVersionMajor >= 2;
bool IsUnlockedNew = false;
if (IsNewLumia)
GPT GPT = null;
if (IsModernFlashApp)
{
GPT GPT = FlashModel.ReadGPT();
GPT = await ReadGPTFromFlashOrBootMgr();
IsUnlockedNew = (GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null) || (GPT.GetPartition("BACKUP_BS_NV") != null);
}
if (CurrentMode == PhoneInterfaces.Lumia_Bootloader)
{
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
await PhoneNotifier.WaitForArrival();
}
}
if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
{
throw new WPinternalsException("Unexpected Mode");
}
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
bool IsOriginalEngineeringLumia = !Info.IsBootloaderSecure && !IsUnlockedNew;
if (IsOldLumia || IsOriginalEngineeringLumia)
if (!IsModernFlashApp || IsOriginalEngineeringLumia)
{
IsSwitchingInterface = true;
try
@@ -996,212 +1020,6 @@ namespace WPinternals
}
}
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);
System.Reflection.Assembly 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 (Stream stream = assembly.GetManifestResourceStream("WPinternals.SBMSM"))
{
using DecompressedStream dec = new(stream);
using MemoryStream SB = new(); // 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 = [];
FlashPart Part = new();
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.");
}
}).Start();
}
private void SwitchFromFlashToMassStorageMode(bool Continuation = false)
{
string ProgressText = Continuation ? "And now rebooting phone to Mass Storage mode..." : "Rebooting phone to Mass Storage mode...";
if (CurrentMode == PhoneInterfaces.Lumia_Bootloader)
{
try
{
((LumiaBootManagerAppModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();
}
catch (Exception ex)
{
LogFile.LogException(ex, LogType.FileOnly);
}
}
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
LumiaFlashAppPhoneInfo 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) || (GPT.GetPartition("BACKUP_BS_NV") != null);
}
bool IsOriginalEngineeringLumia = !Info.IsBootloaderSecure && !IsUnlockedNew;
if (IsOldLumia || IsOriginalEngineeringLumia)
{
IsSwitchingInterface = true;
try
{
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ResetToMassStorageMode();
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
LogFile.Log("Rebooting phone to Mass Storage mode");
}
catch (NotSupportedException) // This means fail: NOKU (unknown command)
{
try
{
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).WriteParam("UBF", [(byte)'M']);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ResetPhone();
ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
LogFile.Log("Rebooting phone to Mass Storage mode");
}
catch (NotSupportedException)
{
ModeSwitchErrorWrapper("Failed to switch to Mass Storage mode");
IsSwitchingInterface = false;
}
}
}
else if (IsUnlockedNew)
{
new Thread(async () =>
{
LogFile.BeginAction("SwitchToMassStorageMode");
@@ -1228,15 +1046,16 @@ namespace WPinternals
// 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 = [];
FlashPart Part = new();
Part.StartSector = (uint)Target.FirstSector;
Part.Stream = SB;
FlashPart Part = new()
{
StartSector = (uint)Target.FirstSector,
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) =>
@@ -1324,12 +1143,224 @@ namespace WPinternals
}
LogFile.EndAction("SwitchToMassStorageMode");
}).Start();
}
else
{
ModeSwitchErrorWrapper("Bootloader was not unlocked. First unlock bootloader before you try to switch to Mass Storage Mode.");
}
}).Start();
}
/// <summary>
/// This function reads GPT from the device, while preserving the current application running.
/// This works whenever the device is unlocked or not, from Flash or Bootloader apps
/// </summary>
/// <returns></returns>
/// <exception cref="WPinternalsException">The device entered an unexpected mode.</exception>
private async Task<GPT> ReadGPTFromFlashOrBootMgr()
{
return await LumiaUnlockBootloaderViewModel.ReadGPTFromFlashOrBootMgr(PhoneNotifier);
}
private void SwitchFromFlashToMassStorageMode(bool Continuation = false)
{
string ProgressText = Continuation ? "And now rebooting phone to Mass Storage mode..." : "Rebooting phone to Mass Storage mode...";
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
bool IsModernFlashApp = Info.FlashAppProtocolVersionMajor >= 2;
MassStorageWarning = null;
if (!IsModernFlashApp)
{
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
{
ModeSwitchErrorWrapper("Bootloader was not unlocked. First unlock bootloader before you try to switch to Mass Storage Mode.");
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.";
}
}
new Thread(async () =>
{
bool IsUnlockedNew = false;
GPT GPT = null;
if (IsModernFlashApp)
{
GPT = await ReadGPTFromFlashOrBootMgr();
IsUnlockedNew = (GPT.GetPartition("IS_UNLOCKED") != null) || (GPT.GetPartition("BACKUP_EFIESP") != null) || (GPT.GetPartition("BACKUP_BS_NV") != null);
}
LumiaFlashAppModel FlashModel = (LumiaFlashAppModel)PhoneNotifier.CurrentModel;
LumiaFlashAppPhoneInfo Info = FlashModel.ReadPhoneInfo(ExtendedInfo: false);
bool IsOriginalEngineeringLumia = !Info.IsBootloaderSecure && !IsUnlockedNew;
if (!IsModernFlashApp || IsOriginalEngineeringLumia)
{
IsSwitchingInterface = true;
try
{
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ResetToMassStorageMode();
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
LogFile.Log("Rebooting phone to Mass Storage mode");
}
catch (NotSupportedException) // This means fail: NOKU (unknown command)
{
try
{
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).WriteParam("UBF", [(byte)'M']);
PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
((LumiaFlashAppModel)PhoneNotifier.CurrentModel).ResetPhone();
ModeSwitchProgressWrapper(ProgressText, MassStorageWarning);
LogFile.Log("Rebooting phone to Mass Storage mode");
}
catch (NotSupportedException)
{
ModeSwitchErrorWrapper("Failed to switch to Mass Storage mode");
IsSwitchingInterface = false;
}
}
}
else if (IsUnlockedNew)
{
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);
System.Reflection.Assembly 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 (Stream stream = assembly.GetManifestResourceStream("WPinternals.SBMSM"))
{
using DecompressedStream dec = new(stream);
using MemoryStream SB = new(); // 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.
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 = [];
FlashPart Part = new()
{
StartSector = (uint)Target.FirstSector,
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");
}
else
{
ModeSwitchErrorWrapper("Bootloader was not unlocked. First unlock bootloader before you try to switch to Mass Storage Mode.");
}
}).Start();
}
internal async static Task<IDisposable> SwitchTo(PhoneNotifierViewModel Notifier, PhoneInterfaces? TargetMode, string RequestedVolumeForMassStorage = "MainOS")
@@ -167,13 +167,15 @@ namespace MadWizard.WinUSBNet.API
}
private static DeviceDetails GetDeviceDetails(string devicePath, IntPtr deviceInfoSet, SP_DEVINFO_DATA deviceInfoData)
{
DeviceDetails details = new();
details.DevicePath = devicePath;
details.DeviceDescription = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_DEVICEDESC);
details.Manufacturer = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_MFG);
DeviceDetails details = new()
{
DevicePath = devicePath,
DeviceDescription = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_DEVICEDESC),
Manufacturer = GetStringProperty(deviceInfoSet, deviceInfoData, SPDRP.SPDRP_MFG),
// Heathcliff74
details.BusName = "";
// Heathcliff74
BusName = ""
};
try
{
details.BusName = GetStringProperty(deviceInfoSet, deviceInfoData, new DEVPROPKEY(new Guid(0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2), 4));
+12 -7
View File
@@ -341,9 +341,10 @@ namespace MadWizard.WinUSBNet.API
public void ReadPipeOverlapped(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToRead, USBAsyncResult result)
{
Overlapped overlapped = new();
overlapped.AsyncResult = result;
Overlapped overlapped = new()
{
AsyncResult = result
};
unsafe
{
@@ -364,8 +365,10 @@ namespace MadWizard.WinUSBNet.API
public void WriteOverlapped(int ifaceIndex, byte pipeID, byte[] buffer, int offset, int bytesToWrite, USBAsyncResult result)
{
Overlapped overlapped = new();
overlapped.AsyncResult = result;
Overlapped overlapped = new()
{
AsyncResult = result
};
unsafe
{
@@ -396,8 +399,10 @@ namespace MadWizard.WinUSBNet.API
setupPacket.Index = index;
setupPacket.Length = length;
Overlapped overlapped = new();
overlapped.AsyncResult = result;
Overlapped overlapped = new()
{
AsyncResult = result
};
unsafe
{