diff --git a/src/LibHac.Nand/Nand.cs b/src/LibHac.Nand/Nand.cs index d35d8085..c6a8204b 100644 --- a/src/LibHac.Nand/Nand.cs +++ b/src/LibHac.Nand/Nand.cs @@ -12,6 +12,7 @@ namespace LibHac.Nand { private GuidPartitionInfo ProdInfo { get; } private GuidPartitionInfo ProdInfoF { get; } + private GuidPartitionInfo[] Package2 { get; } private GuidPartitionInfo Safe { get; } private GuidPartitionInfo System { get; } private GuidPartitionInfo User { get; } @@ -23,6 +24,16 @@ namespace LibHac.Nand GuidPartitionInfo[] partitions = disc.Partitions.Select(x => (GuidPartitionInfo)x).ToArray(); ProdInfo = partitions.FirstOrDefault(x => x.Name == "PRODINFO"); ProdInfoF = partitions.FirstOrDefault(x => x.Name == "PRODINFOF"); + Package2 = new GuidPartitionInfo[] + { + partitions.FirstOrDefault(x => x.Name == "BCPKG2-1-Normal-Main"), + partitions.FirstOrDefault(x => x.Name == "BCPKG2-2-Normal-Sub"), + partitions.FirstOrDefault(x => x.Name == "BCPKG2-3-SafeMode-Main"), + partitions.FirstOrDefault(x => x.Name == "BCPKG2-4-SafeMode-Sub"), + partitions.FirstOrDefault(x => x.Name == "BCPKG2-5-Repair-Main"), + partitions.FirstOrDefault(x => x.Name == "BCPKG2-6-Repair-Sub") + }; + Safe = partitions.FirstOrDefault(x => x.Name == "SAFE"); System = partitions.FirstOrDefault(x => x.Name == "SYSTEM"); User = partitions.FirstOrDefault(x => x.Name == "USER"); @@ -46,6 +57,11 @@ namespace LibHac.Nand return new NandPartition(fat); } + public IStorage OpenPackage2(int index) + { + return Package2[index].Open().AsStorage(); + } + public NandPartition OpenSafePartition() { IStorage encStorage = Safe.Open().AsStorage(); diff --git a/src/LibHac.Nand/NandPartition.cs b/src/LibHac.Nand/NandPartition.cs index 4c8cc545..5c5734b6 100644 --- a/src/LibHac.Nand/NandPartition.cs +++ b/src/LibHac.Nand/NandPartition.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using DiscUtils.Fat; +using LibHac.IO; namespace LibHac.Nand { @@ -9,7 +10,7 @@ namespace LibHac.Nand { public FatFileSystem Fs { get; } - public override string PathSeperator => "/"; + public override string PathSeperator => "\\"; public override IDirectory RootDirectory => new IDirectory(this, ""); public NandPartition(FatFileSystem fileSystem) @@ -27,14 +28,14 @@ namespace LibHac.Nand return Fs.DirectoryExists(directory.Path); } - public new virtual Stream OpenFile(IFile file, FileMode mode) + public new virtual IStorage OpenFile(IFile file, FileMode mode) { - return Fs.OpenFile(file.Path, mode); + return Fs.OpenFile(file.Path, mode).AsStorage(); } - public override Stream OpenFile(IFile file, FileMode mode, FileAccess access) + public override IStorage OpenFile(IFile file, FileMode mode, FileAccess access) { - return Fs.OpenFile(file.Path, mode, access); + return Fs.OpenFile(file.Path, mode, access).AsStorage(); } public new virtual IFileSytemEntry[] GetFileSystemEntries(IDirectory directory, string searchPattern) @@ -46,12 +47,12 @@ namespace LibHac.Nand { string[] files = Fs.GetFiles(directory.Path, searchPattern, searchOption); string[] dirs = Fs.GetDirectories(directory.Path, searchPattern, searchOption); - IFileSytemEntry[] entries = new IFileSytemEntry[files.Length + dirs.Length]; - for (int i = 0; i < files.Length; i++) - entries[i] = new IFile(this, files[i]); + List entries = new List(); for (int i = 0; i < dirs.Length; i++) - entries[i] = new IDirectory(this, files[i]); - return entries; + entries.Add(new IDirectory(this, dirs[i])); + for (int i = 0; i < files.Length; i++) + entries.Add(new IFile(this, files[i])); + return entries.ToArray(); } public string GetFullPath(string path) diff --git a/src/LibHac/FileSystem/IFileSystem.cs b/src/LibHac/FileSystem/IFileSystem.cs index a10325db..1e42c187 100644 --- a/src/LibHac/FileSystem/IFileSystem.cs +++ b/src/LibHac/FileSystem/IFileSystem.cs @@ -1,4 +1,5 @@ -using System.IO; +using LibHac.IO; +using System.IO; namespace LibHac { @@ -11,11 +12,11 @@ namespace LibHac public abstract bool FileExists(IFile path); public abstract bool DirectoryExists(IDirectory path); - public Stream OpenFile(IFile file, FileMode mode) + public IStorage OpenFile(IFile file, FileMode mode) { return OpenFile(file, mode, FileAccess.ReadWrite); } - public abstract Stream OpenFile(IFile file, FileMode mode, FileAccess access); + public abstract IStorage OpenFile(IFile file, FileMode mode, FileAccess access); public IFileSytemEntry[] GetFileSystemEntries(IDirectory directory, string searchPattern) { @@ -46,30 +47,33 @@ namespace LibHac } - public interface IFileSytemEntry + public abstract class IFileSytemEntry { - IFileSystem FileSystem { get; } - string Path { get; } - bool Exists { get; } - } - - public class IDirectory : IFileSytemEntry - { - public IFileSystem FileSystem { get; } - public string Path { get; } + public abstract IFileSystem FileSystem { get; } + public abstract string Path { get; } + public abstract bool Exists { get; } public IDirectory Parent { get { int index = Path.LastIndexOf(FileSystem.PathSeperator); - return FileSystem.GetDirectory(Path.Substring(0, index)); + if(index > 0) + return FileSystem.GetDirectory(Path.Substring(0, index)); + return null; } } + } + + public class IDirectory : IFileSytemEntry + { + public override IFileSystem FileSystem { get; } + public override string Path { get; } + public override bool Exists => FileSystem.DirectoryExists(this); + public IFile[] Files => FileSystem.GetFiles(this); public IDirectory[] Directories => FileSystem.GetDirectories(this); - public bool Exists => FileSystem.DirectoryExists(this); public IDirectory(IFileSystem filesystem, string path) { @@ -100,36 +104,26 @@ namespace LibHac public class IFile : IFileSytemEntry { - public IFileSystem FileSystem { get; } - public string Path { get; } + public override IFileSystem FileSystem { get; } + public override string Path { get; } + public override bool Exists => FileSystem.FileExists(this); public string Name => System.IO.Path.GetFileNameWithoutExtension(Path); public string Extension => System.IO.Path.GetExtension(Path); public string FileName => System.IO.Path.GetFileName(Path); - public bool Exists => FileSystem.FileExists(this); - - public IDirectory Parent { - get - { - int index = Path.LastIndexOf(FileSystem.PathSeperator); - return FileSystem.GetDirectory(Path.Substring(0, index)); - } - } - - public IFile(IFileSystem filesystem, string path) { FileSystem = filesystem; Path = path; } - public Stream Open(FileMode mode) + public IStorage Open(FileMode mode) { return FileSystem.OpenFile(this, mode); } - public Stream Open(FileMode mode, FileAccess access) + public IStorage Open(FileMode mode, FileAccess access) { return FileSystem.OpenFile(this, mode, access); } diff --git a/src/LibHac/FileSystem/LocalFileSystem.cs b/src/LibHac/FileSystem/LocalFileSystem.cs index ce325424..863df473 100644 --- a/src/LibHac/FileSystem/LocalFileSystem.cs +++ b/src/LibHac/FileSystem/LocalFileSystem.cs @@ -1,4 +1,5 @@ -using System; +using LibHac.IO; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -26,9 +27,9 @@ namespace LibHac return Directory.Exists(Path.Combine(Root, directory.Path)); } - public override Stream OpenFile(IFile file, FileMode mode, FileAccess access) + public override IStorage OpenFile(IFile file, FileMode mode, FileAccess access) { - return new FileStream(GetFullPath(file), mode, access); + return new FileStream(GetFullPath(file), mode, access).AsStorage(); } public override IFileSytemEntry[] GetFileSystemEntries(IDirectory path, string searchPattern, SearchOption searchOption) diff --git a/src/LibHac/Pfs0Builder.cs b/src/LibHac/Pfs0Builder.cs index b8f9ceb7..bcb8e008 100644 --- a/src/LibHac/Pfs0Builder.cs +++ b/src/LibHac/Pfs0Builder.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using LibHac.IO; +using System.Collections.Generic; using System.IO; namespace LibHac @@ -8,13 +9,13 @@ namespace LibHac private List Entries { get; } = new List(); private long DataLength { get; set; } - public void AddFile(string filename, Stream stream) + public void AddFile(string filename, IStorage storage) { var entry = new Entry { Name = filename, - Stream = stream, - Length = stream.Length, + Storage = storage, + Length = storage.Length, Offset = DataLength }; @@ -57,8 +58,7 @@ namespace LibHac foreach (Entry entry in Entries) { logger?.LogMessage(entry.Name); - entry.Stream.Position = 0; - entry.Stream.CopyStream(output, entry.Length, logger); + entry.Storage.CopyTo(output.AsStorage(), logger); } logger?.SetTotal(0); } @@ -66,7 +66,7 @@ namespace LibHac private class Entry { public string Name; - public Stream Stream; + public IStorage Storage; public long Length; public long Offset; public int StringOffset; diff --git a/src/LibHac/SwitchFs.cs b/src/LibHac/SwitchFs.cs index 926e950a..e9325c13 100644 --- a/src/LibHac/SwitchFs.cs +++ b/src/LibHac/SwitchFs.cs @@ -128,7 +128,7 @@ namespace LibHac try { - IStorage storage = Fs.OpenFile(file, FileMode.Open).AsStorage(); + IStorage storage = Fs.OpenFile(file, FileMode.Open); string sdPath = Util.GetRelativePath(file.Path, SaveDir.Path).Replace("\\", "/"); var nax0 = new Nax0(Keyset, storage, sdPath, false); @@ -256,9 +256,8 @@ namespace LibHac { IFile file = (IFile)nca; if (file.Name != "00") - { - return file.Open(FileMode.Open, FileAccess.Read).AsStorage(); - } + return file.Open(FileMode.Open, FileAccess.Read); + files.Add(file); } else if (typeof(IDirectory).IsAssignableFrom(nca.GetType())) @@ -277,10 +276,10 @@ namespace LibHac throw new FileNotFoundException("Could not find the input file or directory"); if (files.Count == 1) - return files[0].Open(FileMode.Open, FileAccess.Read).AsStorage(); + return files[0].Open(FileMode.Open, FileAccess.Read); foreach (IFile file in files) - storages.Add(file.Open( FileMode.Open, FileAccess.Read).AsStorage()); + storages.Add(file.Open( FileMode.Open, FileAccess.Read)); if (storages.Count == 0) return null; //todo