mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-03 19:14:44 +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
|
@ -23,6 +23,10 @@
|
||||||
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, 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, 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, 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, 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)
|
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_program_location.hpp>
|
||||||
#include <stratosphere/ncm/ncm_auto_buffer.hpp>
|
#include <stratosphere/ncm/ncm_auto_buffer.hpp>
|
||||||
#include <stratosphere/ncm/ncm_make_path.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_id_utils.hpp>
|
||||||
#include <stratosphere/ncm/ncm_content_info_utils.hpp>
|
#include <stratosphere/ncm/ncm_content_info_utils.hpp>
|
||||||
#include <stratosphere/ncm/ncm_content_meta.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,18 +18,23 @@
|
||||||
|
|
||||||
namespace ams::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
Result AddOnContentLocationResolverImpl::ResolveAddOnContentPath(sf::Out<Path> out, ncm::DataId id) {
|
namespace {
|
||||||
|
|
||||||
|
constexpr const lr::Path EmptyPath = {};
|
||||||
|
|
||||||
|
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. */
|
/* Find a storage that contains the given program id. */
|
||||||
ncm::StorageId storage_id = ncm::StorageId::None;
|
ncm::StorageId storage_id = ncm::StorageId::None;
|
||||||
R_UNLESS(m_registered_storages.Find(std::addressof(storage_id), id), lr::ResultAddOnContentNotFound());
|
R_UNLESS(storages.Find(std::addressof(storage_id), id), lr::ResultAddOnContentNotFound());
|
||||||
|
|
||||||
/* Obtain a content meta database for the storage id. */
|
/* Obtain a content meta database for the storage id. */
|
||||||
ncm::ContentMetaDatabase content_meta_database;
|
ncm::ContentMetaDatabase content_meta_database;
|
||||||
R_TRY(ncm::OpenContentMetaDatabase(std::addressof(content_meta_database), storage_id));
|
R_TRY(ncm::OpenContentMetaDatabase(std::addressof(content_meta_database), storage_id));
|
||||||
|
|
||||||
/* Find the latest data content id for the given program id. */
|
/* Find the latest data content info for the given program id. */
|
||||||
ncm::ContentId data_content_id;
|
ncm::ContentInfo data_content_info;
|
||||||
R_TRY(content_meta_database.GetLatestData(std::addressof(data_content_id), id));
|
R_TRY(content_meta_database.GetLatestData(std::addressof(data_content_info), id));
|
||||||
|
|
||||||
/* Obtain a content storage for the storage id. */
|
/* Obtain a content storage for the storage id. */
|
||||||
ncm::ContentStorage content_storage;
|
ncm::ContentStorage content_storage;
|
||||||
|
@ -37,11 +42,38 @@ namespace ams::lr {
|
||||||
|
|
||||||
/* Get the path of the data content. */
|
/* Get the path of the data content. */
|
||||||
static_assert(sizeof(lr::Path) == sizeof(ncm::Path));
|
static_assert(sizeof(lr::Path) == sizeof(ncm::Path));
|
||||||
content_storage.GetPath(reinterpret_cast<ncm::Path *>(out.GetPointer()), data_content_id);
|
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();
|
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) {
|
Result AddOnContentLocationResolverImpl::RegisterAddOnContentStorageDeprecated(ncm::DataId id, ncm::StorageId storage_id) {
|
||||||
/* Register storage for the given program id. 2.0.0-8.1.0 did not require an owner application id. */
|
/* Register storage for the given program id. 2.0.0-8.1.0 did not require an owner application id. */
|
||||||
R_UNLESS(m_registered_storages.Register(id, storage_id, ncm::InvalidApplicationId), lr::ResultTooManyRegisteredPaths());
|
R_UNLESS(m_registered_storages.Register(id, storage_id, ncm::InvalidApplicationId), lr::ResultTooManyRegisteredPaths());
|
||||||
|
@ -56,17 +88,27 @@ namespace ams::lr {
|
||||||
|
|
||||||
Result AddOnContentLocationResolverImpl::UnregisterAllAddOnContentPath() {
|
Result AddOnContentLocationResolverImpl::UnregisterAllAddOnContentPath() {
|
||||||
m_registered_storages.Clear();
|
m_registered_storages.Clear();
|
||||||
|
m_registered_paths.RemoveAll();
|
||||||
|
m_registered_other_paths.RemoveAll();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AddOnContentLocationResolverImpl::RefreshApplicationAddOnContent(const sf::InArray<ncm::ApplicationId> &ids) {
|
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. */
|
/* Clear all registered storages excluding the provided program ids. */
|
||||||
m_registered_storages.ClearExcluding(reinterpret_cast<const ncm::ProgramId *>(ids.GetPointer()), ids.GetSize());
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -74,6 +116,77 @@ namespace ams::lr {
|
||||||
Result AddOnContentLocationResolverImpl::UnregisterApplicationAddOnContent(ncm::ApplicationId id) {
|
Result AddOnContentLocationResolverImpl::UnregisterApplicationAddOnContent(ncm::ApplicationId id) {
|
||||||
/* Remove entries belonging to the provided application. */
|
/* Remove entries belonging to the provided application. */
|
||||||
m_registered_storages.UnregisterOwnerProgram(id);
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,16 @@
|
||||||
namespace ams::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
class AddOnContentLocationResolverImpl {
|
class AddOnContentLocationResolverImpl {
|
||||||
|
private:
|
||||||
|
struct OwnedPath {
|
||||||
|
RedirectionPath redir_path;
|
||||||
|
ncm::ApplicationId owner_id;
|
||||||
|
};
|
||||||
private:
|
private:
|
||||||
/* Storage for RegisteredData entries by data id. */
|
/* Storage for RegisteredData entries by data id. */
|
||||||
RegisteredStorages<ncm::DataId, 0x800> m_registered_storages;
|
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:
|
private:
|
||||||
static ALWAYS_INLINE size_t GetStorageCapacity() {
|
static ALWAYS_INLINE size_t GetStorageCapacity() {
|
||||||
const auto version = hos::GetVersion();
|
const auto version = hos::GetVersion();
|
||||||
|
@ -37,7 +44,7 @@ namespace ams::lr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
AddOnContentLocationResolverImpl() : m_registered_storages(GetStorageCapacity()) { /* ... */ }
|
AddOnContentLocationResolverImpl() : m_registered_storages(GetStorageCapacity()), m_registered_paths{}, m_registered_other_paths{} { /* ... */ }
|
||||||
|
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
Result ResolveAddOnContentPath(sf::Out<Path> out, ncm::DataId id);
|
Result ResolveAddOnContentPath(sf::Out<Path> out, ncm::DataId id);
|
||||||
|
@ -46,6 +53,13 @@ namespace ams::lr {
|
||||||
Result UnregisterAllAddOnContentPath();
|
Result UnregisterAllAddOnContentPath();
|
||||||
Result RefreshApplicationAddOnContent(const sf::InArray<ncm::ApplicationId> &ids);
|
Result RefreshApplicationAddOnContent(const sf::InArray<ncm::ApplicationId> &ids);
|
||||||
Result UnregisterApplicationAddOnContent(ncm::ApplicationId id);
|
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>);
|
static_assert(lr::IsIAddOnContentLocationResolver<AddOnContentLocationResolverImpl>);
|
||||||
|
|
||||||
|
|
|
@ -28,37 +28,45 @@ namespace ams::lr {
|
||||||
m_content_storage.GetPath(reinterpret_cast<ncm::Path *>(out), content_id);
|
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. */
|
/* 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. */
|
/* If we're not enabled, we can't resolve a program. */
|
||||||
R_UNLESS(m_enabled, lr::ResultProgramNotFound())
|
R_UNLESS(m_enabled, lr::ResultProgramNotFound())
|
||||||
|
|
||||||
/* Find the latest program content for the program id. */
|
/* Find the latest program content for the program id. */
|
||||||
ncm::ContentId program_content_id;
|
ncm::ContentInfo program_content_info;
|
||||||
R_TRY_CATCH(m_content_meta_database.GetLatestProgram(std::addressof(program_content_id), id)) {
|
R_TRY_CATCH(m_content_meta_database.GetLatestProgram(std::addressof(program_content_info), id)) {
|
||||||
R_CONVERT(ncm::ResultContentMetaNotFound, lr::ResultProgramNotFound())
|
R_CONVERT(ncm::ResultContentMetaNotFound, lr::ResultProgramNotFound())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
/* Obtain the content path. */
|
/* Obtain the content path and attributes. */
|
||||||
this->GetContentStoragePath(out.GetPointer(), program_content_id);
|
this->GetContentStoragePath(out, program_content_info.GetId());
|
||||||
|
*out_attr = RedirectionAttributes::Make(program_content_info.GetContentAttributes());
|
||||||
|
|
||||||
R_SUCCEED();
|
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) {
|
Result ContentLocationResolverImpl::RedirectProgramPath(const Path &path, ncm::ProgramId id) {
|
||||||
m_program_redirector.SetRedirection(id, path);
|
m_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,48 +74,49 @@ namespace ams::lr {
|
||||||
/* If we're not enabled, we can't resolve data. */
|
/* If we're not enabled, we can't resolve data. */
|
||||||
R_UNLESS(m_enabled, lr::ResultDataNotFound())
|
R_UNLESS(m_enabled, lr::ResultDataNotFound())
|
||||||
|
|
||||||
/* Find the latest data content for the program id. */
|
/* Find the latest data content info for the program id. */
|
||||||
ncm::ContentId data_content_id;
|
ncm::ContentInfo data_content_info;
|
||||||
R_TRY(m_content_meta_database.GetLatestData(std::addressof(data_content_id), id));
|
R_TRY(m_content_meta_database.GetLatestData(std::addressof(data_content_info), id));
|
||||||
|
|
||||||
/* Obtain the content path. */
|
/* Obtain the content path. */
|
||||||
this->GetContentStoragePath(out.GetPointer(), data_content_id);
|
this->GetContentStoragePath(out.GetPointer(), data_content_info.GetId());
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationControlPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,12 +138,12 @@ namespace ams::lr {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,13 +179,14 @@ namespace ams::lr {
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId id) {
|
Result ContentLocationResolverImpl::ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId id) {
|
||||||
/* Use a redirection if present. */
|
/* 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. */
|
/* If we're not enabled, we can't resolve a program. */
|
||||||
R_UNLESS(m_enabled, lr::ResultDebugProgramNotFound())
|
R_UNLESS(m_enabled, lr::ResultDebugProgramNotFound())
|
||||||
|
|
||||||
/* Otherwise find the path for the program id. */
|
/* 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_CONVERT(lr::ResultProgramNotFound, lr::ResultDebugProgramNotFound())
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
|
@ -184,17 +194,17 @@ namespace ams::lr {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectProgramPathForDebug(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ContentLocationResolverImpl::RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "lr_location_resolver_impl_base.hpp"
|
#include "lr_location_resolver_impl_base.hpp"
|
||||||
|
#include "lr_location_redirector.hpp"
|
||||||
|
|
||||||
namespace ams::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ namespace ams::lr {
|
||||||
private:
|
private:
|
||||||
/* Helper functions. */
|
/* Helper functions. */
|
||||||
void GetContentStoragePath(Path *out, ncm::ContentId content_id);
|
void GetContentStoragePath(Path *out, ncm::ContentId content_id);
|
||||||
|
Result ResolveProgramPath(Path *out, RedirectionAttributes *out_attr, ncm::ProgramId id);
|
||||||
public:
|
public:
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId id);
|
Result ResolveProgramPath(sf::Out<Path> out, ncm::ProgramId id);
|
||||||
|
|
|
@ -25,10 +25,11 @@ namespace ams::lr {
|
||||||
ncm::ProgramId m_program_id;
|
ncm::ProgramId m_program_id;
|
||||||
ncm::ProgramId m_owner_id;
|
ncm::ProgramId m_owner_id;
|
||||||
Path m_path;
|
Path m_path;
|
||||||
|
RedirectionAttributes m_attr;
|
||||||
u32 m_flags;
|
u32 m_flags;
|
||||||
public:
|
public:
|
||||||
Redirection(ncm::ProgramId program_id, ncm::ProgramId owner_id, const Path &path, u32 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_flags(flags) { /* ... */ }
|
m_program_id(program_id), m_owner_id(owner_id), m_path(path), m_attr(attr), m_flags(flags) { /* ... */ }
|
||||||
|
|
||||||
ncm::ProgramId GetProgramId() const {
|
ncm::ProgramId GetProgramId() const {
|
||||||
return m_program_id;
|
return m_program_id;
|
||||||
|
@ -42,6 +43,10 @@ namespace ams::lr {
|
||||||
*out = m_path;
|
*out = m_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetAttributes(RedirectionAttributes *out) const {
|
||||||
|
*out = m_attr;
|
||||||
|
}
|
||||||
|
|
||||||
u32 GetFlags() const {
|
u32 GetFlags() const {
|
||||||
return m_flags;
|
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. */
|
/* Obtain the path of a matching redirection. */
|
||||||
for (const auto &redirection : m_redirection_list) {
|
for (const auto &redirection : m_redirection_list) {
|
||||||
if (redirection.GetProgramId() == program_id) {
|
if (redirection.GetProgramId() == program_id) {
|
||||||
redirection.GetPath(out);
|
redirection.GetPath(out);
|
||||||
|
redirection.GetAttributes(out_attr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationRedirector::SetRedirection(ncm::ProgramId program_id, const Path &path, u32 flags) {
|
void LocationRedirector::SetRedirection(ncm::ProgramId program_id, const Path &path, const RedirectionAttributes &attr, u32 flags) {
|
||||||
this->SetRedirection(program_id, ncm::InvalidProgramId, path, 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. */
|
/* Remove any existing redirections for this program id. */
|
||||||
this->EraseRedirection(program_id);
|
this->EraseRedirection(program_id);
|
||||||
|
|
||||||
/* Insert a new redirection into the list. */
|
/* Insert a new redirection into the list. */
|
||||||
m_redirection_list.push_back(*(new Redirection(program_id, owner_id, path, flags)));
|
m_redirection_list.push_back(*(new Redirection(program_id, owner_id, path, attr, 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationRedirector::EraseRedirection(ncm::ProgramId program_id) {
|
void LocationRedirector::EraseRedirection(ncm::ProgramId program_id) {
|
||||||
|
|
|
@ -24,6 +24,27 @@ namespace ams::lr {
|
||||||
RedirectionFlags_Application = (1 << 0),
|
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 {
|
class LocationRedirector {
|
||||||
NON_COPYABLE(LocationRedirector);
|
NON_COPYABLE(LocationRedirector);
|
||||||
NON_MOVEABLE(LocationRedirector);
|
NON_MOVEABLE(LocationRedirector);
|
||||||
|
@ -38,10 +59,9 @@ namespace ams::lr {
|
||||||
~LocationRedirector() { this->ClearRedirections(); }
|
~LocationRedirector() { this->ClearRedirections(); }
|
||||||
|
|
||||||
/* API. */
|
/* API. */
|
||||||
bool FindRedirection(Path *out, ncm::ProgramId program_id) const;
|
bool FindRedirection(Path *out, RedirectionAttributes *out_attr, ncm::ProgramId program_id) const;
|
||||||
void SetRedirection(ncm::ProgramId program_id, const Path &path, u32 flags = RedirectionFlags_None);
|
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, 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 SetRedirectionFlags(ncm::ProgramId program_id, u32 flags);
|
|
||||||
void EraseRedirection(ncm::ProgramId program_id);
|
void EraseRedirection(ncm::ProgramId program_id);
|
||||||
void ClearRedirections(u32 flags = RedirectionFlags_None);
|
void ClearRedirections(u32 flags = RedirectionFlags_None);
|
||||||
void ClearRedirectionsExcludingOwners(const ncm::ProgramId *excluding_ids, size_t num_ids);
|
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) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectProgramPath(const Path &path, ncm::ProgramId id) {
|
Result RedirectOnlyLocationResolverImpl::RedirectProgramPath(const Path &path, ncm::ProgramId id) {
|
||||||
m_program_redirector.SetRedirection(id, path);
|
m_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::ResolveApplicationControlPath(sf::Out<Path> out, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::ResolveApplicationHtmlDocumentPath(sf::Out<Path> out, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,37 +52,38 @@ namespace ams::lr {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationControlPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationControlPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::ResolveApplicationLegalInformationPath(sf::Out<Path> out, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationLegalInformationPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationLegalInformationPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,12 +93,12 @@ namespace ams::lr {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationProgramPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,26 +134,27 @@ namespace ams::lr {
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId id) {
|
Result RedirectOnlyLocationResolverImpl::ResolveProgramPathForDebug(sf::Out<Path> out, ncm::ProgramId id) {
|
||||||
/* If a debug program redirection is present, use it. */
|
/* 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. */
|
/* 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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectProgramPathForDebug(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationProgramPathForDebugDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RedirectOnlyLocationResolverImpl::RedirectApplicationProgramPathForDebug(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere/lr/lr_types.hpp>
|
#include <stratosphere/lr/lr_types.hpp>
|
||||||
|
#include "lr_location_redirector.hpp"
|
||||||
|
|
||||||
namespace ams::lr {
|
namespace ams::lr {
|
||||||
|
|
||||||
|
@ -137,7 +138,7 @@ namespace ams::lr {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Key, size_t NumEntries>
|
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>
|
template<typename Key, size_t NumEntries>
|
||||||
using RegisteredStorages = RegisteredData<Key, ncm::StorageId, NumEntries>;
|
using RegisteredStorages = RegisteredData<Key, ncm::StorageId, NumEntries>;
|
||||||
|
|
|
@ -23,25 +23,33 @@ namespace ams::lr {
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
bool ResolvePath(Path *out, const LocationRedirector &redirector, const RegisteredLocations<ncm::ProgramId, N> &locations, ncm::ProgramId id) {
|
bool ResolvePath(Path *out, const LocationRedirector &redirector, const RegisteredLocations<ncm::ProgramId, N> &locations, ncm::ProgramId id) {
|
||||||
/* Attempt to use a redirection if present. */
|
/* 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. */
|
/* 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the output path. */
|
||||||
|
*out = redir_path.path;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
void RegisterPath(RegisteredLocations<ncm::ProgramId, N> &locations, ncm::ProgramId id, const Path& path, ncm::ProgramId owner_id) {
|
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 we register successfully, we're good. */
|
||||||
if (locations.Register(id, path, owner_id)) {
|
if (locations.Register(id, redir_path, owner_id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, clear and register (this should always succeed). */
|
/* Otherwise, clear and register (this should always succeed). */
|
||||||
locations.Clear();
|
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) {
|
Result RegisteredLocationResolverImpl::RedirectProgramPathDeprecated(const Path &path, ncm::ProgramId id) {
|
||||||
m_program_redirector.SetRedirection(id, path);
|
m_program_redirector.SetRedirection(id, path, DefaultRedirectionAttributes);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverImpl::RedirectProgramPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,12 +138,12 @@ namespace ams::lr {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverImpl::RedirectHtmlDocumentPathDeprecated(const Path &path, ncm::ProgramId id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result RegisteredLocationResolverImpl::RedirectHtmlDocumentPath(const Path &path, ncm::ProgramId id, ncm::ProgramId owner_id) {
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,6 @@ namespace ams::lr {
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(TooManyRegisteredPaths, 90);
|
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