mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
ncm: update for new 17.0.0 apis
This commit is contained in:
parent
ef9b111bbf
commit
c95741142e
31 changed files with 249 additions and 7 deletions
|
@ -63,6 +63,7 @@
|
|||
#include <stratosphere/fs/fs_signed_system_partition.hpp>
|
||||
#include <stratosphere/fs/fs_system_data.hpp>
|
||||
#include <stratosphere/fs/fs_program_index_map_info.hpp>
|
||||
#include <stratosphere/fs/fs_program_id.hpp>
|
||||
#include <stratosphere/fs/impl/fs_access_log_impl.hpp>
|
||||
#include <stratosphere/fs/impl/fs_hash_generator_factory_selector.hpp>
|
||||
#include <stratosphere/fs/impl/fs_storage_service_object_adapter.hpp>
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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>
|
||||
#include <stratosphere/ncm/ncm_ids.hpp>
|
||||
|
||||
namespace ams::fs {
|
||||
|
||||
/* ACCURATE_TO_VERSION: 17.5.0.0 */
|
||||
Result GetProgramId(ncm::ProgramId *out, const char *path, fs::ContentAttributes attr);
|
||||
|
||||
}
|
|
@ -104,6 +104,7 @@ namespace ams::fssrv {
|
|||
Result GetRightsId(ams::sf::Out<fs::RightsId> out, ncm::ProgramId program_id, ncm::StorageId storage_id);
|
||||
Result RegisterExternalKey(const fs::RightsId &rights_id, const spl::AccessKey &access_key);
|
||||
Result UnregisterAllExternalKey();
|
||||
Result GetProgramId(ams::sf::Out<ncm::ProgramId> out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr);
|
||||
Result GetRightsIdByPath(ams::sf::Out<fs::RightsId> out, const fssrv::sf::FspPath &path);
|
||||
Result GetRightsIdAndKeyGenerationByPathObsolete(ams::sf::Out<fs::RightsId> out, ams::sf::Out<u8> out_key_generation, const fssrv::sf::FspPath &path);
|
||||
Result GetRightsIdAndKeyGenerationByPath(ams::sf::Out<fs::RightsId> out, ams::sf::Out<u8> out_key_generation, const fssrv::sf::FspPath &path, fs::ContentAttributes attr);
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
AMS_SF_METHOD_INFO(C, H, 615, Result, QuerySaveDataInternalStorageTotalSize, (), (), hos::Version_5_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 616, Result, GetSaveDataCommitId, (), (), hos::Version_6_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 617, Result, UnregisterExternalKey, (const fs::RightsId &rights_id), (rights_id), hos::Version_7_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 618, Result, GetProgramId, (ams::sf::Out<ncm::ProgramId> out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr), (out, path, attr), hos::Version_17_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 620, Result, SetSdCardEncryptionSeed, (const fs::EncryptionSeed &seed), (seed), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 630, Result, SetSdCardAccessibility, (bool accessible), (accessible), hos::Version_4_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 631, Result, IsSdCardAccessible, (ams::sf::Out<bool> out), (out), hos::Version_4_0_0) \
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#pragma once
|
||||
#include <stratosphere/ncm/ncm_content_meta_id.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_key.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_meta_platform.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_info.hpp>
|
||||
#include <stratosphere/ncm/ncm_content_info_data.hpp>
|
||||
#include <stratosphere/ncm/ncm_firmware_variation.hpp>
|
||||
|
@ -58,7 +59,7 @@ namespace ams::ncm {
|
|||
u16 content_count;
|
||||
u16 content_meta_count;
|
||||
u8 attributes;
|
||||
StorageId storage_id;
|
||||
ContentMetaPlatform platform;
|
||||
};
|
||||
|
||||
static_assert(sizeof(ContentMetaHeader) == 0x8);
|
||||
|
@ -67,7 +68,7 @@ namespace ams::ncm {
|
|||
u64 id;
|
||||
u32 version;
|
||||
ContentMetaType type;
|
||||
u8 reserved_0D;
|
||||
ContentMetaPlatform platform;
|
||||
u16 extended_header_size;
|
||||
u16 content_count;
|
||||
u16 content_meta_count;
|
||||
|
@ -79,7 +80,6 @@ namespace ams::ncm {
|
|||
u8 reserved_1C[4];
|
||||
};
|
||||
static_assert(sizeof(PackagedContentMetaHeader) == 0x20);
|
||||
static_assert(AMS_OFFSETOF(PackagedContentMetaHeader, reserved_0D) == 0x0D);
|
||||
static_assert(AMS_OFFSETOF(PackagedContentMetaHeader, reserved_1C) == 0x1C);
|
||||
|
||||
using InstallContentMetaHeader = PackagedContentMetaHeader;
|
||||
|
|
|
@ -221,6 +221,11 @@ namespace ams::ncm {
|
|||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetContentInfoByTypeAndIdOffset(out_content_info, key, type, id_offset));
|
||||
}
|
||||
|
||||
Result GetPlatform(ContentMetaPlatform *out, const ContentMetaKey &key) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetPlatform(out, key));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
namespace ams::ncm {
|
||||
|
||||
enum class ContentMetaPlatform : u8 {
|
||||
Nx = 0x0,
|
||||
};
|
||||
|
||||
}
|
|
@ -207,6 +207,11 @@ namespace ams::ncm {
|
|||
R_RETURN(m_interface->GetRightsIdFromPlaceHolderIdWithCacheDeprecated(out_rights_id, cache_content_id, placeholder_id));
|
||||
}
|
||||
}
|
||||
|
||||
Result GetProgramId(ncm::ProgramId *out, ContentId content_id, fs::ContentAttributes attr) {
|
||||
AMS_ASSERT(m_interface != nullptr);
|
||||
R_RETURN(m_interface->GetProgramId(out, content_id, attr));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
AMS_SF_METHOD_INFO(C, H, 22, Result, GetOwnerApplicationId, (sf::Out<ncm::ApplicationId> out_id, const ncm::ContentMetaKey &key), (out_id, key), hos::Version_10_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 23, Result, GetContentAccessibilities, (sf::Out<u8> out_accessibilities, const ncm::ContentMetaKey &key), (out_accessibilities, key), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 24, Result, GetContentInfoByType, (sf::Out<ncm::ContentInfo> out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type), (out_content_info, key, type), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 25, Result, GetContentInfoByTypeAndIdOffset, (sf::Out<ncm::ContentInfo> out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_info, key, type, id_offset), hos::Version_15_0_0)
|
||||
AMS_SF_METHOD_INFO(C, H, 25, Result, GetContentInfoByTypeAndIdOffset, (sf::Out<ncm::ContentInfo> out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_info, key, type, id_offset), hos::Version_15_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out<ncm::ContentMetaPlatform> out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0)
|
||||
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentMetaDatabase, AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO, 0x58021FEC)
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
AMS_SF_METHOD_INFO(C, H, 27, Result, GetRightsIdFromPlaceHolderIdWithCacheDeprecated, (sf::Out<ncm::RightsId> out_rights_id, ncm::ContentId cache_content_id, ncm::PlaceHolderId placeholder_id), (out_rights_id, cache_content_id, placeholder_id), hos::Version_8_0_0, hos::Version_15_0_1) \
|
||||
AMS_SF_METHOD_INFO(C, H, 27, Result, GetRightsIdFromPlaceHolderIdWithCache, (sf::Out<ncm::RightsId> out_rights_id, ncm::PlaceHolderId placeholder_id, ncm::ContentId cache_content_id, fs::ContentAttributes attr), (out_rights_id, placeholder_id, cache_content_id, attr), hos::Version_16_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 28, Result, RegisterPath, (const ncm::ContentId &content_id, const ncm::Path &path), (content_id, path), hos::Version_13_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 29, Result, ClearRegisteredPath, (), (), hos::Version_13_0_0)
|
||||
AMS_SF_METHOD_INFO(C, H, 29, Result, ClearRegisteredPath, (), (), hos::Version_13_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 30, Result, GetProgramId, (sf::Out<ncm::ProgramId> out, ncm::ContentId content_id, fs::ContentAttributes attr), (out, content_id, attr), hos::Version_17_0_0)
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentStorage, AMS_NCM_I_CONTENT_STORAGE_INTERFACE_INFO, 0xFEAE3DD1)
|
||||
|
|
|
@ -71,6 +71,7 @@ namespace ams::ncm {
|
|||
Result GetContentAccessibilities(sf::Out<u8> out_accessibilities, const ContentMetaKey &key);
|
||||
Result GetContentInfoByType(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type);
|
||||
Result GetContentInfoByTypeAndIdOffset(sf::Out<ContentInfo> out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset);
|
||||
Result GetPlatform(sf::Out<ncm::ContentMetaPlatform> out, const ContentMetaKey &key);
|
||||
};
|
||||
static_assert(ncm::IsIContentMetaDatabase<IntegratedContentMetaDatabaseImpl>);
|
||||
|
||||
|
|
|
@ -79,6 +79,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)); }
|
||||
|
|
36
libraries/libstratosphere/source/fs/fs_program_id.cpp
Normal file
36
libraries/libstratosphere/source/fs/fs_program_id.cpp
Normal 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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>);
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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)); }
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)); }
|
||||
|
|
|
@ -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));
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)); }
|
||||
|
|
|
@ -54,6 +54,8 @@ namespace ams::ncm {
|
|||
R_DEFINE_ERROR_RESULT(InvalidContentMetaFileSize, 390);
|
||||
R_DEFINE_ERROR_RESULT(InvalidAddOnContentMetaExtendedHeader, 400);
|
||||
|
||||
R_DEFINE_ERROR_RESULT(InvalidContentMetaDirectory, 430);
|
||||
|
||||
R_DEFINE_ERROR_RANGE(ContentStorageNotActive, 250, 258);
|
||||
R_DEFINE_ERROR_RESULT(GameCardContentStorageNotActive, 251);
|
||||
R_DEFINE_ERROR_RESULT(BuiltInSystemContentStorageNotActive, 252);
|
||||
|
|
Loading…
Reference in a new issue