mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-07-06 09:32:17 +02:00
Updated NCM to 9.0.0
This commit is contained in:
parent
bb3d41b416
commit
1c19856fb0
@ -25,6 +25,7 @@
|
||||
#include "../ncm_make_path.hpp"
|
||||
#include "../ncm_readonlycontentstorage.hpp"
|
||||
#include "ncm_content_manager.hpp"
|
||||
#include "ncm_rights_cache.hpp"
|
||||
|
||||
namespace sts::ncm::impl {
|
||||
|
||||
@ -115,6 +116,7 @@ namespace sts::ncm::impl {
|
||||
ContentMetaDBEntry g_content_meta_entries[MaxContentMetaDBEntries];
|
||||
u32 g_num_content_storage_entries;
|
||||
u32 g_num_content_meta_entries;
|
||||
RightsIdCache g_rights_id_cache;
|
||||
|
||||
ContentStorageEntry* FindContentStorageEntry(StorageId storage_id) {
|
||||
for (size_t i = 0; i < MaxContentStorageEntries; i++) {
|
||||
@ -449,7 +451,7 @@ namespace sts::ncm::impl {
|
||||
break;
|
||||
}
|
||||
|
||||
R_TRY(content_storage->Initialize(entry->root_path, content_path_func, placeholder_path_func, delay_flush));
|
||||
R_TRY(content_storage->Initialize(entry->root_path, content_path_func, placeholder_path_func, delay_flush, &g_rights_id_cache));
|
||||
entry->content_storage = std::move(content_storage);
|
||||
mount_guard.Cancel();
|
||||
}
|
||||
@ -706,4 +708,10 @@ namespace sts::ncm::impl {
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result InvalidateRightsIdCache() {
|
||||
g_rights_id_cache.Invalidate();
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,5 +43,6 @@ namespace sts::ncm::impl {
|
||||
Result CleanupContentMetaDatabase(StorageId storage_id);
|
||||
Result ActivateContentMetaDatabase(StorageId storage_id);
|
||||
Result InactivateContentMetaDatabase(StorageId storage_id);
|
||||
Result InvalidateRightsIdCache();
|
||||
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Adubbz
|
||||
*
|
||||
* 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 "ncm_rights_cache.hpp"
|
||||
|
||||
namespace sts::ncm::impl {
|
||||
|
||||
namespace {
|
||||
|
||||
RightsIdCache g_rights_id_cache;
|
||||
|
||||
}
|
||||
|
||||
RightsIdCache* GetRightsIdCache() {
|
||||
return &g_rights_id_cache;
|
||||
}
|
||||
|
||||
}
|
@ -29,14 +29,23 @@ namespace sts::ncm::impl {
|
||||
util::Uuid uuid;
|
||||
FsRightsId rights_id;
|
||||
u64 key_generation;
|
||||
u64 last_accessed = 1;
|
||||
u64 last_accessed;
|
||||
};
|
||||
|
||||
Entry entries[MaxEntries];
|
||||
u64 counter = 2;
|
||||
u64 counter;
|
||||
HosMutex mutex;
|
||||
|
||||
RightsIdCache() {
|
||||
this->Invalidate();
|
||||
}
|
||||
|
||||
void Invalidate() {
|
||||
this->counter = 2;
|
||||
for (size_t i = 0; i < MaxEntries; i++) {
|
||||
this->entries[i].last_accessed = 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RightsIdCache* GetRightsIdCache();
|
||||
|
||||
}
|
||||
|
@ -77,4 +77,8 @@ namespace sts::ncm {
|
||||
return impl::InactivateContentMetaDatabase(storage_id);
|
||||
}
|
||||
|
||||
Result ContentManagerService::InvalidateRightsIdCache() {
|
||||
return impl::InvalidateRightsIdCache();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ namespace sts::ncm {
|
||||
InactivateContentStorage = 10,
|
||||
ActivateContentMetaDatabase = 11,
|
||||
InactivateContentMetaDatabase = 12,
|
||||
InvalidateRightsIdCache = 13,
|
||||
};
|
||||
public:
|
||||
virtual Result CreateContentStorage(StorageId storage_id);
|
||||
@ -54,6 +55,7 @@ namespace sts::ncm {
|
||||
virtual Result InactivateContentStorage(StorageId storage_id);
|
||||
virtual Result ActivateContentMetaDatabase(StorageId storage_id);
|
||||
virtual Result InactivateContentMetaDatabase(StorageId storage_id);
|
||||
virtual Result InvalidateRightsIdCache();
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, CreateContentStorage),
|
||||
@ -69,6 +71,7 @@ namespace sts::ncm {
|
||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, InactivateContentStorage, FirmwareVersion_200),
|
||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, ActivateContentMetaDatabase, FirmwareVersion_200),
|
||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, InactivateContentMetaDatabase, FirmwareVersion_200),
|
||||
MAKE_SERVICE_COMMAND_META(ContentManagerService, InvalidateRightsIdCache, FirmwareVersion_900),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "impl/ncm_rights_cache.hpp"
|
||||
#include "ncm_contentstorage.hpp"
|
||||
#include "ncm_fs.hpp"
|
||||
#include "ncm_make_path.hpp"
|
||||
@ -26,7 +25,7 @@ namespace sts::ncm {
|
||||
this->Finalize();
|
||||
}
|
||||
|
||||
Result ContentStorageInterface::Initialize(const char* root_path, MakeContentPathFunc content_path_func, MakePlaceHolderPathFunc placeholder_path_func, bool delay_flush) {
|
||||
Result ContentStorageInterface::Initialize(const char* root_path, MakeContentPathFunc content_path_func, MakePlaceHolderPathFunc placeholder_path_func, bool delay_flush, impl::RightsIdCache* rights_id_cache) {
|
||||
R_TRY(this->EnsureEnabled());
|
||||
R_TRY(fs::CheckContentStorageDirectoriesExist(root_path));
|
||||
const size_t root_path_len = strnlen(root_path, FS_MAX_PATH-1);
|
||||
@ -38,6 +37,7 @@ namespace sts::ncm {
|
||||
strncpy(this->root_path, root_path, FS_MAX_PATH-2);
|
||||
this->make_content_path_func = *content_path_func;
|
||||
this->placeholder_accessor.Initialize(this->root_path, *placeholder_path_func, delay_flush);
|
||||
this->rights_id_cache = rights_id_cache;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
@ -428,18 +428,16 @@ namespace sts::ncm {
|
||||
Result ContentStorageInterface::GetRightsIdFromContentId(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, ContentId content_id) {
|
||||
R_TRY(this->EnsureEnabled());
|
||||
|
||||
impl::RightsIdCache* rights_id_cache = impl::GetRightsIdCache();
|
||||
|
||||
{
|
||||
std::scoped_lock<HosMutex> lk(rights_id_cache->mutex);
|
||||
std::scoped_lock<HosMutex> lk(this->rights_id_cache->mutex);
|
||||
|
||||
/* Attempt to locate the content id in the cache. */
|
||||
for (size_t i = 0; i < impl::RightsIdCache::MaxEntries; i++) {
|
||||
impl::RightsIdCache::Entry* entry = &rights_id_cache->entries[i];
|
||||
impl::RightsIdCache::Entry* entry = &this->rights_id_cache->entries[i];
|
||||
|
||||
if (entry->last_accessed != 1 && content_id == entry->uuid) {
|
||||
entry->last_accessed = rights_id_cache->counter;
|
||||
rights_id_cache->counter++;
|
||||
entry->last_accessed = this->rights_id_cache->counter;
|
||||
this->rights_id_cache->counter++;
|
||||
out_rights_id.SetValue(entry->rights_id);
|
||||
out_key_generation.SetValue(entry->key_generation);
|
||||
return ResultSuccess;
|
||||
@ -456,12 +454,12 @@ namespace sts::ncm {
|
||||
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
||||
|
||||
{
|
||||
std::scoped_lock<HosMutex> lk(rights_id_cache->mutex);
|
||||
impl::RightsIdCache::Entry* eviction_candidate = &rights_id_cache->entries[0];
|
||||
std::scoped_lock<HosMutex> lk(this->rights_id_cache->mutex);
|
||||
impl::RightsIdCache::Entry* eviction_candidate = &this->rights_id_cache->entries[0];
|
||||
|
||||
/* Find a suitable existing entry to store our new one at. */
|
||||
for (size_t i = 1; i < impl::RightsIdCache::MaxEntries; i++) {
|
||||
impl::RightsIdCache::Entry* entry = &rights_id_cache->entries[i];
|
||||
impl::RightsIdCache::Entry* entry = &this->rights_id_cache->entries[i];
|
||||
|
||||
/* Change eviction candidates if the uuid already matches ours, or if the uuid doesn't already match and the last_accessed count is lower */
|
||||
if (content_id == entry->uuid || (content_id != eviction_candidate->uuid && entry->last_accessed < eviction_candidate->last_accessed)) {
|
||||
@ -473,8 +471,8 @@ namespace sts::ncm {
|
||||
eviction_candidate->uuid = content_id.uuid;
|
||||
eviction_candidate->rights_id = rights_id;
|
||||
eviction_candidate->key_generation = key_generation;
|
||||
eviction_candidate->last_accessed = rights_id_cache->counter;
|
||||
rights_id_cache->counter++;
|
||||
eviction_candidate->last_accessed = this->rights_id_cache->counter;
|
||||
this->rights_id_cache->counter++;
|
||||
|
||||
/* Set output. */
|
||||
out_rights_id.SetValue(rights_id);
|
||||
@ -599,18 +597,16 @@ namespace sts::ncm {
|
||||
Result ContentStorageInterface::GetRightsIdFromPlaceHolderIdWithCache(Out<FsRightsId> out_rights_id, Out<u64> out_key_generation, PlaceHolderId placeholder_id, ContentId cache_content_id) {
|
||||
R_TRY(this->EnsureEnabled());
|
||||
|
||||
impl::RightsIdCache* rights_id_cache = impl::GetRightsIdCache();
|
||||
|
||||
{
|
||||
std::scoped_lock<HosMutex> lk(rights_id_cache->mutex);
|
||||
std::scoped_lock<HosMutex> lk(this->rights_id_cache->mutex);
|
||||
|
||||
/* Attempt to locate the content id in the cache. */
|
||||
for (size_t i = 0; i < impl::RightsIdCache::MaxEntries; i++) {
|
||||
impl::RightsIdCache::Entry* entry = &rights_id_cache->entries[i];
|
||||
impl::RightsIdCache::Entry* entry = &this->rights_id_cache->entries[i];
|
||||
|
||||
if (entry->last_accessed != 1 && cache_content_id == entry->uuid) {
|
||||
entry->last_accessed = rights_id_cache->counter;
|
||||
rights_id_cache->counter++;
|
||||
entry->last_accessed = this->rights_id_cache->counter;
|
||||
this->rights_id_cache->counter++;
|
||||
out_rights_id.SetValue(entry->rights_id);
|
||||
out_key_generation.SetValue(entry->key_generation);
|
||||
return ResultSuccess;
|
||||
@ -627,12 +623,12 @@ namespace sts::ncm {
|
||||
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
||||
|
||||
{
|
||||
std::scoped_lock<HosMutex> lk(rights_id_cache->mutex);
|
||||
impl::RightsIdCache::Entry* eviction_candidate = &rights_id_cache->entries[0];
|
||||
std::scoped_lock<HosMutex> lk(this->rights_id_cache->mutex);
|
||||
impl::RightsIdCache::Entry* eviction_candidate = &this->rights_id_cache->entries[0];
|
||||
|
||||
/* Find a suitable existing entry to store our new one at. */
|
||||
for (size_t i = 1; i < impl::RightsIdCache::MaxEntries; i++) {
|
||||
impl::RightsIdCache::Entry* entry = &rights_id_cache->entries[i];
|
||||
impl::RightsIdCache::Entry* entry = &this->rights_id_cache->entries[i];
|
||||
|
||||
/* Change eviction candidates if the uuid already matches ours, or if the uuid doesn't already match and the last_accessed count is lower */
|
||||
if (cache_content_id == entry->uuid || (cache_content_id != eviction_candidate->uuid && entry->last_accessed < eviction_candidate->last_accessed)) {
|
||||
@ -644,8 +640,8 @@ namespace sts::ncm {
|
||||
eviction_candidate->uuid = cache_content_id.uuid;
|
||||
eviction_candidate->rights_id = rights_id;
|
||||
eviction_candidate->key_generation = key_generation;
|
||||
eviction_candidate->last_accessed = rights_id_cache->counter;
|
||||
rights_id_cache->counter++;
|
||||
eviction_candidate->last_accessed = this->rights_id_cache->counter;
|
||||
this->rights_id_cache->counter++;
|
||||
|
||||
/* Set output. */
|
||||
out_rights_id.SetValue(rights_id);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "impl/ncm_placeholder_accessor.hpp"
|
||||
#include "impl/ncm_rights_cache.hpp"
|
||||
#include "ncm_icontentstorage.hpp"
|
||||
#include "ncm_path_utils.hpp"
|
||||
|
||||
@ -29,10 +30,11 @@ namespace sts::ncm {
|
||||
impl::PlaceHolderAccessor placeholder_accessor;
|
||||
ContentId cached_content_id;
|
||||
FILE* content_cache_file_handle;
|
||||
impl::RightsIdCache* rights_id_cache;
|
||||
public:
|
||||
~ContentStorageInterface();
|
||||
|
||||
Result Initialize(const char* root_path, MakeContentPathFunc content_path_func, MakePlaceHolderPathFunc placeholder_path_func, bool delay_flush);
|
||||
Result Initialize(const char* root_path, MakeContentPathFunc content_path_func, MakePlaceHolderPathFunc placeholder_path_func, bool delay_flush, impl::RightsIdCache* rights_id_cache);
|
||||
void Finalize();
|
||||
private:
|
||||
void ClearContentCache();
|
||||
|
Loading…
Reference in New Issue
Block a user