card_image: Parse XCI secure partition with NSP
Eliminated duplicate code and adds support for Rev1+ carts
This commit is contained in:
		| @@ -17,6 +17,8 @@ enum class ResultStatus : u16; | ||||
|  | ||||
| namespace Core::Crypto { | ||||
|  | ||||
| constexpr u64 TICKET_FILE_TITLEKEY_OFFSET = 0x180; | ||||
|  | ||||
| using Key128 = std::array<u8, 0x10>; | ||||
| using Key256 = std::array<u8, 0x20>; | ||||
| using SHA256Hash = std::array<u8, 0x20>; | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| #include "common/logging/log.h" | ||||
| #include "core/file_sys/card_image.h" | ||||
| #include "core/file_sys/content_archive.h" | ||||
| #include "core/file_sys/nca_metadata.h" | ||||
| #include "core/file_sys/partition_filesystem.h" | ||||
| #include "core/file_sys/vfs_offset.h" | ||||
| #include "core/loader/loader.h" | ||||
| @@ -44,15 +45,19 @@ XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) { | ||||
|             partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw); | ||||
|     } | ||||
|  | ||||
|     secure_partition = std::make_shared<NSP>( | ||||
|         main_hfs.GetFile(partition_names[static_cast<size_t>(XCIPartition::Secure)])); | ||||
|  | ||||
|     const auto secure_ncas = secure_partition->GetNCAsCollapsed(); | ||||
|     std::copy(secure_ncas.begin(), secure_ncas.end(), std::back_inserter(ncas)); | ||||
|  | ||||
|     program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA; | ||||
|     program = | ||||
|         secure_partition->GetNCA(secure_partition->GetProgramTitleID(), ContentRecordType::Program); | ||||
|     if (program != nullptr) | ||||
|         program_nca_status = program->GetStatus(); | ||||
|  | ||||
|     auto result = AddNCAFromPartition(XCIPartition::Secure); | ||||
|     if (result != Loader::ResultStatus::Success) { | ||||
|         status = result; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     result = AddNCAFromPartition(XCIPartition::Update); | ||||
|     auto result = AddNCAFromPartition(XCIPartition::Update); | ||||
|     if (result != Loader::ResultStatus::Success) { | ||||
|         status = result; | ||||
|         return; | ||||
| @@ -89,6 +94,10 @@ VirtualDir XCI::GetPartition(XCIPartition partition) const { | ||||
|     return partitions[static_cast<size_t>(partition)]; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const { | ||||
|     return secure_partition; | ||||
| } | ||||
|  | ||||
| VirtualDir XCI::GetSecurePartition() const { | ||||
|     return GetPartition(XCIPartition::Secure); | ||||
| } | ||||
| @@ -105,6 +114,16 @@ VirtualDir XCI::GetLogoPartition() const { | ||||
|     return GetPartition(XCIPartition::Logo); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<NCA> XCI::GetProgramNCA() const { | ||||
|     return program; | ||||
| } | ||||
|  | ||||
| VirtualFile XCI::GetProgramNCAFile() const { | ||||
|     if (GetProgramNCA() == nullptr) | ||||
|         return nullptr; | ||||
|     return GetProgramNCA()->GetBaseFile(); | ||||
| } | ||||
|  | ||||
| const std::vector<std::shared_ptr<NCA>>& XCI::GetNCAs() const { | ||||
|     return ncas; | ||||
| } | ||||
|   | ||||
| @@ -10,6 +10,8 @@ | ||||
| #include "common/common_types.h" | ||||
| #include "common/swap.h" | ||||
| #include "core/file_sys/vfs.h" | ||||
| #include "core/loader/loader.h" | ||||
| #include "submission_package.h" | ||||
|  | ||||
| namespace Loader { | ||||
| enum class ResultStatus : u16; | ||||
| @@ -71,11 +73,14 @@ public: | ||||
|     u8 GetFormatVersion() const; | ||||
|  | ||||
|     VirtualDir GetPartition(XCIPartition partition) const; | ||||
|     std::shared_ptr<NSP> GetSecurePartitionNSP() const; | ||||
|     VirtualDir GetSecurePartition() const; | ||||
|     VirtualDir GetNormalPartition() const; | ||||
|     VirtualDir GetUpdatePartition() const; | ||||
|     VirtualDir GetLogoPartition() const; | ||||
|  | ||||
|     std::shared_ptr<NCA> GetProgramNCA() const; | ||||
|     VirtualFile GetProgramNCAFile() const; | ||||
|     const std::vector<std::shared_ptr<NCA>>& GetNCAs() const; | ||||
|     std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const; | ||||
|     VirtualFile GetNCAFileByType(NCAContentType type) const; | ||||
| @@ -101,6 +106,8 @@ private: | ||||
|     Loader::ResultStatus program_nca_status; | ||||
|  | ||||
|     std::vector<VirtualDir> partitions; | ||||
|     std::shared_ptr<NSP> secure_partition; | ||||
|     std::shared_ptr<NCA> program; | ||||
|     std::vector<std::shared_ptr<NCA>> ncas; | ||||
| }; | ||||
| } // namespace FileSys | ||||
|   | ||||
| @@ -17,8 +17,7 @@ namespace Loader { | ||||
|  | ||||
| AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file) | ||||
|     : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)), | ||||
|       nca_loader(std::make_unique<AppLoader_NCA>( | ||||
|           xci->GetNCAFileByType(FileSys::NCAContentType::Program))) { | ||||
|       nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { | ||||
|     if (xci->GetStatus() != ResultStatus::Success) | ||||
|         return; | ||||
|     const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); | ||||
| @@ -64,11 +63,11 @@ ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) { | ||||
|     if (xci->GetProgramNCAStatus() != ResultStatus::Success) | ||||
|         return xci->GetProgramNCAStatus(); | ||||
|  | ||||
|     const auto nca = xci->GetNCAFileByType(FileSys::NCAContentType::Program); | ||||
|     const auto nca = xci->GetProgramNCA(); | ||||
|     if (nca == nullptr && !Core::Crypto::KeyManager::KeyFileExists(false)) | ||||
|         return ResultStatus::ErrorMissingProductionKeyFile; | ||||
|  | ||||
|     auto result = nca_loader->Load(process); | ||||
|     const auto result = nca_loader->Load(process); | ||||
|     if (result != ResultStatus::Success) | ||||
|         return result; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user