mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Revamp FileSystem class
This commit is contained in:
parent
398bb9d67f
commit
0ba490b2dc
9 changed files with 316 additions and 134 deletions
|
@ -1,73 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
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.Combine(Root, path), mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Stream OpenFile(string path, FileMode mode, FileAccess access)
|
|
||||||
{
|
|
||||||
return new FileStream(Path.Combine(Root, 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);
|
|
||||||
var result = new List<string>();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result.AddRange(GetFileSystemEntries(Path.Combine(Root, path), searchPattern));
|
|
||||||
}
|
|
||||||
catch (UnauthorizedAccessException) { /* Skip this directory */ }
|
|
||||||
|
|
||||||
if (searchOption == SearchOption.TopDirectoryOnly)
|
|
||||||
return result.ToArray();
|
|
||||||
|
|
||||||
string[] searchDirectories = Directory.GetDirectories(Path.Combine(Root, path));
|
|
||||||
foreach (string search in searchDirectories)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result.AddRange(GetFileSystemEntries(search, searchPattern, searchOption));
|
|
||||||
}
|
|
||||||
catch (UnauthorizedAccessException) { /* Skip this result */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetFullPath(string path)
|
|
||||||
{
|
|
||||||
return Path.Combine(Root, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
119
src/LibHac/FileSystem/IFileSystem.cs
Normal file
119
src/LibHac/FileSystem/IFileSystem.cs
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace LibHac
|
||||||
|
{
|
||||||
|
public abstract class IFileSystem
|
||||||
|
{
|
||||||
|
public abstract IDirectory RootDirectory { get; }
|
||||||
|
|
||||||
|
public abstract string PathSeperator { get; }
|
||||||
|
|
||||||
|
public abstract bool FileExists(IFile path);
|
||||||
|
public abstract bool DirectoryExists(IDirectory path);
|
||||||
|
|
||||||
|
public Stream OpenFile(IFile file, FileMode mode)
|
||||||
|
{
|
||||||
|
return OpenFile(file, mode, FileAccess.ReadWrite);
|
||||||
|
}
|
||||||
|
public abstract Stream OpenFile(IFile file, FileMode mode, FileAccess access);
|
||||||
|
|
||||||
|
public IFile[] GetFileSystemEntries(IDirectory directory, string searchPattern)
|
||||||
|
{
|
||||||
|
return GetFileSystemEntries(directory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||||
|
}
|
||||||
|
public abstract IFile[] GetFileSystemEntries(IDirectory path, string searchPattern, SearchOption searchOption);
|
||||||
|
|
||||||
|
public IDirectory GetDirectory(string path)
|
||||||
|
{
|
||||||
|
if (path.StartsWith(PathSeperator))
|
||||||
|
path = path.Substring(PathSeperator.Length);
|
||||||
|
return GetPath(path);
|
||||||
|
}
|
||||||
|
protected abstract IDirectory GetPath(string path);
|
||||||
|
|
||||||
|
public IFile GetFile(string path)
|
||||||
|
{
|
||||||
|
if (path.StartsWith(PathSeperator))
|
||||||
|
path = path.Substring(PathSeperator.Length);
|
||||||
|
return GetFile(path);
|
||||||
|
}
|
||||||
|
protected abstract IFile GetFileImpl(string path);
|
||||||
|
|
||||||
|
|
||||||
|
public abstract IFile[] GetFiles(IDirectory directory);
|
||||||
|
public abstract IDirectory[] GetDirectories(IDirectory directory);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IDirectory
|
||||||
|
{
|
||||||
|
public IFileSystem FileSystem;
|
||||||
|
public string Path;
|
||||||
|
|
||||||
|
public IDirectory Parent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int index = Path.LastIndexOf(FileSystem.PathSeperator);
|
||||||
|
return FileSystem.GetDirectory(Path.Substring(0, index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IFile[] Files => FileSystem.GetFiles(this);
|
||||||
|
public IDirectory[] Directories => FileSystem.GetDirectories(this);
|
||||||
|
public bool Exists => FileSystem.DirectoryExists(this);
|
||||||
|
|
||||||
|
public IDirectory(IFileSystem filesystem, string path)
|
||||||
|
{
|
||||||
|
FileSystem = filesystem;
|
||||||
|
Path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IFile GetFile(string path)
|
||||||
|
{
|
||||||
|
return FileSystem.GetFile(Path + FileSystem.PathSeperator + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDirectory GetDirectory(string path)
|
||||||
|
{
|
||||||
|
return FileSystem.GetDirectory(Path + FileSystem.PathSeperator + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IFile
|
||||||
|
{
|
||||||
|
public IFileSystem FileSystem;
|
||||||
|
public string Path;
|
||||||
|
|
||||||
|
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 IDirectory Parent {
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int index = Path.LastIndexOf(FileSystem.PathSeperator);
|
||||||
|
return FileSystem.GetDirectory(Path.Substring(0, index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Exists => FileSystem.FileExists(this);
|
||||||
|
|
||||||
|
public IFile(IFileSystem filesystem, string path)
|
||||||
|
{
|
||||||
|
FileSystem = filesystem;
|
||||||
|
Path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream Open(FileMode mode)
|
||||||
|
{
|
||||||
|
return FileSystem.OpenFile(this, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream Open(FileMode mode, FileAccess access)
|
||||||
|
{
|
||||||
|
return FileSystem.OpenFile(this, mode, access);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
122
src/LibHac/FileSystem/LocalFileSystem.cs
Normal file
122
src/LibHac/FileSystem/LocalFileSystem.cs
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace LibHac
|
||||||
|
{
|
||||||
|
public class LocalFileSystem : IFileSystem
|
||||||
|
{
|
||||||
|
public string Root { get; }
|
||||||
|
public override string PathSeperator => new string(new char[] { Path.DirectorySeparatorChar });
|
||||||
|
public override IDirectory RootDirectory => new IDirectory(this, "");
|
||||||
|
|
||||||
|
public LocalFileSystem(string rootDir)
|
||||||
|
{
|
||||||
|
Root = rootDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool FileExists(IFile file)
|
||||||
|
{
|
||||||
|
return File.Exists(GetFullPath(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool DirectoryExists(IDirectory directory)
|
||||||
|
{
|
||||||
|
return Directory.Exists(Path.Combine(Root, directory.Path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Stream OpenFile(IFile file, FileMode mode, FileAccess access)
|
||||||
|
{
|
||||||
|
return new FileStream(GetFullPath(file), mode, access);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IFile[] GetFileSystemEntries(IDirectory path, string searchPattern, SearchOption searchOption)
|
||||||
|
{
|
||||||
|
//return Directory.GetFileSystemEntries(Path.Combine(Root, path), searchPattern, searchOption);
|
||||||
|
var result = new List<IFile>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result.AddRange(GetFileSystemEntries(path, searchPattern));
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException) { /* Skip this directory */ }
|
||||||
|
|
||||||
|
if (searchOption == SearchOption.TopDirectoryOnly)
|
||||||
|
return result.ToArray();
|
||||||
|
|
||||||
|
string[] searchDirectories = Directory.GetDirectories(GetFullPath(path));
|
||||||
|
foreach (string search in searchDirectories)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result.AddRange(GetFileSystemEntries(FullPathToDirectory(search), searchPattern, searchOption));
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException) { /* Skip this result */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override IFile[] GetFiles(IDirectory directory)
|
||||||
|
{
|
||||||
|
FileInfo[] infos = new DirectoryInfo(GetFullPath(directory)).GetFiles();
|
||||||
|
IFile[] files = new IFile[infos.Length];
|
||||||
|
for (int i = 0; i < files.Length; i++)
|
||||||
|
files[i] = FullPathToFile(infos[i].FullName);
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IDirectory[] GetDirectories(IDirectory directory)
|
||||||
|
{
|
||||||
|
DirectoryInfo[] infos = new DirectoryInfo(GetFullPath(directory)).GetDirectories();
|
||||||
|
IDirectory[] directories = new IDirectory[infos.Length];
|
||||||
|
for (int i = 0; i < directories.Length; i++)
|
||||||
|
directories[i] = FullPathToDirectory(infos[i].FullName);
|
||||||
|
return directories;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IDirectory GetPath(string path)
|
||||||
|
{
|
||||||
|
return new IDirectory(this, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override IFile GetFileImpl(string path)
|
||||||
|
{
|
||||||
|
return new LocalFile(this, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFullPath(IFile file)
|
||||||
|
{
|
||||||
|
return ((LocalFile)file).GetFullPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetFullPath(IDirectory directory)
|
||||||
|
{
|
||||||
|
return Path.Combine(((LocalFileSystem)directory.FileSystem).Root, directory.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IDirectory FullPathToDirectory(string path)
|
||||||
|
{
|
||||||
|
return new IDirectory(this, Util.GetRelativePath(path, Root));
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocalFile FullPathToFile(string path)
|
||||||
|
{
|
||||||
|
return new LocalFile(this, Util.GetRelativePath(path, Root));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LocalFile : IFile
|
||||||
|
{
|
||||||
|
public LocalFile(LocalFileSystem localFileSystem, string path) : base(localFileSystem, path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetFullPath()
|
||||||
|
{
|
||||||
|
return System.IO.Path.Combine(((LocalFileSystem)FileSystem).Root, Path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,8 +13,8 @@ namespace LibHac
|
||||||
{
|
{
|
||||||
public Keyset Keyset { get; }
|
public Keyset Keyset { get; }
|
||||||
public IFileSystem Fs { get; }
|
public IFileSystem Fs { get; }
|
||||||
public string ContentsDir { get; }
|
public IDirectory ContentsDir { get; }
|
||||||
public string SaveDir { get; }
|
public IDirectory SaveDir { 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, Savefile> Saves { get; } = new Dictionary<string, Savefile>(StringComparer.OrdinalIgnoreCase);
|
public Dictionary<string, Savefile> Saves { get; } = new Dictionary<string, Savefile>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
@ -26,21 +26,21 @@ namespace LibHac
|
||||||
Fs = fs;
|
Fs = fs;
|
||||||
Keyset = keyset;
|
Keyset = keyset;
|
||||||
|
|
||||||
if (fs.DirectoryExists("Nintendo"))
|
if (fs.GetDirectory("Nintendo").Exists)
|
||||||
{
|
{
|
||||||
ContentsDir = fs.GetFullPath(Path.Combine("Nintendo", "Contents"));
|
ContentsDir = fs.GetDirectory("Nintendo/Contents");
|
||||||
SaveDir = fs.GetFullPath(Path.Combine("Nintendo", "save"));
|
SaveDir = fs.GetDirectory("Nintendo/save");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fs.DirectoryExists("Contents"))
|
if (fs.GetDirectory("Contents").Exists)
|
||||||
{
|
{
|
||||||
ContentsDir = fs.GetFullPath("Contents");
|
ContentsDir = fs.GetDirectory("Contents");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.DirectoryExists("save"))
|
if (fs.GetDirectory("save").Exists)
|
||||||
{
|
{
|
||||||
SaveDir = fs.GetFullPath("save");
|
SaveDir = fs.GetDirectory("save");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,15 +58,24 @@ namespace LibHac
|
||||||
|
|
||||||
private void OpenAllNcas()
|
private void OpenAllNcas()
|
||||||
{
|
{
|
||||||
string[] files = Fs.GetFileSystemEntries(ContentsDir, "*.nca", SearchOption.AllDirectories);
|
IFile[] files = ContentsDir.Files;
|
||||||
|
IDirectory[] directories = ContentsDir.Directories;
|
||||||
|
|
||||||
foreach (string file in files)
|
Dictionary<string, IStorage> storages = new Dictionary<string, IStorage>();
|
||||||
|
|
||||||
|
foreach (IFile file in files)
|
||||||
|
storages[file.Path] = file.Open(FileMode.Open, FileAccess.Read).AsStorage();
|
||||||
|
foreach(IDirectory directory in directories)
|
||||||
|
storages[directory.Path] = OpenSplitNcaStream(Fs, directory);
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, IStorage> kv in storages)
|
||||||
{
|
{
|
||||||
Nca nca = null;
|
Nca nca = null;
|
||||||
|
string path = kv.Key;
|
||||||
|
IStorage storage = kv.Value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool isNax0;
|
bool isNax0;
|
||||||
IStorage storage = OpenSplitNcaStream(Fs, file);
|
|
||||||
if (storage == null) continue;
|
if (storage == null) continue;
|
||||||
|
|
||||||
using (var reader = new BinaryReader(storage.AsStream(), Encoding.Default, true))
|
using (var reader = new BinaryReader(storage.AsStream(), Encoding.Default, true))
|
||||||
|
@ -78,7 +87,7 @@ namespace LibHac
|
||||||
|
|
||||||
if (isNax0)
|
if (isNax0)
|
||||||
{
|
{
|
||||||
string sdPath = "/" + Util.GetRelativePath(file, ContentsDir).Replace('\\', '/');
|
string sdPath = "/" + path.Replace('\\', '/');
|
||||||
var nax0 = new Nax0(Keyset, storage, sdPath, false);
|
var nax0 = new Nax0(Keyset, storage, sdPath, false);
|
||||||
nca = new Nca(Keyset, nax0.BaseStorage, false);
|
nca = new Nca(Keyset, nax0.BaseStorage, false);
|
||||||
}
|
}
|
||||||
|
@ -87,23 +96,23 @@ namespace LibHac
|
||||||
nca = new Nca(Keyset, storage, false);
|
nca = new Nca(Keyset, storage, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
nca.NcaId = Path.GetFileNameWithoutExtension(file);
|
nca.NcaId = Path.GetFileNameWithoutExtension(path);
|
||||||
string extension = nca.Header.ContentType == ContentType.Meta ? ".cnmt.nca" : ".nca";
|
string extension = nca.Header.ContentType == ContentType.Meta ? ".cnmt.nca" : ".nca";
|
||||||
nca.Filename = nca.NcaId + extension;
|
nca.Filename = nca.NcaId + extension;
|
||||||
}
|
}
|
||||||
catch (MissingKeyException ex)
|
catch (MissingKeyException ex)
|
||||||
{
|
{
|
||||||
if (ex.Name == null)
|
if (ex.Name == null)
|
||||||
{ Console.WriteLine($"{ex.Message} File:\n{file}"); }
|
{ Console.WriteLine($"{ex.Message} File:\n{path}"); }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string name = ex.Type == KeyType.Title ? $"Title key for rights ID {ex.Name}" : ex.Name;
|
string name = ex.Type == KeyType.Title ? $"Title key for rights ID {ex.Name}" : ex.Name;
|
||||||
Console.WriteLine($"{ex.Message}\nKey: {name}\nFile: {file}");
|
Console.WriteLine($"{ex.Message}\nKey: {name}\nFile: {path}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{ex.Message} File: {file}");
|
Console.WriteLine($"{ex.Message} File: {path}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nca?.NcaId != null) Ncas.Add(nca.NcaId, nca);
|
if (nca?.NcaId != null) Ncas.Add(nca.NcaId, nca);
|
||||||
|
@ -114,18 +123,18 @@ namespace LibHac
|
||||||
{
|
{
|
||||||
if (SaveDir == null) return;
|
if (SaveDir == null) return;
|
||||||
|
|
||||||
string[] files = Fs.GetFileSystemEntries(SaveDir, "*");
|
IFile[] files = Fs.GetFileSystemEntries(SaveDir, "*");
|
||||||
|
|
||||||
foreach (string file in files)
|
foreach (IFile file in files)
|
||||||
{
|
{
|
||||||
Savefile save = null;
|
Savefile save = null;
|
||||||
string saveName = Path.GetFileNameWithoutExtension(file);
|
string saveName = Path.GetFileNameWithoutExtension(file.Path);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IStorage storage = Fs.OpenFile(file, FileMode.Open).AsStorage();
|
IStorage storage = Fs.OpenFile(file, FileMode.Open).AsStorage();
|
||||||
|
|
||||||
string sdPath = "/" + Util.GetRelativePath(file, SaveDir).Replace('\\', '/');
|
string sdPath = file.Path.Replace('\\', '/');
|
||||||
var nax0 = new Nax0(Keyset, storage, sdPath, false);
|
var nax0 = new Nax0(Keyset, storage, sdPath, false);
|
||||||
save = new Savefile(Keyset, nax0.BaseStorage, IntegrityCheckLevel.None, true);
|
save = new Savefile(Keyset, nax0.BaseStorage, IntegrityCheckLevel.None, true);
|
||||||
}
|
}
|
||||||
|
@ -232,43 +241,30 @@ namespace LibHac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static IStorage OpenSplitNcaStream(IFileSystem fs, string path)
|
internal static IStorage OpenSplitNcaStream(IFileSystem fs, IDirectory directory)
|
||||||
{
|
{
|
||||||
var files = new List<string>();
|
var files = new List<IFile>();
|
||||||
var storages = new List<IStorage>();
|
var storages = new List<IStorage>();
|
||||||
|
|
||||||
if (fs.DirectoryExists(path))
|
if (directory.Exists)
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
string partName = Path.Combine(path, $"{files.Count:D2}");
|
IFile partFile = directory.GetFile($"{files.Count:D2}");
|
||||||
if (!fs.FileExists(partName)) break;
|
if (!partFile.Exists) break;
|
||||||
|
|
||||||
files.Add(partName);
|
files.Add(partFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fs.FileExists(path))
|
|
||||||
{
|
|
||||||
if (Path.GetFileName(path) != "00")
|
|
||||||
{
|
|
||||||
return fs.OpenFile(path, FileMode.Open, FileAccess.Read).AsStorage();
|
|
||||||
}
|
|
||||||
files.Add(path);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
throw new FileNotFoundException("Could not find the input file or directory");
|
throw new FileNotFoundException("Could not find the input file or directory");
|
||||||
}
|
|
||||||
|
|
||||||
if (files.Count == 1)
|
if (files.Count == 1)
|
||||||
{
|
return files[0].Open(FileMode.Open, FileAccess.Read).AsStorage();
|
||||||
return fs.OpenFile(files[0], FileMode.Open, FileAccess.Read).AsStorage();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string file in files)
|
foreach (IFile file in files)
|
||||||
{
|
storages.Add(file.Open( FileMode.Open, FileAccess.Read).AsStorage());
|
||||||
storages.Add(fs.OpenFile(file, FileMode.Open, FileAccess.Read).AsStorage());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (storages.Count == 0) return null; //todo
|
if (storages.Count == 0) return null; //todo
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ namespace LibHac
|
||||||
throw new ArgumentException($"{nameof(path)} is not a subpath of {nameof(basePath)}");
|
throw new ArgumentException($"{nameof(path)} is not a subpath of {nameof(basePath)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return fullFile.Substring(fullDirectory.Length + 1);
|
return fullFile.Substring(fullDirectory.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool TryHexToInt(char c, out int value)
|
private static bool TryHexToInt(char c, out int value)
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace hactoolnet
|
||||||
{
|
{
|
||||||
public static void Process(Context ctx)
|
public static void Process(Context ctx)
|
||||||
{
|
{
|
||||||
var switchFs = new SwitchFs(ctx.Keyset, new FileSystem(ctx.Options.InFile));
|
var switchFs = new SwitchFs(ctx.Keyset, new LocalFileSystem(ctx.Options.InFile));
|
||||||
|
|
||||||
if (ctx.Options.ListTitles)
|
if (ctx.Options.ListTitles)
|
||||||
{
|
{
|
||||||
|
|
27
tests/LibHac.Tests/FileSystemTests.cs
Normal file
27
tests/LibHac.Tests/FileSystemTests.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LibHac.Tests
|
||||||
|
{
|
||||||
|
public class FileSystemTests
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
LocalFileSystem fs = new LocalFileSystem("C:\\\\");
|
||||||
|
foreach(IFile file in fs.RootDirectory.Files)
|
||||||
|
{
|
||||||
|
Console.WriteLine(file.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (IDirectory directory in fs.RootDirectory.Directories)
|
||||||
|
{
|
||||||
|
Console.WriteLine(directory.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.ReadKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,12 @@
|
||||||
<TargetFrameworks>net46;netcoreapp2.1</TargetFrameworks>
|
<TargetFrameworks>net46;netcoreapp2.1</TargetFrameworks>
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
|
||||||
|
<ApplicationIcon />
|
||||||
|
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
|
||||||
|
<StartupObject>LibHac.Tests.FileSystemTests</StartupObject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
Loading…
Reference in a new issue