Merge branch 'master' of https://github.com/benvanik/xenia
This commit is contained in:
commit
d5bd8b9d5b
|
@ -13,24 +13,30 @@
|
||||||
#include <xenia/kernel/modules/xboxkrnl/objects/xevent.h>
|
#include <xenia/kernel/modules/xboxkrnl/objects/xevent.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
using namespace xe::kernel;
|
using namespace xe::kernel;
|
||||||
using namespace xe::kernel::xboxkrnl;
|
using namespace xe::kernel::xboxkrnl;
|
||||||
|
|
||||||
|
|
||||||
XAsyncRequest::XAsyncRequest(
|
XAsyncRequest::XAsyncRequest(
|
||||||
XObject* object,
|
KernelState* kernel_state, XObject* object,
|
||||||
CompletionCallback callback, void* callback_context) :
|
CompletionCallback callback, void* callback_context) :
|
||||||
object_(object),
|
kernel_state_(kernel_state), object_(object),
|
||||||
callback_(callback), callback_context_(callback_context),
|
callback_(callback), callback_context_(callback_context),
|
||||||
wait_event_(0),
|
|
||||||
apc_routine_(0), apc_context_(0) {
|
apc_routine_(0), apc_context_(0) {
|
||||||
object_->Retain();
|
object_->Retain();
|
||||||
}
|
}
|
||||||
|
|
||||||
XAsyncRequest::~XAsyncRequest() {
|
XAsyncRequest::~XAsyncRequest() {
|
||||||
if (wait_event_) {
|
for (vector<XEvent*>::iterator it = wait_events_.begin();
|
||||||
wait_event_->Release();
|
it != wait_events_.end(); ++it) {
|
||||||
|
(*it)->Release();
|
||||||
}
|
}
|
||||||
object_->Release();
|
object_->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XAsyncRequest::AddWaitEvent(XEvent* ev) {
|
||||||
|
ev->Retain();
|
||||||
|
wait_events_.push_back(ev);
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
|
class KernelState;
|
||||||
class XEvent;
|
class XEvent;
|
||||||
class XObject;
|
class XObject;
|
||||||
|
|
||||||
|
@ -29,24 +30,24 @@ public:
|
||||||
typedef void (*CompletionCallback)(XAsyncRequest* request, void* context);
|
typedef void (*CompletionCallback)(XAsyncRequest* request, void* context);
|
||||||
|
|
||||||
XAsyncRequest(
|
XAsyncRequest(
|
||||||
XObject* object,
|
KernelState* kernel_state, XObject* object,
|
||||||
CompletionCallback callback, void* callback_context);
|
CompletionCallback callback, void* callback_context);
|
||||||
virtual ~XAsyncRequest();
|
virtual ~XAsyncRequest();
|
||||||
|
|
||||||
|
KernelState* kernel_state() const { return kernel_state_; }
|
||||||
XObject* object() const { return object_; }
|
XObject* object() const { return object_; }
|
||||||
|
|
||||||
XEvent* wait_event() const { return wait_event_; }
|
void AddWaitEvent(XEvent* ev);
|
||||||
uint32_t apc_routine() const { return apc_routine_; }
|
|
||||||
uint32_t apc_context() const { return apc_context_; }
|
|
||||||
|
|
||||||
// Complete(result)
|
// Complete(result)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
KernelState* kernel_state_;
|
||||||
XObject* object_;
|
XObject* object_;
|
||||||
CompletionCallback callback_;
|
CompletionCallback callback_;
|
||||||
void* callback_context_;
|
void* callback_context_;
|
||||||
|
|
||||||
XEvent* wait_event_;
|
std::vector<XEvent*> wait_events_;
|
||||||
uint32_t apc_routine_;
|
uint32_t apc_routine_;
|
||||||
uint32_t apc_context_;
|
uint32_t apc_context_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,10 +13,15 @@
|
||||||
#include <xenia/common.h>
|
#include <xenia/common.h>
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
#include <xenia/kernel/xbox.h>
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
|
class XAsyncRequest;
|
||||||
|
|
||||||
namespace fs {
|
namespace fs {
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,6 +72,16 @@ public:
|
||||||
|
|
||||||
//virtual void Query() = 0;
|
//virtual void Query() = 0;
|
||||||
|
|
||||||
|
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
|
size_t* out_bytes_read) {
|
||||||
|
return X_STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
|
XAsyncRequest* request) {
|
||||||
|
// queue completion of failure
|
||||||
|
return X_STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
virtual MemoryMapping* CreateMemoryMapping(
|
virtual MemoryMapping* CreateMemoryMapping(
|
||||||
xe_file_mode file_mode, const size_t offset, const size_t length) = 0;
|
xe_file_mode file_mode, const size_t offset, const size_t length) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include <xenia/kernel/modules/xboxkrnl/objects/xfile.h>
|
#include <xenia/kernel/modules/xboxkrnl/objects/xfile.h>
|
||||||
|
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/async_request.h>
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/fs/entry.h>
|
||||||
#include <xenia/kernel/modules/xboxkrnl/objects/xevent.h>
|
#include <xenia/kernel/modules/xboxkrnl/objects/xevent.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,13 +22,41 @@ using namespace xe::kernel::xboxkrnl::fs;
|
||||||
|
|
||||||
XFile::XFile(KernelState* kernel_state, FileEntry* entry) :
|
XFile::XFile(KernelState* kernel_state, FileEntry* entry) :
|
||||||
entry_(entry),
|
entry_(entry),
|
||||||
|
position_(0),
|
||||||
XObject(kernel_state, kTypeFile) {
|
XObject(kernel_state, kTypeFile) {
|
||||||
|
async_event_ = new XEvent(kernel_state);
|
||||||
|
async_event_->Initialize(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
XFile::~XFile() {
|
XFile::~XFile() {
|
||||||
|
// TODO(benvanik): signal that the file is closing?
|
||||||
|
async_event_->Set(0, false);
|
||||||
|
async_event_->Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
X_STATUS XFile::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
|
// Wait until some async operation completes.
|
||||||
|
return async_event_->Wait(
|
||||||
|
wait_reason, processor_mode, alertable, opt_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
|
size_t* out_bytes_read) {
|
||||||
|
if (byte_offset == -1) {
|
||||||
|
// Read from current position.
|
||||||
|
}
|
||||||
|
X_STATUS result = entry_->Read(buffer, buffer_length, byte_offset, out_bytes_read);
|
||||||
|
if (XSUCCEEDED(result)) {
|
||||||
|
position_ += *out_bytes_read;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
XAsyncRequest* request) {
|
XAsyncRequest* request) {
|
||||||
return X_STATUS_ACCESS_DENIED;
|
// Also tack on our event so that any waiters wake.
|
||||||
|
request->AddWaitEvent(async_event_);
|
||||||
|
position_ = byte_offset;
|
||||||
|
return entry_->Read(buffer, buffer_length, byte_offset, request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,25 +13,41 @@
|
||||||
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
|
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
|
||||||
|
|
||||||
#include <xenia/kernel/xbox.h>
|
#include <xenia/kernel/xbox.h>
|
||||||
#include <xenia/kernel/modules/xboxkrnl/async_request.h>
|
|
||||||
#include <xenia/kernel/modules/xboxkrnl/fs/entry.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
|
class XAsyncRequest;
|
||||||
|
class XEvent;
|
||||||
|
namespace fs {
|
||||||
|
class FileEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class XFile : public XObject {
|
class XFile : public XObject {
|
||||||
public:
|
public:
|
||||||
XFile(KernelState* kernel_state, fs::FileEntry* entry);
|
XFile(KernelState* kernel_state, fs::FileEntry* entry);
|
||||||
virtual ~XFile();
|
virtual ~XFile();
|
||||||
|
|
||||||
|
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
|
uint32_t alertable, uint64_t* opt_timeout);
|
||||||
|
|
||||||
|
// TODO(benvanik): Create/Open
|
||||||
|
|
||||||
|
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
|
size_t* out_bytes_read);
|
||||||
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
|
||||||
XAsyncRequest* request);
|
XAsyncRequest* request);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fs::FileEntry* entry_;
|
fs::FileEntry* entry_;
|
||||||
|
XEvent* async_event_;
|
||||||
|
|
||||||
|
// TODO(benvanik): create flags, open state, etc.
|
||||||
|
|
||||||
|
size_t position_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,10 @@
|
||||||
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_io.h>
|
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_io.h>
|
||||||
|
|
||||||
#include <xenia/kernel/shim_utils.h>
|
#include <xenia/kernel/shim_utils.h>
|
||||||
|
#include <xenia/kernel/modules/xboxkrnl/async_request.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/xfile.h>
|
#include <xenia/kernel/modules/xboxkrnl/objects/xfile.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,6 +107,16 @@ SHIM_CALL NtOpenFile_shim(
|
||||||
SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE);
|
SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class xeNtReadFileState {
|
||||||
|
public:
|
||||||
|
uint32_t x;
|
||||||
|
};
|
||||||
|
void xeNtReadFileCompleted(XAsyncRequest* request, xeNtReadFileState* state) {
|
||||||
|
// TODO(benvanik): set io_status_block_ptr
|
||||||
|
delete request;
|
||||||
|
delete state;
|
||||||
|
}
|
||||||
|
|
||||||
SHIM_CALL NtReadFile_shim(
|
SHIM_CALL NtReadFile_shim(
|
||||||
xe_ppc_state_t* ppc_state, KernelState* state) {
|
xe_ppc_state_t* ppc_state, KernelState* state) {
|
||||||
uint32_t file_handle = SHIM_GET_ARG_32(0);
|
uint32_t file_handle = SHIM_GET_ARG_32(0);
|
||||||
|
@ -115,10 +127,10 @@ SHIM_CALL NtReadFile_shim(
|
||||||
uint32_t buffer = SHIM_GET_ARG_32(5);
|
uint32_t buffer = SHIM_GET_ARG_32(5);
|
||||||
uint32_t buffer_length = SHIM_GET_ARG_32(6);
|
uint32_t buffer_length = SHIM_GET_ARG_32(6);
|
||||||
uint32_t byte_offset_ptr = SHIM_GET_ARG_32(7);
|
uint32_t byte_offset_ptr = SHIM_GET_ARG_32(7);
|
||||||
uint32_t key = SHIM_GET_ARG_32(8);
|
size_t byte_offset = byte_offset_ptr ? SHIM_MEM_64(byte_offset_ptr) : 0;
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
"NtReadFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %d, %.8X)",
|
"NtReadFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %d)",
|
||||||
file_handle,
|
file_handle,
|
||||||
event_handle,
|
event_handle,
|
||||||
apc_routine_ptr,
|
apc_routine_ptr,
|
||||||
|
@ -126,24 +138,69 @@ SHIM_CALL NtReadFile_shim(
|
||||||
io_status_block_ptr,
|
io_status_block_ptr,
|
||||||
buffer,
|
buffer,
|
||||||
buffer_length,
|
buffer_length,
|
||||||
byte_offset_ptr,
|
byte_offset_ptr);
|
||||||
key);
|
|
||||||
|
|
||||||
// Async not supported yet.
|
// Async not supported yet.
|
||||||
XEASSERTNULL(apc_routine_ptr);
|
XEASSERTNULL(apc_routine_ptr);
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_INVALID_HANDLE;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
uint32_t info = 0;
|
uint32_t info = 0;
|
||||||
|
|
||||||
XFile* file = NULL;
|
// Grab event to signal.
|
||||||
result = state->object_table()->GetObject(
|
XEvent* ev = NULL;
|
||||||
file_handle, (XObject**)&file);
|
bool signal_event = false;
|
||||||
if (result == X_STATUS_SUCCESS) {
|
if (event_handle) {
|
||||||
// TODO(benvanik): read!
|
result = state->object_table()->GetObject(
|
||||||
|
event_handle, (XObject**)&ev);
|
||||||
|
}
|
||||||
|
|
||||||
file->Release();
|
// Grab file.
|
||||||
result = X_STATUS_SUCCESS;
|
XFile* file = NULL;
|
||||||
info = 0; // number of bytes read
|
if (XSUCCEEDED(result)) {
|
||||||
|
result = state->object_table()->GetObject(
|
||||||
|
file_handle, (XObject**)&file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute read.
|
||||||
|
if (XSUCCEEDED(result)) {
|
||||||
|
// Reset event before we begin.
|
||||||
|
if (ev) {
|
||||||
|
ev->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(benvanik): async path.
|
||||||
|
if (true) {
|
||||||
|
// Synchronous request.
|
||||||
|
if (byte_offset == 0xFFFFFFFFfffffffe) {
|
||||||
|
// FILE_USE_FILE_POINTER_POSITION
|
||||||
|
byte_offset = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read now.
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
result = file->Read(
|
||||||
|
SHIM_MEM_ADDR(buffer), buffer_length, byte_offset,
|
||||||
|
&bytes_read);
|
||||||
|
if (XSUCCEEDED(result)) {
|
||||||
|
info = (int32_t)bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark that we should signal the event now. We do this after
|
||||||
|
// we have written the info out.
|
||||||
|
signal_event = true;
|
||||||
|
} else {
|
||||||
|
// X_STATUS_PENDING if not returning immediately.
|
||||||
|
// XFile is waitable and signalled after each async req completes.
|
||||||
|
// reset the input event (->Reset())
|
||||||
|
/*xeNtReadFileState* call_state = new xeNtReadFileState();
|
||||||
|
XAsyncRequest* request = new XAsyncRequest(
|
||||||
|
state, file,
|
||||||
|
(XAsyncRequest::CompletionCallback)xeNtReadFileCompleted,
|
||||||
|
call_state);*/
|
||||||
|
//result = file->Read(buffer, buffer_length, byte_offset, request);
|
||||||
|
result = X_STATUS_PENDING;
|
||||||
|
info = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (io_status_block_ptr) {
|
if (io_status_block_ptr) {
|
||||||
|
@ -151,6 +208,16 @@ SHIM_CALL NtReadFile_shim(
|
||||||
SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information
|
SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
file->Release();
|
||||||
|
}
|
||||||
|
if (ev) {
|
||||||
|
if (signal_event) {
|
||||||
|
ev->Set(0, false);
|
||||||
|
}
|
||||||
|
ev->Release();
|
||||||
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN(result);
|
SHIM_SET_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,10 @@ void XObject::Release() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X_STATUS XObject::Delete() {
|
||||||
|
return shared_kernel_state_->object_table()->RemoveHandle(handle_);
|
||||||
|
}
|
||||||
|
|
||||||
X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode,
|
||||||
uint32_t alertable, uint64_t* opt_timeout) {
|
uint32_t alertable, uint64_t* opt_timeout) {
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
|
@ -85,15 +89,15 @@ void XObject::LockType() {
|
||||||
void XObject::UnlockType() {
|
void XObject::UnlockType() {
|
||||||
xe_mutex_unlock(shared_kernel_state_->object_mutex_);
|
xe_mutex_unlock(shared_kernel_state_->object_mutex_);
|
||||||
}
|
}
|
||||||
|
|
||||||
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr) {
|
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr) {
|
||||||
// Unfortunately the XDK seems to inline some KeInitialize calls, meaning
|
// Unfortunately the XDK seems to inline some KeInitialize calls, meaning
|
||||||
// we never see it and just randomly start getting passed events/timers/etc.
|
// 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
|
// 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 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
|
// we init on first use, store our pointer in the struct, and dereference it
|
||||||
// each time.
|
// each time.
|
||||||
// We identify this by checking the low bit of wait_list_blink - if it's 1,
|
// We identify this by checking the low bit of wait_list_blink - if it's 1,
|
||||||
// we have already put our pointer in there.
|
// we have already put our pointer in there.
|
||||||
|
|
||||||
XObject::LockType();
|
XObject::LockType();
|
||||||
|
@ -115,46 +119,46 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr) {
|
||||||
XObject::UnlockType();
|
XObject::UnlockType();
|
||||||
return object;
|
return object;
|
||||||
} else {
|
} else {
|
||||||
// First use, create new.
|
// First use, create new.
|
||||||
// http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html
|
// http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html
|
||||||
XObject* object = NULL;
|
XObject* object = NULL;
|
||||||
switch (header.type_flags & 0xFF) {
|
switch (header.type_flags & 0xFF) {
|
||||||
case 0: // EventNotificationObject
|
case 0: // EventNotificationObject
|
||||||
case 1: // EventSynchronizationObject
|
case 1: // EventSynchronizationObject
|
||||||
{
|
{
|
||||||
XEvent* ev = new XEvent(kernel_state);
|
XEvent* ev = new XEvent(kernel_state);
|
||||||
ev->InitializeNative(native_ptr, header);
|
ev->InitializeNative(native_ptr, header);
|
||||||
object = ev;
|
object = ev;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // MutantObject
|
case 2: // MutantObject
|
||||||
case 3: // ProcessObject
|
case 3: // ProcessObject
|
||||||
case 4: // QueueObject
|
case 4: // QueueObject
|
||||||
case 5: // SemaphoreObject
|
case 5: // SemaphoreObject
|
||||||
case 6: // ThreadObject
|
case 6: // ThreadObject
|
||||||
case 7: // GateObject
|
case 7: // GateObject
|
||||||
case 8: // TimerNotificationObject
|
case 8: // TimerNotificationObject
|
||||||
case 9: // TimerSynchronizationObject
|
case 9: // TimerSynchronizationObject
|
||||||
case 18: // ApcObject
|
case 18: // ApcObject
|
||||||
case 19: // DpcObject
|
case 19: // DpcObject
|
||||||
case 20: // DeviceQueueObject
|
case 20: // DeviceQueueObject
|
||||||
case 21: // EventPairObject
|
case 21: // EventPairObject
|
||||||
case 22: // InterruptObject
|
case 22: // InterruptObject
|
||||||
case 23: // ProfileObject
|
case 23: // ProfileObject
|
||||||
case 24: // ThreadedDpcObject
|
case 24: // ThreadedDpcObject
|
||||||
default:
|
default:
|
||||||
XEASSERTALWAYS();
|
XEASSERTALWAYS();
|
||||||
XObject::UnlockType();
|
XObject::UnlockType();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stash pointer in struct.
|
// Stash pointer in struct.
|
||||||
uint64_t object_ptr = reinterpret_cast<uint64_t>(object);
|
uint64_t object_ptr = reinterpret_cast<uint64_t>(object);
|
||||||
object_ptr |= 0x1;
|
object_ptr |= 0x1;
|
||||||
header_be->wait_list_flink = XESWAP32((uint32_t)(object_ptr >> 32));
|
header_be->wait_list_flink = XESWAP32((uint32_t)(object_ptr >> 32));
|
||||||
header_be->wait_list_blink = XESWAP32((uint32_t)(object_ptr & 0xFFFFFFFF));
|
header_be->wait_list_blink = XESWAP32((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||||
|
|
||||||
XObject::UnlockType();
|
XObject::UnlockType();
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,7 +27,7 @@ namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
|
|
||||||
// http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html
|
// http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t type_flags;
|
uint32_t type_flags;
|
||||||
uint32_t signal_state;
|
uint32_t signal_state;
|
||||||
|
@ -57,6 +57,7 @@ public:
|
||||||
bool ReleaseHandle();
|
bool ReleaseHandle();
|
||||||
void Retain();
|
void Retain();
|
||||||
void Release();
|
void Release();
|
||||||
|
X_STATUS Delete();
|
||||||
|
|
||||||
// Reference()
|
// Reference()
|
||||||
// Dereference()
|
// Dereference()
|
||||||
|
|
|
@ -30,9 +30,10 @@ typedef uint32_t X_STATUS;
|
||||||
#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_ABANDONED_WAIT_0 ((uint32_t)0x00000080L)
|
||||||
#define X_STATUS_USER_APC ((uint32_t)0x000000C0L)
|
#define X_STATUS_USER_APC ((uint32_t)0x000000C0L)
|
||||||
#define X_STATUS_ALERTED ((uint32_t)0x00000101L)
|
#define X_STATUS_ALERTED ((uint32_t)0x00000101L)
|
||||||
#define X_STATUS_TIMEOUT ((uint32_t)0x00000102L)
|
#define X_STATUS_TIMEOUT ((uint32_t)0x00000102L)
|
||||||
|
#define X_STATUS_PENDING ((uint32_t)0x00000103L)
|
||||||
#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)
|
||||||
|
|
Loading…
Reference in New Issue