Add initializers for SwitchFs

This commit is contained in:
Alex Barney 2019-01-13 15:06:15 -06:00
parent 4ded38c1d6
commit edaccdfe81
4 changed files with 80 additions and 42 deletions

View file

@ -20,7 +20,10 @@ namespace LibHac.IO
public IEnumerable<DirectoryEntry> Read() public IEnumerable<DirectoryEntry> Read()
{ {
return BaseDirectory.Read(); foreach (DirectoryEntry entry in BaseDirectory.Read())
{
yield return new DirectoryEntry(entry.Name, FullPath + '/' + entry.Name, entry.Type, entry.Size);
}
} }
public int GetEntryCount() public int GetEntryCount()

View file

@ -11,39 +11,63 @@ namespace LibHac
public class SwitchFs : IDisposable public class SwitchFs : IDisposable
{ {
public Keyset Keyset { get; } public Keyset Keyset { get; }
public IAttributeFileSystem BaseFs { get; } public IFileSystem ContentFs { get; }
public AesXtsFileSystem Fs { get; } public IFileSystem SaveFs { 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<string, SaveDataFileSystem> Saves { get; } = new Dictionary<string, SaveDataFileSystem>(StringComparer.OrdinalIgnoreCase); public Dictionary<string, SaveDataFileSystem> Saves { get; } = new Dictionary<string, SaveDataFileSystem>(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 SwitchFs(Keyset keyset, IAttributeFileSystem fs) public SwitchFs(Keyset keyset, IFileSystem contentFileSystem, IFileSystem saveFileSystem)
{ {
BaseFs = fs;
Keyset = keyset; Keyset = keyset;
ContentFs = contentFileSystem;
SaveFs = saveFileSystem;
var concatFs = new ConcatenationFileSystem(BaseFs); OpenAllSaves();
Fs = new AesXtsFileSystem(concatFs, keyset.SdCardKeys[1], 0x4000);
// OpenAllSaves();
OpenAllNcas(); OpenAllNcas();
ReadTitles(); ReadTitles();
ReadControls(); ReadControls();
CreateApplications(); CreateApplications();
} }
public static SwitchFs OpenSdCard(Keyset keyset, IAttributeFileSystem fileSystem)
{
var concatFs = new ConcatenationFileSystem(fileSystem);
var saveDirFs = new SubdirectoryFileSystem(concatFs, "/Nintendo/save");
var contentDirFs = new SubdirectoryFileSystem(concatFs, "/Nintendo/Contents");
var encSaveFs = new AesXtsFileSystem(saveDirFs, keyset.SdCardKeys[0], 0x4000);
var encContentFs = new AesXtsFileSystem(contentDirFs, keyset.SdCardKeys[1], 0x4000);
return new SwitchFs(keyset, encContentFs, encSaveFs);
}
public static SwitchFs OpenNandPartition(Keyset keyset, IAttributeFileSystem fileSystem)
{
var concatFs = new ConcatenationFileSystem(fileSystem);
var saveDirFs = new SubdirectoryFileSystem(concatFs, "/save");
var contentDirFs = new SubdirectoryFileSystem(concatFs, "/Contents");
return new SwitchFs(keyset, contentDirFs, saveDirFs);
}
public static SwitchFs OpenNcaDirectory(Keyset keyset, IFileSystem fileSystem)
{
return new SwitchFs(keyset, fileSystem, null);
}
private void OpenAllNcas() private void OpenAllNcas()
{ {
IEnumerable<DirectoryEntry> files = Fs.OpenDirectory("/", OpenDirectoryMode.All).EnumerateEntries("*.nca", SearchOptions.RecurseSubdirectories); IEnumerable<DirectoryEntry> files = ContentFs.OpenDirectory("/", OpenDirectoryMode.All).EnumerateEntries("*.nca", SearchOptions.RecurseSubdirectories);
foreach (DirectoryEntry fileEntry in files) foreach (DirectoryEntry fileEntry in files)
{ {
Nca nca = null; Nca nca = null;
try try
{ {
var storage = new FileStorage(Fs.OpenFile(fileEntry.FullPath, OpenMode.Read)); var storage = new FileStorage(ContentFs.OpenFile(fileEntry.FullPath, OpenMode.Read));
nca = new Nca(Keyset, storage, false); nca = new Nca(Keyset, storage, false);
@ -63,43 +87,38 @@ namespace LibHac
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"{ex.Message} File: {fileEntry}"); Console.WriteLine($"{ex.Message} File: {fileEntry.FullPath}");
} }
if (nca?.NcaId != null) Ncas.Add(nca.NcaId, nca); if (nca?.NcaId != null) Ncas.Add(nca.NcaId, nca);
} }
} }
//private void OpenAllSaves() private void OpenAllSaves()
//{ {
// if (SaveDir == null) return; if (SaveFs == null) return;
// string[] files = Fs.GetFileSystemEntries(SaveDir, "*"); foreach (DirectoryEntry fileEntry in SaveFs.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File))
{
SaveDataFileSystem save = null;
string saveName = Path.GetFileNameWithoutExtension(fileEntry.Name);
// foreach (string file in files) try
// { {
// SaveDataFileSystem save = null; IFile file = SaveFs.OpenFile(fileEntry.FullPath, OpenMode.Read);
// string saveName = Path.GetFileNameWithoutExtension(file); save = new SaveDataFileSystem(Keyset, new FileStorage(file), IntegrityCheckLevel.None, true);
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message} File: {fileEntry.FullPath}");
}
// try if (save != null && saveName != null)
// { {
// IStorage storage = Fs.OpenFile(file, FileMode.Open).AsStorage(); Saves[saveName] = save;
}
// string sdPath = "/" + Util.GetRelativePath(file, SaveDir).Replace('\\', '/'); }
// var nax0 = new Nax0(Keyset, storage, sdPath, false); }
// save = new SaveDataFileSystem(Keyset, nax0.BaseStorage, IntegrityCheckLevel.None, true);
// }
// catch (Exception ex)
// {
// Console.WriteLine($"{ex.Message} File: {file}");
// }
// if (save != null && saveName != null)
// {
// Saves[saveName] = save;
// }
// }
//}
private void ReadTitles() private void ReadTitles()
{ {

View file

@ -50,8 +50,7 @@ namespace NandReader
Keyset keyset = OpenKeyset(); Keyset keyset = OpenKeyset();
var nand = new Nand(stream, keyset); var nand = new Nand(stream, keyset);
FatFileSystemProvider user = nand.OpenSystemPartition(); FatFileSystemProvider user = nand.OpenSystemPartition();
// todo SwitchFs sdfs = SwitchFs.OpenNandPartition(keyset, user);
//var sdfs = new SwitchFs(keyset, user);
} }
} }

View file

@ -13,7 +13,24 @@ namespace hactoolnet
{ {
public static void Process(Context ctx) public static void Process(Context ctx)
{ {
var switchFs = new SwitchFs(ctx.Keyset, new LocalFileSystem($"{ctx.Options.InFile}/Nintendo/Contents")); SwitchFs switchFs;
var baseFs = new LocalFileSystem(ctx.Options.InFile);
if (Directory.Exists(Path.Combine(ctx.Options.InFile, "Nintendo", "Contents", "registered")))
{
ctx.Logger.LogMessage("Treating path as SD card storage");
switchFs = SwitchFs.OpenSdCard(ctx.Keyset, baseFs);
}
else if (Directory.Exists(Path.Combine(ctx.Options.InFile, "Contents", "registered")))
{
ctx.Logger.LogMessage("Treating path as NAND storage");
switchFs = SwitchFs.OpenNandPartition(ctx.Keyset, baseFs);
}
else
{
ctx.Logger.LogMessage("Treating path as a directory of loose NCAs");
switchFs = SwitchFs.OpenNcaDirectory(ctx.Keyset, baseFs);
}
if (ctx.Options.ListNcas) if (ctx.Options.ListNcas)
{ {