[XAM] Implemented XamProfileCreateEnumerator & XamProfileEnumerate

This commit is contained in:
Adrian 2024-11-20 18:38:17 +00:00 committed by Radosław Gliński
parent 3096bb87d4
commit feafc3809c
3 changed files with 63 additions and 1 deletions

View File

@ -123,6 +123,50 @@ dword_result_t XamGetPrivateEnumStructureFromHandle_entry(
} }
DECLARE_XAM_EXPORT1(XamGetPrivateEnumStructureFromHandle, kNone, kStub); DECLARE_XAM_EXPORT1(XamGetPrivateEnumStructureFromHandle, kNone, kStub);
dword_result_t XamProfileCreateEnumerator_entry(dword_t device_id,
lpdword_t handle_ptr) {
if (!handle_ptr) {
return X_ERROR_INVALID_PARAMETER;
}
auto e = new XStaticEnumerator<X_PROFILEENUMRESULT>(kernel_state(), 1);
auto result = e->Initialize(XUserIndexAny, 0xFE, 0x23001, 0x23003, 0);
if (XFAILED(result)) {
return result;
}
const auto& profiles =
kernel_state()->xam_state()->profile_manager()->GetProfiles();
for (const auto& [xuid, account] : *profiles) {
X_PROFILEENUMRESULT* profile = e->AppendItem();
profile->xuid_offline = xuid;
profile->device_id = 1;
memcpy(&profile->account, &account, sizeof(X_XAMACCOUNTINFO));
xe::string_util::copy_and_swap_truncating(
profile->account.gamertag, account.gamertag, sizeof(account.gamertag));
}
*handle_ptr = e->handle();
return X_ERROR_SUCCESS;
}
DECLARE_XAM_EXPORT1(XamProfileCreateEnumerator, kNone, kImplemented);
dword_result_t XamProfileEnumerate_entry(dword_t handle, dword_t flags,
lpvoid_t buffer,
pointer_t<XAM_OVERLAPPED> overlapped) {
uint32_t dummy = 0;
auto result = xeXamEnumerate(handle, flags, buffer, 0,
!overlapped ? &dummy : nullptr, overlapped);
return result;
}
DECLARE_XAM_EXPORT1(XamProfileEnumerate, kNone, kImplemented);
} // namespace xam } // namespace xam
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe

View File

@ -1275,7 +1275,8 @@ class SigninDialog : public XamDialog {
char gamertag_[16] = ""; char gamertag_[16] = "";
}; };
dword_result_t XamShowSigninUI_entry(dword_t users_needed, dword_t unk_mask) { X_RESULT xeXamShowSigninUI(uint32_t user_index, uint32_t users_needed,
uint32_t flags) {
// Mask values vary. Probably matching user types? Local/remote? // Mask values vary. Probably matching user types? Local/remote?
// Games seem to sit and loop until we trigger sign in notification. // Games seem to sit and loop until we trigger sign in notification.
if (users_needed != 1 && users_needed != 2 && users_needed != 4) { if (users_needed != 1 && users_needed != 2 && users_needed != 4) {
@ -1305,8 +1306,18 @@ dword_result_t XamShowSigninUI_entry(dword_t users_needed, dword_t unk_mask) {
return xeXamDispatchDialogAsync<SigninDialog>( return xeXamDispatchDialogAsync<SigninDialog>(
new SigninDialog(imgui_drawer, users_needed), close); new SigninDialog(imgui_drawer, users_needed), close);
} }
dword_result_t XamShowSigninUI_entry(dword_t users_needed, dword_t flags) {
return xeXamShowSigninUI(XUserIndexAny, users_needed, flags);
}
DECLARE_XAM_EXPORT1(XamShowSigninUI, kUserProfiles, kImplemented); DECLARE_XAM_EXPORT1(XamShowSigninUI, kUserProfiles, kImplemented);
dword_result_t XamShowSigninUIp_entry(dword_t user_index, dword_t users_needed,
dword_t flags) {
return xeXamShowSigninUI(user_index, users_needed, flags);
}
DECLARE_XAM_EXPORT1(XamShowSigninUIp, kUserProfiles, kImplemented);
} // namespace xam } // namespace xam
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe

View File

@ -642,6 +642,13 @@ struct X_XAMACCOUNTINFO {
static_assert_size(X_XAMACCOUNTINFO, 0x17C); static_assert_size(X_XAMACCOUNTINFO, 0x17C);
#pragma pack(pop) #pragma pack(pop)
struct X_PROFILEENUMRESULT {
xe::be<uint64_t> xuid_offline; // E0.....
X_XAMACCOUNTINFO account;
xe::be<uint32_t> device_id;
};
static_assert_size(X_PROFILEENUMRESULT, 0x188);
} // namespace xe } // namespace xe
// clang-format on // clang-format on