[XAM] Ensure items returned is set in enumerate.
[XAM] Ensure items returned is set in xeXamEnumerate.
This commit is contained in:
parent
c55918d944
commit
215f2a340b
|
@ -32,50 +32,44 @@ uint32_t xeXamEnumerate(uint32_t handle, uint32_t flags, void* buffer,
|
||||||
uint32_t overlapped_ptr) {
|
uint32_t overlapped_ptr) {
|
||||||
assert_true(flags == 0);
|
assert_true(flags == 0);
|
||||||
|
|
||||||
auto e = kernel_state()->object_table()->LookupObject<XEnumerator>(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;
|
X_RESULT result;
|
||||||
uint32_t item_count = 0;
|
uint32_t item_count = 0;
|
||||||
|
|
||||||
if (actual_buffer_length < e->item_size()) {
|
auto e = kernel_state()->object_table()->LookupObject<XEnumerator>(handle);
|
||||||
result = X_ERROR_INSUFFICIENT_BUFFER;
|
if (!e) {
|
||||||
} else if (e->current_item() >= e->item_count()) {
|
result = X_ERROR_INVALID_HANDLE;
|
||||||
result = X_ERROR_NO_MORE_FILES;
|
|
||||||
} else {
|
} else {
|
||||||
auto item_buffer = static_cast<uint8_t*>(buffer);
|
size_t actual_buffer_length = buffer_length;
|
||||||
auto max_items = actual_buffer_length / e->item_size();
|
if (buffer_length == e->items_per_enumerate()) {
|
||||||
while (max_items--) {
|
actual_buffer_length = e->item_size() * e->items_per_enumerate();
|
||||||
if (!e->WriteItem(item_buffer)) {
|
// Known culprits:
|
||||||
break;
|
// Final Fight: Double Impact (saves)
|
||||||
}
|
XELOGW(
|
||||||
item_buffer += e->item_size();
|
"Broken usage of XamEnumerate! buffer length={:X} vs actual "
|
||||||
item_count++;
|
"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<uint8_t*>(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) {
|
if (items_returned) {
|
||||||
|
|
Loading…
Reference in New Issue