ncm: update for new 17.0.0 apis

This commit is contained in:
Michael Scire 2023-10-11 12:31:37 -07:00
parent c73520180c
commit 13ee9a83cd
31 changed files with 249 additions and 7 deletions

View file

@ -0,0 +1,36 @@
/*
* 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/>.
*/
#include <stratosphere.hpp>
#include <stratosphere/fs/fs_rights_id.hpp>
#include "impl/fs_file_system_proxy_service_object.hpp"
namespace ams::fs {
Result GetProgramId(ncm::ProgramId *out, const char *path, fs::ContentAttributes attr) {
AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument());
AMS_FS_R_UNLESS(path != nullptr, fs::ResultNullptrArgument());
/* Convert the path for fsp. */
fssrv::sf::FspPath sf_path;
R_TRY(fs::ConvertToFspPath(std::addressof(sf_path), path));
auto fsp = impl::GetFileSystemProxyServiceObject();
AMS_FS_R_TRY(fsp->GetProgramId(out, sf_path, attr));
R_SUCCEED();
}
}

View file

@ -320,6 +320,10 @@ namespace ams::fs {
AMS_ABORT("TODO");
}
Result GetProgramId(ams::sf::Out<ncm::ProgramId> out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr) {
static_assert(sizeof(ncm::ProgramId) == sizeof(u64));
R_RETURN(fsGetProgramId(reinterpret_cast<u64 *>(out.GetPointer()), path.str, static_cast<::FsContentAttributes>(static_cast<u8>(attr))));
}
Result GetRightsIdByPath(ams::sf::Out<fs::RightsId> out, const fssrv::sf::FspPath &path) {
static_assert(sizeof(RightsId) == sizeof(::FsRightsId));

View file

@ -21,7 +21,7 @@ namespace ams::fs::impl {
#define ADD_ENUM_CASE(v) case v: return #v
template<> const char *IdString::ToString<pkg1::KeyGeneration>(pkg1::KeyGeneration id) {
static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_16_0_0);
static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_17_0_0);
switch (id) {
using enum pkg1::KeyGeneration;
case KeyGeneration_1_0_0: return "1.0.0-2.3.0";
@ -39,7 +39,8 @@ namespace ams::fs::impl {
case KeyGeneration_13_0_0: return "13.0.0-13.2.1";
case KeyGeneration_14_0_0: return "14.0.0-14.1.2";
case KeyGeneration_15_0_0: return "15.0.0-15.0.1";
case KeyGeneration_16_0_0: return "16.0.0-";
case KeyGeneration_16_0_0: return "16.0.0-16.0.3";
case KeyGeneration_17_0_0: return "17.0.0-";
default: return "Unknown";
}
}

View file

@ -26,6 +26,7 @@ namespace ams::ncm {
.content_count = src.content_count,
.content_meta_count = src.content_meta_count,
.attributes = src.attributes,
.platform = src.platform,
};
}
@ -42,6 +43,7 @@ namespace ams::ncm {
.content_count = src.content_count,
.content_meta_count = src.content_meta_count,
.attributes = src.attributes,
.platform = src.platform,
};
}

View file

@ -518,4 +518,20 @@ namespace ams::ncm {
R_RETURN(this->GetContentInfoImpl(out_content_info.GetPointer(), key, type, util::make_optional(id_offset)));
}
Result ContentMetaDatabaseImpl::GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) {
R_TRY(this->EnsureEnabled());
/* Obtain the content meta for the key. */
const void *meta;
size_t meta_size;
R_TRY(this->GetContentMetaPointer(&meta, &meta_size, key));
/* Create a reader. */
ContentMetaReader reader(meta, meta_size);
/* Set the ouput value. */
out.SetValue(reader.GetHeader()->platform);
R_SUCCEED();
}
}

View file

@ -64,6 +64,7 @@ namespace ams::ncm {
virtual Result GetContentAccessibilities(sf::Out<u8> out_accessibilities, const ContentMetaKey &key) override;
virtual Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type) override;
virtual Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) override;
virtual Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) override;
};
}

View file

@ -80,6 +80,7 @@ namespace ams::ncm {
virtual Result GetContentAccessibilities(sf::Out<u8> out_accessibilities, const ContentMetaKey &key) = 0;
virtual Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type) = 0;
virtual Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0;
virtual Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) = 0;
};
static_assert(ncm::IsIContentMetaDatabase<ContentMetaDatabaseImplBase>);

View file

@ -918,4 +918,19 @@ namespace ams::ncm {
R_THROW(ncm::ResultInvalidOperation());
}
Result ContentStorageImpl::GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr) {
R_TRY(this->EnsureEnabled());
/* Get the path of the content. */
Path path;
R_TRY(this->GetPath(std::addressof(path), content_id));
/* Obtain the program id for the content. */
ncm::ProgramId program_id;
R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr));
out.SetValue(program_id);
R_SUCCEED();
}
}

View file

@ -105,6 +105,7 @@ namespace ams::ncm {
virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) override;
virtual Result RegisterPath(const ContentId &content_id, const Path &path) override;
virtual Result ClearRegisteredPath() override;
virtual Result GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr) override;
};
}

