[XAM] Removed gamertag endianness swap
- Fixed issue with XamShowDeviceSelectorUI not being triggered in specific cases - Partially fixed XamProfileCreate - Now it should create profile correctly - Fixed XamProfileGetCreationStatus crash
This commit is contained in:
committed by
Radosław Gliński
parent
eed4242059
commit
edd48cd83d
@@ -54,9 +54,6 @@ bool ProfileManager::DecryptAccountFile(const uint8_t* data,
|
|||||||
if (std::memcmp(data, data_hash, 0x10) == 0) {
|
if (std::memcmp(data, data_hash, 0x10) == 0) {
|
||||||
// Copy account data to output
|
// Copy account data to output
|
||||||
std::memcpy(output, dec_data + 8, sizeof(X_XAMACCOUNTINFO));
|
std::memcpy(output, dec_data + 8, sizeof(X_XAMACCOUNTINFO));
|
||||||
|
|
||||||
// Swap gamertag endian
|
|
||||||
xe::copy_and_swap<char16_t>(output->gamertag, output->gamertag, 0x10);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,10 +71,6 @@ void ProfileManager::EncryptAccountFile(const X_XAMACCOUNTINFO* input,
|
|||||||
reinterpret_cast<X_XAMACCOUNTINFO*>(output + 0x18);
|
reinterpret_cast<X_XAMACCOUNTINFO*>(output + 0x18);
|
||||||
std::memcpy(output_acct, input, sizeof(X_XAMACCOUNTINFO));
|
std::memcpy(output_acct, input, sizeof(X_XAMACCOUNTINFO));
|
||||||
|
|
||||||
// Swap gamertag endian
|
|
||||||
xe::copy_and_swap<char16_t>(output_acct->gamertag, output_acct->gamertag,
|
|
||||||
0x10);
|
|
||||||
|
|
||||||
// Set confounder, should be random but meh
|
// Set confounder, should be random but meh
|
||||||
std::memset(output + 0x10, 0xFD, 8);
|
std::memset(output + 0x10, 0xFD, 8);
|
||||||
|
|
||||||
@@ -500,10 +493,10 @@ const X_XAMACCOUNTINFO* ProfileManager::GetAccount(const uint64_t xuid) {
|
|||||||
bool ProfileManager::CreateAccount(const uint64_t xuid,
|
bool ProfileManager::CreateAccount(const uint64_t xuid,
|
||||||
const std::string gamertag) {
|
const std::string gamertag) {
|
||||||
X_XAMACCOUNTINFO account = {};
|
X_XAMACCOUNTINFO account = {};
|
||||||
std::u16string gamertag_u16 = xe::to_utf16(gamertag);
|
const std::u16string gamertag_u16 = xe::to_utf16(gamertag);
|
||||||
|
|
||||||
string_util::copy_truncating(account.gamertag, gamertag_u16,
|
string_util::copy_and_swap_truncating(account.gamertag, gamertag_u16,
|
||||||
sizeof(account.gamertag));
|
sizeof(account.gamertag));
|
||||||
|
|
||||||
const bool result = UpdateAccount(xuid, &account);
|
const bool result = UpdateAccount(xuid, &account);
|
||||||
DismountProfile(xuid);
|
DismountProfile(xuid);
|
||||||
|
|||||||
@@ -44,6 +44,13 @@ inline const std::string kDashboardStringID =
|
|||||||
|
|
||||||
constexpr std::string_view kDefaultMountFormat = "User_{:016X}";
|
constexpr std::string_view kDefaultMountFormat = "User_{:016X}";
|
||||||
|
|
||||||
|
const static inline uint64_t GenerateXuid() {
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 gen(rd());
|
||||||
|
|
||||||
|
return ((uint64_t)0xE03 << 52) + (gen() % (1 << 31));
|
||||||
|
}
|
||||||
|
|
||||||
class ProfileManager {
|
class ProfileManager {
|
||||||
public:
|
public:
|
||||||
static bool DecryptAccountFile(const uint8_t* data, X_XAMACCOUNTINFO* output,
|
static bool DecryptAccountFile(const uint8_t* data, X_XAMACCOUNTINFO* output,
|
||||||
@@ -116,13 +123,6 @@ class ProfileManager {
|
|||||||
uint8_t FindFirstFreeProfileSlot() const;
|
uint8_t FindFirstFreeProfileSlot() const;
|
||||||
std::bitset<XUserMaxUserCount> GetUsedUserSlots() const;
|
std::bitset<XUserMaxUserCount> GetUsedUserSlots() const;
|
||||||
|
|
||||||
uint64_t GenerateXuid() const {
|
|
||||||
std::random_device rd;
|
|
||||||
std::mt19937 gen(rd());
|
|
||||||
|
|
||||||
return ((uint64_t)0xE03 << 52) + (gen() % (1 << 31));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<uint64_t, X_XAMACCOUNTINFO> accounts_;
|
std::map<uint64_t, X_XAMACCOUNTINFO> accounts_;
|
||||||
std::map<uint8_t, std::unique_ptr<UserProfile>> logged_profiles_;
|
std::map<uint8_t, std::unique_ptr<UserProfile>> logged_profiles_;
|
||||||
|
|
||||||
|
|||||||
@@ -620,10 +620,10 @@ void GamercardUI::SaveAccountData() {
|
|||||||
account.SetSubscriptionTier(gamercardValues_.account_subscription_tier);
|
account.SetSubscriptionTier(gamercardValues_.account_subscription_tier);
|
||||||
account.ToggleLiveFlag(gamercardValues_.is_live_enabled);
|
account.ToggleLiveFlag(gamercardValues_.is_live_enabled);
|
||||||
|
|
||||||
std::u16string gamertag =
|
const std::u16string gamertag =
|
||||||
xe::to_utf16(std::string(gamercardValues_.gamertag));
|
xe::to_utf16(std::string(gamercardValues_.gamertag));
|
||||||
string_util::copy_truncating(account.gamertag, gamertag,
|
string_util::copy_and_swap_truncating(account.gamertag, gamertag,
|
||||||
std::size(account.gamertag));
|
std::size(account.gamertag));
|
||||||
|
|
||||||
if (std::memcmp(&account, &account_original, sizeof(X_XAMACCOUNTINFO)) != 0) {
|
if (std::memcmp(&account, &account_original, sizeof(X_XAMACCOUNTINFO)) != 0) {
|
||||||
if (!is_signed_in_) {
|
if (!is_signed_in_) {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ struct X_XAMACCOUNTINFO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string GetGamertagString() const {
|
std::string GetGamertagString() const {
|
||||||
return xe::to_utf8(std::u16string(gamertag));
|
return xe::to_utf8(xe::string_util::read_u16string_and_swap(gamertag));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToggleLiveFlag(bool is_live) {
|
void ToggleLiveFlag(bool is_live) {
|
||||||
@@ -293,7 +293,7 @@ struct X_PROFILE_CREATION_INFO {
|
|||||||
X_PASSPORT_SESSION_TOKEN user_token;
|
X_PASSPORT_SESSION_TOKEN user_token;
|
||||||
X_PASSPORT_SESSION_TOKEN owner_token;
|
X_PASSPORT_SESSION_TOKEN owner_token;
|
||||||
uint32_t task_handle_ptr;
|
uint32_t task_handle_ptr;
|
||||||
uint32_t unk2;
|
uint32_t profile_creation_ptr;
|
||||||
};
|
};
|
||||||
static_assert_size(X_PROFILE_CREATION_INFO, 0xAC0);
|
static_assert_size(X_PROFILE_CREATION_INFO, 0xAC0);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
|
#include "xenia/kernel/xam/profile_manager.h"
|
||||||
#include "xenia/kernel/xam/xam_private.h"
|
#include "xenia/kernel/xam/xam_private.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
@@ -70,42 +71,41 @@ dword_result_t XamProfileCreate_entry(
|
|||||||
pointer_t<X_USER_PAYMENT_INFO> payment_info,
|
pointer_t<X_USER_PAYMENT_INFO> payment_info,
|
||||||
pointer_t<X_PASSPORT_SESSION_TOKEN> user_token,
|
pointer_t<X_PASSPORT_SESSION_TOKEN> user_token,
|
||||||
pointer_t<X_PASSPORT_SESSION_TOKEN> owner_token,
|
pointer_t<X_PASSPORT_SESSION_TOKEN> owner_token,
|
||||||
pointer_t<X_PROFILE_CREATION_INFO> profile_info_ptr) {
|
lpdword_t profile_info_ptr) {
|
||||||
if ((flags & 0x80000000) == 0x80000000) {
|
*profile_info_ptr =
|
||||||
profile_info_ptr->flags = flags & 0x7fffffff;
|
kernel_memory()->SystemHeapAlloc(sizeof(X_PROFILE_CREATION_INFO));
|
||||||
profile_info_ptr->unk2 = 1;
|
kernel_memory()->Fill(*profile_info_ptr, sizeof(X_PROFILE_CREATION_INFO), 0);
|
||||||
} else {
|
|
||||||
profile_info_ptr->flags = flags;
|
auto profile_info =
|
||||||
profile_info_ptr->unk2 = 0;
|
kernel_memory()->TranslateVirtual<X_PROFILE_CREATION_INFO*>(
|
||||||
}
|
*profile_info_ptr);
|
||||||
|
|
||||||
|
profile_info->flags = flags & 0x7fffffff;
|
||||||
|
|
||||||
if (device_id) {
|
if (device_id) {
|
||||||
*device_id = 0x1;
|
*device_id = 0x1;
|
||||||
profile_info_ptr->device_id = *device_id;
|
profile_info->device_id = *device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile_info_ptr->offline_xuid = xuid;
|
const uint64_t proper_xuid =
|
||||||
profile_info_ptr->account_info = *account;
|
xuid == 0 ? GenerateXuid() : static_cast<uint64_t>(xuid);
|
||||||
|
profile_info->offline_xuid = proper_xuid;
|
||||||
X_XAMACCOUNTINFO account_info_data;
|
profile_info->account_info = *account;
|
||||||
memcpy(&account_info_data, account, sizeof(X_XAMACCOUNTINFO));
|
|
||||||
xe::copy_and_swap<char16_t>(account_info_data.gamertag,
|
|
||||||
account_info_data.gamertag, 16);
|
|
||||||
|
|
||||||
if (payment_info) {
|
if (payment_info) {
|
||||||
profile_info_ptr->user_payment_info = *payment_info;
|
profile_info->user_payment_info = *payment_info;
|
||||||
}
|
}
|
||||||
if (user_token) {
|
if (user_token) {
|
||||||
profile_info_ptr->user_token = *user_token;
|
profile_info->user_token = *user_token;
|
||||||
}
|
}
|
||||||
if (owner_token) {
|
if (owner_token) {
|
||||||
profile_info_ptr->owner_token = *owner_token;
|
profile_info->owner_token = *owner_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calls XamTaskSchedule
|
// calls XamTaskSchedule
|
||||||
|
|
||||||
bool result = kernel_state()->xam_state()->profile_manager()->CreateProfile(
|
bool result = kernel_state()->xam_state()->profile_manager()->CreateProfile(
|
||||||
&account_info_data, xuid);
|
&profile_info->account_info, proper_xuid);
|
||||||
|
|
||||||
return result ? X_ERROR_SUCCESS : X_ERROR_INVALID_PARAMETER;
|
return result ? X_ERROR_SUCCESS : X_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,16 @@ dword_result_t XamProfileGetCreationStatus_entry(
|
|||||||
// XamTaskGetStatus(profile_info->task_handle_ptr);
|
// XamTaskGetStatus(profile_info->task_handle_ptr);
|
||||||
// if (result == 0) {
|
// if (result == 0) {
|
||||||
// result = XamTaskGetCompletionStatus(profile_info->task_handle_ptr)
|
// result = XamTaskGetCompletionStatus(profile_info->task_handle_ptr)
|
||||||
|
|
||||||
|
// Custom safeguard
|
||||||
|
if (!profile_info) {
|
||||||
|
XELOGE("XamProfileGetCreationStatus: Invalid profile_info provided!");
|
||||||
|
return X_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
*offline_xuid = profile_info->offline_xuid;
|
*offline_xuid = profile_info->offline_xuid;
|
||||||
|
|
||||||
|
kernel_state()->memory()->SystemHeapFree(profile_info.guest_address());
|
||||||
// XamTaskCloseHandle(profile_info->task_handle_ptr);
|
// XamTaskCloseHandle(profile_info->task_handle_ptr);
|
||||||
//}
|
//}
|
||||||
return X_ERROR_SUCCESS; // result
|
return X_ERROR_SUCCESS; // result
|
||||||
|
|||||||
@@ -518,13 +518,6 @@ dword_result_t XamShowDeviceSelectorUI_entry(
|
|||||||
return X_ERROR_INVALID_PARAMETER;
|
return X_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user_index != XUserIndexAny &&
|
|
||||||
!kernel_state()->xam_state()->IsUserSignedIn(user_index)) {
|
|
||||||
kernel_state()->CompleteOverlappedImmediate(overlapped,
|
|
||||||
X_ERROR_NO_SUCH_USER);
|
|
||||||
return X_ERROR_IO_PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const DummyDeviceInfo*> devices = ListStorageDevices();
|
std::vector<const DummyDeviceInfo*> devices = ListStorageDevices();
|
||||||
|
|
||||||
if (cvars::headless || !cvars::storage_selection_dialog) {
|
if (cvars::headless || !cvars::storage_selection_dialog) {
|
||||||
|
|||||||
Reference in New Issue
Block a user