mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
sprof: update for 13.1.0 (format version 1)
This commit is contained in:
parent
a14dc6ed89
commit
0e81eac9d1
12 changed files with 119 additions and 85 deletions
|
@ -34,7 +34,7 @@ namespace ams::sprofile::srv {
|
||||||
constexpr const sm::ServiceName ServiceNameForSystemProcess = sm::ServiceName::Encode("sprof:sp");
|
constexpr const sm::ServiceName ServiceNameForSystemProcess = sm::ServiceName::Encode("sprof:sp");
|
||||||
|
|
||||||
constexpr inline size_t BgAgentSessionCountMax = 2;
|
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;
|
constexpr inline size_t SessionCountMax = BgAgentSessionCountMax + SystemProcessSessionCountMax;
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ namespace ams::sprofile::srv {
|
||||||
|
|
||||||
struct ServerManagerOptions {
|
struct ServerManagerOptions {
|
||||||
static constexpr size_t PointerBufferSize = 0x0;
|
static constexpr size_t PointerBufferSize = 0x0;
|
||||||
static constexpr size_t MaxDomains = SessionCountMax; /* NOTE: Official is 3 */
|
static constexpr size_t MaxDomains = SessionCountMax; /* NOTE: Official is 9 */
|
||||||
static constexpr size_t MaxDomainObjects = 16; /* NOTE: Official is 8 */
|
static constexpr size_t MaxDomainObjects = 16; /* NOTE: Official is 14 */
|
||||||
static constexpr bool CanDeferInvokeRequest = false;
|
static constexpr bool CanDeferInvokeRequest = false;
|
||||||
static constexpr bool CanManageMitmServers = false;
|
static constexpr bool CanManageMitmServers = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
#include "sprofile_srv_types.hpp"
|
#include "sprofile_srv_types.hpp"
|
||||||
|
|
||||||
#define AMS_SPROFILE_I_PROFILE_IMPORTER_INTERFACE_INFO(C, H) \
|
#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, 0, Result, ImportProfile, (const sprofile::srv::ProfileDataForImportData &import), (import)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 1, Result, Commit, (), ()) \
|
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, 2, Result, ImportMetadata, (const sprofile::srv::ProfileMetadataForImportMetadata &import), (import)) \
|
||||||
|
|
||||||
AMS_SF_DEFINE_INTERFACE(ams::sprofile, IProfileImporter, AMS_SPROFILE_I_PROFILE_IMPORTER_INTERFACE_INFO)
|
AMS_SF_DEFINE_INTERFACE(ams::sprofile, IProfileImporter, AMS_SPROFILE_I_PROFILE_IMPORTER_INTERFACE_INFO)
|
||||||
|
|
|
@ -21,6 +21,6 @@
|
||||||
AMS_SF_METHOD_INFO(C, H, 1, Result, GetUnsigned64, (sf::Out<u64> out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \
|
AMS_SF_METHOD_INFO(C, H, 1, Result, GetUnsigned64, (sf::Out<u64> out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 2, Result, GetSigned32, (sf::Out<s32> out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \
|
AMS_SF_METHOD_INFO(C, H, 2, Result, GetSigned32, (sf::Out<s32> out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetUnsigned32, (sf::Out<u32> out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \
|
AMS_SF_METHOD_INFO(C, H, 3, Result, GetUnsigned32, (sf::Out<u32> out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetByte, (sf::Out<u8> out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key))
|
AMS_SF_METHOD_INFO(C, H, 4, Result, GetByte, (sf::Out<u8> out, sprofile::Identifier profile, sprofile::Identifier key), (out, profile, key))
|
||||||
|
|
||||||
AMS_SF_DEFINE_INTERFACE(ams::sprofile, IProfileReader, AMS_SPROFILE_I_PROFILE_READER_INTERFACE_INFO)
|
AMS_SF_DEFINE_INTERFACE(ams::sprofile, IProfileReader, AMS_SPROFILE_I_PROFILE_READER_INTERFACE_INFO)
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
#include "sprofile_srv_i_profile_importer.hpp"
|
#include "sprofile_srv_i_profile_importer.hpp"
|
||||||
|
|
||||||
#define AMS_SPROFILE_I_SPROFILE_SERVICE_FOR_BG_AGENT_INTERFACE_INFO(C, H) \
|
#define AMS_SPROFILE_I_SPROFILE_SERVICE_FOR_BG_AGENT_INTERFACE_INFO(C, H) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 100, Result, OpenProfileImporter, (sf::Out<sf::SharedPointer<::ams::sprofile::IProfileImporter>> out), (out)) \
|
AMS_SF_METHOD_INFO(C, H, 100, Result, OpenProfileImporter, (sf::Out<sf::SharedPointer<::ams::sprofile::IProfileImporter>> out), (out)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 200, Result, ReadMetadata, (sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ReadMetadataEntry> &out, const sprofile::srv::ReadMetadataArgument &arg), (out_count, out, arg)) \
|
AMS_SF_METHOD_INFO(C, H, 200, Result, GetMetadataEntryData, (sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ProfileMetadataEntryData> &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg), (out_count, out, arg)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 201, Result, IsUpdateNeeded, (sf::Out<bool> out, sprofile::Identifier revision_key), (out, revision_key)) \
|
AMS_SF_METHOD_INFO(C, H, 201, Result, IsUpdateNeeded, (sf::Out<bool> out, sprofile::Identifier revision_key), (out, revision_key)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 2000, Result, Reset, (), ())
|
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)
|
AMS_SF_DEFINE_INTERFACE(ams::sprofile, ISprofileServiceForBgAgent, AMS_SPROFILE_I_SPROFILE_SERVICE_FOR_BG_AGENT_INTERFACE_INFO)
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace ams::sprofile::srv {
|
||||||
bool HasProfile(Identifier id0, Identifier id1) {
|
bool HasProfile(Identifier id0, Identifier id1) {
|
||||||
/* Require that we have metadata. */
|
/* Require that we have metadata. */
|
||||||
if (m_metadata.has_value()) {
|
if (m_metadata.has_value()) {
|
||||||
for (auto i = 0u; i < m_metadata->num_entries; ++i) {
|
for (auto i = 0u; i < std::min<size_t>(m_metadata->num_entries, util::size(m_metadata->entries)); ++i) {
|
||||||
const auto &entry = m_metadata->entries[i];
|
const auto &entry = m_metadata->entries[i];
|
||||||
if (entry.identifier_0 == id0 && entry.identifier_1 == id1) {
|
if (entry.identifier_0 == id0 && entry.identifier_1 == id1) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -63,7 +63,7 @@ namespace ams::sprofile::srv {
|
||||||
m_revision_key = meta.revision_key;
|
m_revision_key = meta.revision_key;
|
||||||
|
|
||||||
/* Import all profiles. */
|
/* Import all profiles. */
|
||||||
for (auto i = 0u; i < meta.num_entries; ++i) {
|
for (auto i = 0u; i < std::min<size_t>(meta.num_entries, util::size(meta.entries)); ++i) {
|
||||||
const auto &import_entry = meta.entries[i];
|
const auto &import_entry = meta.entries[i];
|
||||||
if (!this->HasProfile(import_entry.identifier_0, import_entry.identifier_1)) {
|
if (!this->HasProfile(import_entry.identifier_0, import_entry.identifier_1)) {
|
||||||
m_importing_profiles[m_importing_count++] = import_entry.identifier_0;
|
m_importing_profiles[m_importing_count++] = import_entry.identifier_0;
|
||||||
|
|
|
@ -19,16 +19,16 @@
|
||||||
|
|
||||||
namespace ams::sprofile::srv {
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
Result ProfileImporterImpl::ImportProfile(const sprofile::srv::ProfileDataForImportData &data) {
|
Result ProfileImporterImpl::ImportProfile(const sprofile::srv::ProfileDataForImportData &import) {
|
||||||
return m_manager->ImportProfile(data);
|
return m_manager->ImportProfile(import);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ProfileImporterImpl::Commit() {
|
Result ProfileImporterImpl::Commit() {
|
||||||
return m_manager->Commit();
|
return m_manager->Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ProfileImporterImpl::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &data) {
|
Result ProfileImporterImpl::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import) {
|
||||||
return m_manager->ImportMetadata(data);
|
return m_manager->ImportMetadata(import);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,9 @@ namespace ams::sprofile::srv {
|
||||||
public:
|
public:
|
||||||
ProfileImporterImpl(ProfileManager *manager) : m_manager(manager) { /* ... */ }
|
ProfileImporterImpl(ProfileManager *manager) : m_manager(manager) { /* ... */ }
|
||||||
public:
|
public:
|
||||||
Result ImportProfile(const sprofile::srv::ProfileDataForImportData &data);
|
Result ImportProfile(const sprofile::srv::ProfileDataForImportData &import);
|
||||||
Result Commit();
|
Result Commit();
|
||||||
Result ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &data);
|
Result ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import);
|
||||||
};
|
};
|
||||||
static_assert(IsIProfileImporter<ProfileImporterImpl>);
|
static_assert(IsIProfileImporter<ProfileImporterImpl>);
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ namespace ams::sprofile::srv {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ProfileManager::ImportProfile(const sprofile::srv::ProfileDataForImportData &data) {
|
Result ProfileManager::ImportProfile(const sprofile::srv::ProfileDataForImportData &import) {
|
||||||
/* Acquire locks. */
|
/* Acquire locks. */
|
||||||
std::scoped_lock lk1(m_profile_importer_mutex);
|
std::scoped_lock lk1(m_profile_importer_mutex);
|
||||||
std::scoped_lock lk2(m_fs_mutex);
|
std::scoped_lock lk2(m_fs_mutex);
|
||||||
|
@ -159,25 +159,37 @@ namespace ams::sprofile::srv {
|
||||||
/* Check that we have an importer. */
|
/* Check that we have an importer. */
|
||||||
R_UNLESS(m_profile_importer.has_value(), sprofile::ResultInvalidState());
|
R_UNLESS(m_profile_importer.has_value(), sprofile::ResultInvalidState());
|
||||||
|
|
||||||
/* Check that the metadata we're importing is valid. */
|
/* Check that the metadata we're importing is a valid version. */
|
||||||
R_UNLESS(data.data.version == ProfileDataVersion, sprofile::ResultInvalidDataVersion());
|
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<size_t>(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. */
|
/* 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. */
|
/* 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. */
|
/* Create temporary directories. */
|
||||||
R_TRY(this->EnsureTemporaryDirectories());
|
R_TRY(this->EnsureTemporaryDirectories());
|
||||||
|
|
||||||
/* Create profile. */
|
/* Create profile. */
|
||||||
char path[0x30];
|
char path[0x30];
|
||||||
CreateTemporaryProfilePath(path, sizeof(path), m_save_data_info.mount_name, data.identifier_0);
|
CreateTemporaryProfilePath(path, sizeof(path), m_save_data_info.mount_name, import.header.identifier_0);
|
||||||
R_TRY(WriteFile(path, std::addressof(data.data), sizeof(data.data)));
|
R_TRY(WriteFile(path, std::addressof(import.data), sizeof(import.data)));
|
||||||
|
|
||||||
/* Set profile imported. */
|
/* Set profile imported. */
|
||||||
m_profile_importer->OnImportProfile(data.identifier_0);
|
m_profile_importer->OnImportProfile(import.header.identifier_0);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +243,7 @@ namespace ams::sprofile::srv {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ProfileManager::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &data) {
|
Result ProfileManager::ImportMetadata(const sprofile::srv::ProfileMetadataForImportMetadata &import) {
|
||||||
/* Acquire locks. */
|
/* Acquire locks. */
|
||||||
std::scoped_lock lk1(m_profile_importer_mutex);
|
std::scoped_lock lk1(m_profile_importer_mutex);
|
||||||
std::scoped_lock lk2(m_fs_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.has_value(), sprofile::ResultInvalidState());
|
||||||
R_UNLESS(m_profile_importer->CanImportMetadata(), sprofile::ResultInvalidState());
|
R_UNLESS(m_profile_importer->CanImportMetadata(), sprofile::ResultInvalidState());
|
||||||
|
|
||||||
/* Check that the metadata we're importing is valid. */
|
/* Check that the metadata we're importing is a valid version. */
|
||||||
R_UNLESS(data.metadata.version == ProfileMetadataVersion, sprofile::ResultInvalidMetadataVersion());
|
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<size_t>(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. */
|
/* Create temporary directories. */
|
||||||
R_TRY(this->EnsureTemporaryDirectories());
|
R_TRY(this->EnsureTemporaryDirectories());
|
||||||
|
@ -249,10 +274,10 @@ namespace ams::sprofile::srv {
|
||||||
/* Create metadata. */
|
/* Create metadata. */
|
||||||
char path[0x30];
|
char path[0x30];
|
||||||
CreateTemporaryMetadataPath(path, sizeof(path), m_save_data_info.mount_name);
|
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. */
|
/* Import the metadata. */
|
||||||
m_profile_importer->ImportMetadata(data.metadata);
|
m_profile_importer->ImportMetadata(import.metadata);
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,13 +334,13 @@ namespace ams::sprofile::srv {
|
||||||
std::scoped_lock lk2(m_general_mutex);
|
std::scoped_lock lk2(m_general_mutex);
|
||||||
|
|
||||||
/* Load the desired profile. */
|
/* Load the desired profile. */
|
||||||
R_TRY(this->LoadProfile(profile));
|
if (R_SUCCEEDED(this->LoadProfile(profile))) {
|
||||||
|
/* Find the specified key. */
|
||||||
/* Find the specified key. */
|
for (auto i = 0u; i < std::min<size_t>(m_service_profile->data.num_entries, util::size(m_service_profile->data.entries)); ++i) {
|
||||||
for (auto i = 0u; i < m_service_profile->data.num_entries; ++i) {
|
if (m_service_profile->data.entries[i].key == key) {
|
||||||
if (m_service_profile->data.entries[i].key == key) {
|
*out = m_service_profile->data.entries[i];
|
||||||
*out = m_service_profile->data.entries[i];
|
return ResultSuccess();
|
||||||
return ResultSuccess();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,6 +451,8 @@ namespace ams::sprofile::srv {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileManager::OnCommitted() {
|
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 we need to, invalidate the loaded service profile. */
|
||||||
if (m_service_profile.has_value()) {
|
if (m_service_profile.has_value()) {
|
||||||
for (auto i = 0; i < m_profile_importer->GetImportingCount(); ++i) {
|
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. */
|
/* Reset profile metadata. */
|
||||||
m_profile_metadata = util::nullopt;
|
m_profile_metadata = util::nullopt;
|
||||||
|
|
||||||
|
@ -445,6 +470,9 @@ namespace ams::sprofile::srv {
|
||||||
for (auto i = 0; i < m_profile_importer->GetImportingCount(); ++i) {
|
for (auto i = 0; i < m_profile_importer->GetImportingCount(); ++i) {
|
||||||
m_update_observer_manager.OnUpdate(m_profile_importer->GetImportingProfile(i));
|
m_update_observer_manager.OnUpdate(m_profile_importer->GetImportingProfile(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset profile importer. */
|
||||||
|
m_profile_importer = util::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ProfileManager::EnsurePrimaryDirectories() {
|
Result ProfileManager::EnsurePrimaryDirectories() {
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace ams::sprofile::srv {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ServiceForBgAgent::ReadMetadata(sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ReadMetadataEntry> &out, const sprofile::srv::ReadMetadataArgument &arg) {
|
Result ServiceForBgAgent::GetMetadataEntryData(sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ProfileMetadataEntryData> &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg) {
|
||||||
/* Check size. */
|
/* Check size. */
|
||||||
R_UNLESS(out.GetSize() >= arg.metadata.num_entries, sprofile::ResultInvalidArgument());
|
R_UNLESS(out.GetSize() >= arg.metadata.num_entries, sprofile::ResultInvalidArgument());
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace ams::sprofile::srv {
|
||||||
constexpr ServiceForBgAgent(MemoryResource *mr, ProfileManager *pm) : m_memory_resource(mr), m_profile_manager(pm) { /* ... */ }
|
constexpr ServiceForBgAgent(MemoryResource *mr, ProfileManager *pm) : m_memory_resource(mr), m_profile_manager(pm) { /* ... */ }
|
||||||
public:
|
public:
|
||||||
Result OpenProfileImporter(sf::Out<sf::SharedPointer<::ams::sprofile::IProfileImporter>> out);
|
Result OpenProfileImporter(sf::Out<sf::SharedPointer<::ams::sprofile::IProfileImporter>> out);
|
||||||
Result ReadMetadata(sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ReadMetadataEntry> &out, const sprofile::srv::ReadMetadataArgument &arg);
|
Result GetMetadataEntryData(sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ProfileMetadataEntryData> &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg);
|
||||||
Result IsUpdateNeeded(sf::Out<bool> out, Identifier revision_key);
|
Result IsUpdateNeeded(sf::Out<bool> out, Identifier revision_key);
|
||||||
Result Reset();
|
Result Reset();
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,34 +18,11 @@
|
||||||
|
|
||||||
namespace ams::sprofile::srv {
|
namespace ams::sprofile::srv {
|
||||||
|
|
||||||
struct ProfileMetadataEntry {
|
constexpr inline const u32 ProfileFormatVersion = 1;
|
||||||
Identifier identifier_0;
|
|
||||||
Identifier identifier_1;
|
|
||||||
u8 unk_0E[0x32];
|
|
||||||
};
|
|
||||||
static_assert(util::is_pod<ProfileMetadataEntry>::value);
|
|
||||||
static_assert(sizeof(ProfileMetadataEntry) == 0x40);
|
|
||||||
|
|
||||||
constexpr inline const u32 ProfileMetadataVersion = 0;
|
constexpr inline bool IsValidProfileFormatVersion(u32 version) {
|
||||||
|
return version == ProfileFormatVersion;
|
||||||
struct ProfileMetadata {
|
}
|
||||||
u32 version;
|
|
||||||
u32 num_entries;
|
|
||||||
Identifier revision_key;
|
|
||||||
u8 unk_10[0x30];
|
|
||||||
ProfileMetadataEntry entries[50];
|
|
||||||
};
|
|
||||||
static_assert(util::is_pod<ProfileMetadata>::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<ProfileMetadataForImportMetadata>::value);
|
|
||||||
static_assert(sizeof(ProfileMetadataForImportMetadata) == 0x8000);
|
|
||||||
|
|
||||||
constexpr inline const u32 ProfileDataVersion = 0;
|
|
||||||
|
|
||||||
enum ValueType : u8 {
|
enum ValueType : u8 {
|
||||||
ValueType_Byte = 0,
|
ValueType_Byte = 0,
|
||||||
|
@ -70,9 +47,9 @@ namespace ams::sprofile::srv {
|
||||||
static_assert(sizeof(ProfileDataEntry) == 0x10);
|
static_assert(sizeof(ProfileDataEntry) == 0x10);
|
||||||
|
|
||||||
struct ProfileData {
|
struct ProfileData {
|
||||||
u32 version;
|
|
||||||
u32 num_entries;
|
u32 num_entries;
|
||||||
u8 unk_08[0x28];
|
u8 unk_04[0x0C];
|
||||||
|
u8 unk_10[0x20];
|
||||||
ProfileDataEntry entries[(0x4000 - 0x30) / sizeof(ProfileDataEntry)];
|
ProfileDataEntry entries[(0x4000 - 0x30) / sizeof(ProfileDataEntry)];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<ProfileData>::value);
|
static_assert(util::is_pod<ProfileData>::value);
|
||||||
|
@ -86,28 +63,55 @@ namespace ams::sprofile::srv {
|
||||||
static_assert(sizeof(ServiceProfile) == 0x4008);
|
static_assert(sizeof(ServiceProfile) == 0x4008);
|
||||||
|
|
||||||
struct ProfileDataForImportData : public sf::LargeData, public sf::PrefersMapAliasTransferMode {
|
struct ProfileDataForImportData : public sf::LargeData, public sf::PrefersMapAliasTransferMode {
|
||||||
Identifier identifier_0;
|
struct {
|
||||||
Identifier identifier_1;
|
Identifier identifier_0;
|
||||||
u8 unk_0E[2];
|
Identifier identifier_1;
|
||||||
|
u8 unk_0E[2];
|
||||||
|
u32 version;
|
||||||
|
u8 unk_14[0x1C];
|
||||||
|
} header;
|
||||||
|
u8 hash[crypto::Md5Generator::HashSize];
|
||||||
ProfileData data;
|
ProfileData data;
|
||||||
u8 unk_4010[0x4400 - 0x4010];
|
u8 unk_4040[0x4400 - 0x4040];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<ProfileDataForImportData>::value);
|
static_assert(util::is_pod<ProfileDataForImportData>::value);
|
||||||
static_assert(sizeof(ProfileDataForImportData) == 0x4400);
|
static_assert(sizeof(ProfileDataForImportData) == 0x4400);
|
||||||
|
|
||||||
struct ReadMetadataEntry {
|
struct ProfileMetadataEntry {
|
||||||
|
Identifier identifier_0;
|
||||||
|
Identifier identifier_1;
|
||||||
|
u8 unk_0E[0x32];
|
||||||
|
};
|
||||||
|
static_assert(util::is_pod<ProfileMetadataEntry>::value);
|
||||||
|
static_assert(sizeof(ProfileMetadataEntry) == 0x40);
|
||||||
|
|
||||||
|
struct ProfileMetadataEntryData : public sf::PrefersMapAliasTransferMode {
|
||||||
u8 unk[0x100];
|
u8 unk[0x100];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<ReadMetadataEntry>::value);
|
static_assert(util::is_pod<ProfileMetadataEntryData>::value);
|
||||||
static_assert(sizeof(ReadMetadataEntry) == 0x100);
|
static_assert(sizeof(ProfileMetadataEntryData) == 0x100);
|
||||||
|
|
||||||
struct ReadMetadataArgument : public sf::LargeData, public sf::PrefersMapAliasTransferMode {
|
struct ProfileMetadata {
|
||||||
ProfileMetadata metadata;
|
u32 num_entries;
|
||||||
ReadMetadataEntry entries[(0x8000 - sizeof(metadata)) / sizeof(ReadMetadataEntry)];
|
u32 unk_04;
|
||||||
u8 unk_7FC0[0x40];
|
Identifier revision_key;
|
||||||
|
u8 unk_10[0x30];
|
||||||
|
ProfileMetadataEntry entries[50];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<ReadMetadataArgument>::value);
|
static_assert(util::is_pod<ProfileMetadata>::value);
|
||||||
static_assert(sizeof(ReadMetadataArgument) == 0x8000);
|
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<ProfileMetadataForImportMetadata>::value);
|
||||||
|
static_assert(sizeof(ProfileMetadataForImportMetadata) == 0x8000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace ams::sprofile {
|
||||||
R_DEFINE_ERROR_RESULT(MaxObservers, 623);
|
R_DEFINE_ERROR_RESULT(MaxObservers, 623);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(InvalidMetadataVersion, 3210);
|
R_DEFINE_ERROR_RESULT(InvalidMetadataVersion, 3210);
|
||||||
|
R_DEFINE_ERROR_RESULT(InvalidMetadataHash, 3211);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidDataVersion, 3230);
|
R_DEFINE_ERROR_RESULT(InvalidDataVersion, 3230);
|
||||||
|
R_DEFINE_ERROR_RESULT(InvalidDataHash, 3231);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue