From 728ed593ade734eac8a034b496237c1a55fd25dc Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sat, 26 May 2018 18:43:07 -0500 Subject: [PATCH] [VFS] Make ResolvePath / Dump virtual --- src/xenia/vfs/device.cc | 26 ----------------- src/xenia/vfs/device.h | 6 ++-- src/xenia/vfs/devices/disc_image_device.cc | 26 +++++++++++++++++ src/xenia/vfs/devices/disc_image_device.h | 3 ++ src/xenia/vfs/devices/host_path_device.cc | 26 +++++++++++++++++ src/xenia/vfs/devices/host_path_device.h | 3 ++ .../vfs/devices/stfs_container_device.cc | 28 ++++++++++++++++++- src/xenia/vfs/devices/stfs_container_device.h | 3 ++ 8 files changed, 90 insertions(+), 31 deletions(-) diff --git a/src/xenia/vfs/device.cc b/src/xenia/vfs/device.cc index 0f5d3aa08..8531e46a4 100644 --- a/src/xenia/vfs/device.cc +++ b/src/xenia/vfs/device.cc @@ -15,33 +15,7 @@ namespace xe { namespace vfs { Device::Device(const std::string& mount_path) : mount_path_(mount_path) {} - Device::~Device() = default; -void Device::Dump(StringBuffer* string_buffer) { - auto global_lock = global_critical_region_.Acquire(); - root_entry_->Dump(string_buffer, 0); -} - -Entry* Device::ResolvePath(std::string path) { - // The filesystem will have stripped our prefix off already, so the path will - // be in the form: - // some\PATH.foo - - XELOGFS("Device::ResolvePath(%s)", path.c_str()); - - // Walk the path, one separator at a time. - auto entry = root_entry_.get(); - auto path_parts = xe::split_path(path); - for (auto& part : path_parts) { - entry = entry->GetChild(part); - if (!entry) { - // Not found. - return nullptr; - } - } - return entry; -} - } // namespace vfs } // namespace xe diff --git a/src/xenia/vfs/device.h b/src/xenia/vfs/device.h index b317891d7..b5f1ed6cb 100644 --- a/src/xenia/vfs/device.h +++ b/src/xenia/vfs/device.h @@ -26,13 +26,12 @@ class Device { virtual ~Device(); virtual bool Initialize() = 0; - void Dump(StringBuffer* string_buffer); const std::string& mount_path() const { return mount_path_; } - virtual bool is_read_only() const { return true; } - Entry* ResolvePath(std::string path); + virtual void Dump(StringBuffer* string_buffer) = 0; + virtual Entry* ResolvePath(std::string path) = 0; virtual uint32_t total_allocation_units() const = 0; virtual uint32_t available_allocation_units() const = 0; @@ -42,7 +41,6 @@ class Device { protected: xe::global_critical_region global_critical_region_; std::string mount_path_; - std::unique_ptr root_entry_; }; } // namespace vfs diff --git a/src/xenia/vfs/devices/disc_image_device.cc b/src/xenia/vfs/devices/disc_image_device.cc index 9db2def38..613cafb92 100644 --- a/src/xenia/vfs/devices/disc_image_device.cc +++ b/src/xenia/vfs/devices/disc_image_device.cc @@ -49,6 +49,32 @@ bool DiscImageDevice::Initialize() { return true; } +void DiscImageDevice::Dump(StringBuffer* string_buffer) { + auto global_lock = global_critical_region_.Acquire(); + root_entry_->Dump(string_buffer, 0); +} + +Entry* DiscImageDevice::ResolvePath(std::string path) { + // The filesystem will have stripped our prefix off already, so the path will + // be in the form: + // some\PATH.foo + + XELOGFS("DiscImageDevice::ResolvePath(%s)", path.c_str()); + + // Walk the path, one separator at a time. + auto entry = root_entry_.get(); + auto path_parts = xe::split_path(path); + for (auto& part : path_parts) { + entry = entry->GetChild(part); + if (!entry) { + // Not found. + return nullptr; + } + } + + return entry; +} + DiscImageDevice::Error DiscImageDevice::Verify(ParseState* state) { // Find sector 32 of the game partition - try at a few points. static const size_t likely_offsets[] = { diff --git a/src/xenia/vfs/devices/disc_image_device.h b/src/xenia/vfs/devices/disc_image_device.h index 66b4b1831..8b3273947 100644 --- a/src/xenia/vfs/devices/disc_image_device.h +++ b/src/xenia/vfs/devices/disc_image_device.h @@ -28,6 +28,8 @@ class DiscImageDevice : public Device { ~DiscImageDevice() override; bool Initialize() override; + void Dump(StringBuffer* string_buffer) override; + Entry* ResolvePath(std::string path) override; uint32_t total_allocation_units() const override { return uint32_t(mmap_->size() / sectors_per_allocation_unit() / @@ -47,6 +49,7 @@ class DiscImageDevice : public Device { }; std::wstring local_path_; + std::unique_ptr root_entry_; std::unique_ptr mmap_; typedef struct { diff --git a/src/xenia/vfs/devices/host_path_device.cc b/src/xenia/vfs/devices/host_path_device.cc index 2d7107fa8..1347cd8ec 100644 --- a/src/xenia/vfs/devices/host_path_device.cc +++ b/src/xenia/vfs/devices/host_path_device.cc @@ -43,6 +43,32 @@ bool HostPathDevice::Initialize() { return true; } +void HostPathDevice::Dump(StringBuffer* string_buffer) { + auto global_lock = global_critical_region_.Acquire(); + root_entry_->Dump(string_buffer, 0); +} + +Entry* HostPathDevice::ResolvePath(std::string 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.c_str()); + + // Walk the path, one separator at a time. + auto entry = root_entry_.get(); + auto path_parts = xe::split_path(path); + for (auto& part : path_parts) { + entry = entry->GetChild(part); + if (!entry) { + // Not found. + return nullptr; + } + } + + return entry; +} + void HostPathDevice::PopulateEntry(HostPathEntry* parent_entry) { auto child_infos = xe::filesystem::ListFiles(parent_entry->local_path()); for (auto& child_info : child_infos) { diff --git a/src/xenia/vfs/devices/host_path_device.h b/src/xenia/vfs/devices/host_path_device.h index 248ee324a..751092b91 100644 --- a/src/xenia/vfs/devices/host_path_device.h +++ b/src/xenia/vfs/devices/host_path_device.h @@ -26,6 +26,8 @@ class HostPathDevice : public Device { ~HostPathDevice() override; bool Initialize() override; + void Dump(StringBuffer* string_buffer) override; + Entry* ResolvePath(std::string path) override; bool is_read_only() const override { return read_only_; } @@ -38,6 +40,7 @@ class HostPathDevice : public Device { void PopulateEntry(HostPathEntry* parent_entry); std::wstring local_path_; + std::unique_ptr root_entry_; bool read_only_; }; diff --git a/src/xenia/vfs/devices/stfs_container_device.cc b/src/xenia/vfs/devices/stfs_container_device.cc index 09bc1dd3d..6e8867809 100644 --- a/src/xenia/vfs/devices/stfs_container_device.cc +++ b/src/xenia/vfs/devices/stfs_container_device.cc @@ -126,6 +126,32 @@ bool StfsContainerDevice::Initialize() { return true; } +void StfsContainerDevice::Dump(StringBuffer* string_buffer) { + auto global_lock = global_critical_region_.Acquire(); + root_entry_->Dump(string_buffer, 0); +} + +Entry* StfsContainerDevice::ResolvePath(std::string path) { + // The filesystem will have stripped our prefix off already, so the path will + // be in the form: + // some\PATH.foo + + XELOGFS("StfsContainerDevice::ResolvePath(%s)", path.c_str()); + + // Walk the path, one separator at a time. + auto entry = root_entry_.get(); + auto path_parts = xe::split_path(path); + for (auto& part : path_parts) { + entry = entry->GetChild(part); + if (!entry) { + // Not found. + return nullptr; + } + } + + return entry; +} + StfsContainerDevice::Error StfsContainerDevice::ReadHeaderAndVerify( const uint8_t* map_ptr) { // Check signature. @@ -133,7 +159,7 @@ StfsContainerDevice::Error StfsContainerDevice::ReadHeaderAndVerify( package_type_ = StfsPackageType::kLive; } else if (memcmp(map_ptr, "PIRS", 4) == 0) { package_type_ = StfsPackageType::kPirs; - } else if (memcmp(map_ptr, "CON", 3) == 0) { + } else if (memcmp(map_ptr, "CON ", 4) == 0) { package_type_ = StfsPackageType::kCon; } else { // Unexpected format. diff --git a/src/xenia/vfs/devices/stfs_container_device.h b/src/xenia/vfs/devices/stfs_container_device.h index 8364ba816..a284dd0ef 100644 --- a/src/xenia/vfs/devices/stfs_container_device.h +++ b/src/xenia/vfs/devices/stfs_container_device.h @@ -129,6 +129,8 @@ class StfsContainerDevice : public Device { ~StfsContainerDevice() override; bool Initialize() override; + void Dump(StringBuffer* string_buffer) override; + Entry* ResolvePath(std::string path) override; uint32_t total_allocation_units() const override { return uint32_t(mmap_->size() / sectors_per_allocation_unit() / @@ -163,6 +165,7 @@ class StfsContainerDevice : public Device { std::wstring local_path_; std::unique_ptr mmap_; + std::unique_ptr root_entry_; StfsPackageType package_type_; StfsHeader header_; uint32_t table_size_shift_;