diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_api.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_api.cpp index 216ae2b53..f08498037 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_api.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_api.cpp @@ -34,7 +34,7 @@ namespace ams::sprofile::srv { constexpr const sm::ServiceName ServiceNameForSystemProcess = sm::ServiceName::Encode("sprof:sp"); constexpr inline size_t BgAgentSessionCountMax = 2; - constexpr inline size_t SystemProcessSessionCountMax = 5; + constexpr inline size_t SystemProcessSessionCountMax = 10; constexpr inline size_t SessionCountMax = BgAgentSessionCountMax + SystemProcessSessionCountMax; @@ -42,8 +42,8 @@ namespace ams::sprofile::srv { struct ServerManagerOptions { static constexpr size_t PointerBufferSize = 0x0; - static constexpr size_t MaxDomains = SessionCountMax; /* NOTE: Official is 3 */ - static constexpr size_t MaxDomainObjects = 16; /* NOTE: Official is 8 */ + static constexpr size_t MaxDomains = SessionCountMax; /* NOTE: Official is 9 */ + static constexpr size_t MaxDomainObjects = 16; /* NOTE: Official is 14 */ static constexpr bool CanDeferInvokeRequest = false; static constexpr bool CanManageMitmServers = false; }; diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_importer.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_importer.hpp index 4858abc95..556ebfe45 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_importer.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_importer.hpp @@ -18,8 +18,8 @@ #include "sprofile_srv_types.hpp" #define AMS_SPROFILE_I_PROFILE_IMPORTER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, ImportProfile, (const sprofile::srv::ProfileDataForImportData &data), (data)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, Commit, (), ()) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, ImportMetadata, (const sprofile::srv::ProfileMetadataForImportMetadata &data), (data)) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, ImportProfile, (const sprofile::srv::ProfileDataForImportData &import), (import)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, Commit, (), ()) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, ImportMetadata, (const sprofile::srv::ProfileMetadataForImportMetadata &import), (import)) \ AMS_SF_DEFINE_INTERFACE(ams::sprofile, IProfileImporter, AMS_SPROFILE_I_PROFILE_IMPORTER_INTERFACE_INFO) diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_reader.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_reader.hpp index 76d8310ef..ca1bc7153 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_reader.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_profile_reader.hpp @@ -21,6 +21,6 @@ AMS_SF_METHOD_INFO(C, H, 1, Result, GetUnsigned64, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \ AMS_SF_METHOD_INFO(C, H, 2, Result, GetSigned32, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \ AMS_SF_METHOD_INFO(C, H, 3, Result, GetUnsigned32, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, GetByte, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) + AMS_SF_METHOD_INFO(C, H, 4, Result, GetByte, (sf::Out out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) AMS_SF_DEFINE_INTERFACE(ams::sprofile, IProfileReader, AMS_SPROFILE_I_PROFILE_READER_INTERFACE_INFO) diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_service_for_bg_agent.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_service_for_bg_agent.hpp index e90cabe9d..5e9612d91 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_service_for_bg_agent.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_i_service_for_bg_agent.hpp @@ -18,9 +18,9 @@ #include "sprofile_srv_i_profile_importer.hpp" #define AMS_SPROFILE_I_SPROFILE_SERVICE_FOR_BG_AGENT_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 100, Result, OpenProfileImporter, (sf::Out> out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 200, Result, ReadMetadata, (sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ReadMetadataArgument &arg), (out_count, out, arg)) \ - AMS_SF_METHOD_INFO(C, H, 201, Result, IsUpdateNeeded, (sf::Out out, sprofile::Identifier revision_key), (out, revision_key)) \ - AMS_SF_METHOD_INFO(C, H, 2000, Result, Reset, (), ()) + AMS_SF_METHOD_INFO(C, H, 100, Result, OpenProfileImporter, (sf::Out> out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 200, Result, GetMetadataEntryData, (sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg), (out_count, out, arg)) \ + AMS_SF_METHOD_INFO(C, H, 201, Result, IsUpdateNeeded, (sf::Out out, sprofile::Identifier revision_key), (out, revision_key)) \ + AMS_SF_METHOD_INFO(C, H, 2000, Result, Reset, (), ()) AMS_SF_DEFINE_INTERFACE(ams::sprofile, ISprofileServiceForBgAgent, AMS_SPROFILE_I_SPROFILE_SERVICE_FOR_BG_AGENT_INTERFACE_INFO) diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer.hpp index fe91c19a2..6ed8ae2b6 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer.hpp @@ -38,7 +38,7 @@ namespace ams::sprofile::srv { bool HasProfile(Identifier id0, Identifier id1) { /* Require that we have metadata. */ if (m_metadata.has_value()) { - for (auto i = 0u; i < m_metadata->num_entries; ++i) { + for (auto i = 0u; i < std::min(m_metadata->num_entries, util::size(m_metadata->entries)); ++i) { const auto &entry = m_metadata->entries[i]; if (entry.identifier_0 == id0 && entry.identifier_1 == id1) { return true; @@ -63,7 +63,7 @@ namespace ams::sprofile::srv { m_revision_key = meta.revision_key; /* Import all profiles. */ - for (auto i = 0u; i < meta.num_entries; ++i) { + for (auto i = 0u; i < std::min(meta.num_entries, util::size(meta.entries)); ++i) { const auto &import_entry = meta.entries[i]; if (!this->HasProfile(import_entry.identifier_0, import_entry.identifier_1)) { m_importing_profiles[m_importing_count++] = import_entry.identifier_0; diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.cpp index 80bfe3070..8535c5604 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.cpp @@ -19,16 +19,16 @@ namespace ams::sprofile::srv { - Result ProfileImporterImpl::ImportProfile(const sprofile::srv::ProfileDataForImportData &data) { - return m_manager->ImportProfile(data); + Result ProfileImporterImpl::ImportProfile(const sprofile::srv::ProfileDataForImportData &import) { + return m_manager->ImportProfile(import); } Result ProfileImporterImpl::Commit() { return m_manager->Commit(); } - Result ProfileImporterImpl::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &data) { - return m_manager->ImportMetadata(data); + Result ProfileImporterImpl::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import) { + return m_manager->ImportMetadata(import); } } diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.hpp index 9e961c788..6ffea3a6c 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_importer_impl.hpp @@ -27,9 +27,9 @@ namespace ams::sprofile::srv { public: ProfileImporterImpl(ProfileManager *manager) : m_manager(manager) { /* ... */ } public: - Result ImportProfile(const sprofile::srv::ProfileDataForImportData &data); + Result ImportProfile(const sprofile::srv::ProfileDataForImportData &import); Result Commit(); - Result ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &data); + Result ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import); }; static_assert(IsIProfileImporter); diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.cpp index a9579b9f5..899bf3318 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_profile_manager.cpp @@ -151,7 +151,7 @@ namespace ams::sprofile::srv { return ResultSuccess(); } - Result ProfileManager::ImportProfile(const sprofile::srv::ProfileDataForImportData &data) { + Result ProfileManager::ImportProfile(const sprofile::srv::ProfileDataForImportData &import) { /* Acquire locks. */ std::scoped_lock lk1(m_profile_importer_mutex); std::scoped_lock lk2(m_fs_mutex); @@ -159,25 +159,37 @@ namespace ams::sprofile::srv { /* Check that we have an importer. */ R_UNLESS(m_profile_importer.has_value(), sprofile::ResultInvalidState()); - /* Check that the metadata we're importing is valid. */ - R_UNLESS(data.data.version == ProfileDataVersion, sprofile::ResultInvalidDataVersion()); + /* Check that the metadata we're importing is a valid version. */ + R_UNLESS(IsValidProfileFormatVersion(import.header.version), sprofile::ResultInvalidDataVersion()); + + /* Check that the metadata we're importing has a valid hash. */ + { + crypto::Md5Generator md5; + md5.Update(std::addressof(import.header), sizeof(import.header)); + md5.Update(std::addressof(import.data), sizeof(import.data) - sizeof(import.data.entries[0]) * (util::size(import.data.entries) - std::min(import.data.num_entries, util::size(import.data.entries)))); + + u8 hash[crypto::Md5Generator::HashSize]; + md5.GetHash(hash, sizeof(hash)); + + R_UNLESS(crypto::IsSameBytes(hash, import.hash, sizeof(hash)), sprofile::ResultInvalidDataHash()); + } /* Succeed if we already have the profile. */ - R_SUCCEED_IF(m_profile_importer->HasProfile(data.identifier_0, data.identifier_1)); + R_SUCCEED_IF(m_profile_importer->HasProfile(import.header.identifier_0, import.header.identifier_1)); /* Check that we're importing the profile. */ - R_UNLESS(m_profile_importer->CanImportProfile(data.identifier_0), sprofile::ResultInvalidState()); + R_UNLESS(m_profile_importer->CanImportProfile(import.header.identifier_0), sprofile::ResultInvalidState()); /* Create temporary directories. */ R_TRY(this->EnsureTemporaryDirectories()); /* Create profile. */ char path[0x30]; - CreateTemporaryProfilePath(path, sizeof(path), m_save_data_info.mount_name, data.identifier_0); - R_TRY(WriteFile(path, std::addressof(data.data), sizeof(data.data))); + CreateTemporaryProfilePath(path, sizeof(path), m_save_data_info.mount_name, import.header.identifier_0); + R_TRY(WriteFile(path, std::addressof(import.data), sizeof(import.data))); /* Set profile imported. */ - m_profile_importer->OnImportProfile(data.identifier_0); + m_profile_importer->OnImportProfile(import.header.identifier_0); return ResultSuccess(); } @@ -231,7 +243,7 @@ namespace ams::sprofile::srv { return ResultSuccess(); } - Result ProfileManager::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &data) { + Result ProfileManager::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import) { /* Acquire locks. */ std::scoped_lock lk1(m_profile_importer_mutex); std::scoped_lock lk2(m_fs_mutex); @@ -240,8 +252,21 @@ namespace ams::sprofile::srv { R_UNLESS(m_profile_importer.has_value(), sprofile::ResultInvalidState()); R_UNLESS(m_profile_importer->CanImportMetadata(), sprofile::ResultInvalidState()); - /* Check that the metadata we're importing is valid. */ - R_UNLESS(data.metadata.version == ProfileMetadataVersion, sprofile::ResultInvalidMetadataVersion()); + /* Check that the metadata we're importing is a valid version. */ + R_UNLESS(IsValidProfileFormatVersion(import.header.version), sprofile::ResultInvalidMetadataVersion()); + + /* Check that the metadata we're importing has a valid hash. */ + { + crypto::Md5Generator md5; + md5.Update(std::addressof(import.header), sizeof(import.header)); + md5.Update(std::addressof(import.metadata), sizeof(import.metadata)); + md5.Update(std::addressof(import.entries), sizeof(import.entries[0]) * std::min(import.metadata.num_entries, util::size(import.metadata.entries))); + + u8 hash[crypto::Md5Generator::HashSize]; + md5.GetHash(hash, sizeof(hash)); + + R_UNLESS(crypto::IsSameBytes(hash, import.hash, sizeof(hash)), sprofile::ResultInvalidMetadataHash()); + } /* Create temporary directories. */ R_TRY(this->EnsureTemporaryDirectories()); @@ -249,10 +274,10 @@ namespace ams::sprofile::srv { /* Create metadata. */ char path[0x30]; CreateTemporaryMetadataPath(path, sizeof(path), m_save_data_info.mount_name); - R_TRY(WriteFile(path, std::addressof(data.metadata), sizeof(data.metadata))); + R_TRY(WriteFile(path, std::addressof(import.metadata), sizeof(import.metadata))); /* Import the metadata. */ - m_profile_importer->ImportMetadata(data.metadata); + m_profile_importer->ImportMetadata(import.metadata); return ResultSuccess(); } @@ -309,13 +334,13 @@ namespace ams::sprofile::srv { std::scoped_lock lk2(m_general_mutex); /* Load the desired profile. */ - R_TRY(this->LoadProfile(profile)); - - /* Find the specified key. */ - for (auto i = 0u; i < m_service_profile->data.num_entries; ++i) { - if (m_service_profile->data.entries[i].key == key) { - *out = m_service_profile->data.entries[i]; - return ResultSuccess(); + if (R_SUCCEEDED(this->LoadProfile(profile))) { + /* Find the specified key. */ + for (auto i = 0u; i < std::min(m_service_profile->data.num_entries, util::size(m_service_profile->data.entries)); ++i) { + if (m_service_profile->data.entries[i].key == key) { + *out = m_service_profile->data.entries[i]; + return ResultSuccess(); + } } } @@ -426,6 +451,8 @@ namespace ams::sprofile::srv { } void ProfileManager::OnCommitted() { + /* TODO: Here, Nintendo sets the erpt ServiceProfileRevisionKey to the current revision key. */ + /* If we need to, invalidate the loaded service profile. */ if (m_service_profile.has_value()) { for (auto i = 0; i < m_profile_importer->GetImportingCount(); ++i) { @@ -436,8 +463,6 @@ namespace ams::sprofile::srv { } } - /* TODO: Here, Nintendo sets the erpt ServiceProfileRevisionKey to the current revision key. */ - /* Reset profile metadata. */ m_profile_metadata = util::nullopt; @@ -445,6 +470,9 @@ namespace ams::sprofile::srv { for (auto i = 0; i < m_profile_importer->GetImportingCount(); ++i) { m_update_observer_manager.OnUpdate(m_profile_importer->GetImportingProfile(i)); } + + /* Reset profile importer. */ + m_profile_importer = util::nullopt; } Result ProfileManager::EnsurePrimaryDirectories() { diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.cpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.cpp index 2c8bb0d44..62653d13a 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.cpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.cpp @@ -34,7 +34,7 @@ namespace ams::sprofile::srv { return ResultSuccess(); } - Result ServiceForBgAgent::ReadMetadata(sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ReadMetadataArgument &arg) { + Result ServiceForBgAgent::GetMetadataEntryData(sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg) { /* Check size. */ R_UNLESS(out.GetSize() >= arg.metadata.num_entries, sprofile::ResultInvalidArgument()); diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.hpp index 986223d66..d7508a250 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_service_for_bg_agent.hpp @@ -29,7 +29,7 @@ namespace ams::sprofile::srv { constexpr ServiceForBgAgent(MemoryResource *mr, ProfileManager *pm) : m_memory_resource(mr), m_profile_manager(pm) { /* ... */ } public: Result OpenProfileImporter(sf::Out> out); - Result ReadMetadata(sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ReadMetadataArgument &arg); + Result GetMetadataEntryData(sf::Out out_count, const sf::OutArray &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg); Result IsUpdateNeeded(sf::Out out, Identifier revision_key); Result Reset(); }; diff --git a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_types.hpp b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_types.hpp index 421ec2b69..43c9e28f0 100644 --- a/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_types.hpp +++ b/libraries/libstratosphere/source/sprofile/srv/sprofile_srv_types.hpp @@ -18,34 +18,11 @@ namespace ams::sprofile::srv { - struct ProfileMetadataEntry { - Identifier identifier_0; - Identifier identifier_1; - u8 unk_0E[0x32]; - }; - static_assert(util::is_pod::value); - static_assert(sizeof(ProfileMetadataEntry) == 0x40); + constexpr inline const u32 ProfileFormatVersion = 1; - constexpr inline const u32 ProfileMetadataVersion = 0; - - struct ProfileMetadata { - u32 version; - u32 num_entries; - Identifier revision_key; - u8 unk_10[0x30]; - ProfileMetadataEntry entries[50]; - }; - static_assert(util::is_pod::value); - static_assert(sizeof(ProfileMetadata) == 0xCC0); - - struct ProfileMetadataForImportMetadata : public sf::LargeData, public sf::PrefersMapAliasTransferMode { - ProfileMetadata metadata; - u8 unk[0x8000 - sizeof(metadata)]; - }; - static_assert(util::is_pod::value); - static_assert(sizeof(ProfileMetadataForImportMetadata) == 0x8000); - - constexpr inline const u32 ProfileDataVersion = 0; + constexpr inline bool IsValidProfileFormatVersion(u32 version) { + return version == ProfileFormatVersion; + } enum ValueType : u8 { ValueType_Byte = 0, @@ -70,9 +47,9 @@ namespace ams::sprofile::srv { static_assert(sizeof(ProfileDataEntry) == 0x10); struct ProfileData { - u32 version; u32 num_entries; - u8 unk_08[0x28]; + u8 unk_04[0x0C]; + u8 unk_10[0x20]; ProfileDataEntry entries[(0x4000 - 0x30) / sizeof(ProfileDataEntry)]; }; static_assert(util::is_pod::value); @@ -86,28 +63,55 @@ namespace ams::sprofile::srv { static_assert(sizeof(ServiceProfile) == 0x4008); struct ProfileDataForImportData : public sf::LargeData, public sf::PrefersMapAliasTransferMode { - Identifier identifier_0; - Identifier identifier_1; - u8 unk_0E[2]; + struct { + Identifier identifier_0; + Identifier identifier_1; + u8 unk_0E[2]; + u32 version; + u8 unk_14[0x1C]; + } header; + u8 hash[crypto::Md5Generator::HashSize]; ProfileData data; - u8 unk_4010[0x4400 - 0x4010]; + u8 unk_4040[0x4400 - 0x4040]; }; static_assert(util::is_pod::value); static_assert(sizeof(ProfileDataForImportData) == 0x4400); - struct ReadMetadataEntry { + struct ProfileMetadataEntry { + Identifier identifier_0; + Identifier identifier_1; + u8 unk_0E[0x32]; + }; + static_assert(util::is_pod::value); + static_assert(sizeof(ProfileMetadataEntry) == 0x40); + + struct ProfileMetadataEntryData : public sf::PrefersMapAliasTransferMode { u8 unk[0x100]; }; - static_assert(util::is_pod::value); - static_assert(sizeof(ReadMetadataEntry) == 0x100); + static_assert(util::is_pod::value); + static_assert(sizeof(ProfileMetadataEntryData) == 0x100); - struct ReadMetadataArgument : public sf::LargeData, public sf::PrefersMapAliasTransferMode { - ProfileMetadata metadata; - ReadMetadataEntry entries[(0x8000 - sizeof(metadata)) / sizeof(ReadMetadataEntry)]; - u8 unk_7FC0[0x40]; + struct ProfileMetadata { + u32 num_entries; + u32 unk_04; + Identifier revision_key; + u8 unk_10[0x30]; + ProfileMetadataEntry entries[50]; }; - static_assert(util::is_pod::value); - static_assert(sizeof(ReadMetadataArgument) == 0x8000); + static_assert(util::is_pod::value); + static_assert(sizeof(ProfileMetadata) == 0xCC0); + struct ProfileMetadataForImportMetadata : public sf::LargeData, public sf::PrefersMapAliasTransferMode { + struct { + u32 version; + u8 unk_04[0x1C]; + } header; + u8 hash[crypto::Md5Generator::HashSize]; + ProfileMetadata metadata; + ProfileMetadataEntryData entries[50]; + u8 unk[0x8000 - 0x3EF0]; + }; + static_assert(util::is_pod::value); + static_assert(sizeof(ProfileMetadataForImportMetadata) == 0x8000); } diff --git a/libraries/libvapours/include/vapours/results/sprofile_results.hpp b/libraries/libvapours/include/vapours/results/sprofile_results.hpp index dafa9dad7..8772bdb0c 100644 --- a/libraries/libvapours/include/vapours/results/sprofile_results.hpp +++ b/libraries/libvapours/include/vapours/results/sprofile_results.hpp @@ -37,6 +37,8 @@ namespace ams::sprofile { R_DEFINE_ERROR_RESULT(MaxObservers, 623); R_DEFINE_ERROR_RESULT(InvalidMetadataVersion, 3210); + R_DEFINE_ERROR_RESULT(InvalidMetadataHash, 3211); R_DEFINE_ERROR_RESULT(InvalidDataVersion, 3230); + R_DEFINE_ERROR_RESULT(InvalidDataHash, 3231); }