NtDuplicateObject.
This commit is contained in:
parent
e8ca05ca0a
commit
0f95864b8d
|
@ -120,6 +120,11 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) {
|
||||||
X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) {
|
X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) {
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
handle = TranslateHandle(handle);
|
||||||
|
if (!handle) {
|
||||||
|
return X_STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
xe_mutex_lock(table_mutex_);
|
xe_mutex_lock(table_mutex_);
|
||||||
|
|
||||||
// Lower 2 bits are ignored.
|
// Lower 2 bits are ignored.
|
||||||
|
@ -155,12 +160,9 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) {
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (handle == 0xFFFFFFFF) {
|
handle = TranslateHandle(handle);
|
||||||
// CurrentProcess
|
if (!handle) {
|
||||||
XEASSERTALWAYS();
|
return X_STATUS_INVALID_HANDLE;
|
||||||
} else if (handle == 0xFFFFFFFE) {
|
|
||||||
// CurrentThread
|
|
||||||
handle = XThread::GetCurrentThreadHandle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xe_mutex_lock(table_mutex_);
|
xe_mutex_lock(table_mutex_);
|
||||||
|
@ -191,3 +193,16 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) {
|
||||||
*out_object = object;
|
*out_object = object;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X_HANDLE ObjectTable::TranslateHandle(X_HANDLE handle) {
|
||||||
|
if (handle == 0xFFFFFFFF) {
|
||||||
|
// CurrentProcess
|
||||||
|
XEASSERTALWAYS();
|
||||||
|
return 0;
|
||||||
|
} else if (handle == 0xFFFFFFFE) {
|
||||||
|
// CurrentThread
|
||||||
|
return XThread::GetCurrentThreadHandle();
|
||||||
|
} else {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
X_STATUS GetObject(X_HANDLE handle, XObject** out_object);
|
X_STATUS GetObject(X_HANDLE handle, XObject** out_object);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
X_HANDLE TranslateHandle(X_HANDLE handle);
|
||||||
X_STATUS FindFreeSlot(uint32_t* out_slot);
|
X_STATUS FindFreeSlot(uint32_t* out_slot);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#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/xobject.h>
|
|
||||||
#include <xenia/kernel/util/shim_utils.h>
|
#include <xenia/kernel/util/shim_utils.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,27 +23,10 @@ namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
|
|
||||||
SHIM_CALL NtClose_shim(
|
|
||||||
PPCContext* ppc_state, KernelState* state) {
|
|
||||||
uint32_t handle = SHIM_GET_ARG_32(0);
|
|
||||||
|
|
||||||
XELOGD(
|
|
||||||
"NtClose(%.8X)",
|
|
||||||
handle);
|
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
|
||||||
|
|
||||||
result = state->object_table()->RemoveHandle(handle);
|
|
||||||
|
|
||||||
SHIM_SET_RETURN(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
|
||||||
void xe::kernel::xboxkrnl::RegisterNtExports(
|
void xe::kernel::xboxkrnl::RegisterNtExports(
|
||||||
ExportResolver* export_resolver, KernelState* state) {
|
ExportResolver* export_resolver, KernelState* state) {
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", NtClose, state);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,62 @@ SHIM_CALL ObDereferenceObject_shim(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL NtDuplicateObject_shim(
|
||||||
|
PPCContext* ppc_state, KernelState* state) {
|
||||||
|
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||||
|
uint32_t new_handle_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
uint32_t options = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"NtDuplicateObject(%.8X, %.8X, %.8X)",
|
||||||
|
handle, new_handle_ptr, options);
|
||||||
|
|
||||||
|
// NOTE: new_handle_ptr can be zero to just close a handle.
|
||||||
|
// NOTE: this function seems to be used to get the current thread handle
|
||||||
|
// (passed handle=-2).
|
||||||
|
// Because this function is not like the NT version (with cross process
|
||||||
|
// mumble), my guess is that it's just use for getting real handles.
|
||||||
|
// So we just fake it and properly reference count but not actually make
|
||||||
|
// different handles.
|
||||||
|
|
||||||
|
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
|
XObject* obj = 0;
|
||||||
|
result = state->object_table()->GetObject(handle, &obj);
|
||||||
|
if (XSUCCEEDED(result)) {
|
||||||
|
obj->RetainHandle();
|
||||||
|
uint32_t new_handle = obj->handle();
|
||||||
|
if (new_handle_ptr) {
|
||||||
|
SHIM_SET_MEM_32(new_handle_ptr, new_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options == 1 /* DUPLICATE_CLOSE_SOURCE */) {
|
||||||
|
// Always close the source object.
|
||||||
|
state->object_table()->RemoveHandle(handle);
|
||||||
|
}
|
||||||
|
obj->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHIM_CALL NtClose_shim(
|
||||||
|
PPCContext* ppc_state, KernelState* state) {
|
||||||
|
uint32_t handle = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
|
XELOGD(
|
||||||
|
"NtClose(%.8X)",
|
||||||
|
handle);
|
||||||
|
|
||||||
|
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
|
result = state->object_table()->RemoveHandle(handle);
|
||||||
|
|
||||||
|
SHIM_SET_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
|
@ -96,4 +152,6 @@ void xe::kernel::xboxkrnl::RegisterObExports(
|
||||||
ExportResolver* export_resolver, KernelState* state) {
|
ExportResolver* export_resolver, KernelState* state) {
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state);
|
||||||
SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state);
|
SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state);
|
||||||
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtDuplicateObject, state);
|
||||||
|
SHIM_SET_MAPPING("xboxkrnl.exe", NtClose, state);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue