Cleanup project structure

This commit is contained in:
Gustave Monce
2024-09-22 10:43:30 +02:00
parent 3b1407f3a5
commit db91b1df5e
44 changed files with 77 additions and 825 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "img2ffu"]
path = img2ffu
url = https://github.com/WOA-Project/img2ffu
@@ -1,49 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader.Compression
{
internal class WindowsNativeCompression
{
[DllImport("ntdll.dll")]
private static extern uint RtlGetCompressionWorkSpaceSize(ushort CompressionFormatAndEngine, out uint CompressBufferWorkSpaceSize, out uint CompressFragmentWorkSpaceSize);
[DllImport("ntdll.dll")]
private static extern uint RtlDecompressBufferEx(ushort CompressionFormat, byte[] UncompressedBuffer, int UncompressedBufferSize, byte[] CompressedBuffer, int CompressedBufferSize, out int FinalUncompressedSize, byte[] WorkSpace);
[DllImport("ntdll.dll")]
private static extern uint RtlCompressBuffer(ushort CompressionFormatAndEngine, byte[] UncompressedBuffer, int UncompressedBufferSize, byte[] CompressedBuffer, int CompressedBufferSize, int UncompressedChunkSize, out int FinalCompressedSize, byte[] WorkSpace);
public static byte[] Decompress(WindowsNativeCompressionAlgorithm CompressionFormat, byte[] CompressedBuffer, int UncompressedBufferSize)
{
uint ntStatus = RtlGetCompressionWorkSpaceSize((ushort)CompressionFormat, out uint compressBufferWorkSpaceSize, out _);
if (ntStatus != 0)
{
throw new Exception($"Cannot get decompress workspace size! NTSTATUS=0x{ntStatus:X8}");
}
byte[] UncompressedBuffer = new byte[UncompressedBufferSize];
byte[] workSpace = new byte[compressBufferWorkSpaceSize];
ntStatus = RtlDecompressBufferEx((ushort)CompressionFormat, UncompressedBuffer, UncompressedBuffer.Length, CompressedBuffer, CompressedBuffer.Length, out _, workSpace);
return ntStatus != 0 ? throw new Exception($"Cannot decompress buffer! NTSTATUS=0x{ntStatus:X8}") : UncompressedBuffer;
}
public static byte[] Compress(WindowsNativeCompressionAlgorithm CompressionFormat, byte[] UncompressedBuffer, int CompressedBufferSize)
{
uint ntStatus = RtlGetCompressionWorkSpaceSize((ushort)CompressionFormat, out uint compressBufferWorkSpaceSize, out _);
if (ntStatus != 0)
{
throw new Exception($"Cannot get compression workspace size! NTSTATUS=0x{ntStatus:X8}");
}
byte[] CompressedBuffer = new byte[CompressedBufferSize];
byte[] workSpace = new byte[compressBufferWorkSpaceSize];
ntStatus = RtlCompressBuffer((ushort)CompressionFormat, UncompressedBuffer, UncompressedBuffer.Length, CompressedBuffer, CompressedBuffer.Length, 4096, out _, workSpace);
return ntStatus != 0 ? throw new Exception($"Cannot compress buffer! NTSTATUS=0x{ntStatus:X8}") : CompressedBuffer;
}
}
}
@@ -1,17 +0,0 @@
using System;
namespace Img2Ffu.Reader.Compression
{
[Flags]
public enum WindowsNativeCompressionAlgorithm
{
COMPRESSION_FORMAT_NONE = 0x0000,
COMPRESSION_ENGINE_STANDARD = 0x0000,
COMPRESSION_FORMAT_DEFAULT = 0x0001,
COMPRESSION_FORMAT_LZNT1 = 0x0002,
COMPRESSION_FORMAT_XPRESS = 0x0003,
COMPRESSION_FORMAT_XPRESS_HUFF = 0x0004,
COMPRESSION_ENGINE_MAXIMUM = 0x0100,
COMPRESSION_ENGINE_HIBER = 0x0200
}
}
-202
View File
@@ -1,202 +0,0 @@
using Img2Ffu.Reader.Compression;
using Img2Ffu.Reader.Enums;
using Img2Ffu.Reader.Structs;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Img2Ffu.Reader.Data
{
public class ImageFlash
{
public ImageHeader ImageHeader;
public string ManifestData = "";
public byte[] Padding = [];
public readonly List<Store> Stores = [];
private readonly long DataBlocksPosition;
private readonly long InitialStreamPosition;
public ImageFlash(Stream stream)
{
InitialStreamPosition = stream.Position;
ImageHeader = stream.ReadStructure<ImageHeader>();
if (ImageHeader.Signature != "ImageFlash ")
{
throw new InvalidDataException("Invalid Image Header Signature!");
}
byte[] manifestDataBuffer = new byte[ImageHeader.ManifestLength];
_ = stream.Read(manifestDataBuffer, 0, (int)ImageHeader.ManifestLength);
ASCIIEncoding asciiEncoding = new();
ManifestData = asciiEncoding.GetString(manifestDataBuffer);
long Position = stream.Position;
if (Position % (ImageHeader.ChunkSize * 1024) > 0)
{
long paddingSize = (ImageHeader.ChunkSize * 1024) - (Position % (ImageHeader.ChunkSize * 1024));
Padding = new byte[paddingSize];
_ = stream.Read(Padding, 0, (int)paddingSize);
}
Store store = new(stream);
Stores.Add(store);
if (store.StoreHeader.MajorVersion == 2 && store.StoreHeader.FullFlashMajorVersion == 2)
{
for (uint i = 2; i <= store.StoreHeaderV2.NumberOfStores; i++)
{
Stores.Add(new Store(stream));
}
}
DataBlocksPosition = stream.Position;
}
public ulong GetImageBlockCount()
{
ulong imageBlockCount = (ulong)(DataBlocksPosition - InitialStreamPosition) / (ImageHeader.ChunkSize * 1024);
ulong storeBlockCount = GetDataBlockCount();
return imageBlockCount + storeBlockCount;
}
public byte[] GetImageBlock(Stream Stream, ulong dataBlockIndex)
{
ulong imageBlockCount = (ulong)(DataBlocksPosition - InitialStreamPosition) / (ImageHeader.ChunkSize * 1024);
// The data block is within the image headers
if (dataBlockIndex < imageBlockCount)
{
byte[] dataBlock = new byte[(ImageHeader.ChunkSize * 1024)];
ulong dataBlockPosition = (ulong)InitialStreamPosition + (dataBlockIndex * (ImageHeader.ChunkSize * 1024));
_ = Stream.Seek((long)dataBlockPosition, SeekOrigin.Begin);
_ = Stream.Read(dataBlock, 0, dataBlock.Length);
return dataBlock;
}
// The data block is within the store data blocks, those may be compressed
else
{
return GetDataBlock(Stream, dataBlockIndex - imageBlockCount);
}
}
public ulong GetDataBlockCount()
{
ulong dataBlockCount = 0;
foreach (Store store in Stores)
{
dataBlockCount += (ulong)store.WriteDescriptors.LongCount();
}
return dataBlockCount;
}
public byte[] GetDataBlock(Stream Stream, ulong dataBlockIndex)
{
ulong dataBlockIndexOffset = 0;
for (ulong storeIndex = 0; storeIndex < (ulong)Stores.Count; storeIndex++)
{
ulong storeDataBlockCount = GetStoreDataBlockCount(storeIndex);
if (dataBlockIndexOffset + storeDataBlockCount > dataBlockIndex)
{
return GetStoreDataBlock(Stream, storeIndex, dataBlockIndex - dataBlockIndexOffset);
}
dataBlockIndexOffset += storeDataBlockCount;
}
throw new Exception("Invalid data block index value");
}
public ulong GetStoreDataBlockCount(ulong storeIndex)
{
return (ulong)Stores[(int)storeIndex].WriteDescriptors.LongCount();
}
public byte[] GetStoreDataBlock(Stream Stream, ulong storeIndex, ulong dataBlockIndex)
{
ulong dataBlockPosition = (ulong)DataBlocksPosition;
for (ulong s = 0; s < storeIndex; s++)
{
Store store = Stores[(int)s];
if (store.CompressionAlgorithm != 0)
{
foreach (WriteDescriptor writeDescriptor in store.WriteDescriptors)
{
dataBlockPosition += writeDescriptor.DataSize;
}
}
else
{
dataBlockPosition += store.StoreHeader.WriteDescriptorCount * store.StoreHeader.BlockSize;
}
}
Store currentStore = Stores[(int)storeIndex];
byte[] dataBlock = new byte[currentStore.StoreHeader.BlockSize];
CompressionAlgorithm compressionAlgorithm = (CompressionAlgorithm)currentStore.CompressionAlgorithm;
if (compressionAlgorithm != CompressionAlgorithm.None)
{
for (ulong i = 0; i < dataBlockIndex; i++)
{
WriteDescriptor writeDescriptor = currentStore.WriteDescriptors[(int)i];
dataBlockPosition += writeDescriptor.DataSize;
}
WriteDescriptor currentWriteDescriptor = currentStore.WriteDescriptors[(int)dataBlockIndex];
uint compressedDataBlockSize = currentWriteDescriptor.DataSize;
byte[] compressedDataBlock = new byte[compressedDataBlockSize];
_ = Stream.Seek((long)dataBlockPosition, SeekOrigin.Begin);
_ = Stream.Read(compressedDataBlock, 0, compressedDataBlock.Length);
switch ((CompressionAlgorithm)currentStore.CompressionAlgorithm)
{
case CompressionAlgorithm.Default:
{
dataBlock = WindowsNativeCompression.Decompress(WindowsNativeCompressionAlgorithm.COMPRESSION_FORMAT_XPRESS, compressedDataBlock, (int)currentStore.StoreHeader.BlockSize);
break;
}
case CompressionAlgorithm.LZNT1:
{
dataBlock = WindowsNativeCompression.Decompress(WindowsNativeCompressionAlgorithm.COMPRESSION_FORMAT_LZNT1, compressedDataBlock, (int)currentStore.StoreHeader.BlockSize);
break;
}
case CompressionAlgorithm.XPRESS:
{
dataBlock = WindowsNativeCompression.Decompress(WindowsNativeCompressionAlgorithm.COMPRESSION_FORMAT_XPRESS, compressedDataBlock, (int)currentStore.StoreHeader.BlockSize);
break;
}
case CompressionAlgorithm.XPRESS_HUFF:
{
dataBlock = WindowsNativeCompression.Decompress(WindowsNativeCompressionAlgorithm.COMPRESSION_FORMAT_XPRESS_HUFF, compressedDataBlock, (int)currentStore.StoreHeader.BlockSize);
break;
}
default:
{
throw new NotImplementedException("The compression algorithm this data block uses is not currently implemented.");
}
}
}
else
{
dataBlockPosition += dataBlockIndex * currentStore.StoreHeader.BlockSize;
_ = Stream.Seek((long)dataBlockPosition, SeekOrigin.Begin);
_ = Stream.Read(dataBlock, 0, dataBlock.Length);
}
return dataBlock;
}
}
}
-132
View File
@@ -1,132 +0,0 @@
using Img2Ffu.Reader.Structs;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
namespace Img2Ffu.Reader.Data
{
public class SignedImage
{
public SecurityHeader SecurityHeader;
public byte[] Catalog;
public byte[] TableOfHashes;
public byte[] Padding = [];
public ImageFlash Image;
public ulong HeaderSize { get; }
public int ChunkSize => (int)(SecurityHeader.ChunkSizeInKB * 1024);
public ulong TotalChunkCount => Image.GetImageBlockCount();
public readonly List<byte[]> BlockHashes = [];
public X509Certificate? Certificate;
private readonly Stream Stream;
public SignedImage(Stream stream)
{
Stream = stream;
SecurityHeader = stream.ReadStructure<SecurityHeader>();
if (SecurityHeader.Signature != "SignedImage ")
{
throw new InvalidDataException("Invalid Security Header Signature!");
}
Catalog = new byte[SecurityHeader.CatalogSize];
_ = stream.Read(Catalog, 0, (int)SecurityHeader.CatalogSize);
TableOfHashes = new byte[SecurityHeader.HashTableSize];
_ = stream.Read(TableOfHashes, 0, (int)SecurityHeader.HashTableSize);
long Position = stream.Position;
uint sizeOfBlock = SecurityHeader.ChunkSizeInKB * 1024;
if (Position % sizeOfBlock > 0)
{
long paddingSize = sizeOfBlock - (Position % sizeOfBlock);
Padding = new byte[paddingSize];
_ = stream.Read(Padding, 0, (int)paddingSize);
}
try
{
Certificate = new X509Certificate(Catalog);
}
catch { }
Image = new ImageFlash(stream);
HeaderSize = (ulong)stream.Position;
ParseBlockHashes();
}
private void ParseBlockHashes()
{
BlockHashes.Clear();
ulong numberOfBlocksToVerify = Image.GetImageBlockCount();
ulong sizeOfHash = (ulong)TableOfHashes.LongLength / numberOfBlocksToVerify;
for (int i = 0; i < TableOfHashes.Length; i += (int)sizeOfHash)
{
BlockHashes.Add(TableOfHashes[i..(i + (int)sizeOfHash)]);
}
}
private uint GetImageHeaderPosition()
{
uint sizeOfBlock = SecurityHeader.ChunkSizeInKB * 1024;
uint ImageHeaderPosition = SecurityHeader.Size + SecurityHeader.CatalogSize + SecurityHeader.HashTableSize;
if (ImageHeaderPosition % sizeOfBlock > 0)
{
uint paddingSize = sizeOfBlock - (ImageHeaderPosition % sizeOfBlock);
ImageHeaderPosition += paddingSize;
}
return ImageHeaderPosition;
}
public void VerifyFFU()
{
ulong numberOfBlocksToVerify = Image.GetImageBlockCount();
long oldPosition = Stream.Position;
using BinaryReader binaryReader = new(Stream, Encoding.ASCII, true);
using BinaryReader hashTableBinaryReader = new(new MemoryStream(TableOfHashes));
for (ulong i = 0; i < numberOfBlocksToVerify; i++)
{
Console.Title = $"{i + 1}/{numberOfBlocksToVerify}";
if (SecurityHeader.AlgorithmId == 0x0000800c) // SHA256 Algorithm ID
{
byte[] block = Image.GetImageBlock(Stream, i);
byte[] hash = SHA256.HashData(block);
byte[] hashTableHash = BlockHashes.ElementAt((int)i);
if (!StructuralComparisons.StructuralEqualityComparer.Equals(hash, hashTableHash))
{
_ = Stream.Seek(oldPosition, SeekOrigin.Begin);
throw new InvalidDataException($"The FFU image contains a mismatched hash value at chunk {i}. " +
$"Expected: {BitConverter.ToString(hashTableHash).Replace("-", "")} " +
$"Computed: {BitConverter.ToString(hash).Replace("-", "")}");
}
}
else
{
throw new InvalidDataException($"Unknown Hash algorithm id: {SecurityHeader.AlgorithmId}");
}
}
Console.Title = $"{numberOfBlocksToVerify}/{numberOfBlocksToVerify}";
_ = Stream.Seek(oldPosition, SeekOrigin.Begin);
}
}
}
-95
View File
@@ -1,95 +0,0 @@
using Img2Ffu.Reader.Enums;
using Img2Ffu.Reader.Structs;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Img2Ffu.Reader.Data
{
public class Store
{
public StoreHeader StoreHeader;
public uint CompressionAlgorithm;
public StoreHeaderV2 StoreHeaderV2;
public string DevicePath = ""; // Device path has no NUL at then end (V2 only)
public readonly List<ValidationDescriptor> ValidationDescriptor = [];
public readonly List<WriteDescriptor> WriteDescriptors = [];
public readonly List<string> PlatformIDs = [];
public byte[] Padding = [];
public readonly FFUVersion FFUVersion;
public Store(Stream stream)
{
StoreHeader = stream.ReadStructure<StoreHeader>();
int lastFinding = 0;
for (int i = 0; i < StoreHeader.PlatformId.Length; i++)
{
if (StoreHeader.PlatformId[i] == '\0')
{
if (i == lastFinding)
{
break;
}
ASCIIEncoding asciiEnconding = new();
string PlatformID = asciiEnconding.GetString(StoreHeader.PlatformId[lastFinding..i]);
PlatformIDs.Add(PlatformID);
lastFinding = i + 1;
}
}
FFUVersion = GetFFUVersion();
switch (FFUVersion)
{
case FFUVersion.V2:
{
StoreHeaderV2 = stream.ReadStructure<StoreHeaderV2>();
byte[] stringBytes = new byte[StoreHeaderV2.DevicePathLength * 2];
_ = stream.Read(stringBytes, 0, stringBytes.Length);
UnicodeEncoding unicodeEncoding = new();
DevicePath = unicodeEncoding.GetString(stringBytes);
break;
}
case FFUVersion.V1_COMPRESSED:
{
using BinaryReader binaryReader = new(stream, Encoding.ASCII, true);
CompressionAlgorithm = binaryReader.ReadUInt32();
break;
}
}
for (uint i = 0; i < StoreHeader.ValidateDescriptorCount; i++)
{
ValidationDescriptor.Add(new ValidationDescriptor(stream));
}
for (uint i = 0; i < StoreHeader.WriteDescriptorCount; i++)
{
WriteDescriptors.Add(new WriteDescriptor(stream, FFUVersion));
}
long Position = stream.Position;
if (Position % StoreHeader.BlockSize > 0)
{
long paddingSize = StoreHeader.BlockSize - (Position % StoreHeader.BlockSize);
Padding = new byte[paddingSize];
_ = stream.Read(Padding, 0, (int)paddingSize);
}
}
public override string ToString()
{
return $"{{StoreHeader: {StoreHeader}, StoreHeaderV2: {StoreHeaderV2}, DevicePath: {DevicePath}}}";
}
private FFUVersion GetFFUVersion() => (StoreHeader.MajorVersion, StoreHeader.FullFlashMajorVersion) switch
{
(1, 2) => FFUVersion.V1,
(1, 3) => FFUVersion.V1_COMPRESSED,
(2, 2) => FFUVersion.V2,
_ => throw new InvalidDataException($"Unsupported FFU Store Format! MajorVersion: {StoreHeader.MajorVersion} FullFlashMajorVersion: {StoreHeader.FullFlashMajorVersion}"),
};
}
}
-44
View File
@@ -1,44 +0,0 @@
using Img2Ffu.Reader.Structs;
using System.Collections.Generic;
using System.IO;
namespace Img2Ffu.Reader.Data
{
public class ValidationDescriptor
{
public ValidationEntry ValidationEntry;
public byte[] ValidationBytes;
public ValidationDescriptor(Stream stream)
{
ValidationEntry = stream.ReadStructure<ValidationEntry>();
ValidationBytes = new byte[ValidationEntry.dwByteCount];
_ = stream.Read(ValidationBytes, 0, (int)ValidationEntry.dwByteCount);
}
public ValidationDescriptor(ValidationEntry validationEntry, byte[] validationBytes)
{
ValidationEntry = validationEntry;
ValidationBytes = validationBytes;
ValidationEntry.dwByteCount = (uint)validationBytes.LongLength;
}
public override string ToString()
{
return $"{{ValidationEntry: {ValidationEntry}}}";
}
public byte[] GetBytes()
{
List<byte> bytes = [];
ValidationEntry.dwByteCount = (uint)ValidationBytes.Length;
bytes.AddRange(ValidationEntry.GetBytes());
bytes.AddRange(ValidationBytes);
return [.. bytes];
}
}
}
-79
View File
@@ -1,79 +0,0 @@
using Img2Ffu.Reader.Enums;
using Img2Ffu.Reader.Structs;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Img2Ffu.Reader.Data
{
public class WriteDescriptor
{
public BlockDataEntry BlockDataEntry;
public uint DataSize;
public readonly List<DiskLocation> DiskLocations = [];
private readonly bool HasDataSizeField;
public WriteDescriptor(Stream stream, FFUVersion ffuVersion)
{
HasDataSizeField = ffuVersion == FFUVersion.V1_COMPRESSED;
BlockDataEntry = stream.ReadStructure<BlockDataEntry>();
if (HasDataSizeField)
{
using BinaryReader binaryReader = new(stream, Encoding.ASCII, true);
DataSize = binaryReader.ReadUInt32();
}
for (uint i = 0; i < BlockDataEntry.LocationCount; i++)
{
DiskLocations.Add(stream.ReadStructure<DiskLocation>());
}
}
public WriteDescriptor(BlockDataEntry blockDataEntry, List<DiskLocation> diskLocations, uint compressedDataBlockSize)
{
HasDataSizeField = true;
BlockDataEntry = blockDataEntry;
DiskLocations = diskLocations;
DataSize = compressedDataBlockSize;
}
public WriteDescriptor(BlockDataEntry blockDataEntry, List<DiskLocation> diskLocations, FFUVersion ffuVersion)
{
HasDataSizeField = false;
BlockDataEntry = blockDataEntry;
DiskLocations = diskLocations;
}
public override string ToString()
{
return $"{{BlockDataEntry: {BlockDataEntry}}}";
}
public byte[] GetBytes()
{
List<byte> bytes = [];
BlockDataEntry.LocationCount = (uint)DiskLocations.Count;
bytes.AddRange(BlockDataEntry.GetBytes());
if (HasDataSizeField)
{
bytes.AddRange(BitConverter.GetBytes(DataSize));
}
foreach (DiskLocation diskLocation in DiskLocations)
{
bytes.AddRange(diskLocation.GetBytes());
}
return [.. bytes];
}
}
}
-11
View File
@@ -1,11 +0,0 @@
namespace Img2Ffu.Reader.Enums
{
public enum CompressionAlgorithm
{
None = 0,
Default = 1,
LZNT1 = 2,
XPRESS = 3,
XPRESS_HUFF = 4
}
}
-8
View File
@@ -1,8 +0,0 @@
namespace Img2Ffu.Reader.Enums
{
public enum DiskAccessMethod
{
DISK_BEGIN = 0,
DISK_END = 2
}
}
-9
View File
@@ -1,9 +0,0 @@
namespace Img2Ffu.Reader.Enums
{
public enum FFUVersion
{
V1,
V1_COMPRESSED,
V2
}
}
-56
View File
@@ -1,56 +0,0 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader
{
public static class StructExtensions
{
public static T GetStruct<T>(this byte[] bytes) where T : struct
{
int requiredSize = Marshal.SizeOf(typeof(T));
if (bytes.Length < requiredSize)
{
throw new Exception($"Invalid buffer size for passed in structure. Expected: {requiredSize} Provided: {bytes.Length}");
}
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T structure = Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
handle.Free();
return structure;
}
public static byte[] GetBytes<T>(this T structure) where T : struct
{
byte[] bytes = new byte[Marshal.SizeOf(typeof(T))];
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
Marshal.StructureToPtr(structure, handle.AddrOfPinnedObject(), false);
handle.Free();
return bytes;
}
public static T Read<T>(this BinaryReader reader) where T : struct
{
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
return bytes.GetStruct<T>();
}
public static void Write<T>(this BinaryWriter writer, T structure) where T : struct
{
byte[] bytes = structure.GetBytes();
writer.Write(bytes);
}
public static T ReadStructure<T>(this Stream stream) where T : struct
{
using BinaryReader binaryReader = new(stream, System.Text.Encoding.ASCII, true);
return binaryReader.Read<T>();
}
public static void WriteStructure<T>(this Stream stream, T structure) where T : struct
{
using BinaryWriter binaryWriter = new(stream, System.Text.Encoding.ASCII, true);
binaryWriter.Write(structure);
}
}
}
-16
View File
@@ -1,16 +0,0 @@
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader.Structs
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BlockDataEntry
{
public uint LocationCount;
public uint BlockCount;
public override readonly string ToString()
{
return $"{{LocationCount: {LocationCount}, BlockCount: {BlockCount}}}";
}
}
}
-16
View File
@@ -1,16 +0,0 @@
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader.Structs
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DiskLocation
{
public uint DiskAccessMethod;
public uint BlockIndex;
public override readonly string ToString()
{
return $"{{DiskAccessMethod: {DiskAccessMethod}, BlockIndex: {BlockIndex}}}";
}
}
}
-14
View File
@@ -1,14 +0,0 @@
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader.Structs
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct ImageHeader
{
public uint Size; // sizeof(ImageHeader)
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public string Signature; // "ImageFlash "
public uint ManifestLength; // in bytes
public uint ChunkSize; // Used only during image generation.
}
}
-16
View File
@@ -1,16 +0,0 @@
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader.Structs
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct SecurityHeader
{
public uint Size; // size of struct, overall
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
public string Signature; // "SignedImage "
public uint ChunkSizeInKB; // size of a hashed chunk within the image
public uint AlgorithmId; // algorithm used to hash
public uint CatalogSize; // size of catalog to validate
public uint HashTableSize; // size of hash table
}
}
-30
View File
@@ -1,30 +0,0 @@
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader.Structs
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct StoreHeader
{
public uint UpdateType; // indicates partial or full flash
public ushort MajorVersion, MinorVersion; // used to validate struct
public ushort FullFlashMajorVersion, FullFlashMinorVersion; // FFU version, i.e. the image format
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 192)]
public byte[] PlatformId; // string which indicates what device this FFU is intended to be written to
public uint BlockSize; // size of an image block in bytes the devices actual sector size may differ
public uint WriteDescriptorCount; // number of write descriptors to iterate through
public uint WriteDescriptorLength; // total size of all the write descriptors, in bytes (included so they can be read out up front and interpreted later)
public uint ValidateDescriptorCount; // number of validation descriptors to check
public uint ValidateDescriptorLength; // total size of all the validation descriptors, in bytes
public uint InitialTableIndex; // block index in the payload of the initial (invalid) GPT
public uint InitialTableCount; // count of blocks for the initial GPT, i.e. the GPT spans blockArray[idx..(idx + count -1)]
public uint FlashOnlyTableIndex; // first block index in the payload of the flash-only GPT (included so safe flashing can be accomplished)
public uint FlashOnlyTableCount; // count of blocks in the flash-only GPT
public uint FinalTableIndex; // index in the table of the real GPT
public uint FinalTableCount; // number of blocks in the real GPT
public override readonly string ToString()
{
return $"{{UpdateType: {UpdateType}, MajorVersion: {MajorVersion}, MinorVersion: {MinorVersion}}}";
}
}
}
-18
View File
@@ -1,18 +0,0 @@
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader.Structs
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct StoreHeaderV2
{
public ushort NumberOfStores; // Total number of stores (V2 only)
public ushort StoreIndex; // Current store index, 1-based (V2 only)
public ulong StorePayloadSize; // Payload data only, excludes padding (V2 only)
public ushort DevicePathLength; // Length of the device path (V2 only)
public override readonly string ToString()
{
return $"{{NumberOfStores: {NumberOfStores}, StoreIndex: {StoreIndex}, StorePayloadSize: {StorePayloadSize}, DevicePathLength: {DevicePathLength}}}";
}
}
}
-12
View File
@@ -1,12 +0,0 @@
using System.Runtime.InteropServices;
namespace Img2Ffu.Reader.Structs
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ValidationEntry
{
public uint dwSectorIndex;
public uint dwSectorOffset;
public uint dwByteCount;
}
}
+69 -1
View File
@@ -3,18 +3,86 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnifiedFlashingPlatform", "UnifiedFlashingPlatform.csproj", "{E1F73032-3193-434B-806D-636D136B8B35}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnifiedFlashingPlatform", "UnifiedFlashingPlatform\UnifiedFlashingPlatform.csproj", "{E1F73032-3193-434B-806D-636D136B8B35}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Img2Ffu.Library", "img2ffu\Img2Ffu.Library\Img2Ffu.Library.csproj", "{65F75BC0-735F-4CA1-8B33-C03FEECFA322}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Img2Ffu.Library.Compression.Windows", "img2ffu\Img2Ffu.Library.Compression.Windows\Img2Ffu.Library.Compression.Windows.csproj", "{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM32 = Debug|ARM32
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM32 = Release|ARM32
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|ARM32.ActiveCfg = Debug|Any CPU
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|ARM32.Build.0 = Debug|Any CPU
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|ARM64.ActiveCfg = Debug|arm64
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|ARM64.Build.0 = Debug|arm64
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|x64.ActiveCfg = Debug|x64
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|x64.Build.0 = Debug|x64
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|x86.ActiveCfg = Debug|x86
{E1F73032-3193-434B-806D-636D136B8B35}.Debug|x86.Build.0 = Debug|x86
{E1F73032-3193-434B-806D-636D136B8B35}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1F73032-3193-434B-806D-636D136B8B35}.Release|Any CPU.Build.0 = Release|Any CPU
{E1F73032-3193-434B-806D-636D136B8B35}.Release|ARM32.ActiveCfg = Release|Any CPU
{E1F73032-3193-434B-806D-636D136B8B35}.Release|ARM32.Build.0 = Release|Any CPU
{E1F73032-3193-434B-806D-636D136B8B35}.Release|ARM64.ActiveCfg = Release|arm64
{E1F73032-3193-434B-806D-636D136B8B35}.Release|ARM64.Build.0 = Release|arm64
{E1F73032-3193-434B-806D-636D136B8B35}.Release|x64.ActiveCfg = Release|x64
{E1F73032-3193-434B-806D-636D136B8B35}.Release|x64.Build.0 = Release|x64
{E1F73032-3193-434B-806D-636D136B8B35}.Release|x86.ActiveCfg = Release|x86
{E1F73032-3193-434B-806D-636D136B8B35}.Release|x86.Build.0 = Release|x86
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|Any CPU.ActiveCfg = Debug|x64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|Any CPU.Build.0 = Debug|x64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|ARM32.ActiveCfg = Debug|ARM32
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|ARM32.Build.0 = Debug|ARM32
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|ARM64.ActiveCfg = Debug|ARM64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|ARM64.Build.0 = Debug|ARM64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|x64.ActiveCfg = Debug|x64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|x64.Build.0 = Debug|x64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|x86.ActiveCfg = Debug|x86
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Debug|x86.Build.0 = Debug|x86
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|Any CPU.ActiveCfg = Release|x64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|Any CPU.Build.0 = Release|x64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|ARM32.ActiveCfg = Release|ARM32
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|ARM32.Build.0 = Release|ARM32
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|ARM64.ActiveCfg = Release|ARM64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|ARM64.Build.0 = Release|ARM64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|x64.ActiveCfg = Release|x64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|x64.Build.0 = Release|x64
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|x86.ActiveCfg = Release|x86
{65F75BC0-735F-4CA1-8B33-C03FEECFA322}.Release|x86.Build.0 = Release|x86
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|Any CPU.ActiveCfg = Debug|x64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|Any CPU.Build.0 = Debug|x64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|ARM32.ActiveCfg = Debug|ARM32
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|ARM32.Build.0 = Debug|ARM32
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|ARM64.Build.0 = Debug|ARM64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|x64.ActiveCfg = Debug|x64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|x64.Build.0 = Debug|x64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|x86.ActiveCfg = Debug|x86
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Debug|x86.Build.0 = Debug|x86
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|Any CPU.ActiveCfg = Release|x64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|Any CPU.Build.0 = Release|x64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|ARM32.ActiveCfg = Release|ARM32
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|ARM32.Build.0 = Release|ARM32
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|ARM64.ActiveCfg = Release|ARM64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|ARM64.Build.0 = Release|ARM64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|x64.ActiveCfg = Release|x64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|x64.Build.0 = Release|x64
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|x86.ActiveCfg = Release|x86
{AB5868C5-4BAC-4CE8-A927-7385D9D8776D}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Some files were not shown because too many files have changed in this diff Show More