Merge branch 'master' into d3d12

This commit is contained in:
Triang3l 2018-11-25 20:13:44 +03:00
commit ab2e1b1ca7
10 changed files with 130 additions and 63 deletions

View File

@ -420,6 +420,12 @@ dword_result_t XamGetPrivateEnumStructureFromHandle(unknown_t unk1,
} }
DECLARE_XAM_EXPORT1(XamGetPrivateEnumStructureFromHandle, kNone, kStub); 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, void RegisterInfoExports(xe::cpu::ExportResolver* export_resolver,
KernelState* kernel_state) {} KernelState* kernel_state) {}

View File

@ -356,7 +356,7 @@ dword_result_t NetDll_WSAWaitForMultipleEvents(dword_t num_events,
} while (result == X_STATUS_ALERTED); } while (result == X_STATUS_ALERTED);
if (XFAILED(result)) { if (XFAILED(result)) {
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result); uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
XThread::SetLastError(error); XThread::SetLastError(error);
return ~0u; return ~0u;
} }
@ -375,7 +375,7 @@ DECLARE_XAM_EXPORT1(NetDll_WSACreateEvent, kNetworking, kImplemented);
dword_result_t NetDll_WSACloseEvent(dword_t event_handle) { dword_result_t NetDll_WSACloseEvent(dword_t event_handle) {
X_STATUS result = kernel_state()->object_table()->ReleaseHandle(event_handle); X_STATUS result = kernel_state()->object_table()->ReleaseHandle(event_handle);
if (XFAILED(result)) { if (XFAILED(result)) {
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result); uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
XThread::SetLastError(error); XThread::SetLastError(error);
return 0; return 0;
} }
@ -386,7 +386,7 @@ DECLARE_XAM_EXPORT1(NetDll_WSACloseEvent, kNetworking, kImplemented);
dword_result_t NetDll_WSAResetEvent(dword_t event_handle) { dword_result_t NetDll_WSAResetEvent(dword_t event_handle) {
X_STATUS result = xboxkrnl::xeNtClearEvent(event_handle); X_STATUS result = xboxkrnl::xeNtClearEvent(event_handle);
if (XFAILED(result)) { if (XFAILED(result)) {
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result); uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
XThread::SetLastError(error); XThread::SetLastError(error);
return 0; return 0;
} }
@ -397,7 +397,7 @@ DECLARE_XAM_EXPORT1(NetDll_WSAResetEvent, kNetworking, kImplemented);
dword_result_t NetDll_WSASetEvent(dword_t event_handle) { dword_result_t NetDll_WSASetEvent(dword_t event_handle) {
X_STATUS result = xboxkrnl::xeNtSetEvent(event_handle, nullptr); X_STATUS result = xboxkrnl::xeNtSetEvent(event_handle, nullptr);
if (XFAILED(result)) { if (XFAILED(result)) {
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result); uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
XThread::SetLastError(error); XThread::SetLastError(error);
return 0; return 0;
} }
@ -567,7 +567,7 @@ dword_result_t NetDll_socket(dword_t caller, dword_t af, dword_t type,
if (XFAILED(result)) { if (XFAILED(result)) {
socket->Release(); socket->Release();
uint32_t error = xboxkrnl::RtlNtStatusToDosError(result); uint32_t error = xboxkrnl::xeRtlNtStatusToDosError(result);
XThread::SetLastError(error); XThread::SetLastError(error);
return -1; 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); X_STATUS status = socket->IOControl(cmd, arg_ptr);
if (XFAILED(status)) { if (XFAILED(status)) {
XThread::SetLastError(xboxkrnl::RtlNtStatusToDosError(status)); XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status));
return -1; return -1;
} }
@ -665,7 +665,7 @@ dword_result_t NetDll_bind(dword_t caller, dword_t socket_handle,
N_XSOCKADDR_IN native_name(name); N_XSOCKADDR_IN native_name(name);
X_STATUS status = socket->Bind(&native_name, namelen); X_STATUS status = socket->Bind(&native_name, namelen);
if (XFAILED(status)) { if (XFAILED(status)) {
XThread::SetLastError(xboxkrnl::RtlNtStatusToDosError(status)); XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status));
return -1; return -1;
} }
@ -686,7 +686,7 @@ dword_result_t NetDll_connect(dword_t caller, dword_t socket_handle,
N_XSOCKADDR native_name(name); N_XSOCKADDR native_name(name);
X_STATUS status = socket->Connect(&native_name, namelen); X_STATUS status = socket->Connect(&native_name, namelen);
if (XFAILED(status)) { if (XFAILED(status)) {
XThread::SetLastError(xboxkrnl::RtlNtStatusToDosError(status)); XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status));
return -1; return -1;
} }
@ -706,7 +706,7 @@ dword_result_t NetDll_listen(dword_t caller, dword_t socket_handle,
X_STATUS status = socket->Listen(backlog); X_STATUS status = socket->Listen(backlog);
if (XFAILED(status)) { if (XFAILED(status)) {
XThread::SetLastError(xboxkrnl::RtlNtStatusToDosError(status)); XThread::SetLastError(xboxkrnl::xeRtlNtStatusToDosError(status));
return -1; return -1;
} }

View File

@ -45,7 +45,8 @@ dword_result_t XAudioGetVoiceCategoryVolume(dword_t unk, lpfloat_t out_ptr) {
return X_ERROR_SUCCESS; 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; } dword_result_t XAudioEnableDucker(dword_t unk) { return X_ERROR_SUCCESS; }
DECLARE_XBOXKRNL_EXPORT1(XAudioEnableDucker, kAudio, kStub); DECLARE_XBOXKRNL_EXPORT1(XAudioEnableDucker, kAudio, kStub);

View File

@ -31,8 +31,7 @@ typedef struct {
} X_THREADNAME_INFO; } X_THREADNAME_INFO;
static_assert_size(X_THREADNAME_INFO, 0x10); static_assert_size(X_THREADNAME_INFO, 0x10);
void RtlRaiseException(pointer_t<X_EXCEPTION_RECORD> record) { void HandleSetThreadName(pointer_t<X_EXCEPTION_RECORD> record) {
if (record->exception_code == 0x406D1388) {
// SetThreadName. FFS. // SetThreadName. FFS.
// https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx // https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
@ -66,15 +65,68 @@ void RtlRaiseException(pointer_t<X_EXCEPTION_RECORD> record) {
} }
// TODO(benvanik): unwinding required here? // TODO(benvanik): unwinding required here?
return; }
}
if (record->exception_code == 0xE06D7363) { 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. // C++ exception.
// https://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx // 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(); xe::debugging::Break();
}
void RtlRaiseException(pointer_t<X_EXCEPTION_RECORD> record) {
switch (record->exception_code) {
case 0x406D1388: {
HandleSetThreadName(record);
return; return;
} }
case 0xE06D7363: {
HandleCppException(record);
return;
}
}
// TODO(benvanik): unwinding. // TODO(benvanik): unwinding.
// This is going to suck. // This is going to suck.

View File

@ -971,7 +971,7 @@ const error_lookup_table error_tables[] = {
}; };
#undef MAKE_ENTRY #undef MAKE_ENTRY
dword_result_t RtlNtStatusToDosError(dword_t source_status) { uint32_t xeRtlNtStatusToDosError(uint32_t source_status) {
uint32_t status = source_status; uint32_t status = source_status;
if (!status || (status & 0x20000000)) { if (!status || (status & 0x20000000)) {
return status; return status;
@ -1010,6 +1010,10 @@ dword_result_t RtlNtStatusToDosError(dword_t source_status) {
XELOGE("RtlNtStatusToDosError lookup NOT IMPLEMENTED"); XELOGE("RtlNtStatusToDosError lookup NOT IMPLEMENTED");
return 317; // ERROR_MR_MID_NOT_FOUND 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, DECLARE_XBOXKRNL_EXPORT3(RtlNtStatusToDosError, kNone, kImportant,
kHighFrequency, kLogResult); kHighFrequency, kLogResult);

View File

@ -17,7 +17,7 @@ namespace xe {
namespace kernel { namespace kernel {
namespace xboxkrnl { namespace xboxkrnl {
dword_result_t RtlNtStatusToDosError(dword_t source_status); uint32_t xeRtlNtStatusToDosError(uint32_t source_status);
} // namespace xboxkrnl } // namespace xboxkrnl
} // namespace kernel } // namespace kernel

View File

@ -286,7 +286,8 @@ dword_result_t RtlMultiByteToUnicodeN(lpword_t destination_ptr,
return 0; 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 // https://msdn.microsoft.com/en-us/library/ff553261
dword_result_t RtlUnicodeToMultiByteN(pointer_t<uint8_t> destination_ptr, 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; 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, pointer_result_t RtlImageXexHeaderField(pointer_t<xex2_header> xex_header,
dword_t field_dword) { dword_t field_dword) {

View File

@ -736,7 +736,7 @@ DECLARE_XBOXKRNL_EXPORT1(NtCancelTimer, kThreading, kImplemented);
uint32_t xeKeWaitForSingleObject(void* object_ptr, uint32_t wait_reason, uint32_t xeKeWaitForSingleObject(void* object_ptr, uint32_t wait_reason,
uint32_t processor_mode, uint32_t alertable, uint32_t processor_mode, uint32_t alertable,
uint64_t* timeout) { uint64_t* timeout_ptr) {
auto object = XObject::GetNativeObject<XObject>(kernel_state(), object_ptr); auto object = XObject::GetNativeObject<XObject>(kernel_state(), object_ptr);
if (!object) { if (!object) {
@ -746,7 +746,7 @@ uint32_t xeKeWaitForSingleObject(void* object_ptr, uint32_t wait_reason,
} }
X_STATUS result = X_STATUS result =
object->Wait(wait_reason, processor_mode, alertable, timeout); object->Wait(wait_reason, processor_mode, alertable, timeout_ptr);
return result; return result;
} }
@ -756,7 +756,7 @@ dword_result_t KeWaitForSingleObject(lpvoid_t object_ptr, dword_t wait_reason,
lpqword_t timeout_ptr) { lpqword_t timeout_ptr) {
uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u; uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u;
return xeKeWaitForSingleObject(object_ptr, wait_reason, processor_mode, return xeKeWaitForSingleObject(object_ptr, wait_reason, processor_mode,
alertable, &timeout); alertable, timeout_ptr ? &timeout : nullptr);
} }
DECLARE_XBOXKRNL_EXPORT3(KeWaitForSingleObject, kThreading, kImplemented, DECLARE_XBOXKRNL_EXPORT3(KeWaitForSingleObject, kThreading, kImplemented,
kBlocking, kHighFrequency); kBlocking, kHighFrequency);
@ -819,7 +819,6 @@ uint32_t xeNtWaitForMultipleObjectsEx(uint32_t count, xe::be<uint32_t>* handles,
uint32_t alertable, uint32_t alertable,
uint64_t* timeout_ptr) { uint64_t* timeout_ptr) {
assert_true(wait_type <= 1); assert_true(wait_type <= 1);
X_STATUS result = X_STATUS_SUCCESS;
std::vector<object_ref<XObject>> objects; std::vector<object_ref<XObject>> objects;
for (uint32_t n = 0; n < count; n++) { 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)); objects.push_back(std::move(object));
} }
result = return XObject::WaitMultiple(count,
XObject::WaitMultiple(count, reinterpret_cast<XObject**>(objects.data()), reinterpret_cast<XObject**>(objects.data()),
wait_type, 6, wait_mode, alertable, timeout_ptr); wait_type, 6, wait_mode, alertable, timeout_ptr);
return result;
} }
dword_result_t NtWaitForMultipleObjectsEx(dword_t count, lpdword_t handles, 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) { lpqword_t timeout_ptr) {
uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u; uint64_t timeout = timeout_ptr ? static_cast<uint64_t>(*timeout_ptr) : 0u;
return xeNtWaitForMultipleObjectsEx(count, handles, wait_type, wait_mode, return xeNtWaitForMultipleObjectsEx(count, handles, wait_type, wait_mode,
alertable, &timeout); alertable,
timeout_ptr ? &timeout : nullptr);
} }
DECLARE_XBOXKRNL_EXPORT3(NtWaitForMultipleObjectsEx, kThreading, kImplemented, DECLARE_XBOXKRNL_EXPORT3(NtWaitForMultipleObjectsEx, kThreading, kImplemented,
kBlocking, kHighFrequency); kBlocking, kHighFrequency);
@ -1132,6 +1130,7 @@ struct X_ERWLOCK {
X_KSEMAPHORE reader_semaphore; // 0x20 X_KSEMAPHORE reader_semaphore; // 0x20
uint32_t spin_lock; // 0x34 uint32_t spin_lock; // 0x34
}; };
static_assert_size(X_ERWLOCK, 0x38);
void ExInitializeReadWriteLock(pointer_t<X_ERWLOCK> lock_ptr) { void ExInitializeReadWriteLock(pointer_t<X_ERWLOCK> lock_ptr) {
lock_ptr->lock_count = -1; lock_ptr->lock_count = -1;
@ -1140,6 +1139,7 @@ void ExInitializeReadWriteLock(pointer_t<X_ERWLOCK> lock_ptr) {
lock_ptr->readers_entry_count = 0; lock_ptr->readers_entry_count = 0;
KeInitializeEvent(&lock_ptr->writer_event, 1, 0); KeInitializeEvent(&lock_ptr->writer_event, 1, 0);
KeInitializeSemaphore(&lock_ptr->reader_semaphore, 0, 0x7FFFFFFF); KeInitializeSemaphore(&lock_ptr->reader_semaphore, 0, 0x7FFFFFFF);
lock_ptr->spin_lock = 0;
} }
DECLARE_XBOXKRNL_EXPORT1(ExInitializeReadWriteLock, kThreading, kImplemented); DECLARE_XBOXKRNL_EXPORT1(ExInitializeReadWriteLock, kThreading, kImplemented);
@ -1155,8 +1155,8 @@ void ExAcquireReadWriteLockExclusive(pointer_t<X_ERWLOCK> lock_ptr) {
lock_ptr->writers_waiting_count++; lock_ptr->writers_waiting_count++;
xeKeWaitForSingleObject(&lock_ptr->writer_event, 0, 0, 0, nullptr); xeKeWaitForSingleObject(&lock_ptr->writer_event, 0, 0, 0, nullptr);
} }
DECLARE_XBOXKRNL_EXPORT4(ExAcquireReadWriteLockExclusive, kThreading, DECLARE_XBOXKRNL_EXPORT3(ExAcquireReadWriteLockExclusive, kThreading,
kImplemented, kBlocking, kHighFrequency, kSketchy); kImplemented, kBlocking, kSketchy);
void ExReleaseReadWriteLock(pointer_t<X_ERWLOCK> lock_ptr) { void ExReleaseReadWriteLock(pointer_t<X_ERWLOCK> lock_ptr) {
auto old_irql = xeKeKfAcquireSpinLock(&lock_ptr->spin_lock); auto old_irql = xeKeKfAcquireSpinLock(&lock_ptr->spin_lock);

View File

@ -21,6 +21,7 @@ namespace kernel {
struct X_KEVENT { struct X_KEVENT {
X_DISPATCH_HEADER header; X_DISPATCH_HEADER header;
}; };
static_assert_size(X_KEVENT, 0x10);
class XEvent : public XObject { class XEvent : public XObject {
public: public:

View File

@ -21,6 +21,7 @@ struct X_KSEMAPHORE {
X_DISPATCH_HEADER header; X_DISPATCH_HEADER header;
xe::be<uint32_t> limit; xe::be<uint32_t> limit;
}; };
static_assert_size(X_KSEMAPHORE, 0x14);
class XSemaphore : public XObject { class XSemaphore : public XObject {
public: public: