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");
|
Console.WriteLine("Usage: NandReader raw_nand_dump_file");
|
||||||
return;
|
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)
|
private static void DumpTickets(string nandFile)
|
||||||
|
|
|
@ -123,7 +123,7 @@ namespace hactoolnet
|
||||||
|
|
||||||
private static void ProcessSwitchFs(Context ctx)
|
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)
|
if (ctx.Options.ListTitles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,40 +37,40 @@ namespace libhac.Nand
|
||||||
return decStream;
|
return decStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FatFileSystem OpenProdInfoF()
|
public NandPartition OpenProdInfoF()
|
||||||
{
|
{
|
||||||
var encStream = ProdInfoF.Open();
|
var encStream = ProdInfoF.Open();
|
||||||
var xts = XtsAes128.Create(Keyset.bis_keys[0]);
|
var xts = XtsAes128.Create(Keyset.bis_keys[0]);
|
||||||
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
||||||
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
||||||
return fat;
|
return new NandPartition(fat);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FatFileSystem OpenSafePartition()
|
public NandPartition OpenSafePartition()
|
||||||
{
|
{
|
||||||
var encStream = Safe.Open();
|
var encStream = Safe.Open();
|
||||||
var xts = XtsAes128.Create(Keyset.bis_keys[1]);
|
var xts = XtsAes128.Create(Keyset.bis_keys[1]);
|
||||||
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
||||||
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
||||||
return fat;
|
return new NandPartition(fat);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FatFileSystem OpenSystemPartition()
|
public NandPartition OpenSystemPartition()
|
||||||
{
|
{
|
||||||
var encStream = System.Open();
|
var encStream = System.Open();
|
||||||
var xts = XtsAes128.Create(Keyset.bis_keys[2]);
|
var xts = XtsAes128.Create(Keyset.bis_keys[2]);
|
||||||
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
||||||
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
||||||
return fat;
|
return new NandPartition(fat);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FatFileSystem OpenUserPartition()
|
public NandPartition OpenUserPartition()
|
||||||
{
|
{
|
||||||
var encStream = User.Open();
|
var encStream = User.Open();
|
||||||
var xts = XtsAes128.Create(Keyset.bis_keys[3]);
|
var xts = XtsAes128.Create(Keyset.bis_keys[3]);
|
||||||
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
var decStream = new RandomAccessSectorStream(new XtsSectorStream(encStream, xts, 0x4000, 0), true);
|
||||||
FatFileSystem fat = new FatFileSystem(decStream, Ownership.None);
|
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;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization.Json;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using libhac.XTSSharp;
|
using libhac.XTSSharp;
|
||||||
|
|
|
@ -10,25 +10,25 @@ namespace libhac
|
||||||
public class SdFs : IDisposable
|
public class SdFs : IDisposable
|
||||||
{
|
{
|
||||||
public Keyset Keyset { get; }
|
public Keyset Keyset { get; }
|
||||||
public string RootDir { get; }
|
public IFileSystem Fs { get; }
|
||||||
public string ContentsDir { get; }
|
public string ContentsDir { get; }
|
||||||
|
|
||||||
public Dictionary<string, Nca> Ncas { get; } = new Dictionary<string, Nca>(StringComparer.OrdinalIgnoreCase);
|
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, Title> Titles { get; } = new Dictionary<ulong, Title>();
|
||||||
public Dictionary<ulong, Application> Applications { get; } = new Dictionary<ulong, Application>();
|
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;
|
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)
|
if (ContentsDir == null)
|
||||||
|
@ -44,7 +44,7 @@ namespace libhac
|
||||||
|
|
||||||
private void OpenAllNcas()
|
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)
|
foreach (var file in files)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ namespace libhac
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool isNax0;
|
bool isNax0;
|
||||||
Stream stream = OpenSplitNcaStream(file);
|
Stream stream = OpenSplitNcaStream(Fs, file);
|
||||||
if (stream == null) continue;
|
if (stream == null) continue;
|
||||||
|
|
||||||
using (var reader = new BinaryReader(stream, Encoding.Default, true))
|
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<string> files = new List<string>();
|
||||||
List<Stream> streams = new List<Stream>();
|
List<Stream> streams = new List<Stream>();
|
||||||
|
|
||||||
if (Directory.Exists(path))
|
if (fs.DirectoryExists(path))
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var partName = Path.Combine(path, $"{files.Count:D2}");
|
var partName = Path.Combine(path, $"{files.Count:D2}");
|
||||||
if (!File.Exists(partName)) break;
|
if (!fs.FileExists(partName)) break;
|
||||||
|
|
||||||
files.Add(partName);
|
files.Add(partName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (File.Exists(path))
|
else if (fs.FileExists(path))
|
||||||
{
|
{
|
||||||
if (Path.GetFileName(path) != "00")
|
if (Path.GetFileName(path) != "00")
|
||||||
{
|
{
|
||||||
return new FileStream(path, FileMode.Open, FileAccess.Read);
|
return fs.OpenFile(path, FileMode.Open, FileAccess.Read);
|
||||||
}
|
}
|
||||||
files.Add(path);
|
files.Add(path);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ namespace libhac
|
||||||
|
|
||||||
foreach (var file in files)
|
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;
|
if (streams.Count == 0) return null;
|
||||||
|
|
Loading…
Reference in a new issue