Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
2e6a2cf9
Commit
2e6a2cf9
authored
Jun 18, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move the WoW64 thread context functions to the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
e84ec36a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
194 additions
and
228 deletions
+194
-228
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+0
-2
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+2
-166
thread.c
dlls/ntdll/thread.c
+0
-60
thread.c
dlls/ntdll/unix/thread.c
+192
-0
No files found.
dlls/ntdll/ntdll_misc.h
View file @
2e6a2cf9
...
...
@@ -59,8 +59,6 @@ extern NTSTATUS close_handle( HANDLE ) DECLSPEC_HIDDEN;
/* exceptions */
extern
LONG
call_vectored_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
DECLSPEC_HIDDEN
;
extern
void
DECLSPEC_NORETURN
raise_status
(
NTSTATUS
status
,
EXCEPTION_RECORD
*
rec
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
set_thread_context
(
HANDLE
handle
,
const
context_t
*
context
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
LONG
WINAPI
call_unhandled_exception_filter
(
PEXCEPTION_POINTERS
eptr
)
DECLSPEC_HIDDEN
;
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
...
...
dlls/ntdll/signal_x86_64.c
View file @
2e6a2cf9
...
...
@@ -1724,172 +1724,12 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
}
/***********************************************************************
* wow64_get_server_context_flags
*/
static
unsigned
int
wow64_get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
WOW64_CONTEXT_i386
;
/* get rid of CPU id */
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
;
}
/***********************************************************************
* wow64_context_from_server
*/
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
;
}
/***********************************************************************
* 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.@)
*/
NTSTATUS
WINAPI
RtlWow64GetThreadContext
(
HANDLE
handle
,
WOW64_CONTEXT
*
context
)
{
BOOL
self
;
NTSTATUS
ret
;
context_t
server_context
;
unsigned
int
server_flags
=
wow64_get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
(
self
)
return
STATUS_INVALID_PARAMETER
;
return
wow64_context_from_server
(
context
,
&
server_context
);
return
NtQueryInformationThread
(
handle
,
ThreadWow64Context
,
context
,
sizeof
(
*
context
),
NULL
);
}
...
...
@@ -1898,11 +1738,7 @@ NTSTATUS WINAPI RtlWow64GetThreadContext( HANDLE handle, WOW64_CONTEXT *context
*/
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
);
return
NtSetInformationThread
(
handle
,
ThreadWow64Context
,
context
,
sizeof
(
*
context
)
);
}
...
...
dlls/ntdll/thread.c
View file @
2e6a2cf9
...
...
@@ -468,66 +468,6 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
/***********************************************************************
* set_thread_context
*/
NTSTATUS
set_thread_context
(
HANDLE
handle
,
const
context_t
*
context
,
BOOL
*
self
)
{
NTSTATUS
ret
;
SERVER_START_REQ
(
set_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
*
self
=
reply
->
self
;
}
SERVER_END_REQ
;
return
ret
;
}
/***********************************************************************
* get_thread_context
*/
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
BOOL
*
self
)
{
NTSTATUS
ret
;
SERVER_START_REQ
(
get_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
flags
=
flags
;
wine_server_set_reply
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
*
self
=
reply
->
self
;
handle
=
wine_server_ptr_handle
(
reply
->
handle
);
}
SERVER_END_REQ
;
if
(
ret
==
STATUS_PENDING
)
{
LARGE_INTEGER
timeout
;
timeout
.
QuadPart
=
-
1000000
;
if
(
NtWaitForSingleObject
(
handle
,
FALSE
,
&
timeout
))
{
NtClose
(
handle
);
return
STATUS_ACCESS_DENIED
;
}
SERVER_START_REQ
(
get_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
flags
=
flags
;
wine_server_set_reply
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
}
return
ret
;
}
/***********************************************************************
* NtContinue (NTDLL.@)
*/
NTSTATUS
WINAPI
NtContinue
(
CONTEXT
*
context
,
BOOLEAN
alertable
)
...
...
dlls/ntdll/unix/thread.c
View file @
2e6a2cf9
...
...
@@ -666,6 +666,163 @@ NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int fla
}
#ifdef __x86_64__
/***********************************************************************
* wow64_get_server_context_flags
*/
static
unsigned
int
wow64_get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
WOW64_CONTEXT_i386
;
/* get rid of CPU id */
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
;
}
/***********************************************************************
* wow64_context_from_server
*/
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
;
}
/***********************************************************************
* 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
)
);
}
}
#endif
/* __x86_64__ */
/******************************************************************************
* NtQueryInformationThread (NTDLL.@)
*/
...
...
@@ -886,6 +1043,26 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
return
status
;
}
case
ThreadWow64Context
:
{
#ifdef __x86_64__
BOOL
self
;
WOW64_CONTEXT
*
context
=
data
;
context_t
server_context
;
unsigned
int
server_flags
;
if
(
length
!=
sizeof
(
*
context
))
return
STATUS_INFO_LENGTH_MISMATCH
;
server_flags
=
wow64_get_server_context_flags
(
context
->
ContextFlags
);
if
((
status
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
status
;
if
(
self
)
return
STATUS_INVALID_PARAMETER
;
status
=
wow64_context_from_server
(
context
,
&
server_context
);
if
(
ret_len
&&
!
status
)
*
ret_len
=
sizeof
(
*
context
);
return
status
;
#else
return
STATUS_INVALID_INFO_CLASS
;
#endif
}
case
ThreadPriority
:
case
ThreadBasePriority
:
case
ThreadImpersonationToken
:
...
...
@@ -1041,6 +1218,21 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
return
status
;
}
case
ThreadWow64Context
:
{
#ifdef __x86_64__
BOOL
self
;
const
WOW64_CONTEXT
*
context
=
data
;
context_t
server_context
;
if
(
length
!=
sizeof
(
*
context
))
return
STATUS_INFO_LENGTH_MISMATCH
;
wow64_context_to_server
(
&
server_context
,
context
);
return
set_thread_context
(
handle
,
&
server_context
,
&
self
);
#else
return
STATUS_INVALID_INFO_CLASS
;
#endif
}
case
ThreadBasicInformation
:
case
ThreadTimes
:
case
ThreadPriority
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment