Implement KeEvent Api's for non-windows event structures.
This commit is contained in:
parent
7067db44dc
commit
18a64386cd
|
@ -60,6 +60,8 @@ namespace NtDll
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
// Copied over from Dxbx.
|
// Copied over from Dxbx.
|
||||||
// TODO : Move towards thread-simulation based Dpc emulation
|
// TODO : Move towards thread-simulation based Dpc emulation
|
||||||
|
@ -73,6 +75,8 @@ typedef struct _DpcData {
|
||||||
|
|
||||||
DpcData g_DpcData = { 0 }; // Note : g_DpcData is initialized in InitDpcAndTimerThread()
|
DpcData g_DpcData = { 0 }; // Note : g_DpcData is initialized in InitDpcAndTimerThread()
|
||||||
|
|
||||||
|
std::map<xboxkrnl::PRKEVENT, HANDLE> g_KeEventHandles;
|
||||||
|
|
||||||
xboxkrnl::ULONGLONG LARGE_INTEGER2ULONGLONG(xboxkrnl::LARGE_INTEGER value)
|
xboxkrnl::ULONGLONG LARGE_INTEGER2ULONGLONG(xboxkrnl::LARGE_INTEGER value)
|
||||||
{
|
{
|
||||||
// Weird construction because there doesn't seem to exist an implicit
|
// Weird construction because there doesn't seem to exist an implicit
|
||||||
|
@ -666,10 +670,19 @@ XBSYSAPI EXPORTNUM(108) xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeEvent
|
||||||
LOG_FUNC_ARG(SignalState)
|
LOG_FUNC_ARG(SignalState)
|
||||||
LOG_FUNC_END;
|
LOG_FUNC_END;
|
||||||
|
|
||||||
|
// Setup the Xbox event struct
|
||||||
Event->Header.Type = Type;
|
Event->Header.Type = Type;
|
||||||
Event->Header.Size = sizeof(KEVENT) / sizeof(LONG);
|
Event->Header.Size = sizeof(KEVENT) / sizeof(LONG);
|
||||||
Event->Header.SignalState = SignalState;
|
Event->Header.SignalState = SignalState;
|
||||||
InitializeListHead(&(Event->Header.WaitListHead));
|
InitializeListHead(&(Event->Header.WaitListHead));
|
||||||
|
|
||||||
|
|
||||||
|
// Create a Windows event, to be used in KeWaitForObject
|
||||||
|
// TODO: This doesn't check for events that are already initialized
|
||||||
|
// This shouldn't happen, except on shoddily coded titles so we
|
||||||
|
// ignore it for now
|
||||||
|
HANDLE hostEvent = CreateEvent(NULL, FALSE, SignalState, NULL);
|
||||||
|
g_KeEventHandles[Event] = hostEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
@ -997,6 +1010,14 @@ XBSYSAPI EXPORTNUM(123) xboxkrnl::LONG NTAPI xboxkrnl::KePulseEvent
|
||||||
LOG_FUNC_ARG(Wait)
|
LOG_FUNC_ARG(Wait)
|
||||||
LOG_FUNC_END;
|
LOG_FUNC_END;
|
||||||
|
|
||||||
|
// Fetch the host event and signal it, if present
|
||||||
|
if (g_KeEventHandles.find(Event) == g_KeEventHandles.end()) {
|
||||||
|
EmuWarning("KePulseEvent called on a non-existant event!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PulseEvent(g_KeEventHandles[Event]);
|
||||||
|
}
|
||||||
|
|
||||||
LOG_UNIMPLEMENTED();
|
LOG_UNIMPLEMENTED();
|
||||||
|
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
|
@ -1295,6 +1316,15 @@ XBSYSAPI EXPORTNUM(138) xboxkrnl::LONG NTAPI xboxkrnl::KeResetEvent
|
||||||
LONG ret = Event->Header.SignalState;
|
LONG ret = Event->Header.SignalState;
|
||||||
Event->Header.SignalState = 0;
|
Event->Header.SignalState = 0;
|
||||||
|
|
||||||
|
// Fetch the host event and signal it, if present
|
||||||
|
if (g_KeEventHandles.find(Event) == g_KeEventHandles.end()) {
|
||||||
|
EmuWarning("KeResetEvent called on a non-existant event!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ResetEvent(g_KeEventHandles[Event]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1422,6 +1452,15 @@ XBSYSAPI EXPORTNUM(145) xboxkrnl::LONG NTAPI xboxkrnl::KeSetEvent
|
||||||
LONG ret = Event->Header.SignalState;
|
LONG ret = Event->Header.SignalState;
|
||||||
Event->Header.SignalState = TRUE;
|
Event->Header.SignalState = TRUE;
|
||||||
|
|
||||||
|
// Fetch the host event and signal it, if present
|
||||||
|
if (g_KeEventHandles.find(Event) == g_KeEventHandles.end()) {
|
||||||
|
EmuWarning("KeSetEvent called on a non-existant event. Creating it!");
|
||||||
|
// TODO: Find out why some XDKs do not call KeInitializeEvent first
|
||||||
|
KeInitializeEvent(Event, NotificationEvent, TRUE);
|
||||||
|
} else {
|
||||||
|
SetEvent(g_KeEventHandles[Event]);
|
||||||
|
}
|
||||||
|
|
||||||
RETURN(ret);
|
RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1683,24 +1722,41 @@ XBSYSAPI EXPORTNUM(158) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeWaitForMultipleObje
|
||||||
|
|
||||||
NTSTATUS ret = STATUS_SUCCESS;
|
NTSTATUS ret = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
// Take the input and build two arrays: One of handles created by our kernel and one for not
|
||||||
|
// Handles created by our kernel need to be forwarded to WaitForMultipleObjects while handles
|
||||||
|
// created by Windows need to be forwarded to NtDll::KeWaitForMultipleObjects
|
||||||
|
std::vector<HANDLE> nativeObjects;
|
||||||
|
std::vector<HANDLE> ntdllObjects;
|
||||||
|
|
||||||
for (uint i = 0; i < Count; i++) {
|
for (uint i = 0; i < Count; i++) {
|
||||||
DbgPrintf("Object: 0x%08X\n", Object[i]);
|
DbgPrintf("Object: 0x%08X\n", Object[i]);
|
||||||
if (IsEmuHandle(Object[i])) {
|
if (g_KeEventHandles.find((PKEVENT)Object[i]) == g_KeEventHandles.end()) {
|
||||||
ret = WAIT_FAILED;
|
ntdllObjects.push_back(Object[i]);
|
||||||
EmuWarning("WaitFor EmuHandle not supported!");
|
} else {
|
||||||
break;
|
nativeObjects.push_back(g_KeEventHandles[(PRKEVENT)Object[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == STATUS_SUCCESS)
|
if (ntdllObjects.size() > 0) {
|
||||||
{
|
|
||||||
// TODO : What should we do with the (currently ignored)
|
// TODO : What should we do with the (currently ignored)
|
||||||
// WaitReason, WaitMode, WaitBlockArray?
|
// WaitReason, WaitMode, WaitBlockArray?
|
||||||
|
|
||||||
// Unused arguments : WaitReason, WaitMode, WaitBlockArray
|
// Unused arguments : WaitReason, WaitMode, WaitBlockArray
|
||||||
ret = NtDll::NtWaitForMultipleObjects(
|
ret = NtDll::NtWaitForMultipleObjects(
|
||||||
Count,
|
ntdllObjects.size(),
|
||||||
Object,
|
&ntdllObjects[0],
|
||||||
|
(NtDll::OBJECT_WAIT_TYPE)WaitType,
|
||||||
|
Alertable,
|
||||||
|
(NtDll::PLARGE_INTEGER)Timeout);
|
||||||
|
|
||||||
|
if (FAILED(ret))
|
||||||
|
EmuWarning("KeWaitForMultipleObjects failed! (%s)", NtStatusToString(ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nativeObjects.size() > 0) {
|
||||||
|
ret = NtDll::NtWaitForMultipleObjects(
|
||||||
|
nativeObjects.size(),
|
||||||
|
&nativeObjects[0],
|
||||||
(NtDll::OBJECT_WAIT_TYPE)WaitType,
|
(NtDll::OBJECT_WAIT_TYPE)WaitType,
|
||||||
Alertable,
|
Alertable,
|
||||||
(NtDll::PLARGE_INTEGER)Timeout);
|
(NtDll::PLARGE_INTEGER)Timeout);
|
||||||
|
|
Loading…
Reference in New Issue