mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
SD card content listing example
This commit is contained in:
parent
a6e72b0ee7
commit
8054d38f5a
5 changed files with 81 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
||||||
using System.IO;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using libhac;
|
using libhac;
|
||||||
|
|
||||||
namespace hactoolnet
|
namespace hactoolnet
|
||||||
|
@ -6,6 +7,11 @@ namespace hactoolnet
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
ListSdContents(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DecryptNax0(string[] args)
|
||||||
{
|
{
|
||||||
var keyset = ExternalKeys.ReadKeyFile(args[0]);
|
var keyset = ExternalKeys.ReadKeyFile(args[0]);
|
||||||
keyset.SetSdSeed(args[1].ToBytes());
|
keyset.SetSdSeed(args[1].ToBytes());
|
||||||
|
@ -21,5 +27,18 @@ namespace hactoolnet
|
||||||
nax0.Stream.CopyStream(output, nax0.Stream.Length, progress);
|
nax0.Stream.CopyStream(output, nax0.Stream.Length, progress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ListSdContents(string[] args)
|
||||||
|
{
|
||||||
|
var keyset = ExternalKeys.ReadKeyFile(args[0]);
|
||||||
|
keyset.SetSdSeed(args[1].ToBytes());
|
||||||
|
var sdfs = new SdFs(keyset, args[2]);
|
||||||
|
var ncas = sdfs.ReadAllNca();
|
||||||
|
|
||||||
|
foreach (var nca in ncas)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{nca.TitleId:X8} {nca.ContentType} {nca.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace libhac
|
||||||
public uint SdkVersion { get; set; } // What SDK was this built with?
|
public uint SdkVersion { get; set; } // What SDK was this built with?
|
||||||
public byte CryptoType2 { get; set; } // Which keyblob (field 2)
|
public byte CryptoType2 { get; set; } // Which keyblob (field 2)
|
||||||
public byte[] RightsId { get; set; }
|
public byte[] RightsId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
public Nca(Keyset keyset, Stream stream)
|
public Nca(Keyset keyset, Stream stream)
|
||||||
{
|
{
|
||||||
|
|
41
libhac/SdFs.cs
Normal file
41
libhac/SdFs.cs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace libhac
|
||||||
|
{
|
||||||
|
public class SdFs
|
||||||
|
{
|
||||||
|
public Keyset Keyset { get; }
|
||||||
|
public string RootDir { get; }
|
||||||
|
public string ContentsDir { get; }
|
||||||
|
public string[] Files { get; }
|
||||||
|
|
||||||
|
public SdFs(Keyset keyset, string sdPath)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(Path.Combine(sdPath, "Nintendo")))
|
||||||
|
{
|
||||||
|
RootDir = sdPath;
|
||||||
|
Keyset = keyset;
|
||||||
|
ContentsDir = Path.Combine(sdPath, "Nintendo", "Contents");
|
||||||
|
}
|
||||||
|
|
||||||
|
Files = Directory.GetFiles(ContentsDir, "00", SearchOption.AllDirectories).Select(Path.GetDirectoryName).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Nca> ReadAllNca()
|
||||||
|
{
|
||||||
|
List<Nca> ncas = new List<Nca>();
|
||||||
|
foreach (var file in Files)
|
||||||
|
{
|
||||||
|
var sdPath = "/" + Util.GetRelativePath(file, ContentsDir).Replace('\\', '/');
|
||||||
|
var nax0 = new Nax0(Keyset, file, sdPath);
|
||||||
|
var nca = new Nca(Keyset, nax0.Stream);
|
||||||
|
ncas.Add(nca);
|
||||||
|
nca.Name = Path.GetFileName(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ncas;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,6 +79,22 @@ namespace libhac
|
||||||
return Encoding.ASCII.GetString(reader.ReadBytes(size), 0, size);
|
return Encoding.ASCII.GetString(reader.ReadBytes(size), 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo Maybe make less naive
|
||||||
|
public static string GetRelativePath(string path, string basePath)
|
||||||
|
{
|
||||||
|
var directory = new DirectoryInfo(basePath);
|
||||||
|
var file = new FileInfo(path);
|
||||||
|
|
||||||
|
string fullDirectory = directory.FullName;
|
||||||
|
string fullFile = file.FullName;
|
||||||
|
|
||||||
|
if (!fullFile.StartsWith(fullDirectory))
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"{nameof(path)} is not a subpath of {nameof(basePath)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullFile.Substring(fullDirectory.Length + 1);
|
||||||
|
}
|
||||||
|
|
||||||
private static int HexToInt(char c)
|
private static int HexToInt(char c)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace libhac.XTSSharp
|
||||||
private bool _bufferDirty;
|
private bool _bufferDirty;
|
||||||
private bool _bufferLoaded;
|
private bool _bufferLoaded;
|
||||||
private int _bufferPos;
|
private int _bufferPos;
|
||||||
|
private int _currentBufferSize;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new stream
|
/// Creates a new stream
|
||||||
|
@ -106,7 +107,7 @@ namespace libhac.XTSSharp
|
||||||
/// <returns>The current position within the stream.</returns>
|
/// <returns>The current position within the stream.</returns>
|
||||||
public override long Position
|
public override long Position
|
||||||
{
|
{
|
||||||
get { return _bufferLoaded ? (_s.Position - _bufferSize + _bufferPos) : _s.Position + _bufferPos; }
|
get { return _bufferLoaded ? (_s.Position - _currentBufferSize + _bufferPos) : _s.Position + _bufferPos; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value < 0L)
|
if (value < 0L)
|
||||||
|
@ -299,6 +300,7 @@ namespace libhac.XTSSharp
|
||||||
_bufferLoaded = true;
|
_bufferLoaded = true;
|
||||||
_bufferPos = 0;
|
_bufferPos = 0;
|
||||||
_bufferDirty = false;
|
_bufferDirty = false;
|
||||||
|
_currentBufferSize = bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in a new issue