Reworking file system so that it's easier to implement file operations.

This commit is contained in:
Ben Vanik 2013-10-16 20:07:10 -07:00
parent 1808af26b1
commit ab5b9d75e0
23 changed files with 555 additions and 319 deletions

View File

@ -10,6 +10,7 @@
#include <xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_device.h>
#include <xenia/kernel/modules/xboxkrnl/fs/gdfx.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.h>
using namespace xe;
@ -17,62 +18,6 @@ using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl::fs;
namespace {
class DiscImageMemoryMapping : public MemoryMapping {
public:
DiscImageMemoryMapping(uint8_t* address, size_t length, xe_mmap_ref mmap) :
MemoryMapping(address, length) {
mmap_ = xe_mmap_retain(mmap);
}
virtual ~DiscImageMemoryMapping() {
xe_mmap_release(mmap_);
}
private:
xe_mmap_ref mmap_;
};
class DiscImageFileEntry : public FileEntry {
public:
DiscImageFileEntry(Device* device, const char* path,
xe_mmap_ref mmap, GDFXEntry* gdfx_entry) :
FileEntry(device, path),
gdfx_entry_(gdfx_entry) {
mmap_ = xe_mmap_retain(mmap);
}
virtual ~DiscImageFileEntry() {
xe_mmap_release(mmap_);
}
virtual MemoryMapping* CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length) {
if (file_mode & kXEFileModeWrite) {
// Only allow reads.
return NULL;
}
size_t real_offset = gdfx_entry_->offset + offset;
size_t real_length = length ?
MIN(length, gdfx_entry_->size) : gdfx_entry_->size;
return new DiscImageMemoryMapping(
xe_mmap_get_addr(mmap_) + real_offset,
real_length,
mmap_);
}
private:
xe_mmap_ref mmap_;
GDFXEntry* gdfx_entry_;
};
}
DiscImageDevice::DiscImageDevice(const char* path, const xechar_t* local_path) :
Device(path) {
@ -146,11 +91,8 @@ Entry* DiscImageDevice::ResolvePath(const char* path) {
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), next_slash + 1));
}
if (gdfx_entry->attributes & GDFXEntry::kAttrFolder) {
//return new DiscImageDirectoryEntry(mmap_, gdfx_entry);
XEASSERTALWAYS();
return NULL;
} else {
return new DiscImageFileEntry(this, path, mmap_, gdfx_entry);
}
Entry::Type type = gdfx_entry->attributes & GDFXEntry::kAttrFolder ?
Entry::kTypeDirectory : Entry::kTypeFile;
return new DiscImageEntry(
type, this, path, mmap_, gdfx_entry);
}

View File

@ -0,0 +1,84 @@
/**
******************************************************************************
* 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/modules/xboxkrnl/fs/devices/disc_image_entry.h>
#include <xenia/kernel/modules/xboxkrnl/fs/gdfx.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.h>
using namespace xe;
using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl;
using namespace xe::kernel::xboxkrnl::fs;
namespace {
class DiscImageMemoryMapping : public MemoryMapping {
public:
DiscImageMemoryMapping(uint8_t* address, size_t length, xe_mmap_ref mmap) :
MemoryMapping(address, length) {
mmap_ = xe_mmap_retain(mmap);
}
virtual ~DiscImageMemoryMapping() {
xe_mmap_release(mmap_);
}
private:
xe_mmap_ref mmap_;
};
}
DiscImageEntry::DiscImageEntry(Type type, Device* device, const char* path,
xe_mmap_ref mmap, GDFXEntry* gdfx_entry) :
gdfx_entry_(gdfx_entry),
Entry(type, device, path) {
mmap_ = xe_mmap_retain(mmap);
}
DiscImageEntry::~DiscImageEntry() {
xe_mmap_release(mmap_);
}
MemoryMapping* DiscImageEntry::CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length) {
if (file_mode & kXEFileModeWrite) {
// Only allow reads.
return NULL;
}
size_t real_offset = gdfx_entry_->offset + offset;
size_t real_length = length ?
MIN(length, gdfx_entry_->size) : gdfx_entry_->size;
return new DiscImageMemoryMapping(
xe_mmap_get_addr(mmap_) + real_offset,
real_length,
mmap_);
}
X_STATUS DiscImageEntry::Open(
KernelState* kernel_state,
/* mode etc */
XFile** out_file) {
//*out_file = new DiscImageFile...
return X_STATUS_NOT_IMPLEMENTED;
}
/* 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

@ -0,0 +1,53 @@
/**
******************************************************************************
* 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_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_ENTRY_H_
#define XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_ENTRY_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/modules/xboxkrnl/fs/entry.h>
namespace xe {
namespace kernel {
namespace xboxkrnl {
namespace fs {
class GDFXEntry;
class DiscImageEntry : public Entry {
public:
DiscImageEntry(Type type, Device* device, const char* path,
xe_mmap_ref mmap, GDFXEntry* gdfx_entry);
virtual ~DiscImageEntry();
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 */
XFile** out_file);
private:
xe_mmap_ref mmap_;
GDFXEntry* gdfx_entry_;
};
} // namespace fs
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_ENTRY_H_

