From: Jinoh Kang jinoh.kang.kr@gmail.com
Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com --- dlls/ntdll/tests/exception.c | 2 -- dlls/ntdll/unix/signal_i386.c | 2 +- dlls/ntdll/unix/signal_x86_64.c | 4 ++-- dlls/ntdll/unix/thread.c | 20 +++++++++++++++++++- dlls/ntdll/unix/unix_private.h | 13 +++++++++++++ 5 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index ee486380b8d..169045bf5e6 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -10721,7 +10721,6 @@ static void test_eflags_sanitization(void) ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status); status = pNtGetContextThread(thread, &context); ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status); - todo_wine ok(context.EFlags == max_eflags, "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags);
context.EFlags = 0; @@ -10729,7 +10728,6 @@ static void test_eflags_sanitization(void) ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status); status = pNtGetContextThread(thread, &context); ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status); - todo_wine ok(context.EFlags == min_eflags, "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags);
context.EFlags = old_eflags; diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 7be0c39c424..9be0769904d 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -941,7 +941,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) frame->esp = context->Esp; frame->ebp = context->Ebp; frame->eip = context->Eip; - frame->eflags = context->EFlags; + frame->eflags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_I386 ); frame->cs = context->SegCs; frame->ss = context->SegSs; } diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 6c87e347eac..c4f67a16cc9 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1788,7 +1788,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) frame->rsp = context->Rsp; frame->rbp = context->Rbp; frame->rip = context->Rip; - frame->eflags = context->EFlags; + frame->eflags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_AMD64 ); frame->cs = context->SegCs; frame->ss = context->SegSs; } @@ -2002,7 +2002,7 @@ NTSTATUS set_thread_wow64_context( HANDLE handle, const void *ctx, ULONG size ) wow_frame->Esp = context->Esp; wow_frame->Ebp = context->Ebp; wow_frame->Eip = context->Eip; - wow_frame->EFlags = context->EFlags; + wow_frame->EFlags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_I386 ); wow_frame->SegCs = cs32_sel; wow_frame->SegSs = ds64_sel; cpu->Flags |= WOW64_CPURESERVED_FLAG_RESET_STATE; diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index ad47a5fce74..e0d44bb4a38 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1663,13 +1663,31 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1 NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USHORT machine ) { context_t server_contexts[2]; - unsigned int count = 0; + unsigned int count = 0, i; NTSTATUS ret;
context_to_server( &server_contexts[count++], native_machine, context, machine ); if (machine != native_machine) context_to_server( &server_contexts[count++], machine, context, machine );
+ for (i = 0; i < count; i++) + { + unsigned int *flags_ptr; + if (!(server_contexts[i].flags & SERVER_CTX_CONTROL)) continue; + switch (server_contexts[i].machine) + { + case IMAGE_FILE_MACHINE_I386: + flags_ptr = &server_contexts[i].ctl.i386_regs.eflags; + break; + case IMAGE_FILE_MACHINE_AMD64: + flags_ptr = &server_contexts[i].ctl.x86_64_regs.flags; + break; + default: + continue; + } + *flags_ptr = arch_flags_reg_from_user( *flags_ptr, machine ); + } + SERVER_START_REQ( set_thread_context ) { req->handle = wine_server_obj_handle( handle ); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 795fc148479..3558f898b36 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -458,4 +458,17 @@ static inline NTSTATUS map_section( HANDLE mapping, void **ptr, SIZE_T *size, UL 0, NULL, size, ViewShare, 0, protect ); }
+static inline DWORD arch_flags_reg_from_user( DWORD flags, USHORT machine ) +{ + switch (machine) + { + case IMAGE_FILE_MACHINE_I386: + return (flags & 0x003f0fd7) | 0x00000202; + case IMAGE_FILE_MACHINE_AMD64: + return (flags & 0x00210fd5) | 0x00000200; + default: + return flags; + } +} + #endif /* __NTDLL_UNIX_PRIVATE_H */