Use working directory provider

This commit is contained in:
momo5502
2025-02-08 17:05:02 +01:00
parent b5a0f73113
commit 72e88d30d4
3 changed files with 51 additions and 44 deletions

View File

@@ -209,7 +209,8 @@ namespace
emu.reg<uint16_t>(x64_register::ss, 0x2B);
}
void setup_context(windows_emulator& win_emu, const emulator_settings& settings)
void setup_context(windows_emulator& win_emu, const emulator_settings& settings,
const windows_path& working_directory)
{
auto& emu = win_emu.emu();
auto& context = win_emu.process();
@@ -269,8 +270,7 @@ namespace
}
allocator.make_unicode_string(proc_params.CommandLine, command_line);
allocator.make_unicode_string(proc_params.CurrentDirectory.DosPath,
win_emu.file_sys().get_working_directory().u16string());
allocator.make_unicode_string(proc_params.CurrentDirectory.DosPath, working_directory.u16string() + u"\\");
allocator.make_unicode_string(proc_params.ImagePathName, application_str);
const auto total_length = allocator.get_next_address() - context.process_params.value();
@@ -829,19 +829,21 @@ windows_emulator::windows_emulator(const emulator_settings& settings, emulator_c
std::unique_ptr<x64_emulator> emu)
: windows_emulator(settings.emulation_root, std::move(emu))
{
windows_path working_dir{};
if (!settings.working_directory.empty())
{
this->file_sys().set_working_directory(settings.working_directory);
working_dir = settings.working_directory;
}
#ifdef OS_WINDOWS
else if (settings.application.is_relative())
{
this->file_sys().set_working_directory(std::filesystem::current_path());
working_dir = std::filesystem::current_path();
}
#endif
else
{
this->file_sys().set_working_directory(settings.application.parent());
working_dir = settings.application.parent();
}
for (const auto& mapping : settings.path_mappings)
@@ -859,12 +861,12 @@ windows_emulator::windows_emulator(const emulator_settings& settings, emulator_c
this->use_relative_time_ = settings.use_relative_time;
this->log.disable_output(settings.disable_logging || this->silent_until_main_);
this->callbacks_ = std::move(callbacks);
this->setup_process(settings);
this->setup_process(settings, working_dir);
}
windows_emulator::windows_emulator(const std::filesystem::path& emulation_root, std::unique_ptr<x64_emulator> emu)
: emulation_root_{emulation_root.empty() ? emulation_root : absolute(emulation_root)},
file_sys_(emulation_root_.empty() ? emulation_root_ : emulation_root_ / "filesys"),
file_sys_(emulation_root_.empty() ? emulation_root_ : emulation_root_ / "filesys", *this),
emu_(std::move(emu)),
process_(*emu_, file_sys_)
{
@@ -878,14 +880,16 @@ windows_emulator::windows_emulator(const std::filesystem::path& emulation_root,
this->setup_hooks();
}
void windows_emulator::setup_process(const emulator_settings& settings)
windows_emulator::~windows_emulator() = default;
void windows_emulator::setup_process(const emulator_settings& settings, const windows_path& working_directory)
{
auto& emu = this->emu();
auto& context = this->process();
context.mod_manager = module_manager(emu, this->file_sys()); // TODO: Cleanup module manager
setup_context(*this, settings);
setup_context(*this, settings, working_directory);
context.executable = context.mod_manager.map_module(settings.application, this->log, true);
@@ -938,6 +942,25 @@ bool windows_emulator::activate_thread(const uint32_t id)
return switch_to_thread(*this, *thread, true);
}
windows_path windows_emulator::get_working_directory()
{
if (!this->process_.peb)
{
return {};
}
const auto peb = this->process_.peb.read();
if (!peb.ProcessParameters)
{
return {};
}
const auto& emu = this->emu();
const auto process_params = emu.read_memory<RTL_USER_PROCESS_PARAMETERS64>(peb.ProcessParameters);
return read_unicode_string(emu, process_params.CurrentDirectory.DosPath);
}
void windows_emulator::on_instruction_execution(const uint64_t address)
{
auto& process = this->process();
@@ -1154,7 +1177,6 @@ void windows_emulator::serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->switch_thread_);
buffer.write(this->use_relative_time_);
this->file_sys().serialize(buffer);
this->emu().serialize(buffer);
this->process_.serialize(buffer);
this->dispatcher_.serialize(buffer);
@@ -1172,7 +1194,6 @@ void windows_emulator::deserialize(utils::buffer_deserializer& buffer)
buffer.read(this->switch_thread_);
buffer.read(this->use_relative_time_);
this->file_sys().deserialize(buffer);
this->emu().deserialize(buffer);
this->process_.deserialize(buffer);
@@ -1184,7 +1205,6 @@ void windows_emulator::save_snapshot()
this->emu().save_snapshot();
utils::buffer_serializer serializer{};
this->file_sys().serialize(serializer);
this->process_.serialize(serializer);
this->process_snapshot_ = serializer.move_buffer();
@@ -1204,7 +1224,6 @@ void windows_emulator::restore_snapshot()
this->emu().restore_snapshot();
utils::buffer_deserializer deserializer{this->process_snapshot_};
this->file_sys().deserialize(deserializer);
this->process_.deserialize(deserializer);
// this->process_ = *this->process_snapshot_;
}