Make sure meta nca is included in title

This commit is contained in:
Alex Barney 2018-06-26 19:42:01 -05:00
parent e4d9b46e60
commit f583d01248
4 changed files with 65 additions and 5 deletions

View file

@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using libhac; using libhac;
@ -20,10 +18,12 @@ namespace hactoolnet
ListTitles(sdfs); ListTitles(sdfs);
//DecryptNax0(sdfs, "C0628FB07A89E9050BDA258F74868E8D"); //DecryptNax0(sdfs, "C0628FB07A89E9050BDA258F74868E8D");
DecryptTitle(sdfs, 0x0100000000010800);
} }
static void DecryptNax0(SdFs sdFs, string name) static void DecryptNax0(SdFs sdFs, string name)
{ {
if (!sdFs.Ncas.ContainsKey(name)) return;
var nca = sdFs.Ncas[name]; var nca = sdFs.Ncas[name];
using (var output = new FileStream($"{nca.NcaId}.nca", FileMode.Create)) using (var output = new FileStream($"{nca.NcaId}.nca", FileMode.Create))
using (var progress = new ProgressBar()) using (var progress = new ProgressBar())
@ -35,6 +35,25 @@ namespace hactoolnet
} }
} }
static void DecryptTitle(SdFs sdFs, ulong titleId)
{
var title = sdFs.Titles[titleId];
var dirName = $"{titleId:X16}v{title.Version.Version}";
Directory.CreateDirectory(dirName);
foreach (var nca in title.Ncas)
{
using (var output = new FileStream(Path.Combine(dirName, nca.Filename), FileMode.Create))
using (var progress = new ProgressBar())
{
progress.LogMessage($"Writing {nca.Filename}");
nca.Stream.Position = 0;
nca.Stream.CopyStream(output, nca.Stream.Length, progress);
}
}
}
static SdFs LoadSdFs(string[] args) static SdFs LoadSdFs(string[] args)
{ {
var keyset = ExternalKeys.ReadKeyFile(args[0]); var keyset = ExternalKeys.ReadKeyFile(args[0]);
@ -60,7 +79,7 @@ namespace hactoolnet
foreach (var content in title.Metadata.ContentEntries) foreach (var content in title.Metadata.ContentEntries)
{ {
Console.WriteLine( Console.WriteLine(
$" {BitConverter.ToString(content.NcaId).Replace("-", "")}.nca {content.Type} {Util.GetBytesReadable(content.Size)}"); $" {content.NcaId.ToHexString()}.nca {content.Type} {Util.GetBytesReadable(content.Size)}");
} }
Console.WriteLine(""); Console.WriteLine("");

View file

@ -9,6 +9,7 @@ namespace libhac
{ {
public NcaHeader Header { get; private set; } public NcaHeader Header { get; private set; }
public string NcaId { get; set; } public string NcaId { get; set; }
public string Filename { get; set; }
public bool HasRightsId { get; private set; } public bool HasRightsId { get; private set; }
public int CryptoType { get; private set; } public int CryptoType { get; private set; }
public byte[][] DecryptedKeys { get; } = Util.CreateJaggedArray<byte[][]>(4, 0x10); public byte[][] DecryptedKeys { get; } = Util.CreateJaggedArray<byte[][]>(4, 0x10);

View file

@ -31,7 +31,7 @@ namespace libhac
ReadTitles(); ReadTitles();
} }
public void OpenAllNcas() private void OpenAllNcas()
{ {
foreach (var file in Files) foreach (var file in Files)
{ {
@ -43,6 +43,8 @@ namespace libhac
Nax0s.Add(nax0); Nax0s.Add(nax0);
nca = new Nca(Keyset, nax0.Stream, false); nca = new Nca(Keyset, nax0.Stream, false);
nca.NcaId = Path.GetFileNameWithoutExtension(file); nca.NcaId = Path.GetFileNameWithoutExtension(file);
var extention = nca.Header.ContentType == ContentType.Meta ? ".cnmt.nca" : ".nca";
nca.Filename = nca.NcaId + extention;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -53,7 +55,7 @@ namespace libhac
} }
} }
public void ReadTitles() private void ReadTitles()
{ {
foreach (var nca in Ncas.Values.Where(x => x.Header.ContentType == ContentType.Meta)) foreach (var nca in Ncas.Values.Where(x => x.Header.ContentType == ContentType.Meta))
{ {
@ -68,6 +70,18 @@ namespace libhac
title.Id = metadata.TitleId; title.Id = metadata.TitleId;
title.Version = new TitleVersion(metadata.TitleVersion); title.Version = new TitleVersion(metadata.TitleVersion);
title.Metadata = metadata; title.Metadata = metadata;
title.Ncas.Add(nca);
foreach (var content in metadata.ContentEntries)
{
var ncaId = content.NcaId.ToHexString();
if (Ncas.TryGetValue(ncaId, out Nca contentNca))
{
title.Ncas.Add(contentNca);
}
}
Titles.Add(title.Id, title); Titles.Add(title.Id, title);
} }
} }

View file

@ -177,6 +177,32 @@ namespace libhac
return result; return result;
} }
private static readonly uint[] Lookup32 = CreateLookup32();
private static uint[] CreateLookup32()
{
var result = new uint[256];
for (int i = 0; i < 256; i++)
{
string s = i.ToString("X2");
result[i] = s[0] + ((uint)s[1] << 16);
}
return result;
}
public static string ToHexString(this byte[] bytes)
{
var lookup32 = Lookup32;
var result = new char[bytes.Length * 2];
for (int i = 0; i < bytes.Length; i++)
{
var val = lookup32[bytes[i]];
result[2 * i] = (char)val;
result[2 * i + 1] = (char)(val >> 16);
}
return new string(result);
}
internal static long MediaToReal(long media) internal static long MediaToReal(long media)
{ {
return MediaSize * media; return MediaSize * media;