Postmortem debug target now loads/scans the trace and inits the filesystem.
This commit is contained in:
@@ -9,20 +9,12 @@
|
||||
|
||||
#include <xenia/kernel/fs/device.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
Device::Device(const std::string& path) : path_(path) {}
|
||||
|
||||
Device::Device(const char* path) {
|
||||
path_ = xestrdupa(path);
|
||||
}
|
||||
Device::~Device() {}
|
||||
|
||||
Device::~Device() {
|
||||
xe_free(path_);
|
||||
}
|
||||
|
||||
const char* Device::path() {
|
||||
return path_;
|
||||
}
|
||||
const char* Device::path() const { return path_.c_str(); }
|
||||
|
||||
@@ -10,37 +10,36 @@
|
||||
#ifndef XENIA_KERNEL_FS_DEVICE_H_
|
||||
#define XENIA_KERNEL_FS_DEVICE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/fs/entry.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class Device {
|
||||
public:
|
||||
Device(const char* path);
|
||||
public:
|
||||
Device(const std::string& path);
|
||||
virtual ~Device();
|
||||
|
||||
const char* path();
|
||||
const char* path() const;
|
||||
|
||||
virtual Entry* ResolvePath(const char* path) = 0;
|
||||
|
||||
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) = 0;
|
||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) = 0;
|
||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info,
|
||||
size_t length) = 0;
|
||||
|
||||
protected:
|
||||
char* path_;
|
||||
protected:
|
||||
std::string path_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_DEVICE_H_
|
||||
|
||||
@@ -17,23 +17,17 @@ using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
|
||||
DiscImageDevice::DiscImageDevice(const char* path, const xechar_t* local_path) :
|
||||
Device(path) {
|
||||
local_path_ = xestrdup(local_path);
|
||||
mmap_ = NULL;
|
||||
gdfx_ = NULL;
|
||||
}
|
||||
DiscImageDevice::DiscImageDevice(const std::string& path,
|
||||
const std::wstring& local_path)
|
||||
: Device(path), local_path_(local_path), mmap_(nullptr), gdfx_(nullptr) {}
|
||||
|
||||
DiscImageDevice::~DiscImageDevice() {
|
||||
delete gdfx_;
|
||||
xe_mmap_release(mmap_);
|
||||
xe_free(local_path_);
|
||||
}
|
||||
|
||||
int DiscImageDevice::Init() {
|
||||
mmap_ = xe_mmap_open(kXEFileModeRead, local_path_, 0, 0);
|
||||
mmap_ = xe_mmap_open(kXEFileModeRead, local_path_.c_str(), 0, 0);
|
||||
if (!mmap_) {
|
||||
XELOGE("Disc image could not be mapped");
|
||||
return 1;
|
||||
|
||||
@@ -10,42 +10,40 @@
|
||||
#ifndef XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_
|
||||
#define XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/fs/device.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class GDFX;
|
||||
|
||||
|
||||
class DiscImageDevice : public Device {
|
||||
public:
|
||||
DiscImageDevice(const char* path, const xechar_t* local_path);
|
||||
virtual ~DiscImageDevice();
|
||||
public:
|
||||
DiscImageDevice(const std::string& path, const std::wstring& local_path);
|
||||
~DiscImageDevice() override;
|
||||
|
||||
int Init();
|
||||
|
||||
virtual Entry* ResolvePath(const char* path);
|
||||
Entry* ResolvePath(const char* path) override;
|
||||
|
||||
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length);
|
||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length);
|
||||
X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override;
|
||||
X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info,
|
||||
size_t length) override;
|
||||
|
||||
private:
|
||||
xechar_t* local_path_;
|
||||
private:
|
||||
std::wstring local_path_;
|
||||
xe_mmap_ref mmap_;
|
||||
GDFX* gdfx_;
|
||||
GDFX* gdfx_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_
|
||||
|
||||
@@ -17,15 +17,11 @@ using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
HostPathDevice::HostPathDevice(const std::string& path,
|
||||
const std::wstring& local_path)
|
||||
: Device(path), local_path_(local_path) {}
|
||||
|
||||
HostPathDevice::HostPathDevice(const char* path, const xechar_t* local_path) :
|
||||
Device(path) {
|
||||
local_path_ = xestrdup(local_path);
|
||||
}
|
||||
|
||||
HostPathDevice::~HostPathDevice() {
|
||||
xe_free(local_path_);
|
||||
}
|
||||
HostPathDevice::~HostPathDevice() {}
|
||||
|
||||
Entry* HostPathDevice::ResolvePath(const char* path) {
|
||||
// The filesystem will have stripped our prefix off already, so the path will
|
||||
@@ -42,7 +38,7 @@ Entry* HostPathDevice::ResolvePath(const char* path) {
|
||||
#endif
|
||||
|
||||
xechar_t full_path[poly::max_path];
|
||||
xe_path_join(local_path_, rel_path, full_path, XECOUNT(full_path));
|
||||
xe_path_join(local_path_.c_str(), rel_path, full_path, XECOUNT(full_path));
|
||||
|
||||
// Swap around path separators.
|
||||
if (poly::path_separator != '\\') {
|
||||
|
||||
@@ -10,35 +10,34 @@
|
||||
#ifndef XENIA_KERNEL_FS_DEVICES_HOST_PATH_DEVICE_H_
|
||||
#define XENIA_KERNEL_FS_DEVICES_HOST_PATH_DEVICE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/fs/device.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class HostPathDevice : public Device {
|
||||
public:
|
||||
HostPathDevice(const char* path, const xechar_t* local_path);
|
||||
virtual ~HostPathDevice();
|
||||
public:
|
||||
HostPathDevice(const std::string& path, const std::wstring& local_path);
|
||||
~HostPathDevice() override;
|
||||
|
||||
virtual Entry* ResolvePath(const char* path);
|
||||
Entry* ResolvePath(const char* path) override;
|
||||
|
||||
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length);
|
||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length);
|
||||
X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override;
|
||||
X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info,
|
||||
size_t length) override;
|
||||
|
||||
private:
|
||||
xechar_t* local_path_;
|
||||
private:
|
||||
std::wstring local_path_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_DEVICES_HOST_PATH_DEVICE_H_
|
||||
|
||||
@@ -17,24 +17,17 @@ using namespace xe;
|
||||
using namespace xe::kernel;
|
||||
using namespace xe::kernel::fs;
|
||||
|
||||
|
||||
|
||||
STFSContainerDevice::STFSContainerDevice(
|
||||
const char* path, const xechar_t* local_path) :
|
||||
Device(path) {
|
||||
local_path_ = xestrdup(local_path);
|
||||
mmap_ = NULL;
|
||||
stfs_ = NULL;
|
||||
}
|
||||
STFSContainerDevice::STFSContainerDevice(const std::string& path,
|
||||
const std::wstring& local_path)
|
||||
: Device(path), local_path_(local_path), mmap_(nullptr), stfs_(nullptr) {}
|
||||
|
||||
STFSContainerDevice::~STFSContainerDevice() {
|
||||
delete stfs_;
|
||||
xe_mmap_release(mmap_);
|
||||
xe_free(local_path_);
|
||||
}
|
||||
|
||||
int STFSContainerDevice::Init() {
|
||||
mmap_ = xe_mmap_open(kXEFileModeRead, local_path_, 0, 0);
|
||||
mmap_ = xe_mmap_open(kXEFileModeRead, local_path_.c_str(), 0, 0);
|
||||
if (!mmap_) {
|
||||
XELOGE("STFS container could not be mapped");
|
||||
return 1;
|
||||
|
||||
@@ -10,42 +10,40 @@
|
||||
#ifndef XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_DEVICE_H_
|
||||
#define XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_DEVICE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/kernel/fs/device.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class STFS;
|
||||
|
||||
|
||||
class STFSContainerDevice : public Device {
|
||||
public:
|
||||
STFSContainerDevice(const char* path, const xechar_t* local_path);
|
||||
virtual ~STFSContainerDevice();
|
||||
public:
|
||||
STFSContainerDevice(const std::string& path, const std::wstring& local_path);
|
||||
~STFSContainerDevice() override;
|
||||
|
||||
int Init();
|
||||
|
||||
virtual Entry* ResolvePath(const char* path);
|
||||
Entry* ResolvePath(const char* path) override;
|
||||
|
||||
virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length);
|
||||
virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length);
|
||||
X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override;
|
||||
X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info,
|
||||
size_t length) override;
|
||||
|
||||
private:
|
||||
xechar_t* local_path_;
|
||||
private:
|
||||
std::wstring local_path_;
|
||||
xe_mmap_ref mmap_;
|
||||
STFS* stfs_;
|
||||
STFS* stfs_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_DEVICE_H_
|
||||
|
||||
@@ -33,19 +33,86 @@ FileSystem::~FileSystem() {
|
||||
symlinks_.clear();
|
||||
}
|
||||
|
||||
int FileSystem::RegisterDevice(const char* path, Device* device) {
|
||||
fs::FileSystemType FileSystem::InferType(const std::wstring& local_path) {
|
||||
auto last_dot = local_path.find_last_of('.');
|
||||
if (last_dot == std::wstring::npos) {
|
||||
// Likely an STFS container.
|
||||
return FileSystemType::STFS_TITLE;
|
||||
} else if (local_path.substr(last_dot) == L".xex") {
|
||||
// Treat as a naked xex file.
|
||||
return FileSystemType::XEX_FILE;
|
||||
} else {
|
||||
// Assume a disc image.
|
||||
return FileSystemType::DISC_IMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
int FileSystem::InitializeFromPath(fs::FileSystemType type,
|
||||
const std::wstring& local_path) {
|
||||
switch (type) {
|
||||
case FileSystemType::STFS_TITLE: {
|
||||
// Register the container in the virtual filesystem.
|
||||
int result_code =
|
||||
RegisterSTFSContainerDevice("\\Device\\Cdrom0", local_path);
|
||||
if (result_code) {
|
||||
XELOGE("Unable to mount STFS container");
|
||||
return result_code;
|
||||
}
|
||||
|
||||
// TODO(benvanik): figure out paths.
|
||||
// Create symlinks to the device.
|
||||
CreateSymbolicLink("game:", "\\Device\\Cdrom0");
|
||||
CreateSymbolicLink("d:", "\\Device\\Cdrom0");
|
||||
break;
|
||||
}
|
||||
case FileSystemType::XEX_FILE: {
|
||||
// Get the parent path of the file.
|
||||
auto last_slash = local_path.find_last_of(poly::path_separator);
|
||||
std::wstring parent_path = local_path.substr(0, last_slash);
|
||||
|
||||
// Register the local directory in the virtual filesystem.
|
||||
int result_code = RegisterHostPathDevice(
|
||||
"\\Device\\Harddisk1\\Partition0", parent_path);
|
||||
if (result_code) {
|
||||
XELOGE("Unable to mount local directory");
|
||||
return result_code;
|
||||
}
|
||||
|
||||
// Create symlinks to the device.
|
||||
CreateSymbolicLink("game:", "\\Device\\Harddisk1\\Partition0");
|
||||
CreateSymbolicLink("d:", "\\Device\\Harddisk1\\Partition0");
|
||||
break;
|
||||
}
|
||||
case FileSystemType::DISC_IMAGE: {
|
||||
// Register the disc image in the virtual filesystem.
|
||||
int result_code = RegisterDiscImageDevice("\\Device\\Cdrom0", local_path);
|
||||
if (result_code) {
|
||||
XELOGE("Unable to mount disc image");
|
||||
return result_code;
|
||||
}
|
||||
|
||||
// Create symlinks to the device.
|
||||
CreateSymbolicLink("game:", "\\Device\\Cdrom0");
|
||||
CreateSymbolicLink("d:", "\\Device\\Cdrom0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FileSystem::RegisterDevice(const std::string& path, Device* device) {
|
||||
devices_.push_back(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FileSystem::RegisterHostPathDevice(
|
||||
const char* path, const xechar_t* local_path) {
|
||||
const std::string& path, const std::wstring& local_path) {
|
||||
Device* device = new HostPathDevice(path, local_path);
|
||||
return RegisterDevice(path, device);
|
||||
}
|
||||
|
||||
int FileSystem::RegisterDiscImageDevice(
|
||||
const char* path, const xechar_t* local_path) {
|
||||
const std::string& path, const std::wstring& local_path) {
|
||||
DiscImageDevice* device = new DiscImageDevice(path, local_path);
|
||||
if (device->Init()) {
|
||||
return 1;
|
||||
@@ -54,7 +121,7 @@ int FileSystem::RegisterDiscImageDevice(
|
||||
}
|
||||
|
||||
int FileSystem::RegisterSTFSContainerDevice(
|
||||
const char* path, const xechar_t* local_path) {
|
||||
const std::string& path, const std::wstring& local_path) {
|
||||
STFSContainerDevice* device = new STFSContainerDevice(path, local_path);
|
||||
if (device->Init()) {
|
||||
return 1;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#ifndef XENIA_KERNEL_FS_FILESYSTEM_H_
|
||||
#define XENIA_KERNEL_FS_FILESYSTEM_H_
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
@@ -18,39 +19,46 @@
|
||||
|
||||
#include <xenia/kernel/fs/entry.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace fs {
|
||||
|
||||
|
||||
class Device;
|
||||
|
||||
enum class FileSystemType {
|
||||
STFS_TITLE,
|
||||
DISC_IMAGE,
|
||||
XEX_FILE,
|
||||
};
|
||||
|
||||
class FileSystem {
|
||||
public:
|
||||
public:
|
||||
FileSystem();
|
||||
~FileSystem();
|
||||
|
||||
int RegisterDevice(const char* path, Device* device);
|
||||
int RegisterHostPathDevice(const char* path, const xechar_t* local_path);
|
||||
int RegisterDiscImageDevice(const char* path, const xechar_t* local_path);
|
||||
int RegisterSTFSContainerDevice(const char* path, const xechar_t* local_path);
|
||||
FileSystemType InferType(const std::wstring& local_path);
|
||||
int InitializeFromPath(FileSystemType type, const std::wstring& local_path);
|
||||
|
||||
int RegisterDevice(const std::string& path, Device* device);
|
||||
int RegisterHostPathDevice(const std::string& path,
|
||||
const std::wstring& local_path);
|
||||
int RegisterDiscImageDevice(const std::string& path,
|
||||
const std::wstring& local_path);
|
||||
int RegisterSTFSContainerDevice(const std::string& path,
|
||||
const std::wstring& local_path);
|
||||
|
||||
int CreateSymbolicLink(const char* path, const char* target);
|
||||
int DeleteSymbolicLink(const char* path);
|
||||
|
||||
Entry* ResolvePath(const char* path);
|
||||
|
||||
private:
|
||||
std::vector<Device*> devices_;
|
||||
private:
|
||||
std::vector<Device*> devices_;
|
||||
std::unordered_map<std::string, std::string> symlinks_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace fs
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_KERNEL_FS_FILESYSTEM_H_
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
|
||||
#include <xenia/kernel/xboxkrnl_rtl.h>
|
||||
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
#include <poly/string.h>
|
||||
#include <xenia/kernel/kernel_state.h>
|
||||
#include <xenia/kernel/xboxkrnl_private.h>
|
||||
#include <xenia/kernel/objects/xthread.h>
|
||||
@@ -329,8 +327,7 @@ X_STATUS xeRtlUnicodeStringToAnsiString(uint32_t destination_ptr,
|
||||
|
||||
std::wstring unicode_str = poly::load_and_swap<std::wstring>(
|
||||
IMPL_MEM_ADDR(IMPL_MEM_32(source_ptr + 4)));
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
std::string ansi_str = converter.to_bytes(unicode_str);
|
||||
std::string ansi_str = poly::to_string(unicode_str);
|
||||
if (ansi_str.size() > 0xFFFF - 1) {
|
||||
return X_STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user