diff --git a/src/LibHac/Es/ETicket.cs b/src/LibHac/Es/ETicket.cs index 2e395c35..4a77d16e 100644 --- a/src/LibHac/Es/ETicket.cs +++ b/src/LibHac/Es/ETicket.cs @@ -43,27 +43,27 @@ namespace LibHac.Es public enum SignatureType { Rsa4096Sha1 = 0x10000, - Rsa2048Sha1, - EcdsaSha1, - Rsa4096Sha256, - Rsa2048Sha256, - EcdsaSha256 + Rsa2048Sha1 = 0x10001, + EcdsaSha1 = 0x10002, + Rsa4096Sha256 = 0x10003, + Rsa2048Sha256 = 0x10004, + EcdsaSha256 = 0x10005 } public enum TitleKeyType : byte { - Common, - Personalized + Common = 0, + Personalized = 1 } public enum LicenseType : byte { - Permanent, - Demo, - Trial, - Rental, - Subscription, - Service + Permanent = 0, + Demo = 1, + Trial = 2, + Rental = 3, + Subscription = 4, + Service = 5 } [Flags] diff --git a/src/LibHac/Xci.cs b/src/LibHac/Xci.cs index e2bb6fb9..27f13542 100644 --- a/src/LibHac/Xci.cs +++ b/src/LibHac/Xci.cs @@ -1,6 +1,7 @@ using LibHac.Common; using LibHac.Fs; using LibHac.FsSystem; +using LibHac.FsSystem.Detail; namespace LibHac { @@ -11,6 +12,7 @@ namespace LibHac private IStorage BaseStorage { get; } private object InitLocker { get; } = new object(); private XciPartition RootPartition { get; set; } + private IFileSystem RootPartition2 { get; set; } public Xci(Keyset keyset, IStorage storage) { @@ -25,7 +27,7 @@ namespace LibHac return GetRootPartition().FileExists(type.GetFileName()); } - public XciPartition OpenPartition(XciPartitionType type) + public XciPartition OpenPartitionO(XciPartitionType type) { XciPartition root = GetRootPartition(); if (type == XciPartitionType.Root) return root; @@ -34,6 +36,19 @@ namespace LibHac return new XciPartition(partitionFile.AsStorage()); } + public IFileSystem OpenPartition(XciPartitionType type) + { + IFileSystem root = GetRootPartition2(); + if (type == XciPartitionType.Root) return root; + + root.OpenFile(out IFile partitionFile, type.GetFileName().ToU8Span(), OpenMode.Read).ThrowIfFailure(); + + var partitionFs = new PartitionFileSystemCore(); + partitionFs.Initialize(partitionFile.AsStorage()).ThrowIfFailure(); + + return partitionFs; + } + private XciPartition GetRootPartition() { if (RootPartition != null) return RootPartition; @@ -43,6 +58,15 @@ namespace LibHac return RootPartition; } + private IFileSystem GetRootPartition2() + { + if (RootPartition2 != null) return RootPartition2; + + InitializeRootPartition2(); + + return RootPartition2; + } + private void InitializeRootPartition() { lock (InitLocker) @@ -58,6 +82,21 @@ namespace LibHac }; } } + + private void InitializeRootPartition2() + { + lock (InitLocker) + { + if (RootPartition2 != null) return; + + IStorage rootStorage = BaseStorage.Slice(Header.RootPartitionOffset); + + var partitionFs = new PartitionFileSystemCore(); + partitionFs.Initialize(rootStorage).ThrowIfFailure(); + + RootPartition2 = partitionFs; + } + } } public class XciPartition : PartitionFileSystem diff --git a/src/hactoolnet/ProcessXci.cs b/src/hactoolnet/ProcessXci.cs index 34494f6d..37691e8b 100644 --- a/src/hactoolnet/ProcessXci.cs +++ b/src/hactoolnet/ProcessXci.cs @@ -47,20 +47,20 @@ namespace hactoolnet if (ctx.Options.OutDir != null) { - XciPartition root = xci.OpenPartition(XciPartitionType.Root); + IFileSystem root = xci.OpenPartition(XciPartitionType.Root); if (root == null) { ctx.Logger.LogMessage("Could not find root partition"); return; } - foreach (PartitionFileEntry sub in root.Files) - { - var subPfs = new PartitionFileSystem(root.OpenFile(sub, OpenMode.Read).AsStorage()); - string subDir = Path.Combine(ctx.Options.OutDir, sub.Name); + //foreach (PartitionFileEntry sub in root.Files) + //{ + // var subPfs = new PartitionFileSystem(root.OpenFile(sub, OpenMode.Read).AsStorage()); + // string subDir = Path.Combine(ctx.Options.OutDir, sub.Name); - subPfs.Extract(subDir, ctx.Logger); - } + // subPfs.Extract(subDir, ctx.Logger); + //} } if (ctx.Options.ExefsOutDir != null || ctx.Options.ExefsOut != null) @@ -113,7 +113,7 @@ namespace hactoolnet private static Nca GetXciMainNca(Xci xci, Context ctx) { - XciPartition partition = xci.OpenPartition(XciPartitionType.Secure); + IFileSystem partition = xci.OpenPartition(XciPartitionType.Secure); if (partition == null) { @@ -123,16 +123,16 @@ namespace hactoolnet Nca mainNca = null; - foreach (PartitionFileEntry fileEntry in partition.Files.Where(x => x.Name.EndsWith(".nca"))) - { - IStorage ncaStorage = partition.OpenFile(fileEntry, OpenMode.Read).AsStorage(); - var nca = new Nca(ctx.Keyset, ncaStorage); + //foreach (PartitionFileEntry fileEntry in partition.Files.Where(x => x.Name.EndsWith(".nca"))) + //{ + // IStorage ncaStorage = partition.OpenFile(fileEntry, OpenMode.Read).AsStorage(); + // var nca = new Nca(ctx.Keyset, ncaStorage); - if (nca.Header.ContentType == NcaContentType.Program) - { - mainNca = nca; - } - } + // if (nca.Header.ContentType == NcaContentType.Program) + // { + // mainNca = nca; + // } + //} return mainNca; } @@ -153,15 +153,15 @@ namespace hactoolnet PrintItem(sb, colLen, "Cartridge Size:", $"0x{Util.MediaToReal(xci.Header.ValidDataEndPage + 1):x12}"); PrintItem(sb, colLen, "Header IV:", xci.Header.AesCbcIv); - PrintPartition(sb, colLen, xci.OpenPartition(XciPartitionType.Root), XciPartitionType.Root); + //PrintPartition(sb, colLen, xci.OpenPartition(XciPartitionType.Root), XciPartitionType.Root); - foreach (XciPartitionType type in Enum.GetValues(typeof(XciPartitionType))) - { - if (type == XciPartitionType.Root || !xci.HasPartition(type)) continue; + //foreach (XciPartitionType type in Enum.GetValues(typeof(XciPartitionType))) + //{ + // if (type == XciPartitionType.Root || !xci.HasPartition(type)) continue; - XciPartition partition = xci.OpenPartition(type); - PrintPartition(sb, colLen, partition, type); - } + // IFileSystem partition = xci.OpenPartition(type); + // PrintPartition(sb, colLen, partition, type); + //} return sb.ToString(); }