@@ -89,7 +89,7 @@ bool DiscImageDevice::VerifyMagic(ParseState& state, size_t offset) {
|
||||
|
||||
DiscImageDevice::Error DiscImageDevice::ReadAllEntries(
|
||||
ParseState& state, const uint8_t* root_buffer) {
|
||||
auto root_entry = new DiscImageEntry(this, "", mmap_.get());
|
||||
auto root_entry = new DiscImageEntry(this, nullptr, "", mmap_.get());
|
||||
root_entry->attributes_ = kFileAttributeDirectory;
|
||||
root_entry_ = std::unique_ptr<Entry>(root_entry);
|
||||
|
||||
@@ -117,8 +117,8 @@ bool DiscImageDevice::ReadEntry(ParseState& state, const uint8_t* buffer,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto entry =
|
||||
new DiscImageEntry(this, std::string(name, name_length), mmap_.get());
|
||||
auto entry = new DiscImageEntry(this, parent, std::string(name, name_length),
|
||||
mmap_.get());
|
||||
entry->attributes_ = attributes | kFileAttributeReadOnly;
|
||||
entry->size_ = length;
|
||||
entry->allocation_size_ = xe::round_up(length, bytes_per_sector());
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
DiscImageEntry::DiscImageEntry(Device* device, std::string path,
|
||||
DiscImageEntry::DiscImageEntry(Device* device, Entry* parent, std::string path,
|
||||
MappedMemory* mmap)
|
||||
: Entry(device, path), mmap_(mmap), data_offset_(0), data_size_(0) {}
|
||||
: Entry(device, parent, path),
|
||||
mmap_(mmap),
|
||||
data_offset_(0),
|
||||
data_size_(0) {}
|
||||
|
||||
DiscImageEntry::~DiscImageEntry() = default;
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ class DiscImageDevice;
|
||||
|
||||
class DiscImageEntry : public Entry {
|
||||
public:
|
||||
DiscImageEntry(Device* device, std::string path, MappedMemory* mmap);
|
||||
DiscImageEntry(Device* device, Entry* parent, std::string path,
|
||||
MappedMemory* mmap);
|
||||
~DiscImageEntry() override;
|
||||
|
||||
MappedMemory* mmap() const { return mmap_; }
|
||||
|
||||
@@ -35,7 +35,7 @@ bool HostPathDevice::Initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
auto root_entry = new HostPathEntry(this, "", local_path_);
|
||||
auto root_entry = new HostPathEntry(this, nullptr, "", local_path_);
|
||||
root_entry->attributes_ = kFileAttributeDirectory;
|
||||
root_entry_ = std::unique_ptr<Entry>(root_entry);
|
||||
PopulateEntry(root_entry);
|
||||
@@ -43,12 +43,12 @@ bool HostPathDevice::Initialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void HostPathDevice::PopulateEntry(HostPathEntry* entry) {
|
||||
auto child_infos = xe::filesystem::ListFiles(entry->local_path());
|
||||
void HostPathDevice::PopulateEntry(HostPathEntry* parent_entry) {
|
||||
auto child_infos = xe::filesystem::ListFiles(parent_entry->local_path());
|
||||
for (auto& child_info : child_infos) {
|
||||
auto child =
|
||||
new HostPathEntry(this, xe::to_string(child_info.name),
|
||||
xe::join_paths(entry->local_path(), child_info.name));
|
||||
auto child = new HostPathEntry(
|
||||
this, parent_entry, xe::to_string(child_info.name),
|
||||
xe::join_paths(parent_entry->local_path(), child_info.name));
|
||||
child->create_timestamp_ = child_info.create_timestamp;
|
||||
child->access_timestamp_ = child_info.access_timestamp;
|
||||
child->write_timestamp_ = child_info.write_timestamp;
|
||||
@@ -65,7 +65,7 @@ void HostPathDevice::PopulateEntry(HostPathEntry* entry) {
|
||||
xe::round_up(child_info.total_size, bytes_per_sector());
|
||||
}
|
||||
|
||||
entry->children_.push_back(std::unique_ptr<Entry>(child));
|
||||
parent_entry->children_.push_back(std::unique_ptr<Entry>(child));
|
||||
|
||||
if (child_info.type == xe::filesystem::FileInfo::Type::kDirectory) {
|
||||
PopulateEntry(child);
|
||||
|
||||
@@ -35,7 +35,7 @@ class HostPathDevice : public Device {
|
||||
uint32_t bytes_per_sector() const override { return 2 * 1024; }
|
||||
|
||||
private:
|
||||
void PopulateEntry(HostPathEntry* entry);
|
||||
void PopulateEntry(HostPathEntry* parent_entry);
|
||||
|
||||
std::wstring local_path_;
|
||||
bool read_only_;
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
HostPathEntry::HostPathEntry(Device* device, std::string path,
|
||||
HostPathEntry::HostPathEntry(Device* device, Entry* parent, std::string path,
|
||||
const std::wstring& local_path)
|
||||
: Entry(device, path), local_path_(local_path) {}
|
||||
: Entry(device, parent, path), local_path_(local_path) {}
|
||||
|
||||
HostPathEntry::~HostPathEntry() = default;
|
||||
|
||||
@@ -49,9 +49,9 @@ X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, bool async,
|
||||
}
|
||||
DWORD flags_and_attributes = async ? FILE_FLAG_OVERLAPPED : 0;
|
||||
HANDLE file =
|
||||
CreateFile(local_path_.c_str(), desired_access, share_mode, NULL,
|
||||
creation_disposition,
|
||||
flags_and_attributes | FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
CreateFileW(local_path_.c_str(), desired_access, share_mode, NULL,
|
||||
creation_disposition,
|
||||
flags_and_attributes | FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
// TODO(benvanik): pick correct response.
|
||||
return X_STATUS_NO_SUCH_FILE;
|
||||
|
||||
@@ -21,7 +21,7 @@ class HostPathDevice;
|
||||
|
||||
class HostPathEntry : public Entry {
|
||||
public:
|
||||
HostPathEntry(Device* device, std::string path,
|
||||
HostPathEntry(Device* device, Entry* parent, std::string path,
|
||||
const std::wstring& local_path);
|
||||
~HostPathEntry() override;
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ STFSContainerDevice::Error STFSContainerDevice::ReadHeaderAndVerify(
|
||||
|
||||
STFSContainerDevice::Error STFSContainerDevice::ReadAllEntries(
|
||||
const uint8_t* map_ptr) {
|
||||
auto root_entry = new STFSContainerEntry(this, "", mmap_.get());
|
||||
auto root_entry = new STFSContainerEntry(this, nullptr, "", mmap_.get());
|
||||
root_entry->attributes_ = kFileAttributeDirectory;
|
||||
|
||||
root_entry_ = std::unique_ptr<Entry>(root_entry);
|
||||
@@ -157,8 +157,16 @@ STFSContainerDevice::Error STFSContainerDevice::ReadAllEntries(
|
||||
uint32_t access_timestamp = xe::load_and_swap<uint32_t>(p + 0x3C);
|
||||
p += 0x40;
|
||||
|
||||
STFSContainerEntry* parent_entry = nullptr;
|
||||
if (path_indicator == 0xFFFF) {
|
||||
parent_entry = root_entry;
|
||||
} else {
|
||||
parent_entry = all_entries[path_indicator];
|
||||
}
|
||||
|
||||
auto entry = new STFSContainerEntry(
|
||||
this, std::string((char*)filename, filename_length_flags & 0x3F),
|
||||
this, parent_entry,
|
||||
std::string((char*)filename, filename_length_flags & 0x3F),
|
||||
mmap_.get());
|
||||
// bit 0x40 = consecutive blocks (not fragmented?)
|
||||
if (filename_length_flags & 0x80) {
|
||||
@@ -198,14 +206,7 @@ STFSContainerDevice::Error STFSContainerDevice::ReadAllEntries(
|
||||
}
|
||||
}
|
||||
|
||||
if (path_indicator == 0xFFFF) {
|
||||
// Root entry.
|
||||
root_entry->children_.emplace_back(std::unique_ptr<Entry>(entry));
|
||||
} else {
|
||||
// Lookup and add.
|
||||
auto parent = all_entries[path_indicator];
|
||||
parent->children_.emplace_back(std::unique_ptr<Entry>(entry));
|
||||
}
|
||||
parent_entry->children_.emplace_back(std::unique_ptr<Entry>(entry));
|
||||
}
|
||||
|
||||
auto block_hash = GetBlockHash(map_ptr, table_block_index, 0);
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
STFSContainerEntry::STFSContainerEntry(Device* device, std::string path,
|
||||
MappedMemory* mmap)
|
||||
: Entry(device, path), mmap_(mmap), data_offset_(0), data_size_(0) {}
|
||||
STFSContainerEntry::STFSContainerEntry(Device* device, Entry* parent,
|
||||
std::string path, MappedMemory* mmap)
|
||||
: Entry(device, parent, path),
|
||||
mmap_(mmap),
|
||||
data_offset_(0),
|
||||
data_size_(0) {}
|
||||
|
||||
STFSContainerEntry::~STFSContainerEntry() = default;
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ class STFSContainerDevice;
|
||||
|
||||
class STFSContainerEntry : public Entry {
|
||||
public:
|
||||
STFSContainerEntry(Device* device, std::string path, MappedMemory* mmap);
|
||||
STFSContainerEntry(Device* device, Entry* parent, std::string path,
|
||||
MappedMemory* mmap);
|
||||
~STFSContainerEntry() override;
|
||||
|
||||
MappedMemory* mmap() const { return mmap_; }
|
||||
|
||||
Reference in New Issue
Block a user