Fix DPMI Event Checking in K32WowCallback16Ex (Try 2)
Robert Shearman
rob at codeweavers.com
Tue Sep 28 06:46:13 CDT 2004
Changes from last patch on this:
- Remove removal of setting SegSs to current data segment.
Hi,
The first fix is to bail from the event check if we are inside the
system as we should do an event check when we go back to 16-bit code anyway.
The second fix is thanks to Jukka's suggestion that iret is only
emulated in bad cases. In this case it was due to stack corruption
caused by using a stale (1 or 2 DWORDs may have been added to it) stack
point in K32WowCallback16Ex. The fix was to always keep the stack
variable up-to-date.
Rob
Changelog:
- Don't perform event check if in system code. Fixes infinite recursion bug.
- Fix stack corruption that could occur in K32WowCallback16Ex if an
event check was inserted.
-------------- next part --------------
Index: wine/dlls/kernel/wowthunk.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/wowthunk.c,v
retrieving revision 1.52
diff -u -p -r1.52 wowthunk.c
--- wine/dlls/kernel/wowthunk.c 17 May 2004 21:08:31 -0000 1.52
+++ wine/dlls/kernel/wowthunk.c 28 Sep 2004 11:34:54 -0000
@@ -194,6 +194,10 @@ static void insert_event_check( CONTEXT
{
char *stack = wine_ldt_get_ptr( context->SegSs, context->Esp );
+ /* don't do event check while in system code */
+ if (wine_ldt_is_system(context->SegCs))
+ return;
+
if(context->SegCs == dpmi_checker_selector &&
context->Eip >= dpmi_checker_offset_call &&
context->Eip <= dpmi_checker_offset_cleanup)
@@ -598,7 +602,7 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vp
* (both for PASCAL and CDECL calling convention), so we simply
* copy them to the 16-bit stack ...
*/
- WORD *stack = (WORD *)CURRENT_STACK16 - cbArgs / sizeof(WORD);
+ char *stack = (char *)CURRENT_STACK16 - cbArgs;
memcpy( stack, pArgs, cbArgs );
@@ -609,11 +613,12 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vp
if (TRACE_ON(relay))
{
DWORD count = cbArgs / sizeof(WORD);
+ WORD * wstack = (WORD *)stack;
DPRINTF("%04lx:CallTo16(func=%04lx:%04x,ds=%04lx",
GetCurrentThreadId(),
context->SegCs, LOWORD(context->Eip), context->SegDs );
- while (count) DPRINTF( ",%04x", stack[--count] );
+ while (count) DPRINTF( ",%04x", wstack[--count] );
DPRINTF(") ss:sp=%04x:%04x",
SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) );
DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x si=%04x di=%04x bp=%04x es=%04x fs=%04x\n",
@@ -636,13 +641,16 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vp
/* push return address */
if (dwFlags & WCB16_REGS_LONG)
{
- *((DWORD *)stack - 1) = HIWORD(call16_ret_addr);
- *((DWORD *)stack - 2) = LOWORD(call16_ret_addr);
+ stack -= sizeof(DWORD);
+ *((DWORD *)stack) = HIWORD(call16_ret_addr);
+ stack -= sizeof(DWORD);
+ *((DWORD *)stack) = LOWORD(call16_ret_addr);
cbArgs += 2 * sizeof(DWORD);
}
else
{
- *((SEGPTR *)stack - 1) = call16_ret_addr;
+ stack -= sizeof(SEGPTR);
+ *((SEGPTR *)stack) = call16_ret_addr;
cbArgs += sizeof(SEGPTR);
}
@@ -682,18 +690,20 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vp
if (TRACE_ON(relay))
{
DWORD count = cbArgs / sizeof(WORD);
+ WORD * wstack = (WORD *)stack;
DPRINTF("%04lx:CallTo16(func=%04x:%04x,ds=%04x",
GetCurrentThreadId(), HIWORD(vpfn16), LOWORD(vpfn16),
SELECTOROF(NtCurrentTeb()->cur_stack) );
- while (count) DPRINTF( ",%04x", stack[--count] );
+ while (count) DPRINTF( ",%04x", wstack[--count] );
DPRINTF(") ss:sp=%04x:%04x\n",
SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) );
SYSLEVEL_CheckNotLevel( 2 );
}
/* push return address */
- *((SEGPTR *)stack - 1) = call16_ret_addr;
+ stack -= sizeof(SEGPTR);
+ *((SEGPTR *)stack) = call16_ret_addr;
cbArgs += sizeof(SEGPTR);
/*
More information about the wine-patches
mailing list