From 1a706069049fe59a31ede847068023dc63285be9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 5 Jan 2015 22:32:44 -0800 Subject: [PATCH] QueryFileSystemAttributes/QueryVolume for STFS/ISO. --- src/xenia/kernel/fs/device.cc | 40 ++++++++++++++ src/xenia/kernel/fs/device.h | 4 +- .../kernel/fs/devices/disc_image_device.cc | 11 ---- .../kernel/fs/devices/disc_image_device.h | 4 -- .../kernel/fs/devices/disc_image_entry.cc | 53 +++++++++++-------- .../kernel/fs/devices/host_path_device.cc | 38 ------------- .../kernel/fs/devices/host_path_device.h | 4 -- .../fs/devices/stfs_container_device.cc | 13 +---- .../kernel/fs/devices/stfs_container_device.h | 4 -- .../kernel/fs/devices/stfs_container_entry.cc | 51 ++++++++++-------- 10 files changed, 105 insertions(+), 117 deletions(-) diff --git a/src/xenia/kernel/fs/device.cc b/src/xenia/kernel/fs/device.cc index f4c32a000..bec6f33d1 100644 --- a/src/xenia/kernel/fs/device.cc +++ b/src/xenia/kernel/fs/device.cc @@ -9,6 +9,8 @@ #include +#include + namespace xe { namespace kernel { namespace fs { @@ -17,6 +19,44 @@ Device::Device(const std::string& path) : path_(path) {} Device::~Device() = default; +// TODO(gibbed): call into HostPathDevice? +X_STATUS Device::QueryVolume(XVolumeInfo* out_info, size_t length) { + assert_not_null(out_info); + const char* name = "test"; // TODO(gibbed): actual value + + auto end = (uint8_t*)out_info + length; + size_t name_length = strlen(name); + if (((uint8_t*)&out_info->label[0]) + name_length > end) { + return X_STATUS_BUFFER_OVERFLOW; + } + + out_info->creation_time = 0; + out_info->serial_number = 12345678; + out_info->supports_objects = 0; + out_info->label_length = (uint32_t)name_length; + memcpy(out_info->label, name, name_length); + return X_STATUS_SUCCESS; +} + +// TODO(gibbed): call into HostPathDevice? +X_STATUS Device::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) { + assert_not_null(out_info); + const char* name = "test"; // TODO(gibbed): actual value + + auto end = (uint8_t*)out_info + length; + size_t name_length = strlen(name); + if (((uint8_t*)&out_info->fs_name[0]) + name_length > end) { + return X_STATUS_BUFFER_OVERFLOW; + } + + out_info->attributes = 0; + out_info->maximum_component_name_length = 255; // TODO(gibbed): actual value + out_info->fs_name_length = (uint32_t)name_length; + memcpy(out_info->fs_name, name, name_length); + return X_STATUS_SUCCESS; +} + } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/device.h b/src/xenia/kernel/fs/device.h index 0758aa2f1..f6aa4ab11 100644 --- a/src/xenia/kernel/fs/device.h +++ b/src/xenia/kernel/fs/device.h @@ -29,9 +29,9 @@ class Device { virtual std::unique_ptr ResolvePath(const char* path) = 0; - virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) = 0; + virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length); virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, - size_t length) = 0; + size_t length); protected: std::string path_; diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index 320e1332f..1bbb5a109 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -68,17 +68,6 @@ std::unique_ptr DiscImageDevice::ResolvePath(const char* path) { gdfx_entry); } -X_STATUS DiscImageDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { - assert_always(); - return X_STATUS_NOT_IMPLEMENTED; -} - -X_STATUS DiscImageDevice::QueryFileSystemAttributes( - XFileSystemAttributeInfo* out_info, size_t length) { - assert_always(); - return X_STATUS_NOT_IMPLEMENTED; -} - } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/devices/disc_image_device.h b/src/xenia/kernel/fs/devices/disc_image_device.h index 352a089db..85af80883 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.h +++ b/src/xenia/kernel/fs/devices/disc_image_device.h @@ -32,10 +32,6 @@ class DiscImageDevice : public Device { std::unique_ptr ResolvePath(const char* path) override; - X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; - X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, - size_t length) override; - private: std::wstring local_path_; std::unique_ptr mmap_; diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index 141d4bf89..ea4c90555 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -51,30 +51,41 @@ X_STATUS DiscImageEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, const char* file_name, bool restart) { assert_not_null(out_info); - if (restart == true && gdfx_entry_iterator_ != gdfx_entry_->children.end()) { - gdfx_entry_iterator_ = gdfx_entry_->children.end(); - } - - if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { - gdfx_entry_iterator_ = gdfx_entry_->children.begin(); - if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { - return X_STATUS_UNSUCCESSFUL; + // TODO(benvanik): move to common code. + assert_null(file_name); + GDFXEntry* entry = nullptr; + if (file_name) { + // Specified filename, return just that info. + assert_true(std::strchr(file_name, '*') == nullptr); + entry = gdfx_entry_->GetChild(file_name); + if (!entry) { + return X_STATUS_NO_SUCH_FILE; } } else { - ++gdfx_entry_iterator_; - if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { - return X_STATUS_UNSUCCESSFUL; + if (restart == true && + gdfx_entry_iterator_ != gdfx_entry_->children.end()) { + gdfx_entry_iterator_ = gdfx_entry_->children.end(); } - } - auto end = (uint8_t*)out_info + length; + if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { + gdfx_entry_iterator_ = gdfx_entry_->children.begin(); + if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { + return X_STATUS_UNSUCCESSFUL; + } + } else { + ++gdfx_entry_iterator_; + if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { + return X_STATUS_UNSUCCESSFUL; + } + } - auto entry = *gdfx_entry_iterator_; - auto entry_name = entry->name; - - if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { - gdfx_entry_iterator_ = gdfx_entry_->children.end(); - return X_STATUS_UNSUCCESSFUL; + auto end = (uint8_t*)out_info + length; + entry = *gdfx_entry_iterator_; + auto entry_name = entry->name; + if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { + gdfx_entry_iterator_ = gdfx_entry_->children.end(); + return X_STATUS_NO_MORE_FILES; + } } out_info->next_entry_offset = 0; @@ -86,8 +97,8 @@ X_STATUS DiscImageEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, out_info->end_of_file = entry->size; out_info->allocation_size = 2048; out_info->attributes = (X_FILE_ATTRIBUTES)entry->attributes; - out_info->file_name_length = static_cast(entry_name.size()); - memcpy(out_info->file_name, entry_name.c_str(), entry_name.size()); + out_info->file_name_length = static_cast(entry->name.size()); + memcpy(out_info->file_name, entry->name.c_str(), entry->name.size()); return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index d14852a91..309a389a9 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -41,44 +41,6 @@ std::unique_ptr HostPathDevice::ResolvePath(const char* path) { return std::make_unique(type, this, path, full_path); } -// TODO(gibbed): call into HostPathDevice? -X_STATUS HostPathDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { - assert_not_null(out_info); - const char* name = "test"; // TODO(gibbed): actual value - - auto end = (uint8_t*)out_info + length; - size_t name_length = strlen(name); - if (((uint8_t*)&out_info->label[0]) + name_length > end) { - return X_STATUS_BUFFER_OVERFLOW; - } - - out_info->creation_time = 0; - out_info->serial_number = 12345678; - out_info->supports_objects = 0; - out_info->label_length = (uint32_t)name_length; - memcpy(out_info->label, name, name_length); - return X_STATUS_SUCCESS; -} - -// TODO(gibbed): call into HostPathDevice? -X_STATUS HostPathDevice::QueryFileSystemAttributes( - XFileSystemAttributeInfo* out_info, size_t length) { - assert_not_null(out_info); - const char* name = "test"; // TODO(gibbed): actual value - - auto end = (uint8_t*)out_info + length; - size_t name_length = strlen(name); - if (((uint8_t*)&out_info->fs_name[0]) + name_length > end) { - return X_STATUS_BUFFER_OVERFLOW; - } - - out_info->attributes = 0; - out_info->maximum_component_name_length = 255; // TODO(gibbed): actual value - out_info->fs_name_length = (uint32_t)name_length; - memcpy(out_info->fs_name, name, name_length); - return X_STATUS_SUCCESS; -} - } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/devices/host_path_device.h b/src/xenia/kernel/fs/devices/host_path_device.h index 0af6d8b62..80f618e05 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.h +++ b/src/xenia/kernel/fs/devices/host_path_device.h @@ -26,10 +26,6 @@ class HostPathDevice : public Device { std::unique_ptr ResolvePath(const char* path) override; - X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; - X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, - size_t length) override; - private: std::wstring local_path_; }; diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index c562ea1fa..0704f8b4a 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -12,6 +12,7 @@ #include #include #include +#include namespace xe { namespace kernel { @@ -68,18 +69,6 @@ std::unique_ptr STFSContainerDevice::ResolvePath(const char* path) { stfs_entry); } -X_STATUS STFSContainerDevice::QueryVolume(XVolumeInfo* out_info, - size_t length) { - assert_always(); - return X_STATUS_NOT_IMPLEMENTED; -} - -X_STATUS STFSContainerDevice::QueryFileSystemAttributes( - XFileSystemAttributeInfo* out_info, size_t length) { - assert_always(); - return X_STATUS_NOT_IMPLEMENTED; -} - } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.h b/src/xenia/kernel/fs/devices/stfs_container_device.h index 34568bedd..1f5dd7607 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.h +++ b/src/xenia/kernel/fs/devices/stfs_container_device.h @@ -32,10 +32,6 @@ class STFSContainerDevice : public Device { std::unique_ptr ResolvePath(const char* path) override; - X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; - X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, - size_t length) override; - private: std::wstring local_path_; std::unique_ptr mmap_; diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.cc b/src/xenia/kernel/fs/devices/stfs_container_entry.cc index db6d5ff75..c28cff9e8 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.cc @@ -45,30 +45,39 @@ X_STATUS STFSContainerEntry::QueryDirectory(XDirectoryInfo* out_info, bool restart) { assert_not_null(out_info); - if (restart && stfs_entry_iterator_ != stfs_entry_->children.end()) { - stfs_entry_iterator_ = stfs_entry_->children.end(); - } - - if (stfs_entry_iterator_ == stfs_entry_->children.end()) { - stfs_entry_iterator_ = stfs_entry_->children.begin(); - if (stfs_entry_iterator_ == stfs_entry_->children.end()) { - return X_STATUS_UNSUCCESSFUL; + // TODO(benvanik): move to common code. + STFSEntry* entry = nullptr; + if (file_name) { + // Specified filename, return just that info. + assert_true(std::strchr(file_name, '*') == nullptr); + entry = stfs_entry_->GetChild(file_name); + if (!entry) { + return X_STATUS_NO_SUCH_FILE; } } else { - ++stfs_entry_iterator_; - if (stfs_entry_iterator_ == stfs_entry_->children.end()) { - return X_STATUS_UNSUCCESSFUL; + if (restart && stfs_entry_iterator_ != stfs_entry_->children.end()) { + stfs_entry_iterator_ = stfs_entry_->children.end(); } - } - auto end = (uint8_t*)out_info + length; + if (stfs_entry_iterator_ == stfs_entry_->children.end()) { + stfs_entry_iterator_ = stfs_entry_->children.begin(); + if (stfs_entry_iterator_ == stfs_entry_->children.end()) { + return X_STATUS_UNSUCCESSFUL; + } + } else { + ++stfs_entry_iterator_; + if (stfs_entry_iterator_ == stfs_entry_->children.end()) { + return X_STATUS_UNSUCCESSFUL; + } + } - auto entry = stfs_entry_iterator_->get(); - auto entry_name = entry->name; - - if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { - stfs_entry_iterator_ = stfs_entry_->children.end(); - return X_STATUS_UNSUCCESSFUL; + auto end = (uint8_t*)out_info + length; + entry = stfs_entry_iterator_->get(); + auto entry_name = entry->name; + if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { + stfs_entry_iterator_ = stfs_entry_->children.end(); + return X_STATUS_NO_MORE_FILES; + } } out_info->file_index = 0xCDCDCDCD; @@ -79,8 +88,8 @@ X_STATUS STFSContainerEntry::QueryDirectory(XDirectoryInfo* out_info, out_info->end_of_file = entry->size; out_info->allocation_size = 4096; out_info->attributes = entry->attributes; - out_info->file_name_length = static_cast(entry_name.size()); - memcpy(out_info->file_name, entry_name.c_str(), entry_name.size()); + out_info->file_name_length = static_cast(entry->name.size()); + memcpy(out_info->file_name, entry->name.c_str(), entry->name.size()); return X_STATUS_SUCCESS; }