[XAM] Added property deserialization

This commit is contained in:
Adrian 2025-04-05 19:55:54 +01:00 committed by Radosław Gliński
parent be715f76fa
commit 900a02efff
7 changed files with 37 additions and 14 deletions

View file

@ -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<uint8_t*>(xgi_property->data_address));
kernel_state_->xam_state()->user_tracker()->AddProperty(user->xuid(),

View file

@ -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<std::u16string>(user_data);
data_.data.unicode.size =
static_cast<uint16_t>(string_util::size_in_bytes(str));
static_cast<uint16_t>(string_util::size_in_bytes(str, false));
extended_data_.resize(data_.data.unicode.size);
memcpy(extended_data_.data(), reinterpret_cast<uint8_t*>(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<const uint8_t> data) {
extended_data_.insert(extended_data_.begin(), data.begin(), data.end());
}
UserData::UserData(std::span<const uint8_t> data) {
data_ =
*reinterpret_cast<const X_USER_DATA*>(data.data() + sizeof(AttributeKey));
if (requires_additional_data()) {
std::span<const uint8_t> 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<const uint8_t> extended_data) {

View file

@ -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<const uint8_t> data);
UserData(std::span<const uint8_t> data);
// For data from GPD
UserData(const X_USER_DATA_TYPE data_type, const X_USER_DATA_UNION* user_data,
std::span<const uint8_t> extended_data);
X_USER_DATA data_;
X_USER_DATA data_ = {};
std::vector<uint8_t> extended_data_ = {};
};

View file

@ -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<const uint8_t>({})) {}
: UserData(std::span<const uint8_t>(serialized_data, data_size)) {
property_id_.value = *reinterpret_cast<const uint32_t*>(serialized_data);
}
Property::Property(std::span<const uint8_t> serialized_data)
: UserData(serialized_data) {
property_id_.value =
*reinterpret_cast<const uint32_t*>(serialized_data.data());
}
Property::~Property() {};
std::vector<uint8_t> Property::Serialize() const {
std::vector<uint8_t> serialized_property(sizeof(XUSER_PROPERTY) +
extended_data_.size());
std::vector<uint8_t> 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 =

View file

@ -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<const uint8_t> serialized_data);
~Property();
const AttributeKey GetPropertyId() const { return property_id_; }

View file

@ -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<UserSettingId>(profile_setting->setting_id.get())),

View file

@ -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(),