diff options
Diffstat (limited to 'src/core/loader/loader.cpp')
| -rw-r--r-- | src/core/loader/loader.cpp | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 90e23ccc11..92e2e2f602 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -82,23 +82,27 @@ std::shared_ptr<FileSys::NSP> OpenContainerAsNsp(FileSys::VirtualFile file, File return nullptr; } - if (type == FileType::NSP) { + if (type == FileType::NSP || type == FileType::NSZ) { auto nsp = std::make_shared<FileSys::NSP>(file, program_id, program_index); return nsp->GetStatus() == ResultStatus::Success ? nsp : nullptr; } - if (type == FileType::XCI) { + if (type == FileType::XCI || type == FileType::XCZ) { FileSys::XCI xci{file, program_id, program_index}; - if (xci.GetStatus() != ResultStatus::Success) { - return nullptr; + if (xci.GetStatus() == ResultStatus::Success) { + auto secure_nsp = xci.GetSecurePartitionNSP(); + if (secure_nsp != nullptr && secure_nsp->GetStatus() == ResultStatus::Success) { + return secure_nsp; + } } - auto secure_nsp = xci.GetSecurePartitionNSP(); - if (secure_nsp == nullptr || secure_nsp->GetStatus() != ResultStatus::Success) { - return nullptr; + // PFS0-shaped .xcz (NSZ-style container) does not parse as XCI; fall back to NSP. + if (type == FileType::XCZ) { + auto nsp = std::make_shared<FileSys::NSP>(file, program_id, program_index); + return nsp->GetStatus() == ResultStatus::Success ? nsp : nullptr; } - return secure_nsp; + return nullptr; } return nullptr; @@ -144,7 +148,8 @@ FileType IdentifyFile(FileSys::VirtualFile file) { } bool IsContainerType(FileType type) { - return type == FileType::NSP || type == FileType::XCI; + return type == FileType::NSP || type == FileType::NSZ || type == FileType::XCI || + type == FileType::XCZ; } bool IsBootableGameContainer(FileSys::VirtualFile file, FileType type, u64 program_id, @@ -180,8 +185,12 @@ FileType GuessFromFilename(const std::string& name) { return FileType::NCA; else if (extension == "xci") return FileType::XCI; + else if (extension == "xcz") + return FileType::XCZ; else if (extension == "nsp") return FileType::NSP; + else if (extension == "nsz") + return FileType::NSZ; else if (extension == "kip") return FileType::KIP; return FileType::Unknown; @@ -197,10 +206,14 @@ std::string GetFileTypeString(FileType type) { return "NCA"; case FileType::XCI: return "XCI"; + case FileType::XCZ: + return "XCZ"; case FileType::NAX: return "NAX"; case FileType::NSP: return "NSP"; + case FileType::NSZ: + return "NSZ"; case FileType::KIP: return "KIP"; case FileType::DeconstructedRomDirectory: @@ -326,12 +339,29 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V system.GetContentProvider(), program_id, program_index); + // NCZ-compressed XCI container. XCI-shaped .xcz goes to the XCI loader, while + // PFS0-shaped (NSZ-style) .xcz containers fall back to the NSP loader. + case FileType::XCZ: { + FileSys::XCI probe{file, program_id, program_index}; + if (probe.GetStatus() == ResultStatus::Success && + probe.GetSecurePartitionNSP() != nullptr) { + return std::make_unique<AppLoader_XCI>(std::move(file), + system.GetFileSystemController(), + system.GetContentProvider(), program_id, + program_index); + } + return std::make_unique<AppLoader_NSP>(std::move(file), system.GetFileSystemController(), + system.GetContentProvider(), program_id, + program_index); + } + // NX NAX (NintendoAesXts) file format. case FileType::NAX: return std::make_unique<AppLoader_NAX>(std::move(file)); // NX NSP (Nintendo Submission Package) file format case FileType::NSP: + case FileType::NSZ: return std::make_unique<AppLoader_NSP>(std::move(file), system.GetFileSystemController(), system.GetContentProvider(), program_id, program_index); |
