diff --git a/src/xenia/kernel/xam/xam_user.cc b/src/xenia/kernel/xam/xam_user.cc index b034f9fba..ca946bc42 100644 --- a/src/xenia/kernel/xam/xam_user.cc +++ b/src/xenia/kernel/xam/xam_user.cc @@ -21,100 +21,79 @@ namespace xe { namespace kernel { namespace xam { -SHIM_CALL XamUserGetXUID_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t unk = SHIM_GET_ARG_32(1); - uint32_t xuid_ptr = SHIM_GET_ARG_32(2); - - XELOGD("XamUserGetXUID(%d, %.8X, %.8X)", user_index, unk, xuid_ptr); - - if (user_index == 0) { - const auto& user_profile = kernel_state->user_profile(); - if (xuid_ptr) { - SHIM_SET_MEM_64(xuid_ptr, user_profile->xuid()); - } - SHIM_SET_RETURN_32(0); - } else { - SHIM_SET_RETURN_32(X_ERROR_NO_SUCH_USER); +dword_result_t XamUserGetXUID(dword_t user_index, dword_t unk, + lpqword_t xuid_ptr) { + if (user_index) { + return X_ERROR_NO_SUCH_USER; } + const auto& user_profile = kernel_state()->user_profile(); + if (xuid_ptr) { + *xuid_ptr = user_profile->xuid(); + } + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserGetXUID, + ExportTag::kUserProfiles | ExportTag::kImplemented); -SHIM_CALL XamUserGetSigninState_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - - XELOGD("XamUserGetSigninState(%d)", user_index); - +dword_result_t XamUserGetSigninState(dword_t user_index) { // Yield, as some games spam this. xe::threading::MaybeYield(); // Lie and say we are signed in, but local-only. // This should keep games from asking us to sign in and also keep them // from initializing the network. + if (user_index == 0 || (user_index & 0xFF) == 0xFF) { - const auto& user_profile = kernel_state->user_profile(); - auto signin_state = user_profile->signin_state(); - SHIM_SET_RETURN_32(signin_state); + const auto& user_profile = kernel_state()->user_profile(); + return user_profile->signin_state(); } else { - SHIM_SET_RETURN_32(0); + return 0; } } +DECLARE_XAM_EXPORT(XamUserGetSigninState, + ExportTag::kUserProfiles | ExportTag::kImplemented); typedef struct { xe::be xuid; - xe::be unk04; // maybe zero? + xe::be unk08; // maybe zero? xe::be signin_state; - xe::be unk0C; // ? xe::be unk10; // ? + xe::be unk14; // ? char name[16]; } X_USER_SIGNIN_INFO; static_assert_size(X_USER_SIGNIN_INFO, 40); -SHIM_CALL XamUserGetSigninInfo_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t flags = SHIM_GET_ARG_32(1); - uint32_t info_ptr = SHIM_GET_ARG_32(2); - - XELOGD("XamUserGetSigninInfo(%d, %.8X, %.8X)", user_index, flags, info_ptr); - - if (!info_ptr) { - SHIM_SET_RETURN_32(X_ERROR_INVALID_PARAMETER); - return; +dword_result_t XamUserGetSigninInfo(dword_t user_index, dword_t flags, + pointer_t info) { + if (!info) { + return X_ERROR_INVALID_PARAMETER; } - auto info = reinterpret_cast(SHIM_MEM_ADDR(info_ptr)); std::memset(info, 0, sizeof(X_USER_SIGNIN_INFO)); - if (user_index == 0) { - const auto& user_profile = kernel_state->user_profile(); + const auto& user_profile = kernel_state()->user_profile(); info->xuid = user_profile->xuid(); info->signin_state = user_profile->signin_state(); std::strncpy(info->name, user_profile->name().data(), 15); - SHIM_SET_RETURN_32(0); + return X_ERROR_SUCCESS; } else { - SHIM_SET_RETURN_32(X_ERROR_NO_SUCH_USER); + return X_ERROR_NO_SUCH_USER; } } +DECLARE_XAM_EXPORT(XamUserGetSigninInfo, + ExportTag::kUserProfiles | ExportTag::kImplemented); -SHIM_CALL XamUserGetName_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t buffer_ptr = SHIM_GET_ARG_32(1); - uint32_t buffer_len = SHIM_GET_ARG_32(2); - - XELOGD("XamUserGetName(%d, %.8X, %d)", user_index, buffer_ptr, buffer_len); - - if (user_index == 0) { - const auto& user_profile = kernel_state->user_profile(); - char* buffer = reinterpret_cast(SHIM_MEM_ADDR(buffer_ptr)); - std::strcpy(buffer, user_profile->name().data()); - SHIM_SET_RETURN_32(0); - } else { - SHIM_SET_RETURN_32(X_ERROR_NO_SUCH_USER); +dword_result_t XamUserGetName(dword_t user_index, lpstring_t buffer, + dword_t buffer_len) { + if (user_index) { + return X_ERROR_NO_SUCH_USER; } + const auto& user_profile = kernel_state()->user_profile(); + std::strncpy(buffer, user_profile->name().data(), buffer_len); + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserGetName, + ExportTag::kUserProfiles | ExportTag::kImplemented); typedef struct { xe::be setting_count; @@ -134,56 +113,39 @@ typedef struct { static_assert_size(X_USER_READ_PROFILE_SETTING, 40); // http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/Generic/xboxtools.cpp -SHIM_CALL XamUserReadProfileSettings_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t title_id = SHIM_GET_ARG_32(0); - uint32_t user_index = SHIM_GET_ARG_32(1); - uint32_t unk_0 = SHIM_GET_ARG_32(2); - uint32_t unk_1 = SHIM_GET_ARG_32(3); - uint32_t setting_count = SHIM_GET_ARG_32(4); - uint32_t setting_ids_ptr = SHIM_GET_ARG_32(5); - uint32_t buffer_size_ptr = SHIM_GET_ARG_32(6); - uint32_t buffer_ptr = SHIM_GET_ARG_32(7); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(8); - - uint32_t buffer_size = !buffer_size_ptr ? 0 : SHIM_MEM_32(buffer_size_ptr); - - XELOGD( - "XamUserReadProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, " - "%.8X)", - title_id, user_index, unk_0, unk_1, setting_count, setting_ids_ptr, - buffer_size_ptr, buffer_size, buffer_ptr, overlapped_ptr); +dword_result_t XamUserReadProfileSettings( + dword_t title_id, dword_t user_index, dword_t unk_0, dword_t unk_1, + dword_t setting_count, lpdword_t setting_ids, lpdword_t buffer_size_ptr, + lpvoid_t buffer_ptr, dword_t overlapped_ptr) { + uint32_t buffer_size = !buffer_size_ptr ? 0 : *buffer_size_ptr; assert_zero(unk_0); assert_zero(unk_1); // TODO(gibbed): why is this a thing? - if (user_index == 255) { - user_index = 0; + uint32_t actual_user_index = user_index; + if (actual_user_index == 255) { + actual_user_index = 0; } // Title ID = 0 means us. // 0xfffe07d1 = profile? - if (user_index) { + if (actual_user_index) { // Only support user 0. if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, - X_ERROR_NOT_FOUND); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_NOT_FOUND); + return X_ERROR_IO_PENDING; } - return; + return X_ERROR_NOT_FOUND; } - const auto& user_profile = kernel_state->user_profile(); + const auto& user_profile = kernel_state()->user_profile(); // First call asks for size (fill buffer_size_ptr). // Second call asks for buffer contents with that size. - auto setting_ids = (xe::be*)SHIM_MEM_ADDR(setting_ids_ptr); - // Compute required base size. uint32_t base_size_needed = sizeof(X_USER_READ_PROFILE_SETTINGS); base_size_needed += setting_count * sizeof(X_USER_READ_PROFILE_SETTING); @@ -209,34 +171,29 @@ SHIM_CALL XamUserReadProfileSettings_shim(PPCContext* ppc_context, if (any_missing) { // TODO(benvanik): don't fail? most games don't even check! if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, - X_ERROR_INVALID_PARAMETER); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(X_ERROR_INVALID_PARAMETER); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_INVALID_PARAMETER); + return X_ERROR_IO_PENDING; } - return; + return X_ERROR_INVALID_PARAMETER; } - SHIM_SET_MEM_32(buffer_size_ptr, size_needed); + *buffer_size_ptr = size_needed; if (!buffer_ptr || buffer_size < size_needed) { if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, - X_ERROR_INSUFFICIENT_BUFFER); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(X_ERROR_INSUFFICIENT_BUFFER); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_INSUFFICIENT_BUFFER); + return X_ERROR_IO_PENDING; } - return; + return X_ERROR_INSUFFICIENT_BUFFER; } - auto out_header = reinterpret_cast( - SHIM_MEM_ADDR(buffer_ptr)); - out_header->setting_count = setting_count; - out_header->settings_ptr = buffer_ptr + 8; + auto out_header = buffer_ptr.as(); + out_header->setting_count = static_cast(setting_count); + out_header->settings_ptr = buffer_ptr.guest_address() + 8; - auto out_setting = reinterpret_cast( - SHIM_MEM_ADDR(out_header->settings_ptr)); + auto out_setting = + reinterpret_cast(buffer_ptr + 8); size_t buffer_offset = base_size_needed; for (uint32_t n = 0; n < setting_count; ++n) { @@ -246,13 +203,13 @@ SHIM_CALL XamUserReadProfileSettings_shim(PPCContext* ppc_context, std::memset(out_setting, 0, sizeof(X_USER_READ_PROFILE_SETTING)); out_setting->from = !setting || !setting->is_set ? 0 : setting->is_title_specific() ? 2 : 1; - out_setting->user_index = user_index; + out_setting->user_index = actual_user_index; out_setting->setting_id = setting_id; if (setting && setting->is_set) { buffer_offset = - setting->Append(&out_setting->setting_data[0], - SHIM_MEM_ADDR(buffer_ptr), buffer_ptr, buffer_offset); + setting->Append(&out_setting->setting_data[0], buffer_ptr, + buffer_ptr.guest_address(), buffer_offset); } // TODO(benvanik): why did I do this? /*else { @@ -263,12 +220,14 @@ SHIM_CALL XamUserReadProfileSettings_shim(PPCContext* ppc_context, } if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; } + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserReadProfileSettings, + ExportTag::kUserProfiles | ExportTag::kImplemented); typedef struct { xe::be from; @@ -293,45 +252,33 @@ typedef struct { }; } X_USER_WRITE_PROFILE_SETTING; -SHIM_CALL XamUserWriteProfileSettings_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t unknown = SHIM_GET_ARG_32(1); - uint32_t setting_count = SHIM_GET_ARG_32(2); - uint32_t settings_ptr = SHIM_GET_ARG_32(3); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(4); - - XELOGD("XamUserWriteProfileSettings(%.8X, %d, %d, %.8X, %.8X)", user_index, - unknown, setting_count, settings_ptr, overlapped_ptr); - - if (!setting_count || !settings_ptr) { +dword_result_t XamUserWriteProfileSettings( + dword_t user_index, dword_t unk, dword_t setting_count, + pointer_t settings, dword_t overlapped_ptr) { + if (!setting_count || !settings) { if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, - X_ERROR_INVALID_PARAMETER); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(X_ERROR_INVALID_PARAMETER); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_INVALID_PARAMETER); + return X_ERROR_IO_PENDING; } - return; + return X_ERROR_INVALID_PARAMETER; } - if (user_index == 255) { - user_index = 0; + uint32_t actual_user_index = user_index; + if (actual_user_index == 255) { + actual_user_index = 0; } - if (user_index) { + if (actual_user_index) { // Only support user 0. - SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); - return; + return X_ERROR_NOT_FOUND; } // Update and save settings. - const auto& user_profile = kernel_state->user_profile(); - auto settings_data_arr = reinterpret_cast( - SHIM_MEM_ADDR(settings_ptr)); + const auto& user_profile = kernel_state()->user_profile(); for (uint32_t n = 0; n < setting_count; ++n) { - const X_USER_WRITE_PROFILE_SETTING& settings_data = settings_data_arr[n]; + const X_USER_WRITE_PROFILE_SETTING& settings_data = settings[n]; XELOGD( "XamUserWriteProfileSettings: setting index [%d]:" " from=%d setting_id=%.8X data.type=%d", @@ -343,14 +290,15 @@ SHIM_CALL XamUserWriteProfileSettings_shim(PPCContext* ppc_context, switch (settingType) { case UserProfile::Setting::Type::BINARY: { - uint8_t* settings_data_ptr = SHIM_MEM_ADDR(settings_data.binary.ptr); + uint8_t* settings_data_ptr = kernel_state()->memory()->TranslateVirtual( + settings_data.binary.ptr); size_t settings_data_len = settings_data.binary.length; std::vector data_vec; if (settings_data.binary.ptr) { // Copy provided data data_vec.resize(settings_data_len); - memcpy(data_vec.data(), settings_data_ptr, settings_data_len); + std::memcpy(data_vec.data(), settings_data_ptr, settings_data_len); } else { // Data pointer was NULL, so just fill with zeroes data_vec.resize(settings_data_len, 0); @@ -377,284 +325,215 @@ SHIM_CALL XamUserWriteProfileSettings_shim(PPCContext* ppc_context, } if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; } + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserWriteProfileSettings, + ExportTag::kUserProfiles | ExportTag::kImplemented); -SHIM_CALL XamUserCheckPrivilege_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t mask = SHIM_GET_ARG_32(1); - uint32_t out_value_ptr = SHIM_GET_ARG_32(2); - - XELOGD("XamUserCheckPrivilege(%d, %.8X, %.8X)", user_index, mask, - out_value_ptr); - - if ((user_index & 0xFF) == 0xFF) { +dword_result_t XamUserCheckPrivilege(dword_t user_index, dword_t mask, + lpdword_t out_value) { + uint32_t actual_user_index = user_index; + if ((actual_user_index & 0xFF) == 0xFF) { // Always pin user to 0. - user_index = 0; + actual_user_index = 0; } - if (user_index) { - SHIM_SET_RETURN_32(X_ERROR_NO_SUCH_USER); - return; + if (actual_user_index) { + return X_ERROR_NO_SUCH_USER; } // If we deny everything, games should hopefully not try to do stuff. - SHIM_SET_MEM_32(out_value_ptr, 0); - - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + *out_value = 0; + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserCheckPrivilege, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamUserContentRestrictionGetFlags_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t out_flags_ptr = SHIM_GET_ARG_32(1); - - XELOGD("XamUserContentRestrictionGetFlags(%d, %.8X)", user_index, - out_flags_ptr); - - if ((user_index & 0xFF) == 0xFF) { +dword_result_t XamUserContentRestrictionGetFlags(dword_t user_index, + lpdword_t out_flags) { + uint32_t actual_user_index = user_index; + if ((actual_user_index & 0xFF) == 0xFF) { // Always pin user to 0. - user_index = 0; + actual_user_index = 0; } - if (user_index) { - SHIM_SET_RETURN_32(X_ERROR_NO_SUCH_USER); - return; + if (actual_user_index) { + return X_ERROR_NO_SUCH_USER; } // No restrictions? - SHIM_SET_MEM_32(out_flags_ptr, 0); - - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + *out_flags = 0; + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserContentRestrictionGetFlags, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamUserContentRestrictionGetRating_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t unk1 = SHIM_GET_ARG_32(1); - uint32_t out_unk2_ptr = SHIM_GET_ARG_32(2); - uint32_t out_unk3_ptr = SHIM_GET_ARG_32(3); - - XELOGD("XamUserContentRestrictionGetRating(%d, %.8X, %.8X, %.8X)", user_index, - unk1, out_unk2_ptr, out_unk3_ptr); - - if ((user_index & 0xFF) == 0xFF) { +dword_result_t XamUserContentRestrictionGetRating(dword_t user_index, + dword_t unk1, + lpdword_t out_unk2, + lpdword_t out_unk3) { + uint32_t actual_user_index = user_index; + if ((actual_user_index & 0xFF) == 0xFF) { // Always pin user to 0. - user_index = 0; + actual_user_index = 0; } - if (user_index) { - SHIM_SET_RETURN_32(X_ERROR_NO_SUCH_USER); - return; + if (actual_user_index) { + return X_ERROR_NO_SUCH_USER; } // Some games have special case paths for 3F that differ from the failure // path, so my guess is that's 'don't care'. - SHIM_SET_MEM_32(out_unk2_ptr, 0x3F); - SHIM_SET_MEM_32(out_unk3_ptr, 0); - - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + *out_unk2 = 0x3F; + *out_unk3 = 0; + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserContentRestrictionGetRating, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamUserContentRestrictionCheckAccess_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t unk1 = SHIM_GET_ARG_32(1); - uint32_t unk2 = SHIM_GET_ARG_32(2); - uint32_t unk3 = SHIM_GET_ARG_32(3); - uint32_t unk4 = SHIM_GET_ARG_32(4); - uint32_t out_unk5_ptr = SHIM_GET_ARG_32(5); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(6); - - XELOGD( - "XamUserContentRestrictionCheckAccess(%d, %.8X, %.8X, %.8X, %.8X, %.8X, " - "%.8X)", - user_index, unk1, unk2, unk3, unk4, out_unk5_ptr, overlapped_ptr); - - SHIM_SET_MEM_32(out_unk5_ptr, 1); +dword_result_t XamUserContentRestrictionCheckAccess(dword_t user_index, + dword_t unk1, dword_t unk2, + dword_t unk3, dword_t unk4, + lpdword_t out_unk5, + dword_t overlapped_ptr) { + *out_unk5 = 1; if (overlapped_ptr) { // TODO(benvanik): does this need the access arg on it? - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_SUCCESS); } - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserContentRestrictionCheckAccess, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamUserAreUsersFriends_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t user_index = SHIM_GET_ARG_32(0); - uint32_t unk1 = SHIM_GET_ARG_32(1); - uint32_t unk2 = SHIM_GET_ARG_32(2); - uint32_t out_value_ptr = SHIM_GET_ARG_32(3); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(4); - - XELOGD("XamUserAreUsersFriends(%d, %.8X, %.8X, %.8X, %.8X)", user_index, unk1, - unk2, out_value_ptr, overlapped_ptr); - - if ((user_index & 0xFF) == 0xFF) { +dword_result_t XamUserAreUsersFriends(dword_t user_index, dword_t unk1, + dword_t unk2, lpdword_t out_value, + dword_t overlapped_ptr) { + uint32_t actual_user_index = user_index; + if ((actual_user_index & 0xFF) == 0xFF) { // Always pin user to 0. - user_index = 0; + actual_user_index = 0; } - SHIM_SET_MEM_32(out_value_ptr, 0); + *out_value = 0; if (user_index) { // Only support user 0. - SHIM_SET_RETURN_32(X_ERROR_NOT_LOGGED_ON); - return; + return X_ERROR_NOT_LOGGED_ON; } X_RESULT result = X_ERROR_SUCCESS; - const auto& user_profile = kernel_state->user_profile(); + const auto& user_profile = kernel_state()->user_profile(); if (user_profile->signin_state() == 0) { result = X_ERROR_NOT_LOGGED_ON; + } else { + // No friends! + *out_value = 0; } - // No friends! - SHIM_SET_MEM_32(out_value_ptr, 0); - if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, result); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(result); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result); + return X_ERROR_IO_PENDING; } + return result; } +DECLARE_XAM_EXPORT(XamUserAreUsersFriends, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamShowSigninUI_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t unk_0 = SHIM_GET_ARG_32(0); - uint32_t unk_mask = SHIM_GET_ARG_32(1); - - XELOGD("XamShowSigninUI(%d, %.8X)", unk_0, unk_mask); - +dword_result_t XamShowSigninUI(dword_t unk, dword_t unk_mask) { // Mask values vary. Probably matching user types? Local/remote? // Games seem to sit and loop until we trigger this notification. - kernel_state->BroadcastNotification(0x00000009, 0); - - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + kernel_state()->BroadcastNotification(0x00000009, 0); + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamShowSigninUI, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamUserCreateAchievementEnumerator_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t title_id = SHIM_GET_ARG_32(0); - uint32_t user_index = SHIM_GET_ARG_32(1); - uint32_t xuid = SHIM_GET_ARG_32(2); - uint32_t flags = SHIM_GET_ARG_32(3); - uint32_t offset = SHIM_GET_ARG_32(4); - uint32_t count = SHIM_GET_ARG_32(5); - uint32_t buffer_size_ptr = SHIM_GET_ARG_32(6); - uint32_t handle_ptr = SHIM_GET_ARG_32(7); - - XELOGD( - "XamUserCreateAchievementEnumerator(%.8X, %d, %.8X, %.8X, %d, %d, %.8X, " - "%.8X)", - title_id, user_index, xuid, flags, offset, count, buffer_size_ptr, - handle_ptr); - +dword_result_t XamUserCreateAchievementEnumerator(dword_t title_id, + dword_t user_index, + dword_t xuid, dword_t flags, + dword_t offset, dword_t count, + lpdword_t buffer_size_ptr, + lpdword_t handle_ptr) { if (buffer_size_ptr) { // TODO(benvanik): struct size/etc. - SHIM_SET_MEM_32(buffer_size_ptr, 64 * count); + *buffer_size_ptr = 64 * count; } - auto e = new XStaticEnumerator(kernel_state, count, 64); + auto e = new XStaticEnumerator(kernel_state(), count, 64); e->Initialize(); - SHIM_SET_MEM_32(handle_ptr, e->handle()); + *handle_ptr = e->handle(); - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamUserCreateAchievementEnumerator, + ExportTag::kUserProfiles | ExportTag::kSketchy); -SHIM_CALL XamParseGamerTileKey_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t key_ptr = SHIM_GET_ARG_32(0); - uint32_t out0_ptr = SHIM_GET_ARG_32(1); - uint32_t out1_ptr = SHIM_GET_ARG_32(2); - uint32_t out2_ptr = SHIM_GET_ARG_32(3); - - XELOGD("XamParseGamerTileKey(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", key_ptr, - out0_ptr, out1_ptr, out2_ptr); - - SHIM_SET_MEM_32(out0_ptr, 0xC0DE0001); - SHIM_SET_MEM_32(out1_ptr, 0xC0DE0002); - SHIM_SET_MEM_32(out2_ptr, 0xC0DE0003); - - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); +dword_result_t XamParseGamerTileKey(lpdword_t key_ptr, lpdword_t out1_ptr, + lpdword_t out2_ptr, lpdword_t out3_ptr) { + *out1_ptr = 0xC0DE0001; + *out2_ptr = 0xC0DE0002; + *out3_ptr = 0xC0DE0003; + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamParseGamerTileKey, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamReadTileToTexture_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t unk0 = SHIM_GET_ARG_32(0); // const? - uint32_t unk1 = SHIM_GET_ARG_32(1); // out0 from XamParseGamerTileKey - uint32_t unk2 = SHIM_GET_ARG_32(2); // some variant of out1/out2 - uint32_t unk3 = SHIM_GET_ARG_32(3); // const? - uint32_t buffer_ptr = SHIM_GET_ARG_32(4); - uint32_t stride = SHIM_GET_ARG_32(5); - uint32_t height = SHIM_GET_ARG_32(6); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(7); - - XELOGD("XamReadTileToTexture(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", unk0, unk1, - unk2, unk3, buffer_ptr, stride, height, overlapped_ptr); +dword_result_t XamReadTileToTexture(dword_t unk1, dword_t unk2, dword_t unk3, + dword_t unk4, lpvoid_t buffer_ptr, + dword_t stride, dword_t height, + dword_t overlapped_ptr) { + // unk1: const? + // unk2: out0 from XamParseGamerTileKey + // unk3: some variant of out1/out2 + // unk4: const? if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; } + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamReadTileToTexture, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamWriteGamerTile_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t arg0 = SHIM_GET_ARG_32(0); - uint32_t arg1 = SHIM_GET_ARG_32(1); - uint32_t arg2 = SHIM_GET_ARG_32(2); - uint32_t arg3 = SHIM_GET_ARG_32(3); - uint32_t arg4 = SHIM_GET_ARG_32(4); - uint32_t overlapped_ptr = SHIM_GET_ARG_32(5); - - XELOGD("XamWriteGamerTile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", arg0, arg1, - arg2, arg3, arg4, overlapped_ptr); - +dword_result_t XamWriteGamerTile(dword_t arg1, dword_t arg2, dword_t arg3, + dword_t arg4, dword_t arg5, + dword_t overlapped_ptr) { if (overlapped_ptr) { - kernel_state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); - SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } else { - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_SUCCESS); + return X_ERROR_IO_PENDING; } + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamWriteGamerTile, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamSessionCreateHandle_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t handle_ptr = SHIM_GET_ARG_32(0); - - XELOGD("XamSessionCreateHandle(%.8X)", handle_ptr); - - SHIM_SET_MEM_32(handle_ptr, 0xCAFEDEAD); - - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); +dword_result_t XamSessionCreateHandle(lpdword_t handle_ptr) { + *handle_ptr = 0xCAFEDEAD; + return X_ERROR_SUCCESS; } +DECLARE_XAM_EXPORT(XamSessionCreateHandle, + ExportTag::kUserProfiles | ExportTag::kStub); -SHIM_CALL XamSessionRefObjByHandle_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t handle = SHIM_GET_ARG_32(0); - uint32_t obj_ptr = SHIM_GET_ARG_32(1); - - XELOGD("XamSessionRefObjByHandle(%.8X, %.8X)", handle, obj_ptr); - +dword_result_t XamSessionRefObjByHandle(dword_t handle, lpdword_t obj_ptr) { assert_true(handle == 0xCAFEDEAD); - - SHIM_SET_MEM_32(obj_ptr, 0); - - SHIM_SET_RETURN_32(X_ERROR_FUNCTION_FAILED); + *obj_ptr = 0; + return X_ERROR_FUNCTION_FAILED; } +DECLARE_XAM_EXPORT(XamSessionRefObjByHandle, + ExportTag::kUserProfiles | ExportTag::kStub); } // namespace xam } // namespace kernel @@ -662,22 +541,4 @@ SHIM_CALL XamSessionRefObjByHandle_shim(PPCContext* ppc_context, void xe::kernel::xam::RegisterUserExports( xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) { - SHIM_SET_MAPPING("xam.xex", XamUserGetXUID, state); - SHIM_SET_MAPPING("xam.xex", XamUserGetSigninState, state); - SHIM_SET_MAPPING("xam.xex", XamUserGetSigninInfo, state); - SHIM_SET_MAPPING("xam.xex", XamUserGetName, state); - SHIM_SET_MAPPING("xam.xex", XamUserReadProfileSettings, state); - SHIM_SET_MAPPING("xam.xex", XamUserWriteProfileSettings, state); - SHIM_SET_MAPPING("xam.xex", XamUserCheckPrivilege, state); - SHIM_SET_MAPPING("xam.xex", XamUserContentRestrictionGetFlags, state); - SHIM_SET_MAPPING("xam.xex", XamUserContentRestrictionGetRating, state); - SHIM_SET_MAPPING("xam.xex", XamUserContentRestrictionCheckAccess, state); - SHIM_SET_MAPPING("xam.xex", XamUserAreUsersFriends, state); - SHIM_SET_MAPPING("xam.xex", XamShowSigninUI, state); - SHIM_SET_MAPPING("xam.xex", XamUserCreateAchievementEnumerator, state); - SHIM_SET_MAPPING("xam.xex", XamParseGamerTileKey, state); - SHIM_SET_MAPPING("xam.xex", XamReadTileToTexture, state); - SHIM_SET_MAPPING("xam.xex", XamWriteGamerTile, state); - SHIM_SET_MAPPING("xam.xex", XamSessionCreateHandle, state); - SHIM_SET_MAPPING("xam.xex", XamSessionRefObjByHandle, state); }