SD card content listing example

This commit is contained in:
Alex Barney 2018-06-21 11:16:51 -05:00
parent a6e72b0ee7
commit 8054d38f5a
5 changed files with 81 additions and 2 deletions

View file

@ -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}");
}
}
} }
} }

View file

@ -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
View 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;
}
}
}

View file

@ -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)
{ {

View file

@ -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>