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) \
|
||||
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, 2000, Result, Reset, (), ())
|
||||
|
||||
|
|
|
@ -260,7 +260,7 @@ namespace ams::sprofile::srv {
|
|||
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)));
|
||||
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];
|
||||
md5.GetHash(hash, sizeof(hash));
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace ams::sprofile::srv {
|
|||
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. */
|
||||
R_UNLESS(out.GetSize() >= arg.metadata.num_entries, sprofile::ResultInvalidArgument());
|
||||
|
||||
|
@ -42,25 +42,31 @@ namespace ams::sprofile::srv {
|
|||
sprofile::srv::ProfileMetadata primary_metadata;
|
||||
R_TRY_CATCH(m_profile_manager->LoadPrimaryMetadata(std::addressof(primary_metadata))) {
|
||||
R_CATCH(fs::ResultPathNotFound) {
|
||||
/* If we have no metadata, we can't get any entries. */
|
||||
*out_count = 0;
|
||||
return ResultSuccess();
|
||||
/* It's okay if we have no primary metadata -- this means that all profiles are importable. */
|
||||
primary_metadata.num_entries = 0;
|
||||
}
|
||||
} 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;
|
||||
for (u32 i = 0; i < arg.metadata.num_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) {
|
||||
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) {
|
||||
out[count++] = arg.entries[i];
|
||||
have_entry = true;
|
||||
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. */
|
||||
|
|
|
@ -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<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 Reset();
|
||||
};
|
||||
|
|
|
@ -46,6 +46,10 @@ namespace ams::sprofile::srv {
|
|||
static_assert(util::is_pod<ProfileDataEntry>::value);
|
||||
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 {
|
||||
u32 num_entries;
|
||||
u8 unk_04[0x0C];
|
||||
|
@ -55,6 +59,11 @@ namespace ams::sprofile::srv {
|
|||
static_assert(util::is_pod<ProfileData>::value);
|
||||
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 {
|
||||
Identifier name;
|
||||
ProfileData data;
|
||||
|
@ -62,6 +71,9 @@ namespace ams::sprofile::srv {
|
|||
static_assert(util::is_pod<ServiceProfile>::value);
|
||||
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 {
|
||||
Identifier identifier_0;
|
||||
|
@ -77,6 +89,11 @@ namespace ams::sprofile::srv {
|
|||
static_assert(util::is_pod<ProfileDataForImportData>::value);
|
||||
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 {
|
||||
Identifier identifier_0;
|
||||
Identifier identifier_1;
|
||||
|
@ -85,22 +102,34 @@ namespace ams::sprofile::srv {
|
|||
static_assert(util::is_pod<ProfileMetadataEntry>::value);
|
||||
static_assert(sizeof(ProfileMetadataEntry) == 0x40);
|
||||
|
||||
struct ProfileMetadataEntryData : public sf::PrefersMapAliasTransferMode {
|
||||
u8 unk[0x100];
|
||||
static_assert(AMS_OFFSETOF(ProfileMetadataEntry, identifier_0) == 0x00);
|
||||
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(sizeof(ProfileMetadataEntryData) == 0x100);
|
||||
static_assert(util::is_pod<ProfileUrl>::value);
|
||||
static_assert(sizeof(ProfileUrl) == 0x100);
|
||||
|
||||
struct ProfileMetadata {
|
||||
u32 num_entries;
|
||||
u32 unk_04;
|
||||
Identifier revision_key;
|
||||
u8 unk_0F[0x1];
|
||||
u8 unk_10[0x30];
|
||||
ProfileMetadataEntry entries[50];
|
||||
};
|
||||
static_assert(util::is_pod<ProfileMetadata>::value);
|
||||
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 {
|
||||
u32 version;
|
||||
|
@ -108,10 +137,16 @@ namespace ams::sprofile::srv {
|
|||
} header;
|
||||
u8 hash[crypto::Md5Generator::HashSize];
|
||||
ProfileMetadata metadata;
|
||||
ProfileMetadataEntryData entries[50];
|
||||
u8 unk[0x8000 - 0x3EF0];
|
||||
ProfileUrl profile_urls[50];
|
||||
u8 unk_3EF0[0x8000 - 0x3EF0];
|
||||
};
|
||||
static_assert(util::is_pod<ProfileMetadataForImportMetadata>::value);
|
||||
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