View file

@ -79,6 +79,7 @@ namespace ams::ncm {
virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) = 0;
virtual Result RegisterPath(const ContentId &content_id, const Path &path) = 0;
virtual Result ClearRegisteredPath() = 0;
virtual Result GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr) = 0;
/* 16.0.0 Alignment change hacks. */
Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); }

View file

@ -224,4 +224,27 @@ namespace ams::ncm {
R_SUCCEED();
}
Result HostContentStorageImpl::GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr) {
R_TRY(this->EnsureEnabled());
/* Get the content path. */
Path path;
R_TRY(m_registered_content->GetPath(std::addressof(path), content_id));
/* Check for correct extension. */
const auto path_len = std::strlen(path.str);
const char *extension = path.str + path_len - 1;
if (*extension == '/') {
--extension;
}
R_UNLESS(path_len >= 4 && std::memcmp(extension - 4, ".ncd", 4) == 0, ncm::ResultInvalidContentMetaDirectory());
/* Obtain the program id for the content. */
ncm::ProgramId program_id;
R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr));
out.SetValue(program_id);
R_SUCCEED();
}
}

View file

@ -77,6 +77,7 @@ namespace ams::ncm {
Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr);
Result RegisterPath(const ContentId &content_id, const Path &path);
Result ClearRegisteredPath();
Result GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr);
/* 16.0.0 Alignment change hacks. */
Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); }

View file

@ -446,4 +446,21 @@ namespace ams::ncm {
}));
}
Result IntegratedContentMetaDatabaseImpl::GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) {
/* Lock ourselves. */
std::scoped_lock lk(m_mutex);
/* Check that we're enabled. */
R_TRY(this->EnsureEnabled());
/* Check that our list has interfaces to check. */
R_UNLESS(m_list.GetCount() > 0, ncm::ResultContentMetaNotFound());
/* Check each interface in turn. */
R_RETURN(m_list.TryEach([&](const auto &data) {
/* Try the current interface. */
R_RETURN(data.interface->GetPlatform(out, key));
}));
}
}

View file

@ -326,4 +326,31 @@ namespace ams::ncm {
R_THROW(ncm::ResultInvalidOperation());
}
Result IntegratedContentStorageImpl::GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr) {
/* Lock ourselves. */
std::scoped_lock lk(m_mutex);
/* Check that we're enabled. */
R_TRY(this->EnsureEnabled());
/* Check that our list has interfaces to check. */
R_UNLESS(m_list.GetCount() > 0, ncm::ResultContentNotFound());
/* Check each interface in turn. */
R_TRY(m_list.TryEach([&](const auto &data) {
/* Check if the current interface has it. */
bool has;
R_TRY(data.interface->Has(std::addressof(has), content_id));
/* If it doesn't, continue on. */
R_UNLESS(has, ncm::ResultContentNotFound());
/* If it does, read the file. */
R_RETURN(data.interface->GetProgramId(out, content_id, attr));
}));
R_SUCCEED();
}
}

View file

@ -297,4 +297,19 @@ namespace ams::ncm {
R_THROW(ncm::ResultInvalidOperation());
}
Result ReadOnlyContentStorageImpl::GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr) {
R_TRY(this->EnsureEnabled());
/* Get the path of the content. */
Path path;
R_TRY(this->GetPath(std::addressof(path), content_id));
/* Obtain the program id for the content. */
ncm::ProgramId program_id;
R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr));
out.SetValue(program_id);
R_SUCCEED();
}
}

View file

@ -58,6 +58,7 @@ namespace ams::ncm {
virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out<ncm::RightsId> out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) override;
virtual Result RegisterPath(const ContentId &content_id, const Path &path) override;
virtual Result ClearRegisteredPath() override;
virtual Result GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr) override;
};
}

View file

@ -186,6 +186,11 @@ namespace ams::ncm {
AMS_UNUSED(out_content_info, key, type, id_offset);
AMS_ABORT();
}
Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key) {
static_assert(sizeof(ncm::ContentMetaPlatform) == sizeof(u8));
R_RETURN(ncmContentMetaDatabaseGetPlatform(std::addressof(m_srv), reinterpret_cast<u8 *>(out.GetPointer()), Convert(key)));
}
};
static_assert(ncm::IsIContentMetaDatabase<RemoteContentMetaDatabaseImpl>);
#endif

View file

@ -219,6 +219,11 @@ namespace ams::ncm {
R_RETURN(ncmContentStorageClearRegisteredPath(std::addressof(m_srv)));
}
Result GetProgramId(sf::Out<ncm::ProgramId> out, ContentId content_id, fs::ContentAttributes attr) {
static_assert(sizeof(ncm::ProgramId) == sizeof(u64));
R_RETURN(ncmContentStorageGetProgramId(std::addressof(m_srv), reinterpret_cast<u64 *>(out.GetPointer()), Convert(content_id), Convert(attr)));
}
/* 16.0.0 Alignment change hacks. */
Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); }
Result Register_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id) { R_RETURN(this->Register(placeholder_id, content_id)); }