xci.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <vector>
  5. #include "common/common_types.h"
  6. #include "core/file_sys/card_image.h"
  7. #include "core/file_sys/content_archive.h"
  8. #include "core/file_sys/control_metadata.h"
  9. #include "core/file_sys/patch_manager.h"
  10. #include "core/file_sys/romfs.h"
  11. #include "core/file_sys/submission_package.h"
  12. #include "core/hle/kernel/process.h"
  13. #include "core/loader/nca.h"
  14. #include "core/loader/xci.h"
  15. namespace Loader {
  16. AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
  17. : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
  18. nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) {
  19. if (xci->GetStatus() != ResultStatus::Success)
  20. return;
  21. const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
  22. if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success)
  23. return;
  24. std::tie(nacp_file, icon_file) =
  25. FileSys::PatchManager(xci->GetProgramTitleID()).ParseControlNCA(control_nca);
  26. }
  27. AppLoader_XCI::~AppLoader_XCI() = default;
  28. FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) {
  29. FileSys::XCI xci(file);
  30. if (xci.GetStatus() == ResultStatus::Success &&
  31. xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr &&
  32. AppLoader_NCA::IdentifyType(xci.GetNCAFileByType(FileSys::NCAContentType::Program)) ==
  33. FileType::NCA) {
  34. return FileType::XCI;
  35. }
  36. return FileType::Error;
  37. }
  38. ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) {
  39. if (is_loaded) {
  40. return ResultStatus::ErrorAlreadyLoaded;
  41. }
  42. if (xci->GetStatus() != ResultStatus::Success)
  43. return xci->GetStatus();
  44. if (xci->GetProgramNCAStatus() != ResultStatus::Success)
  45. return xci->GetProgramNCAStatus();
  46. const auto nca = xci->GetProgramNCA();
  47. if (nca == nullptr && !Core::Crypto::KeyManager::KeyFileExists(false))
  48. return ResultStatus::ErrorMissingProductionKeyFile;
  49. const auto result = nca_loader->Load(process);
  50. if (result != ResultStatus::Success)
  51. return result;
  52. is_loaded = true;
  53. return ResultStatus::Success;
  54. }
  55. ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& dir) {
  56. return nca_loader->ReadRomFS(dir);
  57. }
  58. ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
  59. return nca_loader->ReadProgramId(out_program_id);
  60. }
  61. ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) {
  62. if (icon_file == nullptr)
  63. return ResultStatus::ErrorNoControl;
  64. buffer = icon_file->ReadAllBytes();
  65. return ResultStatus::Success;
  66. }
  67. ResultStatus AppLoader_XCI::ReadTitle(std::string& title) {
  68. if (nacp_file == nullptr)
  69. return ResultStatus::ErrorNoControl;
  70. title = nacp_file->GetApplicationName();
  71. return ResultStatus::Success;
  72. }
  73. } // namespace Loader