Bytes read via ReadFile!

This commit is contained in:
Ben Vanik 2013-10-16 20:50:46 -07:00
parent fea5c06180
commit 8e37fb8502
12 changed files with 105 additions and 34 deletions

View File

@ -70,15 +70,8 @@ MemoryMapping* DiscImageEntry::CreateMemoryMapping(
X_STATUS DiscImageEntry::Open(
KernelState* kernel_state,
/* mode etc */
uint32_t desired_access, bool async,
XFile** out_file) {
//*out_file = new DiscImageFile...
return X_STATUS_NOT_IMPLEMENTED;
*out_file = new DiscImageFile(kernel_state, desired_access, this);
return X_STATUS_SUCCESS;
}
/* size_t real_offset = gdfx_entry_->offset + byte_offset;
size_t real_length = MIN(buffer_length, gdfx_entry_->size - byte_offset);
xe_copy_memory(
buffer, buffer_length,
xe_mmap_get_addr(mmap_) + real_offset, real_length);
*out_bytes_read = real_length;
return X_STATUS_SUCCESS;*/

View File

@ -30,12 +30,15 @@ public:
xe_mmap_ref mmap, GDFXEntry* gdfx_entry);
virtual ~DiscImageEntry();
xe_mmap_ref mmap() const { return mmap_; }
GDFXEntry* gdfx_entry() const { return gdfx_entry_; }
virtual MemoryMapping* CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length);
virtual X_STATUS Open(
KernelState* kernel_state,
/* mode etc */
uint32_t desired_access, bool async,
XFile** out_file);
private:

View File

@ -9,6 +9,7 @@
#include <xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.h>
#include <xenia/kernel/modules/xboxkrnl/fs/gdfx.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.h>
@ -18,10 +19,26 @@ using namespace xe::kernel::xboxkrnl;
using namespace xe::kernel::xboxkrnl::fs;
DiscImageFile::DiscImageFile(KernelState* kernel_state, DiscImageEntry* entry) :
DiscImageFile::DiscImageFile(
KernelState* kernel_state, uint32_t desired_access,
DiscImageEntry* entry) :
entry_(entry),
XFile(kernel_state) {
XFile(kernel_state, desired_access) {
}
DiscImageFile::~DiscImageFile() {
}
X_STATUS DiscImageFile::ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) {
GDFXEntry* gdfx_entry = entry_->gdfx_entry();
xe_mmap_ref mmap = entry_->mmap();
size_t real_offset = gdfx_entry->offset + byte_offset;
size_t real_length = MIN(buffer_length, gdfx_entry->size - byte_offset);
xe_copy_memory(
buffer, buffer_length,
xe_mmap_get_addr(mmap) + real_offset, real_length);
*out_bytes_read = real_length;
return X_STATUS_SUCCESS;
}

View File

@ -26,9 +26,16 @@ class DiscImageEntry;
class DiscImageFile : public XFile {
public:
DiscImageFile(KernelState* kernel_state, DiscImageEntry* entry);
DiscImageFile(KernelState* kernel_state, uint32_t desired_access,
DiscImageEntry* entry);
virtual ~DiscImageFile();
protected:
virtual X_STATUS ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read);
private:
DiscImageEntry* entry_;
};

View File

