mirror of
https://github.com/SabreTools/BinaryObjectScanner.git
synced 2026-07-21 00:05:06 +00:00
Add RomFS header parsing/printing
This commit is contained in:
@@ -161,6 +161,32 @@ namespace BurnOutSharp.Builders
|
||||
|
||||
#endregion
|
||||
|
||||
#region RomFS Headers
|
||||
|
||||
// Create the RomFS header table
|
||||
cart.RomFSHeaders = new RomFSHeader[8];
|
||||
|
||||
// Iterate and build the RomFS headers
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
// If we have an encrypted or invalid partition
|
||||
if (cart.Partitions[i].MagicID != NCCHMagicNumber)
|
||||
continue;
|
||||
|
||||
// Get the RomFS header offset
|
||||
long offset = (cart.Header.PartitionsTable[i].Offset + cart.Partitions[i].RomFSOffsetInMediaUnits) * mediaUnitSize;
|
||||
if (offset < 0 || offset >= data.Length)
|
||||
continue;
|
||||
|
||||
// Seek to the RomFS header
|
||||
data.Seek(offset, SeekOrigin.Begin);
|
||||
|
||||
// Parse the RomFS header
|
||||
cart.RomFSHeaders[i] = ParseRomFSHeader(data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
return cart;
|
||||
}
|
||||
|
||||
@@ -647,6 +673,44 @@ namespace BurnOutSharp.Builders
|
||||
return exeFSFileHeader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a Stream into an RomFS header
|
||||
/// </summary>
|
||||
/// <param name="data">Stream to parse</param>
|
||||
/// <returns>Filled RomFS header on success, null on error</returns>
|
||||
private static RomFSHeader ParseRomFSHeader(Stream data)
|
||||
{
|
||||
// TODO: Use marshalling here instead of building
|
||||
RomFSHeader romFSHeader = new RomFSHeader();
|
||||
|
||||
byte[] magicString = data.ReadBytes(4);
|
||||
romFSHeader.MagicString = Encoding.ASCII.GetString(magicString).TrimEnd('\0');
|
||||
if (romFSHeader.MagicString != RomFSMagicNumber)
|
||||
return null;
|
||||
|
||||
romFSHeader.MagicNumber = data.ReadUInt32();
|
||||
if (romFSHeader.MagicNumber != RomFSSecondMagicNumber)
|
||||
return null;
|
||||
|
||||
romFSHeader.MasterHashSize = data.ReadUInt32();
|
||||
romFSHeader.Level1LogicalOffset = data.ReadUInt64();
|
||||
romFSHeader.Level1HashdataSize = data.ReadUInt64();
|
||||
romFSHeader.Level1BlockSizeLog2 = data.ReadUInt32();
|
||||
romFSHeader.Reserved1 = data.ReadBytes(4);
|
||||
romFSHeader.Level2LogicalOffset = data.ReadUInt64();
|
||||
romFSHeader.Level2HashdataSize = data.ReadUInt64();
|
||||
romFSHeader.Level2BlockSizeLog2 = data.ReadUInt32();
|
||||
romFSHeader.Reserved2 = data.ReadBytes(4);
|
||||
romFSHeader.Level3LogicalOffset = data.ReadUInt64();
|
||||
romFSHeader.Level3HashdataSize = data.ReadUInt64();
|
||||
romFSHeader.Level3BlockSizeLog2 = data.ReadUInt32();
|
||||
romFSHeader.Reserved3 = data.ReadBytes(4);
|
||||
romFSHeader.Reserved4 = data.ReadBytes(4);
|
||||
romFSHeader.OptionalInfoSize = data.ReadUInt32();
|
||||
|
||||
return romFSHeader;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,5 +34,10 @@ namespace BurnOutSharp.Models.N3DS
|
||||
/// ExeFS headers associated with each partition
|
||||
/// </summary>
|
||||
public ExeFSHeader[] ExeFSHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// RomFS headers associated with each partition
|
||||
/// </summary>
|
||||
public RomFSHeader[] RomFSHeaders { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,19 @@
|
||||
/// used as external file storage.
|
||||
/// </summary>
|
||||
/// <see href="https://www.3dbrew.org/wiki/RomFS"/>
|
||||
/// TODO: Implement the other parts of the RomFS tree structure
|
||||
public sealed class RomFSHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Magic "IVFC"
|
||||
/// </summary>
|
||||
public string MagicString;
|
||||
|
||||
/// <summary>
|
||||
/// Magic number 0x10000
|
||||
/// </summary>
|
||||
public uint MagicNumber;
|
||||
|
||||
/// <summary>
|
||||
/// Master hash size
|
||||
/// </summary>
|
||||
|
||||
@@ -204,6 +204,13 @@ namespace BurnOutSharp.Wrappers
|
||||
|
||||
#endregion
|
||||
|
||||
#region RomFS Headers
|
||||
|
||||
/// <inheritdoc cref="Models.N3DS.Cart.RomFSHeaders"/>
|
||||
public Models.N3DS.RomFSHeader[] RomFSHeaders => _cart.RomFSHeaders;
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Instance Variables
|
||||
@@ -284,6 +291,7 @@ namespace BurnOutSharp.Wrappers
|
||||
PrintPartitions();
|
||||
PrintExtendedHeaders();
|
||||
PrintExeFSHeaders();
|
||||
PrintRomFSHeaders();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -641,7 +649,7 @@ namespace BurnOutSharp.Wrappers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print ExeFS header header information
|
||||
/// Print ExeFS header information
|
||||
/// </summary>
|
||||
private void PrintExeFSHeaders()
|
||||
{
|
||||
@@ -688,6 +696,52 @@ namespace BurnOutSharp.Wrappers
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print RomFS header information
|
||||
/// </summary>
|
||||
private void PrintRomFSHeaders()
|
||||
{
|
||||
Console.WriteLine(" RomFS Header Information:");
|
||||
Console.WriteLine(" -------------------------");
|
||||
if (RomFSHeaders == null || RomFSHeaders.Length == 0)
|
||||
{
|
||||
Console.WriteLine(" No RomFS headers");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < RomFSHeaders.Length; i++)
|
||||
{
|
||||
var romFSHeader = RomFSHeaders[i];
|
||||
Console.WriteLine($" RomFS Header {i}");
|
||||
if (romFSHeader == null)
|
||||
{
|
||||
Console.WriteLine($" Unrecognized RomFS data, no data can be parsed");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(value: $" Magic string: {romFSHeader.MagicString}");
|
||||
Console.WriteLine(value: $" Magic number: {romFSHeader.MagicNumber}");
|
||||
Console.WriteLine(value: $" Master hash size: {romFSHeader.MasterHashSize}");
|
||||
Console.WriteLine(value: $" Level 1 logical offset: {romFSHeader.Level1LogicalOffset}");
|
||||
Console.WriteLine(value: $" Level 1 hashdata size: {romFSHeader.Level1HashdataSize}");
|
||||
Console.WriteLine(value: $" Level 1 block size: {romFSHeader.Level1BlockSizeLog2}");
|
||||
Console.WriteLine(value: $" Reserved 1: {BitConverter.ToString(romFSHeader.Reserved1).Replace('-', ' ')}");
|
||||
Console.WriteLine(value: $" Level 2 logical offset: {romFSHeader.Level2LogicalOffset}");
|
||||
Console.WriteLine(value: $" Level 2 hashdata size: {romFSHeader.Level2HashdataSize}");
|
||||
Console.WriteLine(value: $" Level 2 block size: {romFSHeader.Level2BlockSizeLog2}");
|
||||
Console.WriteLine(value: $" Reserved 2: {BitConverter.ToString(romFSHeader.Reserved2).Replace('-', ' ')}");
|
||||
Console.WriteLine(value: $" Level 3 logical offset: {romFSHeader.Level3LogicalOffset}");
|
||||
Console.WriteLine(value: $" Level 3 hashdata size: {romFSHeader.Level3HashdataSize}");
|
||||
Console.WriteLine(value: $" Level 3 block size: {romFSHeader.Level3BlockSizeLog2}");
|
||||
Console.WriteLine(value: $" Reserved 3: {BitConverter.ToString(romFSHeader.Reserved3).Replace('-', ' ')}");
|
||||
Console.WriteLine(value: $" Reserved 4: {BitConverter.ToString(romFSHeader.Reserved4).Replace('-', ' ')}");
|
||||
Console.WriteLine(value: $" Optional info size: {romFSHeader.OptionalInfoSize}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user