diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index 4dfaeddfb09..74e7bbafb78 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -1126,9 +1126,6 @@ @ varargs __wine_call_from_16_word() @ varargs __wine_call_from_16_long() @ varargs __wine_call_from_16_regs() -@ stdcall wine_call_to_16(ptr long) -@ stdcall wine_call_to_16_regs_short(ptr long) -@ stdcall wine_call_to_16_regs_long (ptr long) # Unix files @ stdcall wine_get_unix_file_name(str ptr long) diff --git a/dlls/kernel/ne_module.c b/dlls/kernel/ne_module.c index 1ce122e706e..b83bf648516 100644 --- a/dlls/kernel/ne_module.c +++ b/dlls/kernel/ne_module.c @@ -1284,7 +1284,7 @@ DWORD NE_StartTask(void) SELECTOROF(pTask->teb->cur_stack), OFFSETOF(pTask->teb->cur_stack) ); - wine_call_to_16_regs_short( &context, 0 ); + WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context ); ExitThread( LOWORD(context.Eax) ); } return hInstance; /* error code */ diff --git a/dlls/kernel/ne_segment.c b/dlls/kernel/ne_segment.c index 061f4a69594..3a28371b781 100644 --- a/dlls/kernel/ne_segment.c +++ b/dlls/kernel/ne_segment.c @@ -682,7 +682,7 @@ static BOOL NE_InitDLL( NE_MODULE *pModule ) TRACE_(dll)("Calling LibMain, cs:ip=%04lx:%04lx ds=%04lx di=%04x cx=%04x\n", context.SegCs, context.Eip, context.SegDs, LOWORD(context.Edi), LOWORD(context.Ecx) ); - wine_call_to_16_regs_short( &context, 0 ); + WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context ); return TRUE; } @@ -769,8 +769,8 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason ) } else { - LPBYTE stack = (LPBYTE)CURRENT_STACK16; CONTEXT86 context; + WORD args[8]; memset( &context, 0, sizeof(context) ); context.SegDs = ds; @@ -781,14 +781,15 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason ) context.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack ) + (WORD)&((STACK16FRAME*)0)->bp; - *(DWORD *)(stack - 4) = dwReason; /* dwReason */ - *(WORD *) (stack - 6) = hInst; /* hInst */ - *(WORD *) (stack - 8) = ds; /* wDS */ - *(WORD *) (stack - 10) = heap; /* wHeapSize */ - *(DWORD *)(stack - 14) = 0; /* dwReserved1 */ - *(WORD *) (stack - 16) = 0; /* wReserved2 */ - - wine_call_to_16_regs_short( &context, 16 ); + args[7] = HIWORD(dwReason); + args[6] = LOWORD(dwReason); + args[5] = hInst; + args[4] = ds; + args[3] = heap; + args[2] = 0; /* HIWORD(dwReserved1) */ + args[1] = 0; /* LOWORD(dwReserved1) */ + args[0] = 0; /* wReserved2 */ + WOWCallback16Ex( 0, WCB16_REGS, sizeof(args), args, (DWORD *)&context ); } } diff --git a/dlls/kernel/system.c b/dlls/kernel/system.c index eb5ff464798..55f017d4dc3 100644 --- a/dlls/kernel/system.c +++ b/dlls/kernel/system.c @@ -24,6 +24,7 @@ #include "wingdi.h" #include "wine/winbase16.h" #include "wine/winuser16.h" +#include "wownt32.h" #include "stackframe.h" #include "wine/debug.h" @@ -173,7 +174,7 @@ static void call_timer_proc16( WORD timer ) + (WORD)&((STACK16FRAME*)0)->bp; context.Eax = timer; - wine_call_to_16_regs_short( &context, 0 ); + WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context ); } /**********************************************************************/ diff --git a/dlls/kernel/thunk.c b/dlls/kernel/thunk.c index 019dc9ff50c..6eb451d8dbf 100644 --- a/dlls/kernel/thunk.c +++ b/dlls/kernel/thunk.c @@ -33,6 +33,7 @@ #include "winbase.h" #include "winerror.h" #include "winternl.h" +#include "wownt32.h" #include "wine/winbase16.h" #include "wine/debug.h" @@ -349,12 +350,7 @@ void WINAPI QT_Thunk( CONTEXT86 *context ) if (argsize > 64) argsize = 64; /* 32 WORDs */ - memcpy( (LPBYTE)CURRENT_STACK16 - argsize, - (LPBYTE)context->Esp, argsize ); - - /* let's hope call_to_16 won't mind getting called with such a - * potentially bogus large number of arguments */ - wine_call_to_16_regs_short( &context16, argsize ); + WOWCallback16Ex( 0, WCB16_REGS, argsize, (void *)context->Esp, (DWORD *)&context16 ); context->Eax = context16.Eax; context->Edx = context16.Edx; context->Ecx = context16.Ecx; @@ -460,7 +456,8 @@ void WINAPI FT_Thunk( CONTEXT86 *context ) CONTEXT86 context16; DWORD i, argsize; - LPBYTE newstack, oldstack; + DWORD newstack[32]; + LPBYTE oldstack; memcpy(&context16,context,sizeof(context16)); @@ -470,7 +467,7 @@ void WINAPI FT_Thunk( CONTEXT86 *context ) + (WORD)&((STACK16FRAME*)0)->bp; argsize = context->Ebp-context->Esp-0x40; - newstack = (LPBYTE)CURRENT_STACK16 - argsize; + if (argsize > sizeof(newstack)) argsize = sizeof(newstack); oldstack = (LPBYTE)context->Esp; memcpy( newstack, oldstack, argsize ); @@ -478,13 +475,13 @@ void WINAPI FT_Thunk( CONTEXT86 *context ) for (i = 0; i < 32; i++) /* NOTE: What about > 32 arguments? */ if (mapESPrelative & (1 << i)) { - SEGPTR *arg = (SEGPTR *)(newstack + 2*i); + SEGPTR *arg = (SEGPTR *)newstack[i]; *arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) - argsize + (*(LPBYTE *)arg - oldstack)); } - wine_call_to_16_regs_short( &context16, argsize ); + WOWCallback16Ex( 0, WCB16_REGS, argsize, newstack, (DWORD *)&context16 ); context->Eax = context16.Eax; context->Edx = context16.Edx; context->Ecx = context16.Ecx; @@ -688,10 +685,11 @@ void WINAPI Common32ThkLS( CONTEXT86 *context ) if (context->Edx == context->Eip) argsize = 6 * 4; - memcpy( (LPBYTE)CURRENT_STACK16 - argsize, - (LPBYTE)context->Esp, argsize ); - - wine_call_to_16_regs_long(&context16, argsize + 32); + /* Note: the first 32 bytes we copy are just garbage from the 32-bit stack, in order to reserve + * the space. It is safe to do that since the register function prefix has reserved + * a lot more space than that below context->Esp. + */ + WOWCallback16Ex( 0, WCB16_REGS, argsize + 32, (LPBYTE)context->Esp - 32, (DWORD *)&context16 ); context->Eax = context16.Eax; /* Clean up caller's stack frame */ @@ -739,10 +737,7 @@ void WINAPI OT_32ThkLSF( CONTEXT86 *context ) argsize = 2 * *(WORD *)context->Esp + 2; - memcpy( (LPBYTE)CURRENT_STACK16 - argsize, - (LPBYTE)context->Esp, argsize ); - - wine_call_to_16_regs_short(&context16, argsize); + WOWCallback16Ex( 0, WCB16_REGS, argsize, (void *)context->Esp, (DWORD *)&context16 ); context->Eax = context16.Eax; context->Edx = context16.Edx; diff --git a/dlls/kernel/wowthunk.c b/dlls/kernel/wowthunk.c index 30029b16086..6ee21d88dba 100644 --- a/dlls/kernel/wowthunk.c +++ b/dlls/kernel/wowthunk.c @@ -21,11 +21,14 @@ #include "config.h" #include "wine/port.h" +#include + #include "wine/winbase16.h" #include "winbase.h" #include "winerror.h" #include "wownt32.h" #include "winternl.h" +#include "syslevel.h" #include "file.h" #include "task.h" #include "miscemu.h" @@ -33,6 +36,7 @@ #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(thunk); +WINE_DECLARE_DEBUG_CHANNEL(relay); /* * These are the 16-bit side WOW routines. They reside in wownt16.h @@ -290,7 +294,10 @@ WORD WINAPI K32WOWHandle16( HANDLE handle, WOW_HANDLE_TYPE type ) BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags, DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode ) { - DWORD ret; +#ifdef __i386__ + extern DWORD WINAPI wine_call_to_16( FARPROC16 target, DWORD cbArgs ); + extern void WINAPI wine_call_to_16_regs_short( CONTEXT86 *context, DWORD cbArgs ); + extern void WINAPI wine_call_to_16_regs_long ( CONTEXT86 *context, DWORD cbArgs ); /* * Arguments must be prepared in the correct order by the caller @@ -299,17 +306,86 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags, */ memcpy( (LPBYTE)CURRENT_STACK16 - cbArgs, (LPBYTE)pArgs, cbArgs ); - /* - * Actually, we should take care whether the called routine cleans up - * its stack or not. Fortunately, our wine_call_to_16 core doesn't rely on - * the callee to do so; after the routine has returned, the 16-bit - * stack pointer is always reset to the position it had before. - */ + if (dwFlags & (WCB16_REGS|WCB16_REGS_LONG)) + { + CONTEXT *context = (CONTEXT *)pdwRetCode; - ret = wine_call_to_16( (FARPROC16)vpfn16, cbArgs ); + if (TRACE_ON(relay)) + { + WORD *stack16 = (WORD *)CURRENT_STACK16; + DWORD count = cbArgs / sizeof(WORD); - if ( pdwRetCode ) - *pdwRetCode = ret; + DPRINTF("%04lx:CallTo16(func=%04lx:%04x,ds=%04lx", + GetCurrentThreadId(), + context->SegCs, LOWORD(context->Eip), context->SegDs ); + while (count--) DPRINTF( ",%04x", *--stack16 ); + 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", + (WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx, + (WORD)context->Edx, (WORD)context->Esi, (WORD)context->Edi, + (WORD)context->Ebp, (WORD)context->SegEs, (WORD)context->SegFs ); + SYSLEVEL_CheckNotLevel( 2 ); + } + + _EnterWin16Lock(); + if (dwFlags & WCB16_REGS_LONG) + wine_call_to_16_regs_long( context, cbArgs ); + else + wine_call_to_16_regs_short( context, cbArgs ); + _LeaveWin16Lock(); + + if (TRACE_ON(relay)) + { + DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x ", + GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->cur_stack), + OFFSETOF(NtCurrentTeb()->cur_stack)); + DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x bp=%04x sp=%04x\n", + (WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx, + (WORD)context->Edx, (WORD)context->Ebp, (WORD)context->Esp ); + SYSLEVEL_CheckNotLevel( 2 ); + } + } + else + { + DWORD ret; + + if (TRACE_ON(relay)) + { + WORD *stack16 = (WORD *)CURRENT_STACK16; + DWORD count = cbArgs / sizeof(WORD); + + DPRINTF("%04lx:CallTo16(func=%04x:%04x,ds=%04x", + GetCurrentThreadId(), HIWORD(vpfn16), LOWORD(vpfn16), + SELECTOROF(NtCurrentTeb()->cur_stack) ); + while (count--) DPRINTF( ",%04x", *--stack16 ); + DPRINTF(") ss:sp=%04x:%04x\n", + SELECTOROF(NtCurrentTeb()->cur_stack), OFFSETOF(NtCurrentTeb()->cur_stack) ); + SYSLEVEL_CheckNotLevel( 2 ); + } + + /* + * Actually, we should take care whether the called routine cleans up + * its stack or not. Fortunately, our wine_call_to_16 core doesn't rely on + * the callee to do so; after the routine has returned, the 16-bit + * stack pointer is always reset to the position it had before. + */ + _EnterWin16Lock(); + ret = wine_call_to_16( (FARPROC16)vpfn16, cbArgs ); + if (pdwRetCode) *pdwRetCode = ret; + _LeaveWin16Lock(); + + if (TRACE_ON(relay)) + { + DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x retval=%08lx\n", + GetCurrentThreadId(), SELECTOROF(NtCurrentTeb()->cur_stack), + OFFSETOF(NtCurrentTeb()->cur_stack), ret); + SYSLEVEL_CheckNotLevel( 2 ); + } + } +#else + assert(0); /* cannot call to 16-bit on non-Intel architectures */ +#endif /* __i386__ */ return TRUE; /* success */ } diff --git a/dlls/winedos/int31.c b/dlls/winedos/int31.c index 854d3ae8f89..421e7c4d3e8 100644 --- a/dlls/winedos/int31.c +++ b/dlls/winedos/int31.c @@ -23,6 +23,7 @@ #include "windef.h" #include "wine/winbase16.h" +#include "wownt32.h" #include "miscemu.h" #include "task.h" #include "msdos.h" @@ -362,7 +363,7 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag ) ctx.SegEs = rmcb->regs_sel; ctx.Edi = rmcb->regs_ofs; /* FIXME: I'm pretty sure this isn't right - should push flags first */ - wine_call_to_16_regs_short(&ctx, 0); + WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context ); es = ctx.SegEs; edi = ctx.Edi; } @@ -585,7 +586,7 @@ static void StartPM( CONTEXT86 *context ) __TRY { - wine_call_to_16_regs_short(&pm_ctx, 0); + WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&pm_ctx ); } __EXCEPT(dpmi_exception_handler) { diff --git a/if1632/relay.c b/if1632/relay.c index 39c4665b7aa..bca70f91065 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -79,30 +79,6 @@ BOOL RELAY_Init(void) * (these will never be called but need to be present to satisfy the linker ...) */ #ifndef __i386__ -/*********************************************************************** - * wine_call_to_16 (KERNEL32.@) - */ -LONG WINAPI wine_call_to_16( FARPROC16 target, INT nArgs ) -{ - assert( FALSE ); -} - -/*********************************************************************** - * wine_call_to_16_regs_short (KERNEL32.@) - */ -void WINAPI wine_call_to_16_regs_short( CONTEXT86 *context, INT nArgs ) -{ - assert( FALSE ); -} - -/*********************************************************************** - * wine_call_to_16_regs_long (KERNEL32.@) - */ -void WINAPI wine_call_to_16_regs_long ( CONTEXT86 *context, INT nArgs ) -{ - assert( FALSE ); -} - /*********************************************************************** * __wine_call_from_16_word (KERNEL32.@) */ @@ -387,82 +363,3 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val ) } SYSLEVEL_CheckNotLevel( 2 ); } - - -/*********************************************************************** - * RELAY_DebugCallTo16 - * - * 'target' contains either the function to call (normal CallTo16) - * or a pointer to the CONTEXT86 struct (register CallTo16). - * 'nb_args' is the number of argument bytes on the 16-bit stack; - * 'reg_func' specifies whether we have a register CallTo16 or not. - */ -void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func ) -{ - WORD *stack16; - TEB *teb; - - if (!TRACE_ON(relay)) return; - teb = NtCurrentTeb(); - stack16 = (WORD *)THREAD_STACK16(teb); - - nb_args /= sizeof(WORD); - - if ( reg_func ) - { - CONTEXT86 *context = (CONTEXT86 *)target; - - DPRINTF("%04lx:CallTo16(func=%04lx:%04x,ds=%04lx", - GetCurrentThreadId(), - context->SegCs, LOWORD(context->Eip), context->SegDs ); - while (nb_args--) DPRINTF( ",%04x", *--stack16 ); - DPRINTF(") ss:sp=%04x:%04x", SELECTOROF(teb->cur_stack), - OFFSETOF(teb->cur_stack) ); - DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x si=%04x di=%04x bp=%04x es=%04x fs=%04x\n", - (WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx, - (WORD)context->Edx, (WORD)context->Esi, (WORD)context->Edi, - (WORD)context->Ebp, (WORD)context->SegEs, (WORD)context->SegFs ); - } - else - { - DPRINTF("%04lx:CallTo16(func=%04x:%04x,ds=%04x", - GetCurrentThreadId(), - HIWORD(target), LOWORD(target), SELECTOROF(teb->cur_stack) ); - while (nb_args--) DPRINTF( ",%04x", *--stack16 ); - DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack), - OFFSETOF(teb->cur_stack) ); - } - - SYSLEVEL_CheckNotLevel( 2 ); -} - - -/*********************************************************************** - * RELAY_DebugCallTo16Ret - */ -void RELAY_DebugCallTo16Ret( BOOL reg_func, int ret_val ) -{ - if (!TRACE_ON(relay)) return; - - if (!reg_func) - { - DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x retval=%08x\n", - GetCurrentThreadId(), - SELECTOROF(NtCurrentTeb()->cur_stack), - OFFSETOF(NtCurrentTeb()->cur_stack), ret_val); - } - else - { - CONTEXT86 *context = (CONTEXT86 *)ret_val; - - DPRINTF("%04lx:RetFrom16() ss:sp=%04x:%04x ", - GetCurrentThreadId(), - SELECTOROF(NtCurrentTeb()->cur_stack), - OFFSETOF(NtCurrentTeb()->cur_stack)); - DPRINTF(" ax=%04x bx=%04x cx=%04x dx=%04x bp=%04x sp=%04x\n", - (WORD)context->Eax, (WORD)context->Ebx, (WORD)context->Ecx, - (WORD)context->Edx, (WORD)context->Ebp, (WORD)context->Esp ); - } - - SYSLEVEL_CheckNotLevel( 2 ); -} diff --git a/include/stackframe.h b/include/stackframe.h index 8cb9c39a4d1..237a97f7748 100644 --- a/include/stackframe.h +++ b/include/stackframe.h @@ -38,13 +38,11 @@ typedef struct _STACK32FRAME SEGPTR frame16; /* 10 16-bit frame from last CallFrom16() */ DWORD edi; /* 14 saved registers */ DWORD esi; /* 18 */ - DWORD edx; /* 1c */ - DWORD ecx; /* 20 */ - DWORD ebx; /* 24 */ - DWORD ebp; /* 28 saved 32-bit frame pointer */ - DWORD retaddr; /* 2c return address */ - DWORD target; /* 30 target address / CONTEXT86 pointer */ - DWORD nb_args; /* 34 number of 16-bit argument bytes */ + DWORD ebx; /* 1c */ + DWORD ebp; /* 20 saved 32-bit frame pointer */ + DWORD retaddr; /* 24 return address */ + DWORD target; /* 28 target address / CONTEXT86 pointer */ + DWORD nb_args; /* 2c number of 16-bit argument bytes */ } STACK32FRAME; /* 16-bit stack layout after CallFrom16() */ diff --git a/include/wine/winbase16.h b/include/wine/winbase16.h index e06ababf496..059cfa8857a 100644 --- a/include/wine/winbase16.h +++ b/include/wine/winbase16.h @@ -220,6 +220,7 @@ HGLOBAL16 WINAPI GlobalLRUOldest16(HGLOBAL16); VOID WINAPI GlobalNotify16(FARPROC16); WORD WINAPI GlobalPageLock16(HGLOBAL16); WORD WINAPI GlobalPageUnlock16(HGLOBAL16); +SEGPTR WINAPI HasGPHandler16(SEGPTR); BOOL16 WINAPI IsSharedSelector16(HANDLE16); BOOL16 WINAPI IsTask16(HTASK16); HTASK16 WINAPI IsTaskLocked16(void); @@ -392,11 +393,6 @@ BOOL16 WINAPI WritePrivateProfileSection16(LPCSTR,LPCSTR,LPCSTR); BOOL16 WINAPI WritePrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR); BOOL16 WINAPI WriteProfileSection16(LPCSTR,LPCSTR); -/* Wine-specific functions */ -LONG WINAPI wine_call_to_16( FARPROC16 target, INT nArgs ); -void WINAPI wine_call_to_16_regs_short( CONTEXT86 *context, INT nArgs ); -void WINAPI wine_call_to_16_regs_long ( CONTEXT86 *context, INT nArgs ); - /* Some optimizations */ extern inline LPVOID WINAPI MapSL( SEGPTR segptr ) { diff --git a/include/wownt32.h b/include/wownt32.h index f84e1d0069d..7de80f0cbcf 100644 --- a/include/wownt32.h +++ b/include/wownt32.h @@ -140,6 +140,10 @@ BOOL WINAPI K32WOWCallback16Ex(DWORD,DWORD,DWORD,LPVOID,LPDWORD); #define WCB16_CDECL 1 #define WCB16_MAX_CBARGS 16 +/* Wine extensions: call register function, context ptr is passed in the return value LPDWORD */ +#define WCB16_REGS 2 +#define WCB16_REGS_LONG 4 /* function uses 32-bit lret */ + DWORD WINAPI WOWCallback16(DWORD,DWORD); BOOL WINAPI WOWCallback16Ex(DWORD,DWORD,DWORD,LPVOID,LPDWORD); diff --git a/tools/winebuild/relay.c b/tools/winebuild/relay.c index 05f5a1255fb..c0f7ab257d6 100644 --- a/tools/winebuild/relay.c +++ b/tools/winebuild/relay.c @@ -485,8 +485,6 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) /* Save the 32-bit registers */ fprintf( outfile, "\tpushl %%ebx\n" ); - fprintf( outfile, "\tpushl %%ecx\n" ); - fprintf( outfile, "\tpushl %%edx\n" ); fprintf( outfile, "\tpushl %%esi\n" ); fprintf( outfile, "\tpushl %%edi\n" ); fprintf( outfile, "\t.byte 0x64\n\tmovl %%gs,(%d)\n", STRUCTOFFSET(TEB,gs_sel) ); @@ -500,28 +498,6 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L%s.getgot1], %%ebx\n", name ); } - /* Print debugging info */ - if (debugging) - { - /* Push flags, number of arguments, and target */ - fprintf( outfile, "\tpushl $%d\n", reg_func ); - fprintf( outfile, "\tpushl 12(%%ebp)\n" ); - fprintf( outfile, "\tpushl 8(%%ebp)\n" ); - - if ( UsePIC ) - fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallTo16@PLT") "\n" ); - else - fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallTo16") "\n" ); - - fprintf( outfile, "\taddl $12, %%esp\n" ); - } - - /* Enter Win16 Mutex */ - if ( UsePIC ) - fprintf( outfile, "\tcall " __ASM_NAME("_EnterWin16Lock@PLT") "\n" ); - else - fprintf( outfile, "\tcall " __ASM_NAME("_EnterWin16Lock") "\n" ); - /* Setup exception frame */ fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET ); if (UsePIC) @@ -551,10 +527,10 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) if ( !reg_func ) { - /* Convert and push return value */ + /* Convert return value */ fprintf( outfile, "\tshll $16,%%edx\n" ); fprintf( outfile, "\tmovw %%ax,%%dx\n" ); - fprintf( outfile, "\tpushl %%edx\n" ); + fprintf( outfile, "\tmovl %%edx,%%eax\n" ); } else { @@ -578,46 +554,11 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func ) fprintf( outfile, "\tmovl %%ebp, %d(%%edi)\n", CONTEXTOFFSET(Ebp) ); fprintf( outfile, "\tmovl %%esi, %d(%%edi)\n", CONTEXTOFFSET(Esp) ); /* The return glue code saved %esp into %esi */ - - fprintf( outfile, "\tpushl %%edi\n" ); } - if ( UsePIC ) - { - /* Get Global Offset Table into %ebx (might have been overwritten) */ - fprintf( outfile, "\tcall .L%s.getgot2\n", name ); - fprintf( outfile, ".L%s.getgot2:\n", name ); - fprintf( outfile, "\tpopl %%ebx\n" ); - fprintf( outfile, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-.L%s.getgot2], %%ebx\n", name ); - } - - /* Leave Win16 Mutex */ - if ( UsePIC ) - fprintf( outfile, "\tcall " __ASM_NAME("_LeaveWin16Lock@PLT") "\n" ); - else - fprintf( outfile, "\tcall " __ASM_NAME("_LeaveWin16Lock") "\n" ); - - /* Print debugging info */ - if (debugging) - { - fprintf( outfile, "\tpushl $%d\n", reg_func ); - - if ( UsePIC ) - fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallTo16Ret@PLT") "\n" ); - else - fprintf( outfile, "\tcall " __ASM_NAME("RELAY_DebugCallTo16Ret") "\n" ); - - fprintf( outfile, "\taddl $4, %%esp\n" ); - } - - /* Get return value */ - fprintf( outfile, "\tpopl %%eax\n" ); - /* Restore the 32-bit registers */ fprintf( outfile, "\tpopl %%edi\n" ); fprintf( outfile, "\tpopl %%esi\n" ); - fprintf( outfile, "\tpopl %%edx\n" ); - fprintf( outfile, "\tpopl %%ecx\n" ); fprintf( outfile, "\tpopl %%ebx\n" ); /* Function exit sequence */ diff --git a/windows/winproc.c b/windows/winproc.c index b446b559b50..81cee8a6cd0 100644 --- a/windows/winproc.c +++ b/windows/winproc.c @@ -244,7 +244,7 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, { CONTEXT86 context; LRESULT ret; - WORD *args; + WORD args[5]; DWORD offset = 0; TEB *teb = NtCurrentTeb(); int iWndsLocks; @@ -287,15 +287,14 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, iWndsLocks = WIN_SuspendWndsLock(); - args = (WORD *)THREAD_STACK16(teb) - 5; - args[0] = LOWORD(lParam); - args[1] = HIWORD(lParam); - args[2] = wParam; - args[3] = msg; args[4] = hwnd; - - wine_call_to_16_regs_short( &context, 5 * sizeof(WORD) ); + args[3] = msg; + args[2] = wParam; + args[1] = HIWORD(lParam); + args[0] = LOWORD(lParam); + WOWCallback16Ex( 0, WCB16_REGS, sizeof(args), args, (DWORD *)&context ); ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) ); + if (offset) stack16_pop( offset ); WIN_RestoreWndsLock(iWndsLocks);