Files
2026-04-17 20:09:41 +03:00

161 lines
4.8 KiB
C++

/**
* ReXGlue native filesystem layer
* Part of the AC6 Recompilation project
*/
#pragma once
#include <filesystem>
#include <memory>
#include <string>
#include <vector>
#include <native/filesystem.h>
#include <native/filesystem/wildcard.h>
#include <rex/memory/mapped_memory.h>
#include <rex/string/buffer.h>
#include <rex/system/xtypes.h>
#include <rex/thread/mutex.h>
namespace rex::system {
class KernelState;
class XFile;
} // namespace rex::system
namespace rex::filesystem {
class Device;
class File;
// Matches https://source.winehq.org/source/include/winternl.h#1591.
enum class FileAction {
kSuperseded = 0,
kOpened = 1,
kCreated = 2,
kOverwritten = 3,
kExists = 4,
kDoesNotExist = 5,
};
enum class FileDisposition {
// If exist replace, else create.
kSuperscede = 0,
// If exist open, else error.
kOpen = 1,
// If exist error, else create.
kCreate = 2,
// If exist open, else create.
kOpenIf = 3,
// If exist open and overwrite, else error.
kOverwrite = 4,
// If exist open and overwrite, else create.
kOverwriteIf = 5,
};
// Reuse rex::filesystem definition.
using FileAccess = rex::filesystem::FileAccess;
enum FileAttributeFlags : uint32_t {
kFileAttributeNone = 0x0000,
kFileAttributeReadOnly = 0x0001,
kFileAttributeHidden = 0x0002,
kFileAttributeSystem = 0x0004,
kFileAttributeDirectory = 0x0010,
kFileAttributeArchive = 0x0020,
kFileAttributeDevice = 0x0040,
kFileAttributeNormal = 0x0080,
kFileAttributeTemporary = 0x0100,
kFileAttributeCompressed = 0x0800,
kFileAttributeEncrypted = 0x4000,
};
class Entry {
public:
virtual ~Entry();
void Dump(rex::string::StringBuffer* string_buffer, int indent);
Device* device() const { return device_; }
Entry* parent() const { return parent_; }
const std::string& path() const { return path_; }
const std::string& absolute_path() const { return absolute_path_; }
const std::string& name() const { return name_; }
uint32_t attributes() const { return attributes_; }
size_t size() const { return size_; }
size_t allocation_size() const { return allocation_size_; }
uint64_t create_timestamp() const { return create_timestamp_; }
uint64_t access_timestamp() const { return access_timestamp_; }
uint64_t write_timestamp() const { return write_timestamp_; }
bool delete_on_close() const { return delete_on_close_; }
virtual bool SetAttributes([[maybe_unused]] uint64_t attributes) { return false; }
virtual bool SetCreateTimestamp([[maybe_unused]] uint64_t timestamp) { return false; }
virtual bool SetAccessTimestamp([[maybe_unused]] uint64_t timestamp) { return false; }
virtual bool SetWriteTimestamp([[maybe_unused]] uint64_t timestamp) { return false; }
void SetForDeletion(bool delete_on_close) { delete_on_close_ = delete_on_close; }
bool is_read_only() const;
Entry* GetChild(const std::string_view name);
Entry* ResolvePath(const std::string_view path);
const std::vector<std::unique_ptr<Entry>>& children() const { return children_; }
size_t child_count() const { return children_.size(); }
Entry* IterateChildren(const rex::filesystem::WildcardEngine& engine, size_t* current_index);
Entry* CreateEntry(const std::string_view name, uint32_t attributes);
bool Delete(Entry* entry);
bool Delete();
virtual bool Truncate() { return false; }
void Rename(const std::filesystem::path& file_path);
void Touch();
// If successful, out_file points to a new file. When finished, call
// file->Destroy()
virtual X_STATUS Open(uint32_t desired_access, File** out_file) = 0;
virtual bool can_map() const { return false; }
virtual std::unique_ptr<memory::MappedMemory> OpenMapped(memory::MappedMemory::Mode mode,
size_t offset = 0, size_t length = 0) {
(void)mode;
(void)offset;
(void)length;
return nullptr;
}
virtual void update() { return; }
protected:
Entry(Device* device, Entry* parent, const std::string_view path);
virtual std::unique_ptr<Entry> CreateEntryInternal(const std::string_view name,
uint32_t attributes) {
(void)name;
(void)attributes;
return nullptr;
}
virtual bool DeleteEntryInternal(Entry* entry) {
(void)entry;
return false;
}
virtual void RenameEntryInternal(const std::vector<std::string_view>& path_parts) {
(void)path_parts;
}
rex::thread::global_critical_region global_critical_region_;
Device* device_;
Entry* parent_;
std::string path_;
std::string absolute_path_;
std::string name_;
uint32_t attributes_; // FileAttributeFlags
size_t size_;
size_t allocation_size_;
uint64_t create_timestamp_;
uint64_t access_timestamp_;
uint64_t write_timestamp_;
std::vector<std::unique_ptr<Entry>> children_;
bool delete_on_close_ = false;
};
} // namespace rex::filesystem