From 45f5e1ffffed8b1ccef6579debacf2e22c4cf6df Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 8 Aug 2024 13:32:30 -0400 Subject: [PATCH] Clean up serialization methods --- NDecrypt.N3DS/CIATool.cs | 2 +- NDecrypt.N3DS/Serializer.cs | 583 ++++++++++-------------------------- 2 files changed, 155 insertions(+), 430 deletions(-) diff --git a/NDecrypt.N3DS/CIATool.cs b/NDecrypt.N3DS/CIATool.cs index 0350fa9..9de8d33 100644 --- a/NDecrypt.N3DS/CIATool.cs +++ b/NDecrypt.N3DS/CIATool.cs @@ -72,7 +72,7 @@ public bool ProcessFile() using (BinaryReader reader = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) using (BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))) { - var cia = Serializer.ReadCIAHeader(reader); + var cia = Serializer.ReadCIA(reader); if (cia == null) { Console.WriteLine("Error: Not a 3DS CIA!"); diff --git a/NDecrypt.N3DS/Serializer.cs b/NDecrypt.N3DS/Serializer.cs index 28319b2..b717e0e 100644 --- a/NDecrypt.N3DS/Serializer.cs +++ b/NDecrypt.N3DS/Serializer.cs @@ -13,80 +13,117 @@ internal static class Serializer private const string NCCHMagicNumber = "NCCH"; private const string NCSDMagicNumber = "NCSD"; - private const string RomFSMagicNumber = "IVFC"; - private const uint RomFSSecondMagicNumber = 0x10000; #endregion #region Reading /// - /// Read from a stream and get access control info, if possible + /// Read from a stream and get N3DS cart image, if possible /// /// BinaryReader representing the input stream - /// Access control info object, null on error - public static AccessControlInfo? ReadAccessControlInfo(BinaryReader reader) + /// True if development cart, false otherwise + /// N3DS cart image object, null on error + public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool development) { - var aci = new AccessControlInfo(); + var cart = new Cart(); + NCCHHeader? backupHeader = null; try { - aci.ARM11LocalSystemCapabilities = ReadARM11LocalSystemCapabilities(reader); - aci.ARM11KernelCapabilities = ReadARM11KernelCapabilities(reader); - aci.ARM9AccessControl = ReadARM9AccessControl(reader); - return aci; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get ARM9 access control, if possible - /// - /// BinaryReader representing the input stream - /// ARM9 access control object, null on error - public static ARM9AccessControl? ReadARM9AccessControl(BinaryReader reader) - { - var ac = new ARM9AccessControl(); + cart.Header = ReadNCSDHeader(reader); + if (cart.Header == null) + return (null, null); - try - { - ac.Descriptors = new byte[15]; // TODO: Implement ARM9AccessControlDescriptors in Models - for (int i = 0; i < 15; i++) + if (cart.Header.PartitionsFSType == FilesystemType.Normal + || cart.Header.PartitionsFSType == FilesystemType.None) { - ac.Descriptors[i] = reader.ReadByte(); + cart.CardInfoHeader = ReadCardInfoHeader(reader); + if (cart.CardInfoHeader == null) + return (null, null); + + // TODO: Remove when InitialData is read correctly + backupHeader = ReadNCCHHeader(reader, readSignature: false); + + if (development) + { + cart.DevelopmentCardInfoHeader = ReadDevelopmentCardInfoHeader(reader); + if (cart.DevelopmentCardInfoHeader == null) + return (null, null); + } } - ac.DescriptorVersion = reader.ReadByte(); - return ac; + return (cart, backupHeader); } catch { - return null; + return (null, null); ; } } /// - /// Read from a stream and get ARM11 kernel capabilities, if possible + /// Read from a stream and get a CIA header, if possible /// /// BinaryReader representing the input stream - /// ARM11 kernel capabilities object, null on error - public static ARM11KernelCapabilities? ReadARM11KernelCapabilities(BinaryReader reader) + /// CIA header object, null on error + public static CIA? ReadCIA(BinaryReader reader) { - var kc = new ARM11KernelCapabilities(); + var cia = new CIA(); try { - kc.Descriptors = new uint[28]; - for (int i = 0; i < 28; i++) + var header = new CIAHeader(); + + header.HeaderSize = reader.ReadUInt32(); + header.Type = reader.ReadUInt16(); + header.Version = reader.ReadUInt16(); + header.CertificateChainSize = reader.ReadUInt32(); + header.TicketSize = reader.ReadUInt32(); + header.TMDFileSize = reader.ReadUInt32(); + header.MetaSize = reader.ReadUInt32(); + header.ContentSize = reader.ReadUInt64(); + header.ContentIndex = reader.ReadBytes(0x2000); + + cia.Header = header; + + var certificateChain = new Certificate[3]; + if (reader.BaseStream.Position % 64 != 0) + reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current); + + certificateChain[0] = ReadCertificate(reader)!; // CA + certificateChain[1] = ReadCertificate(reader)!; // Ticket + certificateChain[2] = ReadCertificate(reader)!; // TMD + if (reader.BaseStream.Position % 64 != 0) + reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current); + + cia.CertificateChain = certificateChain; + + cia.Ticket = ReadTicket(reader, header.TicketSize); + if (reader.BaseStream.Position % 64 != 0) + reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current); + + cia.TMDFileData = ReadTitleMetadata(reader, header.TMDFileSize); + if (reader.BaseStream.Position % 64 != 0) + reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current); + + long startingPosition = reader.BaseStream.Position; + var headers = new List(); + while ((ulong)reader.BaseStream.Position < (ulong)startingPosition + header.ContentSize) { - kc.Descriptors[i] = reader.ReadUInt32(); + long initPosition = reader.BaseStream.Position; + var ncchHeader = ReadNCCHHeader(reader, readSignature: true); + if (ncchHeader == null) + break; + + headers.Add(ncchHeader); + reader.BaseStream.Seek(initPosition + ncchHeader.ContentSizeInMediaUnits * 0x200, SeekOrigin.Begin); } - kc.Reserved = reader.ReadBytes(0x10); - return kc; + cia.Partitions = [.. headers]; + if (header.MetaSize > 0) + cia.MetaData = ReadMetaData(reader); + + return cia; } catch { @@ -95,46 +132,31 @@ internal static class Serializer } /// - /// Read from a stream and get ARM11 local system capabilities, if possible + /// Read from a stream and get an ExeFS header, if possible /// /// BinaryReader representing the input stream - /// ARM11 local system capabilities object, null on error - public static ARM11LocalSystemCapabilities? ReadARM11LocalSystemCapabilities(BinaryReader reader) + /// ExeFS header object, null on error + public static ExeFSHeader? ReadExeFSHeader(BinaryReader reader) { - var lsc = new ARM11LocalSystemCapabilities(); + var header = new ExeFSHeader(); try { - lsc.ProgramID = reader.ReadUInt64(); - lsc.CoreVersion = reader.ReadUInt32(); - lsc.Flag1 = (ARM11LSCFlag1)reader.ReadByte(); - lsc.Flag2 = (ARM11LSCFlag2)reader.ReadByte(); - lsc.Flag0 = (ARM11LSCFlag0)reader.ReadByte(); - lsc.Priority = reader.ReadByte(); - - lsc.ResourceLimitDescriptors = new ushort[16]; - for (int i = 0; i < 16; i++) + header.FileHeaders = new ExeFSFileHeader[10]; + for (int i = 0; i < 10; i++) { - lsc.ResourceLimitDescriptors[i] = reader.ReadUInt16(); + header.FileHeaders[i] = ReadExeFSFileHeader(reader)!; } - lsc.StorageInfo = ReadStorageInfo(reader); - - lsc.ServiceAccessControl = new ulong[32]; - for (int i = 0; i < 32; i++) - { - lsc.ServiceAccessControl[i] = reader.ReadUInt64(); - } + header.Reserved = reader.ReadBytes(0x20); - lsc.ExtendedServiceAccessControl = new ulong[2]; - for (int i = 0; i < 2; i++) + header.FileHashes = new byte[10][]; + for (int i = 0; i < 10; i++) { - lsc.ExtendedServiceAccessControl[i] = reader.ReadUInt64(); + header.FileHashes[9 - i] = reader.ReadBytes(0x20); } - lsc.Reserved = reader.ReadBytes(0xF); - lsc.ResourceLimitCategory = (ResourceLimitCategory)reader.ReadByte(); - return lsc; + return header; } catch { @@ -143,45 +165,57 @@ internal static class Serializer } /// - /// Read from a stream and get N3DS cart image, if possible + /// Read from a stream and get an NCCH header, if possible /// /// BinaryReader representing the input stream - /// True if development cart, false otherwise - /// N3DS cart image object, null on error - public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool development) + /// True if the RSA signature is read, false otherwise + /// NCCH header object, null on error + public static NCCHHeader? ReadNCCHHeader(BinaryReader reader, bool readSignature) { - var cart = new Cart(); - NCCHHeader? backupHeader = null; + var header = new NCCHHeader(); try { - cart.Header = ReadNCSDHeader(reader); - if (cart.Header == null) - return (null, null); - - if (cart.Header.PartitionsFSType == FilesystemType.Normal - || cart.Header.PartitionsFSType == FilesystemType.None) - { - cart.CardInfoHeader = ReadCardInfoHeader(reader); - if (cart.CardInfoHeader == null) - return (null, null); + if (readSignature) + header.RSA2048Signature = reader.ReadBytes(0x100); - // TODO: Undocumented in current model? - backupHeader = ReadNCCHHeader(reader, readSignature: false); + if (new string(reader.ReadChars(4)) != NCCHMagicNumber) + return null; - if (development) - { - cart.DevelopmentCardInfoHeader = ReadDevelopmentCardInfoHeader(reader); - if (cart.DevelopmentCardInfoHeader == null) - return (null, null); - } - } + header.ContentSizeInMediaUnits = reader.ReadUInt32(); + header.PartitionId = reader.ReadUInt64(); + header.MakerCode = reader.ReadUInt16(); + header.Version = reader.ReadUInt16(); + header.VerificationHash = reader.ReadUInt32(); + header.ProgramId = reader.ReadBytes(8); + header.Reserved1 = reader.ReadBytes(0x10); + header.LogoRegionHash = reader.ReadBytes(0x20); + byte[] productCodeBytes = reader.ReadBytes(0x10); + header.ProductCode = Encoding.ASCII.GetString(productCodeBytes); + header.ExtendedHeaderHash = reader.ReadBytes(0x20); + header.ExtendedHeaderSizeInBytes = reader.ReadUInt32(); + header.Reserved2 = reader.ReadUInt32(); + header.Flags = ReadNCCHHeaderFlags(reader); + header.PlainRegionOffsetInMediaUnits = reader.ReadUInt32(); + header.PlainRegionSizeInMediaUnits = reader.ReadUInt32(); + header.LogoRegionOffsetInMediaUnits = reader.ReadUInt32(); + header.LogoRegionSizeInMediaUnits = reader.ReadUInt32(); + header.ExeFSOffsetInMediaUnits = reader.ReadUInt32(); + header.ExeFSSizeInMediaUnits = reader.ReadUInt32(); + header.ExeFSHashRegionSizeInMediaUnits = reader.ReadUInt32(); + header.Reserved3 = reader.ReadUInt32(); + header.RomFSOffsetInMediaUnits = reader.ReadUInt32(); + header.RomFSSizeInMediaUnits = reader.ReadUInt32(); + header.RomFSHashRegionSizeInMediaUnits = reader.ReadUInt32(); + header.Reserved4 = reader.ReadUInt32(); + header.ExeFSSuperblockHash = reader.ReadBytes(0x20); + header.RomFSSuperblockHash = reader.ReadBytes(0x20); - return (cart, backupHeader); + return header; } catch { - return (null, null); ; + return null; } } @@ -190,7 +224,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen /// /// BinaryReader representing the input stream /// CardInfo header object, null on error - public static CardInfoHeader? ReadCardInfoHeader(BinaryReader reader) + private static CardInfoHeader? ReadCardInfoHeader(BinaryReader reader) { var header = new CardInfoHeader(); @@ -202,13 +236,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen header.TitleVersion = reader.ReadUInt16(); header.CardRevision = reader.ReadUInt16(); header.Reserved4 = reader.ReadBytes(0xCD6); - - // TODO: Undocumented in current model? - _ = reader.ReadBytes(0x10); // header.CardSeedKeyY - _ = reader.ReadBytes(0x10); // header.EncryptedCardSeed - _ = reader.ReadBytes(0x10); // header.CardSeedAESMAC - _ = reader.ReadBytes(0x0C); // header.CardSeedNonce - _ = reader.ReadBytes(0xC4); // header.Reserved5 + _ = ReadInitialData(reader); return header; } @@ -223,7 +251,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen /// /// BinaryReader representing the input stream /// Certificate object, null on error - public static Certificate? ReadCertificate(BinaryReader reader) + private static Certificate? ReadCertificate(BinaryReader reader) { var ct = new Certificate(); @@ -288,104 +316,12 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen } } - /// - /// Read from a stream and get a CIA header, if possible - /// - /// BinaryReader representing the input stream - /// CIA header object, null on error - public static CIA? ReadCIAHeader(BinaryReader reader) - { - var cia = new CIA(); - - try - { - var header = new CIAHeader(); - - header.HeaderSize = reader.ReadUInt32(); - header.Type = reader.ReadUInt16(); - header.Version = reader.ReadUInt16(); - header.CertificateChainSize = reader.ReadUInt32(); - header.TicketSize = reader.ReadUInt32(); - header.TMDFileSize = reader.ReadUInt32(); - header.MetaSize = reader.ReadUInt32(); - header.ContentSize = reader.ReadUInt64(); - header.ContentIndex = reader.ReadBytes(0x2000); - - cia.Header = header; - - var certificateChain = new Certificate[3]; - if (reader.BaseStream.Position % 64 != 0) - reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current); - - certificateChain[0] = ReadCertificate(reader)!; // CA - certificateChain[1] = ReadCertificate(reader)!; // Ticket - certificateChain[2] = ReadCertificate(reader)!; // TMD - if (reader.BaseStream.Position % 64 != 0) - reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current); - - cia.CertificateChain = certificateChain; - - cia.Ticket = ReadTicket(reader, header.TicketSize); - if (reader.BaseStream.Position % 64 != 0) - reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current); - - cia.TMDFileData = ReadTitleMetadata(reader, header.TMDFileSize); - if (reader.BaseStream.Position % 64 != 0) - reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current); - - long startingPosition = reader.BaseStream.Position; - var headers = new List(); - while ((ulong)reader.BaseStream.Position < (ulong)startingPosition + header.ContentSize) - { - long initPosition = reader.BaseStream.Position; - var ncchHeader = ReadNCCHHeader(reader, readSignature: true); - if (ncchHeader == null) - break; - - headers.Add(ncchHeader); - reader.BaseStream.Seek(initPosition + ncchHeader.ContentSizeInMediaUnits * 0x200, SeekOrigin.Begin); - } - - cia.Partitions = [.. headers]; - if (header.MetaSize > 0) - cia.MetaData = ReadMetaData(reader); - - return cia; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get code set info, if possible - /// - /// BinaryReader representing the input stream - /// Code set info object, null on error - public static CodeSetInfo? ReadCodeSetInfo(BinaryReader reader) - { - var csi = new CodeSetInfo(); - - try - { - csi.Address = reader.ReadUInt32(); - csi.PhysicalRegionSizeInPages = reader.ReadUInt32(); - csi.SizeInBytes = reader.ReadUInt32(); - return csi; - } - catch - { - return null; - } - } - /// /// Read from a stream and get content chunk record, if possible /// /// BinaryReader representing the input stream /// Content chunk record object, null on error - public static ContentChunkRecord? ReadContentChunkRecord(BinaryReader reader) + private static ContentChunkRecord? ReadContentChunkRecord(BinaryReader reader) { var ccr = new ContentChunkRecord(); @@ -409,7 +345,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen /// /// BinaryReader representing the input stream /// Content info record object, null on error - public static ContentInfoRecord? ReadContentInfoRecord(BinaryReader reader) + private static ContentInfoRecord? ReadContentInfoRecord(BinaryReader reader) { var cir = new ContentInfoRecord(); @@ -431,7 +367,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen /// /// BinaryReader representing the input stream /// DevelopmentCardInfo object, null on error - public static DevelopmentCardInfoHeader? ReadDevelopmentCardInfoHeader(BinaryReader reader) + private static DevelopmentCardInfoHeader? ReadDevelopmentCardInfoHeader(BinaryReader reader) { var header = new DevelopmentCardInfoHeader(); @@ -454,7 +390,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen /// /// BinaryReader representing the input stream /// ExeFS file header object, null on error - public static ExeFSFileHeader? ReadExeFSFileHeader(BinaryReader reader) + private static ExeFSFileHeader? ReadExeFSFileHeader(BinaryReader reader) { var header = new ExeFSFileHeader(); @@ -473,31 +409,24 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen } /// - /// Read from a stream and get an ExeFS header, if possible + /// Read from a stream and get inital data, if possible /// /// BinaryReader representing the input stream - /// ExeFS header object, null on error - public static ExeFSHeader? ReadExeFSHeader(BinaryReader reader) + /// Initial data object, null on error + private static InitialData? ReadInitialData(BinaryReader reader) { - var header = new ExeFSHeader(); + var id = new InitialData(); try { - header.FileHeaders = new ExeFSFileHeader[10]; - for (int i = 0; i < 10; i++) - { - header.FileHeaders[i] = ReadExeFSFileHeader(reader)!; - } - - header.Reserved = reader.ReadBytes(0x20); - - header.FileHashes = new byte[10][]; - for (int i = 0; i < 10; i++) - { - header.FileHashes[9 - i] = reader.ReadBytes(0x20); - } + id.CardSeedKeyY = reader.ReadBytes(0x10); + id.EncryptedCardSeed = reader.ReadBytes(0x10); + id.CardSeedAESMAC = reader.ReadBytes(0x10); + id.CardSeedNonce = reader.ReadBytes(0x0C); + id.Reserved = reader.ReadBytes(0xC4); + // TODO: Read backup header here instead of separately - return header; + return id; } catch { @@ -510,7 +439,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen /// /// BinaryReader representing the input stream /// Metafile data object, null on error - public static MetaData? ReadMetaData(BinaryReader reader) + private static MetaData? ReadMetaData(BinaryReader reader) { var metaData = new MetaData(); @@ -530,67 +459,12 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen } } - /// - /// Read from a stream and get an NCCH header, if possible - /// - /// BinaryReader representing the input stream - /// True if the RSA signature is read, false otherwise - /// NCCH header object, null on error - public static NCCHHeader? ReadNCCHHeader(BinaryReader reader, bool readSignature) - { - var header = new NCCHHeader(); - - try - { - if (readSignature) - header.RSA2048Signature = reader.ReadBytes(0x100); - - if (new string(reader.ReadChars(4)) != NCCHMagicNumber) - return null; - - header.ContentSizeInMediaUnits = reader.ReadUInt32(); - header.PartitionId = reader.ReadUInt64(); - header.MakerCode = reader.ReadUInt16(); - header.Version = reader.ReadUInt16(); - header.VerificationHash = reader.ReadUInt32(); - header.ProgramId = reader.ReadBytes(8); - header.Reserved1 = reader.ReadBytes(0x10); - header.LogoRegionHash = reader.ReadBytes(0x20); - byte[] productCodeBytes = reader.ReadBytes(0x10); - header.ProductCode = Encoding.ASCII.GetString(productCodeBytes); - header.ExtendedHeaderHash = reader.ReadBytes(0x20); - header.ExtendedHeaderSizeInBytes = reader.ReadUInt32(); - header.Reserved2 = reader.ReadUInt32(); - header.Flags = ReadNCCHHeaderFlags(reader); - header.PlainRegionOffsetInMediaUnits = reader.ReadUInt32(); - header.PlainRegionSizeInMediaUnits = reader.ReadUInt32(); - header.LogoRegionOffsetInMediaUnits = reader.ReadUInt32(); - header.LogoRegionSizeInMediaUnits = reader.ReadUInt32(); - header.ExeFSOffsetInMediaUnits = reader.ReadUInt32(); - header.ExeFSSizeInMediaUnits = reader.ReadUInt32(); - header.ExeFSHashRegionSizeInMediaUnits = reader.ReadUInt32(); - header.Reserved3 = reader.ReadUInt32(); - header.RomFSOffsetInMediaUnits = reader.ReadUInt32(); - header.RomFSSizeInMediaUnits = reader.ReadUInt32(); - header.RomFSHashRegionSizeInMediaUnits = reader.ReadUInt32(); - header.Reserved4 = reader.ReadUInt32(); - header.ExeFSSuperblockHash = reader.ReadBytes(0x20); - header.RomFSSuperblockHash = reader.ReadBytes(0x20); - - return header; - } - catch - { - return null; - } - } - /// /// Read from a stream and get an NCCH header flags, if possible /// /// BinaryReader representing the input stream /// NCCH header flags object, null on error - public static NCCHHeaderFlags? ReadNCCHHeaderFlags(BinaryReader reader) + private static NCCHHeaderFlags? ReadNCCHHeaderFlags(BinaryReader reader) { var flags = new NCCHHeaderFlags(); @@ -612,36 +486,12 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen } } - /// - /// Read from a stream and get a CXI extended header, if possible - /// - /// BinaryReader representing the input stream - /// CXI extended header object, null on error - public static NCCHExtendedHeader? ReadNCCHExtendedHeader(BinaryReader reader) - { - var header = new NCCHExtendedHeader(); - - try - { - header.SCI = ReadSystemControlInfo(reader); - header.ACI = ReadAccessControlInfo(reader); - header.AccessDescSignature = reader.ReadBytes(0x100); - header.NCCHHDRPublicKey = reader.ReadBytes(0x100); - header.ACIForLimitations = ReadAccessControlInfo(reader); - return header; - } - catch - { - return null; - } - } - /// /// Read from a stream and get an NCSD header, if possible /// /// BinaryReader representing the input stream /// NCSD header object, null on error - public static NCSDHeader? ReadNCSDHeader(BinaryReader reader) + private static NCSDHeader? ReadNCSDHeader(BinaryReader reader) { var header = new NCSDHeader(); @@ -701,7 +551,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen /// /// BinaryReader representing the input stream /// Partition table entry object, null on error - public static PartitionTableEntry? ReadPartitionTableEntry(BinaryReader reader) + private static PartitionTableEntry? ReadPartitionTableEntry(BinaryReader reader) { var entry = new PartitionTableEntry(); @@ -717,138 +567,13 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen } } - /// - /// Read from a stream and get a RomFS header, if possible - /// - /// BinaryReader representing the input stream - /// RomFS header object, null on error - public static RomFSHeader? ReadRomFSHeader(BinaryReader reader) - { - var header = new RomFSHeader(); - - try - { - if (new string(reader.ReadChars(4)) != RomFSMagicNumber) - return null; - - if (reader.ReadUInt32() != RomFSSecondMagicNumber) - return null; - - header.MasterHashSize = reader.ReadUInt32(); - header.Level1LogicalOffset = reader.ReadUInt64(); - header.Level1HashdataSize = reader.ReadUInt64(); - header.Level1BlockSizeLog2 = reader.ReadUInt32(); - header.Reserved1 = reader.ReadUInt32(); - header.Level2LogicalOffset = reader.ReadUInt64(); - header.Level2HashdataSize = reader.ReadUInt64(); - header.Level2BlockSizeLog2 = reader.ReadUInt32(); - header.Reserved2 = reader.ReadUInt32(); - header.Level3LogicalOffset = reader.ReadUInt64(); - header.Level3HashdataSize = reader.ReadUInt64(); - header.Level3BlockSizeLog2 = reader.ReadUInt32(); - header.Reserved3 = reader.ReadUInt32(); - header.Reserved4 = reader.ReadUInt32(); - header.OptionalInfoSize = reader.ReadUInt32(); - - return header; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get storage info, if possible - /// - /// BinaryReader representing the input stream - /// Storage info object, null on error - public static StorageInfo? ReadStorageInfo(BinaryReader reader) - { - var si = new StorageInfo(); - - try - { - si.ExtdataID = reader.ReadUInt64(); - si.SystemSavedataIDs = reader.ReadBytes(8); - si.StorageAccessibleUniqueIDs = reader.ReadBytes(8); - si.FileSystemAccessInfo = reader.ReadBytes(7); - si.OtherAttributes = (StorageInfoOtherAttributes)reader.ReadByte(); - return si; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get system control info, if possible - /// - /// BinaryReader representing the input stream - /// System control info object, null on error - public static SystemControlInfo? ReadSystemControlInfo(BinaryReader reader) - { - var sci = new SystemControlInfo(); - - try - { - byte[] applicationTitleBytes = reader.ReadBytes(8); - sci.ApplicationTitle = Encoding.ASCII.GetString(applicationTitleBytes); - sci.Reserved1 = reader.ReadBytes(5); - sci.Flag = reader.ReadByte(); - sci.RemasterVersion = reader.ReadUInt16(); - sci.TextCodeSetInfo = ReadCodeSetInfo(reader); - sci.StackSize = reader.ReadUInt32(); - sci.ReadOnlyCodeSetInfo = ReadCodeSetInfo(reader); - sci.Reserved2 = reader.ReadUInt32(); - sci.DataCodeSetInfo = ReadCodeSetInfo(reader); - sci.BSSSize = reader.ReadUInt32(); - - sci.DependencyModuleList = new ulong[48]; - for (int i = 0; i < 48; i++) - { - sci.DependencyModuleList[i] = reader.ReadUInt64(); - } - - sci.SystemInfo = ReadSystemInfo(reader); - return sci; - } - catch - { - return null; - } - } - - /// - /// Read from a stream and get system info, if possible - /// - /// BinaryReader representing the input stream - /// System info object, null on error - public static SystemInfo? ReadSystemInfo(BinaryReader reader) - { - var si = new SystemInfo(); - - try - { - si.SaveDataSize = reader.ReadUInt64(); - si.JumpID = reader.ReadUInt64(); - si.Reserved = reader.ReadBytes(0x30); - return si; - } - catch - { - return null; - } - } - /// /// Read from a stream and get ticket, if possible /// /// BinaryReader representing the input stream /// Ticket size from the header /// Ticket object, null on error - public static Ticket? ReadTicket(BinaryReader reader, uint ticketSize) + private static Ticket? ReadTicket(BinaryReader reader, uint ticketSize) { var tk = new Ticket(); @@ -936,7 +661,7 @@ public static (Cart?, NCCHHeader?) ReadCart(BinaryReader reader, bool developmen /// BinaryReader representing the input stream /// Metadata size from the header /// Title metadata object, null on error - public static TitleMetadata? ReadTitleMetadata(BinaryReader reader, uint metadataSize) + private static TitleMetadata? ReadTitleMetadata(BinaryReader reader, uint metadataSize) { var tm = new TitleMetadata();