diff options
26 files changed, 259 insertions, 157 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 242796008..9253e05b7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -210,7 +210,7 @@ struct System::Impl { | |||
| 210 | 210 | ||
| 211 | ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, | 211 | ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, |
| 212 | const std::string& filepath) { | 212 | const std::string& filepath) { |
| 213 | app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath)); | 213 | app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath)); |
| 214 | if (!app_loader) { | 214 | if (!app_loader) { |
| 215 | LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); | 215 | LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); |
| 216 | return ResultStatus::ErrorGetLoader; | 216 | return ResultStatus::ErrorGetLoader; |
| @@ -224,7 +224,7 @@ struct System::Impl { | |||
| 224 | return init_result; | 224 | return init_result; |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | telemetry_session->AddInitialInfo(*app_loader); | 227 | telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); |
| 228 | auto main_process = | 228 | auto main_process = |
| 229 | Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland); | 229 | Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland); |
| 230 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); | 230 | const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); |
| @@ -338,7 +338,7 @@ struct System::Impl { | |||
| 338 | Service::Glue::ApplicationLaunchProperty launch{}; | 338 | Service::Glue::ApplicationLaunchProperty launch{}; |
| 339 | launch.title_id = process.GetTitleID(); | 339 | launch.title_id = process.GetTitleID(); |
| 340 | 340 | ||
| 341 | FileSys::PatchManager pm{launch.title_id}; | 341 | FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider}; |
| 342 | launch.version = pm.GetGameVersion().value_or(0); | 342 | launch.version = pm.GetGameVersion().value_or(0); |
| 343 | 343 | ||
| 344 | // TODO(DarkLordZach): When FSController/Game Card Support is added, if | 344 | // TODO(DarkLordZach): When FSController/Game Card Support is added, if |
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 807b05821..e9d1607d0 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -112,7 +112,10 @@ bool IsDirValidAndNonEmpty(const VirtualDir& dir) { | |||
| 112 | } | 112 | } |
| 113 | } // Anonymous namespace | 113 | } // Anonymous namespace |
| 114 | 114 | ||
| 115 | PatchManager::PatchManager(u64 title_id) : title_id(title_id) {} | 115 | PatchManager::PatchManager(u64 title_id_, |
| 116 | const Service::FileSystem::FileSystemController& fs_controller_, | ||
| 117 | const ContentProvider& content_provider_) | ||
| 118 | : title_id{title_id_}, fs_controller{fs_controller_}, content_provider{content_provider_} {} | ||
| 116 | 119 | ||
| 117 | PatchManager::~PatchManager() = default; | 120 | PatchManager::~PatchManager() = default; |
| 118 | 121 | ||
| @@ -128,34 +131,30 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { | |||
| 128 | 131 | ||
| 129 | if (Settings::values.dump_exefs) { | 132 | if (Settings::values.dump_exefs) { |
| 130 | LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id); | 133 | LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id); |
| 131 | const auto dump_dir = | 134 | const auto dump_dir = fs_controller.GetModificationDumpRoot(title_id); |
| 132 | Core::System::GetInstance().GetFileSystemController().GetModificationDumpRoot(title_id); | ||
| 133 | if (dump_dir != nullptr) { | 135 | if (dump_dir != nullptr) { |
| 134 | const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs"); | 136 | const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs"); |
| 135 | VfsRawCopyD(exefs, exefs_dir); | 137 | VfsRawCopyD(exefs, exefs_dir); |
| 136 | } | 138 | } |
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | const auto& installed = Core::System::GetInstance().GetContentProvider(); | ||
| 140 | |||
| 141 | const auto& disabled = Settings::values.disabled_addons[title_id]; | 141 | const auto& disabled = Settings::values.disabled_addons[title_id]; |
| 142 | const auto update_disabled = | 142 | const auto update_disabled = |
| 143 | std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend(); | 143 | std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend(); |
| 144 | 144 | ||
| 145 | // Game Updates | 145 | // Game Updates |
| 146 | const auto update_tid = GetUpdateTitleID(title_id); | 146 | const auto update_tid = GetUpdateTitleID(title_id); |
| 147 | const auto update = installed.GetEntry(update_tid, ContentRecordType::Program); | 147 | const auto update = content_provider.GetEntry(update_tid, ContentRecordType::Program); |
| 148 | 148 | ||
| 149 | if (!update_disabled && update != nullptr && update->GetExeFS() != nullptr && | 149 | if (!update_disabled && update != nullptr && update->GetExeFS() != nullptr && |
| 150 | update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { | 150 | update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { |
| 151 | LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully", | 151 | LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully", |
| 152 | FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0))); | 152 | FormatTitleVersion(content_provider.GetEntryVersion(update_tid).value_or(0))); |
| 153 | exefs = update->GetExeFS(); | 153 | exefs = update->GetExeFS(); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | // LayeredExeFS | 156 | // LayeredExeFS |
| 157 | const auto load_dir = | 157 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 158 | Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); | ||
| 159 | if (load_dir != nullptr && load_dir->GetSize() > 0) { | 158 | if (load_dir != nullptr && load_dir->GetSize() > 0) { |
| 160 | auto patch_dirs = load_dir->GetSubdirectories(); | 159 | auto patch_dirs = load_dir->GetSubdirectories(); |
| 161 | std::sort( | 160 | std::sort( |
| @@ -241,8 +240,7 @@ std::vector<u8> PatchManager::PatchNSO(const std::vector<u8>& nso, const std::st | |||
| 241 | if (Settings::values.dump_nso) { | 240 | if (Settings::values.dump_nso) { |
| 242 | LOG_INFO(Loader, "Dumping NSO for name={}, build_id={}, title_id={:016X}", name, build_id, | 241 | LOG_INFO(Loader, "Dumping NSO for name={}, build_id={}, title_id={:016X}", name, build_id, |
| 243 | title_id); | 242 | title_id); |
| 244 | const auto dump_dir = | 243 | const auto dump_dir = fs_controller.GetModificationDumpRoot(title_id); |
| 245 | Core::System::GetInstance().GetFileSystemController().GetModificationDumpRoot(title_id); | ||
| 246 | if (dump_dir != nullptr) { | 244 | if (dump_dir != nullptr) { |
| 247 | const auto nso_dir = GetOrCreateDirectoryRelative(dump_dir, "/nso"); | 245 | const auto nso_dir = GetOrCreateDirectoryRelative(dump_dir, "/nso"); |
| 248 | const auto file = nso_dir->CreateFile(fmt::format("{}-{}.nso", name, build_id)); | 246 | const auto file = nso_dir->CreateFile(fmt::format("{}-{}.nso", name, build_id)); |
| @@ -254,8 +252,7 @@ std::vector<u8> PatchManager::PatchNSO(const std::vector<u8>& nso, const std::st | |||
| 254 | 252 | ||
| 255 | LOG_INFO(Loader, "Patching NSO for name={}, build_id={}", name, build_id); | 253 | LOG_INFO(Loader, "Patching NSO for name={}, build_id={}", name, build_id); |
| 256 | 254 | ||
| 257 | const auto load_dir = | 255 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 258 | Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); | ||
| 259 | if (load_dir == nullptr) { | 256 | if (load_dir == nullptr) { |
| 260 | LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); | 257 | LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); |
| 261 | return nso; | 258 | return nso; |
| @@ -298,8 +295,7 @@ bool PatchManager::HasNSOPatch(const BuildID& build_id_) const { | |||
| 298 | 295 | ||
| 299 | LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id); | 296 | LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id); |
| 300 | 297 | ||
| 301 | const auto load_dir = | 298 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 302 | Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); | ||
| 303 | if (load_dir == nullptr) { | 299 | if (load_dir == nullptr) { |
| 304 | LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); | 300 | LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); |
| 305 | return false; | 301 | return false; |
| @@ -313,8 +309,8 @@ bool PatchManager::HasNSOPatch(const BuildID& build_id_) const { | |||
| 313 | } | 309 | } |
| 314 | 310 | ||
| 315 | std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList( | 311 | std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList( |
| 316 | const Core::System& system, const BuildID& build_id_) const { | 312 | const BuildID& build_id_) const { |
| 317 | const auto load_dir = system.GetFileSystemController().GetModificationLoadRoot(title_id); | 313 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 318 | if (load_dir == nullptr) { | 314 | if (load_dir == nullptr) { |
| 319 | LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); | 315 | LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id); |
| 320 | return {}; | 316 | return {}; |
| @@ -347,9 +343,9 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList( | |||
| 347 | return out; | 343 | return out; |
| 348 | } | 344 | } |
| 349 | 345 | ||
| 350 | static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) { | 346 | static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type, |
| 351 | const auto load_dir = | 347 | const Service::FileSystem::FileSystemController& fs_controller) { |
| 352 | Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); | 348 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 353 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || | 349 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || |
| 354 | load_dir == nullptr || load_dir->GetSize() <= 0) { | 350 | load_dir == nullptr || load_dir->GetSize() <= 0) { |
| 355 | return; | 351 | return; |
| @@ -411,19 +407,19 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content | |||
| 411 | const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}", | 407 | const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}", |
| 412 | title_id, static_cast<u8>(type)); | 408 | title_id, static_cast<u8>(type)); |
| 413 | 409 | ||
| 414 | if (type == ContentRecordType::Program || type == ContentRecordType::Data) | 410 | if (type == ContentRecordType::Program || type == ContentRecordType::Data) { |
| 415 | LOG_INFO(Loader, "{}", log_string); | 411 | LOG_INFO(Loader, "{}", log_string); |
| 416 | else | 412 | } else { |
| 417 | LOG_DEBUG(Loader, "{}", log_string); | 413 | LOG_DEBUG(Loader, "{}", log_string); |
| 414 | } | ||
| 418 | 415 | ||
| 419 | if (romfs == nullptr) | 416 | if (romfs == nullptr) { |
| 420 | return romfs; | 417 | return romfs; |
| 421 | 418 | } | |
| 422 | const auto& installed = Core::System::GetInstance().GetContentProvider(); | ||
| 423 | 419 | ||
| 424 | // Game Updates | 420 | // Game Updates |
| 425 | const auto update_tid = GetUpdateTitleID(title_id); | 421 | const auto update_tid = GetUpdateTitleID(title_id); |
| 426 | const auto update = installed.GetEntryRaw(update_tid, type); | 422 | const auto update = content_provider.GetEntryRaw(update_tid, type); |
| 427 | 423 | ||
| 428 | const auto& disabled = Settings::values.disabled_addons[title_id]; | 424 | const auto& disabled = Settings::values.disabled_addons[title_id]; |
| 429 | const auto update_disabled = | 425 | const auto update_disabled = |
| @@ -434,7 +430,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content | |||
| 434 | if (new_nca->GetStatus() == Loader::ResultStatus::Success && | 430 | if (new_nca->GetStatus() == Loader::ResultStatus::Success && |
| 435 | new_nca->GetRomFS() != nullptr) { | 431 | new_nca->GetRomFS() != nullptr) { |
| 436 | LOG_INFO(Loader, " RomFS: Update ({}) applied successfully", | 432 | LOG_INFO(Loader, " RomFS: Update ({}) applied successfully", |
| 437 | FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0))); | 433 | FormatTitleVersion(content_provider.GetEntryVersion(update_tid).value_or(0))); |
| 438 | romfs = new_nca->GetRomFS(); | 434 | romfs = new_nca->GetRomFS(); |
| 439 | } | 435 | } |
| 440 | } else if (!update_disabled && update_raw != nullptr) { | 436 | } else if (!update_disabled && update_raw != nullptr) { |
| @@ -447,7 +443,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content | |||
| 447 | } | 443 | } |
| 448 | 444 | ||
| 449 | // LayeredFS | 445 | // LayeredFS |
| 450 | ApplyLayeredFS(romfs, title_id, type); | 446 | ApplyLayeredFS(romfs, title_id, type, fs_controller); |
| 451 | 447 | ||
| 452 | return romfs; | 448 | return romfs; |
| 453 | } | 449 | } |
| @@ -458,12 +454,11 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 458 | } | 454 | } |
| 459 | 455 | ||
| 460 | std::map<std::string, std::string, std::less<>> out; | 456 | std::map<std::string, std::string, std::less<>> out; |
| 461 | const auto& installed = Core::System::GetInstance().GetContentProvider(); | ||
| 462 | const auto& disabled = Settings::values.disabled_addons[title_id]; | 457 | const auto& disabled = Settings::values.disabled_addons[title_id]; |
| 463 | 458 | ||
| 464 | // Game Updates | 459 | // Game Updates |
| 465 | const auto update_tid = GetUpdateTitleID(title_id); | 460 | const auto update_tid = GetUpdateTitleID(title_id); |
| 466 | PatchManager update{update_tid}; | 461 | PatchManager update{update_tid, fs_controller, content_provider}; |
| 467 | const auto metadata = update.GetControlMetadata(); | 462 | const auto metadata = update.GetControlMetadata(); |
| 468 | const auto& nacp = metadata.first; | 463 | const auto& nacp = metadata.first; |
| 469 | 464 | ||
| @@ -474,8 +469,8 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 474 | if (nacp != nullptr) { | 469 | if (nacp != nullptr) { |
| 475 | out.insert_or_assign(update_label, nacp->GetVersionString()); | 470 | out.insert_or_assign(update_label, nacp->GetVersionString()); |
| 476 | } else { | 471 | } else { |
| 477 | if (installed.HasEntry(update_tid, ContentRecordType::Program)) { | 472 | if (content_provider.HasEntry(update_tid, ContentRecordType::Program)) { |
| 478 | const auto meta_ver = installed.GetEntryVersion(update_tid); | 473 | const auto meta_ver = content_provider.GetEntryVersion(update_tid); |
| 479 | if (meta_ver.value_or(0) == 0) { | 474 | if (meta_ver.value_or(0) == 0) { |
| 480 | out.insert_or_assign(update_label, ""); | 475 | out.insert_or_assign(update_label, ""); |
| 481 | } else { | 476 | } else { |
| @@ -487,8 +482,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 487 | } | 482 | } |
| 488 | 483 | ||
| 489 | // General Mods (LayeredFS and IPS) | 484 | // General Mods (LayeredFS and IPS) |
| 490 | const auto mod_dir = | 485 | const auto mod_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 491 | Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id); | ||
| 492 | if (mod_dir != nullptr && mod_dir->GetSize() > 0) { | 486 | if (mod_dir != nullptr && mod_dir->GetSize() > 0) { |
| 493 | for (const auto& mod : mod_dir->GetSubdirectories()) { | 487 | for (const auto& mod : mod_dir->GetSubdirectories()) { |
| 494 | std::string types; | 488 | std::string types; |
| @@ -532,13 +526,15 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 532 | } | 526 | } |
| 533 | 527 | ||
| 534 | // DLC | 528 | // DLC |
| 535 | const auto dlc_entries = installed.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); | 529 | const auto dlc_entries = |
| 530 | content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); | ||
| 536 | std::vector<ContentProviderEntry> dlc_match; | 531 | std::vector<ContentProviderEntry> dlc_match; |
| 537 | dlc_match.reserve(dlc_entries.size()); | 532 | dlc_match.reserve(dlc_entries.size()); |
| 538 | std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match), | 533 | std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match), |
| 539 | [this, &installed](const ContentProviderEntry& entry) { | 534 | [this](const ContentProviderEntry& entry) { |
| 540 | return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id && | 535 | return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id && |
| 541 | installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success; | 536 | content_provider.GetEntry(entry)->GetStatus() == |
| 537 | Loader::ResultStatus::Success; | ||
| 542 | }); | 538 | }); |
| 543 | if (!dlc_match.empty()) { | 539 | if (!dlc_match.empty()) { |
| 544 | // Ensure sorted so DLC IDs show in order. | 540 | // Ensure sorted so DLC IDs show in order. |
| @@ -559,19 +555,16 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 559 | } | 555 | } |
| 560 | 556 | ||
| 561 | std::optional<u32> PatchManager::GetGameVersion() const { | 557 | std::optional<u32> PatchManager::GetGameVersion() const { |
| 562 | const auto& installed = Core::System::GetInstance().GetContentProvider(); | ||
| 563 | const auto update_tid = GetUpdateTitleID(title_id); | 558 | const auto update_tid = GetUpdateTitleID(title_id); |
| 564 | if (installed.HasEntry(update_tid, ContentRecordType::Program)) { | 559 | if (content_provider.HasEntry(update_tid, ContentRecordType::Program)) { |
| 565 | return installed.GetEntryVersion(update_tid); | 560 | return content_provider.GetEntryVersion(update_tid); |
| 566 | } | 561 | } |
| 567 | 562 | ||
| 568 | return installed.GetEntryVersion(title_id); | 563 | return content_provider.GetEntryVersion(title_id); |
| 569 | } | 564 | } |
| 570 | 565 | ||
| 571 | PatchManager::Metadata PatchManager::GetControlMetadata() const { | 566 | PatchManager::Metadata PatchManager::GetControlMetadata() const { |
| 572 | const auto& installed = Core::System::GetInstance().GetContentProvider(); | 567 | const auto base_control_nca = content_provider.GetEntry(title_id, ContentRecordType::Control); |
| 573 | |||
| 574 | const auto base_control_nca = installed.GetEntry(title_id, ContentRecordType::Control); | ||
| 575 | if (base_control_nca == nullptr) { | 568 | if (base_control_nca == nullptr) { |
| 576 | return {}; | 569 | return {}; |
| 577 | } | 570 | } |
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index 1f28c6241..fb1853035 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h | |||
| @@ -17,8 +17,13 @@ namespace Core { | |||
| 17 | class System; | 17 | class System; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | namespace Service::FileSystem { | ||
| 21 | class FileSystemController; | ||
| 22 | } | ||
| 23 | |||
| 20 | namespace FileSys { | 24 | namespace FileSys { |
| 21 | 25 | ||
| 26 | class ContentProvider; | ||
| 22 | class NCA; | 27 | class NCA; |
| 23 | class NACP; | 28 | class NACP; |
| 24 | 29 | ||
| @@ -29,7 +34,9 @@ public: | |||
| 29 | using Metadata = std::pair<std::unique_ptr<NACP>, VirtualFile>; | 34 | using Metadata = std::pair<std::unique_ptr<NACP>, VirtualFile>; |
| 30 | using PatchVersionNames = std::map<std::string, std::string, std::less<>>; | 35 | using PatchVersionNames = std::map<std::string, std::string, std::less<>>; |
| 31 | 36 | ||
| 32 | explicit PatchManager(u64 title_id); | 37 | explicit PatchManager(u64 title_id_, |
| 38 | const Service::FileSystem::FileSystemController& fs_controller_, | ||
| 39 | const ContentProvider& content_provider_); | ||
| 33 | ~PatchManager(); | 40 | ~PatchManager(); |
| 34 | 41 | ||
| 35 | [[nodiscard]] u64 GetTitleID() const; | 42 | [[nodiscard]] u64 GetTitleID() const; |
| @@ -50,7 +57,7 @@ public: | |||
| 50 | 57 | ||
| 51 | // Creates a CheatList object with all | 58 | // Creates a CheatList object with all |
| 52 | [[nodiscard]] std::vector<Core::Memory::CheatEntry> CreateCheatList( | 59 | [[nodiscard]] std::vector<Core::Memory::CheatEntry> CreateCheatList( |
| 53 | const Core::System& system, const BuildID& build_id) const; | 60 | const BuildID& build_id) const; |
| 54 | 61 | ||
| 55 | // Currently tracked RomFS patches: | 62 | // Currently tracked RomFS patches: |
| 56 | // - Game Updates | 63 | // - Game Updates |
| @@ -80,6 +87,8 @@ private: | |||
| 80 | const std::string& build_id) const; | 87 | const std::string& build_id) const; |
| 81 | 88 | ||
| 82 | u64 title_id; | 89 | u64 title_id; |
| 90 | const Service::FileSystem::FileSystemController& fs_controller; | ||
| 91 | const ContentProvider& content_provider; | ||
| 83 | }; | 92 | }; |
| 84 | 93 | ||
| 85 | } // namespace FileSys | 94 | } // namespace FileSys |
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index e967a254e..987199747 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp | |||
| @@ -37,10 +37,12 @@ void RomFSFactory::SetPackedUpdate(VirtualFile update_raw) { | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess(u64 current_process_title_id) const { | 39 | ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess(u64 current_process_title_id) const { |
| 40 | if (!updatable) | 40 | if (!updatable) { |
| 41 | return MakeResult<VirtualFile>(file); | 41 | return MakeResult<VirtualFile>(file); |
| 42 | } | ||
| 42 | 43 | ||
| 43 | const PatchManager patch_manager(current_process_title_id); | 44 | const PatchManager patch_manager{current_process_title_id, filesystem_controller, |
| 45 | content_provider}; | ||
| 44 | return MakeResult<VirtualFile>( | 46 | return MakeResult<VirtualFile>( |
| 45 | patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw)); | 47 | patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw)); |
| 46 | } | 48 | } |
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index ded52ea0b..c2c11dbcb 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -742,8 +742,10 @@ void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx | |||
| 742 | bool is_locked = false; | 742 | bool is_locked = false; |
| 743 | 743 | ||
| 744 | if (res != Loader::ResultStatus::Success) { | 744 | if (res != Loader::ResultStatus::Success) { |
| 745 | FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()}; | 745 | const FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID(), |
| 746 | auto nacp_unique = pm.GetControlMetadata().first; | 746 | system.GetFileSystemController(), |
| 747 | system.GetContentProvider()}; | ||
| 748 | const auto nacp_unique = pm.GetControlMetadata().first; | ||
| 747 | 749 | ||
| 748 | if (nacp_unique != nullptr) { | 750 | if (nacp_unique != nullptr) { |
| 749 | is_locked = nacp_unique->GetUserAccountSwitchLock(); | 751 | is_locked = nacp_unique->GetUserAccountSwitchLock(); |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index eb097738a..63421b963 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -1381,13 +1381,16 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) { | |||
| 1381 | const auto res = [this] { | 1381 | const auto res = [this] { |
| 1382 | const auto title_id = system.CurrentProcess()->GetTitleID(); | 1382 | const auto title_id = system.CurrentProcess()->GetTitleID(); |
| 1383 | 1383 | ||
| 1384 | FileSys::PatchManager pm{title_id}; | 1384 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), |
| 1385 | system.GetContentProvider()}; | ||
| 1385 | auto res = pm.GetControlMetadata(); | 1386 | auto res = pm.GetControlMetadata(); |
| 1386 | if (res.first != nullptr) { | 1387 | if (res.first != nullptr) { |
| 1387 | return res; | 1388 | return res; |
| 1388 | } | 1389 | } |
| 1389 | 1390 | ||
| 1390 | FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id)}; | 1391 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id), |
| 1392 | system.GetFileSystemController(), | ||
| 1393 | system.GetContentProvider()}; | ||
| 1391 | return pm_update.GetControlMetadata(); | 1394 | return pm_update.GetControlMetadata(); |
| 1392 | }(); | 1395 | }(); |
| 1393 | 1396 | ||
| @@ -1415,13 +1418,16 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { | |||
| 1415 | const auto res = [this] { | 1418 | const auto res = [this] { |
| 1416 | const auto title_id = system.CurrentProcess()->GetTitleID(); | 1419 | const auto title_id = system.CurrentProcess()->GetTitleID(); |
| 1417 | 1420 | ||
| 1418 | FileSys::PatchManager pm{title_id}; | 1421 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), |
| 1422 | system.GetContentProvider()}; | ||
| 1419 | auto res = pm.GetControlMetadata(); | 1423 | auto res = pm.GetControlMetadata(); |
| 1420 | if (res.first != nullptr) { | 1424 | if (res.first != nullptr) { |
| 1421 | return res; | 1425 | return res; |
| 1422 | } | 1426 | } |
| 1423 | 1427 | ||
| 1424 | FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id)}; | 1428 | const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id), |
| 1429 | system.GetFileSystemController(), | ||
| 1430 | system.GetContentProvider()}; | ||
| 1425 | return pm_update.GetControlMetadata(); | 1431 | return pm_update.GetControlMetadata(); |
| 1426 | }(); | 1432 | }(); |
| 1427 | 1433 | ||
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index e58b2c518..173b36da4 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp | |||
| @@ -164,7 +164,8 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) { | |||
| 164 | rb.Push(RESULT_SUCCESS); | 164 | rb.Push(RESULT_SUCCESS); |
| 165 | 165 | ||
| 166 | const auto title_id = system.CurrentProcess()->GetTitleID(); | 166 | const auto title_id = system.CurrentProcess()->GetTitleID(); |
| 167 | FileSys::PatchManager pm{title_id}; | 167 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), |
| 168 | system.GetContentProvider()}; | ||
| 168 | 169 | ||
| 169 | const auto res = pm.GetControlMetadata(); | 170 | const auto res = pm.GetControlMetadata(); |
| 170 | if (res.first == nullptr) { | 171 | if (res.first == nullptr) { |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 3cdef4888..2e53cae5b 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -455,7 +455,9 @@ FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataTy | |||
| 455 | const auto res = system.GetAppLoader().ReadControlData(nacp); | 455 | const auto res = system.GetAppLoader().ReadControlData(nacp); |
| 456 | 456 | ||
| 457 | if (res != Loader::ResultStatus::Success) { | 457 | if (res != Loader::ResultStatus::Success) { |
| 458 | FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()}; | 458 | const FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID(), |
| 459 | system.GetFileSystemController(), | ||
| 460 | system.GetContentProvider()}; | ||
| 459 | const auto metadata = pm.GetControlMetadata(); | 461 | const auto metadata = pm.GetControlMetadata(); |
| 460 | const auto& nacp_unique = metadata.first; | 462 | const auto& nacp_unique = metadata.first; |
| 461 | 463 | ||
| @@ -728,7 +730,8 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove | |||
| 728 | void InstallInterfaces(Core::System& system) { | 730 | void InstallInterfaces(Core::System& system) { |
| 729 | std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager()); | 731 | std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager()); |
| 730 | std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager()); | 732 | std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager()); |
| 731 | std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetReporter()) | 733 | std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetContentProvider(), |
| 734 | system.GetReporter()) | ||
| 732 | ->InstallAsService(system.ServiceManager()); | 735 | ->InstallAsService(system.ServiceManager()); |
| 733 | } | 736 | } |
| 734 | 737 | ||
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 649128be4..031c6dbf6 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -650,8 +650,10 @@ private: | |||
| 650 | u64 next_entry_index = 0; | 650 | u64 next_entry_index = 0; |
| 651 | }; | 651 | }; |
| 652 | 652 | ||
| 653 | FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter) | 653 | FSP_SRV::FSP_SRV(FileSystemController& fsc_, const FileSys::ContentProvider& content_provider_, |
| 654 | : ServiceFramework("fsp-srv"), fsc(fsc), reporter(reporter) { | 654 | const Core::Reporter& reporter_) |
| 655 | : ServiceFramework("fsp-srv"), fsc(fsc_), content_provider{content_provider_}, | ||
| 656 | reporter(reporter_) { | ||
| 655 | // clang-format off | 657 | // clang-format off |
| 656 | static const FunctionInfo functions[] = { | 658 | static const FunctionInfo functions[] = { |
| 657 | {0, nullptr, "OpenFileSystem"}, | 659 | {0, nullptr, "OpenFileSystem"}, |
| @@ -968,7 +970,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) { | |||
| 968 | return; | 970 | return; |
| 969 | } | 971 | } |
| 970 | 972 | ||
| 971 | FileSys::PatchManager pm{title_id}; | 973 | const FileSys::PatchManager pm{title_id, fsc, content_provider}; |
| 972 | 974 | ||
| 973 | auto storage = std::make_shared<IStorage>( | 975 | auto storage = std::make_shared<IStorage>( |
| 974 | pm.PatchRomFS(std::move(data.Unwrap()), 0, FileSys::ContentRecordType::Data)); | 976 | pm.PatchRomFS(std::move(data.Unwrap()), 0, FileSys::ContentRecordType::Data)); |
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index 4964e874e..6c7239e6a 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h | |||
| @@ -12,8 +12,9 @@ class Reporter; | |||
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | namespace FileSys { | 14 | namespace FileSys { |
| 15 | class ContentProvider; | ||
| 15 | class FileSystemBackend; | 16 | class FileSystemBackend; |
| 16 | } | 17 | } // namespace FileSys |
| 17 | 18 | ||
| 18 | namespace Service::FileSystem { | 19 | namespace Service::FileSystem { |
| 19 | 20 | ||
| @@ -32,7 +33,8 @@ enum class LogMode : u32 { | |||
| 32 | 33 | ||
| 33 | class FSP_SRV final : public ServiceFramework<FSP_SRV> { | 34 | class FSP_SRV final : public ServiceFramework<FSP_SRV> { |
| 34 | public: | 35 | public: |
| 35 | explicit FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter); | 36 | explicit FSP_SRV(FileSystemController& fsc_, const FileSys::ContentProvider& content_provider_, |
| 37 | const Core::Reporter& reporter_); | ||
| 36 | ~FSP_SRV() override; | 38 | ~FSP_SRV() override; |
| 37 | 39 | ||
| 38 | private: | 40 | private: |
| @@ -55,6 +57,7 @@ private: | |||
| 55 | void OpenMultiCommitManager(Kernel::HLERequestContext& ctx); | 57 | void OpenMultiCommitManager(Kernel::HLERequestContext& ctx); |
| 56 | 58 | ||
| 57 | FileSystemController& fsc; | 59 | FileSystemController& fsc; |
| 60 | const FileSys::ContentProvider& content_provider; | ||
| 58 | 61 | ||
| 59 | FileSys::VirtualFile romfs; | 62 | FileSys::VirtualFile romfs; |
| 60 | u64 current_process_id = 0; | 63 | u64 current_process_id = 0; |
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 58ee1f712..2594e6839 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | #include "core/core.h" | ||
| 6 | #include "core/file_sys/control_metadata.h" | 7 | #include "core/file_sys/control_metadata.h" |
| 7 | #include "core/file_sys/patch_manager.h" | 8 | #include "core/file_sys/patch_manager.h" |
| 8 | #include "core/file_sys/vfs.h" | 9 | #include "core/file_sys/vfs.h" |
| @@ -29,8 +30,8 @@ IAccountProxyInterface::IAccountProxyInterface() : ServiceFramework{"IAccountPro | |||
| 29 | 30 | ||
| 30 | IAccountProxyInterface::~IAccountProxyInterface() = default; | 31 | IAccountProxyInterface::~IAccountProxyInterface() = default; |
| 31 | 32 | ||
| 32 | IApplicationManagerInterface::IApplicationManagerInterface() | 33 | IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_) |
| 33 | : ServiceFramework{"IApplicationManagerInterface"} { | 34 | : ServiceFramework{"IApplicationManagerInterface"}, system{system_} { |
| 34 | // clang-format off | 35 | // clang-format off |
| 35 | static const FunctionInfo functions[] = { | 36 | static const FunctionInfo functions[] = { |
| 36 | {0, nullptr, "ListApplicationRecord"}, | 37 | {0, nullptr, "ListApplicationRecord"}, |
| @@ -298,7 +299,8 @@ void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestC | |||
| 298 | 299 | ||
| 299 | const auto size = ctx.GetWriteBufferSize(); | 300 | const auto size = ctx.GetWriteBufferSize(); |
| 300 | 301 | ||
| 301 | const FileSys::PatchManager pm{title_id}; | 302 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), |
| 303 | system.GetContentProvider()}; | ||
| 302 | const auto control = pm.GetControlMetadata(); | 304 | const auto control = pm.GetControlMetadata(); |
| 303 | 305 | ||
| 304 | std::vector<u8> out; | 306 | std::vector<u8> out; |
| @@ -538,14 +540,14 @@ IFactoryResetInterface::IFactoryResetInterface::IFactoryResetInterface() | |||
| 538 | 540 | ||
| 539 | IFactoryResetInterface::~IFactoryResetInterface() = default; | 541 | IFactoryResetInterface::~IFactoryResetInterface() = default; |
| 540 | 542 | ||
| 541 | NS::NS(const char* name) : ServiceFramework{name} { | 543 | NS::NS(const char* name, Core::System& system_) : ServiceFramework{name}, system{system_} { |
| 542 | // clang-format off | 544 | // clang-format off |
| 543 | static const FunctionInfo functions[] = { | 545 | static const FunctionInfo functions[] = { |
| 544 | {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, | 546 | {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, |
| 545 | {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, | 547 | {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, |
| 546 | {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, | 548 | {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, |
| 547 | {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, | 549 | {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, |
| 548 | {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"}, | 550 | {7996, &NS::PushIApplicationManagerInterface, "GetApplicationManagerInterface"}, |
| 549 | {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, | 551 | {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, |
| 550 | {7998, &NS::PushInterface<IContentManagementInterface>, "GetContentManagementInterface"}, | 552 | {7998, &NS::PushInterface<IContentManagementInterface>, "GetContentManagementInterface"}, |
| 551 | {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, | 553 | {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, |
| @@ -558,7 +560,7 @@ NS::NS(const char* name) : ServiceFramework{name} { | |||
| 558 | NS::~NS() = default; | 560 | NS::~NS() = default; |
| 559 | 561 | ||
| 560 | std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const { | 562 | std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const { |
| 561 | return GetInterface<IApplicationManagerInterface>(); | 563 | return GetInterface<IApplicationManagerInterface>(system); |
| 562 | } | 564 | } |
| 563 | 565 | ||
| 564 | class NS_DEV final : public ServiceFramework<NS_DEV> { | 566 | class NS_DEV final : public ServiceFramework<NS_DEV> { |
| @@ -678,11 +680,11 @@ public: | |||
| 678 | 680 | ||
| 679 | void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { | 681 | void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { |
| 680 | 682 | ||
| 681 | std::make_shared<NS>("ns:am2")->InstallAsService(service_manager); | 683 | std::make_shared<NS>("ns:am2", system)->InstallAsService(service_manager); |
| 682 | std::make_shared<NS>("ns:ec")->InstallAsService(service_manager); | 684 | std::make_shared<NS>("ns:ec", system)->InstallAsService(service_manager); |
| 683 | std::make_shared<NS>("ns:rid")->InstallAsService(service_manager); | 685 | std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager); |
| 684 | std::make_shared<NS>("ns:rt")->InstallAsService(service_manager); | 686 | std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager); |
| 685 | std::make_shared<NS>("ns:web")->InstallAsService(service_manager); | 687 | std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager); |
| 686 | 688 | ||
| 687 | std::make_shared<NS_DEV>()->InstallAsService(service_manager); | 689 | std::make_shared<NS_DEV>()->InstallAsService(service_manager); |
| 688 | std::make_shared<NS_SU>()->InstallAsService(service_manager); | 690 | std::make_shared<NS_SU>()->InstallAsService(service_manager); |
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h index c2554b878..c90ccd755 100644 --- a/src/core/hle/service/ns/ns.h +++ b/src/core/hle/service/ns/ns.h | |||
| @@ -6,6 +6,10 @@ | |||
| 6 | 6 | ||
| 7 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/service.h" |
| 8 | 8 | ||
| 9 | namespace Core { | ||
| 10 | class System; | ||
| 11 | } | ||
| 12 | |||
| 9 | namespace Service { | 13 | namespace Service { |
| 10 | 14 | ||
| 11 | namespace FileSystem { | 15 | namespace FileSystem { |
| @@ -22,7 +26,7 @@ public: | |||
| 22 | 26 | ||
| 23 | class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> { | 27 | class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> { |
| 24 | public: | 28 | public: |
| 25 | explicit IApplicationManagerInterface(); | 29 | explicit IApplicationManagerInterface(Core::System& system_); |
| 26 | ~IApplicationManagerInterface() override; | 30 | ~IApplicationManagerInterface() override; |
| 27 | 31 | ||
| 28 | ResultVal<u8> GetApplicationDesiredLanguage(u32 supported_languages); | 32 | ResultVal<u8> GetApplicationDesiredLanguage(u32 supported_languages); |
| @@ -32,6 +36,8 @@ private: | |||
| 32 | void GetApplicationControlData(Kernel::HLERequestContext& ctx); | 36 | void GetApplicationControlData(Kernel::HLERequestContext& ctx); |
| 33 | void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx); | 37 | void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx); |
| 34 | void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx); | 38 | void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx); |
| 39 | |||
| 40 | Core::System& system; | ||
| 35 | }; | 41 | }; |
| 36 | 42 | ||
| 37 | class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { | 43 | class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { |
| @@ -72,13 +78,13 @@ public: | |||
| 72 | 78 | ||
| 73 | class NS final : public ServiceFramework<NS> { | 79 | class NS final : public ServiceFramework<NS> { |
| 74 | public: | 80 | public: |
| 75 | explicit NS(const char* name); | 81 | explicit NS(const char* name, Core::System& system_); |
| 76 | ~NS() override; | 82 | ~NS() override; |
| 77 | 83 | ||
| 78 | std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const; | 84 | std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const; |
| 79 | 85 | ||
| 80 | private: | 86 | private: |
| 81 | template <typename T> | 87 | template <typename T, typename... Args> |
| 82 | void PushInterface(Kernel::HLERequestContext& ctx) { | 88 | void PushInterface(Kernel::HLERequestContext& ctx) { |
| 83 | LOG_DEBUG(Service_NS, "called"); | 89 | LOG_DEBUG(Service_NS, "called"); |
| 84 | 90 | ||
| @@ -87,13 +93,23 @@ private: | |||
| 87 | rb.PushIpcInterface<T>(); | 93 | rb.PushIpcInterface<T>(); |
| 88 | } | 94 | } |
| 89 | 95 | ||
| 90 | template <typename T> | 96 | void PushIApplicationManagerInterface(Kernel::HLERequestContext& ctx) { |
| 91 | std::shared_ptr<T> GetInterface() const { | 97 | LOG_DEBUG(Service_NS, "called"); |
| 98 | |||
| 99 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 100 | rb.Push(RESULT_SUCCESS); | ||
| 101 | rb.PushIpcInterface<IApplicationManagerInterface>(system); | ||
| 102 | } | ||
| 103 | |||
| 104 | template <typename T, typename... Args> | ||
| 105 | std::shared_ptr<T> GetInterface(Args&&... args) const { | ||
| 92 | static_assert(std::is_base_of_v<Kernel::SessionRequestHandler, T>, | 106 | static_assert(std::is_base_of_v<Kernel::SessionRequestHandler, T>, |
| 93 | "Not a base of ServiceFrameworkBase"); | 107 | "Not a base of ServiceFrameworkBase"); |
| 94 | 108 | ||
| 95 | return std::make_shared<T>(); | 109 | return std::make_shared<T>(std::forward<Args>(args)...); |
| 96 | } | 110 | } |
| 111 | |||
| 112 | Core::System& system; | ||
| 97 | }; | 113 | }; |
| 98 | 114 | ||
| 99 | /// Registers all NS services with the specified service manager. | 115 | /// Registers all NS services with the specified service manager. |
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 394a1bf26..2002dc4f2 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -114,7 +114,8 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect | |||
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | if (override_update) { | 116 | if (override_update) { |
| 117 | const FileSys::PatchManager patch_manager(metadata.GetTitleID()); | 117 | const FileSys::PatchManager patch_manager( |
| 118 | metadata.GetTitleID(), system.GetFileSystemController(), system.GetContentProvider()); | ||
| 118 | dir = patch_manager.PatchExeFS(dir); | 119 | dir = patch_manager.PatchExeFS(dir); |
| 119 | } | 120 | } |
| 120 | 121 | ||
| @@ -160,7 +161,8 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect | |||
| 160 | modules.clear(); | 161 | modules.clear(); |
| 161 | const VAddr base_address{process.PageTable().GetCodeRegionStart()}; | 162 | const VAddr base_address{process.PageTable().GetCodeRegionStart()}; |
| 162 | VAddr next_load_addr{base_address}; | 163 | VAddr next_load_addr{base_address}; |
| 163 | const FileSys::PatchManager pm{metadata.GetTitleID()}; | 164 | const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), |
| 165 | system.GetContentProvider()}; | ||
| 164 | for (const auto& module : static_modules) { | 166 | for (const auto& module : static_modules) { |
| 165 | const FileSys::VirtualFile module_file{dir->GetFile(module)}; | 167 | const FileSys::VirtualFile module_file{dir->GetFile(module)}; |
| 166 | if (!module_file) { | 168 | if (!module_file) { |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 9bc3a8840..deffe7379 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "common/file_util.h" | 10 | #include "common/file_util.h" |
| 11 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 12 | #include "common/string_util.h" | 12 | #include "common/string_util.h" |
| 13 | #include "core/core.h" | ||
| 13 | #include "core/hle/kernel/process.h" | 14 | #include "core/hle/kernel/process.h" |
| 14 | #include "core/loader/deconstructed_rom_directory.h" | 15 | #include "core/loader/deconstructed_rom_directory.h" |
| 15 | #include "core/loader/elf.h" | 16 | #include "core/loader/elf.h" |
| @@ -194,15 +195,14 @@ AppLoader::~AppLoader() = default; | |||
| 194 | 195 | ||
| 195 | /** | 196 | /** |
| 196 | * Get a loader for a file with a specific type | 197 | * Get a loader for a file with a specific type |
| 197 | * @param file The file to load | 198 | * @param system The system context to use. |
| 198 | * @param type The type of the file | 199 | * @param file The file to retrieve the loader for |
| 199 | * @param file the file to retrieve the loader for | 200 | * @param type The file type |
| 200 | * @param type the file type | ||
| 201 | * @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type | 201 | * @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type |
| 202 | */ | 202 | */ |
| 203 | static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileType type) { | 203 | static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::VirtualFile file, |
| 204 | FileType type) { | ||
| 204 | switch (type) { | 205 | switch (type) { |
| 205 | |||
| 206 | // Standard ELF file format. | 206 | // Standard ELF file format. |
| 207 | case FileType::ELF: | 207 | case FileType::ELF: |
| 208 | return std::make_unique<AppLoader_ELF>(std::move(file)); | 208 | return std::make_unique<AppLoader_ELF>(std::move(file)); |
| @@ -221,7 +221,8 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT | |||
| 221 | 221 | ||
| 222 | // NX XCI (nX Card Image) file format. | 222 | // NX XCI (nX Card Image) file format. |
| 223 | case FileType::XCI: | 223 | case FileType::XCI: |
| 224 | return std::make_unique<AppLoader_XCI>(std::move(file)); | 224 | return std::make_unique<AppLoader_XCI>(std::move(file), system.GetFileSystemController(), |
| 225 | system.GetContentProvider()); | ||
| 225 | 226 | ||
| 226 | // NX NAX (NintendoAesXts) file format. | 227 | // NX NAX (NintendoAesXts) file format. |
| 227 | case FileType::NAX: | 228 | case FileType::NAX: |
| @@ -229,7 +230,8 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT | |||
| 229 | 230 | ||
| 230 | // NX NSP (Nintendo Submission Package) file format | 231 | // NX NSP (Nintendo Submission Package) file format |
| 231 | case FileType::NSP: | 232 | case FileType::NSP: |
| 232 | return std::make_unique<AppLoader_NSP>(std::move(file)); | 233 | return std::make_unique<AppLoader_NSP>(std::move(file), system.GetFileSystemController(), |
| 234 | system.GetContentProvider()); | ||
| 233 | 235 | ||
| 234 | // NX KIP (Kernel Internal Process) file format | 236 | // NX KIP (Kernel Internal Process) file format |
| 235 | case FileType::KIP: | 237 | case FileType::KIP: |
| @@ -244,20 +246,21 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT | |||
| 244 | } | 246 | } |
| 245 | } | 247 | } |
| 246 | 248 | ||
| 247 | std::unique_ptr<AppLoader> GetLoader(FileSys::VirtualFile file) { | 249 | std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file) { |
| 248 | FileType type = IdentifyFile(file); | 250 | FileType type = IdentifyFile(file); |
| 249 | FileType filename_type = GuessFromFilename(file->GetName()); | 251 | const FileType filename_type = GuessFromFilename(file->GetName()); |
| 250 | 252 | ||
| 251 | // Special case: 00 is either a NCA or NAX. | 253 | // Special case: 00 is either a NCA or NAX. |
| 252 | if (type != filename_type && !(file->GetName() == "00" && type == FileType::NAX)) { | 254 | if (type != filename_type && !(file->GetName() == "00" && type == FileType::NAX)) { |
| 253 | LOG_WARNING(Loader, "File {} has a different type than its extension.", file->GetName()); | 255 | LOG_WARNING(Loader, "File {} has a different type than its extension.", file->GetName()); |
| 254 | if (FileType::Unknown == type) | 256 | if (FileType::Unknown == type) { |
| 255 | type = filename_type; | 257 | type = filename_type; |
| 258 | } | ||
| 256 | } | 259 | } |
| 257 | 260 | ||
| 258 | LOG_DEBUG(Loader, "Loading file {} as {}...", file->GetName(), GetFileTypeString(type)); | 261 | LOG_DEBUG(Loader, "Loading file {} as {}...", file->GetName(), GetFileTypeString(type)); |
| 259 | 262 | ||
| 260 | return GetFileLoader(std::move(file), type); | 263 | return GetFileLoader(system, std::move(file), type); |
| 261 | } | 264 | } |
| 262 | 265 | ||
| 263 | } // namespace Loader | 266 | } // namespace Loader |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index ac60b097a..8dc2d7615 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -290,9 +290,12 @@ protected: | |||
| 290 | 290 | ||
| 291 | /** | 291 | /** |
| 292 | * Identifies a bootable file and return a suitable loader | 292 | * Identifies a bootable file and return a suitable loader |
| 293 | * @param file The bootable file | 293 | * |
| 294 | * @return the best loader for this file | 294 | * @param system The system context. |
| 295 | * @param file The bootable file. | ||
| 296 | * | ||
| 297 | * @return the best loader for this file. | ||
| 295 | */ | 298 | */ |
| 296 | std::unique_ptr<AppLoader> GetLoader(FileSys::VirtualFile file); | 299 | std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file); |
| 297 | 300 | ||
| 298 | } // namespace Loader | 301 | } // namespace Loader |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 497f438a1..aa85c1a29 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -149,7 +149,7 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S | |||
| 149 | // Apply cheats if they exist and the program has a valid title ID | 149 | // Apply cheats if they exist and the program has a valid title ID |
| 150 | if (pm) { | 150 | if (pm) { |
| 151 | system.SetCurrentProcessBuildID(nso_header.build_id); | 151 | system.SetCurrentProcessBuildID(nso_header.build_id); |
| 152 | const auto cheats = pm->CreateCheatList(system, nso_header.build_id); | 152 | const auto cheats = pm->CreateCheatList(nso_header.build_id); |
| 153 | if (!cheats.empty()) { | 153 | if (!cheats.empty()) { |
| 154 | system.RegisterCheatList(cheats, nso_header.build_id, load_base, image_size); | 154 | system.RegisterCheatList(cheats, nso_header.build_id, load_base, image_size); |
| 155 | } | 155 | } |
diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 15e528fa8..e821937fd 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp | |||
| @@ -21,26 +21,33 @@ | |||
| 21 | 21 | ||
| 22 | namespace Loader { | 22 | namespace Loader { |
| 23 | 23 | ||
| 24 | AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file) | 24 | AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file, |
| 25 | const Service::FileSystem::FileSystemController& fsc, | ||
| 26 | const FileSys::ContentProvider& content_provider) | ||
| 25 | : AppLoader(file), nsp(std::make_unique<FileSys::NSP>(file)), | 27 | : AppLoader(file), nsp(std::make_unique<FileSys::NSP>(file)), |
| 26 | title_id(nsp->GetProgramTitleID()) { | 28 | title_id(nsp->GetProgramTitleID()) { |
| 27 | 29 | ||
| 28 | if (nsp->GetStatus() != ResultStatus::Success) | 30 | if (nsp->GetStatus() != ResultStatus::Success) { |
| 29 | return; | 31 | return; |
| 32 | } | ||
| 30 | 33 | ||
| 31 | if (nsp->IsExtractedType()) { | 34 | if (nsp->IsExtractedType()) { |
| 32 | secondary_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(nsp->GetExeFS()); | 35 | secondary_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(nsp->GetExeFS()); |
| 33 | } else { | 36 | } else { |
| 34 | const auto control_nca = | 37 | const auto control_nca = |
| 35 | nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control); | 38 | nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control); |
| 36 | if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) | 39 | if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) { |
| 37 | return; | 40 | return; |
| 41 | } | ||
| 38 | 42 | ||
| 39 | std::tie(nacp_file, icon_file) = | 43 | std::tie(nacp_file, icon_file) = [this, &content_provider, &control_nca, &fsc] { |
| 40 | FileSys::PatchManager(nsp->GetProgramTitleID()).ParseControlNCA(*control_nca); | 44 | const FileSys::PatchManager pm{nsp->GetProgramTitleID(), fsc, content_provider}; |
| 45 | return pm.ParseControlNCA(*control_nca); | ||
| 46 | }(); | ||
| 41 | 47 | ||
| 42 | if (title_id == 0) | 48 | if (title_id == 0) { |
| 43 | return; | 49 | return; |
| 50 | } | ||
| 44 | 51 | ||
| 45 | secondary_loader = std::make_unique<AppLoader_NCA>( | 52 | secondary_loader = std::make_unique<AppLoader_NCA>( |
| 46 | nsp->GetNCAFile(title_id, FileSys::ContentRecordType::Program)); | 53 | nsp->GetNCAFile(title_id, FileSys::ContentRecordType::Program)); |
diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index b27deb686..36e8e3533 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h | |||
| @@ -9,15 +9,16 @@ | |||
| 9 | #include "core/file_sys/vfs.h" | 9 | #include "core/file_sys/vfs.h" |
| 10 | #include "core/loader/loader.h" | 10 | #include "core/loader/loader.h" |
| 11 | 11 | ||
| 12 | namespace Core { | ||
| 13 | class System; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace FileSys { | 12 | namespace FileSys { |
| 13 | class ContentProvider; | ||
| 17 | class NACP; | 14 | class NACP; |
| 18 | class NSP; | 15 | class NSP; |
| 19 | } // namespace FileSys | 16 | } // namespace FileSys |
| 20 | 17 | ||
| 18 | namespace Service::FileSystem { | ||
| 19 | class FileSystemController; | ||
| 20 | } | ||
| 21 | |||
| 21 | namespace Loader { | 22 | namespace Loader { |
| 22 | 23 | ||
| 23 | class AppLoader_NCA; | 24 | class AppLoader_NCA; |
| @@ -25,7 +26,9 @@ class AppLoader_NCA; | |||
| 25 | /// Loads an XCI file | 26 | /// Loads an XCI file |
| 26 | class AppLoader_NSP final : public AppLoader { | 27 | class AppLoader_NSP final : public AppLoader { |
| 27 | public: | 28 | public: |
| 28 | explicit AppLoader_NSP(FileSys::VirtualFile file); | 29 | explicit AppLoader_NSP(FileSys::VirtualFile file, |
| 30 | const Service::FileSystem::FileSystemController& fsc, | ||
| 31 | const FileSys::ContentProvider& content_provider); | ||
| 29 | ~AppLoader_NSP() override; | 32 | ~AppLoader_NSP() override; |
| 30 | 33 | ||
| 31 | /** | 34 | /** |
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 25e83af0f..536e721fc 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp | |||
| @@ -20,18 +20,24 @@ | |||
| 20 | 20 | ||
| 21 | namespace Loader { | 21 | namespace Loader { |
| 22 | 22 | ||
| 23 | AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file) | 23 | AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file, |
| 24 | const Service::FileSystem::FileSystemController& fsc, | ||
| 25 | const FileSys::ContentProvider& content_provider) | ||
| 24 | : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)), | 26 | : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)), |
| 25 | nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { | 27 | nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { |
| 26 | if (xci->GetStatus() != ResultStatus::Success) | 28 | if (xci->GetStatus() != ResultStatus::Success) { |
| 27 | return; | 29 | return; |
| 30 | } | ||
| 28 | 31 | ||
| 29 | const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); | 32 | const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); |
| 30 | if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) | 33 | if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) { |
| 31 | return; | 34 | return; |
| 35 | } | ||
| 32 | 36 | ||
| 33 | std::tie(nacp_file, icon_file) = | 37 | std::tie(nacp_file, icon_file) = [this, &content_provider, &control_nca, &fsc] { |
| 34 | FileSys::PatchManager(xci->GetProgramTitleID()).ParseControlNCA(*control_nca); | 38 | const FileSys::PatchManager pm{xci->GetProgramTitleID(), fsc, content_provider}; |
| 39 | return pm.ParseControlNCA(*control_nca); | ||
| 40 | }(); | ||
| 35 | } | 41 | } |
| 36 | 42 | ||
| 37 | AppLoader_XCI::~AppLoader_XCI() = default; | 43 | AppLoader_XCI::~AppLoader_XCI() = default; |
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 04aea286f..6dc1f9243 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h | |||
| @@ -9,15 +9,16 @@ | |||
| 9 | #include "core/file_sys/vfs.h" | 9 | #include "core/file_sys/vfs.h" |
| 10 | #include "core/loader/loader.h" | 10 | #include "core/loader/loader.h" |
| 11 | 11 | ||
| 12 | namespace Core { | ||
| 13 | class System; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace FileSys { | 12 | namespace FileSys { |
| 13 | class ContentProvider; | ||
| 17 | class NACP; | 14 | class NACP; |
| 18 | class XCI; | 15 | class XCI; |
| 19 | } // namespace FileSys | 16 | } // namespace FileSys |
| 20 | 17 | ||
| 18 | namespace Service::FileSystem { | ||
| 19 | class FileSystemController; | ||
| 20 | } | ||
| 21 | |||
| 21 | namespace Loader { | 22 | namespace Loader { |
| 22 | 23 | ||
| 23 | class AppLoader_NCA; | 24 | class AppLoader_NCA; |
| @@ -25,7 +26,9 @@ class AppLoader_NCA; | |||
| 25 | /// Loads an XCI file | 26 | /// Loads an XCI file |
| 26 | class AppLoader_XCI final : public AppLoader { | 27 | class AppLoader_XCI final : public AppLoader { |
| 27 | public: | 28 | public: |
| 28 | explicit AppLoader_XCI(FileSys::VirtualFile file); | 29 | explicit AppLoader_XCI(FileSys::VirtualFile file, |
| 30 | const Service::FileSystem::FileSystemController& fsc, | ||
| 31 | const FileSys::ContentProvider& content_provider); | ||
| 29 | ~AppLoader_XCI() override; | 32 | ~AppLoader_XCI() override; |
| 30 | 33 | ||
| 31 | /** | 34 | /** |
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index e0908186b..d11b15f38 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp | |||
| @@ -147,7 +147,9 @@ TelemetrySession::~TelemetrySession() { | |||
| 147 | } | 147 | } |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) { | 150 | void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader, |
| 151 | const Service::FileSystem::FileSystemController& fsc, | ||
| 152 | const FileSys::ContentProvider& content_provider) { | ||
| 151 | // Log one-time top-level information | 153 | // Log one-time top-level information |
| 152 | AddField(Telemetry::FieldType::None, "TelemetryId", GetTelemetryId()); | 154 | AddField(Telemetry::FieldType::None, "TelemetryId", GetTelemetryId()); |
| 153 | 155 | ||
| @@ -167,7 +169,10 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) { | |||
| 167 | app_loader.ReadTitle(name); | 169 | app_loader.ReadTitle(name); |
| 168 | 170 | ||
| 169 | if (name.empty()) { | 171 | if (name.empty()) { |
| 170 | const auto metadata = FileSys::PatchManager(program_id).GetControlMetadata(); | 172 | const auto metadata = [&content_provider, &fsc, program_id] { |
| 173 | const FileSys::PatchManager pm{program_id, fsc, content_provider}; | ||
| 174 | return pm.GetControlMetadata(); | ||
| 175 | }(); | ||
| 171 | if (metadata.first != nullptr) { | 176 | if (metadata.first != nullptr) { |
| 172 | name = metadata.first->GetApplicationName(); | 177 | name = metadata.first->GetApplicationName(); |
| 173 | } | 178 | } |
diff --git a/src/core/telemetry_session.h b/src/core/telemetry_session.h index 66789d4bd..6f3d45bea 100644 --- a/src/core/telemetry_session.h +++ b/src/core/telemetry_session.h | |||
| @@ -7,10 +7,18 @@ | |||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include "common/telemetry.h" | 8 | #include "common/telemetry.h" |
| 9 | 9 | ||
| 10 | namespace FileSys { | ||
| 11 | class ContentProvider; | ||
| 12 | } | ||
| 13 | |||
| 10 | namespace Loader { | 14 | namespace Loader { |
| 11 | class AppLoader; | 15 | class AppLoader; |
| 12 | } | 16 | } |
| 13 | 17 | ||
| 18 | namespace Service::FileSystem { | ||
| 19 | class FileSystemController; | ||
| 20 | } | ||
| 21 | |||
| 14 | namespace Core { | 22 | namespace Core { |
| 15 | 23 | ||
| 16 | /** | 24 | /** |
| @@ -40,10 +48,14 @@ public: | |||
| 40 | * - Title file format | 48 | * - Title file format |
| 41 | * - Miscellaneous settings values. | 49 | * - Miscellaneous settings values. |
| 42 | * | 50 | * |
| 43 | * @param app_loader The application loader to use to retrieve | 51 | * @param app_loader The application loader to use to retrieve |
| 44 | * title-specific information. | 52 | * title-specific information. |
| 53 | * @param fsc Filesystem controller to use to retrieve info. | ||
| 54 | * @param content_provider Content provider to use to retrieve info. | ||
| 45 | */ | 55 | */ |
| 46 | void AddInitialInfo(Loader::AppLoader& app_loader); | 56 | void AddInitialInfo(Loader::AppLoader& app_loader, |
| 57 | const Service::FileSystem::FileSystemController& fsc, | ||
| 58 | const FileSys::ContentProvider& content_provider); | ||
| 47 | 59 | ||
| 48 | /** | 60 | /** |
| 49 | * Wrapper around the Telemetry::FieldCollection::AddField method. | 61 | * Wrapper around the Telemetry::FieldCollection::AddField method. |
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 81464dd37..8eac3bd9d 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | #include "common/common_paths.h" | 17 | #include "common/common_paths.h" |
| 18 | #include "common/file_util.h" | 18 | #include "common/file_util.h" |
| 19 | #include "core/core.h" | ||
| 19 | #include "core/file_sys/control_metadata.h" | 20 | #include "core/file_sys/control_metadata.h" |
| 20 | #include "core/file_sys/patch_manager.h" | 21 | #include "core/file_sys/patch_manager.h" |
| 21 | #include "core/file_sys/xts_archive.h" | 22 | #include "core/file_sys/xts_archive.h" |
| @@ -89,9 +90,11 @@ void ConfigurePerGame::LoadConfiguration() { | |||
| 89 | ui->display_title_id->setText( | 90 | ui->display_title_id->setText( |
| 90 | QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper()); | 91 | QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper()); |
| 91 | 92 | ||
| 92 | FileSys::PatchManager pm{title_id}; | 93 | auto& system = Core::System::GetInstance(); |
| 94 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), | ||
| 95 | system.GetContentProvider()}; | ||
| 93 | const auto control = pm.GetControlMetadata(); | 96 | const auto control = pm.GetControlMetadata(); |
| 94 | const auto loader = Loader::GetLoader(file); | 97 | const auto loader = Loader::GetLoader(system, file); |
| 95 | 98 | ||
| 96 | if (control.first != nullptr) { | 99 | if (control.first != nullptr) { |
| 97 | ui->display_version->setText(QString::fromStdString(control.first->GetVersionString())); | 100 | ui->display_version->setText(QString::fromStdString(control.first->GetVersionString())); |
diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp index 793fd8975..cdeeec01c 100644 --- a/src/yuzu/configuration/configure_per_game_addons.cpp +++ b/src/yuzu/configuration/configure_per_game_addons.cpp | |||
| @@ -112,8 +112,10 @@ void ConfigurePerGameAddons::LoadConfiguration() { | |||
| 112 | return; | 112 | return; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | FileSys::PatchManager pm{title_id}; | 115 | auto& system = Core::System::GetInstance(); |
| 116 | const auto loader = Loader::GetLoader(file); | 116 | const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), |
| 117 | system.GetContentProvider()}; | ||
| 118 | const auto loader = Loader::GetLoader(system, file); | ||
| 117 | 119 | ||
| 118 | FileSys::VirtualFile update_raw; | 120 | FileSys::VirtualFile update_raw; |
| 119 | loader->ReadUpdateRaw(update_raw); | 121 | loader->ReadUpdateRaw(update_raw); |
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index e0ce45fd9..23643aea2 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp | |||
| @@ -235,12 +235,11 @@ GameListWorker::~GameListWorker() = default; | |||
| 235 | void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { | 235 | void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { |
| 236 | using namespace FileSys; | 236 | using namespace FileSys; |
| 237 | 237 | ||
| 238 | const auto& cache = | 238 | auto& system = Core::System::GetInstance(); |
| 239 | dynamic_cast<ContentProviderUnion&>(Core::System::GetInstance().GetContentProvider()); | 239 | const auto& cache = dynamic_cast<ContentProviderUnion&>(system.GetContentProvider()); |
| 240 | 240 | ||
| 241 | std::vector<std::pair<ContentProviderUnionSlot, ContentProviderEntry>> installed_games; | 241 | auto installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application, |
| 242 | installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application, | 242 | ContentRecordType::Program); |
| 243 | ContentRecordType::Program); | ||
| 244 | 243 | ||
| 245 | if (parent_dir->type() == static_cast<int>(GameListItemType::SdmcDir)) { | 244 | if (parent_dir->type() == static_cast<int>(GameListItemType::SdmcDir)) { |
| 246 | installed_games = cache.ListEntriesFilterOrigin( | 245 | installed_games = cache.ListEntriesFilterOrigin( |
| @@ -254,23 +253,27 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { | |||
| 254 | } | 253 | } |
| 255 | 254 | ||
| 256 | for (const auto& [slot, game] : installed_games) { | 255 | for (const auto& [slot, game] : installed_games) { |
| 257 | if (slot == ContentProviderUnionSlot::FrontendManual) | 256 | if (slot == ContentProviderUnionSlot::FrontendManual) { |
| 258 | continue; | 257 | continue; |
| 258 | } | ||
| 259 | 259 | ||
| 260 | const auto file = cache.GetEntryUnparsed(game.title_id, game.type); | 260 | const auto file = cache.GetEntryUnparsed(game.title_id, game.type); |
| 261 | std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file); | 261 | std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(system, file); |
| 262 | if (!loader) | 262 | if (!loader) { |
| 263 | continue; | 263 | continue; |
| 264 | } | ||
| 264 | 265 | ||
| 265 | std::vector<u8> icon; | 266 | std::vector<u8> icon; |
| 266 | std::string name; | 267 | std::string name; |
| 267 | u64 program_id = 0; | 268 | u64 program_id = 0; |
| 268 | loader->ReadProgramId(program_id); | 269 | loader->ReadProgramId(program_id); |
| 269 | 270 | ||
| 270 | const PatchManager patch{program_id}; | 271 | const PatchManager patch{program_id, system.GetFileSystemController(), |
| 272 | system.GetContentProvider()}; | ||
| 271 | const auto control = cache.GetEntry(game.title_id, ContentRecordType::Control); | 273 | const auto control = cache.GetEntry(game.title_id, ContentRecordType::Control); |
| 272 | if (control != nullptr) | 274 | if (control != nullptr) { |
| 273 | GetMetadataFromControlNCA(patch, *control, icon, name); | 275 | GetMetadataFromControlNCA(patch, *control, icon, name); |
| 276 | } | ||
| 274 | 277 | ||
| 275 | emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id, | 278 | emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id, |
| 276 | compatibility_list, patch), | 279 | compatibility_list, patch), |
| @@ -280,9 +283,11 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) { | |||
| 280 | 283 | ||
| 281 | void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_path, | 284 | void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_path, |
| 282 | unsigned int recursion, GameListDir* parent_dir) { | 285 | unsigned int recursion, GameListDir* parent_dir) { |
| 283 | const auto callback = [this, target, recursion, | 286 | auto& system = Core::System::GetInstance(); |
| 284 | parent_dir](u64* num_entries_out, const std::string& directory, | 287 | |
| 285 | const std::string& virtual_name) -> bool { | 288 | const auto callback = [this, target, recursion, parent_dir, |
| 289 | &system](u64* num_entries_out, const std::string& directory, | ||
| 290 | const std::string& virtual_name) -> bool { | ||
| 286 | if (stop_processing) { | 291 | if (stop_processing) { |
| 287 | // Breaks the callback loop. | 292 | // Breaks the callback loop. |
| 288 | return false; | 293 | return false; |
| @@ -293,7 +298,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa | |||
| 293 | if (!is_dir && | 298 | if (!is_dir && |
| 294 | (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) { | 299 | (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) { |
| 295 | const auto file = vfs->OpenFile(physical_name, FileSys::Mode::Read); | 300 | const auto file = vfs->OpenFile(physical_name, FileSys::Mode::Read); |
| 296 | auto loader = Loader::GetLoader(file); | 301 | auto loader = Loader::GetLoader(system, file); |
| 297 | if (!loader) { | 302 | if (!loader) { |
| 298 | return true; | 303 | return true; |
| 299 | } | 304 | } |
| @@ -331,7 +336,8 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa | |||
| 331 | std::string name = " "; | 336 | std::string name = " "; |
| 332 | [[maybe_unused]] const auto res3 = loader->ReadTitle(name); | 337 | [[maybe_unused]] const auto res3 = loader->ReadTitle(name); |
| 333 | 338 | ||
| 334 | const FileSys::PatchManager patch{program_id}; | 339 | const FileSys::PatchManager patch{program_id, system.GetFileSystemController(), |
| 340 | system.GetContentProvider()}; | ||
| 335 | 341 | ||
| 336 | emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id, | 342 | emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id, |
| 337 | compatibility_list, patch), | 343 | compatibility_list, patch), |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 9dabd8889..e704cc656 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1090,9 +1090,9 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1090 | StoreRecentFile(filename); // Put the filename on top of the list | 1090 | StoreRecentFile(filename); // Put the filename on top of the list |
| 1091 | 1091 | ||
| 1092 | u64 title_id{0}; | 1092 | u64 title_id{0}; |
| 1093 | 1093 | auto& system = Core::System::GetInstance(); | |
| 1094 | const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); | 1094 | const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); |
| 1095 | const auto loader = Loader::GetLoader(v_file); | 1095 | const auto loader = Loader::GetLoader(system, v_file); |
| 1096 | if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) { | 1096 | if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) { |
| 1097 | // Load per game settings | 1097 | // Load per game settings |
| 1098 | Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig); | 1098 | Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig); |
| @@ -1144,9 +1144,13 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1144 | 1144 | ||
| 1145 | std::string title_name; | 1145 | std::string title_name; |
| 1146 | std::string title_version; | 1146 | std::string title_version; |
| 1147 | const auto res = Core::System::GetInstance().GetGameName(title_name); | 1147 | const auto res = system.GetGameName(title_name); |
| 1148 | 1148 | ||
| 1149 | const auto metadata = FileSys::PatchManager(title_id).GetControlMetadata(); | 1149 | const auto metadata = [&system, title_id] { |
| 1150 | const FileSys::PatchManager pm(title_id, system.GetFileSystemController(), | ||
| 1151 | system.GetContentProvider()); | ||
| 1152 | return pm.GetControlMetadata(); | ||
| 1153 | }(); | ||
| 1150 | if (metadata.first != nullptr) { | 1154 | if (metadata.first != nullptr) { |
| 1151 | title_version = metadata.first->GetVersionString(); | 1155 | title_version = metadata.first->GetVersionString(); |
| 1152 | title_name = metadata.first->GetApplicationName(); | 1156 | title_name = metadata.first->GetApplicationName(); |
| @@ -1157,7 +1161,7 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1157 | LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version); | 1161 | LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version); |
| 1158 | UpdateWindowTitle(title_name, title_version); | 1162 | UpdateWindowTitle(title_name, title_version); |
| 1159 | 1163 | ||
| 1160 | loading_screen->Prepare(Core::System::GetInstance().GetAppLoader()); | 1164 | loading_screen->Prepare(system.GetAppLoader()); |
| 1161 | loading_screen->show(); | 1165 | loading_screen->show(); |
| 1162 | 1166 | ||
| 1163 | emulation_running = true; | 1167 | emulation_running = true; |
| @@ -1276,16 +1280,18 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 1276 | const std::string& game_path) { | 1280 | const std::string& game_path) { |
| 1277 | std::string path; | 1281 | std::string path; |
| 1278 | QString open_target; | 1282 | QString open_target; |
| 1283 | auto& system = Core::System::GetInstance(); | ||
| 1279 | 1284 | ||
| 1280 | const auto [user_save_size, device_save_size] = [this, &program_id, &game_path] { | 1285 | const auto [user_save_size, device_save_size] = [this, &game_path, &program_id, &system] { |
| 1281 | FileSys::PatchManager pm{program_id}; | 1286 | const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), |
| 1287 | system.GetContentProvider()}; | ||
| 1282 | const auto control = pm.GetControlMetadata().first; | 1288 | const auto control = pm.GetControlMetadata().first; |
| 1283 | if (control != nullptr) { | 1289 | if (control != nullptr) { |
| 1284 | return std::make_pair(control->GetDefaultNormalSaveSize(), | 1290 | return std::make_pair(control->GetDefaultNormalSaveSize(), |
| 1285 | control->GetDeviceSaveDataSize()); | 1291 | control->GetDeviceSaveDataSize()); |
| 1286 | } else { | 1292 | } else { |
| 1287 | const auto file = Core::GetGameFileFromPath(vfs, game_path); | 1293 | const auto file = Core::GetGameFileFromPath(vfs, game_path); |
| 1288 | const auto loader = Loader::GetLoader(file); | 1294 | const auto loader = Loader::GetLoader(system, file); |
| 1289 | 1295 | ||
| 1290 | FileSys::NACP nacp{}; | 1296 | FileSys::NACP nacp{}; |
| 1291 | loader->ReadControlData(nacp); | 1297 | loader->ReadControlData(nacp); |
| @@ -1612,7 +1618,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 1612 | "cancelled the operation.")); | 1618 | "cancelled the operation.")); |
| 1613 | }; | 1619 | }; |
| 1614 | 1620 | ||
| 1615 | const auto loader = Loader::GetLoader(vfs->OpenFile(game_path, FileSys::Mode::Read)); | 1621 | auto& system = Core::System::GetInstance(); |
| 1622 | const auto loader = Loader::GetLoader(system, vfs->OpenFile(game_path, FileSys::Mode::Read)); | ||
| 1616 | if (loader == nullptr) { | 1623 | if (loader == nullptr) { |
| 1617 | failed(); | 1624 | failed(); |
| 1618 | return; | 1625 | return; |
| @@ -1624,7 +1631,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 1624 | return; | 1631 | return; |
| 1625 | } | 1632 | } |
| 1626 | 1633 | ||
| 1627 | const auto& installed = Core::System::GetInstance().GetContentProvider(); | 1634 | const auto& installed = system.GetContentProvider(); |
| 1628 | const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id); | 1635 | const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id); |
| 1629 | 1636 | ||
| 1630 | if (!romfs_title_id) { | 1637 | if (!romfs_title_id) { |
| @@ -1639,7 +1646,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 1639 | 1646 | ||
| 1640 | if (*romfs_title_id == program_id) { | 1647 | if (*romfs_title_id == program_id) { |
| 1641 | const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); | 1648 | const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); |
| 1642 | FileSys::PatchManager pm{program_id}; | 1649 | const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed}; |
| 1643 | romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program); | 1650 | romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program); |
| 1644 | } else { | 1651 | } else { |
| 1645 | romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); | 1652 | romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); |
| @@ -1756,7 +1763,8 @@ void GMainWindow::OnGameListShowList(bool show) { | |||
| 1756 | void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) { | 1763 | void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) { |
| 1757 | u64 title_id{}; | 1764 | u64 title_id{}; |
| 1758 | const auto v_file = Core::GetGameFileFromPath(vfs, file); | 1765 | const auto v_file = Core::GetGameFileFromPath(vfs, file); |
| 1759 | const auto loader = Loader::GetLoader(v_file); | 1766 | const auto loader = Loader::GetLoader(Core::System::GetInstance(), v_file); |
| 1767 | |||
| 1760 | if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) { | 1768 | if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) { |
| 1761 | QMessageBox::information(this, tr("Properties"), | 1769 | QMessageBox::information(this, tr("Properties"), |
| 1762 | tr("The game properties could not be loaded.")); | 1770 | tr("The game properties could not be loaded.")); |