ntdll: Pass the server context to get/set_thread_context().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e470221dca
commit
36371075f8
|
@ -55,8 +55,8 @@ extern LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) DE
|
|||
extern void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec ) DECLSPEC_NORETURN DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self ) 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;
|
||||
|
||||
/* debug helpers */
|
||||
extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -293,6 +293,24 @@ __ASM_GLOBAL_FUNC( set_cpu_context,
|
|||
"pop {pc}" )
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_server_context_flags
|
||||
*
|
||||
* Convert CPU-specific flags to generic server flags
|
||||
*/
|
||||
static unsigned int get_server_context_flags( DWORD flags )
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
flags &= ~CONTEXT_ARM; /* get rid of CPU id */
|
||||
if (flags & CONTEXT_CONTROL) ret |= SERVER_CTX_CONTROL;
|
||||
if (flags & CONTEXT_INTEGER) ret |= SERVER_CTX_INTEGER;
|
||||
if (flags & CONTEXT_FLOATING_POINT) ret |= SERVER_CTX_FLOATING_POINT;
|
||||
if (flags & CONTEXT_DEBUG_REGISTERS) ret |= SERVER_CTX_DEBUG_REGISTERS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* copy_context
|
||||
*
|
||||
|
@ -449,8 +467,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
|||
{
|
||||
NTSTATUS ret;
|
||||
BOOL self;
|
||||
context_t server_context;
|
||||
|
||||
ret = set_thread_context( handle, context, &self );
|
||||
context_to_server( &server_context, context );
|
||||
ret = set_thread_context( handle, &server_context, &self );
|
||||
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||
return ret;
|
||||
}
|
||||
|
@ -468,7 +488,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
|
|||
|
||||
if (!self)
|
||||
{
|
||||
if ((ret = get_thread_context( handle, context, &self ))) return ret;
|
||||
context_t server_context;
|
||||
unsigned int server_flags = get_server_context_flags( context->ContextFlags );
|
||||
|
||||
if ((ret = get_thread_context( handle, &server_context, server_flags, &self ))) return ret;
|
||||
if ((ret = context_from_server( context, &server_context ))) return ret;
|
||||
needed_flags &= ~context->ContextFlags;
|
||||
}
|
||||
|
||||
|
|
|
@ -231,6 +231,23 @@ static void set_cpu_context( const CONTEXT *context )
|
|||
FIXME( "Not implemented on ARM64\n" );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_server_context_flags
|
||||
*
|
||||
* Convert CPU-specific flags to generic server flags
|
||||
*/
|
||||
static unsigned int get_server_context_flags( DWORD flags )
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
flags &= ~CONTEXT_ARM64; /* get rid of CPU id */
|
||||
if (flags & CONTEXT_CONTROL) ret |= SERVER_CTX_CONTROL;
|
||||
if (flags & CONTEXT_INTEGER) ret |= SERVER_CTX_INTEGER;
|
||||
if (flags & CONTEXT_FLOATING_POINT) ret |= SERVER_CTX_FLOATING_POINT;
|
||||
if (flags & CONTEXT_DEBUG_REGISTERS) ret |= SERVER_CTX_DEBUG_REGISTERS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* copy_context
|
||||
*
|
||||
|
@ -363,8 +380,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
|||
{
|
||||
NTSTATUS ret;
|
||||
BOOL self;
|
||||
context_t server_context;
|
||||
|
||||
ret = set_thread_context( handle, context, &self );
|
||||
context_to_server( &server_context, context );
|
||||
ret = set_thread_context( handle, &server_context, &self );
|
||||
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||
return ret;
|
||||
}
|
||||
|
@ -382,7 +401,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
|
|||
|
||||
if (!self)
|
||||
{
|
||||
if ((ret = get_thread_context( handle, context, &self ))) return ret;
|
||||
context_t server_context;
|
||||
unsigned int server_flags = get_server_context_flags( context->ContextFlags );
|
||||
|
||||
if ((ret = get_thread_context( handle, &server_context, server_flags, &self ))) return ret;
|
||||
if ((ret = context_from_server( context, &server_context ))) return ret;
|
||||
needed_flags &= ~context->ContextFlags;
|
||||
}
|
||||
|
||||
|
|
|
@ -1168,6 +1168,26 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_server_context_flags
|
||||
*
|
||||
* Convert CPU-specific flags to generic server flags
|
||||
*/
|
||||
static unsigned int get_server_context_flags( DWORD flags )
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
flags &= ~CONTEXT_i386; /* get rid of CPU id */
|
||||
if (flags & CONTEXT_CONTROL) ret |= SERVER_CTX_CONTROL;
|
||||
if (flags & CONTEXT_INTEGER) ret |= SERVER_CTX_INTEGER;
|
||||
if (flags & CONTEXT_SEGMENTS) ret |= SERVER_CTX_SEGMENTS;
|
||||
if (flags & CONTEXT_FLOATING_POINT) ret |= SERVER_CTX_FLOATING_POINT;
|
||||
if (flags & CONTEXT_DEBUG_REGISTERS) ret |= SERVER_CTX_DEBUG_REGISTERS;
|
||||
if (flags & CONTEXT_EXTENDED_REGISTERS) ret |= SERVER_CTX_EXTENDED_REGISTERS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* context_to_server
|
||||
*
|
||||
|
@ -1328,7 +1348,12 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
|||
x86_thread_data()->dr6 == context->Dr6 &&
|
||||
x86_thread_data()->dr7 == context->Dr7);
|
||||
|
||||
if (!self) ret = set_thread_context( handle, context, &self );
|
||||
if (!self)
|
||||
{
|
||||
context_t server_context;
|
||||
context_to_server( &server_context, context );
|
||||
ret = set_thread_context( handle, &server_context, &self );
|
||||
}
|
||||
|
||||
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||
return ret;
|
||||
|
@ -1355,7 +1380,11 @@ NTSTATUS CDECL DECLSPEC_HIDDEN __regs_NtGetContextThread( DWORD edi, DWORD esi,
|
|||
|
||||
if (!self)
|
||||
{
|
||||
if ((ret = get_thread_context( handle, context, &self ))) return ret;
|
||||
context_t server_context;
|
||||
unsigned int server_flags = get_server_context_flags( context->ContextFlags );
|
||||
|
||||
if ((ret = get_thread_context( handle, &server_context, server_flags, &self ))) return ret;
|
||||
if ((ret = context_from_server( context, &server_context ))) return ret;
|
||||
needed_flags &= ~context->ContextFlags;
|
||||
}
|
||||
|
||||
|
|
|
@ -274,6 +274,23 @@ static void set_cpu_context( const CONTEXT *context )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_server_context_flags
|
||||
*
|
||||
* Convert CPU-specific flags to generic server flags
|
||||
*/
|
||||
static unsigned int get_server_context_flags( DWORD flags )
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
if (flags & CONTEXT_CONTROL) ret |= SERVER_CTX_CONTROL;
|
||||
if (flags & CONTEXT_INTEGER) ret |= SERVER_CTX_INTEGER;
|
||||
if (flags & CONTEXT_FLOATING_POINT) ret |= SERVER_CTX_FLOATING_POINT;
|
||||
if (flags & CONTEXT_DEBUG_REGISTERS) ret |= SERVER_CTX_DEBUG_REGISTERS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* copy_context
|
||||
*
|
||||
|
@ -577,8 +594,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
|||
{
|
||||
NTSTATUS ret;
|
||||
BOOL self;
|
||||
context_t server_context;
|
||||
|
||||
ret = set_thread_context( handle, context, &self );
|
||||
context_to_server( &server_context, context );
|
||||
ret = set_thread_context( handle, &server_context, &self );
|
||||
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||
return ret;
|
||||
}
|
||||
|
@ -596,7 +615,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
|
|||
|
||||
if (!self)
|
||||
{
|
||||
if ((ret = get_thread_context( handle, context, &self ))) return ret;
|
||||
context_t server_context;
|
||||
unsigned int server_flags = get_server_context_flags( context->ContextFlags );
|
||||
|
||||
if ((ret = get_thread_context( handle, &server_context, server_flags, &self ))) return ret;
|
||||
if ((ret = context_from_server( context, &server_context ))) return ret;
|
||||
needed_flags &= ~context->ContextFlags;
|
||||
}
|
||||
|
||||
|
|
|
@ -1913,6 +1913,25 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_server_context_flags
|
||||
*
|
||||
* Convert CPU-specific flags to generic server flags
|
||||
*/
|
||||
static unsigned int get_server_context_flags( DWORD flags )
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
flags &= ~CONTEXT_AMD64; /* get rid of CPU id */
|
||||
if (flags & CONTEXT_CONTROL) ret |= SERVER_CTX_CONTROL;
|
||||
if (flags & CONTEXT_INTEGER) ret |= SERVER_CTX_INTEGER;
|
||||
if (flags & CONTEXT_SEGMENTS) ret |= SERVER_CTX_SEGMENTS;
|
||||
if (flags & CONTEXT_FLOATING_POINT) ret |= SERVER_CTX_FLOATING_POINT;
|
||||
if (flags & CONTEXT_DEBUG_REGISTERS) ret |= SERVER_CTX_DEBUG_REGISTERS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* copy_context
|
||||
*
|
||||
|
@ -2123,8 +2142,12 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
|
|||
amd64_thread_data()->dr6 == context->Dr6 &&
|
||||
amd64_thread_data()->dr7 == context->Dr7);
|
||||
|
||||
if (!self) ret = set_thread_context( handle, context, &self );
|
||||
|
||||
if (!self)
|
||||
{
|
||||
context_t server_context;
|
||||
context_to_server( &server_context, context );
|
||||
ret = set_thread_context( handle, &server_context, &self );
|
||||
}
|
||||
if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
|
||||
return ret;
|
||||
}
|
||||
|
@ -2145,7 +2168,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
|
|||
|
||||
if (!self)
|
||||
{
|
||||
if ((ret = get_thread_context( handle, context, &self ))) return ret;
|
||||
context_t server_context;
|
||||
unsigned int server_flags = get_server_context_flags( context->ContextFlags );
|
||||
|
||||
if ((ret = get_thread_context( handle, &server_context, server_flags, &self ))) return ret;
|
||||
if ((ret = context_from_server( context, &server_context ))) return ret;
|
||||
needed_flags &= ~context->ContextFlags;
|
||||
}
|
||||
|
||||
|
|
|
@ -855,19 +855,16 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
|
|||
/***********************************************************************
|
||||
* set_thread_context
|
||||
*/
|
||||
NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
|
||||
NTSTATUS set_thread_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 +878,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;
|
||||
|
@ -901,45 +898,20 @@ NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
|
|||
}
|
||||
|
||||
|
||||
/* convert CPU-specific flags to generic server flags */
|
||||
static inline unsigned int get_server_context_flags( DWORD flags )
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
flags &= 0x3f; /* mask CPU id flags */
|
||||
if (flags & CONTEXT_CONTROL) ret |= SERVER_CTX_CONTROL;
|
||||
if (flags & CONTEXT_INTEGER) ret |= SERVER_CTX_INTEGER;
|
||||
#ifdef CONTEXT_SEGMENTS
|
||||
if (flags & CONTEXT_SEGMENTS) ret |= SERVER_CTX_SEGMENTS;
|
||||
#endif
|
||||
#ifdef CONTEXT_FLOATING_POINT
|
||||
if (flags & CONTEXT_FLOATING_POINT) ret |= SERVER_CTX_FLOATING_POINT;
|
||||
#endif
|
||||
#ifdef CONTEXT_DEBUG_REGISTERS
|
||||
if (flags & CONTEXT_DEBUG_REGISTERS) ret |= SERVER_CTX_DEBUG_REGISTERS;
|
||||
#endif
|
||||
#ifdef CONTEXT_EXTENDED_REGISTERS
|
||||
if (flags & CONTEXT_EXTENDED_REGISTERS) ret |= SERVER_CTX_EXTENDED_REGISTERS;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_thread_context
|
||||
*/
|
||||
NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
|
||||
NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, 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->flags = 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;
|
||||
}
|
||||
|
@ -952,9 +924,9 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
|
|||
SERVER_START_REQ( get_thread_context )
|
||||
{
|
||||
req->handle = wine_server_obj_handle( handle );
|
||||
req->flags = server_flags;
|
||||
req->flags = 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,7 +941,6 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
|
|||
NtResumeThread( handle, &dummy );
|
||||
if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
|
||||
}
|
||||
if (!ret) ret = context_from_server( context, &server_context );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue