forked from suyu/suyu
Merge pull request #4944 from lioncash/system-rem
patch_manager: Remove usages of the global system instance
This commit is contained in:
commit
3a85bc1e77
26 changed files with 259 additions and 157 deletions
|
@ -210,7 +210,7 @@ struct System::Impl {
|
||||||
|
|
||||||
ResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
ResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
||||||
const std::string& filepath) {
|
const std::string& filepath) {
|
||||||
app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath));
|
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath));
|
||||||
if (!app_loader) {
|
if (!app_loader) {
|
||||||
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
||||||
return ResultStatus::ErrorGetLoader;
|
return ResultStatus::ErrorGetLoader;
|
||||||
|
@ -224,7 +224,7 @@ struct System::Impl {
|
||||||
return init_result;
|
return init_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
telemetry_session->AddInitialInfo(*app_loader);
|
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
||||||
auto main_process =
|
auto main_process =
|
||||||
Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland);
|
Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland);
|
||||||
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
||||||
|
@ -338,7 +338,7 @@ struct System::Impl {
|
||||||
Service::Glue::ApplicationLaunchProperty launch{};
|
Service::Glue::ApplicationLaunchProperty launch{};
|
||||||
launch.title_id = process.GetTitleID();
|
launch.title_id = process.GetTitleID();
|
||||||
|
|
||||||
FileSys::PatchManager pm{launch.title_id};
|
FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider};
|
||||||
launch.version = pm.GetGameVersion().value_or(0);
|
launch.version = pm.GetGameVersion().value_or(0);
|
||||||
|
|
||||||
// TODO(DarkLordZach): When FSController/Game Card Support is added, if
|
// TODO(DarkLordZach): When FSController/Game Card Support is added, if
|
||||||
|
|
|
@ -112,7 +112,10 @@ bool IsDirValidAndNonEmpty(const VirtualDir& dir) {
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
PatchManager::PatchManager(u64 title_id) : title_id(title_id) {}
|
PatchManager::PatchManager(u64 title_id_,
|
||||||
|
const Service::FileSystem::FileSystemController& fs_controller_,
|
||||||
|
const ContentProvider& content_provider_)
|
||||||
|
: title_id{title_id_}, fs_controller{fs_controller_}, content_provider{content_provider_} {}
|
||||||
|
|
||||||
PatchManager::~PatchManager() = default;
|
PatchManager::~PatchManager() = default;
|
||||||
|
|
||||||
|
@ -128,34 +131,30 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
|
||||||
|
|
||||||
if (Settings::values.dump_exefs) {
|
if (Settings::values.dump_exefs) {
|
||||||
LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id);
|
LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id);
|
||||||
const auto dump_dir =
|
const auto dump_dir = fs_controller.GetModificationDumpRoot(title_id);
|
||||||
Core::System::GetInstance().GetFileSystemController().GetModificationDumpRoot(title_id);
|
|
||||||
if (dump_dir != nullptr) {
|
if (dump_dir != nullptr) {
|
||||||
const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs");
|
const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs");
|
||||||
VfsRawCopyD(exefs, exefs_dir);
|
VfsRawCopyD(exefs, exefs_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
|
||||||
|
|
||||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||||
const auto update_disabled =
|
const auto update_disabled =
|
||||||
std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend();
|
std::find(disabled.cbegin(), disabled.cend(), "Update") != disabled.cend();
|
||||||
|
|
||||||
// Game Updates
|
// Game Updates
|
||||||
const auto update_tid = GetUpdateTitleID(title_id);
|
const auto update_tid = GetUpdateTitleID(title_id);
|
||||||
const auto update = installed.GetEntry(update_tid, ContentRecordType::Program);
|
const auto update = content_provider.GetEntry(update_tid, ContentRecordType::Program);
|
||||||
|
|
||||||
if (!update_disabled && update != nullptr && update->GetExeFS() != nullptr &&
|
if (!update_disabled && update != nullptr && update->GetExeFS() != nullptr &&
|
||||||
update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
|
update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
|
||||||
LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully",
|
LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully",
|
||||||
FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0)));
|
FormatTitleVersion(content_provider.GetEntryVersion(update_tid).value_or(0)));
|
||||||
exefs = update->GetExeFS();
|
exefs = update->GetExeFS();
|
||||||
}
|
}
|
||||||
|
|
||||||
// LayeredExeFS
|
// LayeredExeFS
|
||||||
const auto load_dir =
|
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
|
||||||
if (load_dir != nullptr && load_dir->GetSize() > 0) {
|
if (load_dir != nullptr && load_dir->GetSize() > 0) {
|
||||||
auto patch_dirs = load_dir->GetSubdirectories();
|
auto patch_dirs = load_dir->GetSubdirectories();
|
||||||
std::sort(
|
std::sort(
|
||||||
|
@ -241,8 +240,7 @@ std::vector<u8> PatchManager::PatchNSO(const std::vector<u8>& nso, const std::st
|
||||||
if (Settings::values.dump_nso) {
|
if (Settings::values.dump_nso) {
|
||||||
LOG_INFO(Loader, "Dumping NSO for name={}, build_id={}, title_id={:016X}", name, build_id,
|
LOG_INFO(Loader, "Dumping NSO for name={}, build_id={}, title_id={:016X}", name, build_id,
|
||||||
title_id);
|
title_id);
|
||||||
const auto dump_dir =
|
const auto dump_dir = fs_controller.GetModificationDumpRoot(title_id);
|
||||||
Core::System::GetInstance().GetFileSystemController().GetModificationDumpRoot(title_id);
|
|
||||||
if (dump_dir != nullptr) {
|
if (dump_dir != nullptr) {
|
||||||
const auto nso_dir = GetOrCreateDirectoryRelative(dump_dir, "/nso");
|
const auto nso_dir = GetOrCreateDirectoryRelative(dump_dir, "/nso");
|
||||||
const auto file = nso_dir->CreateFile(fmt::format("{}-{}.nso", name, build_id));
|
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
|
||||||
|
|
||||||
LOG_INFO(Loader, "Patching NSO for name={}, build_id={}", name, build_id);
|
LOG_INFO(Loader, "Patching NSO for name={}, build_id={}", name, build_id);
|
||||||
|
|
||||||
const auto load_dir =
|
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
|
||||||
if (load_dir == nullptr) {
|
if (load_dir == nullptr) {
|
||||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||||
return nso;
|
return nso;
|
||||||
|
@ -298,8 +295,7 @@ bool PatchManager::HasNSOPatch(const BuildID& build_id_) const {
|
||||||
|
|
||||||
LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id);
|
LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id);
|
||||||
|
|
||||||
const auto load_dir =
|
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
|
||||||
if (load_dir == nullptr) {
|
if (load_dir == nullptr) {
|
||||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||||
return false;
|
return false;
|
||||||
|
@ -313,8 +309,8 @@ bool PatchManager::HasNSOPatch(const BuildID& build_id_) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(
|
std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(
|
||||||
const Core::System& system, const BuildID& build_id_) const {
|
const BuildID& build_id_) const {
|
||||||
const auto load_dir = system.GetFileSystemController().GetModificationLoadRoot(title_id);
|
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||||
if (load_dir == nullptr) {
|
if (load_dir == nullptr) {
|
||||||
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
LOG_ERROR(Loader, "Cannot load mods for invalid title_id={:016X}", title_id);
|
||||||
return {};
|
return {};
|
||||||
|
@ -347,9 +343,9 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type) {
|
static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type,
|
||||||
const auto load_dir =
|
const Service::FileSystem::FileSystemController& fs_controller) {
|
||||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||||
if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
|
if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
|
||||||
load_dir == nullptr || load_dir->GetSize() <= 0) {
|
load_dir == nullptr || load_dir->GetSize() <= 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -411,19 +407,19 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
|
||||||
const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}",
|
const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}",
|
||||||
title_id, static_cast<u8>(type));
|
title_id, static_cast<u8>(type));
|
||||||
|
|
||||||
if (type == ContentRecordType::Program || type == ContentRecordType::Data)
|
if (type == ContentRecordType::Program || type == ContentRecordType::Data) {
|
||||||
LOG_INFO(Loader, "{}", log_string);
|
LOG_INFO(Loader, "{}", log_string);
|
||||||
else
|
} else {
|
||||||
LOG_DEBUG(Loader, "{}", log_string);
|
LOG_DEBUG(Loader, "{}", log_string);
|
||||||
|
}
|
||||||
|
|
||||||
if (romfs == nullptr)
|
if (romfs == nullptr) {
|
||||||
return romfs;
|
return romfs;
|
||||||
|
}
|
||||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
|
||||||
|
|
||||||
// Game Updates
|
// Game Updates
|
||||||
const auto update_tid = GetUpdateTitleID(title_id);
|
const auto update_tid = GetUpdateTitleID(title_id);
|
||||||
const auto update = installed.GetEntryRaw(update_tid, type);
|
const auto update = content_provider.GetEntryRaw(update_tid, type);
|
||||||
|
|
||||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||||
const auto update_disabled =
|
const auto update_disabled =
|
||||||
|
@ -434,7 +430,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
|
||||||
if (new_nca->GetStatus() == Loader::ResultStatus::Success &&
|
if (new_nca->GetStatus() == Loader::ResultStatus::Success &&
|
||||||
new_nca->GetRomFS() != nullptr) {
|
new_nca->GetRomFS() != nullptr) {
|
||||||
LOG_INFO(Loader, " RomFS: Update ({}) applied successfully",
|
LOG_INFO(Loader, " RomFS: Update ({}) applied successfully",
|
||||||
FormatTitleVersion(installed.GetEntryVersion(update_tid).value_or(0)));
|
FormatTitleVersion(content_provider.GetEntryVersion(update_tid).value_or(0)));
|
||||||
romfs = new_nca->GetRomFS();
|
romfs = new_nca->GetRomFS();
|
||||||
}
|
}
|
||||||
} else if (!update_disabled && update_raw != nullptr) {
|
} else if (!update_disabled && update_raw != nullptr) {
|
||||||
|
@ -447,7 +443,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
|
||||||
}
|
}
|
||||||
|
|
||||||
// LayeredFS
|
// LayeredFS
|
||||||
ApplyLayeredFS(romfs, title_id, type);
|
ApplyLayeredFS(romfs, title_id, type, fs_controller);
|
||||||
|
|
||||||
return romfs;
|
return romfs;
|
||||||
}
|
}
|
||||||
|
@ -458,12 +454,11 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::string, std::less<>> out;
|
std::map<std::string, std::string, std::less<>> out;
|
||||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
|
||||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||||
|
|
||||||
// Game Updates
|
// Game Updates
|
||||||
const auto update_tid = GetUpdateTitleID(title_id);
|
const auto update_tid = GetUpdateTitleID(title_id);
|
||||||
PatchManager update{update_tid};
|
PatchManager update{update_tid, fs_controller, content_provider};
|
||||||
const auto metadata = update.GetControlMetadata();
|
const auto metadata = update.GetControlMetadata();
|
||||||
const auto& nacp = metadata.first;
|
const auto& nacp = metadata.first;
|
||||||
|
|
||||||
|
@ -474,8 +469,8 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||||
if (nacp != nullptr) {
|
if (nacp != nullptr) {
|
||||||
out.insert_or_assign(update_label, nacp->GetVersionString());
|
out.insert_or_assign(update_label, nacp->GetVersionString());
|
||||||
} else {
|
} else {
|
||||||
if (installed.HasEntry(update_tid, ContentRecordType::Program)) {
|
if (content_provider.HasEntry(update_tid, ContentRecordType::Program)) {
|
||||||
const auto meta_ver = installed.GetEntryVersion(update_tid);
|
const auto meta_ver = content_provider.GetEntryVersion(update_tid);
|
||||||
if (meta_ver.value_or(0) == 0) {
|
if (meta_ver.value_or(0) == 0) {
|
||||||
out.insert_or_assign(update_label, "");
|
out.insert_or_assign(update_label, "");
|
||||||
} else {
|
} else {
|
||||||
|
@ -487,8 +482,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||||
}
|
}
|
||||||
|
|
||||||
// General Mods (LayeredFS and IPS)
|
// General Mods (LayeredFS and IPS)
|
||||||
const auto mod_dir =
|
const auto mod_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||||
Core::System::GetInstance().GetFileSystemController().GetModificationLoadRoot(title_id);
|
|
||||||
if (mod_dir != nullptr && mod_dir->GetSize() > 0) {
|
if (mod_dir != nullptr && mod_dir->GetSize() > 0) {
|
||||||
for (const auto& mod : mod_dir->GetSubdirectories()) {
|
for (const auto& mod : mod_dir->GetSubdirectories()) {
|
||||||
std::string types;
|
std::string types;
|
||||||
|
@ -532,13 +526,15 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||||
}
|
}
|
||||||
|
|
||||||
// DLC
|
// DLC
|
||||||
const auto dlc_entries = installed.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data);
|
const auto dlc_entries =
|
||||||
|
content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data);
|
||||||
std::vector<ContentProviderEntry> dlc_match;
|
std::vector<ContentProviderEntry> dlc_match;
|
||||||
dlc_match.reserve(dlc_entries.size());
|
dlc_match.reserve(dlc_entries.size());
|
||||||
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
|
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
|
||||||
[this, &installed](const ContentProviderEntry& entry) {
|
[this](const ContentProviderEntry& entry) {
|
||||||
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id &&
|
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id &&
|
||||||
installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success;
|
content_provider.GetEntry(entry)->GetStatus() ==
|
||||||
|
Loader::ResultStatus::Success;
|
||||||
});
|
});
|
||||||
if (!dlc_match.empty()) {
|
if (!dlc_match.empty()) {
|
||||||
// Ensure sorted so DLC IDs show in order.
|
// Ensure sorted so DLC IDs show in order.
|
||||||
|
@ -559,19 +555,16 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<u32> PatchManager::GetGameVersion() const {
|
std::optional<u32> PatchManager::GetGameVersion() const {
|
||||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
|
||||||
const auto update_tid = GetUpdateTitleID(title_id);
|
const auto update_tid = GetUpdateTitleID(title_id);
|
||||||
if (installed.HasEntry(update_tid, ContentRecordType::Program)) {
|
if (content_provider.HasEntry(update_tid, ContentRecordType::Program)) {
|
||||||
return installed.GetEntryVersion(update_tid);
|
return content_provider.GetEntryVersion(update_tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return installed.GetEntryVersion(title_id);
|
return content_provider.GetEntryVersion(title_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
PatchManager::Metadata PatchManager::GetControlMetadata() const {
|
PatchManager::Metadata PatchManager::GetControlMetadata() const {
|
||||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
const auto base_control_nca = content_provider.GetEntry(title_id, ContentRecordType::Control);
|
||||||
|
|
||||||
const auto base_control_nca = installed.GetEntry(title_id, ContentRecordType::Control);
|
|
||||||
if (base_control_nca == nullptr) {
|
if (base_control_nca == nullptr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,13 @@ namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Service::FileSystem {
|
||||||
|
class FileSystemController;
|
||||||
|
}
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
|
class ContentProvider;
|
||||||
class NCA;
|
class NCA;
|
||||||
class NACP;
|
class NACP;
|
||||||
|
|
||||||
|
@ -29,7 +34,9 @@ public:
|
||||||
using Metadata = std::pair<std::unique_ptr<NACP>, VirtualFile>;
|
using Metadata = std::pair<std::unique_ptr<NACP>, VirtualFile>;
|
||||||
using PatchVersionNames = std::map<std::string, std::string, std::less<>>;
|
using PatchVersionNames = std::map<std::string, std::string, std::less<>>;
|
||||||
|
|
||||||
explicit PatchManager(u64 title_id);
|
explicit PatchManager(u64 title_id_,
|
||||||
|
const Service::FileSystem::FileSystemController& fs_controller_,
|
||||||
|
const ContentProvider& content_provider_);
|
||||||
~PatchManager();
|
~PatchManager();
|
||||||
|
|
||||||
[[nodiscard]] u64 GetTitleID() const;
|
[[nodiscard]] u64 GetTitleID() const;
|
||||||
|
@ -50,7 +57,7 @@ public:
|
||||||
|
|
||||||
// Creates a CheatList object with all
|
// Creates a CheatList object with all
|
||||||
[[nodiscard]] std::vector<Core::Memory::CheatEntry> CreateCheatList(
|
[[nodiscard]] std::vector<Core::Memory::CheatEntry> CreateCheatList(
|
||||||
const Core::System& system, const BuildID& build_id) const;
|
const BuildID& build_id) const;
|
||||||
|
|
||||||
// Currently tracked RomFS patches:
|
// Currently tracked RomFS patches:
|
||||||
// - Game Updates
|
// - Game Updates
|
||||||
|
@ -80,6 +87,8 @@ private:
|
||||||
const std::string& build_id) const;
|
const std::string& build_id) const;
|
||||||
|
|
||||||
u64 title_id;
|
u64 title_id;
|
||||||
|
const Service::FileSystem::FileSystemController& fs_controller;
|
||||||
|
const ContentProvider& content_provider;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -37,10 +37,12 @@ void RomFSFactory::SetPackedUpdate(VirtualFile update_raw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess(u64 current_process_title_id) const {
|
ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess(u64 current_process_title_id) const {
|
||||||
if (!updatable)
|
if (!updatable) {
|
||||||
return MakeResult<VirtualFile>(file);
|
return MakeResult<VirtualFile>(file);
|
||||||
|
}
|
||||||
|
|
||||||
const PatchManager patch_manager(current_process_title_id);
|
const PatchManager patch_manager{current_process_title_id, filesystem_controller,
|
||||||
|
content_provider};
|
||||||
return MakeResult<VirtualFile>(
|
return MakeResult<VirtualFile>(
|
||||||
patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw));
|
patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw));
|
||||||
}
|
}
|
||||||
|
|
|
@ -742,8 +742,10 @@ void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx
|
||||||
bool is_locked = false;
|
bool is_locked = false;
|
||||||
|
|
||||||
if (res != Loader::ResultStatus::Success) {
|
if (res != Loader::ResultStatus::Success) {
|
||||||
FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
|
const FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID(),
|
||||||
auto nacp_unique = pm.GetControlMetadata().first;
|
system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
|
const auto nacp_unique = pm.GetControlMetadata().first;
|
||||||
|
|
||||||
if (nacp_unique != nullptr) {
|
if (nacp_unique != nullptr) {
|
||||||
is_locked = nacp_unique->GetUserAccountSwitchLock();
|
is_locked = nacp_unique->GetUserAccountSwitchLock();
|
||||||
|
|
|
@ -1381,13 +1381,16 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
|
||||||
const auto res = [this] {
|
const auto res = [this] {
|
||||||
const auto title_id = system.CurrentProcess()->GetTitleID();
|
const auto title_id = system.CurrentProcess()->GetTitleID();
|
||||||
|
|
||||||
FileSys::PatchManager pm{title_id};
|
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
auto res = pm.GetControlMetadata();
|
auto res = pm.GetControlMetadata();
|
||||||
if (res.first != nullptr) {
|
if (res.first != nullptr) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id)};
|
const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id),
|
||||||
|
system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
return pm_update.GetControlMetadata();
|
return pm_update.GetControlMetadata();
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
@ -1415,13 +1418,16 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||||
const auto res = [this] {
|
const auto res = [this] {
|
||||||
const auto title_id = system.CurrentProcess()->GetTitleID();
|
const auto title_id = system.CurrentProcess()->GetTitleID();
|
||||||
|
|
||||||
FileSys::PatchManager pm{title_id};
|
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
auto res = pm.GetControlMetadata();
|
auto res = pm.GetControlMetadata();
|
||||||
if (res.first != nullptr) {
|
if (res.first != nullptr) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id)};
|
const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id),
|
||||||
|
system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
return pm_update.GetControlMetadata();
|
return pm_update.GetControlMetadata();
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,8 @@ void AOC_U::GetAddOnContentBaseId(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
|
||||||
const auto title_id = system.CurrentProcess()->GetTitleID();
|
const auto title_id = system.CurrentProcess()->GetTitleID();
|
||||||
FileSys::PatchManager pm{title_id};
|
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
|
|
||||||
const auto res = pm.GetControlMetadata();
|
const auto res = pm.GetControlMetadata();
|
||||||
if (res.first == nullptr) {
|
if (res.first == nullptr) {
|
||||||
|
|
|
@ -455,7 +455,9 @@ FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataTy
|
||||||
const auto res = system.GetAppLoader().ReadControlData(nacp);
|
const auto res = system.GetAppLoader().ReadControlData(nacp);
|
||||||
|
|
||||||
if (res != Loader::ResultStatus::Success) {
|
if (res != Loader::ResultStatus::Success) {
|
||||||
FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()};
|
const FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID(),
|
||||||
|
system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
const auto metadata = pm.GetControlMetadata();
|
const auto metadata = pm.GetControlMetadata();
|
||||||
const auto& nacp_unique = metadata.first;
|
const auto& nacp_unique = metadata.first;
|
||||||
|
|
||||||
|
@ -728,7 +730,8 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
|
||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager());
|
std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager());
|
||||||
std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager());
|
std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager());
|
||||||
std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetReporter())
|
std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetContentProvider(),
|
||||||
|
system.GetReporter())
|
||||||
->InstallAsService(system.ServiceManager());
|
->InstallAsService(system.ServiceManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -650,8 +650,10 @@ private:
|
||||||
u64 next_entry_index = 0;
|
u64 next_entry_index = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
FSP_SRV::FSP_SRV(FileSystemController& fsc_, const FileSys::ContentProvider& content_provider_,
|
||||||
: ServiceFramework("fsp-srv"), fsc(fsc), reporter(reporter) {
|
const Core::Reporter& reporter_)
|
||||||
|
: ServiceFramework("fsp-srv"), fsc(fsc_), content_provider{content_provider_},
|
||||||
|
reporter(reporter_) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "OpenFileSystem"},
|
{0, nullptr, "OpenFileSystem"},
|
||||||
|
@ -968,7 +970,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSys::PatchManager pm{title_id};
|
const FileSys::PatchManager pm{title_id, fsc, content_provider};
|
||||||
|
|
||||||
auto storage = std::make_shared<IStorage>(
|
auto storage = std::make_shared<IStorage>(
|
||||||
pm.PatchRomFS(std::move(data.Unwrap()), 0, FileSys::ContentRecordType::Data));
|
pm.PatchRomFS(std::move(data.Unwrap()), 0, FileSys::ContentRecordType::Data));
|
||||||
|
|
|
@ -12,8 +12,9 @@ class Reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
class ContentProvider;
|
||||||
class FileSystemBackend;
|
class FileSystemBackend;
|
||||||
}
|
} // namespace FileSys
|
||||||
|
|
||||||
namespace Service::FileSystem {
|
namespace Service::FileSystem {
|
||||||
|
|
||||||
|
@ -32,7 +33,8 @@ enum class LogMode : u32 {
|
||||||
|
|
||||||
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
|
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
|
||||||
public:
|
public:
|
||||||
explicit FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter);
|
explicit FSP_SRV(FileSystemController& fsc_, const FileSys::ContentProvider& content_provider_,
|
||||||
|
const Core::Reporter& reporter_);
|
||||||
~FSP_SRV() override;
|
~FSP_SRV() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -55,6 +57,7 @@ private:
|
||||||
void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);
|
void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
FileSystemController& fsc;
|
FileSystemController& fsc;
|
||||||
|
const FileSys::ContentProvider& content_provider;
|
||||||
|
|
||||||
FileSys::VirtualFile romfs;
|
FileSys::VirtualFile romfs;
|
||||||
u64 current_process_id = 0;
|
u64 current_process_id = 0;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
|
@ -29,8 +30,8 @@ IAccountProxyInterface::IAccountProxyInterface() : ServiceFramework{"IAccountPro
|
||||||
|
|
||||||
IAccountProxyInterface::~IAccountProxyInterface() = default;
|
IAccountProxyInterface::~IAccountProxyInterface() = default;
|
||||||
|
|
||||||
IApplicationManagerInterface::IApplicationManagerInterface()
|
IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_)
|
||||||
: ServiceFramework{"IApplicationManagerInterface"} {
|
: ServiceFramework{"IApplicationManagerInterface"}, system{system_} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "ListApplicationRecord"},
|
{0, nullptr, "ListApplicationRecord"},
|
||||||
|
@ -298,7 +299,8 @@ void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestC
|
||||||
|
|
||||||
const auto size = ctx.GetWriteBufferSize();
|
const auto size = ctx.GetWriteBufferSize();
|
||||||
|
|
||||||
const FileSys::PatchManager pm{title_id};
|
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
const auto control = pm.GetControlMetadata();
|
const auto control = pm.GetControlMetadata();
|
||||||
|
|
||||||
std::vector<u8> out;
|
std::vector<u8> out;
|
||||||
|
@ -538,14 +540,14 @@ IFactoryResetInterface::IFactoryResetInterface::IFactoryResetInterface()
|
||||||
|
|
||||||
IFactoryResetInterface::~IFactoryResetInterface() = default;
|
IFactoryResetInterface::~IFactoryResetInterface() = default;
|
||||||
|
|
||||||
NS::NS(const char* name) : ServiceFramework{name} {
|
NS::NS(const char* name, Core::System& system_) : ServiceFramework{name}, system{system_} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
|
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
|
||||||
{7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
|
{7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
|
||||||
{7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
|
{7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
|
||||||
{7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
|
{7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
|
||||||
{7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"},
|
{7996, &NS::PushIApplicationManagerInterface, "GetApplicationManagerInterface"},
|
||||||
{7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
|
{7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
|
||||||
{7998, &NS::PushInterface<IContentManagementInterface>, "GetContentManagementInterface"},
|
{7998, &NS::PushInterface<IContentManagementInterface>, "GetContentManagementInterface"},
|
||||||
{7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
|
{7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
|
||||||
|
@ -558,7 +560,7 @@ NS::NS(const char* name) : ServiceFramework{name} {
|
||||||
NS::~NS() = default;
|
NS::~NS() = default;
|
||||||
|
|
||||||
std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const {
|
std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const {
|
||||||
return GetInterface<IApplicationManagerInterface>();
|
return GetInterface<IApplicationManagerInterface>(system);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NS_DEV final : public ServiceFramework<NS_DEV> {
|
class NS_DEV final : public ServiceFramework<NS_DEV> {
|
||||||
|
@ -678,11 +680,11 @@ public:
|
||||||
|
|
||||||
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
|
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
|
||||||
|
|
||||||
std::make_shared<NS>("ns:am2")->InstallAsService(service_manager);
|
std::make_shared<NS>("ns:am2", system)->InstallAsService(service_manager);
|
||||||
std::make_shared<NS>("ns:ec")->InstallAsService(service_manager);
|
std::make_shared<NS>("ns:ec", system)->InstallAsService(service_manager);
|
||||||
std::make_shared<NS>("ns:rid")->InstallAsService(service_manager);
|
std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager);
|
||||||
std::make_shared<NS>("ns:rt")->InstallAsService(service_manager);
|
std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager);
|
||||||
std::make_shared<NS>("ns:web")->InstallAsService(service_manager);
|
std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager);
|
||||||
|
|
||||||
std::make_shared<NS_DEV>()->InstallAsService(service_manager);
|
std::make_shared<NS_DEV>()->InstallAsService(service_manager);
|
||||||
std::make_shared<NS_SU>()->InstallAsService(service_manager);
|
std::make_shared<NS_SU>()->InstallAsService(service_manager);
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
|
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
|
|
||||||
namespace FileSystem {
|
namespace FileSystem {
|
||||||
|
@ -22,7 +26,7 @@ public:
|
||||||
|
|
||||||
class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
|
class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
|
||||||
public:
|
public:
|
||||||
explicit IApplicationManagerInterface();
|
explicit IApplicationManagerInterface(Core::System& system_);
|
||||||
~IApplicationManagerInterface() override;
|
~IApplicationManagerInterface() override;
|
||||||
|
|
||||||
ResultVal<u8> GetApplicationDesiredLanguage(u32 supported_languages);
|
ResultVal<u8> GetApplicationDesiredLanguage(u32 supported_languages);
|
||||||
|
@ -32,6 +36,8 @@ private:
|
||||||
void GetApplicationControlData(Kernel::HLERequestContext& ctx);
|
void GetApplicationControlData(Kernel::HLERequestContext& ctx);
|
||||||
void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx);
|
void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx);
|
||||||
void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx);
|
void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
|
class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
|
||||||
|
@ -72,13 +78,13 @@ public:
|
||||||
|
|
||||||
class NS final : public ServiceFramework<NS> {
|
class NS final : public ServiceFramework<NS> {
|
||||||
public:
|
public:
|
||||||
explicit NS(const char* name);
|
explicit NS(const char* name, Core::System& system_);
|
||||||
~NS() override;
|
~NS() override;
|
||||||
|
|
||||||
std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const;
|
std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T, typename... Args>
|
||||||
void PushInterface(Kernel::HLERequestContext& ctx) {
|
void PushInterface(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_NS, "called");
|
LOG_DEBUG(Service_NS, "called");
|
||||||
|
|
||||||
|
@ -87,13 +93,23 @@ private:
|
||||||
rb.PushIpcInterface<T>();
|
rb.PushIpcInterface<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
void PushIApplicationManagerInterface(Kernel::HLERequestContext& ctx) {
|
||||||
std::shared_ptr<T> GetInterface() const {
|
LOG_DEBUG(Service_NS, "called");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface<IApplicationManagerInterface>(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
std::shared_ptr<T> GetInterface(Args&&... args) const {
|
||||||
static_assert(std::is_base_of_v<Kernel::SessionRequestHandler, T>,
|
static_assert(std::is_base_of_v<Kernel::SessionRequestHandler, T>,
|
||||||
"Not a base of ServiceFrameworkBase");
|
"Not a base of ServiceFrameworkBase");
|
||||||
|
|
||||||
return std::make_shared<T>();
|
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Registers all NS services with the specified service manager.
|
/// Registers all NS services with the specified service manager.
|
||||||
|
|
|
@ -114,7 +114,8 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
||||||
}
|
}
|
||||||
|
|
||||||
if (override_update) {
|
if (override_update) {
|
||||||
const FileSys::PatchManager patch_manager(metadata.GetTitleID());
|
const FileSys::PatchManager patch_manager(
|
||||||
|
metadata.GetTitleID(), system.GetFileSystemController(), system.GetContentProvider());
|
||||||
dir = patch_manager.PatchExeFS(dir);
|
dir = patch_manager.PatchExeFS(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +161,8 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
||||||
modules.clear();
|
modules.clear();
|
||||||
const VAddr base_address{process.PageTable().GetCodeRegionStart()};
|
const VAddr base_address{process.PageTable().GetCodeRegionStart()};
|
||||||
VAddr next_load_addr{base_address};
|
VAddr next_load_addr{base_address};
|
||||||
const FileSys::PatchManager pm{metadata.GetTitleID()};
|
const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
for (const auto& module : static_modules) {
|
for (const auto& module : static_modules) {
|
||||||
const FileSys::VirtualFile module_file{dir->GetFile(module)};
|
const FileSys::VirtualFile module_file{dir->GetFile(module)};
|
||||||
if (!module_file) {
|
if (!module_file) {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/loader/deconstructed_rom_directory.h"
|
#include "core/loader/deconstructed_rom_directory.h"
|
||||||
#include "core/loader/elf.h"
|
#include "core/loader/elf.h"
|
||||||
|
@ -194,15 +195,14 @@ AppLoader::~AppLoader() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a loader for a file with a specific type
|
* Get a loader for a file with a specific type
|
||||||
* @param file The file to load
|
* @param system The system context to use.
|
||||||
* @param type The type of the file
|
* @param file The file to retrieve the loader for
|
||||||
* @param file the file to retrieve the loader for
|
* @param type The file type
|
||||||
* @param type the file type
|
|
||||||
* @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type
|
* @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type
|
||||||
*/
|
*/
|
||||||
static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileType type) {
|
static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::VirtualFile file,
|
||||||
|
FileType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
// Standard ELF file format.
|
// Standard ELF file format.
|
||||||
case FileType::ELF:
|
case FileType::ELF:
|
||||||
return std::make_unique<AppLoader_ELF>(std::move(file));
|
return std::make_unique<AppLoader_ELF>(std::move(file));
|
||||||
|
@ -221,7 +221,8 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT
|
||||||
|
|
||||||
// NX XCI (nX Card Image) file format.
|
// NX XCI (nX Card Image) file format.
|
||||||
case FileType::XCI:
|
case FileType::XCI:
|
||||||
return std::make_unique<AppLoader_XCI>(std::move(file));
|
return std::make_unique<AppLoader_XCI>(std::move(file), system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider());
|
||||||
|
|
||||||
// NX NAX (NintendoAesXts) file format.
|
// NX NAX (NintendoAesXts) file format.
|
||||||
case FileType::NAX:
|
case FileType::NAX:
|
||||||
|
@ -229,7 +230,8 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT
|
||||||
|
|
||||||
// NX NSP (Nintendo Submission Package) file format
|
// NX NSP (Nintendo Submission Package) file format
|
||||||
case FileType::NSP:
|
case FileType::NSP:
|
||||||
return std::make_unique<AppLoader_NSP>(std::move(file));
|
return std::make_unique<AppLoader_NSP>(std::move(file), system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider());
|
||||||
|
|
||||||
// NX KIP (Kernel Internal Process) file format
|
// NX KIP (Kernel Internal Process) file format
|
||||||
case FileType::KIP:
|
case FileType::KIP:
|
||||||
|
@ -244,20 +246,21 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AppLoader> GetLoader(FileSys::VirtualFile file) {
|
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file) {
|
||||||
FileType type = IdentifyFile(file);
|
FileType type = IdentifyFile(file);
|
||||||
FileType filename_type = GuessFromFilename(file->GetName());
|
const FileType filename_type = GuessFromFilename(file->GetName());
|
||||||
|
|
||||||
// Special case: 00 is either a NCA or NAX.
|
// Special case: 00 is either a NCA or NAX.
|
||||||
if (type != filename_type && !(file->GetName() == "00" && type == FileType::NAX)) {
|
if (type != filename_type && !(file->GetName() == "00" && type == FileType::NAX)) {
|
||||||
LOG_WARNING(Loader, "File {} has a different type than its extension.", file->GetName());
|
LOG_WARNING(Loader, "File {} has a different type than its extension.", file->GetName());
|
||||||
if (FileType::Unknown == type)
|
if (FileType::Unknown == type) {
|
||||||
type = filename_type;
|
type = filename_type;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG_DEBUG(Loader, "Loading file {} as {}...", file->GetName(), GetFileTypeString(type));
|
LOG_DEBUG(Loader, "Loading file {} as {}...", file->GetName(), GetFileTypeString(type));
|
||||||
|
|
||||||
return GetFileLoader(std::move(file), type);
|
return GetFileLoader(system, std::move(file), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Loader
|
} // namespace Loader
|
||||||
|
|
|
@ -290,9 +290,12 @@ protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies a bootable file and return a suitable loader
|
* Identifies a bootable file and return a suitable loader
|
||||||
* @param file The bootable file
|
*
|
||||||
* @return the best loader for this file
|
* @param system The system context.
|
||||||
|
* @param file The bootable file.
|
||||||
|
*
|
||||||
|
* @return the best loader for this file.
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<AppLoader> GetLoader(FileSys::VirtualFile file);
|
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file);
|
||||||
|
|
||||||
} // namespace Loader
|
} // namespace Loader
|
||||||
|
|
|
@ -149,7 +149,7 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S
|
||||||
// Apply cheats if they exist and the program has a valid title ID
|
// Apply cheats if they exist and the program has a valid title ID
|
||||||
if (pm) {
|
if (pm) {
|
||||||
system.SetCurrentProcessBuildID(nso_header.build_id);
|
system.SetCurrentProcessBuildID(nso_header.build_id);
|
||||||
const auto cheats = pm->CreateCheatList(system, nso_header.build_id);
|
const auto cheats = pm->CreateCheatList(nso_header.build_id);
|
||||||
if (!cheats.empty()) {
|
if (!cheats.empty()) {
|
||||||
system.RegisterCheatList(cheats, nso_header.build_id, load_base, image_size);
|
system.RegisterCheatList(cheats, nso_header.build_id, load_base, image_size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,26 +21,33 @@
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
|
|
||||||
AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file)
|
AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file,
|
||||||
|
const Service::FileSystem::FileSystemController& fsc,
|
||||||
|
const FileSys::ContentProvider& content_provider)
|
||||||
: AppLoader(file), nsp(std::make_unique<FileSys::NSP>(file)),
|
: AppLoader(file), nsp(std::make_unique<FileSys::NSP>(file)),
|
||||||
title_id(nsp->GetProgramTitleID()) {
|
title_id(nsp->GetProgramTitleID()) {
|
||||||
|
|
||||||
if (nsp->GetStatus() != ResultStatus::Success)
|
if (nsp->GetStatus() != ResultStatus::Success) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (nsp->IsExtractedType()) {
|
if (nsp->IsExtractedType()) {
|
||||||
secondary_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(nsp->GetExeFS());
|
secondary_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(nsp->GetExeFS());
|
||||||
} else {
|
} else {
|
||||||
const auto control_nca =
|
const auto control_nca =
|
||||||
nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control);
|
nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control);
|
||||||
if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success)
|
if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::tie(nacp_file, icon_file) =
|
std::tie(nacp_file, icon_file) = [this, &content_provider, &control_nca, &fsc] {
|
||||||
FileSys::PatchManager(nsp->GetProgramTitleID()).ParseControlNCA(*control_nca);
|
const FileSys::PatchManager pm{nsp->GetProgramTitleID(), fsc, content_provider};
|
||||||
|
return pm.ParseControlNCA(*control_nca);
|
||||||
|
}();
|
||||||
|
|
||||||
if (title_id == 0)
|
if (title_id == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
secondary_loader = std::make_unique<AppLoader_NCA>(
|
secondary_loader = std::make_unique<AppLoader_NCA>(
|
||||||
nsp->GetNCAFile(title_id, FileSys::ContentRecordType::Program));
|
nsp->GetNCAFile(title_id, FileSys::ContentRecordType::Program));
|
||||||
|
|
|
@ -9,15 +9,16 @@
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
class ContentProvider;
|
||||||
class NACP;
|
class NACP;
|
||||||
class NSP;
|
class NSP;
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
||||||
|
namespace Service::FileSystem {
|
||||||
|
class FileSystemController;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
|
|
||||||
class AppLoader_NCA;
|
class AppLoader_NCA;
|
||||||
|
@ -25,7 +26,9 @@ class AppLoader_NCA;
|
||||||
/// Loads an XCI file
|
/// Loads an XCI file
|
||||||
class AppLoader_NSP final : public AppLoader {
|
class AppLoader_NSP final : public AppLoader {
|
||||||
public:
|
public:
|
||||||
explicit AppLoader_NSP(FileSys::VirtualFile file);
|
explicit AppLoader_NSP(FileSys::VirtualFile file,
|
||||||
|
const Service::FileSystem::FileSystemController& fsc,
|
||||||
|
const FileSys::ContentProvider& content_provider);
|
||||||
~AppLoader_NSP() override;
|
~AppLoader_NSP() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,18 +20,24 @@
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
|
|
||||||
AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
|
AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file,
|
||||||
|
const Service::FileSystem::FileSystemController& fsc,
|
||||||
|
const FileSys::ContentProvider& content_provider)
|
||||||
: AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
|
: AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
|
||||||
nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) {
|
nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) {
|
||||||
if (xci->GetStatus() != ResultStatus::Success)
|
if (xci->GetStatus() != ResultStatus::Success) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
|
const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
|
||||||
if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success)
|
if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::tie(nacp_file, icon_file) =
|
std::tie(nacp_file, icon_file) = [this, &content_provider, &control_nca, &fsc] {
|
||||||
FileSys::PatchManager(xci->GetProgramTitleID()).ParseControlNCA(*control_nca);
|
const FileSys::PatchManager pm{xci->GetProgramTitleID(), fsc, content_provider};
|
||||||
|
return pm.ParseControlNCA(*control_nca);
|
||||||
|
}();
|
||||||
}
|
}
|
||||||
|
|
||||||
AppLoader_XCI::~AppLoader_XCI() = default;
|
AppLoader_XCI::~AppLoader_XCI() = default;
|
||||||
|
|
|
@ -9,15 +9,16 @@
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
class ContentProvider;
|
||||||
class NACP;
|
class NACP;
|
||||||
class XCI;
|
class XCI;
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
||||||
|
namespace Service::FileSystem {
|
||||||
|
class FileSystemController;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
|
|
||||||
class AppLoader_NCA;
|
class AppLoader_NCA;
|
||||||
|
@ -25,7 +26,9 @@ class AppLoader_NCA;
|
||||||
/// Loads an XCI file
|
/// Loads an XCI file
|
||||||
class AppLoader_XCI final : public AppLoader {
|
class AppLoader_XCI final : public AppLoader {
|
||||||
public:
|
public:
|
||||||
explicit AppLoader_XCI(FileSys::VirtualFile file);
|
explicit AppLoader_XCI(FileSys::VirtualFile file,
|
||||||
|
const Service::FileSystem::FileSystemController& fsc,
|
||||||
|
const FileSys::ContentProvider& content_provider);
|
||||||
~AppLoader_XCI() override;
|
~AppLoader_XCI() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -147,7 +147,9 @@ TelemetrySession::~TelemetrySession() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
|
void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader,
|
||||||
|
const Service::FileSystem::FileSystemController& fsc,
|
||||||
|
const FileSys::ContentProvider& content_provider) {
|
||||||
// Log one-time top-level information
|
// Log one-time top-level information
|
||||||
AddField(Telemetry::FieldType::None, "TelemetryId", GetTelemetryId());
|
AddField(Telemetry::FieldType::None, "TelemetryId", GetTelemetryId());
|
||||||
|
|
||||||
|
@ -167,7 +169,10 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
|
||||||
app_loader.ReadTitle(name);
|
app_loader.ReadTitle(name);
|
||||||
|
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
const auto metadata = FileSys::PatchManager(program_id).GetControlMetadata();
|
const auto metadata = [&content_provider, &fsc, program_id] {
|
||||||
|
const FileSys::PatchManager pm{program_id, fsc, content_provider};
|
||||||
|
return pm.GetControlMetadata();
|
||||||
|
}();
|
||||||
if (metadata.first != nullptr) {
|
if (metadata.first != nullptr) {
|
||||||
name = metadata.first->GetApplicationName();
|
name = metadata.first->GetApplicationName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,18 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/telemetry.h"
|
#include "common/telemetry.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
class ContentProvider;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
class AppLoader;
|
class AppLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Service::FileSystem {
|
||||||
|
class FileSystemController;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,8 +50,12 @@ public:
|
||||||
*
|
*
|
||||||
* @param app_loader The application loader to use to retrieve
|
* @param app_loader The application loader to use to retrieve
|
||||||
* title-specific information.
|
* title-specific information.
|
||||||
|
* @param fsc Filesystem controller to use to retrieve info.
|
||||||
|
* @param content_provider Content provider to use to retrieve info.
|
||||||
*/
|
*/
|
||||||
void AddInitialInfo(Loader::AppLoader& app_loader);
|
void AddInitialInfo(Loader::AppLoader& app_loader,
|
||||||
|
const Service::FileSystem::FileSystemController& fsc,
|
||||||
|
const FileSys::ContentProvider& content_provider);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper around the Telemetry::FieldCollection::AddField method.
|
* Wrapper around the Telemetry::FieldCollection::AddField method.
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/xts_archive.h"
|
#include "core/file_sys/xts_archive.h"
|
||||||
|
@ -89,9 +90,11 @@ void ConfigurePerGame::LoadConfiguration() {
|
||||||
ui->display_title_id->setText(
|
ui->display_title_id->setText(
|
||||||
QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper());
|
QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper());
|
||||||
|
|
||||||
FileSys::PatchManager pm{title_id};
|
auto& system = Core::System::GetInstance();
|
||||||
|
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
const auto control = pm.GetControlMetadata();
|
const auto control = pm.GetControlMetadata();
|
||||||
const auto loader = Loader::GetLoader(file);
|
const auto loader = Loader::GetLoader(system, file);
|
||||||
|
|
||||||
if (control.first != nullptr) {
|
if (control.first != nullptr) {
|
||||||
ui->display_version->setText(QString::fromStdString(control.first->GetVersionString()));
|
ui->display_version->setText(QString::fromStdString(control.first->GetVersionString()));
|
||||||
|
|
|
@ -112,8 +112,10 @@ void ConfigurePerGameAddons::LoadConfiguration() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSys::PatchManager pm{title_id};
|
auto& system = Core::System::GetInstance();
|
||||||
const auto loader = Loader::GetLoader(file);
|
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
|
const auto loader = Loader::GetLoader(system, file);
|
||||||
|
|
||||||
FileSys::VirtualFile update_raw;
|
FileSys::VirtualFile update_raw;
|
||||||
loader->ReadUpdateRaw(update_raw);
|
loader->ReadUpdateRaw(update_raw);
|
||||||
|
|
|
@ -235,11 +235,10 @@ GameListWorker::~GameListWorker() = default;
|
||||||
void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
|
void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
|
||||||
using namespace FileSys;
|
using namespace FileSys;
|
||||||
|
|
||||||
const auto& cache =
|
auto& system = Core::System::GetInstance();
|
||||||
dynamic_cast<ContentProviderUnion&>(Core::System::GetInstance().GetContentProvider());
|
const auto& cache = dynamic_cast<ContentProviderUnion&>(system.GetContentProvider());
|
||||||
|
|
||||||
std::vector<std::pair<ContentProviderUnionSlot, ContentProviderEntry>> installed_games;
|
auto installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application,
|
||||||
installed_games = cache.ListEntriesFilterOrigin(std::nullopt, TitleType::Application,
|
|
||||||
ContentRecordType::Program);
|
ContentRecordType::Program);
|
||||||
|
|
||||||
if (parent_dir->type() == static_cast<int>(GameListItemType::SdmcDir)) {
|
if (parent_dir->type() == static_cast<int>(GameListItemType::SdmcDir)) {
|
||||||
|
@ -254,23 +253,27 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& [slot, game] : installed_games) {
|
for (const auto& [slot, game] : installed_games) {
|
||||||
if (slot == ContentProviderUnionSlot::FrontendManual)
|
if (slot == ContentProviderUnionSlot::FrontendManual) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const auto file = cache.GetEntryUnparsed(game.title_id, game.type);
|
const auto file = cache.GetEntryUnparsed(game.title_id, game.type);
|
||||||
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file);
|
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(system, file);
|
||||||
if (!loader)
|
if (!loader) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<u8> icon;
|
std::vector<u8> icon;
|
||||||
std::string name;
|
std::string name;
|
||||||
u64 program_id = 0;
|
u64 program_id = 0;
|
||||||
loader->ReadProgramId(program_id);
|
loader->ReadProgramId(program_id);
|
||||||
|
|
||||||
const PatchManager patch{program_id};
|
const PatchManager patch{program_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
const auto control = cache.GetEntry(game.title_id, ContentRecordType::Control);
|
const auto control = cache.GetEntry(game.title_id, ContentRecordType::Control);
|
||||||
if (control != nullptr)
|
if (control != nullptr) {
|
||||||
GetMetadataFromControlNCA(patch, *control, icon, name);
|
GetMetadataFromControlNCA(patch, *control, icon, name);
|
||||||
|
}
|
||||||
|
|
||||||
emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id,
|
emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id,
|
||||||
compatibility_list, patch),
|
compatibility_list, patch),
|
||||||
|
@ -280,8 +283,10 @@ void GameListWorker::AddTitlesToGameList(GameListDir* parent_dir) {
|
||||||
|
|
||||||
void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_path,
|
void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_path,
|
||||||
unsigned int recursion, GameListDir* parent_dir) {
|
unsigned int recursion, GameListDir* parent_dir) {
|
||||||
const auto callback = [this, target, recursion,
|
auto& system = Core::System::GetInstance();
|
||||||
parent_dir](u64* num_entries_out, const std::string& directory,
|
|
||||||
|
const auto callback = [this, target, recursion, parent_dir,
|
||||||
|
&system](u64* num_entries_out, const std::string& directory,
|
||||||
const std::string& virtual_name) -> bool {
|
const std::string& virtual_name) -> bool {
|
||||||
if (stop_processing) {
|
if (stop_processing) {
|
||||||
// Breaks the callback loop.
|
// Breaks the callback loop.
|
||||||
|
@ -293,7 +298,7 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
|
||||||
if (!is_dir &&
|
if (!is_dir &&
|
||||||
(HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) {
|
(HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) {
|
||||||
const auto file = vfs->OpenFile(physical_name, FileSys::Mode::Read);
|
const auto file = vfs->OpenFile(physical_name, FileSys::Mode::Read);
|
||||||
auto loader = Loader::GetLoader(file);
|
auto loader = Loader::GetLoader(system, file);
|
||||||
if (!loader) {
|
if (!loader) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -331,7 +336,8 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
|
||||||
std::string name = " ";
|
std::string name = " ";
|
||||||
[[maybe_unused]] const auto res3 = loader->ReadTitle(name);
|
[[maybe_unused]] const auto res3 = loader->ReadTitle(name);
|
||||||
|
|
||||||
const FileSys::PatchManager patch{program_id};
|
const FileSys::PatchManager patch{program_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
|
|
||||||
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id,
|
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id,
|
||||||
compatibility_list, patch),
|
compatibility_list, patch),
|
||||||
|
|
|
@ -1090,9 +1090,9 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||||
StoreRecentFile(filename); // Put the filename on top of the list
|
StoreRecentFile(filename); // Put the filename on top of the list
|
||||||
|
|
||||||
u64 title_id{0};
|
u64 title_id{0};
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
|
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
|
||||||
const auto loader = Loader::GetLoader(v_file);
|
const auto loader = Loader::GetLoader(system, v_file);
|
||||||
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
|
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
|
||||||
// Load per game settings
|
// Load per game settings
|
||||||
Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig);
|
Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig);
|
||||||
|
@ -1144,9 +1144,13 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||||
|
|
||||||
std::string title_name;
|
std::string title_name;
|
||||||
std::string title_version;
|
std::string title_version;
|
||||||
const auto res = Core::System::GetInstance().GetGameName(title_name);
|
const auto res = system.GetGameName(title_name);
|
||||||
|
|
||||||
const auto metadata = FileSys::PatchManager(title_id).GetControlMetadata();
|
const auto metadata = [&system, title_id] {
|
||||||
|
const FileSys::PatchManager pm(title_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider());
|
||||||
|
return pm.GetControlMetadata();
|
||||||
|
}();
|
||||||
if (metadata.first != nullptr) {
|
if (metadata.first != nullptr) {
|
||||||
title_version = metadata.first->GetVersionString();
|
title_version = metadata.first->GetVersionString();
|
||||||
title_name = metadata.first->GetApplicationName();
|
title_name = metadata.first->GetApplicationName();
|
||||||
|
@ -1157,7 +1161,7 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||||
LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
|
LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
|
||||||
UpdateWindowTitle(title_name, title_version);
|
UpdateWindowTitle(title_name, title_version);
|
||||||
|
|
||||||
loading_screen->Prepare(Core::System::GetInstance().GetAppLoader());
|
loading_screen->Prepare(system.GetAppLoader());
|
||||||
loading_screen->show();
|
loading_screen->show();
|
||||||
|
|
||||||
emulation_running = true;
|
emulation_running = true;
|
||||||
|
@ -1276,16 +1280,18 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
|
||||||
const std::string& game_path) {
|
const std::string& game_path) {
|
||||||
std::string path;
|
std::string path;
|
||||||
QString open_target;
|
QString open_target;
|
||||||
|
auto& system = Core::System::GetInstance();
|
||||||
|
|
||||||
const auto [user_save_size, device_save_size] = [this, &program_id, &game_path] {
|
const auto [user_save_size, device_save_size] = [this, &game_path, &program_id, &system] {
|
||||||
FileSys::PatchManager pm{program_id};
|
const FileSys::PatchManager pm{program_id, system.GetFileSystemController(),
|
||||||
|
system.GetContentProvider()};
|
||||||
const auto control = pm.GetControlMetadata().first;
|
const auto control = pm.GetControlMetadata().first;
|
||||||
if (control != nullptr) {
|
if (control != nullptr) {
|
||||||
return std::make_pair(control->GetDefaultNormalSaveSize(),
|
return std::make_pair(control->GetDefaultNormalSaveSize(),
|
||||||
control->GetDeviceSaveDataSize());
|
control->GetDeviceSaveDataSize());
|
||||||
} else {
|
} else {
|
||||||
const auto file = Core::GetGameFileFromPath(vfs, game_path);
|
const auto file = Core::GetGameFileFromPath(vfs, game_path);
|
||||||
const auto loader = Loader::GetLoader(file);
|
const auto loader = Loader::GetLoader(system, file);
|
||||||
|
|
||||||
FileSys::NACP nacp{};
|
FileSys::NACP nacp{};
|
||||||
loader->ReadControlData(nacp);
|
loader->ReadControlData(nacp);
|
||||||
|
@ -1612,7 +1618,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
|
||||||
"cancelled the operation."));
|
"cancelled the operation."));
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto loader = Loader::GetLoader(vfs->OpenFile(game_path, FileSys::Mode::Read));
|
auto& system = Core::System::GetInstance();
|
||||||
|
const auto loader = Loader::GetLoader(system, vfs->OpenFile(game_path, FileSys::Mode::Read));
|
||||||
if (loader == nullptr) {
|
if (loader == nullptr) {
|
||||||
failed();
|
failed();
|
||||||
return;
|
return;
|
||||||
|
@ -1624,7 +1631,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
const auto& installed = system.GetContentProvider();
|
||||||
const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
|
const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
|
||||||
|
|
||||||
if (!romfs_title_id) {
|
if (!romfs_title_id) {
|
||||||
|
@ -1639,7 +1646,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
|
||||||
|
|
||||||
if (*romfs_title_id == program_id) {
|
if (*romfs_title_id == program_id) {
|
||||||
const u64 ivfc_offset = loader->ReadRomFSIVFCOffset();
|
const u64 ivfc_offset = loader->ReadRomFSIVFCOffset();
|
||||||
FileSys::PatchManager pm{program_id};
|
const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed};
|
||||||
romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program);
|
romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program);
|
||||||
} else {
|
} else {
|
||||||
romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS();
|
romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS();
|
||||||
|
@ -1756,7 +1763,8 @@ void GMainWindow::OnGameListShowList(bool show) {
|
||||||
void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
|
void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
|
||||||
u64 title_id{};
|
u64 title_id{};
|
||||||
const auto v_file = Core::GetGameFileFromPath(vfs, file);
|
const auto v_file = Core::GetGameFileFromPath(vfs, file);
|
||||||
const auto loader = Loader::GetLoader(v_file);
|
const auto loader = Loader::GetLoader(Core::System::GetInstance(), v_file);
|
||||||
|
|
||||||
if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
|
if (loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
|
||||||
QMessageBox::information(this, tr("Properties"),
|
QMessageBox::information(this, tr("Properties"),
|
||||||
tr("The game properties could not be loaded."));
|
tr("The game properties could not be loaded."));
|
||||||
|
|
Loading…
Reference in a new issue