mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add IFileSystem interface
I don't know about this. It seems really easy to screw something up. Allows using the same code for reading the raw nand and reading a normal file system
This commit is contained in:
parent
14da035273
commit
f1b660b95f
8 changed files with 166 additions and 26 deletions
|
@ -15,7 +15,31 @@ namespace NandReader
|
|||
Console.WriteLine("Usage: NandReader raw_nand_dump_file");
|
||||
return;
|
||||
}
|
||||
DumpTickets(args[0]);
|
||||
ReadSwitchFs(args[0]);
|
||||
}
|
||||
|
||||
private static void ReadSwitchFs(string nandFile)
|
||||
{
|
||||
using (var logger = new ProgressBar())
|
||||
using (var stream = new FileStream(nandFile, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
var keyset = OpenKeyset();
|
||||
var nand = new Nand(stream, keyset);
|
||||
var user = nand.OpenSystemPartition();
|
||||
var sdfs = new SdFs(keyset, user);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReadCalibration(string nandFile)
|
||||
{
|
||||
using (var logger = new ProgressBar())
|
||||
using (var stream = new FileStream(nandFile, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
var keyset = OpenKeyset();
|
||||
var nand = new Nand(stream, keyset);
|
||||
var prodinfo = nand.OpenProdInfo();
|
||||
var calibration = new Calibration(prodinfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DumpTickets(string nandFile)
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace hactoolnet
|
|||
|
||||
private static void ProcessSwitchFs(Context ctx)
|
||||
{
|
||||
var switchFs = new SdFs(ctx.Keyset, ctx.Options.InFile);
|
||||
var switchFs = new SdFs(ctx.Keyset, new FileSystem(ctx.Options.InFile));
|
||||
|
||||
if (ctx.Options.ListTitles)
|
||||
{
|
||||
|
|
|
@ -37,40 +37,40 @@ namespace libhac.Nand
|
|||
return decStream;
|
||||
}
|
||||
|
||||
public FatFileSystem OpenProdInfoF()
|
||||
public NandPartition OpenProdInfoF()
|
||||
{
|
||||
var encStream = ProdInfoF.Open();
|
||||
var xts = XtsAes128.Create(Keyset.bis_keys[0]);
|
||||
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
||||
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
||||
return fat;
|
||||
return new NandPartition(fat);
|
||||
}
|
||||
|
||||
public FatFileSystem OpenSafePartition()
|
||||
public NandPartition OpenSafePartition()
|
||||
{
|
||||
var encStream = Safe.Open();
|
||||
var xts = XtsAes128.Create(Keyset.bis_keys[1]);
|
||||
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
||||
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
||||
return fat;
|
||||
return new NandPartition(fat);
|
||||
}
|
||||
|
||||
public FatFileSystem OpenSystemPartition()
|
||||
public NandPartition OpenSystemPartition()
|
||||
{
|
||||
var encStream = System.Open();
|
||||
var xts = XtsAes128.Create(Keyset.bis_keys[2]);
|
||||
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
||||
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
||||
return fat;
|
||||
return new NandPartition(fat);
|
||||
}
|
||||
|
||||
public FatFileSystem OpenUserPartition()
|
||||
public NandPartition OpenUserPartition()
|
||||
{
|
||||
var encStream = User.Open();
|
||||
var xts = XtsAes128.Create(Keyset.bis_keys[3]);
|
||||
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
||||
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
||||
return fat;
|
||||
return new NandPartition(fat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
53
libhac.Nand/NandPartition.cs
Normal file
53
libhac.Nand/NandPartition.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using DiscUtils.Fat;
|
||||
|
||||
namespace libhac.Nand
|
||||
{
|
||||
public class NandPartition : IFileSystem
|
||||
{
|
||||
public FatFileSystem Fs { get; }
|
||||
|
||||
public NandPartition(FatFileSystem fileSystem)
|
||||
{
|
||||
Fs = fileSystem;
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
return Fs.FileExists(path);
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string path)
|
||||
{
|
||||
return Fs.DirectoryExists(path);
|
||||
}
|
||||
|
||||
public Stream OpenFile(string path, FileMode mode)
|
||||
{
|
||||
return Fs.OpenFile(path, mode);
|
||||
}
|
||||
|
||||
public Stream OpenFile(string path, FileMode mode, FileAccess access)
|
||||
{
|
||||
return Fs.OpenFile(path, mode, access);
|
||||
}
|
||||
|
||||
public string[] GetFileSystemEntries(string path, string searchPattern)
|
||||
{
|
||||
return Fs.GetFileSystemEntries(path, searchPattern);
|
||||
}
|
||||
|
||||
public string[] GetFileSystemEntries(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
var files = Fs.GetFiles(path, searchPattern, searchOption);
|
||||
var dirs = Fs.GetDirectories(path, searchPattern, searchOption);
|
||||
return files.Concat(dirs).ToArray();
|
||||
}
|
||||
|
||||
public string GetFullPath(string path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
49
libhac/FileSystem.cs
Normal file
49
libhac/FileSystem.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System.IO;
|
||||
|
||||
namespace libhac
|
||||
{
|
||||
public class FileSystem : IFileSystem
|
||||
{
|
||||
public string Root { get; }
|
||||
|
||||
public FileSystem(string rootDir)
|
||||
{
|
||||
Root = Path.GetFullPath(rootDir);
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
return File.Exists(Path.Combine(Root, path));
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string path)
|
||||
{
|
||||
return Directory.Exists(Path.Combine(Root, path));
|
||||
}
|
||||
|
||||
public Stream OpenFile(string path, FileMode mode)
|
||||
{
|
||||
return new FileStream(path, mode);
|
||||
}
|
||||
|
||||
public Stream OpenFile(string path, FileMode mode, FileAccess access)
|
||||
{
|
||||
return new FileStream(path, mode, access);
|
||||
}
|
||||
|
||||
public string[] GetFileSystemEntries(string path, string searchPattern)
|
||||
{
|
||||
return Directory.GetFileSystemEntries(Path.Combine(Root, path), searchPattern);
|
||||
}
|
||||
|
||||
public string[] GetFileSystemEntries(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
return Directory.GetFileSystemEntries(Path.Combine(Root, path), searchPattern, searchOption);
|
||||
}
|
||||
|
||||
public string GetFullPath(string path)
|
||||
{
|
||||
return Path.Combine(Root, path);
|
||||
}
|
||||
}
|
||||
}
|
15
libhac/IFileSystem.cs
Normal file
15
libhac/IFileSystem.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System.IO;
|
||||
|
||||
namespace libhac
|
||||
{
|
||||
public interface IFileSystem
|
||||
{
|
||||
bool FileExists(string path);
|
||||
bool DirectoryExists(string path);
|
||||
Stream OpenFile(string path, FileMode mode);
|
||||
Stream OpenFile(string path, FileMode mode, FileAccess access);
|
||||
string[] GetFileSystemEntries(string path, string searchPattern);
|
||||
string[] GetFileSystemEntries(string path, string searchPattern, SearchOption searchOption);
|
||||
string GetFullPath(string path);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using libhac.XTSSharp;
|
||||
|
|
|
@ -10,25 +10,25 @@ namespace libhac
|
|||
public class SdFs : IDisposable
|
||||
{
|
||||
public Keyset Keyset { get; }
|
||||
public string RootDir { get; }
|
||||
public IFileSystem Fs { get; }
|
||||
public string ContentsDir { get; }
|
||||
|
||||
public Dictionary<string, Nca> Ncas { get; } = new Dictionary<string, Nca>(StringComparer.OrdinalIgnoreCase);
|
||||
public Dictionary<ulong, Title> Titles { get; } = new Dictionary<ulong, Title>();
|
||||
public Dictionary<ulong, Application> Applications { get; } = new Dictionary<ulong, Application>();
|
||||
|
||||
public SdFs(Keyset keyset, string rootDir)
|
||||
public SdFs(Keyset keyset, IFileSystem fs)
|
||||
{
|
||||
RootDir = rootDir;
|
||||
Fs = fs;
|
||||
Keyset = keyset;
|
||||
|
||||
if (Directory.Exists(Path.Combine(rootDir, "Nintendo")))
|
||||
if (fs.DirectoryExists("Nintendo"))
|
||||
{
|
||||
ContentsDir = Path.Combine(rootDir, "Nintendo", "Contents");
|
||||
ContentsDir = fs.GetFullPath(Path.Combine("Nintendo", "Contents"));
|
||||
}
|
||||
else if (Directory.Exists(Path.Combine(rootDir, "Contents")))
|
||||
else if (fs.DirectoryExists("Contents"))
|
||||
{
|
||||
ContentsDir = Path.Combine(rootDir, "Contents");
|
||||
ContentsDir = fs.GetFullPath("Contents");
|
||||
}
|
||||
|
||||
if (ContentsDir == null)
|
||||
|
@ -44,7 +44,7 @@ namespace libhac
|
|||
|
||||
private void OpenAllNcas()
|
||||
{
|
||||
string[] files = Directory.GetFileSystemEntries(ContentsDir, "*.nca", SearchOption.AllDirectories).ToArray();
|
||||
string[] files = Fs.GetFileSystemEntries(ContentsDir, "*.nca", SearchOption.AllDirectories);
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ namespace libhac
|
|||
try
|
||||
{
|
||||
bool isNax0;
|
||||
Stream stream = OpenSplitNcaStream(file);
|
||||
Stream stream = OpenSplitNcaStream(Fs, file);
|
||||
if (stream == null) continue;
|
||||
|
||||
using (var reader = new BinaryReader(stream, Encoding.Default, true))
|
||||
|
@ -178,26 +178,26 @@ namespace libhac
|
|||
}
|
||||
}
|
||||
|
||||
internal static Stream OpenSplitNcaStream(string path)
|
||||
internal static Stream OpenSplitNcaStream(IFileSystem fs, string path)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
List<Stream> streams = new List<Stream>();
|
||||
|
||||
if (Directory.Exists(path))
|
||||
if (fs.DirectoryExists(path))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var partName = Path.Combine(path, $"{files.Count:D2}");
|
||||
if (!File.Exists(partName)) break;
|
||||
if (!fs.FileExists(partName)) break;
|
||||
|
||||
files.Add(partName);
|
||||
}
|
||||
}
|
||||
else if (File.Exists(path))
|
||||
else if (fs.FileExists(path))
|
||||
{
|
||||
if (Path.GetFileName(path) != "00")
|
||||
{
|
||||
return new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||
return fs.OpenFile(path, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
files.Add(path);
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ namespace libhac
|
|||
|
||||
foreach (var file in files)
|
||||
{
|
||||
streams.Add(new FileStream(file, FileMode.Open, FileAccess.Read));
|
||||
streams.Add(fs.OpenFile(file, FileMode.Open, FileAccess.Read));
|
||||
}
|
||||
|
||||
if (streams.Count == 0) return null;
|
||||
|
|
Loading…
Reference in a new issue