Read additional portion of patch content metadata files

This commit is contained in:
Alex Barney 2018-09-25 18:28:49 -05:00
parent 64c98df5b3
commit 7a5bd2347d
2 changed files with 202 additions and 22 deletions

View file

@ -4,22 +4,24 @@ namespace LibHac
{
public class Cnmt
{
public ulong TitleId { get; set; }
public TitleVersion TitleVersion { get; set; }
public TitleType Type { get; set; }
public byte FieldD { get; set; }
public int TableOffset { get; set; }
public int ContentEntryCount { get; set; }
public int MetaEntryCount { get; set; }
public ulong TitleId { get; }
public TitleVersion TitleVersion { get; }
public TitleType Type { get; }
public byte FieldD { get; }
public int TableOffset { get; }
public int ContentEntryCount { get; }
public int MetaEntryCount { get; }
public CnmtContentEntry[] ContentEntries { get; set; }
public CnmtMetaEntry[] MetaEntries { get; set; }
public CnmtContentEntry[] ContentEntries { get; }
public CnmtContentMetaEntry[] MetaEntries { get; }
public ulong ApplicationTitleId { get; set; }
public ulong PatchTitleId { get; set; }
public ulong ApplicationTitleId { get; }
public ulong PatchTitleId { get; }
public TitleVersion MinimumSystemVersion { get; }
public TitleVersion MinimumApplicationVersion { get; }
public CnmtExtended ExtendedData { get; }
public Cnmt() { }
public Cnmt(Stream file)
@ -56,7 +58,7 @@ namespace LibHac
file.Position = 0x20 + TableOffset;
ContentEntries = new CnmtContentEntry[ContentEntryCount];
MetaEntries = new CnmtMetaEntry[MetaEntryCount];
MetaEntries = new CnmtContentMetaEntry[MetaEntryCount];
for (int i = 0; i < ContentEntryCount; i++)
{
@ -65,7 +67,12 @@ namespace LibHac
for (int i = 0; i < MetaEntryCount; i++)
{
MetaEntries[i] = new CnmtMetaEntry(reader);
MetaEntries[i] = new CnmtContentMetaEntry(reader);
}
if (Type == TitleType.Patch)
{
ExtendedData = new CnmtExtended(reader);
}
}
}
@ -91,15 +98,15 @@ namespace LibHac
}
}
public class CnmtMetaEntry
public class CnmtContentMetaEntry
{
public ulong TitleId { get; }
public TitleVersion Version { get; }
public CnmtContentType Type { get; }
public CnmtMetaEntry() { }
public CnmtContentMetaEntry() { }
public CnmtMetaEntry(BinaryReader reader)
public CnmtContentMetaEntry(BinaryReader reader)
{
TitleId = reader.ReadUInt64();
Version = new TitleVersion(reader.ReadUInt32(), true);
@ -108,15 +115,188 @@ namespace LibHac
}
}
public class CnmtExtended
{
public int PrevMetaCount { get; }
public int PrevDeltaCount { get; }
public int DeltaInfoCount { get; }
public int DeltaApplyCount { get; }
public int PrevContentCount { get; }
public int DeltaContentCount { get; }
public CnmtPrevMetaEntry[] PrevMetas { get; }
public CnmtPrevDelta[] PrevDeltas { get; }
public CnmtDeltaInfo[] DeltaInfos { get; }
public CnmtDeltaApplyInfo[] DeltaApplyInfos { get; }
public CnmtPrevContent[] PrevContents { get; }
public CnmtContentEntry[] DeltaContents { get; }
public CnmtExtended(BinaryReader reader)
{
PrevMetaCount = reader.ReadInt32();
PrevDeltaCount = reader.ReadInt32();
DeltaInfoCount = reader.ReadInt32();
DeltaApplyCount = reader.ReadInt32();
PrevContentCount = reader.ReadInt32();
DeltaContentCount = reader.ReadInt32();
reader.BaseStream.Position += 4;
PrevMetas = new CnmtPrevMetaEntry[PrevMetaCount];
PrevDeltas = new CnmtPrevDelta[PrevDeltaCount];
DeltaInfos = new CnmtDeltaInfo[DeltaInfoCount];
DeltaApplyInfos = new CnmtDeltaApplyInfo[DeltaApplyCount];
PrevContents = new CnmtPrevContent[PrevContentCount];
DeltaContents = new CnmtContentEntry[DeltaContentCount];
for (int i = 0; i < PrevMetaCount; i++)
{
PrevMetas[i] = new CnmtPrevMetaEntry(reader);
}
for (int i = 0; i < PrevDeltaCount; i++)
{
PrevDeltas[i] = new CnmtPrevDelta(reader);
}
for (int i = 0; i < DeltaInfoCount; i++)
{
DeltaInfos[i] = new CnmtDeltaInfo(reader);
}
for (int i = 0; i < DeltaApplyCount; i++)
{
DeltaApplyInfos[i] = new CnmtDeltaApplyInfo(reader);
}
for (int i = 0; i < PrevContentCount; i++)
{
PrevContents[i] = new CnmtPrevContent(reader);
}
for (int i = 0; i < DeltaContentCount; i++)
{
DeltaContents[i] = new CnmtContentEntry(reader);
}
}
}
public class CnmtPrevMetaEntry
{
public ulong TitleId { get; }
public TitleVersion Version { get; }
public TitleType Type { get; }
public byte[] Hash { get; }
public short Field30 { get; }
public short Field32 { get; }
public int Field34 { get; }
public CnmtPrevMetaEntry(BinaryReader reader)
{
TitleId = reader.ReadUInt64();
Version = new TitleVersion(reader.ReadUInt32());
Type = (TitleType)reader.ReadByte();
reader.BaseStream.Position += 3;
Hash = reader.ReadBytes(0x20);
Field30 = reader.ReadInt16();
Field32 = reader.ReadInt16();
Field34 = reader.ReadInt32();
}
}
public class CnmtPrevDelta
{
public ulong TitleIdOld { get; }
public ulong TitleIdNew { get; }
public TitleVersion VersionOld { get; }
public TitleVersion VersionNew { get; }
public long Size { get; }
public long Field20 { get; }
public CnmtPrevDelta(BinaryReader reader)
{
TitleIdOld = reader.ReadUInt64();
TitleIdNew = reader.ReadUInt64();
VersionOld = new TitleVersion(reader.ReadUInt32());
VersionNew = new TitleVersion(reader.ReadUInt32());
Size = reader.ReadInt64();
Field20 = reader.ReadInt64();
}
}
public class CnmtDeltaInfo
{
public ulong TitleIdOld { get; }
public ulong TitleIdNew { get; }
public TitleVersion VersionOld { get; }
public TitleVersion VersionNew { get; }
public long Field18 { get; }
public long Field20 { get; }
public CnmtDeltaInfo(BinaryReader reader)
{
TitleIdOld = reader.ReadUInt64();
TitleIdNew = reader.ReadUInt64();
VersionOld = new TitleVersion(reader.ReadUInt32());
VersionNew = new TitleVersion(reader.ReadUInt32());
Field18 = reader.ReadInt64();
Field20 = reader.ReadInt64();
}
}
public class CnmtDeltaApplyInfo
{
public byte[] NcaIdOld { get; }
public byte[] NcaIdNew { get; }
public long SizeOld { get; }
public long SizeNew { get; }
public short Field2C { get; }
public CnmtContentType Type { get; }
public short Field2F { get; }
public int Field30 { get; }
public CnmtDeltaApplyInfo(BinaryReader reader)
{
NcaIdOld = reader.ReadBytes(0x10);
NcaIdNew = reader.ReadBytes(0x10);
SizeOld = reader.ReadUInt32();
SizeOld |= ((long)reader.ReadUInt16() << 32);
SizeNew |= ((long)reader.ReadUInt16() << 32);
SizeNew = reader.ReadUInt32();
Field2C = reader.ReadInt16();
Type = (CnmtContentType)reader.ReadByte();
Field2F = reader.ReadByte();
Field30 = reader.ReadInt32();
}
}
public class CnmtPrevContent
{
public byte[] NcaId { get; }
public long Size { get; }
public CnmtContentType Type { get; }
public CnmtPrevContent(BinaryReader reader)
{
NcaId = reader.ReadBytes(0x10);
Size = reader.ReadUInt32();
Size |= ((long)reader.ReadUInt16() << 32);
Type = (CnmtContentType)reader.ReadByte();
reader.BaseStream.Position += 1;
}
}
public enum CnmtContentType
{
Meta,
Program,
Data,
Control,
OfflineManualHtml,
LegalHtml,
UpdatePatch
HtmlDocument,
LegalInformation,
DeltaFragment
}
public enum TitleType
@ -129,6 +309,6 @@ namespace LibHac
Application = 0x80,
Patch,
AddOnContent,
DeltaTitle
Delta
}
}

View file

@ -304,7 +304,7 @@ namespace LibHac
public long GetSize()
{
return Metadata.ContentEntries
.Where(x => x.Type < CnmtContentType.UpdatePatch)
.Where(x => x.Type < CnmtContentType.DeltaFragment)
.Sum(x => x.Size);
}
}
@ -339,7 +339,7 @@ namespace LibHac
case TitleType.AddOnContent:
AddOnContent.Add(title);
break;
case TitleType.DeltaTitle:
case TitleType.Delta:
break;
}