diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc index 4f11ca04b..d711fa023 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc @@ -144,13 +144,14 @@ dword_result_t NtReadFile_entry(dword_t file_handle, dword_t event_handle, } if (XSUCCEEDED(result)) { - if (true || file->is_synchronous()) { + if (file->is_synchronous()) { // Synchronous. uint32_t bytes_read = 0; result = file->Read( buffer.guest_address(), buffer_length, byte_offset_ptr ? static_cast(*byte_offset_ptr) : -1, &bytes_read, apc_context); + if (io_status_block) { io_status_block->status = result; io_status_block->information = bytes_read; @@ -167,32 +168,34 @@ dword_result_t NtReadFile_entry(dword_t file_handle, dword_t event_handle, } } - if (!file->is_synchronous() && result != X_STATUS_END_OF_FILE) { - result = X_STATUS_PENDING; - } - // Mark that we should signal the event now. We do this after // we have written the info out. signal_event = true; } else { // TODO(benvanik): async. + uint32_t bytes_read = 0; + auto result = file->Read( + buffer.guest_address(), buffer_length, + byte_offset_ptr ? static_cast(*byte_offset_ptr) : -1, + &bytes_read, apc_context); - // X_STATUS_PENDING if not returning immediately. - // XFile is waitable and signalled after each async req completes. - // reset the input event (->Reset()) - /*xeNtReadFileState* call_state = new xeNtReadFileState(); - XAsyncRequest* request = new XAsyncRequest( - state, file, - (XAsyncRequest::CompletionCallback)xeNtReadFileCompleted, - call_state);*/ - // result = file->Read(buffer.guest_address(), buffer_length, byte_offset, - // request); if (io_status_block) { - io_status_block->status = X_STATUS_PENDING; - io_status_block->information = 0; + io_status_block->status = result; + io_status_block->information = bytes_read; } - result = X_STATUS_PENDING; + if ((uint32_t)apc_routine_ptr & ~1) { + if (apc_context) { + auto thread = XThread::GetCurrentThread(); + thread->EnqueueApc(static_cast(apc_routine_ptr) & ~1u, + apc_context, io_status_block, 0); + } + } + + if (ev && XSUCCEEDED(result)) { + ev->Set(0, false); + } + return X_STATUS_PENDING; } }