[VFS] More cleanup in Zarchive loader

This commit is contained in:
Gliniak 2023-09-04 21:09:40 +02:00
parent 9496c04ac5
commit 9554f82c10
6 changed files with 44 additions and 65 deletions

View File

@ -2,7 +2,7 @@
****************************************************************************** ******************************************************************************
* Xenia : Xbox 360 Emulator Research Project * * Xenia : Xbox 360 Emulator Research Project *
****************************************************************************** ******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. * * Copyright 2023 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. * * Released under the BSD license - see LICENSE in the root for more details. *
****************************************************************************** ******************************************************************************
*/ */
@ -19,49 +19,31 @@
namespace xe { namespace xe {
namespace vfs { namespace vfs {
using namespace xe::literals;
const size_t kXESectorSize = 2_KiB;
DiscZarchiveDevice::DiscZarchiveDevice(const std::string_view mount_path, DiscZarchiveDevice::DiscZarchiveDevice(const std::string_view mount_path,
const std::filesystem::path& host_path) const std::filesystem::path& host_path)
: Device(mount_path), : Device(mount_path), name_("GDFX"), host_path_(host_path), reader_() {}
name_("GDFX"),
host_path_(host_path),
opaque_(nullptr) {}
DiscZarchiveDevice::~DiscZarchiveDevice() { DiscZarchiveDevice::~DiscZarchiveDevice(){};
ZArchiveReader* reader = static_cast<ZArchiveReader*>(opaque_);
if (reader != nullptr) {
delete reader;
}
};
bool DiscZarchiveDevice::Initialize() { bool DiscZarchiveDevice::Initialize() {
ZArchiveReader* reader = ZArchiveReader::OpenFromFile(host_path_); reader_ =
std::unique_ptr<ZArchiveReader>(ZArchiveReader::OpenFromFile(host_path_));
if (!reader) { if (!reader_) {
XELOGE("Disc ZArchive could not be opened"); XELOGE("Disc ZArchive could not be opened");
return false; return false;
} }
opaque_ = static_cast<void*>(reader);
bool result = reader->IsFile(reader->LookUp("default.xex", true, false));
if (!result) {
XELOGE("Failed to verify disc ZArchive (no default.xex)");
}
const std::string root_path = std::string("/"); const std::string root_path = std::string("/");
ZArchiveNodeHandle handle = reader->LookUp(root_path); const ZArchiveNodeHandle handle = reader_->LookUp(root_path);
auto root_entry = new DiscZarchiveEntry(this, nullptr, root_path, reader); auto root_entry = new DiscZarchiveEntry(this, nullptr, root_path);
root_entry->attributes_ = kFileAttributeDirectory; root_entry->attributes_ = kFileAttributeDirectory;
root_entry->handle_ = static_cast<uint32_t>(handle); root_entry->handle_ = static_cast<uint32_t>(handle);
root_entry->name_ = root_path; root_entry->name_ = root_path;
root_entry->absolute_path_ = root_path; root_entry->absolute_path_ = root_path;
root_entry_ = std::unique_ptr<Entry>(root_entry); root_entry_ = std::unique_ptr<Entry>(root_entry);
result = ReadAllEntries(reader, "", root_entry, nullptr);
return result; return ReadAllEntries("", root_entry, nullptr);
} }
void DiscZarchiveDevice::Dump(StringBuffer* string_buffer) { void DiscZarchiveDevice::Dump(StringBuffer* string_buffer) {
@ -75,12 +57,11 @@ Entry* DiscZarchiveDevice::ResolvePath(const std::string_view path) {
// some\PATH.foo // some\PATH.foo
XELOGFS("DiscZarchiveDevice::ResolvePath({})", path); XELOGFS("DiscZarchiveDevice::ResolvePath({})", path);
ZArchiveReader* reader = static_cast<ZArchiveReader*>(opaque_); if (!reader_) {
if (!reader) {
return nullptr; return nullptr;
} }
ZArchiveNodeHandle handle = reader->LookUp(path); const ZArchiveNodeHandle handle = reader_->LookUp(path);
if (handle == ZARCHIVE_INVALID_NODE) { if (handle == ZARCHIVE_INVALID_NODE) {
return nullptr; return nullptr;
} }
@ -88,18 +69,17 @@ Entry* DiscZarchiveDevice::ResolvePath(const std::string_view path) {
return root_entry_->ResolvePath(path); return root_entry_->ResolvePath(path);
} }
bool DiscZarchiveDevice::ReadAllEntries(void* opaque, const std::string& path, bool DiscZarchiveDevice::ReadAllEntries(const std::string& path,
DiscZarchiveEntry* node, DiscZarchiveEntry* node,
DiscZarchiveEntry* parent) { DiscZarchiveEntry* parent) {
ZArchiveReader* reader = static_cast<ZArchiveReader*>(opaque); const ZArchiveNodeHandle handle = node->handle_;
ZArchiveNodeHandle handle = node->handle_;
if (handle == ZARCHIVE_INVALID_NODE) { if (handle == ZARCHIVE_INVALID_NODE) {
return false; return false;
} }
if (reader->IsFile(handle)) { if (reader_->IsFile(handle)) {
auto entry = new DiscZarchiveEntry(this, parent, path, opaque); auto entry = new DiscZarchiveEntry(this, parent, path);
entry->attributes_ = kFileAttributeReadOnly; entry->attributes_ = kFileAttributeReadOnly;
entry->handle_ = static_cast<uint32_t>(handle); entry->handle_ = static_cast<uint32_t>(handle);
entry->parent_ = parent; entry->parent_ = parent;
@ -107,23 +87,23 @@ bool DiscZarchiveDevice::ReadAllEntries(void* opaque, const std::string& path,
return true; return true;
} }
if (reader->IsDirectory(handle)) { if (reader_->IsDirectory(handle)) {
const uint32_t count = reader->GetDirEntryCount(handle); const uint32_t count = reader_->GetDirEntryCount(handle);
for (uint32_t i = 0; i < count; i++) { for (uint32_t i = 0; i < count; i++) {
ZArchiveReader::DirEntry dirEntry; ZArchiveReader::DirEntry dirEntry;
if (!reader->GetDirEntry(handle, i, dirEntry)) { if (!reader_->GetDirEntry(handle, i, dirEntry)) {
XELOGE("Invalid ZArchive directory! Skipping loading"); XELOGE("Invalid ZArchive directory! Skipping loading");
return false; return false;
} }
const std::string full_path = path + std::string(dirEntry.name); const std::string full_path = path + std::string(dirEntry.name);
ZArchiveNodeHandle fileHandle = reader->LookUp(full_path); const ZArchiveNodeHandle fileHandle = reader_->LookUp(full_path);
if (handle == ZARCHIVE_INVALID_NODE) { if (fileHandle == ZARCHIVE_INVALID_NODE) {
return false; return false;
} }
auto entry = new DiscZarchiveEntry(this, parent, full_path, opaque); auto entry = new DiscZarchiveEntry(this, parent, full_path);
entry->handle_ = static_cast<uint32_t>(fileHandle); entry->handle_ = static_cast<uint32_t>(fileHandle);
entry->data_offset_ = 0; entry->data_offset_ = 0;
@ -133,17 +113,16 @@ bool DiscZarchiveDevice::ReadAllEntries(void* opaque, const std::string& path,
entry->write_timestamp_ = 10000 * 11644473600000LL; entry->write_timestamp_ = 10000 * 11644473600000LL;
entry->parent_ = node; entry->parent_ = node;
if (dirEntry.isDirectory) { if (dirEntry.isDirectory) {
entry->data_size_ = 0; entry->data_size_ = 0;
entry->size_ = dirEntry.size; entry->size_ = dirEntry.size;
entry->attributes_ = kFileAttributeDirectory | kFileAttributeReadOnly; entry->attributes_ = kFileAttributeDirectory | kFileAttributeReadOnly;
node->children_.push_back(std::unique_ptr<Entry>(entry)); node->children_.push_back(std::unique_ptr<Entry>(entry));
if (!ReadAllEntries(reader, full_path + "\\", entry, node)) { if (!ReadAllEntries(full_path + "\\", entry, node)) {
return false; return false;
} }
} else if (dirEntry.isFile) { } else if (dirEntry.isFile) {
entry->data_size_ = entry->size_ = reader->GetFileSize(fileHandle); entry->data_size_ = entry->size_ = reader_->GetFileSize(fileHandle);
entry->attributes_ = kFileAttributeReadOnly; entry->attributes_ = kFileAttributeReadOnly;
entry->allocation_size_ = entry->allocation_size_ =
xe::round_up(entry->size_, bytes_per_sector()); xe::round_up(entry->size_, bytes_per_sector());

View File

@ -2,7 +2,7 @@
****************************************************************************** ******************************************************************************
* Xenia : Xbox 360 Emulator Research Project * * Xenia : Xbox 360 Emulator Research Project *
****************************************************************************** ******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. * * Copyright 2023 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. * * Released under the BSD license - see LICENSE in the root for more details. *
****************************************************************************** ******************************************************************************
*/ */
@ -16,6 +16,8 @@
#include "xenia/base/mapped_memory.h" #include "xenia/base/mapped_memory.h"
#include "xenia/vfs/device.h" #include "xenia/vfs/device.h"
#include "third_party/zarchive/include/zarchive/zarchivereader.h"
namespace xe { namespace xe {
namespace vfs { namespace vfs {
@ -40,14 +42,16 @@ class DiscZarchiveDevice : public Device {
uint32_t sectors_per_allocation_unit() const override { return 1; } uint32_t sectors_per_allocation_unit() const override { return 1; }
uint32_t bytes_per_sector() const override { return 0x200; } uint32_t bytes_per_sector() const override { return 0x200; }
ZArchiveReader* reader() const { return reader_.get(); }
private: private:
bool ReadAllEntries(void* opaque, const std::string& path, bool ReadAllEntries(const std::string& path, DiscZarchiveEntry* node,
DiscZarchiveEntry* node, DiscZarchiveEntry* parent); DiscZarchiveEntry* parent);
std::string name_; std::string name_;
std::filesystem::path host_path_; std::filesystem::path host_path_;
std::unique_ptr<Entry> root_entry_; std::unique_ptr<Entry> root_entry_;
void* opaque_; std::unique_ptr<ZArchiveReader> reader_;
}; };
} // namespace vfs } // namespace vfs

View File

@ -15,13 +15,13 @@
#include "xenia/vfs/devices/disc_zarchive_file.h" #include "xenia/vfs/devices/disc_zarchive_file.h"
#include "third_party/zarchive/include/zarchive/zarchivereader.h" #include "third_party/zarchive/include/zarchive/zarchivereader.h"
namespace xe { namespace xe {
namespace vfs { namespace vfs {
DiscZarchiveEntry::DiscZarchiveEntry(Device* device, Entry* parent, DiscZarchiveEntry::DiscZarchiveEntry(Device* device, Entry* parent,
const std::string_view path, void* opaque) const std::string_view path)
: Entry(device, parent, path), : Entry(device, parent, path),
opaque_(opaque),
data_offset_(0), data_offset_(0),
data_size_(0), data_size_(0),
handle_(ZARCHIVE_INVALID_NODE) {} handle_(ZARCHIVE_INVALID_NODE) {}
@ -29,10 +29,9 @@ DiscZarchiveEntry::DiscZarchiveEntry(Device* device, Entry* parent,
DiscZarchiveEntry::~DiscZarchiveEntry() = default; DiscZarchiveEntry::~DiscZarchiveEntry() = default;
std::unique_ptr<DiscZarchiveEntry> DiscZarchiveEntry::Create( std::unique_ptr<DiscZarchiveEntry> DiscZarchiveEntry::Create(
Device* device, Entry* parent, const std::string_view name, void* opaque) { Device* device, Entry* parent, const std::string_view name) {
auto path = name; // xe::utf8::join_guest_paths(parent->path(), name); auto path = name; // xe::utf8::join_guest_paths(parent->path(), name);
auto entry = auto entry = std::make_unique<DiscZarchiveEntry>(device, parent, path);
std::make_unique<DiscZarchiveEntry>(device, parent, path, opaque);
return std::move(entry); return std::move(entry);
} }

View File

@ -2,7 +2,7 @@
****************************************************************************** ******************************************************************************
* Xenia : Xbox 360 Emulator Research Project * * Xenia : Xbox 360 Emulator Research Project *
****************************************************************************** ******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. * * Copyright 2023 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. * * Released under the BSD license - see LICENSE in the root for more details. *
****************************************************************************** ******************************************************************************
*/ */
@ -23,14 +23,12 @@ class DiscZarchiveDevice;
class DiscZarchiveEntry : public Entry { class DiscZarchiveEntry : public Entry {
public: public:
DiscZarchiveEntry(Device* device, Entry* parent, const std::string_view path, DiscZarchiveEntry(Device* device, Entry* parent, const std::string_view path);
void* opaque);
~DiscZarchiveEntry() override; ~DiscZarchiveEntry() override;
static std::unique_ptr<DiscZarchiveEntry> Create(Device* device, static std::unique_ptr<DiscZarchiveEntry> Create(Device* device,
Entry* parent, Entry* parent,
const std::string_view name, const std::string_view name);
void* opaque);
MappedMemory* mmap() const { return nullptr; } MappedMemory* mmap() const { return nullptr; }
size_t data_offset() const { return data_offset_; } size_t data_offset() const { return data_offset_; }
@ -47,7 +45,6 @@ class DiscZarchiveEntry : public Entry {
friend class DiscZarchiveDevice; friend class DiscZarchiveDevice;
friend class DiscZarchiveFile; friend class DiscZarchiveFile;
void* opaque_;
uint32_t handle_; uint32_t handle_;
size_t data_offset_; size_t data_offset_;
size_t data_size_; size_t data_size_;

View File

@ -2,7 +2,7 @@
****************************************************************************** ******************************************************************************
* Xenia : Xbox 360 Emulator Research Project * * Xenia : Xbox 360 Emulator Research Project *
****************************************************************************** ******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. * * Copyright 2023 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. * * Released under the BSD license - see LICENSE in the root for more details. *
****************************************************************************** ******************************************************************************
*/ */
@ -11,10 +11,9 @@
#include <algorithm> #include <algorithm>
#include "xenia/vfs/devices/disc_zarchive_device.h"
#include "xenia/vfs/devices/disc_zarchive_entry.h" #include "xenia/vfs/devices/disc_zarchive_entry.h"
#include "third_party/zarchive/include/zarchive/zarchivereader.h"
namespace xe { namespace xe {
namespace vfs { namespace vfs {
@ -32,9 +31,10 @@ X_STATUS DiscZarchiveFile::ReadSync(void* buffer, size_t buffer_length,
if (byte_offset >= entry_->size()) { if (byte_offset >= entry_->size()) {
return X_STATUS_END_OF_FILE; return X_STATUS_END_OF_FILE;
} }
ZArchiveReader* reader = static_cast<ZArchiveReader*>(entry_->opaque_);
const uint64_t bytes_read = const uint64_t bytes_read =
reader->ReadFromFile(entry_->handle_, byte_offset, buffer_length, buffer); ((DiscZarchiveDevice*)entry_->device_)
->reader()
->ReadFromFile(entry_->handle_, byte_offset, buffer_length, buffer);
const size_t real_length = const size_t real_length =
std::min(buffer_length, entry_->data_size() - byte_offset); std::min(buffer_length, entry_->data_size() - byte_offset);
*out_bytes_read = real_length; *out_bytes_read = real_length;

View File

@ -2,7 +2,7 @@
****************************************************************************** ******************************************************************************
* Xenia : Xbox 360 Emulator Research Project * * Xenia : Xbox 360 Emulator Research Project *
****************************************************************************** ******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. * * Copyright 2023 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. * * Released under the BSD license - see LICENSE in the root for more details. *
****************************************************************************** ******************************************************************************
*/ */