mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
ncm: updated to 13.0.0
This commit is contained in:
parent
c1c07af99a
commit
b6b09d6944
9 changed files with 422 additions and 26 deletions
|
@ -38,6 +38,7 @@
|
|||
#include <stratosphere/ncm/ncm_package_install_task.hpp>
|
||||
#include <stratosphere/ncm/ncm_package_system_downgrade_task.hpp>
|
||||
#include <stratosphere/ncm/ncm_package_system_update_task.hpp>
|
||||
#include <stratosphere/ncm/ncm_registered_host_content.hpp>
|
||||
#include <stratosphere/ncm/ncm_submission_package_install_task.hpp>
|
||||
#include <stratosphere/ncm/ncm_storage_utils.hpp>
|
||||
#include <stratosphere/ncm/ncm_api.hpp>
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <stratosphere/ncm/ncm_rights_id_cache.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_management_utils.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_utils.hpp>
|
||||
#include <stratosphere/ncm/ncm_registered_host_content.hpp>
|
||||
#include <stratosphere/kvdb/kvdb_memory_key_value_store.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
@ -108,8 +109,11 @@ namespace ams::ncm {
|
|||
u32 num_content_storage_entries;
|
||||
u32 num_content_meta_entries;
|
||||
RightsIdCache rights_id_cache;
|
||||
RegisteredHostContent registered_host_content;
|
||||
public:
|
||||
ContentManagerImpl() : mutex(true), initialized(false) { /* ... */ };
|
||||
ContentManagerImpl() : mutex(true), initialized(false), num_content_storage_entries(0), num_content_meta_entries(0), rights_id_cache(), registered_host_content() {
|
||||
/* ... */
|
||||
};
|
||||
~ContentManagerImpl();
|
||||
public:
|
||||
Result Initialize(const ContentManagerConfig &config);
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 Adubbz, 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>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 Adubbz, 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 <stratosphere/os.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_path.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class RegisteredHostContent {
|
||||
NON_COPYABLE(RegisteredHostContent);
|
||||
NON_MOVEABLE(RegisteredHostContent);
|
||||
private:
|
||||
class RegisteredPath;
|
||||
private:
|
||||
using RegisteredPathList = ams::util::IntrusiveListBaseTraits<RegisteredPath>::ListType;
|
||||
private:
|
||||
os::SdkMutex mutex;
|
||||
RegisteredPathList path_list;
|
||||
public:
|
||||
RegisteredHostContent() : mutex(), path_list() { /* ... */ }
|
||||
~RegisteredHostContent();
|
||||
|
||||
Result RegisterPath(const ncm::ContentId &content_id, const ncm::Path &path);
|
||||
Result GetPath(Path *out, const ncm::ContentId &content_id);
|
||||
void ClearPaths();
|
||||
};
|
||||
|
||||
}
|
|
@ -35,9 +35,9 @@ namespace ams::ncm {
|
|||
private:
|
||||
Entry entries[MaxEntries];
|
||||
u64 counter;
|
||||
os::Mutex mutex;
|
||||
os::SdkMutex mutex;
|
||||
public:
|
||||
RightsIdCache() : mutex(false) {
|
||||
RightsIdCache() : mutex() {
|
||||
this->Invalidate();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <stratosphere.hpp>
|
||||
#include "ncm_content_storage_impl.hpp"
|
||||
#include "ncm_read_only_content_storage_impl.hpp"
|
||||
#include "ncm_host_content_storage_impl.hpp"
|
||||
#include "ncm_content_meta_database_impl.hpp"
|
||||
#include "ncm_on_memory_content_meta_database_impl.hpp"
|
||||
#include "ncm_fs_utils.hpp"
|
||||
|
@ -551,7 +552,11 @@ namespace ams::ncm {
|
|||
/* Unmount on failure. */
|
||||
auto mount_guard = SCOPE_GUARD { fs::Unmount(root->mount_name); };
|
||||
|
||||
if (storage_id == StorageId::GameCard) {
|
||||
if (storage_id == StorageId::Host) {
|
||||
/* Create a host content storage. */
|
||||
auto content_storage = sf::CreateSharedObjectEmplaced<IContentStorage, HostContentStorageImpl>(std::addressof(this->registered_host_content));
|
||||
root->content_storage = std::move(content_storage);
|
||||
} else if (storage_id == StorageId::GameCard) {
|
||||
/* Game card content storage is read only. */
|
||||
auto content_storage = sf::CreateSharedObjectEmplaced<IContentStorage, ReadOnlyContentStorageImpl>();
|
||||
R_TRY(content_storage.GetImpl().Initialize(root->path, MakeFlatContentFilePath));
|
||||
|
@ -593,7 +598,12 @@ namespace ams::ncm {
|
|||
/* N doesn't bother checking the result of this */
|
||||
root->content_storage->DisableForcibly();
|
||||
root->content_storage = nullptr;
|
||||
fs::Unmount(root->mount_name);
|
||||
|
||||
if (storage_id == StorageId::Host) {
|
||||
this->registered_host_content.ClearPaths();
|
||||
} else {
|
||||
fs::Unmount(root->mount_name);
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 Adubbz, 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/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "ncm_host_content_storage_impl.hpp"
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
Result HostContentStorageImpl::GeneratePlaceHolderId(sf::Out<PlaceHolderId> out) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::DeletePlaceHolder(PlaceHolderId placeholder_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::Register(PlaceHolderId placeholder_id, ContentId content_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::Delete(ContentId content_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::Has(sf::Out<bool> out, ContentId content_id) {
|
||||
R_TRY(this->EnsureEnabled());
|
||||
|
||||
/* Attempt to locate the content. */
|
||||
Path path;
|
||||
R_TRY_CATCH(this->registered_content->GetPath(std::addressof(path), content_id)) {
|
||||
/* The content is absent, this is fine. */
|
||||
R_CATCH(ncm::ResultContentNotFound) {
|
||||
out.SetValue(false);
|
||||
return ResultSuccess();
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
out.SetValue(true);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetPath(sf::Out<Path> out, ContentId content_id) {
|
||||
R_TRY(this->EnsureEnabled());
|
||||
return this->registered_content->GetPath(out.GetPointer(), content_id);
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetPlaceHolderPath(sf::Out<Path> out, PlaceHolderId placeholder_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::CleanupAllPlaceHolder() {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::ListPlaceHolder(sf::Out<s32> out_count, const sf::OutArray<PlaceHolderId> &out_buf) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetContentCount(sf::Out<s32> out_count) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::ListContentId(sf::Out<s32> out_count, const sf::OutArray<ContentId> &out_buf, s32 offset) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetSizeFromContentId(sf::Out<s64> out_size, ContentId content_id) {
|
||||
return ncm::ResultInvalidOperation();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::DisableForcibly() {
|
||||
this->disabled = true;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset) {
|
||||
return ncm::ResultInvalidOperation();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetRightsIdFromPlaceHolderIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, PlaceHolderId placeholder_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetRightsIdFromContentIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, ContentId content_id) {
|
||||
/* Obtain the regular rights id for the content id. */
|
||||
ncm::RightsId rights_id;
|
||||
R_TRY(this->GetRightsIdFromContentId(&rights_id, content_id));
|
||||
|
||||
/* Output the fs rights id. */
|
||||
out_rights_id.SetValue(rights_id.id);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id) {
|
||||
R_TRY(this->EnsureEnabled());
|
||||
|
||||
/* Get the content path. */
|
||||
Path path;
|
||||
R_TRY(this->registered_content->GetPath(std::addressof(path), content_id));
|
||||
|
||||
/* Acquire the rights id for the content. */
|
||||
RightsId rights_id;
|
||||
R_TRY_CATCH(GetRightsId(std::addressof(rights_id), path)) {
|
||||
/* The content is absent, output a blank rights id. */
|
||||
R_CATCH(fs::ResultTargetNotFound) {
|
||||
out_rights_id.SetValue({});
|
||||
return ResultSuccess();
|
||||
}
|
||||
} R_END_TRY_CATCH;
|
||||
|
||||
/* Output the rights id. */
|
||||
out_rights_id.SetValue(rights_id);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetFreeSpaceSize(sf::Out<s64> out_size) {
|
||||
out_size.SetValue(0);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetTotalSpaceSize(sf::Out<s64> out_size) {
|
||||
out_size.SetValue(0);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::FlushPlaceHolder() {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetSizeFromPlaceHolderId(sf::Out<s64> out, PlaceHolderId placeholder_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::RepairInvalidFileAttribute() {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::GetRightsIdFromPlaceHolderIdWithCache(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id) {
|
||||
return ncm::ResultNotSupported();
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::RegisterPath(const ContentId &content_id, const Path &path) {
|
||||
AMS_ABORT_UNLESS(spl::IsDevelopment());
|
||||
return this->registered_content->RegisterPath(content_id, path);
|
||||
}
|
||||
|
||||
Result HostContentStorageImpl::ClearRegisteredPath() {
|
||||
AMS_ABORT_UNLESS(spl::IsDevelopment());
|
||||
this->registered_content->ClearPaths();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 Adubbz, 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 <stratosphere.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class HostContentStorageImpl {
|
||||
protected:
|
||||
RegisteredHostContent *registered_content;
|
||||
bool disabled;
|
||||
protected:
|
||||
/* Helpers. */
|
||||
Result EnsureEnabled() const {
|
||||
R_UNLESS(!this->disabled, ncm::ResultInvalidContentStorage());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
static Result GetRightsId(ncm::RightsId *out_rights_id, const Path &path) {
|
||||
if (hos::GetVersion() >= hos::Version_3_0_0) {
|
||||
R_TRY(fs::GetRightsId(std::addressof(out_rights_id->id), std::addressof(out_rights_id->key_generation), path.str));
|
||||
} else {
|
||||
R_TRY(fs::GetRightsId(std::addressof(out_rights_id->id), path.str));
|
||||
out_rights_id->key_generation = 0;
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
HostContentStorageImpl(RegisteredHostContent *registered_content) : registered_content(registered_content), disabled(false) { /* ... */ }
|
||||
~HostContentStorageImpl();
|
||||
public:
|
||||
/* Actual commands. */
|
||||
virtual Result GeneratePlaceHolderId(sf::Out<PlaceHolderId> out);
|
||||
virtual Result CreatePlaceHolder(PlaceHolderId placeholder_id, ContentId content_id, s64 size);
|
||||
virtual Result DeletePlaceHolder(PlaceHolderId placeholder_id);
|
||||
virtual Result HasPlaceHolder(sf::Out<bool> out, PlaceHolderId placeholder_id);
|
||||
virtual Result WritePlaceHolder(PlaceHolderId placeholder_id, s64 offset, const sf::InBuffer &data);
|
||||
virtual Result Register(PlaceHolderId placeholder_id, ContentId content_id);
|
||||
virtual Result Delete(ContentId content_id);
|
||||
virtual Result Has(sf::Out<bool> out, ContentId content_id);
|
||||
virtual Result GetPath(sf::Out<Path> out, ContentId content_id);
|
||||
virtual Result GetPlaceHolderPath(sf::Out<Path> out, PlaceHolderId placeholder_id);
|
||||
virtual Result CleanupAllPlaceHolder();
|
||||
virtual Result ListPlaceHolder(sf::Out<s32> out_count, const sf::OutArray<PlaceHolderId> &out_buf);
|
||||
virtual Result GetContentCount(sf::Out<s32> out_count);
|
||||
virtual Result ListContentId(sf::Out<s32> out_count, const sf::OutArray<ContentId> &out_buf, s32 start_offset);
|
||||
virtual Result GetSizeFromContentId(sf::Out<s64> out_size, ContentId content_id);
|
||||
virtual Result DisableForcibly();
|
||||
virtual Result RevertToPlaceHolder(PlaceHolderId placeholder_id, ContentId old_content_id, ContentId new_content_id);
|
||||
virtual Result SetPlaceHolderSize(PlaceHolderId placeholder_id, s64 size);
|
||||
virtual Result ReadContentIdFile(const sf::OutBuffer &buf, ContentId content_id, s64 offset);
|
||||
virtual Result GetRightsIdFromPlaceHolderIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, PlaceHolderId placeholder_id);
|
||||
virtual Result GetRightsIdFromPlaceHolderId(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id);
|
||||
virtual Result GetRightsIdFromContentIdDeprecated(sf::Out<ams::fs::RightsId> out_rights_id, ContentId content_id);
|
||||
virtual Result GetRightsIdFromContentId(sf::Out<ncm::RightsId> out_rights_id, ContentId content_id);
|
||||
virtual Result WriteContentForDebug(ContentId content_id, s64 offset, const sf::InBuffer &data);
|
||||
virtual Result GetFreeSpaceSize(sf::Out<s64> out_size);
|
||||
virtual Result GetTotalSpaceSize(sf::Out<s64> out_size);
|
||||
virtual Result FlushPlaceHolder();
|
||||
virtual Result GetSizeFromPlaceHolderId(sf::Out<s64> out, PlaceHolderId placeholder_id);
|
||||
virtual Result RepairInvalidFileAttribute();
|
||||
virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id);
|
||||
virtual Result RegisterPath(const ContentId &content_id, const Path &path);
|
||||
virtual Result ClearRegisteredPath();
|
||||
};
|
||||
static_assert(ncm::IsIContentStorage<HostContentStorageImpl>);
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 Adubbz, 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/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
class RegisteredHostContent::RegisteredPath : public util::IntrusiveListBaseNode<RegisteredPath> {
|
||||
NON_COPYABLE(RegisteredPath);
|
||||
NON_MOVEABLE(RegisteredPath);
|
||||
private:
|
||||
ContentId content_id;
|
||||
Path path;
|
||||
public:
|
||||
RegisteredPath(const ncm::ContentId &content_id, const Path &p) : content_id(content_id), path(p) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
ncm::ContentId GetContentId() const {
|
||||
return this->content_id;
|
||||
}
|
||||
|
||||
void GetPath(Path *out) const {
|
||||
*out = this->path;
|
||||
}
|
||||
|
||||
void SetPath(const Path &path) {
|
||||
this->path = path;
|
||||
}
|
||||
};
|
||||
|
||||
Result RegisteredHostContent::RegisterPath(const ncm::ContentId &content_id, const ncm::Path &path) {
|
||||
std::scoped_lock lk(this->mutex);
|
||||
|
||||
/* Replace the path of any existing entries. */
|
||||
for (auto ®istered_path : this->path_list) {
|
||||
if (registered_path.GetContentId() == content_id) {
|
||||
registered_path.SetPath(path);
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate a new registered path. TODO: Verify allocator. */
|
||||
RegisteredPath *registered_path = new RegisteredPath(content_id, path);
|
||||
R_UNLESS(registered_path != nullptr, ncm::ResultBufferInsufficient());
|
||||
|
||||
/* Insert the path into the list. */
|
||||
this->path_list.push_back(*registered_path);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result RegisteredHostContent::GetPath(Path *out, const ncm::ContentId &content_id) {
|
||||
std::scoped_lock lk(this->mutex);
|
||||
|
||||
/* Obtain the path of the content. */
|
||||
for (const auto ®istered_path : this->path_list) {
|
||||
if (registered_path.GetContentId() == content_id) {
|
||||
registered_path.GetPath(out);
|
||||
return ResultSuccess();
|
||||
}
|
||||
}
|
||||
return ncm::ResultContentNotFound();
|
||||
}
|
||||
|
||||
void RegisteredHostContent::ClearPaths() {
|
||||
/* Remove all paths. */
|
||||
for (auto it = this->path_list.begin(); it != this->path_list.end(); /* ... */) {
|
||||
auto *obj = std::addressof(*it);
|
||||
it = this->path_list.erase(it);
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue