Cleanup Sahara Implementation

This commit is contained in:
Gustave Monce
2023-11-26 18:08:50 +01:00
parent dc6085f185
commit 88efc77887
13 changed files with 142 additions and 138 deletions
@@ -68,7 +68,7 @@ namespace DiscUtils.Internal
result.Add(func(sVal));
}
return result.ToArray();
return [.. result];
}
/// <summary>
@@ -36,7 +36,7 @@ namespace DiscUtils.Fat
return [new VfsFileSystemInfo("FAT", "Microsoft FAT", Open)];
}
return System.Array.Empty<FileSystemInfo>();
return [];
}
private DiscFileSystem Open(Stream stream, VolumeInfo volumeInfo, FileSystemParameters parameters)
@@ -201,7 +201,7 @@ namespace DiscUtils.Fat
}
}
return dirs.ToArray();
return [.. dirs];
}
public DirectoryEntry[] GetFiles()
@@ -215,7 +215,7 @@ namespace DiscUtils.Fat
}
}
return files.ToArray();
return [.. files];
}
public DirectoryEntry GetEntry(long id)
@@ -1258,7 +1258,7 @@ namespace DiscUtils.Fat
dirs.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
}
return dirs.ToArray();
return [.. dirs];
}
/// <summary>
@@ -1275,7 +1275,7 @@ namespace DiscUtils.Fat
List<string> dirs = new();
DoSearch(dirs, path, re, searchOption == SearchOption.AllDirectories, true, false);
return dirs.ToArray();
return [.. dirs];
}
/// <summary>
@@ -1294,7 +1294,7 @@ namespace DiscUtils.Fat
files.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
}
return files.ToArray();
return [.. files];
}
/// <summary>
@@ -1311,7 +1311,7 @@ namespace DiscUtils.Fat
List<string> results = new();
DoSearch(results, path, re, searchOption == SearchOption.AllDirectories, false, true);
return results.ToArray();
return [.. results];
}
/// <summary>
@@ -1330,7 +1330,7 @@ namespace DiscUtils.Fat
result.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
}
return result.ToArray();
return [.. result];
}
/// <summary>
@@ -1356,7 +1356,7 @@ namespace DiscUtils.Fat
}
}
return result.ToArray();
return [.. result];
}
/// <summary>
+1 -1
View File
@@ -386,7 +386,7 @@ namespace WPinternals
Result.Add(Src);
}
return Result.ToArray();
return [.. Result];
}
}
+2 -2
View File
@@ -40,14 +40,14 @@ namespace WPinternals
internal PatchEngine(string PatchDefinitionsXmlString)
{
XmlSerializer x = new(PatchDefinitions.GetType(), null, Array.Empty<Type>(), new XmlRootAttribute("PatchDefinitions"), "");
XmlSerializer x = new(PatchDefinitions.GetType(), null, [], new XmlRootAttribute("PatchDefinitions"), "");
MemoryStream s = new(System.Text.Encoding.ASCII.GetBytes(PatchDefinitionsXmlString));
PatchDefinitions = (List<PatchDefinition>)x.Deserialize(s);
}
internal void WriteDefinitions(string FilePath)
{
XmlSerializer x = new(PatchDefinitions.GetType(), null, Array.Empty<Type>(), new XmlRootAttribute("PatchDefinitions"), "");
XmlSerializer x = new(PatchDefinitions.GetType(), null, [], new XmlRootAttribute("PatchDefinitions"), "");
XmlSerializerNamespaces ns = new();
ns.Add("", "");
+103 -105
View File
@@ -20,11 +20,13 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Documents;
namespace WPinternals
{
@@ -72,6 +74,94 @@ namespace WPinternals
this.Serial = Serial;
}
private static byte[] BuildCommandPacket(SaharaCommand SaharaCommand, byte[] CommandBuffer = null)
{
UInt32 CommandID = (uint)SaharaCommand;
UInt32 CommandBufferLength = 0;
if (CommandBuffer != null)
{
CommandBufferLength = (UInt32)CommandBuffer.Length;
}
UInt32 Length = 0x8u + CommandBufferLength;
byte[] Packet = new byte[Length];
ByteOperations.WriteUInt32(Packet, 0x00, CommandID);
ByteOperations.WriteUInt32(Packet, 0x04, Length);
if (CommandBuffer != null && CommandBufferLength != 0)
{
Buffer.BlockCopy(CommandBuffer, 0, Packet, 0x08, CommandBuffer.Length);
}
return Packet;
}
private static byte[] BuildHelloResponsePacket(SaharaMode SaharaMode, UInt32 ProtocolVersion = 2, UInt32 SupportedVersion = 1, UInt32 MaxPacketLength = 0 /* 0: Status OK */)
{
UInt32 Mode = (uint)SaharaMode;
// Hello packet:
// xxxxxxxx = Protocol version
// xxxxxxxx = Supported version
// xxxxxxxx = Max packet length
// xxxxxxxx = Expected mode
// 6 dwords reserved space
byte[] Hello = new byte[0x28];
ByteOperations.WriteUInt32(Hello, 0x00, ProtocolVersion);
ByteOperations.WriteUInt32(Hello, 0x04, SupportedVersion);
ByteOperations.WriteUInt32(Hello, 0x08, MaxPacketLength);
ByteOperations.WriteUInt32(Hello, 0x0C, Mode);
ByteOperations.WriteUInt32(Hello, 0x10, 0);
ByteOperations.WriteUInt32(Hello, 0x14, 0);
ByteOperations.WriteUInt32(Hello, 0x18, 0);
ByteOperations.WriteUInt32(Hello, 0x1C, 0);
ByteOperations.WriteUInt32(Hello, 0x20, 0);
ByteOperations.WriteUInt32(Hello, 0x24, 0);
return BuildCommandPacket(SaharaCommand.HelloResponse, Hello);
}
private static byte[] BuildExecuteRequestPacket(UInt32 RequestID)
{
byte[] Execute = new byte[0x04];
ByteOperations.WriteUInt32(Execute, 0x00, RequestID);
return BuildCommandPacket(SaharaCommand.ExecuteRequest, Execute);
}
private static byte[] BuildExecuteDataPacket(UInt32 RequestID)
{
byte[] Execute = new byte[0x04];
ByteOperations.WriteUInt32(Execute, 0x00, RequestID);
return BuildCommandPacket(SaharaCommand.ExecuteData, Execute);
}
private byte[][] GetRootKeyHashes()
{
Serial.SendData(BuildExecuteRequestPacket(0x3));
byte[] ReadDataRequest = Serial.GetResponse(null);
UInt32 ResponseID = ByteOperations.ReadUInt32(ReadDataRequest, 0);
if (ResponseID != 0xE)
{
throw new BadConnectionException();
}
uint RKHLength = ByteOperations.ReadUInt32(ReadDataRequest, 0x0C);
Serial.SendData(BuildExecuteDataPacket(0x3));
byte[] Response = Serial.GetResponse(null, Length: (int)RKHLength);
List<byte[]> RootKeyHashes = new();
for (int i = 0; i < RKHLength / 0x20; i++)
{
RootKeyHashes.Add(Response[(i * 0x20)..((i + 1) * 0x20)]);
}
return [.. RootKeyHashes];
}
public byte[] GetRKH()
{
int Step = 0;
@@ -96,30 +186,8 @@ namespace WPinternals
LogFile.Log("MaxLength: 0x" + ByteOperations.ReadUInt32(Hello, 0x10).ToString("X8"), LogType.FileOnly);
LogFile.Log("Mode: 0x" + ByteOperations.ReadUInt32(Hello, 0x14).ToString("X8"), LogType.FileOnly);
// Packet:
// 00000002 = Hello response command id
// 00000030 = Length
// 00000002 = Protocol version
// 00000001 = Supported version
// 00000000 = Status OK
// 00000003 = Mode
// rest is reserved space
Step = 2;
byte[] HelloResponse = [
0x02, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
];
byte[] HelloResponse = BuildHelloResponsePacket(SaharaMode.Command);
Serial.SendData(HelloResponse);
Step = 3;
@@ -132,36 +200,8 @@ namespace WPinternals
}
Step = 4;
Serial.SendData([
0x0D, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00
]);
Step = 5;
ReadDataRequest = Serial.GetResponse(null);
ResponseID = ByteOperations.ReadUInt32(ReadDataRequest, 0);
if (ResponseID != 0xE)
{
throw new BadConnectionException();
}
uint RKHLength = ByteOperations.ReadUInt32(ReadDataRequest, 0x0C);
Step = 6;
Serial.SendData([
0x0F, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00
]);
Step = 7;
byte[] Response = Serial.GetResponse(null, Length: (int)RKHLength);
byte[] Result = new byte[0x20];
Buffer.BlockCopy(Response, 3, Result, 0, 0x20);
return Result;
byte[][] RKHs = GetRootKeyHashes();
return RKHs[0];
}
catch (Exception Ex)
{
@@ -200,30 +240,8 @@ namespace WPinternals
LogFile.Log("MaxLength: 0x" + ByteOperations.ReadUInt32(Hello, 0x10).ToString("X8"), LogType.FileOnly);
LogFile.Log("Mode: 0x" + ByteOperations.ReadUInt32(Hello, 0x14).ToString("X8"), LogType.FileOnly);
// Packet:
// 00000002 = Hello response command id
// 00000030 = Length
// 00000002 = Protocol version
// 00000001 = Supported version
// 00000000 = Status OK
// 00000000 = Mode
// rest is reserved space
Step = 2;
byte[] HelloResponse = [
0x02, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
];
byte[] HelloResponse = BuildHelloResponsePacket(SaharaMode.ImageTransferPending);
Serial.SendData(HelloResponse);
Step = 3;
@@ -298,29 +316,7 @@ namespace WPinternals
LogFile.Log("MaxLength: 0x" + ByteOperations.ReadUInt32(Hello, 0x10).ToString("X8"), LogType.FileOnly);
LogFile.Log("Mode: 0x" + ByteOperations.ReadUInt32(Hello, 0x14).ToString("X8"), LogType.FileOnly);
// Packet:
// 00000002 = Hello response command id
// 00000030 = Length
// 00000002 = Protocol version
// 00000001 = Supported version
// 00000000 = Status OK
// 00000000 = Mode
// rest is reserved space
byte[] HelloResponse = [
0x02, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
];
byte[] HelloResponse = BuildHelloResponsePacket(SaharaMode.ImageTransferPending);
byte[] Ready = Serial.SendCommand(HelloResponse, [0x03, 0x00, 0x00, 0x00]);
}
@@ -334,7 +330,7 @@ namespace WPinternals
public void ResetSahara()
{
Serial.SendCommand([0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00], [0x08, 0x00, 0x00, 0x00]);
Serial.SendCommand(BuildCommandPacket(SaharaCommand.ResetRequest), [0x08, 0x00, 0x00, 0x00]);
}
public bool ConnectToProgrammer(byte[] PacketFromPcToProgrammer)
@@ -469,8 +465,10 @@ namespace WPinternals
public void SwitchMode(SaharaMode Mode)
{
byte[] SwitchModeCommand = [0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
ByteOperations.WriteUInt32(SwitchModeCommand, 8, (UInt32)Mode);
byte[] SwitchMode = new byte[0x04];
ByteOperations.WriteUInt32(SwitchMode, 0x00, (UInt32)Mode);
byte[] SwitchModeCommand = BuildCommandPacket(SaharaCommand.SwitchMode, SwitchMode);
byte[] ResponsePattern = null;
switch (Mode)
{
@@ -490,7 +488,7 @@ namespace WPinternals
public void StartProgrammer()
{
LogFile.Log("Starting programmer", LogType.FileAndConsole);
byte[] DoneCommand = [0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00];
byte[] DoneCommand = BuildCommandPacket(SaharaCommand.DoneRequest);
bool Started = false;
int count = 0;
do
@@ -584,7 +582,7 @@ namespace WPinternals
LogFile.Log(ProgrammerCommand, LogType.FileAndConsole);
byte[] PacketFromPcToProgrammer = Array.Empty<byte>();
byte[] PacketFromPcToProgrammer = [];
byte[] temp = new byte[0x200];
while (true)
@@ -603,7 +601,7 @@ namespace WPinternals
break;
}
PacketFromPcToProgrammer = PacketFromPcToProgrammer.Concat(temp).ToArray();
PacketFromPcToProgrammer = [.. PacketFromPcToProgrammer, .. temp];
}
bool ExpectingReplyFromProgrammer = false;
@@ -842,10 +842,13 @@ namespace WPinternals
//
// If you do not order payloads like this, you will get an error, most likely hash mismatch
//
FlashingPayload[] payloads = Array.Empty<FlashingPayload>();
FlashingPayload[] payloads = [];
if (FlashParts != null)
{
payloads = GetNonOptimizedPayloads(FlashParts, FFU.ChunkSize, (uint)(Info.WriteBufferSize / FFU.ChunkSize), SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Length).ToArray();
payloads =
[
.. GetNonOptimizedPayloads(FlashParts, FFU.ChunkSize, (uint)(Info.WriteBufferSize / FFU.ChunkSize), SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Length),
];
}
bool AssumeImageHeaderFallsInGap = true;
@@ -1834,7 +1837,7 @@ namespace WPinternals
List<FlashingPayload> flashingPayloads = new();
if (flashParts == null)
{
return flashingPayloads.ToArray();
return [.. flashingPayloads];
}
for (UInt32 j = 0; j < flashParts.Count; j++)
@@ -1853,7 +1856,7 @@ namespace WPinternals
}
}
return flashingPayloads.ToArray();
return [.. flashingPayloads];
}
//
@@ -1865,7 +1868,7 @@ namespace WPinternals
List<FlashingPayload> flashingPayloads = new();
if (flashParts == null)
{
return flashingPayloads.ToArray();
return [.. flashingPayloads];
}
long TotalProcess1 = 0;
@@ -1898,7 +1901,7 @@ namespace WPinternals
var payloadIndex = flashingPayloads.FindIndex(x => ByteOperations.Compare(x.ChunkHashes[0], hash));
var locationList = flashingPayloads[payloadIndex].TargetLocations.ToList();
locationList.Add((flashPart.StartSector * 0x200 / (UInt32)chunkSize) + i);
flashingPayloads[payloadIndex].TargetLocations = locationList.ToArray();
flashingPayloads[payloadIndex].TargetLocations = [.. locationList];
}
else
{
@@ -1910,7 +1913,7 @@ namespace WPinternals
}
}
return flashingPayloads.ToArray();
return [.. flashingPayloads];
}
internal static string GetProgrammerPath(byte[] RKH, string Type)
@@ -2262,7 +2265,7 @@ namespace WPinternals
}
}
Parts = Parts.OrderBy(p => p.StartSector).ToList();
Parts = [.. Parts.OrderBy(p => p.StartSector)];
int Count = 1;
Parts.Where(p => p.ProgressText?.StartsWith("Flashing partition ") == true).ToList().ForEach((p) =>
{
@@ -218,10 +218,13 @@ namespace WPinternals
//
// If you do not order payloads like this, you will get an error, most likely hash mismatch
//
LumiaV2UnlockBootViewModel.FlashingPayload[] payloads = Array.Empty<LumiaV2UnlockBootViewModel.FlashingPayload>();
LumiaV2UnlockBootViewModel.FlashingPayload[] payloads = [];
if (FlashParts != null)
{
payloads = LumiaV2UnlockBootViewModel.GetNonOptimizedPayloads(FlashParts, chunkSizes, Info.WriteBufferSize / chunkSize, SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Length).ToArray();
payloads =
[
.. LumiaV2UnlockBootViewModel.GetNonOptimizedPayloads(FlashParts, chunkSizes, Info.WriteBufferSize / chunkSize, SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Length),
];
}
MemoryStream Headerstream1 = new();
@@ -318,7 +318,7 @@ namespace MadWizard.WinUSBNet.API
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
}
return deviceList.ToArray();
return [.. deviceList];
}
public static void RegisterForDeviceNotifications(IntPtr controlHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)
+2 -2
View File
@@ -249,7 +249,7 @@ namespace MadWizard.WinUSBNet.API
throw APIException.Win32("Failed to get WinUSB device pipe information.");
}
}
pipes = pipeList.ToArray();
pipes = [.. pipeList];
}
private void InitializeDevice()
{
@@ -290,7 +290,7 @@ namespace MadWizard.WinUSBNet.API
// also in case of exception (which is why it is in finally block),
// because some handles might have already been opened and need
// to be disposed.
_addInterfaces = interfaces.ToArray();
_addInterfaces = [.. interfaces];
}
// Bind handle (needed for overlapped I/O thread pool)
+6 -6
View File
@@ -178,7 +178,7 @@ namespace MadWizard.WinUSBNet
USBPipeCollection pipeCollection = new(interfacePipes);
interfaces[i] = new USBInterface(this, i, descriptor, pipeCollection);
}
Pipes = new USBPipeCollection(allPipes.ToArray());
Pipes = new USBPipeCollection([.. allPipes]);
Interfaces = new USBInterfaceCollection(interfaces);
}
@@ -424,7 +424,7 @@ namespace MadWizard.WinUSBNet
public void ControlTransfer(byte requestType, byte request, int value, int index)
{
// TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin)
ControlTransfer(requestType, request, value, index, Array.Empty<byte>(), 0);
ControlTransfer(requestType, request, value, index, [], 0);
}
private void CheckIn(byte requestType)
@@ -518,7 +518,7 @@ namespace MadWizard.WinUSBNet
{
CheckIn(requestType);
// TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin)
ControlTransfer(requestType, request, value, index, Array.Empty<byte>());
ControlTransfer(requestType, request, value, index, []);
}
/// <summary>
@@ -566,7 +566,7 @@ namespace MadWizard.WinUSBNet
{
CheckOut(requestType);
// TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin)
ControlTransfer(requestType, request, value, index, Array.Empty<byte>());
ControlTransfer(requestType, request, value, index, []);
}
/// <summary>
@@ -591,7 +591,7 @@ namespace MadWizard.WinUSBNet
public IAsyncResult BeginControlTransfer(byte requestType, byte request, int value, int index, AsyncCallback userCallback, object stateObject)
{
// TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin)
return BeginControlTransfer(requestType, request, value, index, Array.Empty<byte>(), 0, userCallback, stateObject);
return BeginControlTransfer(requestType, request, value, index, [], 0, userCallback, stateObject);
}
/// <summary>
@@ -732,7 +732,7 @@ namespace MadWizard.WinUSBNet
{
CheckOut(requestType);
// TODO: null instead of empty buffer. But overlapped code would have to be fixed for this (no buffer to pin)
return BeginControlTransfer(requestType, request, value, index, Array.Empty<byte>(), userCallback, stateObject);
return BeginControlTransfer(requestType, request, value, index, [], userCallback, stateObject);
}
private void CheckNotDisposed()
@@ -116,7 +116,7 @@ namespace MadWizard.WinUSBNet
matchingInterfaces.Add(iface);
}
}
return matchingInterfaces.ToArray();
return [.. matchingInterfaces];
}
/// <summary>