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_install_task.hpp>
|
||||||
#include <stratosphere/ncm/ncm_package_system_downgrade_task.hpp>
|
#include <stratosphere/ncm/ncm_package_system_downgrade_task.hpp>
|
||||||
#include <stratosphere/ncm/ncm_package_system_update_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_submission_package_install_task.hpp>
|
||||||
#include <stratosphere/ncm/ncm_storage_utils.hpp>
|
#include <stratosphere/ncm/ncm_storage_utils.hpp>
|
||||||
#include <stratosphere/ncm/ncm_api.hpp>
|
#include <stratosphere/ncm/ncm_api.hpp>
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <stratosphere/ncm/ncm_rights_id_cache.hpp>
|
#include <stratosphere/ncm/ncm_rights_id_cache.hpp>
|
||||||
#include <stratosphere/ncm/ncm_content_management_utils.hpp>
|
#include <stratosphere/ncm/ncm_content_management_utils.hpp>
|
||||||
#include <stratosphere/ncm/ncm_content_meta_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>
|
#include <stratosphere/kvdb/kvdb_memory_key_value_store.hpp>
|
||||||
|
|
||||||
namespace ams::ncm {
|
namespace ams::ncm {
|
||||||
|
@ -108,8 +109,11 @@ namespace ams::ncm {
|
||||||
u32 num_content_storage_entries;
|
u32 num_content_storage_entries;
|
||||||
u32 num_content_meta_entries;
|
u32 num_content_meta_entries;
|
||||||
RightsIdCache rights_id_cache;
|
RightsIdCache rights_id_cache;
|
||||||
|
RegisteredHostContent registered_host_content;
|
||||||
public:
|
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();
|
~ContentManagerImpl();
|
||||||
public:
|
public:
|
||||||
Result Initialize(const ContentManagerConfig &config);
|
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:
|
private:
|
||||||
Entry entries[MaxEntries];
|
Entry entries[MaxEntries];
|
||||||
u64 counter;
|
u64 counter;
|
||||||
os::Mutex mutex;
|
os::SdkMutex mutex;
|
||||||
public:
|
public:
|
||||||
RightsIdCache() : mutex(false) {
|
RightsIdCache() : mutex() {
|
||||||
this->Invalidate();
|
this->Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "ncm_content_storage_impl.hpp"
|
#include "ncm_content_storage_impl.hpp"
|
||||||
#include "ncm_read_only_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_content_meta_database_impl.hpp"
|
||||||
#include "ncm_on_memory_content_meta_database_impl.hpp"
|
#include "ncm_on_memory_content_meta_database_impl.hpp"
|
||||||
#include "ncm_fs_utils.hpp"
|
#include "ncm_fs_utils.hpp"
|
||||||
|
@ -551,7 +552,11 @@ namespace ams::ncm {
|
||||||
/* Unmount on failure. */
|
/* Unmount on failure. */
|
||||||
auto mount_guard = SCOPE_GUARD { fs::Unmount(root->mount_name); };
|
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. */
|
/* Game card content storage is read only. */
|
||||||
auto content_storage = sf::CreateSharedObjectEmplaced<IContentStorage, ReadOnlyContentStorageImpl>();
|
auto content_storage = sf::CreateSharedObjectEmplaced<IContentStorage, ReadOnlyContentStorageImpl>();
|
||||||
R_TRY(content_storage.GetImpl().Initialize(root->path, MakeFlatContentFilePath));
|
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 */
|
/* N doesn't bother checking the result of this */
|
||||||
root->content_storage->DisableForcibly();
|
root->content_storage->DisableForcibly();
|
||||||
root->content_storage = nullptr;
|
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();
|
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