diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_add_on_content_location_resolver.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_add_on_content_location_resolver.hpp index 3a05c2204..cbe155218 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_add_on_content_location_resolver.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_add_on_content_location_resolver.hpp @@ -31,10 +31,12 @@ namespace ams::lr { UnregisterApplicationAddOnContent = 4, }; private: + /* Storage for RegisteredData entries by program id. */ RegisteredStorages registered_storages; public: AddOnContentLocationResolverInterface() : registered_storages(hos::GetVersion() < hos::Version_900 ? 0x800 : 0x2) { /* ... */ } + /* Actual commands. */ virtual Result ResolveAddOnContentPath(sf::Out out, ncm::ProgramId id); virtual Result RegisterAddOnContentStorageDeprecated(ncm::StorageId storage_id, ncm::ProgramId id); virtual Result RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::ProgramId id, ncm::ProgramId application_id); diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_content_location_resolver.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_content_location_resolver.hpp index 80266f7e5..18bce1c3e 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_content_location_resolver.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_content_location_resolver.hpp @@ -25,6 +25,8 @@ namespace ams::lr { class ContentLocationResolverInterface : public ILocationResolverInterface { private: ncm::StorageId storage_id; + + /* Objects for this storage type. */ std::shared_ptr content_meta_database; std::shared_ptr content_storage; public: @@ -32,8 +34,10 @@ namespace ams::lr { ~ContentLocationResolverInterface(); private: + /* Helper functions. */ void GetContentStoragePath(Path* out, ncm::ContentId content_id); public: + /* Actual commands. */ virtual Result ResolveProgramPath(sf::Out out, ncm::ProgramId id) override; virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId id) override; virtual Result ResolveApplicationControlPath(sf::Out out, ncm::ProgramId id) override; diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_i_location_resolver.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_i_location_resolver.hpp index 1b35ecfd5..38e4ca7b9 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_i_location_resolver.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_i_location_resolver.hpp @@ -51,12 +51,14 @@ namespace ams::lr { EraseProgramRedirectionForDebug = 19, }; protected: + /* Location redirectors. */ LocationRedirector program_redirector; LocationRedirector debug_program_redirector; LocationRedirector app_control_redirector; LocationRedirector html_docs_redirector; LocationRedirector legal_info_redirector; protected: + /* Helper functions. */ void ClearRedirections(u32 flags = RedirectionFlags_None) { this->program_redirector.ClearRedirections(flags); this->debug_program_redirector.ClearRedirections(flags); @@ -66,13 +68,14 @@ namespace ams::lr { } void ClearRedirections(const ncm::ProgramId* excluding_ids, size_t num_ids) { - this->program_redirector.ClearRedirections(excluding_ids, num_ids); - this->debug_program_redirector.ClearRedirections(excluding_ids, num_ids); - this->app_control_redirector.ClearRedirections(excluding_ids, num_ids); - this->html_docs_redirector.ClearRedirections(excluding_ids, num_ids); - this->legal_info_redirector.ClearRedirections(excluding_ids, num_ids); + this->program_redirector.ClearRedirectionsExcludingOwners(excluding_ids, num_ids); + this->debug_program_redirector.ClearRedirectionsExcludingOwners(excluding_ids, num_ids); + this->app_control_redirector.ClearRedirectionsExcludingOwners(excluding_ids, num_ids); + this->html_docs_redirector.ClearRedirectionsExcludingOwners(excluding_ids, num_ids); + this->legal_info_redirector.ClearRedirectionsExcludingOwners(excluding_ids, num_ids); } public: + /* Actual commands. */ virtual Result ResolveProgramPath(sf::Out out, ncm::ProgramId id) = 0; virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId id) = 0; virtual Result ResolveApplicationControlPath(sf::Out out, ncm::ProgramId id) = 0; diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_i_location_resolver_interface.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_i_location_resolver_interface.hpp index 16ed42c45..4fd313385 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_i_location_resolver_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_i_location_resolver_interface.hpp @@ -22,6 +22,7 @@ namespace ams::lr { class ILocationResolverInterface : public ILocationResolver { public: + /* Actual commands. */ virtual Result ResolveProgramPath(sf::Out out, ncm::ProgramId id) = 0; virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId id) = 0; virtual Result ResolveApplicationControlPath(sf::Out out, ncm::ProgramId id) = 0; diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_location_redirector.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_location_redirector.hpp index 6187eb1a7..a003f0197 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_location_redirector.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_location_redirector.hpp @@ -37,13 +37,14 @@ namespace ams::lr { LocationRedirector() { /* ... */ } ~LocationRedirector() { this->ClearRedirections(); } + /* API. */ bool FindRedirection(Path *out, ncm::ProgramId program_id) const; void SetRedirection(ncm::ProgramId program_id, const Path &path, u32 flags = RedirectionFlags_None); void SetRedirection(ncm::ProgramId program_id, ncm::ProgramId owner_id, const Path &path, u32 flags = RedirectionFlags_None); void SetRedirectionFlags(ncm::ProgramId program_id, u32 flags); void EraseRedirection(ncm::ProgramId program_id); void ClearRedirections(u32 flags = RedirectionFlags_None); - void ClearRedirections(const ncm::ProgramId* excluding_ids, size_t num_ids); + void ClearRedirectionsExcludingOwners(const ncm::ProgramId* excluding_ids, size_t num_ids); private: inline bool IsExcluded(const ncm::ProgramId id, const ncm::ProgramId* excluding_ids, size_t num_ids) const { for (size_t i = 0; i < num_ids; i++) { diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_location_resolver_manager_impl.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_location_resolver_manager_impl.hpp index 5ddcb34e2..fc169934e 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_location_resolver_manager_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_location_resolver_manager_impl.hpp @@ -23,10 +23,12 @@ namespace ams::lr { class LocationResolverManagerImpl final : public ILocationResolverManager { private: - ncm::BoundedMap, 5> g_location_resolvers; - std::shared_ptr g_registered_location_resolver = nullptr; - std::shared_ptr g_add_on_content_location_resolver = nullptr; - os::Mutex g_mutex; + /* Resolver storage. */ + ncm::BoundedMap, 5> location_resolvers; + std::shared_ptr registered_location_resolver = nullptr; + std::shared_ptr add_on_content_location_resolver = nullptr; + + os::Mutex mutex; public: /* Actual commands. */ virtual Result OpenLocationResolver(sf::Out> out, ncm::StorageId storage_id) override; diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_redirect_only_location_resolver.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_redirect_only_location_resolver.hpp index 7dfb33c46..e272a2275 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_redirect_only_location_resolver.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_redirect_only_location_resolver.hpp @@ -24,6 +24,7 @@ namespace ams::lr { public: ~RedirectOnlyLocationResolverInterface(); public: + /* Actual commands. */ virtual Result ResolveProgramPath(sf::Out out, ncm::ProgramId id) override; virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId id) override; virtual Result ResolveApplicationControlPath(sf::Out out, ncm::ProgramId id) override; diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_registered_data.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_registered_data.hpp index 644ffd4c4..dad3b9e31 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_registered_data.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_registered_data.hpp @@ -35,16 +35,18 @@ namespace ams::lr { size_t capacity; private: inline bool IsExcluded(const ncm::ProgramId id, const ncm::ProgramId* excluding_ids, size_t num_ids) const { + /* Try to find program id in exclusions. */ for (size_t i = 0; i < num_ids; i++) { if (id == excluding_ids[i]) { return true; } } - + return false; } inline void RegisterImpl(size_t i, const Key &key, const Value &value, const ncm::ProgramId owner_id) { + /* Populate entry. */ Entry& entry = this->entries[i]; entry.key = key; entry.value = value; @@ -79,6 +81,7 @@ namespace ams::lr { } void Unregister(const Key &key) { + /* Invalidate entries with a matching key. */ for (size_t i = 0; i < this->GetCapacity(); i++) { Entry& entry = this->entries[i]; if (entry.is_valid && entry.key == key) { @@ -88,6 +91,7 @@ namespace ams::lr { } void UnregisterOwnerProgram(ncm::ProgramId owner_id) { + /* Invalidate entries with a matching owner id. */ for (size_t i = 0; i < this->GetCapacity(); i++) { Entry& entry = this->entries[i]; if (entry.owner_id == owner_id) { @@ -97,6 +101,7 @@ namespace ams::lr { } bool Find(Value *out, const Key &key) const { + /* Locate a matching entry. */ for (size_t i = 0; i < this->GetCapacity(); i++) { const Entry& entry = this->entries[i]; if (entry.is_valid && entry.key == key) { @@ -109,12 +114,14 @@ namespace ams::lr { } void Clear() { + /* Invalidate all entries. */ for (size_t i = 0; i < this->GetCapacity(); i++) { this->entries[i].is_valid = false; } } void ClearExcluding(const ncm::ProgramId* ids, size_t num_ids) { + /* Invalidate all entries unless excluded. */ for (size_t i = 0; i < this->GetCapacity(); i++) { Entry& entry = this->entries[i]; diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_registered_location_resolver.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_registered_location_resolver.hpp index 6332866d5..7e6cf517a 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_registered_location_resolver.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_registered_location_resolver.hpp @@ -42,17 +42,20 @@ namespace ams::lr { RefreshExcluding = 9, }; private: + /* Redirection and registered location storage. */ LocationRedirector program_redirector; RegisteredLocations registered_program_locations; LocationRedirector html_docs_redirector; RegisteredLocations registered_html_docs_locations; private: + /* Helper functions. */ void ClearRedirections(u32 flags = RedirectionFlags_None); Result RefreshImpl(const ncm::ProgramId* excluding_ids, size_t num_ids); public: RegisteredLocationResolverInterface() : registered_program_locations(hos::GetVersion() < hos::Version_900 ? 0x10 : MaxRegisteredLocations), registered_html_docs_locations(hos::GetVersion() < hos::Version_900 ? 0x10 : MaxRegisteredLocations) { /* ... */ } ~RegisteredLocationResolverInterface(); + /* Actual commands. */ Result ResolveProgramPath(sf::Out out, ncm::ProgramId id); Result RegisterProgramPathDeprecated(const Path &path, ncm::ProgramId id); Result RegisterProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id); diff --git a/libraries/libstratosphere/include/stratosphere/lr/lr_types.hpp b/libraries/libstratosphere/include/stratosphere/lr/lr_types.hpp index 894bb538c..bfe6a0792 100644 --- a/libraries/libstratosphere/include/stratosphere/lr/lr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/lr/lr_types.hpp @@ -27,6 +27,7 @@ namespace ams::lr { static constexpr Path Encode(const char *p) { Path path = {}; + /* Copy C string to path, terminating when a null byte is found. */ for (size_t i = 0; i < sizeof(path) - 1; i++) { path.str[i] = p[i]; if (p[i] == '\x00') { @@ -37,6 +38,7 @@ namespace ams::lr { } constexpr inline size_t GetLength() const { + /* Determine length from the first null byte occurence. */ size_t len = 0; for (size_t i = 0; i < sizeof(this->str) - 1 && this->str[i] != '\x00'; i++) { len++; @@ -45,6 +47,7 @@ namespace ams::lr { } constexpr inline bool IsValid() const { + /* Determine validity by presence of a terminating null byte. */ for (size_t i = 0; i < sizeof(this->str); i++) { if (this->str[i] == '\x00') { return true; diff --git a/libraries/libstratosphere/source/lr/lr_add_on_content_location_resolver.cpp b/libraries/libstratosphere/source/lr/lr_add_on_content_location_resolver.cpp index 8324c983f..e102b54d6 100644 --- a/libraries/libstratosphere/source/lr/lr_add_on_content_location_resolver.cpp +++ b/libraries/libstratosphere/source/lr/lr_add_on_content_location_resolver.cpp @@ -26,27 +26,36 @@ namespace ams::ncm::impl { namespace ams::lr { Result AddOnContentLocationResolverInterface::ResolveAddOnContentPath(sf::Out out, ncm::ProgramId id) { + /* Find a storage that contains the given program id. */ ncm::StorageId storage_id = ncm::StorageId::None; R_UNLESS(this->registered_storages.Find(&storage_id, id), lr::ResultAddOnContentNotFound()); + /* Obtain a Content Meta Database for the storage id. */ std::shared_ptr content_meta_database; - ncm::ContentId data_content_id; R_TRY(ncm::impl::OpenContentMetaDatabase(&content_meta_database, storage_id)); + + /* Find the latest data content id for the given program id. */ + ncm::ContentId data_content_id; R_TRY(content_meta_database->GetLatestData(&data_content_id, id)); + /* Obtain a Content Storage for the storage id. */ std::shared_ptr content_storage; R_TRY(ncm::impl::OpenContentStorage(&content_storage, storage_id)); + + /* Get the path of the data content. */ R_ABORT_UNLESS(content_storage->GetPath(out.GetPointer(), data_content_id)); return ResultSuccess(); } Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorageDeprecated(ncm::StorageId storage_id, ncm::ProgramId id) { + /* Register storage for the given program id. 2.0.0-8.1.0 did not require an owner application id. */ R_UNLESS(this->registered_storages.Register(id, storage_id, ncm::ProgramId::Invalid), lr::ResultTooManyRegisteredPaths()); return ResultSuccess(); } Result AddOnContentLocationResolverInterface::RegisterAddOnContentStorage(ncm::StorageId storage_id, ncm::ProgramId id, ncm::ProgramId application_id) { + /* Register storage for the given program id and owner application. */ R_UNLESS(this->registered_storages.Register(id, storage_id, application_id), lr::ResultTooManyRegisteredPaths()); return ResultSuccess(); } @@ -58,8 +67,10 @@ namespace ams::lr { Result AddOnContentLocationResolverInterface::RefreshApplicationAddOnContent(const sf::InArray &ids) { if (ids.GetSize() == 0) { + /* Clear all registered storages. */ this->registered_storages.Clear(); } else { + /* Clear all registered storages excluding the provided program ids. */ this->registered_storages.ClearExcluding(ids.GetPointer(), ids.GetSize()); } @@ -67,6 +78,7 @@ namespace ams::lr { } Result AddOnContentLocationResolverInterface::UnregisterApplicationAddOnContent(ncm::ProgramId id) { + /* Remove entries belonging to the provided application. */ this->registered_storages.UnregisterOwnerProgram(id); return ResultSuccess(); } diff --git a/libraries/libstratosphere/source/lr/lr_content_location_resolver.cpp b/libraries/libstratosphere/source/lr/lr_content_location_resolver.cpp index bb1c0bcc8..91d77979b 100644 --- a/libraries/libstratosphere/source/lr/lr_content_location_resolver.cpp +++ b/libraries/libstratosphere/source/lr/lr_content_location_resolver.cpp @@ -29,19 +29,24 @@ namespace ams::lr { this->ClearRedirections(); } + /* Helper function. */ void ContentLocationResolverInterface::GetContentStoragePath(Path* out, ncm::ContentId content_id) { R_ABORT_UNLESS(this->content_storage->GetPath(out, content_id)); } Result ContentLocationResolverInterface::ResolveProgramPath(sf::Out out, ncm::ProgramId id) { + /* Use a redirection if present. */ R_UNLESS(!this->program_redirector.FindRedirection(out.GetPointer(), id), ResultSuccess()); - ncm::ContentId program_content_id; + /* Find the latest program content for the program id. */ + ncm::ContentId program_content_id; R_TRY_CATCH(this->content_meta_database->GetLatestProgram(&program_content_id, id)) { R_CONVERT(ncm::ResultContentMetaNotFound, lr::ResultProgramNotFound()) } R_END_TRY_CATCH; + /* Obtain the content path. */ this->GetContentStoragePath(out.GetPointer(), program_content_id); + return ResultSuccess(); } @@ -61,10 +66,13 @@ namespace ams::lr { } Result ContentLocationResolverInterface::ResolveDataPath(sf::Out out, ncm::ProgramId id) { + /* Find the latest data content for the program id. */ ncm::ContentId data_content_id; - R_TRY(this->content_meta_database->GetLatestData(&data_content_id, id)); + + /* Obtain the content path. */ this->GetContentStoragePath(out.GetPointer(), data_content_id); + return ResultSuccess(); } @@ -104,14 +112,19 @@ namespace ams::lr { } Result ContentLocationResolverInterface::Refresh() { + /* Obtain Content Meta Database and Content Storage objects for this resolver's storage. */ std::shared_ptr content_meta_database; std::shared_ptr content_storage; - R_TRY(ncm::impl::OpenContentMetaDatabase(&content_meta_database, this->storage_id)); R_TRY(ncm::impl::OpenContentStorage(&content_storage, this->storage_id)); + + /* Store the acquired objects. */ this->content_meta_database = std::move(content_meta_database); this->content_storage = std::move(content_storage); + + /* Remove any existing redirections. */ this->ClearRedirections(); + return ResultSuccess(); } @@ -131,7 +144,7 @@ namespace ams::lr { } Result ContentLocationResolverInterface::ClearApplicationRedirection(const sf::InArray &excluding_ids) { - this->ClearRedirections(excluding_ids.GetPointer(), excluding_ids.GetSize()); + this->ClearRedirectionsExcludingOwners(excluding_ids.GetPointer(), excluding_ids.GetSize()); return ResultSuccess(); } @@ -156,8 +169,10 @@ namespace ams::lr { } Result ContentLocationResolverInterface::ResolveProgramPathForDebug(sf::Out out, ncm::ProgramId id) { + /* Use a redirection if present. */ R_UNLESS(!this->debug_program_redirector.FindRedirection(out.GetPointer(), id), ResultSuccess()); + /* Otherwise find the path for the program id. */ R_TRY_CATCH(this->ResolveProgramPath(out.GetPointer(), id)) { R_CONVERT(ResultProgramNotFound, lr::ResultDebugProgramNotFound()) } R_END_TRY_CATCH; diff --git a/libraries/libstratosphere/source/lr/lr_location_redirector.cpp b/libraries/libstratosphere/source/lr/lr_location_redirector.cpp index 272159cb2..f20db83ca 100644 --- a/libraries/libstratosphere/source/lr/lr_location_redirector.cpp +++ b/libraries/libstratosphere/source/lr/lr_location_redirector.cpp @@ -51,6 +51,7 @@ namespace ams::lr { }; bool LocationRedirector::FindRedirection(Path *out, ncm::ProgramId program_id) const { + /* Obtain the path of a matching redirection. */ for (const auto &redirection : this->redirection_list) { if (redirection.GetProgramId() == program_id) { redirection.GetPath(out); @@ -65,11 +66,15 @@ namespace ams::lr { } void LocationRedirector::SetRedirection(ncm::ProgramId program_id, ncm::ProgramId owner_id, const Path &path, u32 flags) { + /* Remove any existing redirections for this program id. */ this->EraseRedirection(program_id); + + /* Insert a new redirection into the list. */ this->redirection_list.push_back(*(new Redirection(program_id, owner_id, path, flags))); } void LocationRedirector::SetRedirectionFlags(ncm::ProgramId program_id, u32 flags) { + /* Set the flags of a redirection with a matching program id. */ for (auto &redirection : this->redirection_list) { if (redirection.GetProgramId() == program_id) { redirection.SetFlags(flags); @@ -78,7 +83,9 @@ namespace ams::lr { } } - void LocationRedirector::EraseRedirection(ncm::ProgramId program_id) { + void LocationRedirector::EraseRedirection(ncm::ProgramId program_id) + { + /* Remove any redirections with a matching program id. */ for (auto &redirection : this->redirection_list) { if (redirection.GetProgramId() == program_id) { this->redirection_list.erase(this->redirection_list.iterator_to(redirection)); @@ -89,6 +96,7 @@ namespace ams::lr { } void LocationRedirector::ClearRedirections(u32 flags) { + /* Remove anyredirections with matching flags. */ for (auto it = this->redirection_list.begin(); it != this->redirection_list.end();) { if ((it->GetFlags() & flags) == flags) { auto old = it; @@ -100,13 +108,15 @@ namespace ams::lr { } } - void LocationRedirector::ClearRedirections(const ncm::ProgramId* excluding_ids, size_t num_ids) { + void LocationRedirector::ClearRedirectionsExcludingOwners(const ncm::ProgramId* excluding_ids, size_t num_ids) { for (auto it = this->redirection_list.begin(); it != this->redirection_list.end();) { + /* Skip removal if the redirection has an excluded owner program id. */ if (this->IsExcluded(it->GetOwnerProgramId(), excluding_ids, num_ids)) { it++; continue; } + /* Remove the redirection. */ auto old = it; it = this->redirection_list.erase(it); delete std::addressof(*old); diff --git a/libraries/libstratosphere/source/lr/lr_location_resolver_manager_impl.cpp b/libraries/libstratosphere/source/lr/lr_location_resolver_manager_impl.cpp index ec201e2d2..e10043dd4 100644 --- a/libraries/libstratosphere/source/lr/lr_location_resolver_manager_impl.cpp +++ b/libraries/libstratosphere/source/lr/lr_location_resolver_manager_impl.cpp @@ -18,43 +18,52 @@ namespace ams::lr { Result LocationResolverManagerImpl::OpenLocationResolver(sf::Out> out, ncm::StorageId storage_id) { - std::scoped_lock lk(g_mutex); - auto resolver = g_location_resolvers.Find(storage_id); + std::scoped_lock lk(this->mutex); + /* Find an existing resolver. */ + auto resolver = this->location_resolvers.Find(storage_id); + /* No existing resolver is present, create one. */ if (!resolver) { if (storage_id == ncm::StorageId::Host) { - g_location_resolvers[storage_id] = std::make_shared(); + this->location_resolvers[storage_id] = std::make_shared(); } else { auto content_resolver = std::make_shared(storage_id); R_TRY(content_resolver->Refresh()); - g_location_resolvers[storage_id] = std::move(content_resolver); + this->location_resolvers[storage_id] = std::move(content_resolver); } - resolver = g_location_resolvers.Find(storage_id); + + /* Acquire the newly-created resolver. */ + resolver = this->location_resolvers.Find(storage_id); } + /* Copy the output interface. */ std::shared_ptr new_intf = *resolver; out.SetValue(std::move(new_intf)); return ResultSuccess(); } Result LocationResolverManagerImpl::OpenRegisteredLocationResolver(sf::Out> out) { - std::scoped_lock lk(g_mutex); + std::scoped_lock lk(this->mutex); - if (!g_registered_location_resolver) { - g_registered_location_resolver = std::make_shared(); + /* No existing resolver is present, create one. */ + if (!this->registered_location_resolver) { + this->registered_location_resolver = std::make_shared(); } - std::shared_ptr new_intf = g_registered_location_resolver; + /* Copy the output interface. */ + std::shared_ptr new_intf = this->registered_location_resolver; out.SetValue(std::move(new_intf)); return ResultSuccess(); } Result LocationResolverManagerImpl::RefreshLocationResolver(ncm::StorageId storage_id) { - std::scoped_lock lk(g_mutex); - auto resolver = g_location_resolvers.Find(storage_id); + std::scoped_lock lk(this->mutex); + /* Attempt to find an existing resolver. */ + auto resolver = this->location_resolvers.Find(storage_id); R_UNLESS(resolver, lr::ResultUnknownStorageId()); + /* Refresh the resolver. */ if (storage_id != ncm::StorageId::Host) { (*resolver)->Refresh(); } @@ -63,13 +72,15 @@ namespace ams::lr { } Result LocationResolverManagerImpl::OpenAddOnContentLocationResolver(sf::Out> out) { - std::scoped_lock lk(g_mutex); + std::scoped_lock lk(this->mutex); - if (!g_add_on_content_location_resolver) { - g_add_on_content_location_resolver = std::make_shared(); + /* No existing resolver is present, create one. */ + if (!this->add_on_content_location_resolver) { + this->add_on_content_location_resolver = std::make_shared(); } - std::shared_ptr new_intf = g_add_on_content_location_resolver; + /* Copy the output interface. */ + std::shared_ptr new_intf = this->add_on_content_location_resolver; out.SetValue(std::move(new_intf)); return ResultSuccess(); } diff --git a/libraries/libstratosphere/source/lr/lr_redirect_only_location_resolver.cpp b/libraries/libstratosphere/source/lr/lr_redirect_only_location_resolver.cpp index aeb31ae8a..2c4178553 100644 --- a/libraries/libstratosphere/source/lr/lr_redirect_only_location_resolver.cpp +++ b/libraries/libstratosphere/source/lr/lr_redirect_only_location_resolver.cpp @@ -18,6 +18,7 @@ namespace ams::lr { RedirectOnlyLocationResolverInterface::~RedirectOnlyLocationResolverInterface() { + /* Ensure entries are deallocated */ this->ClearRedirections(); } @@ -101,7 +102,7 @@ namespace ams::lr { } Result RedirectOnlyLocationResolverInterface::ClearApplicationRedirection(const sf::InArray &excluding_ids) { - this->ClearRedirections(excluding_ids.GetPointer(), excluding_ids.GetSize()); + this->ClearRedirectionsExcludingOwners(excluding_ids.GetPointer(), excluding_ids.GetSize()); return ResultSuccess(); } @@ -126,8 +127,10 @@ namespace ams::lr { } Result RedirectOnlyLocationResolverInterface::ResolveProgramPathForDebug(sf::Out out, ncm::ProgramId id) { + /* Use a redirection if present. */ R_UNLESS(!this->debug_program_redirector.FindRedirection(out.GetPointer(), id), ResultSuccess()); + /* Otherwise find the path for the program id. */ R_TRY_CATCH(this->ResolveProgramPath(out.GetPointer(), id)) { R_CONVERT(ResultProgramNotFound, lr::ResultDebugProgramNotFound()) } R_END_TRY_CATCH; diff --git a/libraries/libstratosphere/source/lr/lr_registered_location_resolver.cpp b/libraries/libstratosphere/source/lr/lr_registered_location_resolver.cpp index 6f48f24d8..aec8c1267 100644 --- a/libraries/libstratosphere/source/lr/lr_registered_location_resolver.cpp +++ b/libraries/libstratosphere/source/lr/lr_registered_location_resolver.cpp @@ -21,7 +21,9 @@ namespace ams::lr { template bool ResolvePath(Path *out, const LocationRedirector &redirector, const RegisteredLocations &locations, ncm::ProgramId id) { + /* Attempt to use a redirection if present. */ if (!redirector.FindRedirection(out, id)) { + /* Otherwise try and use a registered location. */ if (!locations.Find(out, id)) { return false; } @@ -48,6 +50,7 @@ namespace ams::lr { this->ClearRedirections(); } + /* Helper function. */ void RegisteredLocationResolverInterface::ClearRedirections(u32 flags) { this->html_docs_redirector.ClearRedirections(flags); this->program_redirector.ClearRedirections(flags); @@ -70,8 +73,8 @@ namespace ams::lr { } /* Clear redirectors using exclusion lists. */ - this->program_redirector.ClearRedirections(excluding_ids, num_ids); - this->html_docs_redirector.ClearRedirections(excluding_ids, num_ids); + this->program_redirector.ClearRedirectionsExcludingOwners(excluding_ids, num_ids); + this->html_docs_redirector.ClearRedirectionsExcludingOwners(excluding_ids, num_ids); return ResultSuccess(); }