From 5a07260e1b692ca9e15ce2a40df612332e651f00 Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Sun, 22 Mar 2026 22:18:14 +0100 Subject: [PATCH] loader: Fix identifying zcci files when system files are not set up --- src/core/loader/3dsx.cpp | 16 +++++++-------- src/core/loader/elf.cpp | 11 +++++------ src/core/loader/ncch.cpp | 42 ++++++++++++++++++++-------------------- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index 83a41a5e7..d8c0beded 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -261,15 +261,15 @@ AppLoader_THREEDSX::AppLoader_THREEDSX(Core::System& system_, FileUtil::IOFile&& } FileType AppLoader_THREEDSX::IdentifyType(FileUtil::IOFile* file) { - u32 magic; - file->Seek(0, SEEK_SET); - if (1 != file->ReadArray(&magic, 1)) - return FileType::Error; + u32 magic{}; - if (MakeMagic('3', 'D', 'S', 'X') == magic || - (MakeMagic('Z', '3', 'D', 'S') == magic && - FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file) == MakeMagic('3', 'D', 'S', 'X'))) - return FileType::THREEDSX; + if (file->Seek(0, SEEK_SET) && 1 == file->ReadArray(&magic, 1)) { + if (MakeMagic('3', 'D', 'S', 'X') == magic || + (MakeMagic('Z', '3', 'D', 'S') == magic && + FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file) == + MakeMagic('3', 'D', 'S', 'X'))) + return FileType::THREEDSX; + } return FileType::Error; } diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index c03ef3267..ebecb6712 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -357,13 +357,12 @@ SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const namespace Loader { FileType AppLoader_ELF::IdentifyType(FileUtil::IOFile* file) { - u32 magic; - file->Seek(0, SEEK_SET); - if (1 != file->ReadArray(&magic, 1)) - return FileType::Error; + u32 magic{}; - if (MakeMagic('\x7f', 'E', 'L', 'F') == magic) - return FileType::ELF; + if (file->Seek(0, SEEK_SET) && 1 == file->ReadArray(&magic, 1)) { + if (MakeMagic('\x7f', 'E', 'L', 'F') == magic) + return FileType::ELF; + } return FileType::Error; } diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index d988dbb83..f61f5724b 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -37,35 +37,17 @@ static constexpr u64 UPDATE_TID_HIGH = 0x0004000e00000000; static constexpr u64 DLP_CHILD_TID_HIGH = 0x0004000100000000; FileType AppLoader_NCCH::IdentifyType(FileUtil::IOFile* file) { - u32 magic; - file->Seek(0x100, SEEK_SET); - if (1 != file->ReadArray(&magic, 1)) - return FileType::Error; - - if (MakeMagic('N', 'C', 'S', 'D') == magic) - return FileType::CCI; - - if (MakeMagic('N', 'C', 'C', 'H') == magic) - return FileType::CXI; + u32 magic{}; std::unique_ptr file_crypto = HW::UniqueData::OpenUniqueCryptoFile( file->Filename(), "rb", HW::UniqueData::UniqueCryptoFileID::NCCH); - file_crypto->Seek(0x100, SEEK_SET); - if (1 != file_crypto->ReadArray(&magic, 1)) - return FileType::Error; - - if (MakeMagic('N', 'C', 'S', 'D') == magic) - return FileType::CCI; - - if (MakeMagic('N', 'C', 'C', 'H') == magic) - return FileType::CXI; - + // Check compressed NCCH file std::optional magic_zstd = FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file); if (!magic_zstd.has_value()) { + // Handle compressed and crypto NCCH file magic_zstd = FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file_crypto.get()); } - if (magic_zstd.has_value()) { if (MakeMagic('N', 'C', 'S', 'D') == magic_zstd) return FileType::CCI; @@ -74,6 +56,24 @@ FileType AppLoader_NCCH::IdentifyType(FileUtil::IOFile* file) { return FileType::CXI; } + // Check normal NCCH file + if (file->Seek(0x100, SEEK_SET) && 1 == file->ReadArray(&magic, 1)) { + if (MakeMagic('N', 'C', 'S', 'D') == magic) + return FileType::CCI; + + if (MakeMagic('N', 'C', 'C', 'H') == magic) + return FileType::CXI; + } + + // Check crypto NCCH file + if (file_crypto->Seek(0x100, SEEK_SET) && 1 == file_crypto->ReadArray(&magic, 1)) { + if (MakeMagic('N', 'C', 'S', 'D') == magic) + return FileType::CCI; + + if (MakeMagic('N', 'C', 'C', 'H') == magic) + return FileType::CXI; + } + return FileType::Error; }