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 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); } }