mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add an IFileSystem provider for DiscUtils
This commit is contained in:
parent
828c1f5b54
commit
3e4dcd9466
7 changed files with 179 additions and 23 deletions
63
src/LibHac.Nand/FatFileSystemDirectory.cs
Normal file
63
src/LibHac.Nand/FatFileSystemDirectory.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
using System.Collections.Generic;
|
||||
using DiscUtils;
|
||||
using LibHac.IO;
|
||||
using DirectoryEntry = LibHac.IO.DirectoryEntry;
|
||||
using IFileSystem = LibHac.IO.IFileSystem;
|
||||
|
||||
namespace LibHac.Nand
|
||||
{
|
||||
public class FatFileSystemDirectory : IDirectory
|
||||
{
|
||||
public IFileSystem ParentFileSystem { get; }
|
||||
public string FullPath { get; }
|
||||
public OpenDirectoryMode Mode { get; }
|
||||
private DiscDirectoryInfo DirInfo { get; }
|
||||
|
||||
public FatFileSystemDirectory(FatFileSystemProvider fs, string path, OpenDirectoryMode mode)
|
||||
{
|
||||
ParentFileSystem = fs;
|
||||
FullPath = path;
|
||||
Mode = mode;
|
||||
|
||||
path = FatFileSystemProvider.ToDiscUtilsPath(PathTools.Normalize(path));
|
||||
|
||||
DirInfo = fs.Fs.GetDirectoryInfo(path);
|
||||
}
|
||||
|
||||
public IEnumerable<DirectoryEntry> Read()
|
||||
{
|
||||
if (Mode.HasFlag(OpenDirectoryMode.Directories))
|
||||
{
|
||||
foreach (DiscDirectoryInfo dir in DirInfo.GetDirectories())
|
||||
{
|
||||
yield return new DirectoryEntry(dir.Name, FullPath + '/' + dir.Name, DirectoryEntryType.Directory, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (Mode.HasFlag(OpenDirectoryMode.Files))
|
||||
{
|
||||
foreach (DiscFileInfo file in DirInfo.GetFiles())
|
||||
{
|
||||
yield return new DirectoryEntry(file.Name, FullPath + '/' + file.Name, DirectoryEntryType.File, file.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetEntryCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (Mode.HasFlag(OpenDirectoryMode.Directories))
|
||||
{
|
||||
count += DirInfo.GetDirectories().Length;
|
||||
}
|
||||
|
||||
if (Mode.HasFlag(OpenDirectoryMode.Files))
|
||||
{
|
||||
count += DirInfo.GetFiles().Length;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
92
src/LibHac.Nand/FatFileSystemProvider.cs
Normal file
92
src/LibHac.Nand/FatFileSystemProvider.cs
Normal file
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using DiscUtils.Fat;
|
||||
using LibHac.IO;
|
||||
|
||||
namespace LibHac.Nand
|
||||
{
|
||||
public class FatFileSystemProvider : IAttributeFileSystem
|
||||
{
|
||||
public FatFileSystem Fs { get; }
|
||||
|
||||
public FatFileSystemProvider(FatFileSystem fileSystem)
|
||||
{
|
||||
Fs = fileSystem;
|
||||
}
|
||||
|
||||
public void DeleteDirectory(string path)
|
||||
{
|
||||
path = ToDiscUtilsPath(PathTools.Normalize(path));
|
||||
Fs.DeleteDirectory(path);
|
||||
}
|
||||
|
||||
public void DeleteFile(string path)
|
||||
{
|
||||
path = ToDiscUtilsPath(PathTools.Normalize(path));
|
||||
Fs.DeleteFile(path);
|
||||
}
|
||||
|
||||
public IDirectory OpenDirectory(string path, OpenDirectoryMode mode)
|
||||
{
|
||||
path = PathTools.Normalize(path);
|
||||
|
||||
return new FatFileSystemDirectory(this, path, mode);
|
||||
}
|
||||
|
||||
public IFile OpenFile(string path, OpenMode mode)
|
||||
{
|
||||
path = ToDiscUtilsPath(PathTools.Normalize(path));
|
||||
|
||||
Stream stream = Fs.OpenFile(path, FileMode.Open, GetFileAccess(mode));
|
||||
return stream.AsIFile(mode);
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string path)
|
||||
{
|
||||
path = ToDiscUtilsPath(PathTools.Normalize(path));
|
||||
|
||||
if (path == @"\\") return true;
|
||||
|
||||
return Fs.DirectoryExists(path);
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
path = ToDiscUtilsPath(PathTools.Normalize(path));
|
||||
|
||||
return Fs.FileExists(path);
|
||||
}
|
||||
|
||||
public FileAttributes GetFileAttributes(string path)
|
||||
{
|
||||
path = ToDiscUtilsPath(PathTools.Normalize(path));
|
||||
|
||||
return Fs.GetAttributes(path);
|
||||
}
|
||||
|
||||
public long GetFileSize(string path)
|
||||
{
|
||||
path = ToDiscUtilsPath(PathTools.Normalize(path));
|
||||
|
||||
return Fs.GetFileInfo(path).Length;
|
||||
}
|
||||
|
||||
public void Commit() { }
|
||||
|
||||
public void CreateDirectory(string path) => throw new NotSupportedException();
|
||||
public void CreateFile(string path, long size) => throw new NotSupportedException();
|
||||
public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException();
|
||||
public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException();
|
||||
|
||||
private static FileAccess GetFileAccess(OpenMode mode)
|
||||
{
|
||||
// FileAccess and OpenMode have the same flags
|
||||
return (FileAccess)(mode & OpenMode.ReadWrite);
|
||||
}
|
||||
|
||||
internal static string ToDiscUtilsPath(string path)
|
||||
{
|
||||
return path.Replace("/", @"\\");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,40 +37,40 @@ namespace LibHac.Nand
|
|||
return decStorage.AsStream();
|
||||
}
|
||||
|
||||
public NandPartition OpenProdInfoF()
|
||||
public FatFileSystemProvider OpenProdInfoF()
|
||||
{
|
||||
IStorage encStorage = ProdInfoF.Open().AsStorage();
|
||||
var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[0], 0x4000, true), 0x4000, 4, true);
|
||||
decStorage.SetReadOnly();
|
||||
var fat = new FatFileSystem(decStorage.AsStream(), Ownership.None);
|
||||
return new NandPartition(fat);
|
||||
return new FatFileSystemProvider(fat);
|
||||
}
|
||||
|
||||
public NandPartition OpenSafePartition()
|
||||
public FatFileSystemProvider OpenSafePartition()
|
||||
{
|
||||
IStorage encStorage = Safe.Open().AsStorage();
|
||||
var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[1], 0x4000, true), 0x4000, 4, true);
|
||||
decStorage.SetReadOnly();
|
||||
var fat = new FatFileSystem(decStorage.AsStream(), Ownership.None);
|
||||
return new NandPartition(fat);
|
||||
return new FatFileSystemProvider(fat);
|
||||
}
|
||||
|
||||
public NandPartition OpenSystemPartition()
|
||||
public FatFileSystemProvider OpenSystemPartition()
|
||||
{
|
||||
IStorage encStorage = System.Open().AsStorage();
|
||||
var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[2], 0x4000, true), 0x4000, 4, true);
|
||||
decStorage.SetReadOnly();
|
||||
var fat = new FatFileSystem(decStorage.AsStream(), Ownership.None);
|
||||
return new NandPartition(fat);
|
||||
return new FatFileSystemProvider(fat);
|
||||
}
|
||||
|
||||
public NandPartition OpenUserPartition()
|
||||
public FatFileSystemProvider OpenUserPartition()
|
||||
{
|
||||
IStorage encStorage = User.Open().AsStorage();
|
||||
var decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[3], 0x4000, true), 0x4000, 4, true);
|
||||
decStorage.SetReadOnly();
|
||||
var fat = new FatFileSystem(decStorage.AsStream(), Ownership.None);
|
||||
return new NandPartition(fat);
|
||||
return new FatFileSystemProvider(fat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace LibHac.IO
|
|||
|
||||
public static IEnumerable<DirectoryEntry> EnumerateEntries(this IFileSystem fileSystem)
|
||||
{
|
||||
return fileSystem.OpenDirectory("/", OpenDirectoryMode.All).EnumerateEntries();
|
||||
return fileSystem.OpenDirectory("/", OpenDirectoryMode.All).EnumerateEntries("*", SearchOptions.RecurseSubdirectories);
|
||||
}
|
||||
|
||||
public static IEnumerable<DirectoryEntry> EnumerateEntries(this IDirectory directory)
|
||||
|
|
|
@ -48,12 +48,12 @@ namespace LibHac.IO
|
|||
|
||||
if (Mode.HasFlag(OpenDirectoryMode.Directories))
|
||||
{
|
||||
count += Directory.EnumerateDirectories(LocalPath).Count();
|
||||
count += DirInfo.EnumerateDirectories().Count();
|
||||
}
|
||||
|
||||
if (Mode.HasFlag(OpenDirectoryMode.Files))
|
||||
{
|
||||
count += Directory.EnumerateFiles(LocalPath).Count();
|
||||
count += DirInfo.EnumerateFiles().Count();
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
|
@ -49,8 +49,9 @@ namespace NandReader
|
|||
{
|
||||
Keyset keyset = OpenKeyset();
|
||||
var nand = new Nand(stream, keyset);
|
||||
NandPartition user = nand.OpenSystemPartition();
|
||||
var sdfs = new SwitchFs(keyset, user);
|
||||
FatFileSystemProvider user = nand.OpenSystemPartition();
|
||||
// todo
|
||||
//var sdfs = new SwitchFs(keyset, user);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,13 +88,13 @@ namespace NandReader
|
|||
private static Ticket[] GetTickets(Keyset keyset, Nand nand, IProgressReport logger = null)
|
||||
{
|
||||
var tickets = new List<Ticket>();
|
||||
NandPartition system = nand.OpenSystemPartition();
|
||||
FatFileSystemProvider system = nand.OpenSystemPartition();
|
||||
|
||||
Stream saveE1File = system.OpenFile("save\\80000000000000E1", FileMode.Open, FileAccess.Read);
|
||||
tickets.AddRange(ReadTickets(keyset, saveE1File));
|
||||
IFile saveE1File = system.OpenFile("/save/80000000000000E1", OpenMode.Read);
|
||||
tickets.AddRange(ReadTickets(keyset, saveE1File.AsStream()));
|
||||
|
||||
Stream saveE2 = system.OpenFile("save\\80000000000000E2", FileMode.Open, FileAccess.Read);
|
||||
tickets.AddRange(ReadTickets(keyset, saveE2));
|
||||
IFile saveE2 = system.OpenFile("/save/80000000000000E2", OpenMode.Read);
|
||||
tickets.AddRange(ReadTickets(keyset, saveE2.AsStream()));
|
||||
|
||||
logger?.LogMessage($"Found {tickets.Count} tickets");
|
||||
|
||||
|
|
|
@ -71,13 +71,13 @@ namespace NandReaderGui.ViewModel
|
|||
private static Ticket[] GetTickets(Keyset keyset, Nand nand, IProgressReport logger = null)
|
||||
{
|
||||
var tickets = new List<Ticket>();
|
||||
NandPartition system = nand.OpenSystemPartition();
|
||||
FatFileSystemProvider system = nand.OpenSystemPartition();
|
||||
|
||||
Stream saveE1File = system.OpenFile("save\\80000000000000E1", FileMode.Open, FileAccess.Read);
|
||||
tickets.AddRange(ReadTickets(keyset, saveE1File));
|
||||
IFile saveE1File = system.OpenFile("/save/80000000000000E1", OpenMode.Read);
|
||||
tickets.AddRange(ReadTickets(keyset, saveE1File.AsStream()));
|
||||
|
||||
Stream saveE2 = system.OpenFile("save\\80000000000000E2", FileMode.Open, FileAccess.Read);
|
||||
tickets.AddRange(ReadTickets(keyset, saveE2));
|
||||
IFile saveE2 = system.OpenFile("/save/80000000000000E2", OpenMode.Read);
|
||||
tickets.AddRange(ReadTickets(keyset, saveE2.AsStream()));
|
||||
|
||||
logger?.LogMessage($"Found {tickets.Count} tickets");
|
||||
|
||||
|
|
Loading…
Reference in a new issue