From d9092fb2329a327dfdcc6747f471234bf477ce53 Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Tue, 22 Jul 2025 16:41:42 +0100 Subject: [PATCH] [XAM] Cleanup XEnumerateCrossTitle --- src/xenia/kernel/xam/apps/xam_app.cc | 71 ++++++++++--------- src/xenia/kernel/xam/xam_content_aggregate.cc | 1 + src/xenia/kernel/xenumerator.h | 21 ++++++ 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/xenia/kernel/xam/apps/xam_app.cc b/src/xenia/kernel/xam/apps/xam_app.cc index 817353c32..b2309a013 100644 --- a/src/xenia/kernel/xam/apps/xam_app.cc +++ b/src/xenia/kernel/xam/apps/xam_app.cc @@ -36,51 +36,52 @@ X_HRESULT XamApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, auto buffer = memory_->TranslateVirtual(buffer_ptr); switch (message) { case 0x0002000E: { - struct message_data { - xe::be user_index; - xe::be unk_04; - xe::be extra_ptr; - xe::be buffer_ptr; - xe::be buffer_size; - xe::be unk_14; - xe::be length_ptr; - xe::be unk_1C; - }* data = reinterpret_cast(buffer); + X_ENUMERATE_PARAM* data_ptr = + reinterpret_cast(buffer); + XELOGD( - "XamAppEnumerateContentAggregate({}, {:08X}, {:08X}, {:08X}, {}, " - "{:08X}, {:08X}, {:08X})", - (uint32_t)data->user_index, (uint32_t)data->unk_04, - (uint32_t)data->extra_ptr, (uint32_t)data->buffer_ptr, - (uint32_t)data->buffer_size, (uint32_t)data->unk_14, - (uint32_t)data->length_ptr, (uint32_t)data->unk_1C); - if (!data->buffer_ptr || !data->extra_ptr) { + "XEnumerateCrossTitle({:04X}, {:04X}, {:04X}, {:04X}, {}, {}, " + "{:04X})", + data_ptr->user_index.get(), data_ptr->flags.get(), + data_ptr->private_enum_structure_ptr.get(), + data_ptr->buffer_ptr.get(), data_ptr->buffer_size.get(), + data_ptr->items_requested.get(), data_ptr->items_returned_ptr.get()); + + if (!data_ptr->buffer_ptr || !data_ptr->private_enum_structure_ptr) { return X_E_INVALIDARG; } - auto extra = memory_->TranslateVirtual( - data->extra_ptr); - auto buffer = memory_->TranslateVirtual(data->buffer_ptr); + auto enum_struct = + memory_->TranslateVirtual( + data_ptr->private_enum_structure_ptr); + auto e = kernel_state_->object_table()->LookupObject( - extra->handle); + enum_struct->handle); + if (!e) { return X_E_INVALIDARG; } - assert_true(extra->magic == kXObjSignature); - if (data->buffer_size) { - std::memset(buffer, 0, data->buffer_size); - } - uint32_t item_count = 0; - auto result = e->WriteItems(data->buffer_ptr, buffer, &item_count); - if (result == X_ERROR_SUCCESS && item_count >= 1) { - if (data->length_ptr) { - auto length_ptr = - memory_->TranslateVirtual*>(data->length_ptr); - *length_ptr = 1; - } - return X_E_SUCCESS; + assert_true(enum_struct->magic == kXObjSignature); + + // This is a struct of XCONTENT_AGGREGATE_DATA + uint8_t* content_data_ptr = + memory_->TranslateVirtual(data_ptr->buffer_ptr); + + std::memset(content_data_ptr, 0, data_ptr->buffer_size); + + uint32_t item_count = 0; + X_RESULT result = e->WriteItems(0, content_data_ptr, &item_count); + + 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); } - return X_E_NO_MORE_FILES; + + return result; } case 0x00020021: { struct XContentQueryVolumeDeviceType { diff --git a/src/xenia/kernel/xam/xam_content_aggregate.cc b/src/xenia/kernel/xam/xam_content_aggregate.cc index 389b21bef..fc118f97f 100644 --- a/src/xenia/kernel/xam/xam_content_aggregate.cc +++ b/src/xenia/kernel/xam/xam_content_aggregate.cc @@ -76,6 +76,7 @@ void AddODDContentTest(object_ref> e, } } +// Alias XContentCreateCrossTitleEnumerator dword_result_t XamContentAggregateCreateEnumerator_entry(qword_t xuid, dword_t device_id, dword_t content_type, diff --git a/src/xenia/kernel/xenumerator.h b/src/xenia/kernel/xenumerator.h index 119c3653d..e90007c8a 100644 --- a/src/xenia/kernel/xenumerator.h +++ b/src/xenia/kernel/xenumerator.h @@ -19,6 +19,15 @@ namespace xe { namespace kernel { +enum X_ENUMERATION_FLAGS : uint32_t { + None = 0x0, + Back = 0x1, + Foreground = 0x2, + MatchingInstance = 0x4, + IncludePartialDownloads = 0x8, + IncludeCorruptContent = 0x10, +}; + struct X_KENUMERATOR { be app_id; be open_message; @@ -29,10 +38,22 @@ struct X_KENUMERATOR { }; static_assert_size(X_KENUMERATOR, 0x18); +struct X_ENUMERATE_PARAM { + xe::be user_index; + xe::be flags; + xe::be private_enum_structure_ptr; + xe::be buffer_ptr; // XCONTENT_DATA_INTERNAL + xe::be buffer_size; + xe::be items_requested; + xe::be items_returned_ptr; +}; +static_assert_size(X_ENUMERATE_PARAM, 0x1C); + struct X_KENUMERATOR_CONTENT_AGGREGATE { be magic; be handle; }; +static_assert_size(X_KENUMERATOR_CONTENT_AGGREGATE, 0x8); class XEnumerator : public XObject { public: