Don't send the incoming context to the server for get_thread_context,

instead copy only the relevant fields of the return value on the
client side.
This commit is contained in:
Alexandre Julliard 2005-11-01 21:41:26 +00:00
parent ecca104869
commit d6f7adb367
5 changed files with 232 additions and 6 deletions

View File

@ -498,6 +498,231 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/* copy a context structure according to the flags */
static inline void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
{
#ifdef __i386__
if (flags & CONTEXT_INTEGER)
{
to->Eax = from->Eax;
to->Ebx = from->Ebx;
to->Ecx = from->Ecx;
to->Edx = from->Edx;
to->Esi = from->Esi;
to->Edi = from->Edi;
}
if (flags & CONTEXT_CONTROL)
{
to->Ebp = from->Ebp;
to->Esp = from->Esp;
to->Eip = from->Eip;
to->SegCs = from->SegCs;
to->SegSs = from->SegSs;
to->EFlags = from->EFlags;
}
if (flags & CONTEXT_SEGMENTS)
{
to->SegDs = from->SegDs;
to->SegEs = from->SegEs;
to->SegFs = from->SegFs;
to->SegGs = from->SegGs;
}
if (flags & CONTEXT_DEBUG_REGISTERS)
{
to->Dr0 = from->Dr0;
to->Dr1 = from->Dr1;
to->Dr2 = from->Dr2;
to->Dr3 = from->Dr3;
to->Dr6 = from->Dr6;
to->Dr7 = from->Dr7;
}
if (flags & CONTEXT_FLOATING_POINT)
{
to->FloatSave = from->FloatSave;
}
#elif defined(__x86_64__)
if (flags & CONTEXT_CONTROL)
{
to->Rbp = from->Rbp;
to->Rip = from->Rip;
to->Rsp = from->Rsp;
to->SegCs = from->SegCs;
to->SegSs = from->SegSs;
to->EFlags = from->EFlags;
to->MxCsr = from->MxCsr;
}
if (flags & CONTEXT_INTEGER)
{
to->Rax = from->Rax;
to->Rcx = from->Rcx;
to->Rdx = from->Rdx;
to->Rbx = from->Rbx;
to->Rsi = from->Rsi;
to->Rdi = from->Rdi;
to->R8 = from->R8;
to->R9 = from->R9;
to->R10 = from->R10;
to->R11 = from->R11;
to->R12 = from->R12;
to->R13 = from->R13;
to->R14 = from->R14;
to->R15 = from->R15;
}
if (flags & CONTEXT_SEGMENTS)
{
to->SegDs = from->SegDs;
to->SegEs = from->SegEs;
to->SegFs = from->SegFs;
to->SegGs = from->SegGs;
}
if (flags & CONTEXT_FLOATING_POINT)
{
to->u.FltSave = from->u.FltSave;
}
if (flags & CONTEXT_DEBUG_REGISTERS)
{
to->Dr0 = from->Dr0;
to->Dr1 = from->Dr1;
to->Dr2 = from->Dr2;
to->Dr3 = from->Dr3;
to->Dr6 = from->Dr6;
to->Dr7 = from->Dr7;
}
#elif defined(__sparc__)
if (flags & CONTEXT_CONTROL)
{
to->psr = from->psr;
to->pc = from->pc;
to->npc = from->npc;
to->y = from->y;
to->wim = from->wim;
to->tbr = from->tbr;
}
if (flags & CONTEXT_INTEGER)
{
to->g0 = from->g0;
to->g1 = from->g1;
to->g2 = from->g2;
to->g3 = from->g3;
to->g4 = from->g4;
to->g5 = from->g5;
to->g6 = from->g6;
to->g7 = from->g7;
to->o0 = from->o0;
to->o1 = from->o1;
to->o2 = from->o2;
to->o3 = from->o3;
to->o4 = from->o4;
to->o5 = from->o5;
to->o6 = from->o6;
to->o7 = from->o7;
to->l0 = from->l0;
to->l1 = from->l1;
to->l2 = from->l2;
to->l3 = from->l3;
to->l4 = from->l4;
to->l5 = from->l5;
to->l6 = from->l6;
to->l7 = from->l7;
to->i0 = from->i0;
to->i1 = from->i1;
to->i2 = from->i2;
to->i3 = from->i3;
to->i4 = from->i4;
to->i5 = from->i5;
to->i6 = from->i6;
to->i7 = from->i7;
}
if (flags & CONTEXT_FLOATING_POINT)
{
/* FIXME */
}
#elif defined(__powerpc__)
if (flags & CONTEXT_CONTROL)
{
to->Msr = from->Msr;
to->Ctr = from->Ctr;
to->Iar = from->Iar;
}
if (flags & CONTEXT_INTEGER)
{
to->Gpr0 = from->Gpr0;
to->Gpr1 = from->Gpr1;
to->Gpr2 = from->Gpr2;
to->Gpr3 = from->Gpr3;
to->Gpr4 = from->Gpr4;
to->Gpr5 = from->Gpr5;
to->Gpr6 = from->Gpr6;
to->Gpr7 = from->Gpr7;
to->Gpr8 = from->Gpr8;
to->Gpr9 = from->Gpr9;
to->Gpr10 = from->Gpr10;
to->Gpr11 = from->Gpr11;
to->Gpr12 = from->Gpr12;
to->Gpr13 = from->Gpr13;
to->Gpr14 = from->Gpr14;
to->Gpr15 = from->Gpr15;
to->Gpr16 = from->Gpr16;
to->Gpr17 = from->Gpr17;
to->Gpr18 = from->Gpr18;
to->Gpr19 = from->Gpr19;
to->Gpr20 = from->Gpr20;
to->Gpr21 = from->Gpr21;
to->Gpr22 = from->Gpr22;
to->Gpr23 = from->Gpr23;
to->Gpr24 = from->Gpr24;
to->Gpr25 = from->Gpr25;
to->Gpr26 = from->Gpr26;
to->Gpr27 = from->Gpr27;
to->Gpr28 = from->Gpr28;
to->Gpr29 = from->Gpr29;
to->Gpr30 = from->Gpr30;
to->Gpr31 = from->Gpr31;
to->Xer = from->Xer;
to->Cr = from->Cr;
}
if (flags & CONTEXT_FLOATING_POINT)
{
to->Fpr0 = from->Fpr0;
to->Fpr1 = from->Fpr1;
to->Fpr2 = from->Fpr2;
to->Fpr3 = from->Fpr3;
to->Fpr4 = from->Fpr4;
to->Fpr5 = from->Fpr5;
to->Fpr6 = from->Fpr6;
to->Fpr7 = from->Fpr7;
to->Fpr8 = from->Fpr8;
to->Fpr9 = from->Fpr9;
to->Fpr10 = from->Fpr10;
to->Fpr11 = from->Fpr11;
to->Fpr12 = from->Fpr12;
to->Fpr13 = from->Fpr13;
to->Fpr14 = from->Fpr14;
to->Fpr15 = from->Fpr15;
to->Fpr16 = from->Fpr16;
to->Fpr17 = from->Fpr17;
to->Fpr18 = from->Fpr18;
to->Fpr19 = from->Fpr19;
to->Fpr20 = from->Fpr20;
to->Fpr21 = from->Fpr21;
to->Fpr22 = from->Fpr22;
to->Fpr23 = from->Fpr23;
to->Fpr24 = from->Fpr24;
to->Fpr25 = from->Fpr25;
to->Fpr26 = from->Fpr26;
to->Fpr27 = from->Fpr27;
to->Fpr28 = from->Fpr28;
to->Fpr29 = from->Fpr29;
to->Fpr30 = from->Fpr30;
to->Fpr31 = from->Fpr31;
to->Fpscr = from->Fpscr;
}
#else
#error You must implement context copying for your CPU
#endif
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
@ -505,16 +730,17 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
{
NTSTATUS ret;
CONTEXT ctx;
SERVER_START_REQ( get_thread_context )
{
req->handle = handle;
req->flags = context->ContextFlags;
wine_server_add_data( req, context, sizeof(*context) );
wine_server_set_reply( req, context, sizeof(*context) );
wine_server_set_reply( req, &ctx, sizeof(ctx) );
ret = wine_server_call( req );
}
SERVER_END_REQ;
if (ret == STATUS_SUCCESS) copy_context( context, &ctx, context->ContextFlags );
return ret;
}

View File

@ -587,9 +587,7 @@ DECL_HANDLER(get_thread_context)
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
{
/* copy incoming context into reply */
memset( data, 0, sizeof(CONTEXT) );
memcpy( data, get_req_data(), min( get_req_data_size(), sizeof(CONTEXT) ));
if (thread->context) /* thread is inside an exception event */
{

View File

@ -306,6 +306,8 @@ DECL_HANDLER(get_thread_context)
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
{
memset( data, 0, sizeof(CONTEXT) );
if (thread->context) /* thread is inside an exception event */
{
copy_context( data, thread->context, flags );

View File

@ -200,6 +200,8 @@ DECL_HANDLER(get_thread_context)
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
{
memset( data, 0, sizeof(CONTEXT) );
if (thread->context) /* thread is inside an exception event */
{
copy_context( data, thread->context, flags );

View File

@ -298,9 +298,7 @@ DECL_HANDLER(get_thread_context)
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
{
/* copy incoming context into reply */
memset( data, 0, sizeof(CONTEXT) );
memcpy( data, get_req_data(), min( get_req_data_size(), sizeof(CONTEXT) ));
if (thread->context) /* thread is inside an exception event */
{