From 215f2a340b7c06a232f8480401b37c73bb79f238 Mon Sep 17 00:00:00 2001 From: gibbed Date: Sun, 29 Nov 2020 02:00:16 -0600 Subject: [PATCH] [XAM] Ensure items returned is set in enumerate. [XAM] Ensure items returned is set in xeXamEnumerate. --- src/xenia/kernel/xam/xam_enum.cc | 72 +++++++++++++++----------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/src/xenia/kernel/xam/xam_enum.cc b/src/xenia/kernel/xam/xam_enum.cc index 2cab56ab7..9aec9b056 100644 --- a/src/xenia/kernel/xam/xam_enum.cc +++ b/src/xenia/kernel/xam/xam_enum.cc @@ -32,50 +32,44 @@ uint32_t xeXamEnumerate(uint32_t handle, uint32_t flags, void* buffer, uint32_t overlapped_ptr) { assert_true(flags == 0); - auto e = kernel_state()->object_table()->LookupObject(handle); - if (!e) { - if (overlapped_ptr) { - kernel_state()->CompleteOverlappedImmediateEx( - overlapped_ptr, X_ERROR_INVALID_HANDLE, X_ERROR_INVALID_HANDLE, 0); - return X_ERROR_IO_PENDING; - } else { - return X_ERROR_INVALID_HANDLE; - } - } - - size_t actual_buffer_length = buffer_length; - if (buffer_length == e->items_per_enumerate()) { - actual_buffer_length = e->item_size() * e->items_per_enumerate(); - // Known culprits: - // Final Fight: Double Impact (saves) - XELOGW( - "Broken usage of XamEnumerate! buffer length={:X} vs actual " - "length={:X} " - "(item size={:X}, items per enumerate={})", - (uint32_t)buffer_length, actual_buffer_length, e->item_size(), - e->items_per_enumerate()); - } - - std::memset(buffer, 0, actual_buffer_length); - X_RESULT result; uint32_t item_count = 0; - if (actual_buffer_length < e->item_size()) { - result = X_ERROR_INSUFFICIENT_BUFFER; - } else if (e->current_item() >= e->item_count()) { - result = X_ERROR_NO_MORE_FILES; + auto e = kernel_state()->object_table()->LookupObject(handle); + if (!e) { + result = X_ERROR_INVALID_HANDLE; } else { - auto item_buffer = static_cast(buffer); - auto max_items = actual_buffer_length / e->item_size(); - while (max_items--) { - if (!e->WriteItem(item_buffer)) { - break; - } - item_buffer += e->item_size(); - item_count++; + size_t actual_buffer_length = buffer_length; + if (buffer_length == e->items_per_enumerate()) { + actual_buffer_length = e->item_size() * e->items_per_enumerate(); + // Known culprits: + // Final Fight: Double Impact (saves) + XELOGW( + "Broken usage of XamEnumerate! buffer length={:X} vs actual " + "length={:X} " + "(item size={:X}, items per enumerate={})", + (uint32_t)buffer_length, actual_buffer_length, e->item_size(), + e->items_per_enumerate()); + } + + std::memset(buffer, 0, actual_buffer_length); + + if (actual_buffer_length < e->item_size()) { + result = X_ERROR_INSUFFICIENT_BUFFER; + } else if (e->current_item() >= e->item_count()) { + result = X_ERROR_NO_MORE_FILES; + } else { + auto item_buffer = static_cast(buffer); + auto max_items = actual_buffer_length / e->item_size(); + while (max_items--) { + if (!e->WriteItem(item_buffer)) { + break; + } + item_buffer += e->item_size(); + item_count++; + } + result = X_ERROR_SUCCESS; } - result = X_ERROR_SUCCESS; } if (items_returned) {