public Cnmt(Stream file) { using (var reader = new BinaryReader(file)) { TitleId = reader.ReadUInt64(); uint version = reader.ReadUInt32(); Type = (TitleType)reader.ReadByte(); TitleVersion = new TitleVersion(version, Type < TitleType.Application); FieldD = reader.ReadByte(); TableOffset = reader.ReadUInt16(); ContentEntryCount = reader.ReadUInt16(); MetaEntryCount = reader.ReadUInt16(); file.Position += 12; switch (Type) { case TitleType.Application: ApplicationTitleId = TitleId; PatchTitleId = reader.ReadUInt64(); MinimumSystemVersion = new TitleVersion(reader.ReadUInt32(), true); break; case TitleType.Patch: ApplicationTitleId = reader.ReadUInt64(); MinimumSystemVersion = new TitleVersion(reader.ReadUInt32(), true); break; case TitleType.AddOnContent: ApplicationTitleId = reader.ReadUInt64(); MinimumApplicationVersion = new TitleVersion(reader.ReadUInt32()); break; } file.Position = 0x20 + TableOffset; ContentEntries = new CnmtContentEntry[ContentEntryCount]; MetaEntries = new CnmtContentMetaEntry[MetaEntryCount]; for (int i = 0; i < ContentEntryCount; i++) { ContentEntries[i] = new CnmtContentEntry(reader); } for (int i = 0; i < MetaEntryCount; i++) { MetaEntries[i] = new CnmtContentMetaEntry(reader); } if (Type == TitleType.Patch) { ExtendedData = new CnmtExtended(reader); } Hash = reader.ReadBytes(0x20); } }
public CnmtExtended(BinaryReader reader) { PrevMetaCount = reader.ReadInt32(); // Lists all previous content meta files PrevDeltaSetCount = reader.ReadInt32(); // Lists all previous delta sets DeltaSetCount = reader.ReadInt32(); // Lists the delta set for the current title version FragmentSetCount = reader.ReadInt32(); // Groups fragments into full deltas PrevContentCount = reader.ReadInt32(); // Lists all previous NCAs for the title DeltaContentCount = reader.ReadInt32(); // Lists all NCAs containing delta fragments reader.BaseStream.Position += 4; PrevMetas = new CnmtPrevMetaEntry[PrevMetaCount]; PrevDeltaSets = new CnmtPrevDelta[PrevDeltaSetCount]; DeltaSets = new CnmtDeltaSetInfo[DeltaSetCount]; FragmentSets = new CnmtFragmentSetInfo[FragmentSetCount]; 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 < PrevDeltaSetCount; i++) { PrevDeltaSets[i] = new CnmtPrevDelta(reader); } for (int i = 0; i < DeltaSetCount; i++) { DeltaSets[i] = new CnmtDeltaSetInfo(reader); } for (int i = 0; i < FragmentSetCount; i++) { FragmentSets[i] = new CnmtFragmentSetInfo(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); } int fragmentCount = FragmentSets.Sum(x => x.FragmentCount); FragmentMap = new FragmentMapEntry[fragmentCount]; for (int i = 0; i < fragmentCount; i++) { FragmentMap[i] = new FragmentMapEntry(reader); } }
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 Cnmt(Stream file) { using (var reader = new BinaryReader(file)) { TitleId = reader.ReadUInt64(); uint version = reader.ReadUInt32(); Type = (ContentMetaType)reader.ReadByte(); TitleVersion = new TitleVersion(version, Type < ContentMetaType.Application); FieldD = reader.ReadByte(); TableOffset = reader.ReadUInt16(); ContentEntryCount = reader.ReadUInt16(); MetaEntryCount = reader.ReadUInt16(); // Old, pre-release cnmt files don't have the "required system version" field. // Try to detect this by reading the padding after that field. // The old format usually contains hashes there. file.Position += 8; int padding = reader.ReadInt32(); bool isOldCnmtFormat = padding != 0; switch (Type) { case ContentMetaType.Application: ApplicationTitleId = TitleId; PatchTitleId = reader.ReadUInt64(); MinimumSystemVersion = new TitleVersion(reader.ReadUInt32(), true); break; case ContentMetaType.Patch: ApplicationTitleId = reader.ReadUInt64(); MinimumSystemVersion = new TitleVersion(reader.ReadUInt32(), true); break; case ContentMetaType.AddOnContent: ApplicationTitleId = reader.ReadUInt64(); MinimumApplicationVersion = new TitleVersion(reader.ReadUInt32()); break; } int baseOffset = isOldCnmtFormat ? 0x18 : 0x20; file.Position = baseOffset + TableOffset; ContentEntries = new CnmtContentEntry[ContentEntryCount]; MetaEntries = new CnmtContentMetaEntry[MetaEntryCount]; for (int i = 0; i < ContentEntryCount; i++) { ContentEntries[i] = new CnmtContentEntry(reader); } for (int i = 0; i < MetaEntryCount; i++) { MetaEntries[i] = new CnmtContentMetaEntry(reader); } if (Type == ContentMetaType.Patch) { ExtendedData = new CnmtExtended(reader); } Hash = reader.ReadBytes(0x20); } }