Merge branch 'master' into d3d12
This commit is contained in:
commit
ab2e1b1ca7
|
@ -420,6 +420,12 @@ dword_result_t XamGetPrivateEnumStructureFromHandle(unknown_t unk1,
|
|||
}
|
||||
DECLARE_XAM_EXPORT1(XamGetPrivateEnumStructureFromHandle, kNone, kStub);
|
||||
|
||||
dword_result_t XamQueryLiveHiveW(lpwstring_t name, lpvoid_t out_buf,
|
||||
dword_t out_size, dword_t type /* guess */) {
|
||||
return X_STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
DECLARE_XAM_EXPORT1(XamQueryLiveHiveW, kNone, kStub);
|
||||
|
||||
void RegisterInfoExports(xe::cpu::ExportResolver* export_resolver,
|
||||
KernelState* kernel_state) {}
|
||||
|
||||
|
|
|
@ -356,7 +356,7 @@ dword_result_t NetDll_WSAWaitForMultipleEvents(dword_t num_events,
|
|||
} while (result == X_STATUS_ALERTED);
|
||||
|
||||
if (XFAILED(result)) {
|
||||
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result);
|
||||
uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
|
||||
XThread::SetLastError(error);
|
||||
return ~0u;
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ DECLARE_XAM_EXPORT1(NetDll_WSACreateEvent, kNetworking, kImplemented);
|
|||
dword_result_t NetDll_WSACloseEvent(dword_t event_handle) {
|
||||
X_STATUS result = kernel_state()->object_table()->ReleaseHandle(event_handle);
|
||||
if (XFAILED(result)) {
|
||||
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result);
|
||||
uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
|
||||
XThread::SetLastError(error);
|
||||
return 0;
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ DECLARE_XAM_EXPORT1(NetDll_WSACloseEvent, kNetworking, kImplemented);
|
|||
dword_result_t NetDll_WSAResetEvent(dword_t event_handle) {
|
||||
X_STATUS result = xboxkrnl::xeNtClearEvent(event_handle);
|
||||
if (XFAILED(result)) {
|
||||
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result);
|
||||
uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
|
||||
XThread::SetLastError(error);
|
||||
return 0;
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ DECLARE_XAM_EXPORT1(NetDll_WSAResetEvent, kNetworking, kImplemented);
|
|||
dword_result_t NetDll_WSASetEvent(dword_t event_handle) {
|
||||
X_STATUS result = xboxkrnl::xeNtSetEvent(event_handle, nullptr);
|
||||
if (XFAILED(result)) {
|
||||
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result);
|
||||
uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
|
||||
XThread::SetLastError(error);
|
||||
return 0;
|
||||
}
|
||||
|
@ -567,7 +567,7 @@ dword_result_t NetDll_socket(dword_t caller, dword_t af, dword_t type,
|
|||
if (XFAILED(result)) {
|
||||
socket->Release();
|
||||
|
||||
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result);
|
||||
uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
|
||||
XThread::SetLastError(error);
|
||||
return -1;
|
||||
}
|
||||
|
@ -643,7 +643,7 @@ dword_result_t NetDll_ioctlsocket(dword_t caller, dword_t socket_handle,
|
|||
|
||||
X_STATUS status = socket->IOControl(cmd, arg_ptr);
|
||||
if (XFAILED(status)) {
|
||||
XThread::SetLastError(xboxkrnl::RtlNtStatusToDosError(status));
|
||||
XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -665,7 +665,7 @@ dword_result_t NetDll_bind(dword_t caller, dword_t socket_handle,
|
|||
N_XSOCKADDR_IN native_name(name);
|
||||
X_STATUS status = socket->Bind(&native_name, namelen);
|
||||
if (XFAILED(status)) {
|
||||
XThread::SetLastError(xboxkrnl::RtlNtStatusToDosError(status));
|
||||
XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -686,7 +686,7 @@ dword_result_t NetDll_connect(dword_t caller, dword_t socket_handle,
|
|||
N_XSOCKADDR native_name(name);
|
||||
X_STATUS status = socket->Connect(&native_name, namelen);
|
||||
if (XFAILED(status)) {
|
||||
XThread::SetLastError(xboxkrnl::RtlNtStatusToDosError(status));
|
||||
XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -706,7 +706,7 @@ dword_result_t NetDll_listen(dword_t caller, dword_t socket_handle,
|
|||
|
||||
X_STATUS status = socket->Listen(backlog);
|
||||
if (XFAILED(status)) {
|
||||
XThread::SetLastError(xboxkrnl::RtlNtStatusToDosError(status));
|
||||
XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ dword_result_t XAudioGetVoiceCategoryVolume(dword_t unk, lpfloat_t out_ptr) {
|
|||
|
||||
return X_ERROR_SUCCESS;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(XAudioGetVoiceCategoryVolume, kAudio, kStub);
|
||||
DECLARE_XBOXKRNL_EXPORT2(XAudioGetVoiceCategoryVolume, kAudio, kStub,
|
||||
kHighFrequency);
|
||||
|
||||
dword_result_t XAudioEnableDucker(dword_t unk) { return X_ERROR_SUCCESS; }
|
||||
DECLARE_XBOXKRNL_EXPORT1(XAudioEnableDucker, kAudio, kStub);
|
||||
|
|
|
@ -31,49 +31,101 @@ typedef struct {
|
|||
} X_THREADNAME_INFO;
|
||||
static_assert_size(X_THREADNAME_INFO, 0x10);
|
||||
|
||||
void RtlRaiseException(pointer_t<X_EXCEPTION_RECORD> record) {
|
||||
if (record->exception_code == 0x406D1388) {
|
||||
// SetThreadName. FFS.
|
||||
// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
|
||||
void HandleSetThreadName(pointer_t<X_EXCEPTION_RECORD> record) {
|
||||
// SetThreadName. FFS.
|
||||
// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
|
||||
|
||||
// TODO(benvanik): check record->number_parameters to make sure it's a
|
||||
// correct size.
|
||||
auto thread_info =
|
||||
reinterpret_cast<X_THREADNAME_INFO*>(&record->exception_information[0]);
|
||||
// TODO(benvanik): check record->number_parameters to make sure it's a
|
||||
// correct size.
|
||||
auto thread_info =
|
||||
reinterpret_cast<X_THREADNAME_INFO*>(&record->exception_information[0]);
|
||||
|
||||
assert_true(thread_info->type == 0x1000);
|
||||
assert_true(thread_info->type == 0x1000);
|
||||
|
||||
if (!thread_info->name_ptr) {
|
||||
XELOGD("SetThreadName called with null name_ptr");
|
||||
return;
|
||||
}
|
||||
|
||||
auto name =
|
||||
kernel_memory()->TranslateVirtual<const char*>(thread_info->name_ptr);
|
||||
|
||||
object_ref<XThread> thread;
|
||||
if (thread_info->thread_id == -1) {
|
||||
// Current thread.
|
||||
thread = retain_object(XThread::GetCurrentThread());
|
||||
} else {
|
||||
// Lookup thread by ID.
|
||||
thread = kernel_state()->GetThreadByID(thread_info->thread_id);
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
XELOGD("SetThreadName(%d, %s)", thread->thread_id(), name);
|
||||
thread->set_name(name);
|
||||
}
|
||||
|
||||
// TODO(benvanik): unwinding required here?
|
||||
if (!thread_info->name_ptr) {
|
||||
XELOGD("SetThreadName called with null name_ptr");
|
||||
return;
|
||||
}
|
||||
|
||||
if (record->exception_code == 0xE06D7363) {
|
||||
// C++ exception.
|
||||
// https://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
|
||||
xe::debugging::Break();
|
||||
return;
|
||||
auto name =
|
||||
kernel_memory()->TranslateVirtual<const char*>(thread_info->name_ptr);
|
||||
|
||||
object_ref<XThread> thread;
|
||||
if (thread_info->thread_id == -1) {
|
||||
// Current thread.
|
||||
thread = retain_object(XThread::GetCurrentThread());
|
||||
} else {
|
||||
// Lookup thread by ID.
|
||||
thread = kernel_state()->GetThreadByID(thread_info->thread_id);
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
XELOGD("SetThreadName(%d, %s)", thread->thread_id(), name);
|
||||
thread->set_name(name);
|
||||
}
|
||||
|
||||
// TODO(benvanik): unwinding required here?
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
xe::be<int32_t> mdisp;
|
||||
xe::be<int32_t> pdisp;
|
||||
xe::be<int32_t> vdisp;
|
||||
} x_PMD;
|
||||
|
||||
typedef struct {
|
||||
xe::be<uint32_t> properties;
|
||||
xe::be<uint32_t> type_ptr;
|
||||
x_PMD this_displacement;
|
||||
xe::be<int32_t> size_or_offset;
|
||||
xe::be<uint32_t> copy_function_ptr;
|
||||
} x_s__CatchableType;
|
||||
|
||||
typedef struct {
|
||||
xe::be<int32_t> number_catchable_types;
|
||||
xe::be<uint32_t> catchable_type_ptrs[1];
|
||||
} x_s__CatchableTypeArray;
|
||||
|
||||
typedef struct {
|
||||
xe::be<uint32_t> attributes;
|
||||
xe::be<uint32_t> unwind_ptr;
|
||||
xe::be<uint32_t> forward_compat_ptr;
|
||||
xe::be<uint32_t> catchable_type_array_ptr;
|
||||
} x_s__ThrowInfo;
|
||||
|
||||
void HandleCppException(pointer_t<X_EXCEPTION_RECORD> record) {
|
||||
// C++ exception.
|
||||
// https://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
|
||||
// http://www.drdobbs.com/visual-c-exception-handling-instrumentat/184416600
|
||||
// http://www.openrce.org/articles/full_view/21
|
||||
|
||||
assert_true(record->number_parameters == 3);
|
||||
assert_true(record->exception_information[0] == 0x19930520);
|
||||
|
||||
auto thrown_ptr = record->exception_information[1];
|
||||
auto thrown = kernel_memory()->TranslateVirtual(thrown_ptr);
|
||||
auto vftable_ptr = *reinterpret_cast<xe::be<uint32_t>*>(thrown);
|
||||
|
||||
auto throw_info_ptr = record->exception_information[2];
|
||||
auto throw_info =
|
||||
kernel_memory()->TranslateVirtual<x_s__ThrowInfo*>(throw_info_ptr);
|
||||
auto catchable_types =
|
||||
kernel_memory()->TranslateVirtual<x_s__CatchableTypeArray*>(
|
||||
throw_info->catchable_type_array_ptr);
|
||||
|
||||
xe::debugging::Break();
|
||||
}
|
||||
|
||||
void RtlRaiseException(pointer_t<X_EXCEPTION_RECORD> record) {
|
||||
switch (record->exception_code) {
|
||||
case 0x406D1388: {
|
||||
HandleSetThreadName(record);
|
||||
return;
|
||||
}
|
||||
case 0xE06D7363: {
|
||||
HandleCppException(record);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(benvanik): unwinding.
|
||||
|
|
|
@ -971,7 +971,7 @@ const error_lookup_table error_tables[] = {
|
|||
};
|
||||
#undef MAKE_ENTRY
|
||||
|
||||
dword_result_t RtlNtStatusToDosError(dword_t source_status) {
|
||||
uint32_t xeRtlNtStatusToDosError(uint32_t source_status) {
|
||||
uint32_t status = source_status;
|
||||
if (!status || (status & 0x20000000)) {
|
||||
return status;
|
||||
|
@ -1010,6 +1010,10 @@ dword_result_t RtlNtStatusToDosError(dword_t source_status) {
|
|||
XELOGE("RtlNtStatusToDosError lookup NOT IMPLEMENTED");
|
||||
return 317; // ERROR_MR_MID_NOT_FOUND
|
||||
}
|
||||
|
||||
dword_result_t RtlNtStatusToDosError(dword_t source_status) {
|
||||
return xeRtlNtStatusToDosError(source_status);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT3(RtlNtStatusToDosError, kNone, kImportant,
|
||||
kHighFrequency, kLogResult);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace xe {
|
|||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
dword_result_t RtlNtStatusToDosError(dword_t source_status);
|
||||
uint32_t xeRtlNtStatusToDosError(uint32_t source_status);
|
||||
|
||||
} // namespace xboxkrnl
|
||||
} // namespace kernel
|
||||
|
|
|
@ -286,7 +286,8 @@ dword_result_t RtlMultiByteToUnicodeN(lpword_t destination_ptr,
|
|||
|
||||
return 0;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT2(RtlMultiByteToUnicodeN, kNone, kImplemented, kSketchy);
|
||||
DECLARE_XBOXKRNL_EXPORT3(RtlMultiByteToUnicodeN, kNone, kImplemented,
|
||||
kHighFrequency, kSketchy);
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/ff553261
|
||||
dword_result_t RtlUnicodeToMultiByteN(pointer_t<uint8_t> destination_ptr,
|
||||
|
@ -308,7 +309,8 @@ dword_result_t RtlUnicodeToMultiByteN(pointer_t<uint8_t> destination_ptr,
|
|||
|
||||
return 0;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT2(RtlUnicodeToMultiByteN, kNone, kImplemented, kSketchy);
|
||||
DECLARE_XBOXKRNL_EXPORT3(RtlUnicodeToMultiByteN, kNone, kImplemented,
|
||||
kHighFrequency, kSketchy);
|
||||
|
||||
pointer_result_t RtlImageXexHeaderField(pointer_t<xex2_header> xex_header,
|
||||
dword_t field_dword) {
|
||||
|
|
|
@ -736,7 +736,7 @@ DECLARE_XBOXKRNL_EXPORT1(NtCancelTimer, kThreading, kImplemented);
|
|||
|
||||
uint32_t xeKeWaitForSingleObject(void* object_ptr, uint32_t wait_reason,
|
||||
uint32_t processor_mode, uint32_t alertable,
|
||||
uint64_t* timeout) {
|
||||
uint64_t* timeout_ptr) {
|
||||
auto object = XObject::GetNativeObject<XObject>(kernel_state(), object_ptr);
|
||||
|
||||
if (!object) {
|
||||
|
@ -746,7 +746,7 @@ uint32_t xeKeWaitForSingleObject(void* object_ptr, uint32_t wait_reason,
|
|||
}
|
||||
|
||||
X_STATUS result =
|
||||
object->Wait(wait_reason, processor_mode, alertable, timeout);
|
||||
object->Wait(wait_reason, processor_mode, alertable, timeout_ptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ dword_result_t KeWaitForSingleObject(lpvoid_t object_ptr, dword_t wait_reason,
|
|||
lpqword_t timeout_ptr) {
|
||||
uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u;
|
||||
return xeKeWaitForSingleObject(object_ptr, wait_reason, processor_mode,
|
||||
alertable, &timeout);
|
||||
alertable, timeout_ptr ? &timeout : nullptr);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT3(KeWaitForSingleObject, kThreading, kImplemented,
|
||||
kBlocking, kHighFrequency);
|
||||
|
@ -819,7 +819,6 @@ uint32_t xeNtWaitForMultipleObjectsEx(uint32_t count, xe::be<uint32_t>* handles,
|
|||
uint32_t alertable,
|
||||
uint64_t* timeout_ptr) {
|
||||
assert_true(wait_type <= 1);
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
|
||||
std::vector<object_ref<XObject>> objects;
|
||||
for (uint32_t n = 0; n < count; n++) {
|
||||
|
@ -832,11 +831,9 @@ uint32_t xeNtWaitForMultipleObjectsEx(uint32_t count, xe::be<uint32_t>* handles,
|
|||
objects.push_back(std::move(object));
|
||||
}
|
||||
|
||||
result =
|
||||
XObject::WaitMultiple(count, reinterpret_cast<XObject**>(objects.data()),
|
||||
wait_type, 6, wait_mode, alertable, timeout_ptr);
|
||||
|
||||
return result;
|
||||
return XObject::WaitMultiple(count,
|
||||
reinterpret_cast<XObject**>(objects.data()),
|
||||
wait_type, 6, wait_mode, alertable, timeout_ptr);
|
||||
}
|
||||
|
||||
dword_result_t NtWaitForMultipleObjectsEx(dword_t count, lpdword_t handles,
|
||||
|
@ -845,7 +842,8 @@ dword_result_t NtWaitForMultipleObjectsEx(dword_t count, lpdword_t handles,
|
|||
lpqword_t timeout_ptr) {
|
||||
uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u;
|
||||
return xeNtWaitForMultipleObjectsEx(count, handles, wait_type, wait_mode,
|
||||
alertable, &timeout);
|
||||
alertable,
|
||||
timeout_ptr ? &timeout : nullptr);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT3(NtWaitForMultipleObjectsEx, kThreading, kImplemented,
|
||||
kBlocking, kHighFrequency);
|
||||
|
@ -1132,6 +1130,7 @@ struct X_ERWLOCK {
|
|||
X_KSEMAPHORE reader_semaphore; // 0x20
|
||||
uint32_t spin_lock; // 0x34
|
||||
};
|
||||
static_assert_size(X_ERWLOCK, 0x38);
|
||||
|
||||
void ExInitializeReadWriteLock(pointer_t<X_ERWLOCK> lock_ptr) {
|
||||
lock_ptr->lock_count = -1;
|
||||
|
@ -1140,6 +1139,7 @@ void ExInitializeReadWriteLock(pointer_t<X_ERWLOCK> lock_ptr) {
|
|||
lock_ptr->readers_entry_count = 0;
|
||||
KeInitializeEvent(&lock_ptr->writer_event, 1, 0);
|
||||
KeInitializeSemaphore(&lock_ptr->reader_semaphore, 0, 0x7FFFFFFF);
|
||||
lock_ptr->spin_lock = 0;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(ExInitializeReadWriteLock, kThreading, kImplemented);
|
||||
|
||||
|
@ -1155,8 +1155,8 @@ void ExAcquireReadWriteLockExclusive(pointer_t<X_ERWLOCK> lock_ptr) {
|
|||
lock_ptr->writers_waiting_count++;
|
||||
xeKeWaitForSingleObject(&lock_ptr->writer_event, 0, 0, 0, nullptr);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT4(ExAcquireReadWriteLockExclusive, kThreading,
|
||||
kImplemented, kBlocking, kHighFrequency, kSketchy);
|
||||
DECLARE_XBOXKRNL_EXPORT3(ExAcquireReadWriteLockExclusive, kThreading,
|
||||
kImplemented, kBlocking, kSketchy);
|
||||
|
||||
void ExReleaseReadWriteLock(pointer_t<X_ERWLOCK> lock_ptr) {
|
||||
auto old_irql = xeKeKfAcquireSpinLock(&lock_ptr->spin_lock);
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace kernel {
|
|||
struct X_KEVENT {
|
||||
X_DISPATCH_HEADER header;
|
||||
};
|
||||
static_assert_size(X_KEVENT, 0x10);
|
||||
|
||||
class XEvent : public XObject {
|
||||
public:
|
||||
|
|
|
@ -21,6 +21,7 @@ struct X_KSEMAPHORE {
|
|||
X_DISPATCH_HEADER header;
|
||||
xe::be<uint32_t> limit;
|
||||
};
|
||||
static_assert_size(X_KSEMAPHORE, 0x14);
|
||||
|
||||
class XSemaphore : public XObject {
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue