Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2018
- 68 participants
- 1149 messages
Out for a few days
by Alexandre Julliard
Folks,
I'm going to be out from tomorrow until Sunday, so release 3.10 is going
to be delayed until Monday.
--
Alexandre Julliard
julliard(a)winehq.org
June 6, 2018
Re: [PATCH 2/3] kernel32: Implement Wow64GetThreadContext().
by Zebediah Figura
On 06/06/2018 09:34 AM, Alexandre Julliard wrote:
> Zebediah Figura <zfigura(a)codeweavers.com> writes:
>
>> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
>> ---
>> With code essentially copied from ntdll. As far as I can tell there is no
>> ntdll entry point for this function.
>
> RtlWow64GetThreadContext() is probably what you are looking for. It will
> need some test cases obviously.
>
Thanks; I can see I was looking in the wrong place. I've sent updated
patches.
June 6, 2018
[PATCH v2 5/5] kernel32: Implement Wow64SetThreadContext().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/kernel32/kernel32.spec | 2 +-
dlls/kernel32/thread.c | 17 +++++++++++++++++
include/winbase.h | 1 +
include/winternl.h | 1 +
4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 1cb0b54..de6f007 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1603,7 +1603,7 @@
@ stdcall Wow64GetThreadContext(long ptr)
# @ stub Wow64GetThreadSelectorEntry
@ stdcall Wow64RevertWow64FsRedirection(ptr)
-# @ stub Wow64SetThreadContext
+@ stdcall Wow64SetThreadContext(long ptr)
# @ stub Wow64SuspendThread
@ stdcall WriteConsoleA(long ptr long ptr ptr)
@ stdcall WriteConsoleInputA(long ptr long ptr)
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index 3aa2887..eb304dc 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -236,6 +236,23 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread
/***********************************************************************
+ * Wow64SetThreadContext [KERNEL32.@]
+ */
+BOOL WINAPI Wow64SetThreadContext( HANDLE handle, const WOW64_CONTEXT *context)
+{
+#ifdef __i386__
+ NTSTATUS status = NtSetContextThread( handle, (const CONTEXT *)context );
+#elif defined(_WIN64)
+ NTSTATUS status = RtlWow64SetThreadContext( handle, context );
+#else
+ NTSTATUS status = STATUS_NOT_IMPLEMENTED;
+ FIXME("not implemented on this platform\n");
+#endif
+ if (status) SetLastError( RtlNtStatusToDosError(status) );
+ return !status;
+}
+
+/***********************************************************************
* GetThreadContext [KERNEL32.@] Retrieves context of thread.
*
* RETURNS
diff --git a/include/winbase.h b/include/winbase.h
index f7239b8..667df96 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2708,6 +2708,7 @@ WINBASEAPI BOOL WINAPI Wow64DisableWow64FsRedirection(PVOID*);
WINBASEAPI BOOLEAN WINAPI Wow64EnableWow64FsRedirection(BOOLEAN);
WINBASEAPI BOOL WINAPI Wow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
WINBASEAPI BOOL WINAPI Wow64RevertWow64FsRedirection(PVOID);
+WINBASEAPI BOOL WINAPI Wow64SetThreadContext(HANDLE, const WOW64_CONTEXT *);
WINADVAPI DWORD WINAPI WriteEncryptedFileRaw(PFE_IMPORT_FUNC,PVOID,PVOID);
WINBASEAPI BOOL WINAPI WriteFile(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
WINBASEAPI BOOL WINAPI WriteFileEx(HANDLE,LPCVOID,DWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE);
diff --git a/include/winternl.h b/include/winternl.h
index 9361825..9341c40 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2838,6 +2838,7 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirection(BOOLEAN);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx(ULONG,ULONG*);
#ifdef _WIN64
NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
+NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE, const WOW64_CONTEXT *);
#endif
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG,PCWSTR,PCWSTR,ULONG,PVOID,ULONG);
NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE);
--
2.7.4
June 6, 2018
[PATCH v2 4/5] kernel32: Implement Wow64GetThreadContext().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/kernel32/kernel32.spec | 2 +-
dlls/kernel32/thread.c | 18 ++++++++++++++++++
include/winbase.h | 1 +
include/winternl.h | 3 +++
4 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 9ed5dfb..1cb0b54 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1600,7 +1600,7 @@
@ stdcall WinExec(str long)
@ stdcall Wow64EnableWow64FsRedirection(long)
@ stdcall Wow64DisableWow64FsRedirection(ptr)
-# @ stub Wow64GetThreadContext
+@ stdcall Wow64GetThreadContext(long ptr)
# @ stub Wow64GetThreadSelectorEntry
@ stdcall Wow64RevertWow64FsRedirection(ptr)
# @ stub Wow64SetThreadContext
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index b6ca9f260..3aa2887 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -251,6 +251,24 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with
}
+/***********************************************************************
+ * Wow64GetThreadContext [KERNEL32.@]
+ */
+BOOL WINAPI Wow64GetThreadContext( HANDLE handle, WOW64_CONTEXT *context)
+{
+#ifdef __i386__
+ NTSTATUS status = NtGetContextThread( handle, (CONTEXT *)context );
+#elif defined(_WIN64)
+ NTSTATUS status = RtlWow64GetThreadContext( handle, context );
+#else
+ NTSTATUS status = STATUS_NOT_IMPLEMENTED;
+ FIXME("not implemented on this platform\n");
+#endif
+ if (status) SetLastError( RtlNtStatusToDosError(status) );
+ return !status;
+}
+
+
/**********************************************************************
* SuspendThread [KERNEL32.@] Suspends a thread.
*
diff --git a/include/winbase.h b/include/winbase.h
index 4ddc1d3..f7239b8 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2706,6 +2706,7 @@ WINBASEAPI VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE);
WINBASEAPI UINT WINAPI WinExec(LPCSTR,UINT);
WINBASEAPI BOOL WINAPI Wow64DisableWow64FsRedirection(PVOID*);
WINBASEAPI BOOLEAN WINAPI Wow64EnableWow64FsRedirection(BOOLEAN);
+WINBASEAPI BOOL WINAPI Wow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
WINBASEAPI BOOL WINAPI Wow64RevertWow64FsRedirection(PVOID);
WINADVAPI DWORD WINAPI WriteEncryptedFileRaw(PFE_IMPORT_FUNC,PVOID,PVOID);
WINBASEAPI BOOL WINAPI WriteFile(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
diff --git a/include/winternl.h b/include/winternl.h
index 3ecd068..9361825 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2836,6 +2836,9 @@ NTSYSAPI void WINAPI RtlWakeConditionVariable(RTL_CONDITION_VARIABLE *);
NTSYSAPI NTSTATUS WINAPI RtlWalkHeap(HANDLE,PVOID);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirection(BOOLEAN);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx(ULONG,ULONG*);
+#ifdef _WIN64
+NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
+#endif
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG,PCWSTR,PCWSTR,ULONG,PVOID,ULONG);
NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE);
NTSYSAPI NTSTATUS WINAPI RtlpNtCreateKey(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,const UNICODE_STRING*,ULONG,PULONG);
--
2.7.4
June 6, 2018
[PATCH v2 3/5] ntdll: Implement RtlWow64SetThreadContext().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/tests/exception.c | 6 +++
dlls/ntdll/thread.c | 96 +++++++++++++++++++++++++++++++++++++++-----
3 files changed, 93 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index f1dd6ed..77cc1ae 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -978,6 +978,7 @@
@ stdcall RtlWow64EnableFsRedirection(long)
@ stdcall RtlWow64EnableFsRedirectionEx(long ptr)
@ stdcall -arch=win64 RtlWow64GetThreadContext(long ptr)
+@ stdcall -arch=win64 RtlWow64SetThreadContext(long ptr)
@ stub RtlWriteMemoryStream
@ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long)
@ stub RtlZeroHeap
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 0ab3812..f09e86d 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" );
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index df04b33..52c7953 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -851,23 +851,16 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
return NtCurrentTeb()->ActiveFrame;
}
-
-/***********************************************************************
- * set_thread_context
- */
-NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
+static NTSTATUS set_server_context( HANDLE handle, const context_t *context, BOOL *self )
{
NTSTATUS ret;
DWORD dummy, i;
- context_t server_context;
-
- context_to_server( &server_context, context );
SERVER_START_REQ( set_thread_context )
{
req->handle = wine_server_obj_handle( handle );
req->suspend = 1;
- wine_server_add_data( req, &server_context, sizeof(server_context) );
+ wine_server_add_data( req, context, sizeof(*context) );
ret = wine_server_call( req );
*self = reply->self;
}
@@ -881,7 +874,7 @@ NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
{
req->handle = wine_server_obj_handle( handle );
req->suspend = 0;
- wine_server_add_data( req, &server_context, sizeof(server_context) );
+ wine_server_add_data( req, context, sizeof(*context) );
ret = wine_server_call( req );
}
SERVER_END_REQ;
@@ -900,6 +893,12 @@ NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
return ret;
}
+NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
+{
+ context_t server_context;
+ context_to_server( &server_context, context );
+ return set_server_context( handle, &server_context, self );
+}
/* convert CPU-specific flags to generic server flags */
static inline unsigned int get_server_context_flags( DWORD flags )
@@ -978,6 +977,83 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self)
}
#ifdef _WIN64
+static NTSTATUS 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) );
+ }
+ return STATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * 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_server_context( handle, &server_context, &self );
+}
+
/* convert CPU-specific flags to generic server flags */
static inline unsigned int wow64_get_server_context_flags( DWORD flags )
{
--
2.7.4
June 6, 2018
[PATCH v2 2/5] ntdll: Implement RtlWow64GetThreadContext().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/tests/exception.c | 36 ++++++++++++++
dlls/ntdll/thread.c | 114 ++++++++++++++++++++++++++++++++++++++++---
3 files changed, 143 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index c0f5d6f..f1dd6ed 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -977,6 +977,7 @@
@ stdcall RtlWalkHeap(long ptr)
@ stdcall RtlWow64EnableFsRedirection(long)
@ stdcall RtlWow64EnableFsRedirectionEx(long ptr)
+@ stdcall -arch=win64 RtlWow64GetThreadContext(long ptr)
@ stub RtlWriteMemoryStream
@ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long)
@ stub RtlZeroHeap
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index c47c8cb..0ab3812 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -149,6 +149,7 @@ static PRUNTIME_FUNCTION (WINAPI *pRtlLookupFunctionEntry)(ULONG64, ULONG64*, UN
static EXCEPTION_DISPOSITION (WINAPI *p__C_specific_handler)(EXCEPTION_RECORD*, ULONG64, CONTEXT*, DISPATCHER_CONTEXT*);
static VOID (WINAPI *pRtlCaptureContext)(CONTEXT*);
static VOID (CDECL *pRtlRestoreContext)(CONTEXT*, EXCEPTION_RECORD*);
+static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE, WOW64_CONTEXT *);
static VOID (CDECL *pRtlUnwindEx)(VOID*, VOID*, EXCEPTION_RECORD*, VOID*, CONTEXT*, UNWIND_HISTORY_TABLE*);
static int (CDECL *p_setjmp)(_JUMP_BUFFER*);
#endif
@@ -2490,6 +2491,38 @@ static void test_dpe_exceptions(void)
pRtlRemoveVectoredExceptionHandler(handler);
}
+static void test_wow64_context(void)
+{
+ char cmdline[] = "C:\\windows\\syswow64\\notepad.exe";
+ PROCESS_INFORMATION pi;
+ STARTUPINFOA si = {0};
+ WOW64_CONTEXT ctx;
+ NTSTATUS ret;
+
+ memset(&ctx, 0x55, sizeof(ctx));
+ ctx.ContextFlags = WOW64_CONTEXT_ALL;
+ ret = pRtlWow64GetThreadContext( GetCurrentThread(), &ctx );
+ ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
+
+ CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
+
+ ret = pRtlWow64GetThreadContext( pi.hThread, &ctx );
+ ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
+ ok(ctx.ContextFlags == WOW64_CONTEXT_ALL, "got context flags %#x\n", ctx.ContextFlags);
+ ok(!ctx.Ebp, "got ebp %08x\n", ctx.Ebp);
+ ok(!ctx.Ecx, "got ecx %08x\n", ctx.Ecx);
+ ok(!ctx.Edx, "got edx %08x\n", ctx.Edx);
+ ok(!ctx.Esi, "got esi %08x\n", ctx.Esi);
+ ok(!ctx.Edi, "got edi %08x\n", ctx.Edi);
+ ok((ctx.EFlags & ~2) == 0x200, "got eflags %08x\n", ctx.EFlags);
+ ok((WORD) ctx.FloatSave.ControlWord == 0x27f, "got control word %08x\n",
+ ctx.FloatSave.ControlWord);
+ ok(*(WORD *)ctx.ExtendedRegisters == 0x27f, "got SSE control word %04x\n",
+ *(WORD *)ctx.ExtendedRegisters);
+
+ pNtTerminateProcess(pi.hProcess, 0);
+}
+
#endif /* __x86_64__ */
#if defined(__i386__) || defined(__x86_64__)
@@ -3128,6 +3161,8 @@ START_TEST(exception)
"RtlRestoreContext" );
pRtlUnwindEx = (void *)GetProcAddress( hntdll,
"RtlUnwindEx" );
+ pRtlWow64GetThreadContext = (void *)GetProcAddress( hntdll,
+ "RtlWow64GetThreadContext" );
p_setjmp = (void *)GetProcAddress( hmsvcrt,
"_setjmp" );
@@ -3143,6 +3178,7 @@ START_TEST(exception)
test_restore_context();
test_prot_fault();
test_dpe_exceptions();
+ test_wow64_context();
if (pRtlAddFunctionTable && pRtlDeleteFunctionTable && pRtlInstallFunctionTableCallback && pRtlLookupFunctionEntry)
test_dynamic_unwind();
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 35e23d2..df04b33 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -924,22 +924,18 @@ static inline unsigned int get_server_context_flags( DWORD flags )
return ret;
}
-/***********************************************************************
- * get_thread_context
- */
-NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
+static NTSTATUS get_server_context( HANDLE handle, unsigned int server_flags,
+ context_t *context, BOOL *self )
{
NTSTATUS ret;
DWORD dummy, i;
- unsigned int server_flags = get_server_context_flags( context->ContextFlags );
- context_t server_context;
SERVER_START_REQ( get_thread_context )
{
req->handle = wine_server_obj_handle( handle );
req->flags = server_flags;
req->suspend = 1;
- wine_server_set_reply( req, &server_context, sizeof(server_context) );
+ wine_server_set_reply( req, context, sizeof(*context) );
ret = wine_server_call( req );
*self = reply->self;
}
@@ -954,7 +950,7 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
req->handle = wine_server_obj_handle( handle );
req->flags = server_flags;
req->suspend = 0;
- wine_server_set_reply( req, &server_context, sizeof(server_context) );
+ wine_server_set_reply( req, context, sizeof(*context) );
ret = wine_server_call( req );
}
SERVER_END_REQ;
@@ -969,10 +965,112 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
NtResumeThread( handle, &dummy );
if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
}
+ return ret;
+}
+
+NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self)
+{
+ context_t server_context;
+ unsigned int server_flags = get_server_context_flags( context->ContextFlags );
+ NTSTATUS ret = get_server_context( handle, server_flags, &server_context, self);
if (!ret) ret = context_from_server( context, &server_context );
return ret;
}
+#ifdef _WIN64
+/* convert CPU-specific flags to generic server flags */
+static inline unsigned int wow64_get_server_context_flags( DWORD flags )
+{
+ unsigned int ret = 0;
+
+ flags &= 0x3f; /* mask CPU id flags */
+ if (flags & WOW64_CONTEXT_CONTROL) ret |= SERVER_CTX_CONTROL;
+ if (flags & WOW64_CONTEXT_INTEGER) ret |= SERVER_CTX_INTEGER;
+ if (flags & WOW64_CONTEXT_SEGMENTS) ret |= SERVER_CTX_SEGMENTS;
+ if (flags & WOW64_CONTEXT_FLOATING_POINT) ret |= SERVER_CTX_FLOATING_POINT;
+ if (flags & WOW64_CONTEXT_DEBUG_REGISTERS) ret |= SERVER_CTX_DEBUG_REGISTERS;
+ if (flags & WOW64_CONTEXT_EXTENDED_REGISTERS) ret |= SERVER_CTX_EXTENDED_REGISTERS;
+ return ret;
+}
+
+static NTSTATUS wow64_context_from_server( WOW64_CONTEXT *to, const context_t *from )
+{
+ if (from->cpu != CPU_x86) return STATUS_INVALID_PARAMETER;
+
+ to->ContextFlags = WOW64_CONTEXT_i386;
+ if (from->flags & SERVER_CTX_CONTROL)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_CONTROL;
+ to->Ebp = from->ctl.i386_regs.ebp;
+ to->Esp = from->ctl.i386_regs.esp;
+ to->Eip = from->ctl.i386_regs.eip;
+ to->SegCs = from->ctl.i386_regs.cs;
+ to->SegSs = from->ctl.i386_regs.ss;
+ to->EFlags = from->ctl.i386_regs.eflags;
+ }
+ if (from->flags & SERVER_CTX_INTEGER)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_INTEGER;
+ to->Eax = from->integer.i386_regs.eax;
+ to->Ebx = from->integer.i386_regs.ebx;
+ to->Ecx = from->integer.i386_regs.ecx;
+ to->Edx = from->integer.i386_regs.edx;
+ to->Esi = from->integer.i386_regs.esi;
+ to->Edi = from->integer.i386_regs.edi;
+ }
+ if (from->flags & SERVER_CTX_SEGMENTS)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_SEGMENTS;
+ to->SegDs = from->seg.i386_regs.ds;
+ to->SegEs = from->seg.i386_regs.es;
+ to->SegFs = from->seg.i386_regs.fs;
+ to->SegGs = from->seg.i386_regs.gs;
+ }
+ if (from->flags & SERVER_CTX_FLOATING_POINT)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_FLOATING_POINT;
+ to->FloatSave.ControlWord = from->fp.i386_regs.ctrl;
+ to->FloatSave.StatusWord = from->fp.i386_regs.status;
+ to->FloatSave.TagWord = from->fp.i386_regs.tag;
+ to->FloatSave.ErrorOffset = from->fp.i386_regs.err_off;
+ to->FloatSave.ErrorSelector = from->fp.i386_regs.err_sel;
+ to->FloatSave.DataOffset = from->fp.i386_regs.data_off;
+ to->FloatSave.DataSelector = from->fp.i386_regs.data_sel;
+ to->FloatSave.Cr0NpxState = from->fp.i386_regs.cr0npx;
+ memcpy( to->FloatSave.RegisterArea, from->fp.i386_regs.regs, sizeof(to->FloatSave.RegisterArea) );
+ }
+ if (from->flags & SERVER_CTX_DEBUG_REGISTERS)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_DEBUG_REGISTERS;
+ to->Dr0 = from->debug.i386_regs.dr0;
+ to->Dr1 = from->debug.i386_regs.dr1;
+ to->Dr2 = from->debug.i386_regs.dr2;
+ to->Dr3 = from->debug.i386_regs.dr3;
+ to->Dr6 = from->debug.i386_regs.dr6;
+ to->Dr7 = from->debug.i386_regs.dr7;
+ }
+ if (from->flags & SERVER_CTX_EXTENDED_REGISTERS)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_EXTENDED_REGISTERS;
+ memcpy( to->ExtendedRegisters, from->ext.i386_regs, sizeof(to->ExtendedRegisters) );
+ }
+ return STATUS_SUCCESS;
+}
+
+
+/******************************************************************************
+ * RtlWow64GetThreadContext (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlWow64GetThreadContext( HANDLE handle, WOW64_CONTEXT *context )
+{
+ BOOL self;
+ context_t server_context;
+ unsigned int server_flags = wow64_get_server_context_flags( context->ContextFlags );
+ NTSTATUS ret = get_server_context( handle, server_flags, &server_context, &self );
+ if (!ret) ret = wow64_context_from_server( context, &server_context );
+ return ret;
+}
+#endif
/******************************************************************************
* NtQueryInformationThread (NTDLL.@)
--
2.7.4
June 6, 2018
[PATCH v2 1/5] winnt.h: Add some WOW64 definitions.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
include/winnt.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/include/winnt.h b/include/winnt.h
index 54bf11d..c41eff4 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -2112,6 +2112,96 @@ typedef CONTEXT *PCONTEXT;
NTSYSAPI void WINAPI RtlCaptureContext(CONTEXT*);
+#define WOW64_CONTEXT_i386 0x00010000
+#define WOW64_CONTEXT_i486 0x00010000
+#define WOW64_CONTEXT_CONTROL (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000001))
+#define WOW64_CONTEXT_INTEGER (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000002))
+#define WOW64_CONTEXT_SEGMENTS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000004))
+#define WOW64_CONTEXT_FLOATING_POINT (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000008))
+#define WOW64_CONTEXT_DEBUG_REGISTERS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000010))
+#define WOW64_CONTEXT_EXTENDED_REGISTERS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000020))
+#define WOW64_CONTEXT_FULL (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS)
+#define WOW64_CONTEXT_ALL (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | \
+ WOW64_CONTEXT_SEGMENTS | WOW64_CONTEXT_FLOATING_POINT | \
+ WOW64_CONTEXT_DEBUG_REGISTERS | WOW64_CONTEXT_EXTENDED_REGISTERS)
+
+#define WOW64_CONTEXT_XSTATE (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000040))
+
+#define WOW64_CONTEXT_EXCEPTION_ACTIVE 0x08000000
+#define WOW64_CONTEXT_SERVICE_ACTIVE 0x10000000
+#define WOW64_CONTEXT_EXCEPTION_REQUEST 0x40000000
+#define WOW64_CONTEXT_EXCEPTION_REPORTING 0x80000000
+
+#define WOW64_SIZE_OF_80387_REGISTERS 80
+#define WOW64_MAXIMUM_SUPPORTED_EXTENSION 512
+
+typedef struct _WOW64_FLOATING_SAVE_AREA {
+ DWORD ControlWord;
+ DWORD StatusWord;
+ DWORD TagWord;
+ DWORD ErrorOffset;
+ DWORD ErrorSelector;
+ DWORD DataOffset;
+ DWORD DataSelector;
+ BYTE RegisterArea[WOW64_SIZE_OF_80387_REGISTERS];
+ DWORD Cr0NpxState;
+} WOW64_FLOATING_SAVE_AREA, *PWOW64_FLOATING_SAVE_AREA;
+
+#include "pshpack4.h"
+typedef struct _WOW64_CONTEXT {
+ DWORD ContextFlags;
+ DWORD Dr0;
+ DWORD Dr1;
+ DWORD Dr2;
+ DWORD Dr3;
+ DWORD Dr6;
+ DWORD Dr7;
+ WOW64_FLOATING_SAVE_AREA FloatSave;
+ DWORD SegGs;
+ DWORD SegFs;
+ DWORD SegEs;
+ DWORD SegDs;
+ DWORD Edi;
+ DWORD Esi;
+ DWORD Ebx;
+ DWORD Edx;
+ DWORD Ecx;
+ DWORD Eax;
+ DWORD Ebp;
+ DWORD Eip;
+ DWORD SegCs;
+ DWORD EFlags;
+ DWORD Esp;
+ DWORD SegSs;
+ BYTE ExtendedRegisters[WOW64_MAXIMUM_SUPPORTED_EXTENSION];
+} WOW64_CONTEXT, *PWOW64_CONTEXT;
+#include "poppack.h"
+
+typedef struct _WOW64_LDT_ENTRY {
+ WORD LimitLow;
+ WORD BaseLow;
+ union {
+ struct {
+ BYTE BaseMid;
+ BYTE Flags1;
+ BYTE Flags2;
+ BYTE BaseHi;
+ } Bytes;
+ struct {
+ DWORD BaseMid : 8;
+ DWORD Type : 5;
+ DWORD Dpl : 2;
+ DWORD Pres : 1;
+ DWORD LimitHi : 4;
+ DWORD Sys : 1;
+ DWORD Reserved_0 : 1;
+ DWORD Default_Big : 1;
+ DWORD Granularity : 1;
+ DWORD BaseHi : 8;
+ } Bits;
+ } HighWord;
+} WOW64_LDT_ENTRY, *PWOW64_LDT_ENTRY;
+
/*
* Product types
*/
--
2.7.4
June 6, 2018
Re: [PATCH 4/5] d3d9: Get rid of an unnecessary wined3d_device_set_base_vertex_index() call.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 6, 2018
Re: [PATCH 5/5] d3d11/tests: Add test for negative viewport coordinates.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 6, 2018
Re: [PATCH] d3d8/tests: Use the available ARRAY_SIZE() macro
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 6, 2018