From 04868ab9da2049429808a265dc50696f6300b2b4 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 12 Jul 2023 23:17:18 +0200 Subject: file_sys/content_archive: Detect compressed NCAs (#11047) --- src/core/file_sys/content_archive.cpp | 39 ++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'src/core/file_sys') diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 50303fe42..06efab46d 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -57,11 +57,34 @@ struct NCASectionHeaderBlock { }; static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size."); +struct NCABucketInfo { + u64 table_offset; + u64 table_size; + std::array table_header; +}; +static_assert(sizeof(NCABucketInfo) == 0x20, "NCABucketInfo has incorrect size."); + +struct NCASparseInfo { + NCABucketInfo bucket; + u64 physical_offset; + u16 generation; + INSERT_PADDING_BYTES_NOINIT(0x6); +}; +static_assert(sizeof(NCASparseInfo) == 0x30, "NCASparseInfo has incorrect size."); + +struct NCACompressionInfo { + NCABucketInfo bucket; + INSERT_PADDING_BYTES_NOINIT(0x8); +}; +static_assert(sizeof(NCACompressionInfo) == 0x28, "NCACompressionInfo has incorrect size."); + struct NCASectionRaw { NCASectionHeaderBlock header; std::array block_data; std::array section_ctr; - INSERT_PADDING_BYTES_NOINIT(0xB8); + NCASparseInfo sparse_info; + NCACompressionInfo compression_info; + INSERT_PADDING_BYTES_NOINIT(0x60); }; static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size."); @@ -225,6 +248,20 @@ bool NCA::ReadSections(const std::vector& sections, u64 bktr_b for (std::size_t i = 0; i < sections.size(); ++i) { const auto& section = sections[i]; + if (section.raw.sparse_info.bucket.table_offset != 0 && + section.raw.sparse_info.bucket.table_size != 0) { + LOG_ERROR(Loader, "Sparse NCAs are not supported."); + status = Loader::ResultStatus::ErrorSparseNCA; + return false; + } + + if (section.raw.compression_info.bucket.table_offset != 0 && + section.raw.compression_info.bucket.table_size != 0) { + LOG_ERROR(Loader, "Compressed NCAs are not supported."); + status = Loader::ResultStatus::ErrorCompressedNCA; + return false; + } + if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) { if (!ReadRomFSSection(section, header.section_tables[i], bktr_base_ivfc_offset)) { return false; -- cgit v1.2.3