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);
|
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) {}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue