Commit 36371075 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Pass the server context to get/set_thread_context().

parent e470221d
...@@ -55,8 +55,8 @@ extern LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) DE ...@@ -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 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_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 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 set_thread_context( HANDLE handle, const context_t *context, BOOL *self ) DECLSPEC_HIDDEN;
extern NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN; extern NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int flags, BOOL *self ) DECLSPEC_HIDDEN;
/* debug helpers */ /* debug helpers */
extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN; extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
......
...@@ -294,6 +294,24 @@ __ASM_GLOBAL_FUNC( set_cpu_context, ...@@ -294,6 +294,24 @@ __ASM_GLOBAL_FUNC( set_cpu_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_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 * copy_context
* *
* Copy a register context according to the flags. * Copy a register context according to the flags.
...@@ -449,8 +467,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) ...@@ -449,8 +467,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
{ {
NTSTATUS ret; NTSTATUS ret;
BOOL self; 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 ); if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
return ret; return ret;
} }
...@@ -468,7 +488,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) ...@@ -468,7 +488,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
if (!self) 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; needed_flags &= ~context->ContextFlags;
} }
......
...@@ -232,6 +232,23 @@ static void set_cpu_context( const CONTEXT *context ) ...@@ -232,6 +232,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;
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 * copy_context
* *
* Copy a register context according to the flags. * Copy a register context according to the flags.
...@@ -363,8 +380,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) ...@@ -363,8 +380,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
{ {
NTSTATUS ret; NTSTATUS ret;
BOOL self; 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 ); if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
return ret; return ret;
} }
...@@ -382,7 +401,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) ...@@ -382,7 +401,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
if (!self) 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; needed_flags &= ~context->ContextFlags;
} }
......
...@@ -1169,6 +1169,26 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context ) ...@@ -1169,6 +1169,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 * context_to_server
* *
* Convert a register context to the server format. * Convert a register context to the server format.
...@@ -1328,7 +1348,12 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) ...@@ -1328,7 +1348,12 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
x86_thread_data()->dr6 == context->Dr6 && x86_thread_data()->dr6 == context->Dr6 &&
x86_thread_data()->dr7 == context->Dr7); 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 ); if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
return ret; return ret;
...@@ -1355,7 +1380,11 @@ NTSTATUS CDECL DECLSPEC_HIDDEN __regs_NtGetContextThread( DWORD edi, DWORD esi, ...@@ -1355,7 +1380,11 @@ NTSTATUS CDECL DECLSPEC_HIDDEN __regs_NtGetContextThread( DWORD edi, DWORD esi,
if (!self) 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; needed_flags &= ~context->ContextFlags;
} }
......
...@@ -275,6 +275,23 @@ static void set_cpu_context( const CONTEXT *context ) ...@@ -275,6 +275,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 * copy_context
* *
* Copy a register context according to the flags. * Copy a register context according to the flags.
...@@ -577,8 +594,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) ...@@ -577,8 +594,10 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
{ {
NTSTATUS ret; NTSTATUS ret;
BOOL self; 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 ); if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
return ret; return ret;
} }
...@@ -596,7 +615,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) ...@@ -596,7 +615,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
if (!self) 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; needed_flags &= ~context->ContextFlags;
} }
......
...@@ -1914,6 +1914,25 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context ) ...@@ -1914,6 +1914,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 * copy_context
* *
* Copy a register context according to the flags. * Copy a register context according to the flags.
...@@ -2123,8 +2142,12 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) ...@@ -2123,8 +2142,12 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
amd64_thread_data()->dr6 == context->Dr6 && amd64_thread_data()->dr6 == context->Dr6 &&
amd64_thread_data()->dr7 == context->Dr7); 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 ); if (self && ret == STATUS_SUCCESS) set_cpu_context( context );
return ret; return ret;
} }
...@@ -2145,7 +2168,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) ...@@ -2145,7 +2168,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
if (!self) 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; needed_flags &= ~context->ContextFlags;
} }
......
...@@ -855,19 +855,16 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void) ...@@ -855,19 +855,16 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
/*********************************************************************** /***********************************************************************
* set_thread_context * 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; NTSTATUS ret;
DWORD dummy, i; DWORD dummy, i;
context_t server_context;
context_to_server( &server_context, context );
SERVER_START_REQ( set_thread_context ) SERVER_START_REQ( set_thread_context )
{ {
req->handle = wine_server_obj_handle( handle ); req->handle = wine_server_obj_handle( handle );
req->suspend = 1; 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 ); ret = wine_server_call( req );
*self = reply->self; *self = reply->self;
} }
...@@ -881,7 +878,7 @@ NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self ) ...@@ -881,7 +878,7 @@ NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
{ {
req->handle = wine_server_obj_handle( handle ); req->handle = wine_server_obj_handle( handle );
req->suspend = 0; 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 ); ret = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -901,45 +898,20 @@ NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self ) ...@@ -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 * 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; NTSTATUS ret;
DWORD dummy, i; DWORD dummy, i;
unsigned int server_flags = get_server_context_flags( context->ContextFlags );
context_t server_context;
SERVER_START_REQ( get_thread_context ) SERVER_START_REQ( get_thread_context )
{ {
req->handle = wine_server_obj_handle( handle ); req->handle = wine_server_obj_handle( handle );
req->flags = server_flags; req->flags = flags;
req->suspend = 1; 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 ); ret = wine_server_call( req );
*self = reply->self; *self = reply->self;
} }
...@@ -952,9 +924,9 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self ) ...@@ -952,9 +924,9 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
SERVER_START_REQ( get_thread_context ) SERVER_START_REQ( get_thread_context )
{ {
req->handle = wine_server_obj_handle( handle ); req->handle = wine_server_obj_handle( handle );
req->flags = server_flags; req->flags = flags;
req->suspend = 0; 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 ); ret = wine_server_call( req );
} }
SERVER_END_REQ; SERVER_END_REQ;
...@@ -969,7 +941,6 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self ) ...@@ -969,7 +941,6 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
NtResumeThread( handle, &dummy ); NtResumeThread( handle, &dummy );
if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED; if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
} }
if (!ret) ret = context_from_server( context, &server_context );
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment