diff --git a/src/common/platform/threading.hpp b/src/common/platform/threading.hpp index 7594e991..f3fe70fd 100644 --- a/src/common/platform/threading.hpp +++ b/src/common/platform/threading.hpp @@ -80,3 +80,10 @@ typedef struct _THREAD_BASIC_INFORMATION64 EMULATOR_CAST(std::uint32_t, KPRIORITY) Priority; EMULATOR_CAST(std::uint32_t, KPRIORITY) BasePriority; } THREAD_BASIC_INFORMATION64, *PTHREAD_BASIC_INFORMATION64; + +typedef struct _THREAD_TEB_INFORMATION +{ + EmulatorTraits::PVOID TebInformation; // Buffer to write data into. + ULONG TebOffset; // Offset in TEB to begin reading from. + ULONG BytesToRead; // Number of bytes to read. +} THREAD_TEB_INFORMATION, *PTHREAD_TEB_INFORMATION; diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 57db80a6..1f2c96b6 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -1499,6 +1499,25 @@ namespace return STATUS_INVALID_HANDLE; } + if (info_class == ThreadTebInformation) + { + if (return_length) + { + return_length.write(sizeof(THREAD_TEB_INFORMATION)); + } + + if (thread_information_length < sizeof(THREAD_TEB_INFORMATION)) + { + return STATUS_BUFFER_OVERFLOW; + } + + const auto teb_info = c.emu.read_memory(thread_information); + const auto data = c.emu.read_memory(thread->teb->value() + teb_info.TebOffset, teb_info.BytesToRead); + c.emu.write_memory(teb_info.TebInformation, data.data(), data.size()); + + return STATUS_SUCCESS; + } + if (info_class == ThreadBasicInformation) { if (return_length) @@ -2909,7 +2928,6 @@ namespace return mode; } - std::optional get_io_device_name(const std::u16string_view filename) { constexpr std::u16string_view device_prefix = u"\\Device\\";