Files
windows-user-space-emulator/src/windows-emulator/file_system.hpp
momo5502 a3c6e9a5c0 Cleanup emulation root handling
This fixes #103
This fixes #105
2025-01-25 08:30:43 +01:00

87 lines
2.2 KiB
C++

#pragma once
#include "std_include.hpp"
#include "windows_path.hpp"
#include <platform/compiler.hpp>
class file_system
{
public:
file_system(std::filesystem::path root, windows_path working_dir = "C:\\")
: root_(std::move(root)),
working_dir_(std::move(working_dir))
{
}
std::filesystem::path translate(const windows_path& win_path) const
{
const auto& full_path = win_path.is_absolute() //
? win_path
: (this->working_dir_ / win_path);
#ifdef OS_WINDOWS
if (this->root_.empty())
{
return full_path.u16string();
}
#endif
// TODO: Sanitize path to prevent traversal!
return this->root_ / full_path.to_portable_path();
}
void set_working_directory(windows_path working_dir)
{
this->working_dir_ = std::move(working_dir);
}
const windows_path& get_working_directory() const
{
return this->working_dir_;
}
windows_path local_to_windows_path(const std::filesystem::path& local_path) const
{
const auto absolute_local_path = absolute(local_path);
const auto relative_path = relative(absolute_local_path, this->root_);
if (relative_path.empty() || *relative_path.begin() == "..")
{
throw std::runtime_error("Path '" + local_path.string() + "' is not within the root filesystem!");
}
char drive{};
std::list<std::u16string> folders{};
for (auto i = relative_path.begin(); i != relative_path.end(); ++i)
{
if (i == relative_path.begin())
{
const auto str = i->string();
assert(str.size() == 1);
drive = str[0];
}
else
{
folders.push_back(i->u16string());
}
}
return windows_path{drive, std::move(folders)};
}
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->working_dir_);
}
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->working_dir_);
}
private:
std::filesystem::path root_{};
windows_path working_dir_{};
};