[VFS] Make ResolvePath / Dump virtual

This commit is contained in:
Dr. Chat 2018-05-26 18:43:07 -05:00
parent 9231317eeb
commit 728ed593ad
8 changed files with 90 additions and 31 deletions

View File

@ -15,33 +15,7 @@ namespace xe {
namespace vfs { namespace vfs {
Device::Device(const std::string& mount_path) : mount_path_(mount_path) {} Device::Device(const std::string& mount_path) : mount_path_(mount_path) {}
Device::~Device() = default; 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 vfs
} // namespace xe } // namespace xe

View File

@ -26,13 +26,12 @@ class Device {
virtual ~Device(); virtual ~Device();
virtual bool Initialize() = 0; virtual bool Initialize() = 0;
void Dump(StringBuffer* string_buffer);
const std::string& mount_path() const { return mount_path_; } const std::string& mount_path() const { return mount_path_; }
virtual bool is_read_only() const { return true; } 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 total_allocation_units() const = 0;
virtual uint32_t available_allocation_units() const = 0; virtual uint32_t available_allocation_units() const = 0;
@ -42,7 +41,6 @@ class Device {
protected: protected:
xe::global_critical_region global_critical_region_; xe::global_critical_region global_critical_region_;
std::string mount_path_; std::string mount_path_;
std::unique_ptr<Entry> root_entry_;
}; };
} // namespace vfs } // namespace vfs

View File

@ -49,6 +49,32 @@ bool DiscImageDevice::Initialize() {
return true; 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) { DiscImageDevice::Error DiscImageDevice::Verify(ParseState* state) {
// Find sector 32 of the game partition - try at a few points. // Find sector 32 of the game partition - try at a few points.
static const size_t likely_offsets[] = { static const size_t likely_offsets[] = {

View File

@ -28,6 +28,8 @@ class DiscImageDevice : public Device {
~DiscImageDevice() override; ~DiscImageDevice() override;
bool Initialize() override; bool Initialize() override;
void Dump(StringBuffer* string_buffer) override;
Entry* ResolvePath(std::string path) override;
uint32_t total_allocation_units() const override { uint32_t total_allocation_units() const override {
return uint32_t(mmap_->size() / sectors_per_allocation_unit() / return uint32_t(mmap_->size() / sectors_per_allocation_unit() /
@ -47,6 +49,7 @@ class DiscImageDevice : public Device {
}; };
std::wstring local_path_; std::wstring local_path_;
std::unique_ptr<Entry> root_entry_;
std::unique_ptr<MappedMemory> mmap_; std::unique_ptr<MappedMemory> mmap_;
typedef struct { typedef struct {

View File

@ -43,6 +43,32 @@ bool HostPathDevice::Initialize() {
return true; 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) { void HostPathDevice::PopulateEntry(HostPathEntry* parent_entry) {
auto child_infos = xe::filesystem::ListFiles(parent_entry->local_path()); auto child_infos = xe::filesystem::ListFiles(parent_entry->local_path());
for (auto& child_info : child_infos) { for (auto& child_info : child_infos) {

View File

@ -26,6 +26,8 @@ class HostPathDevice : public Device {
~HostPathDevice() override; ~HostPathDevice() override;
bool Initialize() 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_; } bool is_read_only() const override { return read_only_; }
@ -38,6 +40,7 @@ class HostPathDevice : public Device {
void PopulateEntry(HostPathEntry* parent_entry); void PopulateEntry(HostPathEntry* parent_entry);
std::wstring local_path_; std::wstring local_path_;
std::unique_ptr<Entry> root_entry_;
bool read_only_; bool read_only_;
}; };

View File

@ -126,6 +126,32 @@ bool StfsContainerDevice::Initialize() {
return true; 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( StfsContainerDevice::Error StfsContainerDevice::ReadHeaderAndVerify(
const uint8_t* map_ptr) { const uint8_t* map_ptr) {
// Check signature. // Check signature.
@ -133,7 +159,7 @@ StfsContainerDevice::Error StfsContainerDevice::ReadHeaderAndVerify(
package_type_ = StfsPackageType::kLive; package_type_ = StfsPackageType::kLive;
} else if (memcmp(map_ptr, "PIRS", 4) == 0) { } else if (memcmp(map_ptr, "PIRS", 4) == 0) {
package_type_ = StfsPackageType::kPirs; package_type_ = StfsPackageType::kPirs;
} else if (memcmp(map_ptr, "CON", 3) == 0) { } else if (memcmp(map_ptr, "CON ", 4) == 0) {
package_type_ = StfsPackageType::kCon; package_type_ = StfsPackageType::kCon;
} else { } else {
// Unexpected format. // Unexpected format.

View File

@ -129,6 +129,8 @@ class StfsContainerDevice : public Device {
~StfsContainerDevice() override; ~StfsContainerDevice() override;
bool Initialize() override; bool Initialize() override;
void Dump(StringBuffer* string_buffer) override;
Entry* ResolvePath(std::string path) override;
uint32_t total_allocation_units() const override { uint32_t total_allocation_units() const override {
return uint32_t(mmap_->size() / sectors_per_allocation_unit() / return uint32_t(mmap_->size() / sectors_per_allocation_unit() /
@ -163,6 +165,7 @@ class StfsContainerDevice : public Device {
std::wstring local_path_; std::wstring local_path_;
std::unique_ptr<MappedMemory> mmap_; std::unique_ptr<MappedMemory> mmap_;
std::unique_ptr<Entry> root_entry_;
StfsPackageType package_type_; StfsPackageType package_type_;
StfsHeader header_; StfsHeader header_;
uint32_t table_size_shift_; uint32_t table_size_shift_;