From 900a02efff43f45ce3044da7567cd0078931a340 Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Sat, 5 Apr 2025 19:55:54 +0100 Subject: [PATCH] [XAM] Added property deserialization --- src/xenia/kernel/xam/apps/xgi_app.cc | 5 ++--- src/xenia/kernel/xam/user_data.cc | 17 +++++++++++++++-- src/xenia/kernel/xam/user_data.h | 7 ++++--- src/xenia/kernel/xam/user_property.cc | 16 +++++++++++++--- src/xenia/kernel/xam/user_property.h | 3 ++- src/xenia/kernel/xam/user_settings.cc | 1 - src/xenia/kernel/xam/user_tracker.cc | 2 +- 7 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/xenia/kernel/xam/apps/xgi_app.cc b/src/xenia/kernel/xam/apps/xgi_app.cc index c49501db6..b3f1f7c55 100644 --- a/src/xenia/kernel/xam/apps/xgi_app.cc +++ b/src/xenia/kernel/xam/apps/xgi_app.cc @@ -134,9 +134,8 @@ X_HRESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, if (user) { Property property( xgi_property->property_id, - UserSetting::get_valid_data_size(xgi_property->property_id, - xgi_property->data_size), - + Property::get_valid_data_size(xgi_property->property_id, + xgi_property->data_size), memory_->TranslateVirtual(xgi_property->data_address)); kernel_state_->xam_state()->user_tracker()->AddProperty(user->xuid(), diff --git a/src/xenia/kernel/xam/user_data.cc b/src/xenia/kernel/xam/user_data.cc index 349902f0b..7b4ec344c 100644 --- a/src/xenia/kernel/xam/user_data.cc +++ b/src/xenia/kernel/xam/user_data.cc @@ -35,7 +35,7 @@ UserData::UserData(X_USER_DATA_TYPE data_type, UserDataTypes user_data) { case X_USER_DATA_TYPE::WSTRING: { std::u16string str = std::get(user_data); data_.data.unicode.size = - static_cast(string_util::size_in_bytes(str)); + static_cast(string_util::size_in_bytes(str, false)); extended_data_.resize(data_.data.unicode.size); memcpy(extended_data_.data(), reinterpret_cast(str.data()), @@ -64,7 +64,7 @@ UserData::UserData(X_USER_DATA_TYPE data_type, UserDataTypes user_data) { } UserData::UserData(const X_USER_DATA_TYPE data_type, - const uint32_t data_max_size, const X_USER_DATA* user_data) { + const X_USER_DATA* user_data) { memcpy(&data_, user_data, sizeof(X_USER_DATA)); data_.type = data_type; @@ -103,6 +103,19 @@ UserData::UserData(X_USER_DATA_TYPE data_type, std::span data) { extended_data_.insert(extended_data_.begin(), data.begin(), data.end()); } +UserData::UserData(std::span data) { + data_ = + *reinterpret_cast(data.data() + sizeof(AttributeKey)); + + if (requires_additional_data()) { + std::span extended_data = data.subspan( + sizeof(AttributeKey) + sizeof(X_USER_DATA), data_.data.binary.size); + + extended_data_.insert(extended_data_.begin(), extended_data.begin(), + extended_data.end()); + } +} + UserData::UserData(const X_USER_DATA_TYPE data_type, const X_USER_DATA_UNION* user_data, std::span extended_data) { diff --git a/src/xenia/kernel/xam/user_data.h b/src/xenia/kernel/xam/user_data.h index 32c964302..3d2284d8f 100644 --- a/src/xenia/kernel/xam/user_data.h +++ b/src/xenia/kernel/xam/user_data.h @@ -141,6 +141,7 @@ class UserData { return sizeof(X_USER_DATA) + extended_data_.size(); } + // Settings specific static size_t get_data_size(uint32_t id, const X_USER_DATA* user_data) { if (requires_additional_data(id)) { return std::min(get_max_size(id), @@ -159,17 +160,17 @@ class UserData { // From host UserData(X_USER_DATA_TYPE data_type, UserDataTypes user_data); // From guest - UserData(const X_USER_DATA_TYPE data_type, const uint32_t data_max_size, - const X_USER_DATA* user_data); + UserData(const X_USER_DATA_TYPE data_type, const X_USER_DATA* user_data); // From guest - Property specific ctor. Property transfer raw data directly. UserData(X_USER_DATA_TYPE data_type, std::span data); + UserData(std::span data); // For data from GPD UserData(const X_USER_DATA_TYPE data_type, const X_USER_DATA_UNION* user_data, std::span extended_data); - X_USER_DATA data_; + X_USER_DATA data_ = {}; std::vector extended_data_ = {}; }; diff --git a/src/xenia/kernel/xam/user_property.cc b/src/xenia/kernel/xam/user_property.cc index da4a47ab1..3b0ce525b 100644 --- a/src/xenia/kernel/xam/user_property.cc +++ b/src/xenia/kernel/xam/user_property.cc @@ -33,13 +33,21 @@ Property::Property(uint32_t property_id, uint32_t value_size, } Property::Property(const uint8_t* serialized_data, size_t data_size) - : UserData(X_USER_DATA_TYPE::CONTEXT, std::span({})) {} + : UserData(std::span(serialized_data, data_size)) { + property_id_.value = *reinterpret_cast(serialized_data); +} + +Property::Property(std::span serialized_data) + : UserData(serialized_data) { + property_id_.value = + *reinterpret_cast(serialized_data.data()); +} Property::~Property() {}; std::vector Property::Serialize() const { - std::vector serialized_property(sizeof(XUSER_PROPERTY) + - extended_data_.size()); + std::vector serialized_property( + sizeof(AttributeKey) + sizeof(X_USER_DATA) + extended_data_.size()); memcpy(serialized_property.data(), &property_id_, sizeof(AttributeKey)); memcpy(serialized_property.data() + sizeof(AttributeKey), &data_, @@ -58,6 +66,8 @@ void Property::WriteToGuest(XUSER_PROPERTY* property) const { return; } + property->property_id = property_id_.value; + if (requires_additional_data()) { property->data.type = data_.type; property->data.data.binary.size = diff --git a/src/xenia/kernel/xam/user_property.h b/src/xenia/kernel/xam/user_property.h index 7aeb750af..81a005e1a 100644 --- a/src/xenia/kernel/xam/user_property.h +++ b/src/xenia/kernel/xam/user_property.h @@ -36,11 +36,12 @@ class Property : public UserData { Property(); Property(const Property& property); - Property(uint32_t property_id, UserDataTypes setting_data); + Property(uint32_t property_id, UserDataTypes property_data); // Ctor used while guest is creating property. Property(uint32_t property_id, uint32_t value_size, uint8_t* value_ptr); // Ctor used for deserialization Property(const uint8_t* serialized_data, size_t data_size); + Property(std::span serialized_data); ~Property(); const AttributeKey GetPropertyId() const { return property_id_; } diff --git a/src/xenia/kernel/xam/user_settings.cc b/src/xenia/kernel/xam/user_settings.cc index 6b77b6c68..e5212dc44 100644 --- a/src/xenia/kernel/xam/user_settings.cc +++ b/src/xenia/kernel/xam/user_settings.cc @@ -44,7 +44,6 @@ UserSetting::UserSetting(UserSettingId setting_id, UserDataTypes setting_data) UserSetting::UserSetting(const X_USER_PROFILE_SETTING* profile_setting) : UserData(UserSetting::get_type(profile_setting->setting_id), - UserSetting::get_max_size(profile_setting->setting_id), &profile_setting->data), setting_id_( static_cast(profile_setting->setting_id.get())), diff --git a/src/xenia/kernel/xam/user_tracker.cc b/src/xenia/kernel/xam/user_tracker.cc index 86cd315e7..458fa2307 100644 --- a/src/xenia/kernel/xam/user_tracker.cc +++ b/src/xenia/kernel/xam/user_tracker.cc @@ -475,7 +475,7 @@ X_STATUS UserTracker::GetProperty(const uint64_t xuid, uint32_t* property_size, } *property_size = 0; - const auto property_id = property->property_id; + const auto& property_id = property->property_id; const auto entry = std::find_if(user->properties_.cbegin(), user->properties_.cend(),