mirror of
https://github.com/reactos/wine.git
synced 2025-02-08 21:27:31 +00:00
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.
This commit is contained in:
parent
cb1c112dd6
commit
3a5b7cf105
@ -1126,9 +1126,6 @@
|
|||||||
@ varargs __wine_call_from_16_word()
|
@ varargs __wine_call_from_16_word()
|
||||||
@ varargs __wine_call_from_16_long()
|
@ varargs __wine_call_from_16_long()
|
||||||
@ varargs __wine_call_from_16_regs()
|
@ 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
|
# Unix files
|
||||||
@ stdcall wine_get_unix_file_name(str ptr long)
|
@ stdcall wine_get_unix_file_name(str ptr long)
|
||||||
|
@ -1284,7 +1284,7 @@ DWORD NE_StartTask(void)
|
|||||||
SELECTOROF(pTask->teb->cur_stack),
|
SELECTOROF(pTask->teb->cur_stack),
|
||||||
OFFSETOF(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) );
|
ExitThread( LOWORD(context.Eax) );
|
||||||
}
|
}
|
||||||
return hInstance; /* error code */
|
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",
|
TRACE_(dll)("Calling LibMain, cs:ip=%04lx:%04lx ds=%04lx di=%04x cx=%04x\n",
|
||||||
context.SegCs, context.Eip, context.SegDs,
|
context.SegCs, context.Eip, context.SegDs,
|
||||||
LOWORD(context.Edi), LOWORD(context.Ecx) );
|
LOWORD(context.Edi), LOWORD(context.Ecx) );
|
||||||
wine_call_to_16_regs_short( &context, 0 );
|
WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&context );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,8 +769,8 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LPBYTE stack = (LPBYTE)CURRENT_STACK16;
|
|
||||||
CONTEXT86 context;
|
CONTEXT86 context;
|
||||||
|
WORD args[8];
|
||||||
|
|
||||||
memset( &context, 0, sizeof(context) );
|
memset( &context, 0, sizeof(context) );
|
||||||
context.SegDs = ds;
|
context.SegDs = ds;
|
||||||
@ -781,14 +781,15 @@ static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
|
|||||||
context.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack )
|
context.Ebp = OFFSETOF( NtCurrentTeb()->cur_stack )
|
||||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||||
|
|
||||||
*(DWORD *)(stack - 4) = dwReason; /* dwReason */
|
args[7] = HIWORD(dwReason);
|
||||||
*(WORD *) (stack - 6) = hInst; /* hInst */
|
args[6] = LOWORD(dwReason);
|
||||||
*(WORD *) (stack - 8) = ds; /* wDS */
|
args[5] = hInst;
|
||||||
*(WORD *) (stack - 10) = heap; /* wHeapSize */
|
args[4] = ds;
|
||||||
*(DWORD *)(stack - 14) = 0; /* dwReserved1 */
|
args[3] = heap;
|
||||||
*(WORD *) (stack - 16) = 0; /* wReserved2 */
|
args[2] = 0; /* HIWORD(dwReserved1) */
|
||||||
|
args[1] = 0; /* LOWORD(dwReserved1) */
|
||||||
wine_call_to_16_regs_short( &context, 16 );
|
args[0] = 0; /* wReserved2 */
|
||||||
|
WOWCallback16Ex( 0, WCB16_REGS, sizeof(args), args, (DWORD *)&context );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "wine/winuser16.h"
|
#include "wine/winuser16.h"
|
||||||
|
#include "wownt32.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
@ -173,7 +174,7 @@ static void call_timer_proc16( WORD timer )
|
|||||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||||
context.Eax = timer;
|
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 "winbase.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
|
#include "wownt32.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
@ -349,12 +350,7 @@ void WINAPI QT_Thunk( CONTEXT86 *context )
|
|||||||
if (argsize > 64)
|
if (argsize > 64)
|
||||||
argsize = 64; /* 32 WORDs */
|
argsize = 64; /* 32 WORDs */
|
||||||
|
|
||||||
memcpy( (LPBYTE)CURRENT_STACK16 - argsize,
|
WOWCallback16Ex( 0, WCB16_REGS, argsize, (void *)context->Esp, (DWORD *)&context16 );
|
||||||
(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 );
|
|
||||||
context->Eax = context16.Eax;
|
context->Eax = context16.Eax;
|
||||||
context->Edx = context16.Edx;
|
context->Edx = context16.Edx;
|
||||||
context->Ecx = context16.Ecx;
|
context->Ecx = context16.Ecx;
|
||||||
@ -460,7 +456,8 @@ void WINAPI FT_Thunk( CONTEXT86 *context )
|
|||||||
|
|
||||||
CONTEXT86 context16;
|
CONTEXT86 context16;
|
||||||
DWORD i, argsize;
|
DWORD i, argsize;
|
||||||
LPBYTE newstack, oldstack;
|
DWORD newstack[32];
|
||||||
|
LPBYTE oldstack;
|
||||||
|
|
||||||
memcpy(&context16,context,sizeof(context16));
|
memcpy(&context16,context,sizeof(context16));
|
||||||
|
|
||||||
@ -470,7 +467,7 @@ void WINAPI FT_Thunk( CONTEXT86 *context )
|
|||||||
+ (WORD)&((STACK16FRAME*)0)->bp;
|
+ (WORD)&((STACK16FRAME*)0)->bp;
|
||||||
|
|
||||||
argsize = context->Ebp-context->Esp-0x40;
|
argsize = context->Ebp-context->Esp-0x40;
|
||||||
newstack = (LPBYTE)CURRENT_STACK16 - argsize;
|
if (argsize > sizeof(newstack)) argsize = sizeof(newstack);
|
||||||
oldstack = (LPBYTE)context->Esp;
|
oldstack = (LPBYTE)context->Esp;
|
||||||
|
|
||||||
memcpy( newstack, oldstack, argsize );
|
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? */
|
for (i = 0; i < 32; i++) /* NOTE: What about > 32 arguments? */
|
||||||
if (mapESPrelative & (1 << i))
|
if (mapESPrelative & (1 << i))
|
||||||
{
|
{
|
||||||
SEGPTR *arg = (SEGPTR *)(newstack + 2*i);
|
SEGPTR *arg = (SEGPTR *)newstack[i];
|
||||||
*arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->cur_stack),
|
*arg = MAKESEGPTR(SELECTOROF(NtCurrentTeb()->cur_stack),
|
||||||
OFFSETOF(NtCurrentTeb()->cur_stack) - argsize
|
OFFSETOF(NtCurrentTeb()->cur_stack) - argsize
|
||||||
+ (*(LPBYTE *)arg - oldstack));
|
+ (*(LPBYTE *)arg - oldstack));
|
||||||
}
|
}
|
||||||
|
|
||||||
wine_call_to_16_regs_short( &context16, argsize );
|
WOWCallback16Ex( 0, WCB16_REGS, argsize, newstack, (DWORD *)&context16 );
|
||||||
context->Eax = context16.Eax;
|
context->Eax = context16.Eax;
|
||||||
context->Edx = context16.Edx;
|
context->Edx = context16.Edx;
|
||||||
context->Ecx = context16.Ecx;
|
context->Ecx = context16.Ecx;
|
||||||
@ -688,10 +685,11 @@ void WINAPI Common32ThkLS( CONTEXT86 *context )
|
|||||||
if (context->Edx == context->Eip)
|
if (context->Edx == context->Eip)
|
||||||
argsize = 6 * 4;
|
argsize = 6 * 4;
|
||||||
|
|
||||||
memcpy( (LPBYTE)CURRENT_STACK16 - argsize,
|
/* Note: the first 32 bytes we copy are just garbage from the 32-bit stack, in order to reserve
|
||||||
(LPBYTE)context->Esp, argsize );
|
* the space. It is safe to do that since the register function prefix has reserved
|
||||||
|
* a lot more space than that below context->Esp.
|
||||||
wine_call_to_16_regs_long(&context16, argsize + 32);
|
*/
|
||||||
|
WOWCallback16Ex( 0, WCB16_REGS, argsize + 32, (LPBYTE)context->Esp - 32, (DWORD *)&context16 );
|
||||||
context->Eax = context16.Eax;
|
context->Eax = context16.Eax;
|
||||||
|
|
||||||
/* Clean up caller's stack frame */
|
/* Clean up caller's stack frame */
|
||||||
@ -739,10 +737,7 @@ void WINAPI OT_32ThkLSF( CONTEXT86 *context )
|
|||||||
|
|
||||||
argsize = 2 * *(WORD *)context->Esp + 2;
|
argsize = 2 * *(WORD *)context->Esp + 2;
|
||||||
|
|
||||||
memcpy( (LPBYTE)CURRENT_STACK16 - argsize,
|
WOWCallback16Ex( 0, WCB16_REGS, argsize, (void *)context->Esp, (DWORD *)&context16 );
|
||||||
(LPBYTE)context->Esp, argsize );
|
|
||||||
|
|
||||||
wine_call_to_16_regs_short(&context16, argsize);
|
|
||||||
context->Eax = context16.Eax;
|
context->Eax = context16.Eax;
|
||||||
context->Edx = context16.Edx;
|
context->Edx = context16.Edx;
|
||||||
|
|
||||||
|
@ -21,11 +21,14 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "wine/port.h"
|
#include "wine/port.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "wownt32.h"
|
#include "wownt32.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
|
#include "syslevel.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "miscemu.h"
|
#include "miscemu.h"
|
||||||
@ -33,6 +36,7 @@
|
|||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(thunk);
|
WINE_DEFAULT_DEBUG_CHANNEL(thunk);
|
||||||
|
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are the 16-bit side WOW routines. They reside in wownt16.h
|
* 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,
|
BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
|
||||||
DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode )
|
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
|
* 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 );
|
memcpy( (LPBYTE)CURRENT_STACK16 - cbArgs, (LPBYTE)pArgs, cbArgs );
|
||||||
|
|
||||||
/*
|
if (dwFlags & (WCB16_REGS|WCB16_REGS_LONG))
|
||||||
* 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
|
CONTEXT *context = (CONTEXT *)pdwRetCode;
|
||||||
* the callee to do so; after the routine has returned, the 16-bit
|
|
||||||
* stack pointer is always reset to the position it had before.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = wine_call_to_16( (FARPROC16)vpfn16, cbArgs );
|
if (TRACE_ON(relay))
|
||||||
|
{
|
||||||
|
WORD *stack16 = (WORD *)CURRENT_STACK16;
|
||||||
|
DWORD count = cbArgs / sizeof(WORD);
|
||||||
|
|
||||||
if ( pdwRetCode )
|
DPRINTF("%04lx:CallTo16(func=%04lx:%04x,ds=%04lx",
|
||||||
*pdwRetCode = ret;
|
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 */
|
return TRUE; /* success */
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
|
#include "wownt32.h"
|
||||||
#include "miscemu.h"
|
#include "miscemu.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "msdos.h"
|
#include "msdos.h"
|
||||||
@ -362,7 +363,7 @@ static void DPMI_CallRMCBProc( CONTEXT86 *context, RMCB *rmcb, WORD flag )
|
|||||||
ctx.SegEs = rmcb->regs_sel;
|
ctx.SegEs = rmcb->regs_sel;
|
||||||
ctx.Edi = rmcb->regs_ofs;
|
ctx.Edi = rmcb->regs_ofs;
|
||||||
/* FIXME: I'm pretty sure this isn't right - should push flags first */
|
/* 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;
|
es = ctx.SegEs;
|
||||||
edi = ctx.Edi;
|
edi = ctx.Edi;
|
||||||
}
|
}
|
||||||
@ -585,7 +586,7 @@ static void StartPM( CONTEXT86 *context )
|
|||||||
|
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
wine_call_to_16_regs_short(&pm_ctx, 0);
|
WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)&pm_ctx );
|
||||||
}
|
}
|
||||||
__EXCEPT(dpmi_exception_handler)
|
__EXCEPT(dpmi_exception_handler)
|
||||||
{
|
{
|
||||||
|
103
if1632/relay.c
103
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 ...)
|
* (these will never be called but need to be present to satisfy the linker ...)
|
||||||
*/
|
*/
|
||||||
#ifndef __i386__
|
#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.@)
|
* __wine_call_from_16_word (KERNEL32.@)
|
||||||
*/
|
*/
|
||||||
@ -387,82 +363,3 @@ void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val )
|
|||||||
}
|
}
|
||||||
SYSLEVEL_CheckNotLevel( 2 );
|
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() */
|
SEGPTR frame16; /* 10 16-bit frame from last CallFrom16() */
|
||||||
DWORD edi; /* 14 saved registers */
|
DWORD edi; /* 14 saved registers */
|
||||||
DWORD esi; /* 18 */
|
DWORD esi; /* 18 */
|
||||||
DWORD edx; /* 1c */
|
DWORD ebx; /* 1c */
|
||||||
DWORD ecx; /* 20 */
|
DWORD ebp; /* 20 saved 32-bit frame pointer */
|
||||||
DWORD ebx; /* 24 */
|
DWORD retaddr; /* 24 return address */
|
||||||
DWORD ebp; /* 28 saved 32-bit frame pointer */
|
DWORD target; /* 28 target address / CONTEXT86 pointer */
|
||||||
DWORD retaddr; /* 2c return address */
|
DWORD nb_args; /* 2c number of 16-bit argument bytes */
|
||||||
DWORD target; /* 30 target address / CONTEXT86 pointer */
|
|
||||||
DWORD nb_args; /* 34 number of 16-bit argument bytes */
|
|
||||||
} STACK32FRAME;
|
} STACK32FRAME;
|
||||||
|
|
||||||
/* 16-bit stack layout after CallFrom16() */
|
/* 16-bit stack layout after CallFrom16() */
|
||||||
|
@ -220,6 +220,7 @@ HGLOBAL16 WINAPI GlobalLRUOldest16(HGLOBAL16);
|
|||||||
VOID WINAPI GlobalNotify16(FARPROC16);
|
VOID WINAPI GlobalNotify16(FARPROC16);
|
||||||
WORD WINAPI GlobalPageLock16(HGLOBAL16);
|
WORD WINAPI GlobalPageLock16(HGLOBAL16);
|
||||||
WORD WINAPI GlobalPageUnlock16(HGLOBAL16);
|
WORD WINAPI GlobalPageUnlock16(HGLOBAL16);
|
||||||
|
SEGPTR WINAPI HasGPHandler16(SEGPTR);
|
||||||
BOOL16 WINAPI IsSharedSelector16(HANDLE16);
|
BOOL16 WINAPI IsSharedSelector16(HANDLE16);
|
||||||
BOOL16 WINAPI IsTask16(HTASK16);
|
BOOL16 WINAPI IsTask16(HTASK16);
|
||||||
HTASK16 WINAPI IsTaskLocked16(void);
|
HTASK16 WINAPI IsTaskLocked16(void);
|
||||||
@ -392,11 +393,6 @@ BOOL16 WINAPI WritePrivateProfileSection16(LPCSTR,LPCSTR,LPCSTR);
|
|||||||
BOOL16 WINAPI WritePrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR);
|
BOOL16 WINAPI WritePrivateProfileStruct16(LPCSTR,LPCSTR,LPVOID,UINT16,LPCSTR);
|
||||||
BOOL16 WINAPI WriteProfileSection16(LPCSTR,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 */
|
/* Some optimizations */
|
||||||
extern inline LPVOID WINAPI MapSL( SEGPTR segptr )
|
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_CDECL 1
|
||||||
#define WCB16_MAX_CBARGS 16
|
#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);
|
DWORD WINAPI WOWCallback16(DWORD,DWORD);
|
||||||
BOOL WINAPI WOWCallback16Ex(DWORD,DWORD,DWORD,LPVOID,LPDWORD);
|
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 */
|
/* Save the 32-bit registers */
|
||||||
fprintf( outfile, "\tpushl %%ebx\n" );
|
fprintf( outfile, "\tpushl %%ebx\n" );
|
||||||
fprintf( outfile, "\tpushl %%ecx\n" );
|
|
||||||
fprintf( outfile, "\tpushl %%edx\n" );
|
|
||||||
fprintf( outfile, "\tpushl %%esi\n" );
|
fprintf( outfile, "\tpushl %%esi\n" );
|
||||||
fprintf( outfile, "\tpushl %%edi\n" );
|
fprintf( outfile, "\tpushl %%edi\n" );
|
||||||
fprintf( outfile, "\t.byte 0x64\n\tmovl %%gs,(%d)\n", STRUCTOFFSET(TEB,gs_sel) );
|
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 );
|
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 */
|
/* Setup exception frame */
|
||||||
fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET );
|
fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET );
|
||||||
if (UsePIC)
|
if (UsePIC)
|
||||||
@ -551,10 +527,10 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
|
|||||||
|
|
||||||
if ( !reg_func )
|
if ( !reg_func )
|
||||||
{
|
{
|
||||||
/* Convert and push return value */
|
/* Convert return value */
|
||||||
fprintf( outfile, "\tshll $16,%%edx\n" );
|
fprintf( outfile, "\tshll $16,%%edx\n" );
|
||||||
fprintf( outfile, "\tmovw %%ax,%%dx\n" );
|
fprintf( outfile, "\tmovw %%ax,%%dx\n" );
|
||||||
fprintf( outfile, "\tpushl %%edx\n" );
|
fprintf( outfile, "\tmovl %%edx,%%eax\n" );
|
||||||
}
|
}
|
||||||
else
|
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 %%ebp, %d(%%edi)\n", CONTEXTOFFSET(Ebp) );
|
||||||
fprintf( outfile, "\tmovl %%esi, %d(%%edi)\n", CONTEXTOFFSET(Esp) );
|
fprintf( outfile, "\tmovl %%esi, %d(%%edi)\n", CONTEXTOFFSET(Esp) );
|
||||||
/* The return glue code saved %esp into %esi */
|
/* 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 */
|
/* Restore the 32-bit registers */
|
||||||
fprintf( outfile, "\tpopl %%edi\n" );
|
fprintf( outfile, "\tpopl %%edi\n" );
|
||||||
fprintf( outfile, "\tpopl %%esi\n" );
|
fprintf( outfile, "\tpopl %%esi\n" );
|
||||||
fprintf( outfile, "\tpopl %%edx\n" );
|
|
||||||
fprintf( outfile, "\tpopl %%ecx\n" );
|
|
||||||
fprintf( outfile, "\tpopl %%ebx\n" );
|
fprintf( outfile, "\tpopl %%ebx\n" );
|
||||||
|
|
||||||
/* Function exit sequence */
|
/* Function exit sequence */
|
||||||
|
@ -244,7 +244,7 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
|
|||||||
{
|
{
|
||||||
CONTEXT86 context;
|
CONTEXT86 context;
|
||||||
LRESULT ret;
|
LRESULT ret;
|
||||||
WORD *args;
|
WORD args[5];
|
||||||
DWORD offset = 0;
|
DWORD offset = 0;
|
||||||
TEB *teb = NtCurrentTeb();
|
TEB *teb = NtCurrentTeb();
|
||||||
int iWndsLocks;
|
int iWndsLocks;
|
||||||
@ -287,15 +287,14 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
|
|||||||
|
|
||||||
iWndsLocks = WIN_SuspendWndsLock();
|
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;
|
args[4] = hwnd;
|
||||||
|
args[3] = msg;
|
||||||
wine_call_to_16_regs_short( &context, 5 * sizeof(WORD) );
|
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) );
|
ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
|
||||||
|
|
||||||
if (offset) stack16_pop( offset );
|
if (offset) stack16_pop( offset );
|
||||||
|
|
||||||
WIN_RestoreWndsLock(iWndsLocks);
|
WIN_RestoreWndsLock(iWndsLocks);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user