From bc92023652a9e35eff4f8832975295dfa5117516 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 31 May 2025 16:30:39 +0200 Subject: [PATCH] Fix directory enumation with filesystem mappings --- src/windows-emulator/file_system.hpp | 13 ++++ src/windows-emulator/syscalls/file.cpp | 83 +++++++++++++++++--------- src/windows-emulator/windows_path.hpp | 10 ++++ 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/src/windows-emulator/file_system.hpp b/src/windows-emulator/file_system.hpp index de5a618b..ae5a60dc 100644 --- a/src/windows-emulator/file_system.hpp +++ b/src/windows-emulator/file_system.hpp @@ -56,6 +56,19 @@ class file_system return root; } + template + void access_mapped_entries(const windows_path& win_path, const F& accessor) const + { + for (const auto& mapping : this->mappings_) + { + const auto& mapped_path = mapping.first; + if (!mapped_path.empty() && mapped_path.parent() == win_path) + { + accessor(mapping); + } + } + } + windows_path local_to_windows_path(const std::filesystem::path& local_path) const { const auto absolute_local_path = weakly_canonical(absolute(local_path)); diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index fc323e1f..fdeb61ee 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -17,6 +17,35 @@ namespace syscalls { + namespace + { + std::pair open_file(const file_system& file_sys, const windows_path& path, + const std::u16string& mode) + { + FILE* file{}; + const auto error = open_unicode(&file, file_sys.translate(path), mode); + + if (file) + { + return {file, STATUS_SUCCESS}; + } + + using fh = utils::file_handle; + + switch (error) + { + case ENOENT: + return {fh{}, STATUS_OBJECT_NAME_NOT_FOUND}; + case EACCES: + return {fh{}, STATUS_ACCESS_DENIED}; + case EISDIR: + return {fh{}, STATUS_FILE_IS_A_DIRECTORY}; + default: + return {fh{}, STATUS_NOT_SUPPORTED}; + } + } + } + NTSTATUS handle_NtSetInformationFile(const syscall_context& c, const handle file_handle, const emulator_object>> io_status_block, const uint64_t file_information, const ULONG length, @@ -117,10 +146,13 @@ namespace syscalls } } - std::vector scan_directory(const std::filesystem::path& dir, const std::u16string_view file_mask) + std::vector scan_directory(const file_system& file_sys, const windows_path& win_path, + const std::u16string_view file_mask) { std::vector files{}; + const auto dir = file_sys.translate(win_path); + if (file_mask.empty() || file_mask == u"*") { files.emplace_back(file_entry{.file_path = ".", .is_directory = true}); @@ -142,6 +174,27 @@ namespace syscalls }); } + file_sys.access_mapped_entries(win_path, [&](const std::pair& entry) { + const auto filename = entry.first.leaf(); + + if (!file_mask.empty() && !utils::wildcard::match_filename(filename, file_mask)) + { + return; + } + + const std::filesystem::directory_entry dir_entry(entry.second, ec); + if (ec || !dir_entry.exists()) + { + return; + } + + files.emplace_back(file_entry{ + .file_path = filename, + .file_size = dir_entry.file_size(), + .is_directory = dir_entry.is_directory(), + }); + }); + return files; } @@ -166,7 +219,7 @@ namespace syscalls } f->enumeration_state.emplace(file_enumeration_state{}); - f->enumeration_state->files = scan_directory(c.win_emu.file_sys.translate(f->name), mask); + f->enumeration_state->files = scan_directory(c.win_emu.file_sys, f->name, mask); } auto& enum_state = *f->enumeration_state; @@ -464,32 +517,6 @@ namespace syscalls return ret(STATUS_NOT_SUPPORTED); } - static std::pair open_file(const file_system& file_sys, const windows_path& path, - const std::u16string& mode) - { - FILE* file{}; - const auto error = open_unicode(&file, file_sys.translate(path), mode); - - if (file) - { - return {file, STATUS_SUCCESS}; - } - - using fh = utils::file_handle; - - switch (error) - { - case ENOENT: - return {fh{}, STATUS_OBJECT_NAME_NOT_FOUND}; - case EACCES: - return {fh{}, STATUS_ACCESS_DENIED}; - case EISDIR: - return {fh{}, STATUS_FILE_IS_A_DIRECTORY}; - default: - return {fh{}, STATUS_NOT_SUPPORTED}; - } - } - NTSTATUS handle_NtQueryInformationByName( const syscall_context& c, const emulator_object>> object_attributes, const emulator_object>> io_status_block, const uint64_t file_information, diff --git a/src/windows-emulator/windows_path.hpp b/src/windows-emulator/windows_path.hpp index dea40aab..e2b10ba0 100644 --- a/src/windows-emulator/windows_path.hpp +++ b/src/windows-emulator/windows_path.hpp @@ -224,6 +224,16 @@ class windows_path return {this->drive_, std::move(folders)}; } + std::u16string leaf() const + { + if (this->folders_.empty()) + { + return {}; + } + + return this->folders_.back(); + } + void serialize(utils::buffer_serializer& buffer) const { buffer.write_optional(this->drive_);