This commit is contained in:
Ben Vanik 2014-01-07 18:32:55 -08:00
parent 40ca0bcb76
commit 5019f350f8
7 changed files with 169 additions and 1 deletions

View File

@ -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',

View File

@ -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;
}
}

View File

@ -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_

View File

@ -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);

View File

@ -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

View File

@ -37,6 +37,7 @@ public:
kTypeFile, kTypeFile,
kTypeSemaphore, kTypeSemaphore,
kTypeNotifyListener, kTypeNotifyListener,
kTypeMutant,
}; };
XObject(KernelState* kernel_state, Type type); XObject(KernelState* kernel_state, Type type);

View File

@ -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)