Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
gus33000 committed Sep 22, 2024
1 parent 10dfbe8 commit 707d8a6
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 153 deletions.
195 changes: 54 additions & 141 deletions Img2Ffu.Library/Writer/FFUFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ namespace Img2Ffu.Writer
{
public static class FFUFactory
{
private static byte[] GenerateHashTable(MemoryStream FFUMetadataHeaderTempFileStream, IEnumerable<KeyValuePair<ByteArrayKey, BlockPayload>> BlockPayloads, uint BlockSize)
private static byte[] GenerateHashTable(
MemoryStream FFUMetadataHeaderTempFileStream,
IEnumerable<KeyValuePair<ByteArrayKey, BlockPayload>> BlockPayloads,
uint BlockSize)
{
_ = FFUMetadataHeaderTempFileStream.Seek(0, SeekOrigin.Begin);

Expand All @@ -20,6 +23,7 @@ private static byte[] GenerateHashTable(MemoryStream FFUMetadataHeaderTempFileSt
{
byte[] buffer = new byte[BlockSize];
_ = FFUMetadataHeaderTempFileStream.Read(buffer, 0, (int)BlockSize);

byte[] hash = SHA256.HashData(buffer);
binaryWriter.Write(hash, 0, hash.Length);
}
Expand All @@ -29,136 +33,14 @@ private static byte[] GenerateHashTable(MemoryStream FFUMetadataHeaderTempFileSt
binaryWriter.Write(payload.Key.Bytes, 0, payload.Key.Bytes.Length);
}

byte[] HashTableBuffer = new byte[HashTableStream.Length];
_ = HashTableStream.Seek(0, SeekOrigin.Begin);

byte[] HashTableBuffer = new byte[HashTableStream.Length];
HashTableStream.ReadExactly(HashTableBuffer, 0, HashTableBuffer.Length);

return HashTableBuffer;
}

/*
*: Device Targeting Infos is optional
**: Only available on V1_COMPRESSION FFU file formats
***: Only available on V2 FFU file formats
- Validation Descriptor is always of size 0
- While it is possible in the struct to specify more than one Block
for a BlockDataEntry it shall only be equal to 0
- The hash table contains every hash of every block in the FFU file
starting from the Image Header to the end
- When using V1_COMPRESSION FFU file format, BlockDataEntry contains
an extra entry of size 4 bytes
- Multiple locations for a block data entry only copies the block
to multiple places
+------------------------------+
| |
| Security Header |
| |
+------------------------------+
| |
| Security Catalog |
| |
+------------------------------+
| |
| Hash Table |
| |
+------------------------------+
| |
| (Block Size) Padding |
| |
+------------------------------+
| |
| Image Header |
| |
+------------------------------+
| * |
| Image Header Extended |
| DeviceTargetingInfoCount |
| |
+------------------------------+
| |
| Image Manifest |
| |
+------------------------------+
| * |
| DeviceTargetInfoLengths[0] |
| |
+------------------------------+
| * |
| DeviceTargetInfoStrings[0] |
| |
+------------------------------+
| * |
| . . . |
| |
+------------------------------+
| * |
| DeviceTargetInfoLengths[n] |
| |
+------------------------------+
| * |
| DeviceTargetInfoStrings[n] |
| |
+------------------------------+
| |
| (Block Size) Padding |
| |
+------------------------------+
| |
| Store Header[0] |
| |
+------------------------------+
| * * |
| CompressionAlgo[0] |
| |
+------------------------------+
| * * * |
| Store Header Ex[0] |
| |
+------------------------------+
| |
| Validation Descriptor[0] |
| |
+------------------------------+
| |
| Write Descriptors[0] |
|(BlockDataEntry+DiskLocations)|
+------------------------------+
| |
| (Block Size) Padding[0] |
| |
+------------------------------+
| * * * |
| . . . |
| |
+------------------------------+
| * * * |
| Store Header[n] |
| |
+------------------------------+
| * * * |
| Store Header Ex[n] |
| |
+------------------------------+
| * * * |
| Validation Descriptor[n] |
| |
+------------------------------+
| * * * |
| Write Descriptors[n] |
|(BlockDataEntry+DiskLocations)|
+------------------------------+
| * * * |
| (Block Size) Padding[n] |
| |
+------------------------------+
| |
| Data Blocks |
| |
+------------------------------+
*/

public static void GenerateFFU(
IEnumerable<InputForStore> InputsForStores,
string FFUFile,
Expand All @@ -177,6 +59,12 @@ public static void GenerateFFU(
return;
}

if (!Directory.Exists(Path.GetDirectoryName(Path.GetFullPath(FFUFile))))
{
Logging.Log("Directory to place the FFU file into does not exist!", ILoggingLevel.Error);
return;
}

Logging.Log($"Destination image: {FFUFile}");
Logging.Log($"Platform IDs: {string.Join("\nPlatform IDs: ", PlatformIDs)}");
Logging.Log($"Sector Size: {SectorSize}");
Expand All @@ -197,7 +85,14 @@ public static void GenerateFFU(
AntiTheftVersion = AntiTheftVersion
};

List<(uint MinSectorCount, List<GPT.Partition> partitions, byte[] StoreHeaderBuffer, byte[] WriteDescriptorBuffer, KeyValuePair<ByteArrayKey, BlockPayload>[] BlockPayloads, VirtualDisk? InputDisk)> StoreGenerationParameters = [];
List<(
uint MinSectorCount,
List<GPT.Partition> partitions,
byte[] StoreHeaderBuffer,
byte[] WriteDescriptorBuffer,
KeyValuePair<ByteArrayKey, BlockPayload>[] BlockPayloads,
VirtualDisk? InputDisk
)> StoreGenerationParameters = [];

ushort StoreIndex = 0;
ushort StoreCount = (ushort)InputsForStores.Count();
Expand All @@ -211,7 +106,14 @@ public static void GenerateFFU(
Logging.Log($"[Store #{StoreIndex}] Device Path: {inputForStore.DevicePath}");
Logging.Log($"[Store #{StoreIndex}] Is Fixed Disk Length: {inputForStore.IsFixedDiskLength}");

(uint MinSectorCount, List<GPT.Partition> partitions, byte[] StoreHeaderBuffer, byte[] WriteDescriptorBuffer, KeyValuePair<ByteArrayKey, BlockPayload>[] BlockPayloads, VirtualDisk? InputDisk) GeneratedStoreParameters = StoreFactory.GenerateStore(
(
uint MinSectorCount,
List<GPT.Partition> partitions,
byte[] StoreHeaderBuffer,
byte[] WriteDescriptorBuffer,
KeyValuePair<ByteArrayKey, BlockPayload>[] BlockPayloads,
VirtualDisk? InputDisk
) GeneratedStoreParameters = StoreFactory.GenerateStore(
inputForStore,
PlatformIDs,
SectorSize,
Expand Down Expand Up @@ -283,7 +185,14 @@ public static void GenerateFFU(
Logging.Log("Writing Padding...");
ChunkUtils.RoundUpToChunks(FFUMetadataHeaderStream, BlockSize);

foreach ((uint _, List<GPT.Partition> _, byte[] StoreHeaderBuffer, byte[] WriteDescriptorBuffer, KeyValuePair<ByteArrayKey, BlockPayload>[] _, VirtualDisk? _) in StoreGenerationParameters)
foreach ((
uint _,
List<GPT.Partition> _,
byte[] StoreHeaderBuffer,
byte[] WriteDescriptorBuffer,
KeyValuePair<ByteArrayKey, BlockPayload>[] _,
VirtualDisk? _
) in StoreGenerationParameters)
{
//
// Store Header[0]
Expand Down Expand Up @@ -319,8 +228,9 @@ public static void GenerateFFU(

byte[] SecurityHeaderBuffer = security.GetResultingBuffer(BlockSize);

byte[] FFUMetadataHeaderBuffer = new byte[FFUMetadataHeaderStream.Length];
_ = FFUMetadataHeaderStream.Seek(0, SeekOrigin.Begin);

byte[] FFUMetadataHeaderBuffer = new byte[FFUMetadataHeaderStream.Length];
_ = FFUMetadataHeaderStream.Read(FFUMetadataHeaderBuffer, 0, (int)FFUMetadataHeaderStream.Length);

Logging.Log("Opening FFU file for writing...");
Expand All @@ -330,7 +240,15 @@ public static void GenerateFFU(
StoreGenerationParameters.ForEach(x => x.InputDisk?.Dispose());
}

private static void WriteFFUFile(string FFUFile, byte[] SecurityHeaderBuffer, byte[] CatalogBuffer, byte[] HashTable, byte[] FFUMetadataHeaderBuffer, IEnumerable<KeyValuePair<ByteArrayKey, BlockPayload>> BlockPayloads, uint BlockSize, ILogging Logging)
private static void WriteFFUFile(
string FFUFile,
byte[] SecurityHeaderBuffer,
byte[] CatalogBuffer,
byte[] HashTable,
byte[] FFUMetadataHeaderBuffer,
IEnumerable<KeyValuePair<ByteArrayKey, BlockPayload>> BlockPayloads,
uint BlockSize,
ILogging Logging)
{
FileStream FFUFileStream = new(FFUFile, FileMode.CreateNew);

Expand Down Expand Up @@ -366,32 +284,27 @@ private static void WriteFFUFile(string FFUFile, byte[] SecurityHeaderBuffer, by
// Write Descriptors[0]
// (Block Size) Padding[0]
//
Logging.Log("Writing Image Header...");
Logging.Log("Writing Image Manifest...");
Logging.Log("Writing Padding...");
Logging.Log("Writing Store Header...");
Logging.Log("Writing Write Descriptors...");
Logging.Log("Writing Padding...");
Logging.Log("Writing FFU Metadata Header...");
FFUFileStream.Write(FFUMetadataHeaderBuffer, 0, FFUMetadataHeaderBuffer.Length);

DateTime startTime = DateTime.Now;

//
// Data Blocks
//
Logging.Log("Writing Data Blocks...");

DateTime startTime = DateTime.Now;
ulong totalBytes = (ulong)BlockPayloads.LongCount() * BlockSize;

for (ulong CurrentBlockIndex = 0; CurrentBlockIndex < (ulong)BlockPayloads.LongCount(); CurrentBlockIndex++)
{
BlockPayload BlockPayload = BlockPayloads.ElementAt((int)CurrentBlockIndex).Value;
byte[] BlockBuffer = BlockPayload.ReadBlock(BlockSize);

FFUFileStream.Write(BlockBuffer, 0, (int)BlockSize);

ulong totalBytes = (ulong)BlockPayloads.LongCount() * BlockSize;
ulong bytesRead = CurrentBlockIndex * BlockSize;
ulong sourcePosition = CurrentBlockIndex * BlockSize;

LoggingHelpers.ShowProgress(totalBytes, bytesRead, sourcePosition, startTime, Logging);
LoggingHelpers.ShowProgress(totalBytes, bytesRead, bytesRead, startTime, Logging);
}
Logging.Log("");

Expand Down
20 changes: 17 additions & 3 deletions Img2Ffu.Library/Writer/StoreFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ private static (Stream InputStream, VirtualDisk? InputDisk) OpenInput(string Inp
return (InputStream, InputDisk);
}

internal static (uint MinSectorCount, List<GPT.Partition> partitions, byte[] StoreHeaderBuffer, byte[] WriteDescriptorBuffer, KeyValuePair<ByteArrayKey, BlockPayload>[] BlockPayloads, VirtualDisk? InputDisk) GenerateStore(
internal static (
uint MinSectorCount,
List<GPT.Partition> partitions,
byte[] StoreHeaderBuffer,
byte[] WriteDescriptorBuffer,
KeyValuePair<ByteArrayKey, BlockPayload>[] BlockPayloads,
VirtualDisk? InputDisk
) GenerateStore(
InputForStore InputForStore,
string[] PlatformIDs,
uint SectorSize,
Expand All @@ -75,10 +82,17 @@ internal static (uint MinSectorCount, List<GPT.Partition> partitions, byte[] Sto
(Stream InputStream, VirtualDisk? InputDisk) = OpenInput(InputForStore.InputFile, Logging);

Logging.Log("Generating Image Slices...");
(FlashPart[] flashParts, List<GPT.Partition> partitions) = ImageSplitter.GetImageSlices(InputStream, BlockSize, InputForStore.ExcludedPartitionNames, SectorSize, Logging);
(FlashPart[] flashParts, List<GPT.Partition> partitions) = ImageSplitter.GetImageSlices(InputStream,
BlockSize,
InputForStore.ExcludedPartitionNames,
SectorSize,
Logging);

Logging.Log("Generating Block Payloads...");
KeyValuePair<ByteArrayKey, BlockPayload>[] BlockPayloads = BlockPayloadsGenerator.GetOptimizedPayloads(flashParts, BlockSize, InputForStore.MaximumNumberOfBlankBlocksAllowed, Logging);
KeyValuePair<ByteArrayKey, BlockPayload>[] BlockPayloads = BlockPayloadsGenerator.GetOptimizedPayloads(flashParts,
BlockSize,
InputForStore.MaximumNumberOfBlankBlocksAllowed,
Logging);

BlockPayloads = BlockPayloadsGenerator.GetGPTPayloads(BlockPayloads, InputStream, BlockSize, InputForStore.IsFixedDiskLength);

Expand Down
Binary file added docs/Windows Manufacturing Documentation 2019.pdf
Binary file not shown.
Loading

0 comments on commit 707d8a6

Please sign in to comment.