diff --git a/src/common/platform/file_management.hpp b/src/common/platform/file_management.hpp index 63022c11..3e0e90d3 100644 --- a/src/common/platform/file_management.hpp +++ b/src/common/platform/file_management.hpp @@ -272,6 +272,14 @@ struct OBJECT_ATTRIBUTES typename Traits::PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE }; +typedef struct _FILE_FS_SIZE_INFORMATION +{ + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER AvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; + typedef struct _FILE_FS_DEVICE_INFORMATION { DEVICE_TYPE DeviceType; diff --git a/src/common/platform/status.hpp b/src/common/platform/status.hpp index 59fbd48a..8c60d27d 100644 --- a/src/common/platform/status.hpp +++ b/src/common/platform/status.hpp @@ -26,6 +26,7 @@ using NTSTATUS = std::uint32_t; #define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS)0x40000000L) #define STATUS_NO_MORE_FILES ((NTSTATUS)0x80000006L) +#define STATUS_NO_MORE_ENTRIES ((NTSTATUS)0x8000001AL) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) diff --git a/src/windows-emulator/context_frame.cpp b/src/windows-emulator/context_frame.cpp index 01bd06d0..e7adf26b 100644 --- a/src/windows-emulator/context_frame.cpp +++ b/src/windows-emulator/context_frame.cpp @@ -5,7 +5,7 @@ namespace context_frame { void restore(x64_emulator& emu, const CONTEXT64& context) { - if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) + if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64) { emu.reg(x64_register::dr0, context.Dr0); emu.reg(x64_register::dr1, context.Dr1); @@ -15,7 +15,7 @@ namespace context_frame emu.reg(x64_register::dr7, context.Dr7); } - if (context.ContextFlags & CONTEXT_CONTROL_64) + if ((context.ContextFlags & CONTEXT_CONTROL_64) == CONTEXT_CONTROL_64) { emu.reg(x64_register::ss, context.SegSs); emu.reg(x64_register::cs, context.SegCs); @@ -26,7 +26,7 @@ namespace context_frame emu.reg(x64_register::eflags, context.EFlags); } - if (context.ContextFlags & CONTEXT_INTEGER_64) + if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64) { emu.reg(x64_register::rax, context.Rax); emu.reg(x64_register::rbx, context.Rbx); @@ -45,7 +45,7 @@ namespace context_frame emu.reg(x64_register::r15, context.R15); } - /*if (context.ContextFlags & CONTEXT_SEGMENTS) + /*if ((context.ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) { emu.reg(x64_register::ds, context.SegDs); emu.reg(x64_register::es, context.SegEs); @@ -53,7 +53,7 @@ namespace context_frame emu.reg(x64_register::gs, context.SegGs); }*/ - if (context.ContextFlags & CONTEXT_FLOATING_POINT_64) + if ((context.ContextFlags & CONTEXT_FLOATING_POINT_64) == CONTEXT_FLOATING_POINT_64) { emu.reg(x64_register::fpcw, context.FltSave.ControlWord); emu.reg(x64_register::fpsw, context.FltSave.StatusWord); @@ -66,7 +66,7 @@ namespace context_frame } } - if (context.ContextFlags & CONTEXT_XSTATE_64) + if ((context.ContextFlags & CONTEXT_XSTATE_64) == CONTEXT_XSTATE_64) { emu.reg(x64_register::mxcsr, context.MxCsr); @@ -80,7 +80,7 @@ namespace context_frame void save(x64_emulator& emu, CONTEXT64& context) { - if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) + if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64) { context.Dr0 = emu.reg(x64_register::dr0); context.Dr1 = emu.reg(x64_register::dr1); @@ -90,7 +90,7 @@ namespace context_frame context.Dr7 = emu.reg(x64_register::dr7); } - if (context.ContextFlags & CONTEXT_CONTROL_64) + if ((context.ContextFlags & CONTEXT_CONTROL_64) == CONTEXT_CONTROL_64) { context.SegSs = emu.reg(x64_register::ss); context.SegCs = emu.reg(x64_register::cs); @@ -99,7 +99,7 @@ namespace context_frame context.EFlags = emu.reg(x64_register::eflags); } - if (context.ContextFlags & CONTEXT_INTEGER_64) + if ((context.ContextFlags & CONTEXT_INTEGER_64) == CONTEXT_INTEGER_64) { context.Rax = emu.reg(x64_register::rax); context.Rbx = emu.reg(x64_register::rbx); @@ -118,7 +118,7 @@ namespace context_frame context.R15 = emu.reg(x64_register::r15); } - if (context.ContextFlags & CONTEXT_SEGMENTS_64) + if ((context.ContextFlags & CONTEXT_SEGMENTS_64) == CONTEXT_SEGMENTS_64) { context.SegDs = emu.reg(x64_register::ds); context.SegEs = emu.reg(x64_register::es); @@ -126,7 +126,7 @@ namespace context_frame context.SegGs = emu.reg(x64_register::gs); } - if (context.ContextFlags & CONTEXT_FLOATING_POINT_64) + if ((context.ContextFlags & CONTEXT_FLOATING_POINT_64) == CONTEXT_FLOATING_POINT_64) { context.FltSave.ControlWord = emu.reg(x64_register::fpcw); context.FltSave.StatusWord = emu.reg(x64_register::fpsw); @@ -138,7 +138,7 @@ namespace context_frame } } - if (context.ContextFlags & CONTEXT_XSTATE_64) + if ((context.ContextFlags & CONTEXT_XSTATE_64) == CONTEXT_INTEGER_64) { context.MxCsr = emu.reg(x64_register::mxcsr); for (int i = 0; i < 16; i++) diff --git a/src/windows-emulator/handles.hpp b/src/windows-emulator/handles.hpp index 7f0eca2e..0abf1887 100644 --- a/src/windows-emulator/handles.hpp +++ b/src/windows-emulator/handles.hpp @@ -348,6 +348,8 @@ class handle_store : public generic_handle_store value_map store_{}; }; +constexpr auto NULL_HANDLE = make_handle(0ULL); + constexpr auto KNOWN_DLLS_DIRECTORY = make_pseudo_handle(0x1, handle_types::directory); constexpr auto BASE_NAMED_OBJECTS_DIRECTORY = make_pseudo_handle(0x2, handle_types::directory); diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 1b0612d9..5a9e1cd8 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -588,28 +588,41 @@ namespace const ULONG /*length*/, const FS_INFORMATION_CLASS fs_information_class) { - if (fs_information_class != FileFsDeviceInformation) + if (fs_information_class == FileFsDeviceInformation) { - c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class); - c.emu.stop(); - return STATUS_NOT_SUPPORTED; + const emulator_object info_obj{c.emu, fs_information}; + info_obj.access([&](FILE_FS_DEVICE_INFORMATION& info) { + if (file_handle == STDOUT_HANDLE.bits && !c.win_emu.buffer_stdout) + { + info.DeviceType = FILE_DEVICE_CONSOLE; + info.Characteristics = 0x20000; + } + else + { + info.DeviceType = FILE_DEVICE_DISK; + info.Characteristics = 0x20020; + } + }); + + return STATUS_SUCCESS; } - const emulator_object info_obj{c.emu, fs_information}; - info_obj.access([&](FILE_FS_DEVICE_INFORMATION& info) { - if (file_handle == STDOUT_HANDLE.bits && !c.win_emu.buffer_stdout) - { - info.DeviceType = FILE_DEVICE_CONSOLE; - info.Characteristics = 0x20000; - } - else - { - info.DeviceType = FILE_DEVICE_DISK; - info.Characteristics = 0x20020; - } - }); + if (fs_information_class == FileFsSizeInformation) + { + const emulator_object info_obj{c.emu, fs_information}; + info_obj.access([&](FILE_FS_SIZE_INFORMATION& info) { + info.BytesPerSector = 0x1000; + info.SectorsPerAllocationUnit = 0x1000; + info.TotalAllocationUnits.QuadPart = 0x10000; + info.AvailableAllocationUnits.QuadPart = 0x1000; + }); - return STATUS_SUCCESS; + return STATUS_SUCCESS; + } + + c.win_emu.log.error("Unsupported fs info class: %X\n", fs_information_class); + c.emu.stop(); + return STATUS_NOT_SUPPORTED; } NTSTATUS handle_NtOpenSection(const syscall_context& c, const emulator_object section_handle, @@ -628,6 +641,13 @@ namespace return STATUS_SUCCESS; } + if (filename == u"windows_shell_global_counters" // + || filename == u"{00020000-0000-1005-8005-0000C06B5161}" // + || filename == u"Global\\{00020000-0000-1005-8005-0000C06B5161}") + { + return STATUS_NOT_SUPPORTED; + } + if (attributes.RootDirectory != KNOWN_DLLS_DIRECTORY) { c.win_emu.log.error("Unsupported section\n"); @@ -1022,6 +1042,11 @@ namespace return STATUS_SUCCESS; } + if (info_class == SystemProcessInformation) + { + return STATUS_NOT_SUPPORTED; + } + if (info_class != SystemBasicInformation && info_class != SystemEmulationBasicInformation) { c.win_emu.log.error("Unsupported system info class: %X\n", info_class); @@ -1073,7 +1098,7 @@ namespace return STATUS_SUCCESS; } - c.win_emu.log.error("Duplicating non-pseudo object not supported yet!"); + c.win_emu.log.error("Duplicating non-pseudo object not supported yet!\n"); return STATUS_NOT_SUPPORTED; } @@ -3262,6 +3287,16 @@ namespace return 1; } + NTSTATUS handle_NtUserGetDC() + { + return handle_NtUserGetDCEx(); + } + + NTSTATUS handle_NtUserReleaseDC() + { + return STATUS_SUCCESS; + } + NTSTATUS handle_NtUserModifyUserStartupInfoFlags() { return STATUS_SUCCESS; @@ -3432,11 +3467,71 @@ namespace return STATUS_SUCCESS; } - NTSTATUS handle_NtSetInformationVirtualMemory(const syscall_context&) + NTSTATUS handle_NtSetInformationVirtualMemory() { return STATUS_NOT_SUPPORTED; } + NTSTATUS handle_NtEnumerateKey() + { + return STATUS_NOT_SUPPORTED; + } + + NTSTATUS handle_NtAlpcConnectPort() + { + return STATUS_NOT_SUPPORTED; + } + + NTSTATUS handle_NtSetInformationObject() + { + return STATUS_NOT_SUPPORTED; + } + + NTSTATUS handle_NtUserGetCursorPos() + { + return STATUS_NOT_SUPPORTED; + } + + NTSTATUS handle_NtUserFindExistingCursorIcon() + { + return STATUS_NOT_SUPPORTED; + } + + NTSTATUS handle_NtGetNextThread(const syscall_context& c, const handle process_handle, const handle thread_handle, + const ACCESS_MASK /*desired_access*/, const ULONG /*handle_attributes*/, + const ULONG flags, const emulator_object new_thread_handle) + { + if (process_handle != CURRENT_PROCESS || thread_handle.value.type != handle_types::thread) + { + return STATUS_INVALID_HANDLE; + } + + if (flags != 0) + { + c.win_emu.log.error("NtGetNextThread flags %X not supported\n", flags); + c.emu.stop(); + return STATUS_NOT_SUPPORTED; + } + + bool return_next_thread = thread_handle == NULL_HANDLE; + for (const auto& t : c.proc.threads) + { + if (return_next_thread && !t.second.is_terminated()) + { + new_thread_handle.write(c.proc.threads.make_handle(t.first)); + return STATUS_SUCCESS; + } + + if (t.first == thread_handle.value.id) + { + return_next_thread = true; + } + } + + new_thread_handle.write(NULL_HANDLE); + return STATUS_NO_MORE_ENTRIES; + } + NTSTATUS handle_NtGetContextThread(const syscall_context& c, const handle thread_handle, const emulator_object thread_context) { @@ -3448,12 +3543,14 @@ namespace } c.proc.active_thread->save(c.emu); - const auto _ = utils::finally([&] { c.proc.active_thread->restore(c.emu); }); + const auto _ = utils::finally([&] { + c.proc.active_thread->restore(c.emu); // + }); thread->restore(c.emu); thread_context.access([&](CONTEXT64& context) { - if (context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) + if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64) { c.win_emu.log.print(color::pink, "--> Reading debug registers!\n"); } @@ -3464,6 +3561,42 @@ namespace return STATUS_SUCCESS; } + NTSTATUS handle_NtSetContextThread(const syscall_context& c, const handle thread_handle, + const emulator_object thread_context) + { + const auto* thread = thread_handle == CURRENT_THREAD ? c.proc.active_thread : c.proc.threads.get(thread_handle); + + if (!thread) + { + return STATUS_INVALID_HANDLE; + } + + const auto needs_swich = thread != c.proc.active_thread; + + if (needs_swich) + { + c.proc.active_thread->save(c.emu); + thread->restore(c.emu); + } + + const auto _ = utils::finally([&] { + if (needs_swich) + { + c.proc.active_thread->restore(c.emu); // + } + }); + + const auto context = thread_context.read(); + context_frame::restore(c.emu, context); + + if ((context.ContextFlags & CONTEXT_DEBUG_REGISTERS_64) == CONTEXT_DEBUG_REGISTERS_64) + { + c.win_emu.log.print(color::pink, "--> Setting debug registers!\n"); + } + + return STATUS_SUCCESS; + } + NTSTATUS handle_NtYieldExecution(const syscall_context& c) { c.win_emu.yield_thread(); @@ -3584,8 +3717,17 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtYieldExecution); add_handler(NtUserModifyUserStartupInfoFlags); add_handler(NtUserGetDCEx); + add_handler(NtUserGetDC); add_handler(NtUserGetDpiForCurrentProcess); add_handler(NtReleaseSemaphore); + add_handler(NtEnumerateKey); + add_handler(NtAlpcConnectPort); + add_handler(NtGetNextThread); + add_handler(NtSetInformationObject); + add_handler(NtUserGetCursorPos); + add_handler(NtUserReleaseDC); + add_handler(NtUserFindExistingCursorIcon); + add_handler(NtSetContextThread); #undef add_handler }