2024-03-04 21:50:33 +01:00
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
|
|
|
|
namespace UnifiedFlashingPlatform
|
|
|
|
|
{
|
|
|
|
|
public partial class UnifiedFlashingPlatformTransport
|
|
|
|
|
{
|
2024-03-06 23:05:17 +01:00
|
|
|
public void FlashSectors(uint StartSector, byte[] Data, byte TargetDevice = 0, int Progress = 0)
|
2024-03-04 21:50:33 +01:00
|
|
|
{
|
|
|
|
|
// Start sector is in UInt32, so max size of eMMC is 2 TB.
|
|
|
|
|
|
|
|
|
|
byte[] Request = new byte[Data.Length + 0x40];
|
|
|
|
|
|
2024-03-04 23:24:28 +01:00
|
|
|
string Header = FlashSignature; // NOKF
|
2024-03-04 21:50:33 +01:00
|
|
|
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
2024-03-05 20:34:12 +01:00
|
|
|
Request[0x05] = TargetDevice; // Target device: 0: eMMC, 1: SDIO, 2: Other ???, 3: ???
|
2024-03-04 21:50:33 +01:00
|
|
|
Buffer.BlockCopy(BigEndian.GetBytes(StartSector, 4), 0, Request, 0x0B, 4); // Start sector
|
|
|
|
|
Buffer.BlockCopy(BigEndian.GetBytes(Data.Length / 0x200, 4), 0, Request, 0x0F, 4); // Sector count
|
|
|
|
|
Request[0x13] = (byte)Progress; // Progress (0 - 100)
|
2024-03-04 23:24:28 +01:00
|
|
|
Request[0x18] = 0; // Verify needed
|
|
|
|
|
Request[0x19] = 0; // Skip write
|
2024-03-04 21:50:33 +01:00
|
|
|
|
|
|
|
|
Buffer.BlockCopy(Data, 0, Request, 0x40, Data.Length);
|
|
|
|
|
|
2024-03-06 23:05:17 +01:00
|
|
|
_ = ExecuteRawMethod(Request);
|
2024-03-04 21:50:33 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-04 23:24:28 +01:00
|
|
|
public void Hello()
|
2024-03-04 21:50:33 +01:00
|
|
|
{
|
|
|
|
|
byte[] Request = new byte[4];
|
|
|
|
|
ByteOperations.WriteAsciiString(Request, 0, HelloSignature);
|
|
|
|
|
byte[] Response = ExecuteRawMethod(Request);
|
|
|
|
|
if (Response == null)
|
|
|
|
|
{
|
|
|
|
|
throw new BadConnectionException();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ByteOperations.ReadAsciiString(Response, 0, 4) != HelloSignature)
|
|
|
|
|
{
|
|
|
|
|
throw new WPinternalsException("Bad response from phone!", "The phone did not answer properly to the Hello message sent.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-04 23:24:28 +01:00
|
|
|
public void ResetPhone()
|
2024-03-04 21:50:33 +01:00
|
|
|
{
|
|
|
|
|
Debug.WriteLine("Rebooting phone");
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
byte[] Request = new byte[4];
|
|
|
|
|
ByteOperations.WriteAsciiString(Request, 0, RebootSignature);
|
|
|
|
|
ExecuteRawVoidMethod(Request);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("Sending reset-request failed");
|
|
|
|
|
Debug.WriteLine("Assuming automatic reset already in progress");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-04 23:24:28 +01:00
|
|
|
public GPT ReadGPT()
|
2024-03-04 21:50:33 +01:00
|
|
|
{
|
|
|
|
|
// 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.
|
|
|
|
|
|
|
|
|
|
// Only works in BootLoader-mode or on unlocked bootloaders in Flash-mode!!
|
|
|
|
|
|
|
|
|
|
/*PhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
|
|
|
|
|
FlashAppType OriginalAppType = Info.App;
|
|
|
|
|
bool Switch = (Info.App != FlashAppType.BootManager) && Info.IsBootloaderSecure;
|
|
|
|
|
if (Switch)
|
|
|
|
|
{
|
|
|
|
|
SwitchToBootManagerContext();
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
byte[] Request = new byte[0x04];
|
|
|
|
|
string Header = GetGPTSignature;
|
|
|
|
|
|
|
|
|
|
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
|
|
|
|
|
|
|
|
|
byte[] Buffer = ExecuteRawMethod(Request);
|
|
|
|
|
if ((Buffer == null) || (Buffer.Length < 0x4408))
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Unable to read GPT!");
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 23:05:17 +01:00
|
|
|
ushort Error = (ushort)((Buffer[6] << 8) + Buffer[7]);
|
2024-03-04 21:50:33 +01:00
|
|
|
if (Error > 0)
|
|
|
|
|
{
|
|
|
|
|
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 20:34:12 +01:00
|
|
|
// Length: 0x4400 for 512 (0x200) Sector Size (from sector 0 to sector 34)
|
|
|
|
|
// Length: 0x6000 for 4096 (0x1000) Sector Size (from sector 0 to sector 6)
|
|
|
|
|
|
2024-03-06 23:05:17 +01:00
|
|
|
uint ReturnedGPTBufferLength = (uint)Buffer.Length - 8;
|
|
|
|
|
uint SectorSize = Buffer.Length == 0x4408
|
|
|
|
|
? 512
|
|
|
|
|
: Buffer.Length == 0x6008
|
|
|
|
|
? (uint)4096
|
|
|
|
|
: throw new NotSupportedException("ReadGPT: Unsupported output size! 0x" + ReturnedGPTBufferLength.ToString("X4"));
|
2024-03-05 20:34:12 +01:00
|
|
|
|
|
|
|
|
byte[] GPTBuffer = new byte[ReturnedGPTBufferLength - SectorSize];
|
2024-03-06 23:05:17 +01:00
|
|
|
System.Buffer.BlockCopy(Buffer, 8 + (int)SectorSize, GPTBuffer, 0, (int)ReturnedGPTBufferLength - (int)SectorSize);
|
2024-03-04 21:50:33 +01:00
|
|
|
|
|
|
|
|
/*if (Switch)
|
|
|
|
|
{
|
|
|
|
|
if (OriginalAppType == FlashAppType.FlashApp)
|
|
|
|
|
{
|
|
|
|
|
SwitchToFlashAppContext();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SwitchToPhoneInfoAppContext();
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
|
2024-03-05 20:34:12 +01:00
|
|
|
return new GPT(GPTBuffer, SectorSize); // NOKT message header and MBR are ignored
|
2024-03-04 21:50:33 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-04 23:24:28 +01:00
|
|
|
public byte[] ReadPhoneInfo()
|
|
|
|
|
{
|
|
|
|
|
byte[] Request = new byte[4];
|
|
|
|
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature); // NOKV
|
|
|
|
|
byte[] Response = ExecuteRawMethod(Request);
|
2024-03-06 23:05:17 +01:00
|
|
|
return (Response == null) || (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
|
|
|
|
? throw new NotSupportedException()
|
|
|
|
|
: Response[5..];
|
2024-03-04 23:24:28 +01:00
|
|
|
}
|
2024-03-04 21:50:33 +01:00
|
|
|
|
|
|
|
|
public void Shutdown()
|
|
|
|
|
{
|
|
|
|
|
byte[] Request = new byte[4];
|
|
|
|
|
string Header = ShutdownSignature;
|
|
|
|
|
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
2024-03-04 23:24:28 +01:00
|
|
|
ExecuteRawVoidMethod(Request);
|
2024-03-04 21:50:33 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|