From b5b4a50d94eed2cdde00fe392486bfe175e76a00 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 14 Nov 2024 11:20:46 -0500 Subject: [PATCH] Fix deserialization of NCCH extended header The actual fix to this is somewhere in the conversion code where an array of Enum values somehow just... fails? I'm not totally sure how that's happening but this is the easiest way around it until that auto stuff can be fixed. --- .../Deserializers/N3DS.cs | 46 ++++++++++++++++++- SabreTools.Serialization/Printers/N3DS.cs | 17 ++++++- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/SabreTools.Serialization/Deserializers/N3DS.cs b/SabreTools.Serialization/Deserializers/N3DS.cs index 4f521bb0..b73eee2f 100644 --- a/SabreTools.Serialization/Deserializers/N3DS.cs +++ b/SabreTools.Serialization/Deserializers/N3DS.cs @@ -329,7 +329,51 @@ namespace SabreTools.Serialization.Deserializers /// Filled NCCH extended header on success, null on error public static NCCHExtendedHeader? ParseNCCHExtendedHeader(Stream data) { - return data.ReadType(); + // TODO: Replace with `data.ReadType();` when enum serialization fixed + var header = new NCCHExtendedHeader(); + + header.SCI = data.ReadType(); + header.ACI = ParseAccessControlInfo(data); + header.AccessDescSignature = data.ReadBytes(0x100); + header.NCCHHDRPublicKey = data.ReadBytes(0x100); + header.ACIForLimitations = ParseAccessControlInfo(data); + + return header; + } + + /// + /// Parse a Stream into an access control info + /// + /// Stream to parse + /// Filled access control info on success, null on error + public static AccessControlInfo? ParseAccessControlInfo(Stream data) + { + var aci = new AccessControlInfo(); + + aci.ARM11LocalSystemCapabilities = data.ReadType(); + aci.ARM11KernelCapabilities = data.ReadType(); + aci.ARM9AccessControl = ParseARM9AccessControl(data); + + return aci; + } + + /// + /// Parse a Stream into an ARM9 access control + /// + /// Stream to parse + /// Filled ARM9 access control on success, null on error + public static ARM9AccessControl? ParseARM9AccessControl(Stream data) + { + var a9ac = new ARM9AccessControl(); + + a9ac.Descriptors = new ARM9AccessControlDescriptors[15]; + for (int i = 0; i < a9ac.Descriptors.Length; i++) + { + a9ac.Descriptors[i] = (ARM9AccessControlDescriptors)data.ReadByteValue(); + } + a9ac.DescriptorVersion = data.ReadByteValue(); + + return a9ac; } /// diff --git a/SabreTools.Serialization/Printers/N3DS.cs b/SabreTools.Serialization/Printers/N3DS.cs index 7ff8bcff..57d54c7f 100644 --- a/SabreTools.Serialization/Printers/N3DS.cs +++ b/SabreTools.Serialization/Printers/N3DS.cs @@ -1,3 +1,4 @@ +using System; using System.Text; using SabreTools.Models.N3DS; using SabreTools.Serialization.Interfaces; @@ -491,7 +492,13 @@ namespace SabreTools.Serialization.Printers } else { - builder.AppendLine($" Descriptors: {entry.ACI.ARM9AccessControl.Descriptors} (0x{entry.ACI.ARM9AccessControl.Descriptors:X})"); + string descriptorsStr = "[NULL]"; + if (entry.ACI.ARM9AccessControl.Descriptors != null) + { + var descriptors = Array.ConvertAll(entry.ACI.ARM9AccessControl.Descriptors, d => d.ToString()); + descriptorsStr = string.Join(", ", descriptors); + } + builder.AppendLine(descriptorsStr, " Descriptors"); builder.AppendLine(entry.ACI.ARM9AccessControl.DescriptorVersion, " Descriptor version"); } @@ -559,7 +566,13 @@ namespace SabreTools.Serialization.Printers } else { - builder.AppendLine($" Descriptors: {entry.ACIForLimitations.ARM9AccessControl.Descriptors} (0x{entry.ACIForLimitations.ARM9AccessControl.Descriptors:X})"); + string descriptorsStr = "[NULL]"; + if (entry.ACIForLimitations.ARM9AccessControl.Descriptors != null) + { + var descriptors = Array.ConvertAll(entry.ACIForLimitations.ARM9AccessControl.Descriptors, d => d.ToString()); + descriptorsStr = string.Join(", ", descriptors); + } + builder.AppendLine(descriptorsStr, " Descriptors"); builder.AppendLine(entry.ACIForLimitations.ARM9AccessControl.DescriptorVersion, " Descriptor version"); } }