mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
ncm: update for new add on content/attr changes
This commit is contained in:
parent
ef07964ea0
commit
427130a122
14 changed files with 290 additions and 143 deletions
|
@ -17,12 +17,16 @@
|
|||
#pragma once
|
||||
#include <stratosphere/lr/lr_types.hpp>
|
||||
|
||||
#define AMS_LR_I_ADD_ON_CONTENT_LOCATION_RESOLVER_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, ResolveAddOnContentPath, (sf::Out<lr::Path> out, ncm::DataId id), (out, id), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, RegisterAddOnContentStorageDeprecated, (ncm::DataId id, ncm::StorageId storage_id), (id, storage_id), hos::Version_2_0_0, hos::Version_8_1_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, RegisterAddOnContentStorage, (ncm::DataId id, ncm::ApplicationId application_id, ncm::StorageId storage_id), (id, application_id, storage_id), hos::Version_9_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, UnregisterAllAddOnContentPath, (), (), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, RefreshApplicationAddOnContent, (const sf::InArray<ncm::ApplicationId> &ids), (ids), hos::Version_9_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, UnregisterApplicationAddOnContent, (ncm::ApplicationId id), (id), hos::Version_9_0_0)
|
||||
#define AMS_LR_I_ADD_ON_CONTENT_LOCATION_RESOLVER_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, ResolveAddOnContentPath, (sf::Out<lr::Path> out, ncm::DataId id), (out, id), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, RegisterAddOnContentStorageDeprecated, (ncm::DataId id, ncm::StorageId storage_id), (id, storage_id), hos::Version_2_0_0, hos::Version_8_1_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, RegisterAddOnContentStorage, (ncm::DataId id, ncm::ApplicationId application_id, ncm::StorageId storage_id), (id, application_id, storage_id), hos::Version_9_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, UnregisterAllAddOnContentPath, (), (), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, RefreshApplicationAddOnContent, (const sf::InArray<ncm::ApplicationId> &ids), (ids), hos::Version_9_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, UnregisterApplicationAddOnContent, (ncm::ApplicationId id), (id), hos::Version_9_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, GetRegisteredAddOnContentPaths, (sf::Out<lr::Path> out, sf::Out<lr::Path> out2, ncm::DataId id), (out, out2, id), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, RegisterAddOnContentPath, (ncm::DataId id, ncm::ApplicationId application_id, const lr::Path &path), (id, application_id, path), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, RegisterAddOnContentPaths, (ncm::DataId id, ncm::ApplicationId application_id, const lr::Path &path, const lr::Path &path2), (id, application_id, path, path2), hos::Version_15_0_0)
|
||||
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::lr, IAddOnContentLocationResolver, AMS_LR_I_ADD_ON_CONTENT_LOCATION_RESOLVER_INTERFACE_INFO, 0x77617E39)
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <stratosphere/ncm/ncm_program_location.hpp>
|
||||
#include <stratosphere/ncm/ncm_auto_buffer.hpp>
|
||||
#include <stratosphere/ncm/ncm_make_path.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_attributes.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_id_utils.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_info_utils.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta.hpp>
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/fs/fs_content_attributes.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
/* TODO: What is this struct, really? It is presumably not ContentAttributes/has more fields. */
|
||||
struct ContentAttributes {
|
||||
fs::ContentAttributes content_attributes;
|
||||
u8 unknown[0xF];
|
||||
|
||||
static constexpr ALWAYS_INLINE ContentAttributes Make(fs::ContentAttributes attr) {
|
||||
return { attr, };
|
||||
}
|
||||
};
|
||||
static_assert(util::is_pod<ContentAttributes>::value);
|
||||
static_assert(sizeof(ContentAttributes) == 0x10);
|
||||
|
||||
constexpr inline const ContentAttributes DefaultContentAttributes = ContentAttributes::Make(fs::ContentAttributes_None);
|
||||
|
||||
}
|
|
@ -18,28 +18,60 @@
|
|||
|
||||
namespace ams::lr {
|
||||
|
||||
Result AddOnContentLocationResolverImpl::ResolveAddOnContentPath(sf::Out<Path> out, ncm::DataId id) {
|
||||
/* Find a storage that contains the given program id. */
|
||||
ncm::StorageId storage_id = ncm::StorageId::None;
|
||||
R_UNLESS(m_registered_storages.Find(std::addressof(storage_id), id), lr::ResultAddOnContentNotFound());
|
||||
namespace {
|
||||
|
||||
/* Obtain a content meta database for the storage id. */
|
||||
ncm::ContentMetaDatabase content_meta_database;
|
||||
R_TRY(ncm::OpenContentMetaDatabase(std::addressof(content_meta_database), storage_id));
|
||||
constexpr const lr::Path EmptyPath = {};
|
||||
|
||||
/* Find the latest data content id for the given program id. */
|
||||
ncm::ContentId data_content_id;
|
||||
R_TRY(content_meta_database.GetLatestData(std::addressof(data_content_id), id));
|
||||
template<size_t N>
|
||||
Result ResolveAddOnContentPathImpl(Path *out, RedirectionAttributes *out_attr, const RegisteredStorages<ncm::DataId, N> &storages, ncm::DataId id) {
|
||||
/* Find a storage that contains the given program id. */
|
||||
ncm::StorageId storage_id = ncm::StorageId::None;
|
||||
R_UNLESS(storages.Find(std::addressof(storage_id), id), lr::ResultAddOnContentNotFound());
|
||||
|
||||
/* Obtain a content storage for the storage id. */
|
||||
ncm::ContentStorage content_storage;
|
||||
R_TRY(ncm::OpenContentStorage(std::addressof(content_storage), storage_id));
|
||||
/* Obtain a content meta database for the storage id. */
|
||||
ncm::ContentMetaDatabase content_meta_database;
|
||||
R_TRY(ncm::OpenContentMetaDatabase(std::addressof(content_meta_database), storage_id));
|
||||
|
||||
/* Get the path of the data content. */
|
||||
static_assert(sizeof(lr::Path) == sizeof(ncm::Path));
|
||||
content_storage.GetPath(reinterpret_cast<ncm::Path *>(out.GetPointer()), data_content_id);
|
||||
/* Find the latest data content info for the given program id. */
|
||||
ncm::ContentInfo data_content_info;
|
||||
R_TRY(content_meta_database.GetLatestData(std::addressof(data_content_info), id));
|
||||
|
||||
/* Obtain a content storage for the storage id. */
|
||||
ncm::ContentStorage content_storage;
|
||||
R_TRY(ncm::OpenContentStorage(std::addressof(content_storage), storage_id));
|
||||
|
||||
/* Get the path of the data content. */
|
||||
static_assert(sizeof(lr::Path) == sizeof(ncm::Path));
|
||||
content_storage.GetPath(reinterpret_cast<ncm::Path *>(out), data_content_info.GetId());
|
||||
|
||||
/* Get the redirection attributes. */
|
||||
*out_attr = RedirectionAttributes::Make(data_content_info.GetContentAttributes());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::ResolveAddOnContentPath(Path *out, RedirectionAttributes *out_attr, ncm::DataId id) {
|
||||
/* Try to resolve using our registered storages. */
|
||||
if (const auto result = ResolveAddOnContentPathImpl(out, out_attr, m_registered_storages, id); R_SUCCEEDED(result) || !lr::ResultAddOnContentNotFound::Includes(result)) {
|
||||
R_RETURN(result);
|
||||
}
|
||||
|
||||
/* If we failed to find the add-on content by storage, we should check if there's a registered path. */
|
||||
auto * const found = m_registered_paths.Find(id);
|
||||
R_UNLESS(found != nullptr, lr::ResultAddOnContentNotFound());
|
||||
|
||||
/* Set the output path. */
|
||||
*out = found->redir_path.path;
|
||||
*out_attr = found->redir_path.attributes;
|
||||
R_SUCCEED();
|
||||
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::ResolveAddOnContentPath(sf::Out<Path> out, ncm::DataId id) {
|
||||
RedirectionAttributes attr;
|
||||
R_RETURN(this->ResolveAddOnContentPath(out.GetPointer(), std::addressof(attr), id));
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::RegisterAddOnContentStorageDeprecated(ncm::DataId id, ncm::StorageId storage_id) {
|
||||
|
@ -56,17 +88,27 @@ namespace ams::lr {
|
|||
|
||||
Result AddOnContentLocationResolverImpl::UnregisterAllAddOnContentPath() {
|
||||
m_registered_storages.Clear();
|
||||
m_registered_paths.RemoveAll();
|
||||
m_registered_other_paths.RemoveAll();
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::RefreshApplicationAddOnContent(const sf::InArray<ncm::ApplicationId> &ids) {
|
||||
if (ids.GetSize() == 0) {
|
||||
/* Clear all registered storages. */
|
||||
m_registered_storages.Clear();
|
||||
} else {
|
||||
/* Clear all registered storages excluding the provided program ids. */
|
||||
m_registered_storages.ClearExcluding(reinterpret_cast<const ncm::ProgramId *>(ids.GetPointer()), ids.GetSize());
|
||||
}
|
||||
/* Clear all registered storages excluding the provided program ids. */
|
||||
m_registered_storages.ClearExcluding(reinterpret_cast<const ncm::ProgramId *>(ids.GetPointer()), ids.GetSize());
|
||||
|
||||
auto ShouldRefresh = [&ids](const ncm::DataId &, const OwnedPath &owned_path) {
|
||||
for (size_t i = 0; i < ids.GetSize(); ++i) {
|
||||
if (owned_path.owner_id == ids[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
m_registered_paths.RemoveIf(ShouldRefresh);
|
||||
m_registered_other_paths.RemoveIf(ShouldRefresh);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
@ -74,6 +116,77 @@ namespace ams::lr {
|
|||
Result AddOnContentLocationResolverImpl::UnregisterApplicationAddOnContent(ncm::ApplicationId id) {
|
||||
/* Remove entries belonging to the provided application. */
|
||||
m_registered_storages.UnregisterOwnerProgram(id);
|
||||
|
||||
auto ShouldRefresh = [&id](const ncm::DataId &, const OwnedPath &owned_path) {
|
||||
return owned_path.owner_id == id;
|
||||
};
|
||||
|
||||
m_registered_paths.RemoveIf(ShouldRefresh);
|
||||
m_registered_other_paths.RemoveIf(ShouldRefresh);
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::GetRegisteredAddOnContentPaths(Path *out, RedirectionAttributes *out_attr, Path *out2, RedirectionAttributes *out_attr2, ncm::DataId id) {
|
||||
/* Find a registered path. */
|
||||
auto * const found = m_registered_paths.Find(id);
|
||||
if (found == nullptr) {
|
||||
/* We have no registered path, so perform a normal resolution. */
|
||||
R_TRY(ResolveAddOnContentPathImpl(out, out_attr, m_registered_storages, id));
|
||||
|
||||
/* Clear the second output path. */
|
||||
*out2 = {};
|
||||
*out_attr2 = {};
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
/* Set the output path. */
|
||||
*out = found->redir_path.path;
|
||||
*out_attr = found->redir_path.attributes;
|
||||
|
||||
/* If we have a second path, set it to output. */
|
||||
if (auto * const found2 = m_registered_other_paths.Find(id); found2 != nullptr) {
|
||||
*out2 = found2->redir_path.path;
|
||||
*out_attr2 = found2->redir_path.attributes;
|
||||
} else {
|
||||
*out2 = {};
|
||||
*out_attr2 = {};
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::GetRegisteredAddOnContentPaths(sf::Out<Path> out, sf::Out<Path> out2, ncm::DataId id) {
|
||||
RedirectionAttributes attr, attr2;
|
||||
R_RETURN(this->GetRegisteredAddOnContentPaths(out.GetPointer(), std::addressof(attr), out2.GetPointer(), std::addressof(attr2), id));
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::RegisterAddOnContentPath(ncm::DataId id, ncm::ApplicationId application_id, const lr::Path &path) {
|
||||
R_RETURN(this->RegisterAddOnContentPaths(id, application_id, path, DefaultRedirectionAttributes, EmptyPath, DefaultRedirectionAttributes));
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::RegisterAddOnContentPaths(ncm::DataId id, ncm::ApplicationId application_id, const lr::Path &path, const lr::Path &path2) {
|
||||
R_RETURN(this->RegisterAddOnContentPaths(id, application_id, path, DefaultRedirectionAttributes, path2, DefaultRedirectionAttributes));
|
||||
}
|
||||
|
||||
Result AddOnContentLocationResolverImpl::RegisterAddOnContentPaths(ncm::DataId id, ncm::ApplicationId application_id, const Path &path, const RedirectionAttributes &attr, const Path &path2, const RedirectionAttributes &attr2) {
|
||||
/* Check that it's possible for us to register the path. */
|
||||
/* NOTE: This check is technically incorrect, if the id is already registered. */
|
||||
R_UNLESS(!m_registered_paths.IsFull(), lr::ResultTooManyRegisteredPaths());
|
||||
|
||||
/* Check that the input path isn't empty. */
|
||||
R_UNLESS(path.str[0] != '\x00', lr::ResultInvalidPath());
|
||||
|
||||
/* Insert the path. */
|
||||
m_registered_paths.InsertOrAssign(id, OwnedPath{ { path, attr }, application_id });
|
||||
|
||||
/* If we have a second path, insert it. */
|
||||
if (path2.str[0] != '\x00') {
|
||||
m_registered_other_paths.InsertOrAssign(id, OwnedPath { { path2, attr2 }, application_id });
|
||||
} else {
|
||||
m_registered_other_paths.Remove(id);
|
||||
}
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,16 @@
|
|||
namespace ams::lr {
|
||||
|
||||
class AddOnContentLocationResolverImpl {
|
||||
private:
|
||||
struct OwnedPath {
|
||||
RedirectionPath redir_path;
|
||||
ncm::ApplicationId owner_id;
|
||||
};
|
||||
private:
|
||||
/* Storage for RegisteredData entries by data id. */
|
||||
RegisteredStorages<ncm::DataId, 0x800> m_registered_storages;
|
||||
ncm::BoundedMap<ncm::DataId, OwnedPath, 8> m_registered_paths;
|
||||
ncm::BoundedMap<ncm::DataId, OwnedPath, 8> m_registered_other_paths;
|
||||
private:
|
||||
static ALWAYS_INLINE size_t GetStorageCapacity() {
|
||||
const auto version = hos::GetVersion();
|
||||
|
@ -37,7 +44,7 @@ namespace ams::lr {
|
|||
}
|
||||
}
|
||||
public:
|
||||
AddOnContentLocationResolverImpl() : m_registered_storages(GetStorageCapacity()) { /* ... */ }
|
||||
AddOnContentLocationResolverImpl() : m_registered_storages(GetStorageCapacity()), m_registered_paths{}, m_registered_other_paths{} { /* ... */ }
|
||||
|
||||
/* Actual commands. */
|
||||
Result ResolveAddOnContentPath(sf::Out<Path> out, ncm::DataId id);
|
||||
|
@ -46,6 +53,13 @@ namespace ams::lr {
|
|||
Result UnregisterAllAddOnContentPath();
|
||||
Result RefreshApplicationAddOnContent(const sf::InArray<ncm::ApplicationId> &ids);
|
||||
Result UnregisterApplicationAddOnContent(ncm::ApplicationId id);
|
||||
Result GetRegisteredAddOnContentPaths(sf::Out<Path> out, sf::Out<Path> out2, ncm::DataId id);
|
||||
Result RegisterAddOnContentPath(ncm::DataId id, ncm::ApplicationId application_id, const Path &path);
|
||||
Result RegisterAddOnContentPaths(ncm::DataId id, ncm::ApplicationId application_id, const Path &path, const Path &path2);
|
||||
private:
|
||||
Result ResolveAddOnContentPath(Path *out, RedirectionAttributes *out_attr, ncm::DataId id);
|
||||
Result GetRegisteredAddOnContentPaths(Path *out, RedirectionAttributes *out_attr, Path *out2, RedirectionAttributes *out_attr2, ncm::DataId id);
|
||||
Result RegisterAddOnContentPaths(ncm::DataId id, ncm::ApplicationId application_id, const Path &path, const RedirectionAttributes &attr, const Path &path2, const RedirectionAttributes &attr2);
|
||||
};
|
||||
static_assert(lr::IsIAddOnContentLocationResolver<AddOnContentLocationResolverImpl>);
|
||||
|
||||
|
|
|
@ -28,37 +28,45 @@ namespace ams::lr {
|
|||
m_content_storage.GetPath(reinterpret_cast<ncm::Path *>(out), content_id);
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
Result ContentLocationResolverImpl::ResolveProgramPath(Path *out, RedirectionAttributes *out_attr, ncm::ProgramId id) {
|
||||
/* Use a redirection if present. */
|
||||
R_SUCCEED_IF(m_program_redirector.FindRedirection(out.GetPointer(), id));
|
||||
R_SUCCEED_IF(m_program_redirector.FindRedirection(out, out_attr, id));
|
||||
|
||||
/* If we're not enabled, we can't resolve a program. */
|
||||
R_UNLESS(m_enabled, lr::ResultProgramNotFound())
|
||||
|
||||
/* Find the latest program content for the program id. */
|
||||
ncm::ContentId program_content_id;
|
||||
R_TRY_CATCH(m_content_meta_database.GetLatestProgram(std::addressof(program_content_id), id)) {
|
||||
ncm::ContentInfo program_content_info;
|
||||
R_TRY_CATCH(m_content_meta_database.GetLatestProgram(std::addressof(program_content_info), id)) {
|
||||
R_CONVERT(ncm::ResultContentMetaNotFound, lr::ResultProgramNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
/* Obtain the content path. */
|
||||
this->GetContentStoragePath(out.GetPointer(), program_content_id);
|
||||
/* Obtain the content path and attributes. */
|
||||
this->GetContentStoragePath(out, program_content_info.GetId());
|
||||
*out_attr = RedirectionAttributes::Make(program_content_info.GetContentAttributes());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
RedirectionAttributes attr;
|
||||
R_RETURN(this->ResolveProgramPath(out.GetPointer(), std::addressof(attr), id));
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectProgramPath(const Path &path, ncm::ProgramId id) {
|
||||
m_program_redirector.SetRedirection(id, path);
|
||||
m_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
R_UNLESS(m_app_control_redirector.FindRedirection(out.GetPointer(), id), lr::ResultControlNotFound());
|
||||
RedirectionAttributes attr;
|
||||
R_UNLESS(m_app_control_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id), lr::ResultControlNotFound());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
R_UNLESS(m_html_docs_redirector.FindRedirection(out.GetPointer(), id), lr::ResultHtmlDocumentNotFound());
|
||||
RedirectionAttributes attr;
|
||||
R_UNLESS(m_html_docs_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id), lr::ResultHtmlDocumentNotFound());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
@ -66,48 +74,49 @@ namespace ams::lr {
|
|||
/* If we're not enabled, we can't resolve data. */
|
||||
R_UNLESS(m_enabled, lr::ResultDataNotFound())
|
||||
|
||||
/* Find the latest data content for the program id. */
|
||||
ncm::ContentId data_content_id;
|
||||
R_TRY(m_content_meta_database.GetLatestData(std::addressof(data_content_id), id));
|
||||
/* Find the latest data content info for the program id. */
|
||||
ncm::ContentInfo data_content_info;
|
||||
R_TRY(m_content_meta_database.GetLatestData(std::addressof(data_content_info), id));
|
||||
|
||||
/* Obtain the content path. */
|
||||
this->GetContentStoragePath(out.GetPointer(), data_content_id);
|
||||
this->GetContentStoragePath(out.GetPointer(), data_content_info.GetId());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_app_control_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_app_control_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationControlPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_app_control_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_app_control_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_html_docs_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_html_docs_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_html_docs_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_html_docs_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
R_UNLESS(m_legal_info_redirector.FindRedirection(out.GetPointer(), id), lr::ResultLegalInformationNotFound());
|
||||
RedirectionAttributes attr;
|
||||
R_UNLESS(m_legal_info_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id), lr::ResultLegalInformationNotFound());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_legal_info_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_legal_info_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_legal_info_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_legal_info_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
@ -129,12 +138,12 @@ namespace ams::lr {
|
|||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_program_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_program_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_program_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
@ -170,13 +179,14 @@ namespace ams::lr {
|
|||
|
||||
Result ContentLocationResolverImpl::ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
/* Use a redirection if present. */
|
||||
R_SUCCEED_IF(m_debug_program_redirector.FindRedirection(out.GetPointer(), id));
|
||||
RedirectionAttributes attr;
|
||||
R_SUCCEED_IF(m_debug_program_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id));
|
||||
|
||||
/* If we're not enabled, we can't resolve a program. */
|
||||
R_UNLESS(m_enabled, lr::ResultDebugProgramNotFound())
|
||||
|
||||
/* Otherwise find the path for the program id. */
|
||||
R_TRY_CATCH(this->ResolveProgramPath(out.GetPointer(), id)) {
|
||||
R_TRY_CATCH(this->ResolveProgramPath(out.GetPointer(), std::addressof(attr), id)) {
|
||||
R_CONVERT(lr::ResultProgramNotFound, lr::ResultDebugProgramNotFound())
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
|
@ -184,17 +194,17 @@ namespace ams::lr {
|
|||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectProgramPathForDebug(const Path &path, ncm::ProgramId id) {
|
||||
m_debug_program_redirector.SetRedirection(id, path);
|
||||
m_debug_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_debug_program_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_debug_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result ContentLocationResolverImpl::RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_debug_program_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_debug_program_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#pragma once
|
||||
#include "lr_location_resolver_impl_base.hpp"
|
||||
#include "lr_location_redirector.hpp"
|
||||
|
||||
namespace ams::lr {
|
||||
|
||||
|
@ -34,6 +35,7 @@ namespace ams::lr {
|
|||
private:
|
||||
/* Helper functions. */
|
||||
void GetContentStoragePath(Path *out, ncm::ContentId content_id);
|
||||
Result ResolveProgramPath(Path *out, RedirectionAttributes *out_attr, ncm::ProgramId id);
|
||||
public:
|
||||
/* Actual commands. */
|
||||
Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId id);
|
||||
|
|
|
@ -25,10 +25,11 @@ namespace ams::lr {
|
|||
ncm::ProgramId m_program_id;
|
||||
ncm::ProgramId m_owner_id;
|
||||
Path m_path;
|
||||
RedirectionAttributes m_attr;
|
||||
u32 m_flags;
|
||||
public:
|
||||
Redirection(ncm::ProgramId program_id, ncm::ProgramId owner_id, const Path &path, u32 flags) :
|
||||
m_program_id(program_id), m_owner_id(owner_id), m_path(path), m_flags(flags) { /* ... */ }
|
||||
Redirection(ncm::ProgramId program_id, ncm::ProgramId owner_id, const Path &path, const RedirectionAttributes &attr, u32 flags) :
|
||||
m_program_id(program_id), m_owner_id(owner_id), m_path(path), m_attr(attr), m_flags(flags) { /* ... */ }
|
||||
|
||||
ncm::ProgramId GetProgramId() const {
|
||||
return m_program_id;
|
||||
|
@ -42,6 +43,10 @@ namespace ams::lr {
|
|||
*out = m_path;
|
||||
}
|
||||
|
||||
void GetAttributes(RedirectionAttributes *out) const {
|
||||
*out = m_attr;
|
||||
}
|
||||
|
||||
u32 GetFlags() const {
|
||||
return m_flags;
|
||||
}
|
||||
|
@ -51,37 +56,28 @@ namespace ams::lr {
|
|||
}
|
||||
};
|
||||
|
||||
bool LocationRedirector::FindRedirection(Path *out, ncm::ProgramId program_id) const {
|
||||
bool LocationRedirector::FindRedirection(Path *out, RedirectionAttributes *out_attr, ncm::ProgramId program_id) const {
|
||||
/* Obtain the path of a matching redirection. */
|
||||
for (const auto &redirection : m_redirection_list) {
|
||||
if (redirection.GetProgramId() == program_id) {
|
||||
redirection.GetPath(out);
|
||||
redirection.GetAttributes(out_attr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LocationRedirector::SetRedirection(ncm::ProgramId program_id, const Path &path, u32 flags) {
|
||||
this->SetRedirection(program_id, ncm::InvalidProgramId, path, flags);
|
||||
void LocationRedirector::SetRedirection(ncm::ProgramId program_id, const Path &path, const RedirectionAttributes &attr, u32 flags) {
|
||||
this->SetRedirection(program_id, ncm::InvalidProgramId, path, attr, flags);
|
||||
}
|
||||
|
||||
void LocationRedirector::SetRedirection(ncm::ProgramId program_id, ncm::ProgramId owner_id, const Path &path, u32 flags) {
|
||||
void LocationRedirector::SetRedirection(ncm::ProgramId program_id, ncm::ProgramId owner_id, const Path &path, const RedirectionAttributes &attr, u32 flags) {
|
||||
/* Remove any existing redirections for this program id. */
|
||||
this->EraseRedirection(program_id);
|
||||
|
||||
/* Insert a new redirection into the list. */
|
||||
m_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 : m_redirection_list) {
|
||||
if (redirection.GetProgramId() == program_id) {
|
||||
redirection.SetFlags(flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_redirection_list.push_back(*(new Redirection(program_id, owner_id, path, attr, flags)));
|
||||
}
|
||||
|
||||
void LocationRedirector::EraseRedirection(ncm::ProgramId program_id) {
|
||||
|
|
|
@ -24,6 +24,27 @@ namespace ams::lr {
|
|||
RedirectionFlags_Application = (1 << 0),
|
||||
};
|
||||
|
||||
/* TODO: Do any of these unknown fields exist? */
|
||||
struct RedirectionAttributes {
|
||||
fs::ContentAttributes content_attributes;
|
||||
u8 unknown[0xF];
|
||||
|
||||
static constexpr ALWAYS_INLINE RedirectionAttributes Make(fs::ContentAttributes attr) {
|
||||
return { attr, };
|
||||
}
|
||||
};
|
||||
static_assert(util::is_pod<RedirectionAttributes>::value);
|
||||
static_assert(sizeof(RedirectionAttributes) == 0x10);
|
||||
|
||||
constexpr inline const RedirectionAttributes DefaultRedirectionAttributes = RedirectionAttributes::Make(fs::ContentAttributes_None);
|
||||
|
||||
struct RedirectionPath {
|
||||
Path path;
|
||||
RedirectionAttributes attributes;
|
||||
};
|
||||
static_assert(util::is_pod<RedirectionPath>::value);
|
||||
static_assert(sizeof(RedirectionPath) == 0x310);
|
||||
|
||||
class LocationRedirector {
|
||||
NON_COPYABLE(LocationRedirector);
|
||||
NON_MOVEABLE(LocationRedirector);
|
||||
|
@ -38,10 +59,9 @@ namespace ams::lr {
|
|||
~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);
|
||||
bool FindRedirection(Path *out, RedirectionAttributes *out_attr, ncm::ProgramId program_id) const;
|
||||
void SetRedirection(ncm::ProgramId program_id, const Path &path, const RedirectionAttributes &attr, u32 flags = RedirectionFlags_None);
|
||||
void SetRedirection(ncm::ProgramId program_id, ncm::ProgramId owner_id, const Path &path, const RedirectionAttributes &attr, u32 flags = RedirectionFlags_None);
|
||||
void EraseRedirection(ncm::ProgramId program_id);
|
||||
void ClearRedirections(u32 flags = RedirectionFlags_None);
|
||||
void ClearRedirectionsExcludingOwners(const ncm::ProgramId *excluding_ids, size_t num_ids);
|
||||
|
|
|
@ -24,22 +24,25 @@ namespace ams::lr {
|
|||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
R_UNLESS(m_program_redirector.FindRedirection(out.GetPointer(), id), lr::ResultProgramNotFound());
|
||||
RedirectionAttributes attr;
|
||||
R_UNLESS(m_program_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id), lr::ResultProgramNotFound());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectProgramPath(const Path &path, ncm::ProgramId id) {
|
||||
m_program_redirector.SetRedirection(id, path);
|
||||
m_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
R_UNLESS(m_app_control_redirector.FindRedirection(out.GetPointer(), id), lr::ResultControlNotFound());
|
||||
RedirectionAttributes attr;
|
||||
R_UNLESS(m_app_control_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id), lr::ResultControlNotFound());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
R_UNLESS(m_html_docs_redirector.FindRedirection(out.GetPointer(), id), lr::ResultHtmlDocumentNotFound());
|
||||
RedirectionAttributes attr;
|
||||
R_UNLESS(m_html_docs_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id), lr::ResultHtmlDocumentNotFound());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
@ -49,37 +52,38 @@ namespace ams::lr {
|
|||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_app_control_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_app_control_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationControlPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_app_control_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_app_control_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_html_docs_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_html_docs_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_html_docs_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_html_docs_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
R_UNLESS(m_legal_info_redirector.FindRedirection(out.GetPointer(), id), lr::ResultLegalInformationNotFound());
|
||||
RedirectionAttributes attr;
|
||||
R_UNLESS(m_legal_info_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id), lr::ResultLegalInformationNotFound());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_legal_info_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_legal_info_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_legal_info_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_legal_info_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
@ -89,12 +93,12 @@ namespace ams::lr {
|
|||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_program_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_program_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_program_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
@ -130,26 +134,27 @@ namespace ams::lr {
|
|||
|
||||
Result RedirectOnlyLocationResolverImpl::ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId id) {
|
||||
/* If a debug program redirection is present, use it. */
|
||||
R_SUCCEED_IF(m_debug_program_redirector.FindRedirection(out.GetPointer(), id));
|
||||
RedirectionAttributes attr;
|
||||
R_SUCCEED_IF(m_debug_program_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id));
|
||||
|
||||
/* Otherwise, try to find a normal program redirection. */
|
||||
R_UNLESS(m_program_redirector.FindRedirection(out.GetPointer(), id), lr::ResultDebugProgramNotFound());
|
||||
R_UNLESS(m_program_redirector.FindRedirection(out.GetPointer(), std::addressof(attr), id), lr::ResultDebugProgramNotFound());
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectProgramPathForDebug(const Path &path, ncm::ProgramId id) {
|
||||
m_debug_program_redirector.SetRedirection(id, path);
|
||||
m_debug_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_debug_program_redirector.SetRedirection(id, path, RedirectionFlags_Application);
|
||||
m_debug_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_debug_program_redirector.SetRedirection(id, owner_id, path, RedirectionFlags_Application);
|
||||
m_debug_program_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes, RedirectionFlags_Application);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#pragma once
|
||||
#include <stratosphere/lr/lr_types.hpp>
|
||||
#include "lr_location_redirector.hpp"
|
||||
|
||||
namespace ams::lr {
|
||||
|
||||
|
@ -137,7 +138,7 @@ namespace ams::lr {
|
|||
};
|
||||
|
||||
template<typename Key, size_t NumEntries>
|
||||
using RegisteredLocations = RegisteredData<Key, lr::Path, NumEntries>;
|
||||
using RegisteredLocations = RegisteredData<Key, RedirectionPath, NumEntries>;
|
||||
|
||||
template<typename Key, size_t NumEntries>
|
||||
using RegisteredStorages = RegisteredData<Key, ncm::StorageId, NumEntries>;
|
||||
|
|
|
@ -23,25 +23,33 @@ 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)) {
|
||||
RedirectionAttributes attr;
|
||||
if (!redirector.FindRedirection(out, std::addressof(attr), id)) {
|
||||
/* Otherwise try and use a registered location. */
|
||||
if (!locations.Find(out, id)) {
|
||||
RedirectionPath redir_path;
|
||||
if (!locations.Find(std::addressof(redir_path), id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set the output path. */
|
||||
*out = redir_path.path;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
void RegisterPath(RegisteredLocations<ncm::ProgramId, N> &locations, ncm::ProgramId id, const Path& path, ncm::ProgramId owner_id) {
|
||||
/* Create a redirection path. */
|
||||
const RedirectionPath redir_path = { path, DefaultRedirectionAttributes };
|
||||
|
||||
/* If we register successfully, we're good. */
|
||||
if (locations.Register(id, path, owner_id)) {
|
||||
if (locations.Register(id, redir_path, owner_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, clear and register (this should always succeed). */
|
||||
locations.Clear();
|
||||
locations.Register(id, path, owner_id);
|
||||
locations.Register(id, redir_path, owner_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -100,12 +108,12 @@ namespace ams::lr {
|
|||
}
|
||||
|
||||
Result RegisteredLocationResolverImpl::RedirectProgramPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_program_redirector.SetRedirection(id, path);
|
||||
m_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RegisteredLocationResolverImpl::RedirectProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_program_redirector.SetRedirection(id, owner_id, path);
|
||||
m_program_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
@ -130,12 +138,12 @@ namespace ams::lr {
|
|||
}
|
||||
|
||||
Result RegisteredLocationResolverImpl::RedirectHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||
m_html_docs_redirector.SetRedirection(id, path);
|
||||
m_html_docs_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result RegisteredLocationResolverImpl::RedirectHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
||||
m_html_docs_redirector.SetRedirection(id, owner_id, path);
|
||||
m_html_docs_redirector.SetRedirection(id, owner_id, path, DefaultRedirectionAttributes);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,4 +32,6 @@ namespace ams::lr {
|
|||
|
||||
R_DEFINE_ERROR_RESULT(TooManyRegisteredPaths, 90);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidPath, 140);
|
||||
|
||||
}
|
||||
|
|
|
@ -134,6 +134,15 @@ namespace ams::util {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void RemoveIf(F f) {
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (m_keys[i] && f(m_keys[i].value(), GetReference(m_values[i]))) {
|
||||
this->FreeEntry(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue