Basic implementation of events.
This commit is contained in:
parent
474ecea277
commit
8424a668bf
|
@ -32,6 +32,7 @@ KernelState::KernelState(Runtime* runtime) :
|
||||||
filesystem_ = runtime->filesystem();
|
filesystem_ = runtime->filesystem();
|
||||||
|
|
||||||
object_table_ = new ObjectTable();
|
object_table_ = new ObjectTable();
|
||||||
|
object_mutex_ = xe_mutex_alloc(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
KernelState::~KernelState() {
|
KernelState::~KernelState() {
|
||||||
|
@ -41,6 +42,7 @@ KernelState::~KernelState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete all objects.
|
// Delete all objects.
|
||||||
|
xe_mutex_free(object_mutex_);
|
||||||
delete object_table_;
|
delete object_table_;
|
||||||
|
|
||||||
filesystem_.reset();
|
filesystem_.reset();
|
||||||
|
|
|
@ -45,15 +45,13 @@ public:
|
||||||
void SetExecutableModule(XModule* module);
|
void SetExecutableModule(XModule* module);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
X_HANDLE InsertObject(XObject* obj);
|
|
||||||
void RemoveObject(XObject* obj);
|
|
||||||
|
|
||||||
Runtime* runtime_;
|
Runtime* runtime_;
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
shared_ptr<cpu::Processor> processor_;
|
shared_ptr<cpu::Processor> processor_;
|
||||||
shared_ptr<fs::FileSystem> filesystem_;
|
shared_ptr<fs::FileSystem> filesystem_;
|
||||||
|
|
||||||
ObjectTable* object_table_;
|
ObjectTable* object_table_;
|
||||||
|
xe_mutex_t* object_mutex_;
|
||||||
|
|
||||||
XModule* executable_module_;
|
XModule* executable_module_;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||||
{
|
{
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'xevent.cc',
|
||||||
|
'xevent.h',
|
||||||
'xmodule.cc',
|
'xmodule.cc',
|
||||||
'xmodule.h',
|
'xmodule.h',
|
||||||
'xthread.cc',
|
'xthread.cc',
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/objects/xevent.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::kernel;
|
||||||
|
using namespace xe::kernel::xboxkrnl;
|
||||||
|
|
||||||
|
|
||||||
|
XEvent::XEvent(KernelState* kernel_state) :
|
||||||
|
XObject(kernel_state, kTypeEvent),
|
||||||
|
handle_(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
XEvent::~XEvent() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void XEvent::Initialize(void* native_ptr, DISPATCH_HEADER& header) {
|
||||||
|
XEASSERTNULL(handle_);
|
||||||
|
|
||||||
|
bool manual_reset;
|
||||||
|
switch (header.type_flags >> 24) {
|
||||||
|
case 0x00: // EventNotificationObject (manual reset)
|
||||||
|
manual_reset = true;
|
||||||
|
break;
|
||||||
|
case 0x01: // EventSynchronizationObject (auto reset)
|
||||||
|
manual_reset = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
XEASSERTALWAYS();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initial_state = header.signal_state ? true : false;
|
||||||
|
|
||||||
|
handle_ = CreateEvent(NULL, manual_reset, initial_state, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t XEvent::Set(uint32_t priority_increment, bool wait) {
|
||||||
|
return SetEvent(handle_) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t XEvent::Reset() {
|
||||||
|
return ResetEvent(handle_) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XEvent::Clear() {
|
||||||
|
ResetEvent(handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
X_STATUS XEvent::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
|
DWORD timeout_ms;
|
||||||
|
if (opt_timeout) {
|
||||||
|
int64_t timeout_ticks = (int64_t)(*opt_timeout);
|
||||||
|
if (timeout_ticks > 0) {
|
||||||
|
// Absolute time, based on January 1, 1601.
|
||||||
|
// TODO(benvanik): convert time to relative time.
|
||||||
|
XEASSERTALWAYS();
|
||||||
|
timeout_ms = 0;
|
||||||
|
} else if (timeout_ticks < 0) {
|
||||||
|
// Relative time.
|
||||||
|
timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS
|
||||||
|
} else {
|
||||||
|
timeout_ms = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
timeout_ms = INFINITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD result = WaitForSingleObjectEx(handle_, timeout_ms, alertable);
|
||||||
|
switch (result) {
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
case WAIT_IO_COMPLETION:
|
||||||
|
// Or X_STATUS_ALERTED?
|
||||||
|
return X_STATUS_USER_APC;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return X_STATUS_TIMEOUT;
|
||||||
|
default:
|
||||||
|
case WAIT_FAILED:
|
||||||
|
case WAIT_ABANDONED:
|
||||||
|
return X_STATUS_ABANDONED_WAIT_0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_XEVENT_H_
|
||||||
|
#define XENIA_KERNEL_MODULES_XBOXKRNL_XEVENT_H_
|
||||||
|
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
|
||||||
|
|
||||||
|
#include <xenia/kernel/xbox.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace kernel {
|
||||||
|
namespace xboxkrnl {
|
||||||
|
|
||||||
|
|
||||||
|
class XEvent : public XObject {
|
||||||
|
public:
|
||||||
|
XEvent(KernelState* kernel_state);
|
||||||
|
virtual ~XEvent();
|
||||||
|
|
||||||
|
void Initialize(void* native_ptr, DISPATCH_HEADER& header);
|
||||||
|
|
||||||
|
int32_t Set(uint32_t priority_increment, bool wait);
|
||||||
|
int32_t Reset();
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE handle_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xboxkrnl
|
||||||
|
} // namespace kernel
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_XEVENT_H_
|
|
@ -12,6 +12,7 @@
|
||||||
#include <xenia/kernel/shim_utils.h>
|
#include <xenia/kernel/shim_utils.h>
|
||||||
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
|
||||||
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_private.h>
|
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_private.h>
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/objects/xevent.h>
|
||||||
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,8 +308,48 @@ SHIM_CALL KeTlsSetValue_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t xeKeResetEvent(void* event_ptr) {
|
int32_t xeKeSetEvent(void* event_ptr, uint32_t increment, uint32_t wait) {
|
||||||
|
KernelState* state = shared_kernel_state_;
|
||||||
|
XEASSERTNOTNULL(state);
|
||||||
|
|
||||||
|
XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr);
|
||||||
|
XEASSERTNOTNULL(ev);
|
||||||
|
if (!ev) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ev->Set(increment, !!wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL KeSetEvent_shim(
|
||||||
|
xe_ppc_state_t* ppc_state, KernelState* 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(%.4X, %.4X, %.4X)",
|
||||||
|
event_ref, increment, wait);
|
||||||
|
|
||||||
|
void* event_ptr = SHIM_MEM_ADDR(event_ref);
|
||||||
|
int32_t result = xeKeSetEvent(event_ptr, increment, wait);
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t xeKeResetEvent(void* event_ptr) {
|
||||||
|
KernelState* state = shared_kernel_state_;
|
||||||
|
XEASSERTNOTNULL(state);
|
||||||
|
|
||||||
|
XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr);
|
||||||
|
XEASSERTNOTNULL(ev);
|
||||||
|
if (!ev) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ev->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -327,33 +368,19 @@ SHIM_CALL KeResetEvent_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t xeKeSetEvent(void* event_ptr, uint32_t increment, uint32_t wait) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SHIM_CALL KeSetEvent_shim(
|
|
||||||
xe_ppc_state_t* ppc_state, KernelState* 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(%.4X, %.4X, %.4X)",
|
|
||||||
event_ref, increment, wait);
|
|
||||||
|
|
||||||
void* event_ptr = SHIM_MEM_ADDR(event_ref);
|
|
||||||
int32_t result = xeKeSetEvent(
|
|
||||||
event_ptr, increment, wait);
|
|
||||||
|
|
||||||
SHIM_SET_RETURN(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
X_STATUS xeKeWaitForSingleObject(
|
X_STATUS xeKeWaitForSingleObject(
|
||||||
void* object_ptr, uint32_t wait_reason, uint32_t processor_mode,
|
void* object_ptr, uint32_t wait_reason, uint32_t processor_mode,
|
||||||
uint32_t alertable, uint32_t* opt_timeout) {
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
return X_STATUS_NOT_IMPLEMENTED;
|
KernelState* state = shared_kernel_state_;
|
||||||
|
XEASSERTNOTNULL(state);
|
||||||
|
|
||||||
|
XObject* object = XObject::GetObject(state, object_ptr);
|
||||||
|
if (!object) {
|
||||||
|
// The only kind-of failure code.
|
||||||
|
return X_STATUS_ABANDONED_WAIT_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return object->Wait(wait_reason, processor_mode, alertable, opt_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -370,7 +397,7 @@ SHIM_CALL KeWaitForSingleObject_shim(
|
||||||
object, wait_reason, processor_mode, alertable, timeout_ptr);
|
object, wait_reason, processor_mode, alertable, timeout_ptr);
|
||||||
|
|
||||||
void* object_ptr = SHIM_MEM_ADDR(object);
|
void* object_ptr = SHIM_MEM_ADDR(object);
|
||||||
uint32_t timeout = timeout_ptr ? SHIM_MEM_32(timeout_ptr) : 0;
|
uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0;
|
||||||
X_STATUS result = xeKeWaitForSingleObject(
|
X_STATUS result = xeKeWaitForSingleObject(
|
||||||
object_ptr, wait_reason, processor_mode, alertable,
|
object_ptr, wait_reason, processor_mode, alertable,
|
||||||
timeout_ptr ? &timeout : NULL);
|
timeout_ptr ? &timeout : NULL);
|
||||||
|
@ -395,8 +422,8 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports(
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeTlsGetValue, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeTlsGetValue, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeTlsSetValue, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeTlsSetValue, state);
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeResetEvent, state);
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeSetEvent, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeSetEvent, state);
|
||||||
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeResetEvent, state);
|
||||||
|
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForSingleObject, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForSingleObject, state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,8 @@ int KeTlsFree(uint32_t tls_index);
|
||||||
uint32_t xeKeTlsGetValue(uint32_t tls_index);
|
uint32_t xeKeTlsGetValue(uint32_t tls_index);
|
||||||
int xeKeTlsSetValue(uint32_t tls_index, uint32_t tls_value);
|
int xeKeTlsSetValue(uint32_t tls_index, uint32_t tls_value);
|
||||||
|
|
||||||
int32_t xeKeResetEvent(void* event_ptr);
|
|
||||||
int32_t xeKeSetEvent(void* event_ptr, uint32_t increment, uint32_t wait);
|
int32_t xeKeSetEvent(void* event_ptr, uint32_t increment, uint32_t wait);
|
||||||
|
int32_t xeKeResetEvent(void* event_ptr);
|
||||||
|
|
||||||
X_STATUS xeKeWaitForSingleObject(
|
X_STATUS xeKeWaitForSingleObject(
|
||||||
void* object_ptr, uint32_t wait_reason, uint32_t processor_mode,
|
void* object_ptr, uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
|
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
|
||||||
|
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_private.h>
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/objects/xevent.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
using namespace xe::kernel;
|
using namespace xe::kernel;
|
||||||
|
@ -69,3 +72,89 @@ void XObject::Release() {
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XObject::LockType() {
|
||||||
|
xe_mutex_lock(shared_kernel_state_->object_mutex_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XObject::UnlockType() {
|
||||||
|
xe_mutex_unlock(shared_kernel_state_->object_mutex_);
|
||||||
|
}
|
||||||
|
|
||||||
|
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr) {
|
||||||
|
// Unfortunately the XDK seems to inline some KeInitialize calls, meaning
|
||||||
|
// we never see it and just randomly start getting passed events/timers/etc.
|
||||||
|
// Luckily it seems like all other calls (Set/Reset/Wait/etc) are used and
|
||||||
|
// we don't have to worry about PPC code poking the struct. Because of that,
|
||||||
|
// we init on first use, store our pointer in the struct, and dereference it
|
||||||
|
// each time.
|
||||||
|
// We identify this by checking the low bit of wait_list_blink - if it's 1,
|
||||||
|
// we have already put our pointer in there.
|
||||||
|
|
||||||
|
XObject::LockType();
|
||||||
|
|
||||||
|
DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)native_ptr;
|
||||||
|
DISPATCH_HEADER header;
|
||||||
|
header.type_flags = XESWAP32(header_be->type_flags);
|
||||||
|
header.signal_state = XESWAP32(header_be->signal_state);
|
||||||
|
header.wait_list_flink = XESWAP32(header_be->wait_list_flink);
|
||||||
|
header.wait_list_blink = XESWAP32(header_be->wait_list_blink);
|
||||||
|
|
||||||
|
if (header.wait_list_blink & 0x1) {
|
||||||
|
// Already initialized.
|
||||||
|
uint64_t object_ptr =
|
||||||
|
((uint64_t)header.wait_list_flink << 32) |
|
||||||
|
((header.wait_list_blink) & ~0x1);
|
||||||
|
XObject* object = reinterpret_cast<XObject*>(object_ptr);
|
||||||
|
// TODO(benvanik): assert nothing has been changed in the struct.
|
||||||
|
XObject::UnlockType();
|
||||||
|
return object;
|
||||||
|
} else {
|
||||||
|
// First use, create new.
|
||||||
|
// http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html
|
||||||
|
XObject* object = NULL;
|
||||||
|
switch (header.type_flags & 0xFF) {
|
||||||
|
case 0: // EventNotificationObject
|
||||||
|
case 1: // EventSynchronizationObject
|
||||||
|
{
|
||||||
|
XEvent* ev = new XEvent(kernel_state);
|
||||||
|
ev->Initialize(native_ptr, header);
|
||||||
|
object = ev;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // MutantObject
|
||||||
|
case 3: // ProcessObject
|
||||||
|
case 4: // QueueObject
|
||||||
|
case 5: // SemaphoreObject
|
||||||
|
case 6: // ThreadObject
|
||||||
|
case 7: // GateObject
|
||||||
|
case 8: // TimerNotificationObject
|
||||||
|
case 9: // TimerSynchronizationObject
|
||||||
|
case 18: // ApcObject
|
||||||
|
case 19: // DpcObject
|
||||||
|
case 20: // DeviceQueueObject
|
||||||
|
case 21: // EventPairObject
|
||||||
|
case 22: // InterruptObject
|
||||||
|
case 23: // ProfileObject
|
||||||
|
case 24: // ThreadedDpcObject
|
||||||
|
default:
|
||||||
|
XEASSERTALWAYS();
|
||||||
|
XObject::UnlockType();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stash pointer in struct.
|
||||||
|
uint64_t object_ptr = reinterpret_cast<uint64_t>(object);
|
||||||
|
object_ptr |= 0x1;
|
||||||
|
header_be->wait_list_flink = XESWAP32((uint32_t)(object_ptr >> 32));
|
||||||
|
header_be->wait_list_blink = XESWAP32((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||||
|
|
||||||
|
XObject::UnlockType();
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,11 +27,21 @@ namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
|
|
||||||
|
// http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html
|
||||||
|
typedef struct {
|
||||||
|
uint32_t type_flags;
|
||||||
|
uint32_t signal_state;
|
||||||
|
uint32_t wait_list_flink;
|
||||||
|
uint32_t wait_list_blink;
|
||||||
|
} DISPATCH_HEADER;
|
||||||
|
|
||||||
|
|
||||||
class XObject {
|
class XObject {
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
kTypeModule = 0x00000001,
|
kTypeModule = 0x00000001,
|
||||||
kTypeThread = 0x00000002,
|
kTypeThread = 0x00000002,
|
||||||
|
kTypeEvent = 0x00000003,
|
||||||
};
|
};
|
||||||
|
|
||||||
XObject(KernelState* kernel_state, Type type);
|
XObject(KernelState* kernel_state, Type type);
|
||||||
|
@ -47,6 +57,16 @@ public:
|
||||||
void Retain();
|
void Retain();
|
||||||
void Release();
|
void Release();
|
||||||
|
|
||||||
|
// Reference()
|
||||||
|
// Dereference()
|
||||||
|
|
||||||
|
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout);
|
||||||
|
|
||||||
|
static void LockType();
|
||||||
|
static void UnlockType();
|
||||||
|
static XObject* GetObject(KernelState* kernel_state, void* native_ptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Runtime* runtime();
|
Runtime* runtime();
|
||||||
xe_memory_ref memory(); // unretained
|
xe_memory_ref memory(); // unretained
|
||||||
|
|
|
@ -29,6 +29,10 @@ typedef uint32_t X_STATUS;
|
||||||
#define XFAILED(s) (s & X_STATUS_UNSUCCESSFUL)
|
#define XFAILED(s) (s & X_STATUS_UNSUCCESSFUL)
|
||||||
#define XSUCCEEDED(s) !XFAILED(s)
|
#define XSUCCEEDED(s) !XFAILED(s)
|
||||||
#define X_STATUS_SUCCESS ((uint32_t)0x00000000L)
|
#define X_STATUS_SUCCESS ((uint32_t)0x00000000L)
|
||||||
|
#define X_STATUS_ABANDONED_WAIT_0 ((uint32_t)0x00000080L)
|
||||||
|
#define X_STATUS_USER_APC ((uint32_t)0x000000C0L)
|
||||||
|
#define X_STATUS_ALERTED ((uint32_t)0x00000101L)
|
||||||
|
#define X_STATUS_TIMEOUT ((uint32_t)0x00000102L)
|
||||||
#define X_STATUS_UNSUCCESSFUL ((uint32_t)0xC0000001L)
|
#define X_STATUS_UNSUCCESSFUL ((uint32_t)0xC0000001L)
|
||||||
#define X_STATUS_NOT_IMPLEMENTED ((uint32_t)0xC0000002L)
|
#define X_STATUS_NOT_IMPLEMENTED ((uint32_t)0xC0000002L)
|
||||||
#define X_STATUS_ACCESS_VIOLATION ((uint32_t)0xC0000005L)
|
#define X_STATUS_ACCESS_VIOLATION ((uint32_t)0xC0000005L)
|
||||||
|
@ -46,7 +50,6 @@ typedef uint32_t X_STATUS;
|
||||||
#define X_STATUS_INVALID_PARAMETER_2 ((uint32_t)0xC00000F0L)
|
#define X_STATUS_INVALID_PARAMETER_2 ((uint32_t)0xC00000F0L)
|
||||||
#define X_STATUS_INVALID_PARAMETER_3 ((uint32_t)0xC00000F1L)
|
#define X_STATUS_INVALID_PARAMETER_3 ((uint32_t)0xC00000F1L)
|
||||||
|
|
||||||
|
|
||||||
// MEM_*, used by NtAllocateVirtualMemory
|
// MEM_*, used by NtAllocateVirtualMemory
|
||||||
#define X_MEM_COMMIT 0x00001000
|
#define X_MEM_COMMIT 0x00001000
|
||||||
#define X_MEM_RESERVE 0x00002000
|
#define X_MEM_RESERVE 0x00002000
|
||||||
|
|
Loading…
Reference in New Issue