@ -65,7 +65,24 @@ MemoryMapping* HostPathEntry::CreateMemoryMapping(
X_STATUS HostPathEntry::Open(
KernelState* kernel_state,
uint32_t desired_access, bool async,
XFile** out_file) {
//*out_file = new DiscImageFile...
return X_STATUS_NOT_IMPLEMENTED;
DWORD share_mode = FILE_SHARE_READ;
DWORD creation_disposition = OPEN_EXISTING;
DWORD flags_and_attributes = async ? FILE_FLAG_OVERLAPPED : 0;
HANDLE file = CreateFile(
local_path_,
desired_access,
share_mode,
NULL,
creation_disposition,
flags_and_attributes,
NULL);
if (!file) {
// TODO(benvanik): pick correct response.
return X_STATUS_ACCESS_DENIED;
}
*out_file = new HostPathFile(kernel_state, desired_access, this, file);
return X_STATUS_SUCCESS;
}

View File

@ -35,6 +35,7 @@ public:
virtual X_STATUS Open(
KernelState* kernel_state,
uint32_t desired_access, bool async,
XFile** out_file);
private:

View File

@ -18,10 +18,30 @@ using namespace xe::kernel::xboxkrnl;
using namespace xe::kernel::xboxkrnl::fs;
HostPathFile::HostPathFile(KernelState* kernel_state, HostPathEntry* entry) :
entry_(entry),
XFile(kernel_state) {
HostPathFile::HostPathFile(
KernelState* kernel_state, uint32_t desired_access,
HostPathEntry* entry, HANDLE file_handle) :
entry_(entry), file_handle_(file_handle),
XFile(kernel_state, desired_access) {
}
HostPathFile::~HostPathFile() {
CloseHandle(file_handle_);
}
X_STATUS HostPathFile::ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) {
OVERLAPPED overlapped;
overlapped.Pointer = (PVOID)byte_offset;
overlapped.hEvent = NULL;
DWORD bytes_read = 0;
BOOL read = ReadFile(
file_handle_, buffer, (DWORD)buffer_length, &bytes_read, &overlapped);
if (read) {
*out_bytes_read = bytes_read;
return X_STATUS_SUCCESS;
} else {
return X_STATUS_UNSUCCESSFUL;
}
}

View File

@ -26,11 +26,18 @@ class HostPathEntry;
class HostPathFile : public XFile {
public:
HostPathFile(KernelState* kernel_state, HostPathEntry* entry);
HostPathFile(KernelState* kernel_state, uint32_t desired_access,
HostPathEntry* entry, HANDLE file_handle);
virtual ~HostPathFile();
protected:
virtual X_STATUS ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read);
private:
HostPathEntry* entry_;
HANDLE file_handle_;
};

View File

@ -59,7 +59,8 @@ public:
xe_file_mode file_mode, const size_t offset, const size_t length) = 0;
virtual X_STATUS Open(
KernelState* kernel_state,
KernelState* kernel_state,
uint32_t desired_access, bool async,
XFile** out_file) = 0;
private:

View File

@ -18,8 +18,8 @@ using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl;
XFile::XFile(KernelState* kernel_state) :
position_(0),
XFile::XFile(KernelState* kernel_state, uint32_t desired_access) :
desired_access_(desired_access), position_(0),
XObject(kernel_state, kTypeFile) {
async_event_ = new XEvent(kernel_state);
async_event_->Initialize(false, false);
@ -42,12 +42,12 @@ 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.
byte_offset = position_;
}
X_STATUS result = ReadSync(buffer, buffer_length, byte_offset, out_bytes_read);
if (XSUCCEEDED(result)) {
position_ += *out_bytes_read;
}
// X_STATUS result = entry_->Read(buffer, buffer_length, byte_offset, out_bytes_read);
// if (XSUCCEEDED(result)) {
// position_ += *out_bytes_read;
// }
X_STATUS result = X_STATUS_NOT_IMPLEMENTED;
return result;
}
@ -56,7 +56,7 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
// 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);
//return entry_->ReadAsync(buffer, buffer_length, byte_offset, request);
X_STATUS result = X_STATUS_NOT_IMPLEMENTED;
return result;
}

View File

@ -25,23 +25,24 @@ class XEvent;
class XFile : public XObject {
public:
XFile(KernelState* kernel_state);
XFile(KernelState* kernel_state, uint32_t desired_access);
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,
XAsyncRequest* request);
protected:
// open/read/write/etc
virtual X_STATUS ReadSync(
void* buffer, size_t buffer_length, size_t byte_offset,
size_t* out_bytes_read) = 0;
private:
uint32_t desired_access_;
XEvent* async_event_;
// TODO(benvanik): create flags, open state, etc.

View File

@ -80,7 +80,11 @@ SHIM_CALL NtCreateFile_shim(
XFile* file = NULL;
if (entry && entry->type() == Entry::kTypeFile) {
// Open the file.
result = entry->Open(state, &file);
result = entry->Open(
state,
desired_access,
false, // TODO(benvanik): pick async mode, if needed.
&file);
} else {
result = X_STATUS_NO_SUCH_FILE;
info = X_FILE_DOES_NOT_EXIST;