From dffba5a81e14f6018cbc8c652ebebf4deb3aa71e Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:30:10 +0000 Subject: [PATCH] [XAM] Implemented XamUserLogon --- src/xenia/kernel/xam/xam_notify.cc | 7 +++ src/xenia/kernel/xam/xam_user.cc | 89 ++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/src/xenia/kernel/xam/xam_notify.cc b/src/xenia/kernel/xam/xam_notify.cc index ed69086b2..e98299541 100644 --- a/src/xenia/kernel/xam/xam_notify.cc +++ b/src/xenia/kernel/xam/xam_notify.cc @@ -102,6 +102,13 @@ void XNotifyPositionUI_entry(dword_t position) { } DECLARE_XAM_EXPORT1(XNotifyPositionUI, kNone, kStub); +dword_result_t XNotifyBroadcast_entry(dword_t notification, dword_t data) { + kernel_state()->BroadcastNotification(notification, data); + + return X_ERROR_SUCCESS; +} +DECLARE_XAM_EXPORT1(XNotifyBroadcast, kNone, kStub); + } // namespace xam } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam/xam_user.cc b/src/xenia/kernel/xam/xam_user.cc index 158c19ae8..0169355b4 100644 --- a/src/xenia/kernel/xam/xam_user.cc +++ b/src/xenia/kernel/xam/xam_user.cc @@ -1075,6 +1075,95 @@ dword_result_t XamUserGetUserTenure_entry(dword_t user_index, } DECLARE_XAM_EXPORT1(XamUserGetUserTenure, kUserProfiles, kImplemented); +// https://github.com/TeaModz/XeLiveStealth-Full-Source/blob/d4a7439ac6241c4a13e883a6f156623d1c08f6eb/XeLive/Utils.cpp#L416 +dword_result_t XamUserLogon_entry(lpqword_t xuids_ptr, dword_t flags, + pointer_t overlapped_ptr) { + const auto host_xuids_ptr = + kernel_memory()->TranslateVirtual*>(xuids_ptr); + + const auto xuids = std::vector>( + host_xuids_ptr, host_xuids_ptr + XUserMaxUserCount); + + if (!xuids_ptr) { + return X_ERROR_INVALID_PARAMETER; + } + + auto run = [xuids, flags](uint32_t& extended_error, + uint32_t& length) -> X_RESULT { + auto const profile_manager = kernel_state()->xam_state()->profile_manager(); + + X_STATUS result = X_ERROR_SUCCESS; + + if (flags & static_cast(UserLogonFlags::AddUser)) { + for (auto& xuid : xuids) { + if (xuid) { + profile_manager->Login(xuid, XUserIndexAny, true); + } + } + } + + if (flags & static_cast(UserLogonFlags::RemoveUser)) { + for (auto& xuid : xuids) { + const uint8_t assigned_index = + profile_manager->GetUserIndexAssignedToProfile(xuid); + + if (xuid) { + if (kernel_state()->xam_state()->IsUserSignedIn(xuid)) { + profile_manager->Logout(assigned_index, true); + } + } + } + } + + // Log everyone out + if (flags & static_cast(UserLogonFlags::ForceLiveLogOff)) { + for (uint32_t user_index = 0; user_index < XUserMaxUserCount; + user_index++) { + if (kernel_state()->xam_state()->IsUserSignedIn(user_index)) { + profile_manager->Logout(user_index, true); + } + } + } + + extended_error = X_HRESULT_FROM_WIN32(result); + length = 0; + + return result; + }; + + if (!overlapped_ptr) { + uint32_t extended_error, length = 0; + return run(extended_error, length); + } else { + kernel_state()->CompleteOverlappedDeferredEx(run, overlapped_ptr); + return X_ERROR_IO_PENDING; + } +} +DECLARE_XAM_EXPORT1(XamUserLogon, kUserProfiles, kImplemented); + +dword_result_t XamUserLogonEx_entry(pointer_t profile_ptr, + dword_t flags, + pointer_t overlapped_ptr) { + auto run = [profile_ptr, flags](uint32_t& extended_error, + uint32_t& length) -> X_RESULT { + X_STATUS result = X_ERROR_SUCCESS; + + extended_error = X_HRESULT_FROM_WIN32(result); + length = 0; + + return result; + }; + + if (!overlapped_ptr) { + uint32_t extended_error, length = 0; + return run(extended_error, length); + } else { + kernel_state()->CompleteOverlappedDeferredEx(run, overlapped_ptr); + return X_ERROR_IO_PENDING; + } +} +DECLARE_XAM_EXPORT1(XamUserLogonEx, kUserProfiles, kSketchy); + } // namespace xam } // namespace kernel } // namespace xe