[Kernel/VFS] Cleanup info query/set+sector size.
[VFS] Device now exposes name, attributes, component name max length.
[VFS] Fix STFS device to return 0x200 sector size. XCTD compression
userland code appears to always expect a sector size of 0x200.
[Kernel] Move X_FILE_*_INFORMATION structs to new files.
[Kernel] Move NtQueryInformationFile, NtSetInformationFile,
NtQueryVolumeInformationFile to new file.
[Kernel] Cleanup implementation of NtQueryInformationFile,
NetSetInformationFile, NtQueryVolumeInformationFile.
[Kernel] Properly validate arguments to NtQueryInformationFile,
NetSetInformationFile, NtQueryVolumeInformationFile.
[Kernel] Properly implement query of XFileFsVolumeInformation.
[Kernel] Properly implement query of XFileFsSizeInformation.
[Kernel] Properly implement query of XFileFsAttributeInformation.
This commit is contained in:
@@ -33,6 +33,10 @@ class Device {
|
||||
virtual void Dump(StringBuffer* string_buffer) = 0;
|
||||
virtual Entry* ResolvePath(const std::string_view path) = 0;
|
||||
|
||||
virtual const std::string& name() const = 0;
|
||||
virtual uint32_t attributes() const = 0;
|
||||
virtual uint32_t component_name_max_length() const = 0;
|
||||
|
||||
virtual uint32_t total_allocation_units() const = 0;
|
||||
virtual uint32_t available_allocation_units() const = 0;
|
||||
virtual uint32_t sectors_per_allocation_unit() const = 0;
|
||||
|
||||
@@ -20,7 +20,7 @@ const size_t kXESectorSize = 2048;
|
||||
|
||||
DiscImageDevice::DiscImageDevice(const std::string_view mount_path,
|
||||
const std::filesystem::path& host_path)
|
||||
: Device(mount_path), host_path_(host_path) {}
|
||||
: Device(mount_path), name_("GDFX"), host_path_(host_path) {}
|
||||
|
||||
DiscImageDevice::~DiscImageDevice() = default;
|
||||
|
||||
|
||||
@@ -31,13 +31,17 @@ class DiscImageDevice : public Device {
|
||||
void Dump(StringBuffer* string_buffer) override;
|
||||
Entry* ResolvePath(const std::string_view path) override;
|
||||
|
||||
const std::string& name() const override { return name_; }
|
||||
uint32_t attributes() const override { return 0; }
|
||||
uint32_t component_name_max_length() const override { return 255; }
|
||||
|
||||
uint32_t total_allocation_units() const override {
|
||||
return uint32_t(mmap_->size() / sectors_per_allocation_unit() /
|
||||
bytes_per_sector());
|
||||
}
|
||||
uint32_t available_allocation_units() const override { return 0; }
|
||||
uint32_t sectors_per_allocation_unit() const override { return 1; }
|
||||
uint32_t bytes_per_sector() const override { return 2 * 1024; }
|
||||
uint32_t bytes_per_sector() const override { return 0x200; }
|
||||
|
||||
private:
|
||||
enum class Error {
|
||||
@@ -48,6 +52,7 @@ class DiscImageDevice : public Device {
|
||||
kErrorDamagedFile = -31,
|
||||
};
|
||||
|
||||
std::string name_;
|
||||
std::filesystem::path host_path_;
|
||||
std::unique_ptr<Entry> root_entry_;
|
||||
std::unique_ptr<MappedMemory> mmap_;
|
||||
|
||||
@@ -21,7 +21,10 @@ namespace vfs {
|
||||
HostPathDevice::HostPathDevice(const std::string_view mount_path,
|
||||
const std::filesystem::path& host_path,
|
||||
bool read_only)
|
||||
: Device(mount_path), host_path_(host_path), read_only_(read_only) {}
|
||||
: Device(mount_path),
|
||||
name_("STFS"),
|
||||
host_path_(host_path),
|
||||
read_only_(read_only) {}
|
||||
|
||||
HostPathDevice::~HostPathDevice() = default;
|
||||
|
||||
|
||||
@@ -31,14 +31,19 @@ class HostPathDevice : public Device {
|
||||
|
||||
bool is_read_only() const override { return read_only_; }
|
||||
|
||||
const std::string& name() const override { return name_; }
|
||||
uint32_t attributes() const override { return 0; }
|
||||
uint32_t component_name_max_length() const override { return 40; }
|
||||
|
||||
uint32_t total_allocation_units() const override { return 128 * 1024; }
|
||||
uint32_t available_allocation_units() const override { return 128 * 1024; }
|
||||
uint32_t sectors_per_allocation_unit() const override { return 1; }
|
||||
uint32_t bytes_per_sector() const override { return 2 * 1024; }
|
||||
uint32_t bytes_per_sector() const override { return 0x200; }
|
||||
|
||||
private:
|
||||
void PopulateEntry(HostPathEntry* parent_entry);
|
||||
|
||||
std::string name_;
|
||||
std::filesystem::path host_path_;
|
||||
std::unique_ptr<Entry> root_entry_;
|
||||
bool read_only_;
|
||||
|
||||
@@ -55,7 +55,15 @@ uint64_t decode_fat_timestamp(uint32_t date, uint32_t time) {
|
||||
|
||||
StfsContainerDevice::StfsContainerDevice(const std::string_view mount_path,
|
||||
const std::filesystem::path& host_path)
|
||||
: Device(mount_path), host_path_(host_path) {}
|
||||
: Device(mount_path),
|
||||
name_("STFS"),
|
||||
host_path_(host_path),
|
||||
mmap_total_size_(),
|
||||
base_offset_(),
|
||||
magic_offset_(),
|
||||
package_type_(),
|
||||
header_(),
|
||||
table_size_shift_() {}
|
||||
|
||||
StfsContainerDevice::~StfsContainerDevice() = default;
|
||||
|
||||
@@ -370,7 +378,7 @@ StfsContainerDevice::Error StfsContainerDevice::ReadEntrySVOD(
|
||||
// Entry is a file
|
||||
entry->attributes_ = kFileAttributeNormal | kFileAttributeReadOnly;
|
||||
entry->size_ = length;
|
||||
entry->allocation_size_ = xe::round_up(length, bytes_per_sector());
|
||||
entry->allocation_size_ = xe::round_up(length, kSectorSize);
|
||||
entry->data_offset_ = data_address;
|
||||
entry->data_size_ = length;
|
||||
entry->block_ = data_block;
|
||||
@@ -536,7 +544,7 @@ StfsContainerDevice::Error StfsContainerDevice::ReadSTFS() {
|
||||
entry->data_size_ = file_size;
|
||||
}
|
||||
entry->size_ = file_size;
|
||||
entry->allocation_size_ = xe::round_up(file_size, bytes_per_sector());
|
||||
entry->allocation_size_ = xe::round_up(file_size, kSectorSize);
|
||||
|
||||
entry->create_timestamp_ = decode_fat_timestamp(update_date, update_time);
|
||||
entry->access_timestamp_ = decode_fat_timestamp(access_date, access_time);
|
||||
@@ -618,7 +626,7 @@ StfsContainerDevice::BlockHash StfsContainerDevice::GetBlockHash(
|
||||
// table and then subtract one sector to land on the table itself.
|
||||
size_t hash_offset = BlockToOffsetSTFS(
|
||||
xe::round_up(block_index + 1, kSTFSHashSpacing) - kSTFSHashSpacing);
|
||||
hash_offset -= bytes_per_sector();
|
||||
hash_offset -= kSectorSize;
|
||||
const uint8_t* hash_data = map_ptr + hash_offset;
|
||||
|
||||
// table_index += table_offset - (1 << table_size_shift_);
|
||||
|
||||
@@ -173,15 +173,21 @@ class StfsContainerDevice : public Device {
|
||||
void Dump(StringBuffer* string_buffer) override;
|
||||
Entry* ResolvePath(const std::string_view path) override;
|
||||
|
||||
const std::string& name() const override { return name_; }
|
||||
uint32_t attributes() const override { return 0; }
|
||||
uint32_t component_name_max_length() const override { return 40; }
|
||||
|
||||
uint32_t total_allocation_units() const override {
|
||||
return uint32_t(mmap_total_size_ / sectors_per_allocation_unit() /
|
||||
bytes_per_sector());
|
||||
}
|
||||
uint32_t available_allocation_units() const override { return 0; }
|
||||
uint32_t sectors_per_allocation_unit() const override { return 1; }
|
||||
uint32_t bytes_per_sector() const override { return 4 * 1024; }
|
||||
uint32_t sectors_per_allocation_unit() const override { return 8; }
|
||||
uint32_t bytes_per_sector() const override { return 0x200; }
|
||||
|
||||
private:
|
||||
const uint32_t kSectorSize = 0x1000;
|
||||
|
||||
enum class Error {
|
||||
kSuccess = 0,
|
||||
kErrorOutOfMemory = -1,
|
||||
@@ -215,6 +221,7 @@ class StfsContainerDevice : public Device {
|
||||
BlockHash GetBlockHash(const uint8_t* map_ptr, uint32_t block_index,
|
||||
uint32_t table_offset);
|
||||
|
||||
std::string name_;
|
||||
std::filesystem::path host_path_;
|
||||
std::map<size_t, std::unique_ptr<MappedMemory>> mmap_;
|
||||
size_t mmap_total_size_;
|
||||
|
||||
@@ -22,7 +22,8 @@ StfsContainerEntry::StfsContainerEntry(Device* device, Entry* parent,
|
||||
: Entry(device, parent, path),
|
||||
mmap_(mmap),
|
||||
data_offset_(0),
|
||||
data_size_(0) {}
|
||||
data_size_(0),
|
||||
block_(0) {}
|
||||
|
||||
StfsContainerEntry::~StfsContainerEntry() = default;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user