mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-04-22 12:34:47 +00:00
lr: Add comments
This commit is contained in:
parent
fb44433715
commit
88f9d0ff85
16 changed files with 117 additions and 36 deletions
|
@ -31,10 +31,12 @@ namespace ams::lr {
|
|||
UnregisterApplicationAddOnContent = 4,
|
||||
};
|
||||
private:
|
||||
/* Storage for RegisteredData entries by program id. */
|
||||
RegisteredStorages<ncm::ProgramId, 0x800> registered_storages;
|
||||
public:
|
||||
AddOnContentLocationResolverInterface() : registered_storages(hos::GetVersion() < hos::Version_900 ? 0x800 : 0x2) { /* ... */ }
|
||||
|
||||
/* Actual commands. */
|
||||
virtual Result ResolveAddOnContentPath(sf::Out<Path> 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);
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace ams::lr {
|
|||
class ContentLocationResolverInterface : public ILocationResolverInterface {
|
||||
private:
|
||||
ncm::StorageId storage_id;
|
||||
|
||||
/* Objects for this storage type. */
|
||||
std::shared_ptr<ncm::IContentMetaDatabase> content_meta_database;
|
||||
std::shared_ptr<ncm::IContentStorage> 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<Path> out, ncm::ProgramId id) override;
|
||||
virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId id) override;
|
||||
virtual Result ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId id) override;
|
||||
|
|
|
@ -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<Path> out, ncm::ProgramId id) = 0;
|
||||
virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId id) = 0;
|
||||
virtual Result ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId id) = 0;
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace ams::lr {
|
|||
|
||||
class ILocationResolverInterface : public ILocationResolver {
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId id) = 0;
|
||||
virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId id) = 0;
|
||||
virtual Result ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId id) = 0;
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -23,10 +23,12 @@ namespace ams::lr {
|
|||
|
||||
class LocationResolverManagerImpl final : public ILocationResolverManager {
|
||||
private:
|
||||
ncm::BoundedMap<ncm::StorageId, std::shared_ptr<ILocationResolverInterface>, 5> g_location_resolvers;
|
||||
std::shared_ptr<RegisteredLocationResolverInterface> g_registered_location_resolver = nullptr;
|
||||
std::shared_ptr<AddOnContentLocationResolverInterface> g_add_on_content_location_resolver = nullptr;
|
||||
os::Mutex g_mutex;
|
||||
/* Resolver storage. */
|
||||
ncm::BoundedMap<ncm::StorageId, std::shared_ptr<ILocationResolverInterface>, 5> location_resolvers;
|
||||
std::shared_ptr<RegisteredLocationResolverInterface> registered_location_resolver = nullptr;
|
||||
std::shared_ptr<AddOnContentLocationResolverInterface> add_on_content_location_resolver = nullptr;
|
||||
|
||||
os::Mutex mutex;
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result OpenLocationResolver(sf::Out<std::shared_ptr<ILocationResolverInterface>> out, ncm::StorageId storage_id) override;
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace ams::lr {
|
|||
public:
|
||||
~RedirectOnlyLocationResolverInterface();
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId id) override;
|
||||
virtual Result RedirectProgramPath(const Path &path, ncm::ProgramId id) override;
|
||||
virtual Result ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId id) override;
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -42,17 +42,20 @@ namespace ams::lr {
|
|||
RefreshExcluding = 9,
|
||||
};
|
||||
private:
|
||||
/* Redirection and registered location storage. */
|
||||
LocationRedirector program_redirector;
|
||||
RegisteredLocations<ncm::ProgramId, MaxRegisteredLocations> registered_program_locations;
|
||||
LocationRedirector html_docs_redirector;
|
||||
RegisteredLocations<ncm::ProgramId, MaxRegisteredLocations> 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<Path> out, ncm::ProgramId id);
|
||||
Result RegisterProgramPathDeprecated(const Path &path, ncm::ProgramId id);
|
||||
Result RegisterProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -26,27 +26,36 @@ namespace ams::ncm::impl {
|
|||
namespace ams::lr {
|
||||
|
||||
Result AddOnContentLocationResolverInterface::ResolveAddOnContentPath(sf::Out<Path> 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<ncm::IContentMetaDatabase> 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<ncm::IContentStorage> 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<ncm::ProgramId> &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();
|
||||
}
|
||||
|
|
|
@ -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<Path> 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<Path> 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<ncm::IContentMetaDatabase> content_meta_database;
|
||||
std::shared_ptr<ncm::IContentStorage> 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<ncm::ProgramId> &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<Path> 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -18,43 +18,52 @@
|
|||
namespace ams::lr {
|
||||
|
||||
Result LocationResolverManagerImpl::OpenLocationResolver(sf::Out<std::shared_ptr<ILocationResolverInterface>> 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<RedirectOnlyLocationResolverInterface>();
|
||||
this->location_resolvers[storage_id] = std::make_shared<RedirectOnlyLocationResolverInterface>();
|
||||
} else {
|
||||
auto content_resolver = std::make_shared<ContentLocationResolverInterface>(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<ILocationResolverInterface> new_intf = *resolver;
|
||||
out.SetValue(std::move(new_intf));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result LocationResolverManagerImpl::OpenRegisteredLocationResolver(sf::Out<std::shared_ptr<RegisteredLocationResolverInterface>> 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<RegisteredLocationResolverInterface>();
|
||||
/* No existing resolver is present, create one. */
|
||||
if (!this->registered_location_resolver) {
|
||||
this->registered_location_resolver = std::make_shared<RegisteredLocationResolverInterface>();
|
||||
}
|
||||
|
||||
std::shared_ptr<RegisteredLocationResolverInterface> new_intf = g_registered_location_resolver;
|
||||
/* Copy the output interface. */
|
||||
std::shared_ptr<RegisteredLocationResolverInterface> 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<std::shared_ptr<AddOnContentLocationResolverInterface>> 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<AddOnContentLocationResolverInterface>();
|
||||
/* No existing resolver is present, create one. */
|
||||
if (!this->add_on_content_location_resolver) {
|
||||
this->add_on_content_location_resolver = std::make_shared<AddOnContentLocationResolverInterface>();
|
||||
}
|
||||
|
||||
std::shared_ptr<AddOnContentLocationResolverInterface> new_intf = g_add_on_content_location_resolver;
|
||||
/* Copy the output interface. */
|
||||
std::shared_ptr<AddOnContentLocationResolverInterface> new_intf = this->add_on_content_location_resolver;
|
||||
out.SetValue(std::move(new_intf));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
|
|
@ -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<ncm::ProgramId> &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<Path> 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;
|
||||
|
|
|
@ -21,7 +21,9 @@ namespace ams::lr {
|
|||
|
||||
template<size_t N>
|
||||
bool ResolvePath(Path *out, const LocationRedirector &redirector, const RegisteredLocations<ncm::ProgramId, N> &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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue