From 07501cfcb9f592c3f99eeb7a8d8f10294755a980 Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Sat, 22 Nov 2025 20:28:10 +0000 Subject: [PATCH] [XAM] Fixed XEnumerateCrossTitle corrupt items_returned_ptr Fixed Halo: Reach from crashing when accessing The Armory --- src/xenia/kernel/xam/apps/xam_app.cc | 14 +++++++------- src/xenia/kernel/xam/content_manager.h | 6 ++++++ src/xenia/kernel/xam/xam_content_aggregate.cc | 19 ++++++++++++++----- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/xenia/kernel/xam/apps/xam_app.cc b/src/xenia/kernel/xam/apps/xam_app.cc index 7cf8a1276..0a3b86371 100644 --- a/src/xenia/kernel/xam/apps/xam_app.cc +++ b/src/xenia/kernel/xam/apps/xam_app.cc @@ -64,11 +64,11 @@ X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, assert_true(enum_struct->magic == kXObjSignature); - // This is a struct of XCONTENT_AGGREGATE_DATA + // This is a struct of XCONTENT_DATA_INTERNAL uint8_t* content_data_ptr = memory_->TranslateVirtual(data_ptr->buffer_ptr); - assert_true(data_ptr->buffer_size == sizeof(XCONTENT_AGGREGATE_DATA)); + assert_true(data_ptr->buffer_size == sizeof(XCONTENT_DATA_INTERNAL)); std::memset(content_data_ptr, 0, data_ptr->buffer_size); @@ -77,11 +77,11 @@ X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, result = X_HRESULT_FROM_WIN32(result); - if (result == X_E_SUCCESS && data_ptr->items_returned_ptr && - item_count >= 1) { - xe::store_and_swap( - memory_->TranslateVirtual(data_ptr->items_returned_ptr), 1); - } + xe::be* items_returned_ptr = + memory_->TranslateVirtual*>( + data_ptr->items_returned_ptr); + + *items_returned_ptr = item_count; return result; } diff --git a/src/xenia/kernel/xam/content_manager.h b/src/xenia/kernel/xam/content_manager.h index 618c12022..02b03c19f 100644 --- a/src/xenia/kernel/xam/content_manager.h +++ b/src/xenia/kernel/xam/content_manager.h @@ -119,6 +119,12 @@ struct XCONTENT_AGGREGATE_DATA : XCONTENT_DATA { }; static_assert_size(XCONTENT_AGGREGATE_DATA, 0x148); +struct XCONTENT_CROSS_TITLE_DATA { + XCONTENT_DATA content_data; + xe::be title_id; +}; +static_assert_size(XCONTENT_CROSS_TITLE_DATA, 0x138); + struct XCONTENT_DATA_MEDIA { be series_id[0x10]; // 0x0 sz:0x10 be seasonid[0x10]; // 0x10 sz:0x10 diff --git a/src/xenia/kernel/xam/xam_content_aggregate.cc b/src/xenia/kernel/xam/xam_content_aggregate.cc index fc118f97f..539b0c431 100644 --- a/src/xenia/kernel/xam/xam_content_aggregate.cc +++ b/src/xenia/kernel/xam/xam_content_aggregate.cc @@ -89,7 +89,7 @@ dword_result_t XamContentAggregateCreateEnumerator_entry(qword_t xuid, return X_E_INVALIDARG; } - auto e = make_object>( + auto e = make_object>( kernel_state(), 1); X_KENUMERATOR_CONTENT_AGGREGATE* extra; auto result = e->Initialize(XUserIndexAny, 0xFE, 0x2000E, 0x20010, 0, &extra); @@ -125,15 +125,24 @@ dword_result_t XamContentAggregateCreateEnumerator_entry(qword_t xuid, auto item = e->AppendItem(); assert_not_null(item); if (item) { - *item = content_data; + item->content_data.device_id = content_data.device_id; + item->content_data.content_type = content_data.content_type; + item->content_data.display_name_raw = content_data.display_name_raw; + std::memcpy(item->content_data.file_name_raw, + content_data.file_name_raw, + sizeof(content_data.file_name_raw)); + item->content_data.padding[0] = 0; + item->content_data.padding[1] = 0; + + item->title_id = content_data.title_id; } } } } - if (!device_info || device_info->device_type == DeviceType::ODD) { - AddODDContentTest(e, content_type_enum); - } + // if (!device_info || device_info->device_type == DeviceType::ODD) { + // AddODDContentTest(e, content_type_enum); + // } XELOGD("XamContentAggregateCreateEnumerator: added {} items to enumerator", e->item_count());