Cleanup some Ke* threading APIs (and update the dispatch header when possible)
This commit is contained in:
@@ -423,6 +423,65 @@ SHIM_CALL KeTlsSetValue_shim(PPCContext* ppc_context,
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
dword_result_t KeInitializeEvent(pointer_t<X_KEVENT> event_ptr,
|
||||
dword_t event_type, dword_t initial_state) {
|
||||
event_ptr.Zero();
|
||||
event_ptr->header.type = event_type;
|
||||
event_ptr->header.signal_state = (uint32_t)initial_state;
|
||||
auto ev =
|
||||
XObject::GetNativeObject<XEvent>(kernel_state(), event_ptr, event_type);
|
||||
if (!ev) {
|
||||
return X_STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(KeInitializeEvent,
|
||||
ExportTag::kImplemented | ExportTag::kThreading);
|
||||
|
||||
dword_result_t KeSetEvent(pointer_t<X_KEVENT> event_ptr, dword_t increment,
|
||||
dword_t wait) {
|
||||
// Update dispatch header
|
||||
xe::atomic_exchange(xe::byte_swap<uint32_t>(1),
|
||||
(uint32_t*)&event_ptr->header.signal_state);
|
||||
|
||||
auto ev = XObject::GetNativeObject<XEvent>(kernel_state(), event_ptr);
|
||||
if (!ev) {
|
||||
assert_always();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ev->Set(increment, !!wait);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(KeSetEvent,
|
||||
ExportTag::kImplemented | ExportTag::kThreading);
|
||||
|
||||
dword_result_t KePulseEvent(pointer_t<X_KEVENT> event_ptr, dword_t increment,
|
||||
dword_t wait) {
|
||||
auto ev = XObject::GetNativeObject<XEvent>(kernel_state(), event_ptr);
|
||||
if (!ev) {
|
||||
assert_always();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ev->Pulse(increment, !!wait);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(KePulseEvent, ExportTag::kImplemented);
|
||||
|
||||
dword_result_t KeResetEvent(pointer_t<X_KEVENT> event_ptr) {
|
||||
// Update dispatch header
|
||||
xe::atomic_exchange(0, (uint32_t*)&event_ptr->header.signal_state);
|
||||
|
||||
auto ev = XObject::GetNativeObject<XEvent>(kernel_state(), event_ptr);
|
||||
if (!ev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ev->Reset();
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(KeResetEvent,
|
||||
ExportTag::kImplemented | ExportTag::kThreading);
|
||||
|
||||
SHIM_CALL NtCreateEvent_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(0);
|
||||
@@ -451,43 +510,6 @@ SHIM_CALL NtCreateEvent_shim(PPCContext* ppc_context,
|
||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
SHIM_CALL KeInitializeEvent_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t event_type = SHIM_GET_ARG_32(1);
|
||||
uint32_t initial_state = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD("KeInitializeEvent(%.8X, %.8X, %.8X)", handle_ptr, event_type,
|
||||
initial_state);
|
||||
|
||||
XEvent* ev = new XEvent(kernel_state);
|
||||
ev->Initialize(!event_type, !!initial_state);
|
||||
|
||||
if (handle_ptr) {
|
||||
SHIM_SET_MEM_32(handle_ptr, ev->handle());
|
||||
}
|
||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
SHIM_CALL KeSetEvent_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||
uint32_t event_ref = SHIM_GET_ARG_32(0);
|
||||
uint32_t increment = SHIM_GET_ARG_32(1);
|
||||
uint32_t wait = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD("KeSetEvent(%.8X, %.8X, %.8X)", event_ref, increment, wait);
|
||||
|
||||
void* event_ptr = SHIM_MEM_ADDR(event_ref);
|
||||
|
||||
auto ev = XObject::GetNativeObject<XEvent>(kernel_state, event_ptr);
|
||||
if (!ev) {
|
||||
SHIM_SET_RETURN_32(0);
|
||||
return;
|
||||
}
|
||||
|
||||
auto result = ev->Set(increment, !!wait);
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtSetEvent_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||
uint32_t event_handle = SHIM_GET_ARG_32(0);
|
||||
uint32_t previous_state_ptr = SHIM_GET_ARG_32(1);
|
||||
@@ -509,25 +531,6 @@ SHIM_CALL NtSetEvent_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL KePulseEvent_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t event_ref = SHIM_GET_ARG_32(0);
|
||||
uint32_t increment = SHIM_GET_ARG_32(1);
|
||||
uint32_t wait = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD("KePulseEvent(%.8X, %.8X, %.8X)", event_ref, increment, wait);
|
||||
|
||||
int32_t result = 0;
|
||||
|
||||
void* event_ptr = SHIM_MEM_ADDR(event_ref);
|
||||
auto ev = XObject::GetNativeObject<XEvent>(kernel_state, event_ptr);
|
||||
if (ev) {
|
||||
result = ev->Pulse(increment, !!wait);
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtPulseEvent_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t event_handle = SHIM_GET_ARG_32(0);
|
||||
@@ -550,23 +553,6 @@ SHIM_CALL NtPulseEvent_shim(PPCContext* ppc_context,
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL KeResetEvent_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t event_ref = SHIM_GET_ARG_32(0);
|
||||
|
||||
XELOGD("KeResetEvent(%.8X)", event_ref);
|
||||
|
||||
void* event_ptr = SHIM_MEM_ADDR(event_ref);
|
||||
auto ev = XObject::GetNativeObject<XEvent>(kernel_state, event_ptr);
|
||||
if (!ev) {
|
||||
SHIM_SET_RETURN_32(0);
|
||||
return;
|
||||
}
|
||||
|
||||
auto result = ev->Reset();
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
dword_result_t NtClearEvent(dword_t handle) {
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
|
||||
@@ -582,6 +568,41 @@ dword_result_t NtClearEvent(dword_t handle) {
|
||||
DECLARE_XBOXKRNL_EXPORT(NtClearEvent,
|
||||
ExportTag::kImplemented | ExportTag::kThreading);
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff552150(v=vs.85).aspx
|
||||
void KeInitializeSemaphore(pointer_t<X_KSEMAPHORE> semaphore_ptr, dword_t count,
|
||||
dword_t limit) {
|
||||
semaphore_ptr->header.type = 5; // SemaphoreObject
|
||||
semaphore_ptr->header.signal_state = (uint32_t)count;
|
||||
semaphore_ptr->limit = (uint32_t)limit;
|
||||
|
||||
auto sem = XObject::GetNativeObject<XSemaphore>(kernel_state(), semaphore_ptr,
|
||||
5 /* SemaphoreObject */);
|
||||
if (!sem) {
|
||||
assert_always();
|
||||
return;
|
||||
}
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(KeInitializeSemaphore,
|
||||
ExportTag::kImplemented | ExportTag::kThreading);
|
||||
|
||||
dword_result_t KeReleaseSemaphore(pointer_t<X_KSEMAPHORE> semaphore_ptr,
|
||||
dword_t increment, dword_t adjustment,
|
||||
dword_t wait) {
|
||||
auto sem =
|
||||
XObject::GetNativeObject<XSemaphore>(kernel_state(), semaphore_ptr);
|
||||
if (!sem) {
|
||||
assert_always();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(benvanik): increment thread priority?
|
||||
// TODO(benvanik): wait?
|
||||
|
||||
return sem->ReleaseSemaphore(adjustment);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(KeReleaseSemaphore,
|
||||
ExportTag::kImplemented | ExportTag::kThreading);
|
||||
|
||||
SHIM_CALL NtCreateSemaphore_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(0);
|
||||
@@ -613,48 +634,6 @@ SHIM_CALL NtCreateSemaphore_shim(PPCContext* ppc_context,
|
||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
SHIM_CALL KeInitializeSemaphore_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t semaphore_ref = SHIM_GET_ARG_32(0);
|
||||
int32_t count = SHIM_GET_ARG_32(1);
|
||||
int32_t limit = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD("KeInitializeSemaphore(%.8X, %d, %d)", semaphore_ref, count, limit);
|
||||
|
||||
void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref);
|
||||
auto sem = XObject::GetNativeObject<XSemaphore>(kernel_state, semaphore_ptr,
|
||||
5 /* SemaphoreObject */);
|
||||
if (!sem) {
|
||||
return;
|
||||
}
|
||||
|
||||
sem->Initialize(count, limit);
|
||||
}
|
||||
|
||||
SHIM_CALL KeReleaseSemaphore_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t semaphore_ref = SHIM_GET_ARG_32(0);
|
||||
int32_t increment = SHIM_GET_ARG_32(1);
|
||||
int32_t adjustment = SHIM_GET_ARG_32(2);
|
||||
int32_t wait = SHIM_GET_ARG_32(3);
|
||||
|
||||
XELOGD("KeReleaseSemaphore(%.8X, %d, %d, %d)", semaphore_ref, increment,
|
||||
adjustment, wait);
|
||||
|
||||
void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref);
|
||||
auto sem = XObject::GetNativeObject<XSemaphore>(kernel_state, semaphore_ptr);
|
||||
if (!sem) {
|
||||
SHIM_SET_RETURN_32(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(benvanik): increment thread priority?
|
||||
// TODO(benvanik): wait?
|
||||
|
||||
int32_t result = sem->ReleaseSemaphore(adjustment);
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtReleaseSemaphore_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t sem_handle = SHIM_GET_ARG_32(0);
|
||||
@@ -680,35 +659,30 @@ SHIM_CALL NtReleaseSemaphore_shim(PPCContext* ppc_context,
|
||||
SHIM_SET_RETURN_32(result);
|
||||
}
|
||||
|
||||
SHIM_CALL NtCreateMutant_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
uint32_t handle_ptr = SHIM_GET_ARG_32(0);
|
||||
uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(1);
|
||||
uint32_t initial_owner = SHIM_GET_ARG_32(2);
|
||||
|
||||
XELOGD("NtCreateMutant(%.8X, %.8X, %.1X)", handle_ptr, obj_attributes_ptr,
|
||||
initial_owner);
|
||||
|
||||
dword_result_t NtCreateMutant(lpdword_t handle_out,
|
||||
pointer_t<X_OBJECT_ATTRIBUTES> obj_attributes,
|
||||
dword_t initial_owner) {
|
||||
// TODO(benvanik): check for name collision. May return existing object if
|
||||
// type matches.
|
||||
if (obj_attributes_ptr) {
|
||||
AssertNoNameCollision(kernel_state, obj_attributes_ptr);
|
||||
if (obj_attributes) {
|
||||
AssertNoNameCollision(kernel_state(), obj_attributes);
|
||||
}
|
||||
|
||||
XMutant* mutant = new XMutant(kernel_state);
|
||||
XMutant* mutant = new XMutant(kernel_state());
|
||||
mutant->Initialize(initial_owner ? true : false);
|
||||
|
||||
// obj_attributes may have a name inside of it, if != NULL.
|
||||
if (obj_attributes_ptr) {
|
||||
mutant->SetAttributes(obj_attributes_ptr);
|
||||
if (obj_attributes) {
|
||||
mutant->SetAttributes(obj_attributes);
|
||||
}
|
||||
|
||||
if (handle_ptr) {
|
||||
SHIM_SET_MEM_32(handle_ptr, mutant->handle());
|
||||
if (handle_out) {
|
||||
*handle_out = mutant->handle();
|
||||
}
|
||||
|
||||
SHIM_SET_RETURN_32(X_STATUS_SUCCESS);
|
||||
return X_STATUS_SUCCESS;
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT(NtCreateMutant, ExportTag::kImplemented);
|
||||
|
||||
SHIM_CALL NtReleaseMutant_shim(PPCContext* ppc_context,
|
||||
KernelState* kernel_state) {
|
||||
@@ -1331,6 +1305,7 @@ pointer_result_t InterlockedFlushSList(pointer_t<X_SLIST_HEADER> plist_ptr) {
|
||||
|
||||
uint32_t next = plist_ptr->next.next;
|
||||
plist_ptr->next.next = 0;
|
||||
plist_ptr->depth = 0;
|
||||
|
||||
return next;
|
||||
}
|
||||
@@ -1365,19 +1340,12 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports(
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeTlsSetValue, state);
|
||||
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateEvent, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeInitializeEvent, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeSetEvent, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtSetEvent, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KePulseEvent, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtPulseEvent, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeResetEvent, state);
|
||||
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateSemaphore, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeInitializeSemaphore, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeReleaseSemaphore, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtReleaseSemaphore, state);
|
||||
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateMutant, state);
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtReleaseMutant, state);
|
||||
|
||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateTimer, state);
|
||||
|
||||
Reference in New Issue
Block a user