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);
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) {}

View File

@ -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;
}

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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);

View File

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

View File

@ -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: