Reworking file system so that it's easier to implement file operations.
This commit is contained in:
parent
1808af26b1
commit
ab5b9d75e0
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;*/
|
|
@ -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_
|
|
@ -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() {
|
||||
}
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -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() {
|
||||
}
|
|
@ -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_
|
|
@ -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;
|
||||
}
|
|
@ -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',
|
||||
],
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue