Mutants.
This commit is contained in:
parent
40ca0bcb76
commit
5019f350f8
|
@ -7,6 +7,8 @@
|
||||||
'xfile.h',
|
'xfile.h',
|
||||||
'xmodule.cc',
|
'xmodule.cc',
|
||||||
'xmodule.h',
|
'xmodule.h',
|
||||||
|
'xmutant.cc',
|
||||||
|
'xmutant.h',
|
||||||
'xnotify_listener.cc',
|
'xnotify_listener.cc',
|
||||||
'xnotify_listener.h',
|
'xnotify_listener.h',
|
||||||
'xsemaphore.cc',
|
'xsemaphore.cc',
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* 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/objects/xmutant.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xe;
|
||||||
|
using namespace xe::kernel;
|
||||||
|
|
||||||
|
|
||||||
|
XMutant::XMutant(KernelState* kernel_state) :
|
||||||
|
XObject(kernel_state, kTypeMutant),
|
||||||
|
handle_(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
XMutant::~XMutant() {
|
||||||
|
if (handle_) {
|
||||||
|
CloseHandle(handle_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMutant::Initialize(bool initial_owner) {
|
||||||
|
XEASSERTNULL(handle_);
|
||||||
|
|
||||||
|
handle_ = CreateMutex(NULL, initial_owner ? TRUE : FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMutant::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) {
|
||||||
|
XEASSERTNULL(handle_);
|
||||||
|
|
||||||
|
// Haven't seen this yet, but it's possible.
|
||||||
|
XEASSERTALWAYS();
|
||||||
|
}
|
||||||
|
|
||||||
|
X_STATUS XMutant::ReleaseMutant(
|
||||||
|
uint32_t priority_increment, bool abandon, bool wait) {
|
||||||
|
// TODO(benvanik): abandoning.
|
||||||
|
XEASSERTFALSE(abandon);
|
||||||
|
BOOL result = ReleaseMutex(handle_);
|
||||||
|
if (result) {
|
||||||
|
return X_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
|
return X_STATUS_MUTANT_NOT_OWNED;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* 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_XBOXKRNL_XMUTANT_H_
|
||||||
|
#define XENIA_KERNEL_XBOXKRNL_XMUTANT_H_
|
||||||
|
|
||||||
|
#include <xenia/kernel/xobject.h>
|
||||||
|
|
||||||
|
#include <xenia/xbox.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace kernel {
|
||||||
|
|
||||||
|
|
||||||
|
class XMutant : public XObject {
|
||||||
|
public:
|
||||||
|
XMutant(KernelState* kernel_state);
|
||||||
|
virtual ~XMutant();
|
||||||
|
|
||||||
|
void Initialize(bool initial_owner);
|
||||||
|
void InitializeNative(void* native_ptr, DISPATCH_HEADER& header);
|
||||||
|
|
||||||
|
X_STATUS ReleaseMutant(uint32_t priority_increment, bool abandon, bool wait);
|
||||||
|
|
||||||
|
virtual void* GetWaitHandle() { return handle_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE handle_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace kernel
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XENIA_KERNEL_XBOXKRNL_XMUTANT_H_
|
|
@ -12,6 +12,7 @@
|
||||||
#include <xenia/kernel/kernel_state.h>
|
#include <xenia/kernel/kernel_state.h>
|
||||||
#include <xenia/kernel/xboxkrnl_private.h>
|
#include <xenia/kernel/xboxkrnl_private.h>
|
||||||
#include <xenia/kernel/objects/xevent.h>
|
#include <xenia/kernel/objects/xevent.h>
|
||||||
|
#include <xenia/kernel/objects/xmutant.h>
|
||||||
#include <xenia/kernel/objects/xsemaphore.h>
|
#include <xenia/kernel/objects/xsemaphore.h>
|
||||||
#include <xenia/kernel/objects/xthread.h>
|
#include <xenia/kernel/objects/xthread.h>
|
||||||
#include <xenia/kernel/util/shim_utils.h>
|
#include <xenia/kernel/util/shim_utils.h>
|
||||||
|
@ -885,6 +886,65 @@ SHIM_CALL NtReleaseSemaphore_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL NtCreateMutant_shim(
|
||||||
|
PPCContext* ppc_state, KernelState* 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);
|
||||||
|
|
||||||
|
XMutant* mutant = new XMutant(state);
|
||||||
|
mutant->Initialize(initial_owner ? true : false);
|
||||||
|
|
||||||
|
// obj_attributes may have a name inside of it, if != NULL.
|
||||||
|
if (obj_attributes_ptr) {
|
||||||
|
//mutant->SetName(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle_ptr) {
|
||||||
|
SHIM_SET_MEM_32(handle_ptr, mutant->handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(X_STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL NtReleaseMutant_shim(
|
||||||
|
PPCContext* ppc_state, KernelState* state) {
|
||||||
|
uint32_t mutant_handle = SHIM_GET_ARG_32(0);
|
||||||
|
int32_t unknown = SHIM_GET_ARG_32(1);
|
||||||
|
// This doesn't seem to be supported.
|
||||||
|
//int32_t previous_count_ptr = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
|
// Whatever arg 1 is all games seem to set it to 0, so whether it's
|
||||||
|
// abandon or wait we just say false. Which is good, cause they are
|
||||||
|
// both ignored.
|
||||||
|
XEASSERTZERO(unknown);
|
||||||
|
uint32_t priority_increment = 0;
|
||||||
|
bool abandon = false;
|
||||||
|
bool wait = false;
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"NtReleaseMutant(%.8X, %8.X)",
|
||||||
|
mutant_handle, unknown);
|
||||||
|
|
||||||
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
XMutant* mutant = NULL;
|
||||||
|
result = state->object_table()->GetObject(
|
||||||
|
mutant_handle, (XObject**)&mutant);
|
||||||
|
if (XSUCCEEDED(result)) {
|
||||||
|
result = mutant->ReleaseMutant(priority_increment, abandon, wait);
|
||||||
|
mutant->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
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, uint64_t* opt_timeout) {
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
|
@ -1145,6 +1205,9 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports(
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeReleaseSemaphore, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeReleaseSemaphore, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtReleaseSemaphore, 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", KeWaitForSingleObject, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForSingleObject, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtWaitForSingleObjectEx, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtWaitForSingleObjectEx, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForMultipleObjects, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForMultipleObjects, state);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <xenia/kernel/xboxkrnl_private.h>
|
#include <xenia/kernel/xboxkrnl_private.h>
|
||||||
#include <xenia/kernel/objects/xevent.h>
|
#include <xenia/kernel/objects/xevent.h>
|
||||||
|
#include <xenia/kernel/objects/xmutant.h>
|
||||||
#include <xenia/kernel/objects/xsemaphore.h>
|
#include <xenia/kernel/objects/xsemaphore.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -225,6 +226,13 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||||
object = ev;
|
object = ev;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 2: // MutantObjectt
|
||||||
|
{
|
||||||
|
XMutant* mutant = new XMutant(kernel_state);
|
||||||
|
mutant->InitializeNative(native_ptr, header);
|
||||||
|
object = mutant;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 5: // SemaphoreObject
|
case 5: // SemaphoreObject
|
||||||
{
|
{
|
||||||
XSemaphore* sem = new XSemaphore(kernel_state);
|
XSemaphore* sem = new XSemaphore(kernel_state);
|
||||||
|
@ -232,7 +240,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||||
object = sem;
|
object = sem;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // MutantObject
|
|
||||||
case 3: // ProcessObject
|
case 3: // ProcessObject
|
||||||
case 4: // QueueObject
|
case 4: // QueueObject
|
||||||
case 6: // ThreadObject
|
case 6: // ThreadObject
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
kTypeFile,
|
kTypeFile,
|
||||||
kTypeSemaphore,
|
kTypeSemaphore,
|
||||||
kTypeNotifyListener,
|
kTypeNotifyListener,
|
||||||
|
kTypeMutant,
|
||||||
};
|
};
|
||||||
|
|
||||||
XObject(KernelState* kernel_state, Type type);
|
XObject(KernelState* kernel_state, Type type);
|
||||||
|
|
|
@ -45,6 +45,7 @@ typedef uint32_t X_STATUS;
|
||||||
#define X_STATUS_BUFFER_TOO_SMALL ((uint32_t)0xC0000023L)
|
#define X_STATUS_BUFFER_TOO_SMALL ((uint32_t)0xC0000023L)
|
||||||
#define X_STATUS_OBJECT_TYPE_MISMATCH ((uint32_t)0xC0000024L)
|
#define X_STATUS_OBJECT_TYPE_MISMATCH ((uint32_t)0xC0000024L)
|
||||||
#define X_STATUS_INVALID_PAGE_PROTECTION ((uint32_t)0xC0000045L)
|
#define X_STATUS_INVALID_PAGE_PROTECTION ((uint32_t)0xC0000045L)
|
||||||
|
#define X_STATUS_MUTANT_NOT_OWNED ((uint32_t)0xC0000046L)
|
||||||
#define X_STATUS_MEMORY_NOT_ALLOCATED ((uint32_t)0xC00000A0L)
|
#define X_STATUS_MEMORY_NOT_ALLOCATED ((uint32_t)0xC00000A0L)
|
||||||
#define X_STATUS_INVALID_PARAMETER_1 ((uint32_t)0xC00000EFL)
|
#define X_STATUS_INVALID_PARAMETER_1 ((uint32_t)0xC00000EFL)
|
||||||
#define X_STATUS_INVALID_PARAMETER_2 ((uint32_t)0xC00000F0L)
|
#define X_STATUS_INVALID_PARAMETER_2 ((uint32_t)0xC00000F0L)
|
||||||
|
|
Loading…
Reference in New Issue