View File

@ -0,0 +1,27 @@
/**
******************************************************************************
* 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/modules/xboxkrnl/fs/devices/disc_image_file.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.h>
using namespace xe;
using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl;
using namespace xe::kernel::xboxkrnl::fs;
DiscImageFile::DiscImageFile(KernelState* kernel_state, DiscImageEntry* entry) :
entry_(entry),
XFile(kernel_state) {
}
DiscImageFile::~DiscImageFile() {
}

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_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_
#define XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/modules/xboxkrnl/objects/xfile.h>
namespace xe {
namespace kernel {
namespace xboxkrnl {
namespace fs {
class DiscImageEntry;
class DiscImageFile : public XFile {
public:
DiscImageFile(KernelState* kernel_state, DiscImageEntry* entry);
virtual ~DiscImageFile();
private:
DiscImageEntry* entry_;
};
} // namespace fs
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_DISC_IMAGE_FILE_H_

View File

@ -0,0 +1,65 @@
/**
******************************************************************************
* 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/modules/xboxkrnl/fs/devices/host_path_device.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.h>
using namespace xe;
using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl::fs;
HostPathDevice::HostPathDevice(const char* path, const xechar_t* local_path) :
Device(path) {
local_path_ = xestrdup(local_path);
}
HostPathDevice::~HostPathDevice() {
xe_free(local_path_);
}
Entry* HostPathDevice::ResolvePath(const char* path) {
// The filesystem will have stripped our prefix off already, so the path will
// be in the form:
// some\PATH.foo
XELOGFS("HostPathDevice::ResolvePath(%s)", path);
#if XE_WCHAR
xechar_t rel_path[XE_MAX_PATH];
XEIGNORE(xestrwiden(rel_path, XECOUNT(rel_path), path));
#else
const xechar_t* rel_path = path;
#endif
xechar_t full_path[XE_MAX_PATH];
xe_path_join(local_path_, rel_path, full_path, XECOUNT(full_path));
// Swap around path separators.
if (XE_PATH_SEPARATOR != '\\') {
for (size_t n = 0; n < XECOUNT(full_path); n++) {
if (full_path[n] == 0) {
break;
}
if (full_path[n] == '\\') {
full_path[n] = XE_PATH_SEPARATOR;
}
}
}
// TODO(benvanik): get file info
// TODO(benvanik): fail if does not exit
// TODO(benvanik): switch based on type
Entry::Type type = Entry::kTypeFile;
HostPathEntry* entry = new HostPathEntry(type, this, path, full_path);
return entry;
}

View File

@ -7,8 +7,8 @@
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_LOCAL_DIRECTORY_DEVICE_H_
#define XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_LOCAL_DIRECTORY_DEVICE_H_
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_DEVICE_H_
#define XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_DEVICE_H_
#include <xenia/common.h>
#include <xenia/core.h>
@ -22,10 +22,10 @@ namespace xboxkrnl {
namespace fs {
class LocalDirectoryDevice : public Device {
class HostPathDevice : public Device {
public:
LocalDirectoryDevice(const char* path, const xechar_t* local_path);
virtual ~LocalDirectoryDevice();
HostPathDevice(const char* path, const xechar_t* local_path);
virtual ~HostPathDevice();
virtual Entry* ResolvePath(const char* path);
@ -40,4 +40,4 @@ private:
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_LOCAL_DIRECTORY_DEVICE_H_
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_DEVICE_H_

View File

@ -0,0 +1,71 @@
/**
******************************************************************************
* 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/modules/xboxkrnl/fs/devices/host_path_entry.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.h>
using namespace xe;
using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl;
using namespace xe::kernel::xboxkrnl::fs;
namespace {
class HostPathMemoryMapping : public MemoryMapping {
public:
HostPathMemoryMapping(uint8_t* address, size_t length, xe_mmap_ref mmap) :
MemoryMapping(address, length) {
mmap_ = xe_mmap_retain(mmap);
}
virtual ~HostPathMemoryMapping() {
xe_mmap_release(mmap_);
}
private:
xe_mmap_ref mmap_;
};
}
HostPathEntry::HostPathEntry(Type type, Device* device, const char* path,
const xechar_t* local_path) :
Entry(type, device, path) {
local_path_ = xestrdup(local_path);
}
HostPathEntry::~HostPathEntry() {
xe_free(local_path_);
}
MemoryMapping* HostPathEntry::CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length) {
xe_mmap_ref mmap = xe_mmap_open(file_mode, local_path_, offset, length);
if (!mmap) {
return NULL;
}
HostPathMemoryMapping* lfmm = new HostPathMemoryMapping(
(uint8_t*)xe_mmap_get_addr(mmap), xe_mmap_get_length(mmap),
mmap);
xe_mmap_release(mmap);
return lfmm;
}
X_STATUS HostPathEntry::Open(
KernelState* kernel_state,
XFile** out_file) {
//*out_file = new DiscImageFile...
return X_STATUS_NOT_IMPLEMENTED;
}

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. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_ENTRY_H_
#define XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_ENTRY_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/modules/xboxkrnl/fs/entry.h>
namespace xe {
namespace kernel {
namespace xboxkrnl {
namespace fs {
class HostPathEntry : public Entry {
public:
HostPathEntry(Type type, Device* device, const char* path,
const xechar_t* local_path);
virtual ~HostPathEntry();
const xechar_t* local_path() { return local_path_; }
virtual MemoryMapping* CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length);
virtual X_STATUS Open(
KernelState* kernel_state,
XFile** out_file);
private:
xechar_t* local_path_;
};
} // namespace fs
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_ENTRY_H_

View File

@ -0,0 +1,27 @@
/**
******************************************************************************
* 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/modules/xboxkrnl/fs/devices/host_path_file.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.h>
using namespace xe;
using namespace xe::kernel;
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() {
}

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_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_FILE_H_
#define XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_FILE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/modules/xboxkrnl/objects/xfile.h>
namespace xe {
namespace kernel {
namespace xboxkrnl {
namespace fs {
class HostPathEntry;
class HostPathFile : public XFile {
public:
HostPathFile(KernelState* kernel_state, HostPathEntry* entry);
virtual ~HostPathFile();
private:
HostPathEntry* entry_;
};
} // namespace fs
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_MODULES_XBOXKRNL_FS_DEVICES_HOST_PATH_FILE_H_

View File

@ -1,115 +0,0 @@
/**
******************************************************************************
* 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/modules/xboxkrnl/fs/devices/local_directory_device.h>
using namespace xe;
using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl::fs;
namespace {
class LocalFileMemoryMapping : public MemoryMapping {
public:
LocalFileMemoryMapping(uint8_t* address, size_t length, xe_mmap_ref mmap) :
MemoryMapping(address, length) {
mmap_ = xe_mmap_retain(mmap);
}
virtual ~LocalFileMemoryMapping() {
xe_mmap_release(mmap_);
}
private:
xe_mmap_ref mmap_;
};
class LocalFileEntry : public FileEntry {
public:
LocalFileEntry(Device* device, const char* path, const xechar_t* local_path) :
FileEntry(device, path) {
local_path_ = xestrdup(local_path);
}
virtual ~LocalFileEntry() {
xe_free(local_path_);
}
const xechar_t* local_path() { return local_path_; }
virtual MemoryMapping* CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length) {
xe_mmap_ref mmap = xe_mmap_open(file_mode, local_path_, offset, length);
if (!mmap) {
return NULL;
}
LocalFileMemoryMapping* lfmm = new LocalFileMemoryMapping(
(uint8_t*)xe_mmap_get_addr(mmap), xe_mmap_get_length(mmap),
mmap);
xe_mmap_release(mmap);
return lfmm;
}
private:
xechar_t* local_path_;
};
}
LocalDirectoryDevice::LocalDirectoryDevice(const char* path,
const xechar_t* local_path) :
Device(path) {
local_path_ = xestrdup(local_path);
}
LocalDirectoryDevice::~LocalDirectoryDevice() {
xe_free(local_path_);
}
Entry* LocalDirectoryDevice::ResolvePath(const char* path) {
// The filesystem will have stripped our prefix off already, so the path will
// be in the form:
// some\PATH.foo
XELOGFS("LocalDirectoryDevice::ResolvePath(%s)", path);
#if XE_WCHAR
xechar_t rel_path[XE_MAX_PATH];
XEIGNORE(xestrwiden(rel_path, XECOUNT(rel_path), path));
#else
const xechar_t* rel_path = path;
#endif
xechar_t full_path[XE_MAX_PATH];
xe_path_join(local_path_, rel_path, full_path, XECOUNT(full_path));
// Swap around path separators.
if (XE_PATH_SEPARATOR != '\\') {
for (size_t n = 0; n < XECOUNT(full_path); n++) {
if (full_path[n] == 0) {
break;
}
if (full_path[n] == '\\') {
full_path[n] = XE_PATH_SEPARATOR;
}
}
}
// TODO(benvanik): get file info
// TODO(benvanik): fail if does not exit
// TODO(benvanik): switch based on type
LocalFileEntry* file_entry = new LocalFileEntry(this, path, full_path);
return file_entry;
}

View File

@ -3,7 +3,15 @@
'sources': [
'disc_image_device.cc',
'disc_image_device.h',
'local_directory_device.cc',
'local_directory_device.h',
'disc_image_entry.cc',
'disc_image_entry.h',
'disc_image_file.cc',
'disc_image_file.h',
'host_path_device.cc',
'host_path_device.h',
'host_path_entry.cc',
'host_path_entry.h',
'host_path_file.cc',
'host_path_file.h',
],
}

View File

@ -15,6 +15,14 @@ using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl::fs;
MemoryMapping::MemoryMapping(uint8_t* address, size_t length) :
address_(address), length_(length) {
}
MemoryMapping::~MemoryMapping() {
}
Entry::Entry(Type type, Device* device, const char* path) :
type_(type),
device_(device) {
@ -27,51 +35,3 @@ Entry::~Entry() {
xe_free(path_);
xe_free(name_);
}
Entry::Type Entry::type() {
return type_;
}
Device* Entry::device() {
return device_;
}
const char* Entry::path() {
return path_;
}
const char* Entry::name() {
return name_;
}
MemoryMapping::MemoryMapping(uint8_t* address, size_t length) :
address_(address), length_(length) {
}
MemoryMapping::~MemoryMapping() {
}
uint8_t* MemoryMapping::address() {
return address_;
}
size_t MemoryMapping::length() {
return length_;
}
FileEntry::FileEntry(Device* device, const char* path) :
Entry(kTypeFile, device, path) {
}
FileEntry::~FileEntry() {
}
DirectoryEntry::DirectoryEntry(Device* device, const char* path) :
Entry(kTypeDirectory, device, path) {
}
DirectoryEntry::~DirectoryEntry() {
}

View File

@ -19,15 +19,27 @@
namespace xe {
namespace kernel {
namespace xboxkrnl {
class XAsyncRequest;
class KernelState;
class XFile;
namespace fs {
class Device;
class MemoryMapping {
public:
MemoryMapping(uint8_t* address, size_t length);
virtual ~MemoryMapping();
uint8_t* address() const { return address_; }
size_t length() const { return length_; }
private:
uint8_t* address_;
size_t length_;
};
class Entry {
public:
enum Type {
@ -38,10 +50,17 @@ public:
Entry(Type type, Device* device, const char* path);
virtual ~Entry();
Type type();
Device* device();
const char* path();
const char* name();
Type type() const { return type_; }
Device* device() const { return device_; }
const char* path() const { return path_; }
const char* name() const { return name_; }
virtual MemoryMapping* CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length) = 0;
virtual X_STATUS Open(
KernelState* kernel_state,
XFile** out_file) = 0;
private:
Type type_;
@ -51,51 +70,6 @@ private:
};
class MemoryMapping {
public:
MemoryMapping(uint8_t* address, size_t length);
virtual ~MemoryMapping();
uint8_t* address();
size_t length();
private:
uint8_t* address_;
size_t length_;
};
class FileEntry : public Entry {
public:
FileEntry(Device* device, const char* path);
virtual ~FileEntry();
//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(
xe_file_mode file_mode, const size_t offset, const size_t length) = 0;
};
class DirectoryEntry : public Entry {
public:
DirectoryEntry(Device* device, const char* path);
virtual ~DirectoryEntry();
//virtual void Query() = 0;
};
} // namespace fs
} // namespace xboxkrnl
} // namespace kernel

View File

@ -10,7 +10,7 @@
#include <xenia/kernel/modules/xboxkrnl/fs/filesystem.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_device.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/local_directory_device.h>
#include <xenia/kernel/modules/xboxkrnl/fs/devices/host_path_device.h>
using namespace xe;
@ -37,9 +37,9 @@ int FileSystem::RegisterDevice(const char* path, Device* device) {
return 0;
}
int FileSystem::RegisterLocalDirectoryDevice(
int FileSystem::RegisterHostPathDevice(
const char* path, const xechar_t* local_path) {
Device* device = new LocalDirectoryDevice(path, local_path);
Device* device = new HostPathDevice(path, local_path);
return RegisterDevice(path, device);
}

View File

@ -33,8 +33,7 @@ public:
~FileSystem();
int RegisterDevice(const char* path, Device* device);
int RegisterLocalDirectoryDevice(const char* path,
const xechar_t* local_path);
int RegisterHostPathDevice(const char* path, const xechar_t* local_path);
int RegisterDiscImageDevice(const char* path, const xechar_t* local_path);
int CreateSymbolicLink(const char* path, const char* target);

View File

@ -174,7 +174,9 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) {
}
// Retain the object pointer.
object->Retain();
if (object) {
object->Retain();
}
xe_mutex_unlock(table_mutex_);

View File

@ -10,18 +10,15 @@
#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>
using namespace xe;
using namespace xe::kernel;
using namespace xe::kernel::xboxkrnl;
using namespace xe::kernel::xboxkrnl::fs;
XFile::XFile(KernelState* kernel_state, FileEntry* entry) :
entry_(entry),
XFile::XFile(KernelState* kernel_state) :
position_(0),
XObject(kernel_state, kTypeFile) {
async_event_ = new XEvent(kernel_state);
@ -33,7 +30,7 @@ XFile::~XFile() {
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.
@ -46,10 +43,11 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset,
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;
}
// 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;
}
@ -58,5 +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_->Read(buffer, buffer_length, byte_offset, request);
X_STATUS result = X_STATUS_NOT_IMPLEMENTED;
return result;
}

View File

@ -21,16 +21,13 @@ namespace xboxkrnl {
class XAsyncRequest;
class XEvent;
namespace fs {
class FileEntry;
}
class XFile : public XObject {
public:
XFile(KernelState* kernel_state, fs::FileEntry* entry);
virtual ~XFile();
XFile(KernelState* kernel_state);
virtual ~XFile();
virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode,
uint32_t alertable, uint64_t* opt_timeout);
@ -41,8 +38,10 @@ public:
X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset,
XAsyncRequest* request);
protected:
// open/read/write/etc
private:
fs::FileEntry* entry_;
XEvent* async_event_;
// TODO(benvanik): create flags, open state, etc.

View File

@ -68,10 +68,9 @@ X_STATUS XModule::LoadFromFile(const char* path) {
XELOGE("Invalid file type: %s", path);
return X_STATUS_NO_SUCH_FILE;
}
fs::FileEntry* fs_file = static_cast<fs::FileEntry*>(fs_entry);
// Map into memory.
fs::MemoryMapping* mmap = fs_file->CreateMemoryMapping(kXEFileModeRead, 0, 0);
fs::MemoryMapping* mmap = fs_entry->CreateMemoryMapping(kXEFileModeRead, 0, 0);
if (!mmap) {
return X_STATUS_UNSUCCESSFUL;
}

View File

@ -77,14 +77,18 @@ SHIM_CALL NtCreateFile_shim(
// Resolve the file using the virtual file system.
FileSystem* fs = state->filesystem();
Entry* entry = fs->ResolvePath(object_name.buffer);
XFile* file = NULL;
if (entry && entry->type() == Entry::kTypeFile) {
// Create file handle wrapper.
FileEntry* file_entry = (FileEntry*)entry;
XFile* file = new XFile(state, file_entry);
// Open the file.
result = entry->Open(state, &file);
} else {
result = X_STATUS_NO_SUCH_FILE;
info = X_FILE_DOES_NOT_EXIST;
}
if (XSUCCEEDED(result)) {
// Handle ref is incremented, so return that.
handle = file->handle();
// TODO(benvanik): open/create/etc.
file->Release();
result = X_STATUS_SUCCESS;
info = X_FILE_OPENED;

View File

@ -84,7 +84,7 @@ int Runtime::LaunchXexFile(const xechar_t* path) {
parent_path[file_name - path] = 0;
// Register the local directory in the virtual filesystem.
result_code = filesystem_->RegisterLocalDirectoryDevice(
result_code = filesystem_->RegisterHostPathDevice(
"\\Device\\Harddisk1\\Partition0", parent_path);
if (result_code) {
XELOGE("Unable to mount local directory");