Zebediah Figura : ntdll: Implement RtlWow64SetThreadContext().
Alexandre Julliard
julliard at winehq.org
Tue Jun 12 17:36:03 CDT 2018
Module: wine
Branch: master
Commit: b8927cf1365e80986c5377e742c1fd72079167fe
URL: https://source.winehq.org/git/wine.git/?a=commit;h=b8927cf1365e80986c5377e742c1fd72079167fe
Author: Zebediah Figura <zfigura at codeweavers.com>
Date: Wed Jun 6 13:30:18 2018 -0500
ntdll: Implement RtlWow64SetThreadContext().
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/signal_x86_64.c | 82 ++++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/tests/exception.c | 6 ++++
3 files changed, 89 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index d493e4f..45cedb7 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -979,6 +979,7 @@
@ stdcall RtlWow64EnableFsRedirection(long)
@ stdcall RtlWow64EnableFsRedirectionEx(long ptr)
@ stdcall -arch=x86_64 RtlWow64GetThreadContext(long ptr)
+@ stdcall -arch=x86_64 RtlWow64SetThreadContext(long ptr)
@ stub RtlWriteMemoryStream
@ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long)
@ stub RtlZeroHeap
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 8d45ba8..0d25360 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -2284,6 +2284,74 @@ static NTSTATUS wow64_context_from_server( WOW64_CONTEXT *to, const context_t *f
return STATUS_SUCCESS;
}
+/***********************************************************************
+ * wow64_context_to_server
+ */
+static void wow64_context_to_server( context_t *to, const WOW64_CONTEXT *from )
+{
+ DWORD flags = from->ContextFlags & ~WOW64_CONTEXT_i386; /* get rid of CPU id */
+
+ memset( to, 0, sizeof(*to) );
+ to->cpu = CPU_x86;
+
+ if (flags & WOW64_CONTEXT_CONTROL)
+ {
+ to->flags |= SERVER_CTX_CONTROL;
+ to->ctl.i386_regs.ebp = from->Ebp;
+ to->ctl.i386_regs.esp = from->Esp;
+ to->ctl.i386_regs.eip = from->Eip;
+ to->ctl.i386_regs.cs = from->SegCs;
+ to->ctl.i386_regs.ss = from->SegSs;
+ to->ctl.i386_regs.eflags = from->EFlags;
+ }
+ if (flags & WOW64_CONTEXT_INTEGER)
+ {
+ to->flags |= SERVER_CTX_INTEGER;
+ to->integer.i386_regs.eax = from->Eax;
+ to->integer.i386_regs.ebx = from->Ebx;
+ to->integer.i386_regs.ecx = from->Ecx;
+ to->integer.i386_regs.edx = from->Edx;
+ to->integer.i386_regs.esi = from->Esi;
+ to->integer.i386_regs.edi = from->Edi;
+ }
+ if (flags & WOW64_CONTEXT_SEGMENTS)
+ {
+ to->flags |= SERVER_CTX_SEGMENTS;
+ to->seg.i386_regs.ds = from->SegDs;
+ to->seg.i386_regs.es = from->SegEs;
+ to->seg.i386_regs.fs = from->SegFs;
+ to->seg.i386_regs.gs = from->SegGs;
+ }
+ if (flags & WOW64_CONTEXT_FLOATING_POINT)
+ {
+ to->flags |= SERVER_CTX_FLOATING_POINT;
+ to->fp.i386_regs.ctrl = from->FloatSave.ControlWord;
+ to->fp.i386_regs.status = from->FloatSave.StatusWord;
+ to->fp.i386_regs.tag = from->FloatSave.TagWord;
+ to->fp.i386_regs.err_off = from->FloatSave.ErrorOffset;
+ to->fp.i386_regs.err_sel = from->FloatSave.ErrorSelector;
+ to->fp.i386_regs.data_off = from->FloatSave.DataOffset;
+ to->fp.i386_regs.data_sel = from->FloatSave.DataSelector;
+ to->fp.i386_regs.cr0npx = from->FloatSave.Cr0NpxState;
+ memcpy( to->fp.i386_regs.regs, from->FloatSave.RegisterArea, sizeof(to->fp.i386_regs.regs) );
+ }
+ if (flags & WOW64_CONTEXT_DEBUG_REGISTERS)
+ {
+ to->flags |= SERVER_CTX_DEBUG_REGISTERS;
+ to->debug.i386_regs.dr0 = from->Dr0;
+ to->debug.i386_regs.dr1 = from->Dr1;
+ to->debug.i386_regs.dr2 = from->Dr2;
+ to->debug.i386_regs.dr3 = from->Dr3;
+ to->debug.i386_regs.dr6 = from->Dr6;
+ to->debug.i386_regs.dr7 = from->Dr7;
+ }
+ if (flags & WOW64_CONTEXT_EXTENDED_REGISTERS)
+ {
+ to->flags |= SERVER_CTX_EXTENDED_REGISTERS;
+ memcpy( to->ext.i386_regs, from->ExtendedRegisters, sizeof(to->ext.i386_regs) );
+ }
+}
+
/******************************************************************************
* RtlWow64GetThreadContext (NTDLL.@)
@@ -2300,6 +2368,20 @@ NTSTATUS WINAPI RtlWow64GetThreadContext( HANDLE handle, WOW64_CONTEXT *context
return wow64_context_from_server( context, &server_context );
}
+
+/******************************************************************************
+ * RtlWow64SetThreadContext (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlWow64SetThreadContext( HANDLE handle, const WOW64_CONTEXT *context )
+{
+ BOOL self;
+ context_t server_context;
+
+ wow64_context_to_server( &server_context, context );
+ return set_thread_context( handle, &server_context, &self );
+}
+
+
extern void raise_func_trampoline( EXCEPTION_RECORD *rec, CONTEXT *context, raise_func func );
__ASM_GLOBAL_FUNC( raise_func_trampoline,
__ASM_CFI(".cfi_signal_frame\n\t")
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 9310297..e30cd59 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -150,6 +150,7 @@ static EXCEPTION_DISPOSITION (WINAPI *p__C_specific_handler)(EXCEPTION_RECORD*,
static VOID (WINAPI *pRtlCaptureContext)(CONTEXT*);
static VOID (CDECL *pRtlRestoreContext)(CONTEXT*, EXCEPTION_RECORD*);
static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE, WOW64_CONTEXT *);
+static NTSTATUS (WINAPI *pRtlWow64SetThreadContext)(HANDLE, const WOW64_CONTEXT *);
static VOID (CDECL *pRtlUnwindEx)(VOID*, VOID*, EXCEPTION_RECORD*, VOID*, CONTEXT*, UNWIND_HISTORY_TABLE*);
static int (CDECL *p_setjmp)(_JUMP_BUFFER*);
#endif
@@ -2520,6 +2521,9 @@ static void test_wow64_context(void)
ok(*(WORD *)ctx.ExtendedRegisters == 0x27f, "got SSE control word %04x\n",
*(WORD *)ctx.ExtendedRegisters);
+ ret = pRtlWow64SetThreadContext( pi.hThread, &ctx );
+ ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
+
pNtTerminateProcess(pi.hProcess, 0);
}
@@ -3163,6 +3167,8 @@ START_TEST(exception)
"RtlUnwindEx" );
pRtlWow64GetThreadContext = (void *)GetProcAddress( hntdll,
"RtlWow64GetThreadContext" );
+ pRtlWow64SetThreadContext = (void *)GetProcAddress( hntdll,
+ "RtlWow64SetThreadContext" );
p_setjmp = (void *)GetProcAddress( hmsvcrt,
"_setjmp" );
More information about the wine-cvs
mailing list