Parse entire NACP file

This commit is contained in:
Alex Barney 2018-08-02 16:40:08 -05:00
parent 46cfb2f948
commit d84c406655
5 changed files with 120 additions and 14 deletions

View file

@ -297,7 +297,7 @@ namespace hactoolnet
{
foreach (var title in sdfs.Titles.Values.OrderBy(x => x.Id))
{
Console.WriteLine($"{title.Name} {title.Control?.Version}");
Console.WriteLine($"{title.Name} {title.Control?.DisplayVersion}");
Console.WriteLine($"{title.Id:X16} v{title.Version.Version} ({title.Version}) {title.Metadata.Type}");
foreach (var content in title.Metadata.ContentEntries)
@ -347,8 +347,8 @@ namespace hactoolnet
sb.AppendLine($"User save: {Util.GetBytesReadable(app.Nacp.UserTotalSaveDataSize)}");
if (app.Nacp?.DeviceTotalSaveDataSize > 0)
sb.AppendLine($"System save: {Util.GetBytesReadable(app.Nacp.DeviceTotalSaveDataSize)}");
if (app.Nacp?.BcatSaveDataSize > 0)
sb.AppendLine($"BCAT save: {Util.GetBytesReadable(app.Nacp.BcatSaveDataSize)}");
if (app.Nacp?.BcatDeliveryCacheStorageSize > 0)
sb.AppendLine($"BCAT save: {Util.GetBytesReadable(app.Nacp.BcatDeliveryCacheStorageSize)}");
sb.AppendLine();
}

View file

@ -20,6 +20,8 @@ namespace libhac
public TitleVersion MinimumSystemVersion { get; }
public TitleVersion MinimumApplicationVersion { get; }
public Cnmt() { }
public Cnmt(Stream file)
{
using (var reader = new BinaryReader(file))
@ -33,7 +35,7 @@ namespace libhac
ContentEntryCount = reader.ReadUInt16();
MetaEntryCount = reader.ReadUInt16();
file.Position += 12;
switch (Type)
{
case TitleType.Application:
@ -76,6 +78,8 @@ namespace libhac
public long Size { get; set; }
public CnmtContentType Type { get; set; }
public CnmtContentEntry() { }
public CnmtContentEntry(BinaryReader reader)
{
Hash = reader.ReadBytes(0x20);
@ -93,6 +97,7 @@ namespace libhac
public TitleVersion Version { get; }
public CnmtContentType Type { get; }
public CnmtMetaEntry() { }
public CnmtMetaEntry(BinaryReader reader)
{

View file

@ -1,23 +1,66 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
namespace libhac
{
public class Nacp
{
public NacpLang[] Languages { get; } = new NacpLang[0x10];
public string Version { get; }
public string Isbn { get; }
public byte StartupUserAccount { get; }
public byte TouchScreenUsageMode { get; }
public byte AocRegistrationType { get; }
public int AttributeFlag { get; }
public uint SupportedLanguageFlag { get; }
public uint ParentalControlFlag { get; }
public byte Screenshot { get; }
public byte VideoCapture { get; }
public byte DataLossConfirmation { get; }
public byte PlayLogPolicy { get; }
public ulong PresenceGroupId { get; }
public sbyte[] RatingAge { get; } = new sbyte[32];
public string DisplayVersion { get; }
public ulong AddOnContentBaseId { get; }
public ulong SaveDataOwnerId { get; }
public long UserAccountSaveDataSize { get; }
public long UserAccountSaveDataJournalSize { get; }
public long DeviceSaveDataSize { get; }
public long DeviceSaveDataJournalSize { get; }
public long BcatSaveDataSize { get; }
public long BcatDeliveryCacheStorageSize { get; }
public string ApplicationErrorCodeCategory { get; }
public ulong[] LocalCommunicationId { get; } = new ulong[8];
public byte LogoType { get; }
public byte LogoHandling { get; }
public byte RuntimeAddOnContentInstall { get; }
public byte[] Reserved00 { get; }
public byte CrashReport { get; }
public byte Hdcp { get; }
public ulong SeedForPseudoDeviceId { get; }
public string BcatPassphrase { get; }
public byte Reserved01 { get; }
public byte[] Reserved02 { get; }
public long UserAccountSaveDataSizeMax { get; }
public long UserAccountSaveDataJournalSizeMax { get; }
public long DeviceSaveDataSizeMax { get; }
public long DeviceSaveDataJournalSizeMax { get; }
public long TemporaryStorageSize { get; }
public long CacheStorageSize { get; }
public long CacheStorageJournalSize { get; }
public long CacheStorageDataAndJournalSizeMax { get; }
public short CacheStorageIndex { get; }
public byte[] Reserved03 { get; }
public List<ulong> PlayLogQueryableApplicationId { get; } = new List<ulong>();
public byte PlayLogQueryCapability { get; }
public byte RepairFlag { get; }
public byte ProgramIndex { get; }
public long TotalSaveDataSize { get; }
public long UserTotalSaveDataSize { get; }
public long DeviceTotalSaveDataSize { get; }
public Nacp() { }
public Nacp(BinaryReader reader)
{
var start = reader.BaseStream.Position;
@ -27,8 +70,26 @@ namespace libhac
Languages[i] = new NacpLang(reader);
}
reader.BaseStream.Position = start + 0x3060;
Version = reader.ReadUtf8Z();
Isbn = reader.ReadUtf8Z(37);
reader.BaseStream.Position = start + 0x3025;
StartupUserAccount = reader.ReadByte();
TouchScreenUsageMode = reader.ReadByte();
AocRegistrationType = reader.ReadByte();
AttributeFlag = reader.ReadInt32();
SupportedLanguageFlag = reader.ReadUInt32();
ParentalControlFlag = reader.ReadUInt32();
Screenshot = reader.ReadByte();
VideoCapture = reader.ReadByte();
DataLossConfirmation = reader.ReadByte();
PlayLogPolicy = reader.ReadByte();
PresenceGroupId = reader.ReadUInt64();
for (int i = 0; i < RatingAge.Length; i++)
{
RatingAge[i] = reader.ReadSByte();
}
DisplayVersion = reader.ReadUtf8Z(16);
reader.BaseStream.Position = start + 0x3070;
AddOnContentBaseId = reader.ReadUInt64();
SaveDataOwnerId = reader.ReadUInt64();
@ -36,7 +97,45 @@ namespace libhac
UserAccountSaveDataJournalSize = reader.ReadInt64();
DeviceSaveDataSize = reader.ReadInt64();
DeviceSaveDataJournalSize = reader.ReadInt64();
BcatSaveDataSize = reader.ReadInt64();
BcatDeliveryCacheStorageSize = reader.ReadInt64();
ApplicationErrorCodeCategory = reader.ReadUtf8Z(8);
reader.BaseStream.Position = start + 0x30B0;
for (int i = 0; i < LocalCommunicationId.Length; i++)
{
LocalCommunicationId[i] = reader.ReadUInt64();
}
LogoType = reader.ReadByte();
LogoHandling = reader.ReadByte();
RuntimeAddOnContentInstall = reader.ReadByte();
Reserved00 = reader.ReadBytes(3);
CrashReport = reader.ReadByte();
Hdcp = reader.ReadByte();
SeedForPseudoDeviceId = reader.ReadUInt64();
BcatPassphrase = reader.ReadUtf8Z(65);
reader.BaseStream.Position = start + 0x3148;
UserAccountSaveDataSizeMax = reader.ReadInt64();
UserAccountSaveDataJournalSizeMax = reader.ReadInt64();
DeviceSaveDataSizeMax = reader.ReadInt64();
DeviceSaveDataJournalSizeMax = reader.ReadInt64();
TemporaryStorageSize = reader.ReadInt64();
CacheStorageSize = reader.ReadInt64();
CacheStorageJournalSize = reader.ReadInt64();
CacheStorageDataAndJournalSizeMax = reader.ReadInt64();
CacheStorageIndex = reader.ReadInt16();
Reserved03 = reader.ReadBytes(6);
for (int i = 0; i < 16; i++)
{
var value = reader.ReadUInt64();
if (value != 0) PlayLogQueryableApplicationId.Add(value);
}
PlayLogQueryCapability = reader.ReadByte();
RepairFlag = reader.ReadByte();
ProgramIndex = reader.ReadByte();
UserTotalSaveDataSize = UserAccountSaveDataSize + UserAccountSaveDataJournalSize;
DeviceTotalSaveDataSize = DeviceSaveDataSize + DeviceSaveDataJournalSize;
@ -49,6 +148,8 @@ namespace libhac
public string Title { get; }
public string Developer { get; }
public NacpLang() { }
public NacpLang(BinaryReader reader)
{
var start = reader.BaseStream.Position;

View file

@ -298,14 +298,14 @@ namespace libhac
{
Name = Patch.Name;
Version = Patch.Version;
DisplayVersion = Patch.Control?.Version ?? "";
DisplayVersion = Patch.Control?.DisplayVersion ?? "";
Nacp = Patch.Control;
}
else if (Main != null)
{
Name = Main.Name;
Version = Main.Version;
DisplayVersion = Main.Control?.Version ?? "";
DisplayVersion = Main.Control?.DisplayVersion ?? "";
Nacp = Main.Control;
}
else

View file

@ -67,14 +67,14 @@ namespace libhac
const int bufferSize = 0x8000;
long remaining = length;
byte[] buffer = new byte[bufferSize];
progress?.SetTotal((length + bufferSize) / bufferSize);
progress?.SetTotal(length);
int read;
while ((read = input.Read(buffer, 0, (int)Math.Min(buffer.Length, remaining))) > 0)
{
output.Write(buffer, 0, read);
remaining -= read;
progress?.ReportAdd(1);
progress?.ReportAdd(read);
}
}