Improvements

This commit is contained in:
Gustave Monce
2023-08-28 17:46:56 +02:00
parent 4612c324f3
commit 227bc44a75
5 changed files with 118 additions and 20 deletions
+82 -11
View File
@@ -9,6 +9,8 @@ namespace Ffu2Vhdx
{
static void Main(string[] args)
{
Console.WriteLine("\nFFU Image To VHDx(s) tool\nVersion: 1.0.0.0\n");
if (args.Length != 2)
{
Console.WriteLine("Usage: Ffu2Vhdx <Path to FFU File> <Output director for LUNi.vhdx files>");
@@ -33,6 +35,69 @@ namespace Ffu2Vhdx
ConvertFFU2VHD(FfuPath, OutputDirectory);
}
private readonly static Guid EmmcUserPartitionGuid = new("B615F1F5-5088-43CD-809C-A16E52487D00");
private readonly static Guid EmmcBootPartition1Guid = new("12C55B20-25D3-41C9-8E06-282D94C676AD");
private readonly static Guid EmmcBootPartition2Guid = new("6B76A6DB-0257-48A9-AA99-F6B1655F7B00");
private readonly static Guid EmmcRpmbPartitionGuid = new("C49551EA-D6BC-4966-9499-871E393133CD");
private readonly static Guid EmmcGppPartition1Guid = new("B9251EA5-3462-4807-86C6-8948B1B36163");
private readonly static Guid EmmcGppPartition2Guid = new("24F906CD-EE11-43E1-8427-DC7A36F4C059");
private readonly static Guid EmmcGppPartition3Guid = new("5A5709A9-AC40-4F72-8862-5B0104166E76");
private readonly static Guid EmmcGppPartition4Guid = new("A44E27C9-258E-406E-BF33-77F5F244C487");
private readonly static Guid SdRemovableGuid = new("D1531D41-3F80-4091-8D0A-541F59236D66");
private readonly static Guid UfsLU0Guid = new("860845C1-BE09-4355-8BC1-30D64FF8E63A");
private readonly static Guid UfsLU1Guid = new("8D90D477-39A3-4A38-AB9E-586FF69ED051");
private readonly static Guid UfsLU2Guid = new("EDF85868-87EC-4F77-9CDA-5F10DF2FE601");
private readonly static Guid UfsLU3Guid = new("1AE69024-8AEB-4DF8-BC98-0032DBDF5024");
private readonly static Guid UfsLU4Guid = new("D33F1985-F107-4A85-BE38-68DC7AD32CEA");
private readonly static Guid UfsLU5Guid = new("4BA1D05F-088E-483F-A97E-B19B9CCF59B0");
private readonly static Guid UfsLU6Guid = new("4ACF98F6-26FA-44D2-8132-282F2D19A4C5");
private readonly static Guid UfsLU7Guid = new("8598155F-34DE-415C-8B55-843E3322D36F");
private readonly static Guid UfsRPMBGuid = new("5397474E-F75D-44B3-8E57-D9324FCF6FE1");
private static Dictionary<Guid, string> guidNames = new Dictionary<Guid, string>()
{
{ EmmcUserPartitionGuid, "eMMC (User)" },
{ EmmcBootPartition1Guid, "eMMC (Boot 1)" },
{ EmmcBootPartition2Guid, "eMMC (Boot 2)" },
{ EmmcRpmbPartitionGuid, "eMMC (RPMB)" },
{ EmmcGppPartition1Guid, "eMMC (GPP 1)" },
{ EmmcGppPartition2Guid, "eMMC (GPP 2)" },
{ EmmcGppPartition3Guid, "eMMC (GPP 3)" },
{ EmmcGppPartition4Guid, "eMMC (GPP 4)" },
{ SdRemovableGuid, "SD Card (Removable)" },
{ UfsLU0Guid, "UFS (LUN 0)" },
{ UfsLU1Guid, "UFS (LUN 1)" },
{ UfsLU2Guid, "UFS (LUN 2)" },
{ UfsLU3Guid, "UFS (LUN 3)" },
{ UfsLU4Guid, "UFS (LUN 4)" },
{ UfsLU5Guid, "UFS (LUN 5)" },
{ UfsLU6Guid, "UFS (LUN 6)" },
{ UfsLU7Guid, "UFS (LUN 7)" },
{ UfsRPMBGuid, "UFS (RPMB)" },
};
private static string FormatDevicePath(string DevicePath)
{
if (DevicePath.Contains("VenHw("))
{
string DevicePathGuidBit = DevicePath.Split("(")[^1].Split(")")[0];
if (Guid.TryParse(DevicePathGuidBit, out Guid DevicePathGuid))
{
if (guidNames.TryGetValue(DevicePathGuid, out string FriendlyDesc))
{
return $"{DevicePath}: {FriendlyDesc}";
}
}
}
return DevicePath;
}
private static string ReplaceInvalidChars(string filename)
{
return string.Join("_", filename.Split(Path.GetInvalidFileNameChars()));
}
private static void ConvertFFU2VHD(string ffuPath, string outputDirectory)
{
DiscUtils.Setup.SetupHelper.RegisterAssembly(typeof(Disk).Assembly);
@@ -42,22 +107,28 @@ namespace Ffu2Vhdx
for (int i = 0; i < ffuFile.StoreCount; i++)
{
string vhdfile = Path.Combine(outputDirectory, $"LUN{i}.vhdx");
Console.WriteLine($"Dumping {vhdfile}...");
using FfuStoreStream store = ffuFile.OpenStore(i);
string friendlyDevicePath = FormatDevicePath(store.DevicePath);
string vhdfile = Path.Combine(outputDirectory, $"Store{i}_{ReplaceInvalidChars(store.DevicePath)}.vhdx");
Console.WriteLine($"Store: {i}");
Console.WriteLine($"Size: {store.Length}");
Console.WriteLine($"Device Path: {friendlyDevicePath}");
Console.WriteLine($"Destination: {vhdfile}");
long SectorSize = ffuFile.GetSectorSize(i);
long diskCapacity = (long)ffuFile.GetMinSectorCount(i) * ffuFile.GetSectorSize(i);
using Stream fs = new FileStream(vhdfile, FileMode.CreateNew, FileAccess.ReadWrite);
using VirtualDisk outDisk = Disk.InitializeDynamic(fs, Ownership.None, diskCapacity, logicalSectorSize: (int)ffuFile.GetSectorSize(i));
using Stream store = ffuFile.OpenStore(i);
using VirtualDisk outDisk = Disk.InitializeDynamic(fs, Ownership.None, store.Length, logicalSectorSize: (int)SectorSize);
StreamPump pump = new()
{
InputStream = store,
OutputStream = outDisk.Content,
SparseCopy = true,
SparseChunkSize = (int)ffuFile.GetSectorSize(i),
BufferSize = (int)ffuFile.GetSectorSize(i) * 1024
SparseChunkSize = (int)SectorSize,
BufferSize = (int)SectorSize * 1024
};
long totalBytes = store.Length;
@@ -67,10 +138,10 @@ namespace Ffu2Vhdx
Console.WriteLine($"Dumping Store {i}");
pump.Run();
Console.WriteLine();
store.Dispose();
Console.WriteLine("\n");
}
Console.WriteLine("The operation completed successfully.");
}
protected static void ShowProgress(ulong readBytes, ulong totalBytes, DateTime startTime)
+1 -1
View File
@@ -35,7 +35,7 @@ namespace FfuStream
payloadReader.WriteToStream(outputStream, storePayload, fullFlashUpdateStore.MinSectorCount, fullFlashUpdateStore.SectorSize);
}
public Stream OpenStore(int StoreIndex)
public FfuStoreStream OpenStore(int StoreIndex)
{
if (StoreIndex >= StoreCount || StoreIndex < 0)
{
+3 -1
View File
@@ -16,13 +16,15 @@ namespace FfuStream
this.storePayload = storePayload;
}
public string DevicePath => fullFlashUpdateStore.DevicePath;
public override bool CanRead => true;
public override bool CanSeek => true;
public override bool CanWrite => false;
public override long Length => fullFlashUpdateStore.MinSectorCount * fullFlashUpdateStore.SectorSize;
public override long Length => ((long)fullFlashUpdateStore.MinSectorCount * fullFlashUpdateStore.SectorSize);
public override long Position
{
+2 -2
View File
@@ -84,9 +84,9 @@ namespace Microsoft.WindowsPhone.Imaging
get; set;
}
private string DevicePath
public string DevicePath
{
get; set;
get; private set;
}
private bool OnlyAllocateDefinedGptEntries
+30 -5
View File
@@ -92,7 +92,7 @@ namespace Microsoft.WindowsPhone.Imaging
return end > begin;
}
private static void WriteDetour(long inputPosition, byte[] inputBuffer, int inputCount, long position, byte[] buffer, int offset, int count)
private static int WriteDetour(long inputPosition, byte[] inputBuffer, int inputCount, long position, byte[] buffer, int offset, int count)
{
long begin = Math.Max(inputPosition, position);
long end = Math.Min(inputPosition + inputCount, position + count);
@@ -105,7 +105,11 @@ namespace Microsoft.WindowsPhone.Imaging
using var strm = new MemoryStream(buffer);
strm.Seek(index, SeekOrigin.Begin);
strm.Write(inputBuffer, inputIndex, (int)(end - begin));
return (int)(end - begin);
}
return 0;
}
public void WriteToStream(StorePayload storePayload, ulong sectorCount, uint sectorSize, long position, byte[] buffer, int offset, int count)
@@ -121,10 +125,20 @@ namespace Microsoft.WindowsPhone.Imaging
_payloadStream.Position = payloadOffset.Offset;
int blocksRead = 0;
for (StorePayload.BlockPhase blockPhase = StorePayload.BlockPhase.Phase1; blockPhase != StorePayload.BlockPhase.Invalid; blockPhase++)
{
int readCount = 0;
foreach (DataBlockEntry dataBlockEntry in storePayload.GetPhaseEntries(blockPhase))
{
if (readCount == count)
{
blocksRead++;
continue;
}
bool blockMatches = false;
byte[] ibuffer = new byte[bytesPerBlock];
@@ -138,22 +152,33 @@ namespace Microsoft.WindowsPhone.Imaging
if (blockMatches)
{
WriteDetour(ioffset, ibuffer, (int)bytesPerBlock, position, buffer, offset, count);
readCount += WriteDetour(ioffset, ibuffer, (int)bytesPerBlock, position, buffer, offset, count);
if (readCount == count)
{
break;
}
}
else
{
blockMatches = WriteDetourOk(ioffset, (int)bytesPerBlock, position, count);
if (blockMatches)
{
_payloadStream.Position = payloadOffset.Offset + (bytesPerBlock * blocksRead);
_payloadStream.Read(ibuffer, 0, (int)bytesPerBlock);
WriteDetour(ioffset, ibuffer, (int)bytesPerBlock, position, buffer, offset, count);
blocksRead++;
readCount += WriteDetour(ioffset, ibuffer, (int)bytesPerBlock, position, buffer, offset, count);
if (readCount == count)
{
break;
}
}
}
}
if (!blockMatches)
{
_payloadStream.Seek((int)bytesPerBlock, SeekOrigin.Current);
blocksRead++;
}
}
}
@@ -206,4 +231,4 @@ namespace Microsoft.WindowsPhone.Imaging
}
}
}
}
}