[XAM] Improvement rollup. Content, enumerators...
- [Kernel] Create guest object for XEnumerator. - [XAM] Split content data into host/guest variants. - [XAM] Correct message return type from RESULT to HRESULT. - [XAM] Add a new dummy content device for ODD. - [XAM] Implement XamContentAggregateCreateEnumerator. - [XAM] Implement XamGetPrivateEnumStructureFromHandle. - [XAM] Implement XMsgCompleteIORequest (sketchy). - [XAM] Implement XamGetOverlappedResult (sketchy). - [XAM] Implement XamTaskSchedule (sketchy).
This commit is contained in:
@@ -11,7 +11,9 @@
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/util/shim_utils.h"
|
||||
#include "xenia/kernel/xam/xam_private.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_error.h"
|
||||
#include "xenia/kernel/xevent.h"
|
||||
#include "xenia/kernel/xthread.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
@@ -40,39 +42,49 @@ dword_result_t XMsgSystemProcessCall(dword_t app, dword_t message,
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XMsgSystemProcessCall, kNone, kImplemented);
|
||||
|
||||
dword_result_t XMsgStartIORequest(dword_t app, dword_t message,
|
||||
pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||
dword_t buffer, dword_t buffer_length) {
|
||||
struct XMSGSTARTIOREQUEST_UNKNOWNARG {
|
||||
be<uint32_t> unk_0;
|
||||
be<uint32_t> unk_1;
|
||||
};
|
||||
|
||||
X_HRESULT xeXMsgStartIORequestEx(uint32_t app, uint32_t message,
|
||||
uint32_t overlapped_ptr, uint32_t buffer_ptr,
|
||||
uint32_t buffer_length,
|
||||
XMSGSTARTIOREQUEST_UNKNOWNARG* unknown) {
|
||||
auto result = kernel_state()->app_manager()->DispatchMessageAsync(
|
||||
app, message, buffer, buffer_length);
|
||||
if (result == X_ERROR_NOT_FOUND) {
|
||||
XELOGE("XMsgStartIORequest: app {:08X} undefined", app);
|
||||
app, message, buffer_ptr, buffer_length);
|
||||
if (result == X_E_NOTFOUND) {
|
||||
XELOGE("XMsgStartIORequestEx: app {:08X} undefined", app);
|
||||
result = X_E_INVALIDARG;
|
||||
XThread::SetLastError(X_ERROR_NOT_FOUND);
|
||||
}
|
||||
if (overlapped_ptr) {
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result);
|
||||
result = X_ERROR_IO_PENDING;
|
||||
}
|
||||
if (result == X_ERROR_SUCCESS || X_ERROR_IO_PENDING) {
|
||||
XThread::SetLastError(0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XMsgStartIORequest, kNone, kImplemented);
|
||||
|
||||
dword_result_t XMsgStartIORequestEx(dword_t app, dword_t message,
|
||||
pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||
dword_t buffer, dword_t buffer_length,
|
||||
lpdword_t unknown_ptr) {
|
||||
auto result = kernel_state()->app_manager()->DispatchMessageAsync(
|
||||
app, message, buffer, buffer_length);
|
||||
if (result == X_ERROR_NOT_FOUND) {
|
||||
XELOGE("XMsgStartIORequestEx: app {:08X} undefined", app);
|
||||
}
|
||||
if (overlapped_ptr) {
|
||||
kernel_state()->CompleteOverlappedImmediate(overlapped_ptr, result);
|
||||
result = X_ERROR_IO_PENDING;
|
||||
}
|
||||
return result;
|
||||
dword_result_t XMsgStartIORequestEx(
|
||||
dword_t app, dword_t message, pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||
dword_t buffer_ptr, dword_t buffer_length,
|
||||
pointer_t<XMSGSTARTIOREQUEST_UNKNOWNARG> unknown_ptr) {
|
||||
return xeXMsgStartIORequestEx(app, message, overlapped_ptr, buffer_ptr,
|
||||
buffer_length, unknown_ptr);
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XMsgStartIORequestEx, kNone, kImplemented);
|
||||
|
||||
dword_result_t XMsgStartIORequest(dword_t app, dword_t message,
|
||||
pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||
dword_t buffer_ptr, dword_t buffer_length) {
|
||||
return xeXMsgStartIORequestEx(app, message, overlapped_ptr, buffer_ptr,
|
||||
buffer_length, nullptr);
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XMsgStartIORequest, kNone, kImplemented);
|
||||
|
||||
dword_result_t XMsgCancelIORequest(pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||
dword_t wait) {
|
||||
X_HANDLE event_handle = XOverlappedGetEvent(overlapped_ptr);
|
||||
@@ -88,9 +100,42 @@ dword_result_t XMsgCancelIORequest(pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XMsgCancelIORequest, kNone, kImplemented);
|
||||
|
||||
dword_result_t XMsgCompleteIORequest(pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||
dword_t result, dword_t extended_error,
|
||||
dword_t length) {
|
||||
kernel_state()->CompleteOverlappedImmediateEx(overlapped_ptr, result,
|
||||
extended_error, length);
|
||||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
DECLARE_XAM_EXPORT2(XMsgCompleteIORequest, kNone, kImplemented, kSketchy);
|
||||
|
||||
dword_result_t XamGetOverlappedResult(pointer_t<XAM_OVERLAPPED> overlapped_ptr,
|
||||
lpdword_t length_ptr, dword_t unknown) {
|
||||
uint32_t result;
|
||||
if (overlapped_ptr->result != X_ERROR_IO_PENDING) {
|
||||
result = overlapped_ptr->result;
|
||||
} else if (!overlapped_ptr->event) {
|
||||
result = X_ERROR_IO_INCOMPLETE;
|
||||
} else {
|
||||
auto ev = kernel_state()->object_table()->LookupObject<XEvent>(
|
||||
overlapped_ptr->event);
|
||||
result = ev->Wait(3, 1, 0, nullptr);
|
||||
if (XSUCCEEDED(result)) {
|
||||
result = overlapped_ptr->result;
|
||||
} else {
|
||||
result = xboxkrnl::xeRtlNtStatusToDosError(result);
|
||||
}
|
||||
}
|
||||
if (XSUCCEEDED(result) && length_ptr) {
|
||||
*length_ptr = overlapped_ptr->length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
DECLARE_XAM_EXPORT2(XamGetOverlappedResult, kNone, kImplemented, kSketchy);
|
||||
|
||||
void RegisterMsgExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state) {}
|
||||
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
} // namespace xe
|
||||
|
||||
Reference in New Issue
Block a user