Updated cnmt parsing

This commit is contained in:
Alex Barney 2019-03-01 15:00:19 -06:00
parent caccc5a677
commit bc986a4d0b

View file

@ -1,4 +1,5 @@
using System.IO; using System.IO;
using System.Linq;
namespace LibHac namespace LibHac
{ {
@ -22,6 +23,8 @@ namespace LibHac
public CnmtExtended ExtendedData { get; } public CnmtExtended ExtendedData { get; }
public byte[] Hash { get; }
public Cnmt() { } public Cnmt() { }
public Cnmt(Stream file) public Cnmt(Stream file)
@ -74,6 +77,8 @@ namespace LibHac
{ {
ExtendedData = new CnmtExtended(reader); ExtendedData = new CnmtExtended(reader);
} }
Hash = reader.ReadBytes(0x20);
} }
} }
} }
@ -118,33 +123,34 @@ namespace LibHac
public class CnmtExtended public class CnmtExtended
{ {
public int PrevMetaCount { get; } public int PrevMetaCount { get; }
public int PrevDeltaCount { get; } public int PrevDeltaSetCount { get; }
public int DeltaInfoCount { get; } public int DeltaSetCount { get; }
public int DeltaApplyCount { get; } public int FragmentSetCount { get; }
public int PrevContentCount { get; } public int PrevContentCount { get; }
public int DeltaContentCount { get; } public int DeltaContentCount { get; }
public CnmtPrevMetaEntry[] PrevMetas { get; } public CnmtPrevMetaEntry[] PrevMetas { get; }
public CnmtPrevDelta[] PrevDeltas { get; } public CnmtPrevDelta[] PrevDeltaSets { get; }
public CnmtDeltaInfo[] DeltaInfos { get; } public CnmtDeltaSetInfo[] DeltaSets { get; }
public CnmtDeltaApplyInfo[] DeltaApplyInfos { get; } public CnmtFragmentSetInfo[] FragmentSets { get; }
public CnmtPrevContent[] PrevContents { get; } public CnmtPrevContent[] PrevContents { get; }
public CnmtContentEntry[] DeltaContents { get; } public CnmtContentEntry[] DeltaContents { get; }
public FragmentMapEntry[] FragmentMap { get; }
public CnmtExtended(BinaryReader reader) public CnmtExtended(BinaryReader reader)
{ {
PrevMetaCount = reader.ReadInt32(); PrevMetaCount = reader.ReadInt32(); // Lists all previous content meta files
PrevDeltaCount = reader.ReadInt32(); PrevDeltaSetCount = reader.ReadInt32(); // Lists all previous delta sets
DeltaInfoCount = reader.ReadInt32(); DeltaSetCount = reader.ReadInt32(); // Lists the delta set for the current title version
DeltaApplyCount = reader.ReadInt32(); FragmentSetCount = reader.ReadInt32(); // Groups fragments into full deltas
PrevContentCount = reader.ReadInt32(); PrevContentCount = reader.ReadInt32(); // Lists all previous NCAs for the title
DeltaContentCount = reader.ReadInt32(); DeltaContentCount = reader.ReadInt32(); // Lists all NCAs containing delta fragments
reader.BaseStream.Position += 4; reader.BaseStream.Position += 4;
PrevMetas = new CnmtPrevMetaEntry[PrevMetaCount]; PrevMetas = new CnmtPrevMetaEntry[PrevMetaCount];
PrevDeltas = new CnmtPrevDelta[PrevDeltaCount]; PrevDeltaSets = new CnmtPrevDelta[PrevDeltaSetCount];
DeltaInfos = new CnmtDeltaInfo[DeltaInfoCount]; DeltaSets = new CnmtDeltaSetInfo[DeltaSetCount];
DeltaApplyInfos = new CnmtDeltaApplyInfo[DeltaApplyCount]; FragmentSets = new CnmtFragmentSetInfo[FragmentSetCount];
PrevContents = new CnmtPrevContent[PrevContentCount]; PrevContents = new CnmtPrevContent[PrevContentCount];
DeltaContents = new CnmtContentEntry[DeltaContentCount]; DeltaContents = new CnmtContentEntry[DeltaContentCount];
@ -153,19 +159,19 @@ namespace LibHac
PrevMetas[i] = new CnmtPrevMetaEntry(reader); PrevMetas[i] = new CnmtPrevMetaEntry(reader);
} }
for (int i = 0; i < PrevDeltaCount; i++) for (int i = 0; i < PrevDeltaSetCount; i++)
{ {
PrevDeltas[i] = new CnmtPrevDelta(reader); PrevDeltaSets[i] = new CnmtPrevDelta(reader);
} }
for (int i = 0; i < DeltaInfoCount; i++) for (int i = 0; i < DeltaSetCount; i++)
{ {
DeltaInfos[i] = new CnmtDeltaInfo(reader); DeltaSets[i] = new CnmtDeltaSetInfo(reader);
} }
for (int i = 0; i < DeltaApplyCount; i++) for (int i = 0; i < FragmentSetCount; i++)
{ {
DeltaApplyInfos[i] = new CnmtDeltaApplyInfo(reader); FragmentSets[i] = new CnmtFragmentSetInfo(reader);
} }
for (int i = 0; i < PrevContentCount; i++) for (int i = 0; i < PrevContentCount; i++)
@ -177,6 +183,14 @@ namespace LibHac
{ {
DeltaContents[i] = new CnmtContentEntry(reader); DeltaContents[i] = new CnmtContentEntry(reader);
} }
int fragmentCount = FragmentSets.Sum(x => x.FragmentCount);
FragmentMap = new FragmentMapEntry[fragmentCount];
for (int i = 0; i < fragmentCount; i++)
{
FragmentMap[i] = new FragmentMapEntry(reader);
}
} }
} }
@ -186,9 +200,9 @@ namespace LibHac
public TitleVersion Version { get; } public TitleVersion Version { get; }
public TitleType Type { get; } public TitleType Type { get; }
public byte[] Hash { get; } public byte[] Hash { get; }
public short Field30 { get; } public short ContentCount { get; }
public short Field32 { get; } public short CnmtPrevMetaEntryField32 { get; }
public int Field34 { get; } public int CnmtPrevMetaEntryField34 { get; }
public CnmtPrevMetaEntry(BinaryReader reader) public CnmtPrevMetaEntry(BinaryReader reader)
{ {
@ -197,9 +211,9 @@ namespace LibHac
Type = (TitleType)reader.ReadByte(); Type = (TitleType)reader.ReadByte();
reader.BaseStream.Position += 3; reader.BaseStream.Position += 3;
Hash = reader.ReadBytes(0x20); Hash = reader.ReadBytes(0x20);
Field30 = reader.ReadInt16(); ContentCount = reader.ReadInt16();
Field32 = reader.ReadInt16(); CnmtPrevMetaEntryField32 = reader.ReadInt16();
Field34 = reader.ReadInt32(); CnmtPrevMetaEntryField34 = reader.ReadInt32();
} }
} }
@ -210,7 +224,7 @@ namespace LibHac
public TitleVersion VersionOld { get; } public TitleVersion VersionOld { get; }
public TitleVersion VersionNew { get; } public TitleVersion VersionNew { get; }
public long Size { get; } public long Size { get; }
public long Field20 { get; } public long CnmtPrevDeltaField20 { get; }
public CnmtPrevDelta(BinaryReader reader) public CnmtPrevDelta(BinaryReader reader)
{ {
@ -219,43 +233,43 @@ namespace LibHac
VersionOld = new TitleVersion(reader.ReadUInt32()); VersionOld = new TitleVersion(reader.ReadUInt32());
VersionNew = new TitleVersion(reader.ReadUInt32()); VersionNew = new TitleVersion(reader.ReadUInt32());
Size = reader.ReadInt64(); Size = reader.ReadInt64();
Field20 = reader.ReadInt64(); CnmtPrevDeltaField20 = reader.ReadInt64();
} }
} }
public class CnmtDeltaInfo public class CnmtDeltaSetInfo
{ {
public ulong TitleIdOld { get; } public ulong TitleIdOld { get; }
public ulong TitleIdNew { get; } public ulong TitleIdNew { get; }
public TitleVersion VersionOld { get; } public TitleVersion VersionOld { get; }
public TitleVersion VersionNew { get; } public TitleVersion VersionNew { get; }
public long Field18 { get; } public long FragmentSetCount { get; }
public long Field20 { get; } public long DeltaContentCount { get; }
public CnmtDeltaInfo(BinaryReader reader) public CnmtDeltaSetInfo(BinaryReader reader)
{ {
TitleIdOld = reader.ReadUInt64(); TitleIdOld = reader.ReadUInt64();
TitleIdNew = reader.ReadUInt64(); TitleIdNew = reader.ReadUInt64();
VersionOld = new TitleVersion(reader.ReadUInt32()); VersionOld = new TitleVersion(reader.ReadUInt32());
VersionNew = new TitleVersion(reader.ReadUInt32()); VersionNew = new TitleVersion(reader.ReadUInt32());
Field18 = reader.ReadInt64(); FragmentSetCount = reader.ReadInt64();
Field20 = reader.ReadInt64(); DeltaContentCount = reader.ReadInt64();
} }
} }
public class CnmtDeltaApplyInfo public class CnmtFragmentSetInfo
{ {
public byte[] NcaIdOld { get; } public byte[] NcaIdOld { get; }
public byte[] NcaIdNew { get; } public byte[] NcaIdNew { get; }
public long SizeOld { get; } public long SizeOld { get; }
public long SizeNew { get; } public long SizeNew { get; }
public short Field2C { get; } public short FragmentCount { get; }
public CnmtContentType Type { get; } public CnmtContentType Type { get; }
public short Field2F { get; } public CnmtDeltaType DeltaType { get; }
public int Field30 { get; } public int FragmentSetInfoField30 { get; }
public CnmtDeltaApplyInfo(BinaryReader reader) public CnmtFragmentSetInfo(BinaryReader reader)
{ {
NcaIdOld = reader.ReadBytes(0x10); NcaIdOld = reader.ReadBytes(0x10);
NcaIdNew = reader.ReadBytes(0x10); NcaIdNew = reader.ReadBytes(0x10);
@ -265,10 +279,10 @@ namespace LibHac
SizeNew |= (long)reader.ReadUInt16() << 32; SizeNew |= (long)reader.ReadUInt16() << 32;
SizeNew = reader.ReadUInt32(); SizeNew = reader.ReadUInt32();
Field2C = reader.ReadInt16(); FragmentCount = reader.ReadInt16();
Type = (CnmtContentType)reader.ReadByte(); Type = (CnmtContentType)reader.ReadByte();
Field2F = reader.ReadByte(); DeltaType = (CnmtDeltaType)reader.ReadByte();
Field30 = reader.ReadInt32(); FragmentSetInfoField30 = reader.ReadInt32();
} }
} }
@ -288,6 +302,18 @@ namespace LibHac
} }
} }
public class FragmentMapEntry
{
public short ContentIndex { get; }
public short FragmentIndex { get; }
public FragmentMapEntry(BinaryReader reader)
{
ContentIndex = reader.ReadInt16();
FragmentIndex = reader.ReadInt16();
}
}
public enum CnmtContentType public enum CnmtContentType
{ {
Meta, Meta,
@ -299,6 +325,13 @@ namespace LibHac
DeltaFragment DeltaFragment
} }
public enum CnmtDeltaType
{
Delta,
Replace,
NewContent
}
public enum TitleType public enum TitleType
{ {
SystemProgram = 1, SystemProgram = 1,