From 585c351917b17cdb63e74872cf61045986484538 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Wed, 2 Jan 2019 18:16:19 -0700 Subject: [PATCH] Remove old Pfs and Romfs classes --- src/LibHac/IO/FileStorage.cs | 31 +++++ src/LibHac/IO/PartitionFileSystem.cs | 16 +-- src/LibHac/IO/PathTools.cs | 10 +- src/LibHac/IO/RomFsFileSystem.cs | 33 +++++ src/LibHac/Nca.cs | 10 +- src/LibHac/Pfs.cs | 191 --------------------------- src/LibHac/Romfs.cs | 163 ----------------------- src/LibHac/SwitchFs.cs | 10 +- src/LibHac/Xci.cs | 12 +- src/hactoolnet/ProcessNca.cs | 2 +- src/hactoolnet/ProcessRomfs.cs | 6 +- src/hactoolnet/ProcessSwitchFs.cs | 2 +- src/hactoolnet/ProcessXci.cs | 12 +- tests/LibHac.Tests/PathToolsTests.cs | 22 +-- 14 files changed, 117 insertions(+), 403 deletions(-) create mode 100644 src/LibHac/IO/FileStorage.cs delete mode 100644 src/LibHac/Pfs.cs delete mode 100644 src/LibHac/Romfs.cs diff --git a/src/LibHac/IO/FileStorage.cs b/src/LibHac/IO/FileStorage.cs new file mode 100644 index 00000000..7de4bdb8 --- /dev/null +++ b/src/LibHac/IO/FileStorage.cs @@ -0,0 +1,31 @@ +using System; + +namespace LibHac.IO +{ + public class FileStorage : Storage + { + private IFile BaseFile { get; } + + public FileStorage(IFile baseFile) + { + BaseFile = baseFile; + } + + protected override void ReadImpl(Span destination, long offset) + { + BaseFile.Read(destination, offset); + } + + protected override void WriteImpl(ReadOnlySpan source, long offset) + { + BaseFile.Write(source, offset); + } + + public override void Flush() + { + BaseFile.Flush(); + } + + public override long Length => BaseFile.GetSize(); + } +} diff --git a/src/LibHac/IO/PartitionFileSystem.cs b/src/LibHac/IO/PartitionFileSystem.cs index aea87a20..fb9ac289 100644 --- a/src/LibHac/IO/PartitionFileSystem.cs +++ b/src/LibHac/IO/PartitionFileSystem.cs @@ -101,8 +101,8 @@ namespace LibHac.IO public enum PartitionFileSystemType { - Pfs0, - Hfs0 + Standard, + Hashed } public class PartitionFileSystemHeader @@ -125,10 +125,10 @@ namespace LibHac.IO switch (Magic) { case "PFS0": - Type = PartitionFileSystemType.Pfs0; + Type = PartitionFileSystemType.Standard; break; case "HFS0": - Type = PartitionFileSystemType.Hfs0; + Type = PartitionFileSystemType.Hashed; break; default: throw new InvalidDataException($"Invalid Partition FS type \"{Magic}\""); @@ -151,7 +151,7 @@ namespace LibHac.IO } - if (Type == PartitionFileSystemType.Hfs0) + if (Type == PartitionFileSystemType.Hashed) { for (int i = 0; i < NumFiles; i++) { @@ -166,9 +166,9 @@ namespace LibHac.IO { switch (type) { - case PartitionFileSystemType.Pfs0: + case PartitionFileSystemType.Standard: return 24; - case PartitionFileSystemType.Hfs0: + case PartitionFileSystemType.Hashed: return 0x40; default: throw new ArgumentOutOfRangeException(nameof(type), type, null); @@ -193,7 +193,7 @@ namespace LibHac.IO Offset = reader.ReadInt64(); Size = reader.ReadInt64(); StringTableOffset = reader.ReadUInt32(); - if (type == PartitionFileSystemType.Hfs0) + if (type == PartitionFileSystemType.Hashed) { HashedRegionSize = reader.ReadInt32(); Reserved = reader.ReadInt64(); diff --git a/src/LibHac/IO/PathTools.cs b/src/LibHac/IO/PathTools.cs index 59934dcf..1363246b 100644 --- a/src/LibHac/IO/PathTools.cs +++ b/src/LibHac/IO/PathTools.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using System.Runtime.CompilerServices; namespace LibHac.IO @@ -13,15 +12,14 @@ namespace LibHac.IO // See the LICENSE file in the project root for more information. public static string Normalize(string inPath) { + // Relative paths aren't a thing for IFileSystem, so assume all paths are absolute + // and add a '/' to the beginning of the path if it doesn't already begin with one + if (inPath.Length == 0 || !IsDirectorySeparator(inPath[0])) inPath = DirectorySeparator + inPath; + ReadOnlySpan path = inPath.AsSpan(); if (path.Length == 0) return DirectorySeparator.ToString(); - if (path[0] != DirectorySeparator) - { - throw new InvalidDataException($"{nameof(path)} must begin with '{DirectorySeparator}'"); - } - Span initialBuffer = stackalloc char[0x200]; var sb = new ValueStringBuilder(initialBuffer); diff --git a/src/LibHac/IO/RomFsFileSystem.cs b/src/LibHac/IO/RomFsFileSystem.cs index 5163ce2e..87c87e4e 100644 --- a/src/LibHac/IO/RomFsFileSystem.cs +++ b/src/LibHac/IO/RomFsFileSystem.cs @@ -161,5 +161,38 @@ namespace LibHac.IO return FileDict.ContainsKey(path); } + + public IStorage GetBaseStorage() + { + return BaseStorage; + } + } + + public class RomfsHeader + { + public long HeaderSize { get; } + public long DirHashTableOffset { get; } + public long DirHashTableSize { get; } + public long DirMetaTableOffset { get; } + public long DirMetaTableSize { get; } + public long FileHashTableOffset { get; } + public long FileHashTableSize { get; } + public long FileMetaTableOffset { get; } + public long FileMetaTableSize { get; } + public long DataOffset { get; } + + public RomfsHeader(BinaryReader reader) + { + HeaderSize = reader.ReadInt64(); + DirHashTableOffset = reader.ReadInt64(); + DirHashTableSize = reader.ReadInt64(); + DirMetaTableOffset = reader.ReadInt64(); + DirMetaTableSize = reader.ReadInt64(); + FileHashTableOffset = reader.ReadInt64(); + FileHashTableSize = reader.ReadInt64(); + FileMetaTableOffset = reader.ReadInt64(); + FileMetaTableSize = reader.ReadInt64(); + DataOffset = reader.ReadInt64(); + } } } diff --git a/src/LibHac/Nca.cs b/src/LibHac/Nca.cs index 569e1f55..1299807d 100644 --- a/src/LibHac/Nca.cs +++ b/src/LibHac/Nca.cs @@ -297,9 +297,11 @@ namespace LibHac { if (Header.ContentType != ContentType.Program) return; - var pfs = new Pfs(OpenSection(ProgramPartitionType.Code, false, IntegrityCheckLevel.ErrorOnInvalid, true)); + var pfs = new PartitionFileSystem(OpenSection(ProgramPartitionType.Code, false, IntegrityCheckLevel.ErrorOnInvalid, true)); - if (!pfs.TryOpenFile("main.npdm", out IStorage npdmStorage)) return; + if (!pfs.FileExists("main.npdm")) return; + + var npdmStorage = new FileStorage(pfs.OpenFile("main.npdm", OpenMode.Read)); Npdm = new Npdm.NpdmBinary(npdmStorage.AsStream(), Keyset); @@ -523,11 +525,11 @@ namespace LibHac case SectionType.Invalid: break; case SectionType.Pfs0: - var pfs0 = new Pfs(storage); + var pfs0 = new PartitionFileSystem(storage); pfs0.Extract(outputDir, logger); break; case SectionType.Romfs: - var romfs = new Romfs(storage); + var romfs = new RomFsFileSystem(storage); romfs.Extract(outputDir, logger); break; case SectionType.Bktr: diff --git a/src/LibHac/Pfs.cs b/src/LibHac/Pfs.cs deleted file mode 100644 index 2416feba..00000000 --- a/src/LibHac/Pfs.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using LibHac.IO; - -namespace LibHac -{ - public class Pfs - { - public PfsHeader Header { get; } - public int HeaderSize { get; } - public PfsFileEntry[] Files { get; } - - private Dictionary FileDict { get; } - private IStorage BaseStorage { get; } - - public Pfs(IStorage storage) - { - using (var reader = new BinaryReader(storage.AsStream(), Encoding.Default, true)) - { - Header = new PfsHeader(reader); - } - - HeaderSize = Header.HeaderSize; - Files = Header.Files; - FileDict = Header.Files.ToDictionary(x => x.Name, x => x); - BaseStorage = storage; - } - - public IStorage OpenFile(string filename) - { - if (!FileDict.TryGetValue(filename, out PfsFileEntry file)) - { - throw new FileNotFoundException(); - } - - return OpenFile(file); - } - - public bool TryOpenFile(string filename, out IStorage storage) - { - if (!FileDict.TryGetValue(filename, out PfsFileEntry file)) - { - storage = null; - return false; - } - - storage = OpenFile(file); - return true; - } - - public IStorage OpenFile(PfsFileEntry file) - { - return BaseStorage.Slice(HeaderSize + file.Offset, file.Size); - } - - public bool FileExists(string filename) - { - return FileDict.ContainsKey(filename); - } - } - - public enum PfsType - { - Pfs0, - Hfs0 - } - - public class PfsHeader - { - public string Magic; - public int NumFiles; - public int StringTableSize; - public long Reserved; - public PfsType Type; - public int HeaderSize; - public PfsFileEntry[] Files; - - public PfsHeader(BinaryReader reader) - { - Magic = reader.ReadAscii(4); - NumFiles = reader.ReadInt32(); - StringTableSize = reader.ReadInt32(); - Reserved = reader.ReadInt32(); - - switch (Magic) - { - case "PFS0": - Type = PfsType.Pfs0; - break; - case "HFS0": - Type = PfsType.Hfs0; - break; - default: - throw new InvalidDataException($"Invalid Partition FS type \"{Magic}\""); - } - - int entrysize = GetFileEntrySize(Type); - int stringTableOffset = 16 + entrysize * NumFiles; - HeaderSize = stringTableOffset + StringTableSize; - - Files = new PfsFileEntry[NumFiles]; - for (int i = 0; i < NumFiles; i++) - { - Files[i] = new PfsFileEntry(reader, Type) { Index = i }; - } - - for (int i = 0; i < NumFiles; i++) - { - reader.BaseStream.Position = stringTableOffset + Files[i].StringTableOffset; - Files[i].Name = reader.ReadAsciiZ(); - } - - - if (Type == PfsType.Hfs0) - { - for (int i = 0; i < NumFiles; i++) - { - reader.BaseStream.Position = HeaderSize + Files[i].Offset; - Files[i].HashValidity = Crypto.CheckMemoryHashTable(reader.ReadBytes(Files[i].HashedRegionSize), Files[i].Hash, 0, Files[i].HashedRegionSize); - } - } - - } - - private static int GetFileEntrySize(PfsType type) - { - switch (type) - { - case PfsType.Pfs0: - return 24; - case PfsType.Hfs0: - return 0x40; - default: - throw new ArgumentOutOfRangeException(nameof(type), type, null); - } - } - } - - public class PfsFileEntry - { - public int Index; - public long Offset; - public long Size; - public uint StringTableOffset; - public long Reserved; - public int HashedRegionSize; - public byte[] Hash; - public string Name; - public Validity HashValidity = Validity.Unchecked; - - public PfsFileEntry(BinaryReader reader, PfsType type) - { - Offset = reader.ReadInt64(); - Size = reader.ReadInt64(); - StringTableOffset = reader.ReadUInt32(); - if (type == PfsType.Hfs0) - { - HashedRegionSize = reader.ReadInt32(); - Reserved = reader.ReadInt64(); - Hash = reader.ReadBytes(Crypto.Sha256DigestSize); - } - else - { - Reserved = reader.ReadUInt32(); - } - } - } - - public static class PfsExtensions - { - public static void Extract(this Pfs pfs, string outDir, IProgressReport logger = null) - { - foreach (PfsFileEntry file in pfs.Header.Files) - { - IStorage storage = pfs.OpenFile(file); - string outName = Path.Combine(outDir, file.Name); - string dir = Path.GetDirectoryName(outName); - if (!string.IsNullOrWhiteSpace(dir)) Directory.CreateDirectory(dir); - - using (var outFile = new FileStream(outName, FileMode.Create, FileAccess.ReadWrite)) - { - logger?.LogMessage(file.Name); - storage.CopyToStream(outFile, storage.Length, logger); - } - } - } - } -} diff --git a/src/LibHac/Romfs.cs b/src/LibHac/Romfs.cs deleted file mode 100644 index 25bc1ae2..00000000 --- a/src/LibHac/Romfs.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using LibHac.IO; - -namespace LibHac -{ - public class Romfs - { - public const int IvfcMaxLevel = 6; - public RomfsHeader Header { get; } - public List Directories { get; } = new List(); - public List Files { get; } = new List(); - public RomfsDir RootDir { get; } - - public Dictionary FileDict { get; } - private IStorage BaseStorage { get; } - - public Romfs(IStorage storage) - { - BaseStorage = storage; - - byte[] dirMetaTable; - byte[] fileMetaTable; - using (var reader = new BinaryReader(BaseStorage.AsStream(), Encoding.Default, true)) - { - Header = new RomfsHeader(reader); - reader.BaseStream.Position = Header.DirMetaTableOffset; - dirMetaTable = reader.ReadBytes((int)Header.DirMetaTableSize); - reader.BaseStream.Position = Header.FileMetaTableOffset; - fileMetaTable = reader.ReadBytes((int)Header.FileMetaTableSize); - } - - using (var reader = new BinaryReader(new MemoryStream(dirMetaTable))) - { - int position = 0; - while (position + 20 < Header.DirMetaTableSize) - { - var dir = new RomfsDir(reader) { Offset = position }; - Directories.Add(dir); - if (dir.ParentDirOffset == position) RootDir = dir; - position = (int)reader.BaseStream.Position; - } - } - - using (var reader = new BinaryReader(new MemoryStream(fileMetaTable))) - { - int position = 0; - while (position + 20 < Header.FileMetaTableSize) - { - var file = new RomfsFile(reader) { Offset = position }; - Files.Add(file); - position = (int)reader.BaseStream.Position; - } - } - - SetReferences(); - RomfsEntry.ResolveFilenames(Files); - RomfsEntry.ResolveFilenames(Directories); - FileDict = Files.ToDictionary(x => x.FullPath, x => x); - } - - public IStorage OpenFile(string filename) - { - if (!FileDict.TryGetValue(filename, out RomfsFile file)) - { - throw new FileNotFoundException(); - } - - return OpenFile(file); - } - - public IStorage OpenFile(RomfsFile file) - { - return BaseStorage.Slice(Header.DataOffset + file.DataOffset, file.DataLength); - } - - public byte[] GetFile(string filename) - { - IStorage storage = OpenFile(filename); - var file = new byte[storage.Length]; - - storage.Read(file, 0); - - return file; - } - - public bool FileExists(string filename) => FileDict.ContainsKey(filename); - - public IStorage OpenRawStream() => BaseStorage.Slice(0); - - private void SetReferences() - { - Dictionary dirDict = Directories.ToDictionary(x => x.Offset, x => x); - Dictionary fileDict = Files.ToDictionary(x => x.Offset, x => x); - - foreach (RomfsDir dir in Directories) - { - if (dir.ParentDirOffset >= 0 && dir.ParentDirOffset != dir.Offset) dir.ParentDir = dirDict[dir.ParentDirOffset]; - if (dir.NextSiblingOffset >= 0) dir.NextSibling = dirDict[dir.NextSiblingOffset]; - if (dir.FirstChildOffset >= 0) dir.FirstChild = dirDict[dir.FirstChildOffset]; - if (dir.FirstFileOffset >= 0) dir.FirstFile = fileDict[dir.FirstFileOffset]; - if (dir.NextDirHashOffset >= 0) dir.NextDirHash = dirDict[dir.NextDirHashOffset]; - } - - foreach (RomfsFile file in Files) - { - if (file.ParentDirOffset >= 0) file.ParentDir = dirDict[file.ParentDirOffset]; - if (file.NextSiblingOffset >= 0) file.NextSibling = fileDict[file.NextSiblingOffset]; - if (file.NextFileHashOffset >= 0) file.NextFileHash = fileDict[file.NextFileHashOffset]; - } - } - } - - public class RomfsHeader - { - public long HeaderSize { get; } - public long DirHashTableOffset { get; } - public long DirHashTableSize { get; } - public long DirMetaTableOffset { get; } - public long DirMetaTableSize { get; } - public long FileHashTableOffset { get; } - public long FileHashTableSize { get; } - public long FileMetaTableOffset { get; } - public long FileMetaTableSize { get; } - public long DataOffset { get; } - - public RomfsHeader(BinaryReader reader) - { - HeaderSize = reader.ReadInt64(); - DirHashTableOffset = reader.ReadInt64(); - DirHashTableSize = reader.ReadInt64(); - DirMetaTableOffset = reader.ReadInt64(); - DirMetaTableSize = reader.ReadInt64(); - FileHashTableOffset = reader.ReadInt64(); - FileHashTableSize = reader.ReadInt64(); - FileMetaTableOffset = reader.ReadInt64(); - FileMetaTableSize = reader.ReadInt64(); - DataOffset = reader.ReadInt64(); - } - } - - public static class RomfsExtensions - { - public static void Extract(this Romfs romfs, string outDir, IProgressReport logger = null) - { - foreach (RomfsFile file in romfs.Files) - { - IStorage storage = romfs.OpenFile(file); - string outName = outDir + file.FullPath; - string dir = Path.GetDirectoryName(outName); - if (!string.IsNullOrWhiteSpace(dir)) Directory.CreateDirectory(dir); - - using (var outFile = new FileStream(outName, FileMode.Create, FileAccess.ReadWrite)) - { - logger?.LogMessage(file.FullPath); - storage.CopyToStream(outFile, storage.Length, logger); - } - } - } - } -} diff --git a/src/LibHac/SwitchFs.cs b/src/LibHac/SwitchFs.cs index 93d29957..e7fb1d69 100644 --- a/src/LibHac/SwitchFs.cs +++ b/src/LibHac/SwitchFs.cs @@ -149,10 +149,10 @@ namespace LibHac // Meta contents always have 1 Partition FS section with 1 file in it IStorage sect = nca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true); - var pfs0 = new Pfs(sect); - IStorage file = pfs0.OpenFile(pfs0.Files[0]); + var pfs0 = new PartitionFileSystem(sect); + IFile file = pfs0.OpenFile(pfs0.Files[0], OpenMode.Read); - var metadata = new Cnmt(file.AsStream()); + var metadata = new Cnmt(new FileStorage(file).AsStream()); title.Id = metadata.TitleId; title.Version = metadata.TitleVersion; title.Metadata = metadata; @@ -188,8 +188,8 @@ namespace LibHac { foreach (Title title in Titles.Values.Where(x => x.ControlNca != null)) { - var romfs = new Romfs(title.ControlNca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true)); - IStorage control = romfs.OpenFile("/control.nacp"); + var romfs = new RomFsFileSystem(title.ControlNca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true)); + IStorage control = new FileStorage(romfs.OpenFile("control.nacp", OpenMode.Read)); title.Control = new Nacp(control.AsStream()); diff --git a/src/LibHac/Xci.cs b/src/LibHac/Xci.cs index 81677391..e95b0ff7 100644 --- a/src/LibHac/Xci.cs +++ b/src/LibHac/Xci.cs @@ -25,9 +25,9 @@ namespace LibHac public Xci(Keyset keyset, IStorage storage) { Header = new XciHeader(keyset, storage.AsStream()); - IStorage hfs0Stream = storage.Slice(Header.PartitionFsHeaderAddress); + IStorage hfs0Storage = storage.Slice(Header.PartitionFsHeaderAddress); - RootPartition = new XciPartition(hfs0Stream) + RootPartition = new XciPartition(hfs0Storage) { Name = RootPartitionName, Offset = Header.PartitionFsHeaderAddress, @@ -36,11 +36,11 @@ namespace LibHac Partitions.Add(RootPartition); - foreach (PfsFileEntry file in RootPartition.Files) + foreach (PartitionFileEntry file in RootPartition.Files) { - IStorage partitionStorage = RootPartition.OpenFile(file); + IFile partitionFile = RootPartition.OpenFile(file, OpenMode.Read); - var partition = new XciPartition(partitionStorage) + var partition = new XciPartition(new FileStorage(partitionFile)) { Name = file.Name, Offset = Header.PartitionFsHeaderAddress + RootPartition.HeaderSize + file.Offset, @@ -57,7 +57,7 @@ namespace LibHac } } - public class XciPartition : Pfs + public class XciPartition : PartitionFileSystem { public string Name { get; internal set; } public long Offset { get; internal set; } diff --git a/src/hactoolnet/ProcessNca.cs b/src/hactoolnet/ProcessNca.cs index 2b13b6c3..433cc28d 100644 --- a/src/hactoolnet/ProcessNca.cs +++ b/src/hactoolnet/ProcessNca.cs @@ -44,7 +44,7 @@ namespace hactoolnet if (ctx.Options.ListRomFs && nca.Sections[1] != null) { - var romfs = new Romfs(nca.OpenSection(1, false, ctx.Options.IntegrityLevel, true)); + var romfs = new RomFsFileSystem(nca.OpenSection(1, false, ctx.Options.IntegrityLevel, true)); foreach (RomfsFile romfsFile in romfs.Files) { diff --git a/src/hactoolnet/ProcessRomfs.cs b/src/hactoolnet/ProcessRomfs.cs index c4ed0ec7..27a07832 100644 --- a/src/hactoolnet/ProcessRomfs.cs +++ b/src/hactoolnet/ProcessRomfs.cs @@ -10,12 +10,12 @@ namespace hactoolnet { using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read)) { - var romfs = new Romfs(file.AsStorage()); + var romfs = new RomFsFileSystem(file.AsStorage()); Process(ctx, romfs); } } - public static void Process(Context ctx, Romfs romfs) + public static void Process(Context ctx, RomFsFileSystem romfs) { if (ctx.Options.ListRomFs) { @@ -29,7 +29,7 @@ namespace hactoolnet { using (var outFile = new FileStream(ctx.Options.RomfsOut, FileMode.Create, FileAccess.ReadWrite)) { - IStorage romfsStorage = romfs.OpenRawStream(); + IStorage romfsStorage = romfs.GetBaseStorage(); romfsStorage.CopyToStream(outFile, romfsStorage.Length, ctx.Logger); } } diff --git a/src/hactoolnet/ProcessSwitchFs.cs b/src/hactoolnet/ProcessSwitchFs.cs index f4eae639..e955067f 100644 --- a/src/hactoolnet/ProcessSwitchFs.cs +++ b/src/hactoolnet/ProcessSwitchFs.cs @@ -101,7 +101,7 @@ namespace hactoolnet if (ctx.Options.RomfsOutDir != null) { - var romfs = new Romfs(title.MainNca.OpenSection(section.SectionNum, false, ctx.Options.IntegrityLevel, true)); + var romfs = new RomFsFileSystem(title.MainNca.OpenSection(section.SectionNum, false, ctx.Options.IntegrityLevel, true)); romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger); } diff --git a/src/hactoolnet/ProcessXci.cs b/src/hactoolnet/ProcessXci.cs index ea4e27bd..5bd4907b 100644 --- a/src/hactoolnet/ProcessXci.cs +++ b/src/hactoolnet/ProcessXci.cs @@ -51,9 +51,9 @@ namespace hactoolnet return; } - foreach (PfsFileEntry sub in root.Files) + foreach (PartitionFileEntry sub in root.Files) { - var subPfs = new Pfs(root.OpenFile(sub)); + var subPfs = new PartitionFileSystem(new FileStorage(root.OpenFile(sub, OpenMode.Read))); string subDir = Path.Combine(ctx.Options.OutDir, sub.Name); subPfs.Extract(subDir, ctx.Logger); @@ -109,7 +109,7 @@ namespace hactoolnet if (ctx.Options.RomfsOutDir != null) { - var romfs = new Romfs(mainNca.OpenSection(romfsSection.SectionNum, false, ctx.Options.IntegrityLevel, true)); + var romfs = new RomFsFileSystem(mainNca.OpenSection(romfsSection.SectionNum, false, ctx.Options.IntegrityLevel, true)); romfs.Extract(ctx.Options.RomfsOutDir, ctx.Logger); } @@ -131,9 +131,9 @@ namespace hactoolnet Nca mainNca = null; - foreach (PfsFileEntry fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca"))) + foreach (PartitionFileEntry fileEntry in xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca"))) { - IStorage ncaStorage = xci.SecurePartition.OpenFile(fileEntry); + IStorage ncaStorage = new FileStorage(xci.SecurePartition.OpenFile(fileEntry, OpenMode.Read)); var nca = new Nca(ctx.Keyset, ncaStorage, true); if (nca.Header.ContentType == ContentType.Program) @@ -182,7 +182,7 @@ namespace hactoolnet { for (int i = 0; i < partition.Files.Length; i++) { - PfsFileEntry file = partition.Files[i]; + PartitionFileEntry file = partition.Files[i]; string label = i == 0 ? " Files:" : ""; string offsets = $"{file.Offset:x12}-{file.Offset + file.Size:x12}{file.HashValidity.GetValidityString()}"; diff --git a/tests/LibHac.Tests/PathToolsTests.cs b/tests/LibHac.Tests/PathToolsTests.cs index f8764ff2..6476f8ca 100644 --- a/tests/LibHac.Tests/PathToolsTests.cs +++ b/tests/LibHac.Tests/PathToolsTests.cs @@ -1,5 +1,4 @@ -using System.IO; -using LibHac.IO; +using LibHac.IO; using Xunit; namespace LibHac.Tests @@ -18,13 +17,24 @@ namespace LibHac.Tests new object[] {"/a/../../..", "/"}, new object[] {"/a/../../../a/b/c", "/a/b/c"}, new object[] {"//a/b//.//c", "/a/b/c"}, + new object[] {"/../a/b/c/.", "/a/b/c"}, + new object[] {"/./a/b/c/.", "/a/b/c"}, new object[] {"/a/b/c/", "/a/b/c/"}, new object[] {"/a/./b/../c/", "/a/c/"}, + new object[] {"/./b/../c/", "/c/"}, new object[] {"/a/../../../", "/"}, new object[] {"//a/b//.//c/", "/a/b/c/"}, - new object[] {@"/tmp/../", @"/"}, + new object[] {"/tmp/../", "/"}, + + new object[] {"a", "/a"}, + new object[] {"a/../../../a/b/c", "/a/b/c"}, + new object[] {"./b/../c/", "/c/"}, + new object[] {".", "/"}, + new object[] {"..", "/"}, + new object[] {"../a/b/c/.", "/a/b/c"}, + new object[] {"./a/b/c/.", "/a/b/c"}, }; [Theory] @@ -35,11 +45,5 @@ namespace LibHac.Tests Assert.Equal(expected, actual); } - - [Fact] - public static void NormalizeThrowsOnInvalidStartChar() - { - Assert.Throws(() => PathTools.Normalize(@"c:\a\b\c")); - } } }