Commit 3a5b7cf1 authored by Alexandre Julliard's avatar Alexandre Julliard

Extended WOWCallback16Ex to support register functions too. This

allows simplifying the wine_call_to_16 assembly code by moving part of it to C code, and getting rid of the extra kernel exports.
parent cb1c112d
......@@ -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)
......
......@@ -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 */
......
......@@ -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 );
}
}
......
......@@ -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 );
}
/**********************************************************************/
......
......@@ -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;
......
......@@ -21,11 +21,14 @@
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#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;
if (TRACE_ON(relay))
{
WORD *stack16 = (WORD *)CURRENT_STACK16;
DWORD count = cbArgs / sizeof(WORD);
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 );
}
ret = wine_call_to_16( (FARPROC16)vpfn16, cbArgs );
_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 );
}
if ( pdwRetCode )
*pdwRetCode = ret;
/*
* 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 */
}
......
......@@ -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)
{
......
......@@ -80,30 +80,6 @@ BOOL RELAY_Init(void)
*/
#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.@)
*/
WORD __wine_call_from_16_word()
......@@ -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 );
}
......@@ -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() */
......
......@@ -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 )
{
......
......@@ -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);
......
......@@ -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 */
......
......@@ -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);
......
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