mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
sprofile: fix off-by-one in struct definition, fix GetImportableProfileUrls
This commit is contained in:
parent
d1f3c4904b
commit
2a0b99d9f9
5 changed files with 59 additions and 18 deletions
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#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, 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, 200, Result, GetImportableProfileUrls, (sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ProfileUrl> &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, (), ())
|
||||||
|
|
||||||
|
|
|
@ -260,7 +260,7 @@ namespace ams::sprofile::srv {
|
||||||
crypto::Md5Generator md5;
|
crypto::Md5Generator md5;
|
||||||
md5.Update(std::addressof(import.header), sizeof(import.header));
|
md5.Update(std::addressof(import.header), sizeof(import.header));
|
||||||
md5.Update(std::addressof(import.metadata), sizeof(import.metadata));
|
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)));
|
md5.Update(std::addressof(import.profile_urls), sizeof(import.profile_urls[0]) * std::min<size_t>(import.metadata.num_entries, util::size(import.metadata.entries)));
|
||||||
|
|
||||||
u8 hash[crypto::Md5Generator::HashSize];
|
u8 hash[crypto::Md5Generator::HashSize];
|
||||||
md5.GetHash(hash, sizeof(hash));
|
md5.GetHash(hash, sizeof(hash));
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace ams::sprofile::srv {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ServiceForBgAgent::GetMetadataEntryData(sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ProfileMetadataEntryData> &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg) {
|
Result ServiceForBgAgent::GetImportableProfileUrls(sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ProfileUrl> &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());
|
||||||
|
|
||||||
|
@ -42,25 +42,31 @@ namespace ams::sprofile::srv {
|
||||||
sprofile::srv::ProfileMetadata primary_metadata;
|
sprofile::srv::ProfileMetadata primary_metadata;
|
||||||
R_TRY_CATCH(m_profile_manager->LoadPrimaryMetadata(std::addressof(primary_metadata))) {
|
R_TRY_CATCH(m_profile_manager->LoadPrimaryMetadata(std::addressof(primary_metadata))) {
|
||||||
R_CATCH(fs::ResultPathNotFound) {
|
R_CATCH(fs::ResultPathNotFound) {
|
||||||
/* If we have no metadata, we can't get any entries. */
|
/* It's okay if we have no primary metadata -- this means that all profiles are importable. */
|
||||||
*out_count = 0;
|
primary_metadata.num_entries = 0;
|
||||||
return ResultSuccess();
|
|
||||||
}
|
}
|
||||||
} R_END_TRY_CATCH;
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
/* Copy matching entries. */
|
/* We want to return the set of profiles that can be imported, which is just the profiles we don't already have. */
|
||||||
u32 count = 0;
|
u32 count = 0;
|
||||||
for (u32 i = 0; i < arg.metadata.num_entries; ++i) {
|
for (u32 i = 0; i < arg.metadata.num_entries; ++i) {
|
||||||
const auto &arg_entry = arg.metadata.entries[i];
|
const auto &arg_entry = arg.metadata.entries[i];
|
||||||
|
|
||||||
|
/* Check if we have the entry. */
|
||||||
|
bool have_entry = false;
|
||||||
for (u32 j = 0; j < primary_metadata.num_entries; ++j) {
|
for (u32 j = 0; j < primary_metadata.num_entries; ++j) {
|
||||||
const auto &pri_entry = primary_metadata.entries[j];
|
const auto &pri_entry = primary_metadata.entries[j];
|
||||||
|
|
||||||
if (pri_entry.identifier_0 == arg_entry.identifier_0 && pri_entry.identifier_1 == arg_entry.identifier_1) {
|
if (pri_entry.identifier_0 == arg_entry.identifier_0 && pri_entry.identifier_1 == arg_entry.identifier_1) {
|
||||||
out[count++] = arg.entries[i];
|
have_entry = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we don't already have the entry, it's importable -- copy it out. */
|
||||||
|
if (!have_entry) {
|
||||||
|
out[count++] = arg.profile_urls[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set output count. */
|
/* Set output count. */
|
||||||
|
|
|
@ -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 GetMetadataEntryData(sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ProfileMetadataEntryData> &out, const sprofile::srv::ProfileMetadataForImportMetadata &arg);
|
Result GetImportableProfileUrls(sf::Out<u32> out_count, const sf::OutArray<sprofile::srv::ProfileUrl> &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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,6 +46,10 @@ namespace ams::sprofile::srv {
|
||||||
static_assert(util::is_pod<ProfileDataEntry>::value);
|
static_assert(util::is_pod<ProfileDataEntry>::value);
|
||||||
static_assert(sizeof(ProfileDataEntry) == 0x10);
|
static_assert(sizeof(ProfileDataEntry) == 0x10);
|
||||||
|
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileDataEntry, key) == 0x00);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileDataEntry, type) == 0x07);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileDataEntry, value_s64) == 0x08);
|
||||||
|
|
||||||
struct ProfileData {
|
struct ProfileData {
|
||||||
u32 num_entries;
|
u32 num_entries;
|
||||||
u8 unk_04[0x0C];
|
u8 unk_04[0x0C];
|
||||||
|
@ -55,6 +59,11 @@ namespace ams::sprofile::srv {
|
||||||
static_assert(util::is_pod<ProfileData>::value);
|
static_assert(util::is_pod<ProfileData>::value);
|
||||||
static_assert(sizeof(ProfileData) == 0x4000);
|
static_assert(sizeof(ProfileData) == 0x4000);
|
||||||
|
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileData, num_entries) == 0x00);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileData, unk_04) == 0x04);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileData, unk_10) == 0x10);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileData, entries) == 0x30);
|
||||||
|
|
||||||
struct ServiceProfile {
|
struct ServiceProfile {
|
||||||
Identifier name;
|
Identifier name;
|
||||||
ProfileData data;
|
ProfileData data;
|
||||||
|
@ -62,6 +71,9 @@ namespace ams::sprofile::srv {
|
||||||
static_assert(util::is_pod<ServiceProfile>::value);
|
static_assert(util::is_pod<ServiceProfile>::value);
|
||||||
static_assert(sizeof(ServiceProfile) == 0x4008);
|
static_assert(sizeof(ServiceProfile) == 0x4008);
|
||||||
|
|
||||||
|
static_assert(AMS_OFFSETOF(ServiceProfile, name) == 0x00);
|
||||||
|
static_assert(AMS_OFFSETOF(ServiceProfile, data) == 0x08);
|
||||||
|
|
||||||
struct ProfileDataForImportData : public sf::LargeData, public sf::PrefersMapAliasTransferMode {
|
struct ProfileDataForImportData : public sf::LargeData, public sf::PrefersMapAliasTransferMode {
|
||||||
struct {
|
struct {
|
||||||
Identifier identifier_0;
|
Identifier identifier_0;
|
||||||
|
@ -77,6 +89,11 @@ namespace ams::sprofile::srv {
|
||||||
static_assert(util::is_pod<ProfileDataForImportData>::value);
|
static_assert(util::is_pod<ProfileDataForImportData>::value);
|
||||||
static_assert(sizeof(ProfileDataForImportData) == 0x4400);
|
static_assert(sizeof(ProfileDataForImportData) == 0x4400);
|
||||||
|
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileDataForImportData, header) == 0x00);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileDataForImportData, hash) == 0x30);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileDataForImportData, data) == 0x40);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileDataForImportData, unk_4040) == 0x4040);
|
||||||
|
|
||||||
struct ProfileMetadataEntry {
|
struct ProfileMetadataEntry {
|
||||||
Identifier identifier_0;
|
Identifier identifier_0;
|
||||||
Identifier identifier_1;
|
Identifier identifier_1;
|
||||||
|
@ -85,22 +102,34 @@ namespace ams::sprofile::srv {
|
||||||
static_assert(util::is_pod<ProfileMetadataEntry>::value);
|
static_assert(util::is_pod<ProfileMetadataEntry>::value);
|
||||||
static_assert(sizeof(ProfileMetadataEntry) == 0x40);
|
static_assert(sizeof(ProfileMetadataEntry) == 0x40);
|
||||||
|
|
||||||
struct ProfileMetadataEntryData : public sf::PrefersMapAliasTransferMode {
|
static_assert(AMS_OFFSETOF(ProfileMetadataEntry, identifier_0) == 0x00);
|
||||||
u8 unk[0x100];
|
static_assert(AMS_OFFSETOF(ProfileMetadataEntry, identifier_1) == 0x07);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadataEntry, unk_0E) == 0x0E);
|
||||||
|
|
||||||
|
struct ProfileUrl : public sf::PrefersMapAliasTransferMode {
|
||||||
|
char url[0x100];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<ProfileMetadataEntryData>::value);
|
static_assert(util::is_pod<ProfileUrl>::value);
|
||||||
static_assert(sizeof(ProfileMetadataEntryData) == 0x100);
|
static_assert(sizeof(ProfileUrl) == 0x100);
|
||||||
|
|
||||||
struct ProfileMetadata {
|
struct ProfileMetadata {
|
||||||
u32 num_entries;
|
u32 num_entries;
|
||||||
u32 unk_04;
|
u32 unk_04;
|
||||||
Identifier revision_key;
|
Identifier revision_key;
|
||||||
|
u8 unk_0F[0x1];
|
||||||
u8 unk_10[0x30];
|
u8 unk_10[0x30];
|
||||||
ProfileMetadataEntry entries[50];
|
ProfileMetadataEntry entries[50];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<ProfileMetadata>::value);
|
static_assert(util::is_pod<ProfileMetadata>::value);
|
||||||
static_assert(sizeof(ProfileMetadata) == 0xCC0);
|
static_assert(sizeof(ProfileMetadata) == 0xCC0);
|
||||||
|
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadata, num_entries) == 0x00);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadata, unk_04) == 0x04);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadata, revision_key) == 0x08);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadata, unk_0F) == 0x0F);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadata, unk_10) == 0x10);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadata, entries) == 0x40);
|
||||||
|
|
||||||
struct ProfileMetadataForImportMetadata : public sf::LargeData, public sf::PrefersMapAliasTransferMode {
|
struct ProfileMetadataForImportMetadata : public sf::LargeData, public sf::PrefersMapAliasTransferMode {
|
||||||
struct {
|
struct {
|
||||||
u32 version;
|
u32 version;
|
||||||
|
@ -108,10 +137,16 @@ namespace ams::sprofile::srv {
|
||||||
} header;
|
} header;
|
||||||
u8 hash[crypto::Md5Generator::HashSize];
|
u8 hash[crypto::Md5Generator::HashSize];
|
||||||
ProfileMetadata metadata;
|
ProfileMetadata metadata;
|
||||||
ProfileMetadataEntryData entries[50];
|
ProfileUrl profile_urls[50];
|
||||||
u8 unk[0x8000 - 0x3EF0];
|
u8 unk_3EF0[0x8000 - 0x3EF0];
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<ProfileMetadataForImportMetadata>::value);
|
static_assert(util::is_pod<ProfileMetadataForImportMetadata>::value);
|
||||||
static_assert(sizeof(ProfileMetadataForImportMetadata) == 0x8000);
|
static_assert(sizeof(ProfileMetadataForImportMetadata) == 0x8000);
|
||||||
|
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, header) == 0x00);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, hash) == 0x20);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, metadata) == 0x30);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, profile_urls) == 0xCF0);
|
||||||
|
static_assert(AMS_OFFSETOF(ProfileMetadataForImportMetadata, unk_3EF0) == 0x3EF0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue