Instead of manually building a STACK16FRAME.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- I have changes planned that modify the STACK16FRAME layout and the 16-to-32 assembly code. This becomes much easier when there are not a half dozen places which must implicitly be kept in sync.
dlls/ifsmgr.vxd/ifsmgr.c | 6 ++-- dlls/krnl386.exe16/dosexe.h | 6 +--- dlls/krnl386.exe16/dosmem.c | 14 --------- dlls/krnl386.exe16/instr.c | 4 +-- dlls/krnl386.exe16/interrupts.c | 37 +++++++++++----------- dlls/krnl386.exe16/krnl386.exe16.spec | 3 +- dlls/krnl386.exe16/relay.c | 44 --------------------------- dlls/vwin32.vxd/vwin32.c | 6 ++-- 8 files changed, 30 insertions(+), 90 deletions(-)
diff --git a/dlls/ifsmgr.vxd/ifsmgr.c b/dlls/ifsmgr.vxd/ifsmgr.c index 2fe3198a6ba..ab232ec6c23 100644 --- a/dlls/ifsmgr.vxd/ifsmgr.c +++ b/dlls/ifsmgr.vxd/ifsmgr.c @@ -97,7 +97,7 @@ static void CONTEXT_2_win32apieq(const CONTEXT *pCxt, struct win32apireq *pOut) /* FIXME: pOut->ar_pad ignored */ }
-extern void __wine_call_int_handler( CONTEXT *context, BYTE intnum ); +extern void WINAPI __wine_call_int_handler16( BYTE intnum, CONTEXT *context );
/*********************************************************************** * DeviceIoControl (IFSMGR.VXD.@) @@ -132,9 +132,9 @@ BOOL WINAPI IFSMGR_DeviceIoControl(DWORD dwIoControlCode, LPVOID lpvInBuffer, DW win32apieq_2_CONTEXT(pIn,&cxt);
if(dwIoControlCode==IFS_IOCTL_21) - __wine_call_int_handler( &cxt, 0x21 ); + __wine_call_int_handler16( 0x21, &cxt ); else - __wine_call_int_handler( &cxt, 0x2f ); + __wine_call_int_handler16( 0x2f, &cxt );
CONTEXT_2_win32apieq(&cxt,pOut); return TRUE; diff --git a/dlls/krnl386.exe16/dosexe.h b/dlls/krnl386.exe16/dosexe.h index 42b8e0f4437..1e4d15c75e5 100644 --- a/dlls/krnl386.exe16/dosexe.h +++ b/dlls/krnl386.exe16/dosexe.h @@ -40,7 +40,6 @@ typedef void (WINAPI *INTPROC)(CONTEXT*);
extern WORD DOSVM_psp DECLSPEC_HIDDEN; /* psp of current DOS task */ extern WORD int16_sel DECLSPEC_HIDDEN; -extern WORD relay_code_sel DECLSPEC_HIDDEN;
#define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
@@ -236,7 +235,7 @@ extern void WINAPI DOSVM_Int2fHandler(CONTEXT*) DECLSPEC_HIDDEN; extern void WINAPI DOSVM_Int31Handler(CONTEXT*) DECLSPEC_HIDDEN;
/* interrupts.c */ -extern void __wine_call_int_handler( CONTEXT *, BYTE ) DECLSPEC_HIDDEN; +extern void WINAPI __wine_call_int_handler16( BYTE, CONTEXT * ) DECLSPEC_HIDDEN; extern BOOL DOSVM_EmulateInterruptPM( CONTEXT *, BYTE ) DECLSPEC_HIDDEN; extern FARPROC16 DOSVM_GetPMHandler16( BYTE ) DECLSPEC_HIDDEN; extern void DOSVM_SetPMHandler16( BYTE, FARPROC16 ) DECLSPEC_HIDDEN; @@ -245,7 +244,4 @@ extern void DOSVM_SetPMHandler16( BYTE, FARPROC16 ) DECLSPEC_HIDDEN; extern DWORD DOSVM_inport( int port, int size ) DECLSPEC_HIDDEN; extern void DOSVM_outport( int port, int size, DWORD value ) DECLSPEC_HIDDEN;
-/* relay.c */ -void DOSVM_BuildCallFrame( CONTEXT *, DOSRELAY, LPVOID ) DECLSPEC_HIDDEN; - #endif /* __WINE_DOSEXE_H */ diff --git a/dlls/krnl386.exe16/dosmem.c b/dlls/krnl386.exe16/dosmem.c index 2d55eb050de..64df77a3747 100644 --- a/dlls/krnl386.exe16/dosmem.c +++ b/dlls/krnl386.exe16/dosmem.c @@ -44,7 +44,6 @@ WORD DOSMEM_BiosSysSeg; /* BIOS ROM segment at 0xf000:0 */
WORD DOSVM_psp = 0; WORD int16_sel = 0; -WORD relay_code_sel = 0;
/* DOS memory highest address (including HMA) */ #define DOSMEM_SIZE 0x110000 @@ -302,11 +301,6 @@ static void DOSMEM_InitSegments(void) LPSTR ptr; int i;
- static const char relay[]= - { - 0xca, 0x04, 0x00, /* 16-bit far return and pop 4 bytes (relay void* arg) */ - }; - /* * PM / offset N*5: Interrupt N in 16-bit protected mode. */ @@ -325,14 +319,6 @@ static void DOSMEM_InitSegments(void) ptr[i * 5 + 4] = 0x00; } GlobalUnlock16( int16_sel ); - - /* - * PM / offset 0: Stub where __wine_call_from_16_regs returns. - */ - relay_code_sel = GLOBAL_Alloc( GMEM_FIXED, sizeof(relay), 0, LDT_FLAGS_CODE ); - ptr = GlobalLock16( relay_code_sel ); - memcpy( ptr, relay, sizeof(relay) ); - GlobalUnlock16( relay_code_sel ); }
/****************************************************************** diff --git a/dlls/krnl386.exe16/instr.c b/dlls/krnl386.exe16/instr.c index ff7f866f9e0..789c6dfb212 100644 --- a/dlls/krnl386.exe16/instr.c +++ b/dlls/krnl386.exe16/instr.c @@ -895,7 +895,7 @@ LONG CALLBACK INSTR_vectored_handler( EXCEPTION_POINTERS *ptrs ) */ void WINAPI DOS3Call( CONTEXT *context ) { - __wine_call_int_handler( context, 0x21 ); + __wine_call_int_handler16( 0x21, context ); }
@@ -904,7 +904,7 @@ void WINAPI DOS3Call( CONTEXT *context ) */ void WINAPI NetBIOSCall16( CONTEXT *context ) { - __wine_call_int_handler( context, 0x5c ); + __wine_call_int_handler16( 0x5c, context ); }
diff --git a/dlls/krnl386.exe16/interrupts.c b/dlls/krnl386.exe16/interrupts.c index d397d20072d..3c99eabcbba 100644 --- a/dlls/krnl386.exe16/interrupts.c +++ b/dlls/krnl386.exe16/interrupts.c @@ -120,19 +120,25 @@ static INTPROC DOSVM_GetBuiltinHandler( BYTE intnum ) return DOSVM_DefaultHandler; }
- -/********************************************************************** - * DOSVM_IntProcRelay +/* Set up the context so that we will call __wine_call_int_handler16 upon + * resuming execution. * - * Simple DOSRELAY that interprets its argument as INTPROC and calls it. - */ -static void DOSVM_IntProcRelay( CONTEXT *context, LPVOID data ) + * We can't just call the interrupt handler directly, since some code (in + * particular, LoadModule16) assumes that it's running on the 32-bit stack and + * that CURRENT_STACK16 points to the bottom of the used 16-bit stack. */ +static void return_to_interrupt_handler( CONTEXT *context, BYTE intnum ) { - INTPROC proc = (INTPROC)data; - proc(context); + FARPROC16 addr = GetProcAddress16( GetModuleHandle16( "KERNEL" ), "__wine_call_int_handler" ); + WORD *stack = ldt_get_ptr( context->SegSs, context->Esp ); + + *--stack = intnum; + *--stack = context->SegCs; + *--stack = context->Eip; + context->Esp -= 3 * sizeof(WORD); + context->SegCs = SELECTOROF(addr); + context->Eip = OFFSETOF(addr); }
- /********************************************************************** * DOSVM_PushFlags * @@ -205,10 +211,7 @@ static void DOSVM_HardwareInterruptPM( CONTEXT *context, BYTE intnum ) if (intnum == 0x25 || intnum == 0x26) DOSVM_PushFlags( context, FALSE, FALSE );
- DOSVM_BuildCallFrame( context, - DOSVM_IntProcRelay, - DOSVM_GetBuiltinHandler( - OFFSETOF(addr)/DOSVM_STUB_PM16 ) ); + return_to_interrupt_handler( context, OFFSETOF(addr) / DOSVM_STUB_PM16 ); } else { @@ -267,9 +270,7 @@ BOOL DOSVM_EmulateInterruptPM( CONTEXT *context, BYTE intnum ) if (intnum == 0x25 || intnum == 0x26) DOSVM_PushFlags( context, FALSE, TRUE );
- DOSVM_BuildCallFrame( context, - DOSVM_IntProcRelay, - DOSVM_GetBuiltinHandler(intnum) ); + return_to_interrupt_handler( context, intnum ); } else if (ldt_is_system(context->SegCs)) { @@ -399,9 +400,9 @@ static void DOSVM_CallBuiltinHandler( CONTEXT *context, BYTE intnum )
/********************************************************************** - * __wine_call_int_handler (KERNEL.@) + * __wine_call_int_handler16 (KERNEL.@) */ -void __wine_call_int_handler( CONTEXT *context, BYTE intnum ) +void WINAPI __wine_call_int_handler16( BYTE intnum, CONTEXT *context ) { DOSMEM_InitDosMemory(); DOSVM_CallBuiltinHandler( context, intnum ); diff --git a/dlls/krnl386.exe16/krnl386.exe16.spec b/dlls/krnl386.exe16/krnl386.exe16.spec index ddd321cbc31..c6ffd9df701 100644 --- a/dlls/krnl386.exe16/krnl386.exe16.spec +++ b/dlls/krnl386.exe16/krnl386.exe16.spec @@ -741,7 +741,8 @@ # or 'wine_' (for user-visible functions) to avoid namespace conflicts.
# DOS support -@ cdecl -arch=win32 __wine_call_int_handler(ptr long) +2000 pascal -register __wine_call_int_handler(word) __wine_call_int_handler16 +@ stdcall -arch=win32 __wine_call_int_handler16(long ptr)
# VxDs @ cdecl -arch=win32 -private __wine_vxd_open(wstr long ptr) diff --git a/dlls/krnl386.exe16/relay.c b/dlls/krnl386.exe16/relay.c index 116198e5ddb..2ec657bd3f8 100644 --- a/dlls/krnl386.exe16/relay.c +++ b/dlls/krnl386.exe16/relay.c @@ -551,47 +551,3 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT *conte } return ret_val; } - -/********************************************************************** - * RELAY_RelayStub - * - * This stub is called by __wine_call_from_16_regs in order to marshall - * relay parameters. - */ -static void __stdcall RELAY_RelayStub( DOSRELAY proc, unsigned char *args, CONTEXT *context ) -{ - proc( context, *(LPVOID *)args ); -} - -/********************************************************************** - * DOSVM_BuildCallFrame - * - * Modifies the context so that return to context calls DOSRELAY and - * only after return from DOSRELAY the original context will be returned to. - */ -void DOSVM_BuildCallFrame( CONTEXT *context, DOSRELAY relay, LPVOID data ) -{ - /* - * Build call frame. - */ - PUSH_WORD16( context, HIWORD(data) ); /* argument.hiword */ - PUSH_WORD16( context, LOWORD(data) ); /* argument.loword */ - PUSH_WORD16( context, context->SegCs ); /* STACK16FRAME.cs */ - PUSH_WORD16( context, LOWORD(context->Eip) ); /* STACK16FRAME.ip */ - PUSH_WORD16( context, LOWORD(context->Ebp) ); /* STACK16FRAME.bp */ - PUSH_WORD16( context, HIWORD(relay) ); /* STACK16FRAME.entry_point.hiword */ - PUSH_WORD16( context, LOWORD(relay) ); /* STACK16FRAME.entry_point.loword */ - PUSH_WORD16( context, 0 ); /* STACK16FRAME.entry_ip */ - PUSH_WORD16( context, HIWORD(RELAY_RelayStub) ); /* STACK16FRAME.relay.hiword */ - PUSH_WORD16( context, LOWORD(RELAY_RelayStub) ); /* STACK16FRAME.relay.loword */ - PUSH_WORD16( context, 0 ); /* STACK16FRAME.module_cs.hiword */ - PUSH_WORD16( context, relay_code_sel ); /* STACK16FRAME.module_cs.loword */ - PUSH_WORD16( context, 0 ); /* STACK16FRAME.callfrom_ip.hiword */ - PUSH_WORD16( context, 0 ); /* STACK16FRAME.callfrom_ip.loword */ - - /* - * Adjust code pointer. - */ - context->SegCs = get_cs(); - context->Eip = (DWORD)__wine_call_from_16_regs; -} diff --git a/dlls/vwin32.vxd/vwin32.c b/dlls/vwin32.vxd/vwin32.c index 82fa80c4e65..5a33f2ba665 100644 --- a/dlls/vwin32.vxd/vwin32.c +++ b/dlls/vwin32.vxd/vwin32.c @@ -55,7 +55,7 @@ typedef struct tagMID { } MID, *PMID; #include <poppack.h>
-extern void __wine_call_int_handler( CONTEXT *context, BYTE intnum ); +extern void WINAPI __wine_call_int_handler16( BYTE intnum, CONTEXT *context );
/* Pop a DWORD from the 32-bit stack */ static inline DWORD stack32_pop( CONTEXT *context ) @@ -155,7 +155,7 @@ BOOL WINAPI VWIN32_DeviceIoControl(DWORD dwIoControlCode, break; }
- __wine_call_int_handler( &cxt, intnum ); + __wine_call_int_handler16( intnum, &cxt ); CONTEXT_2_DIOCRegs( &cxt, pOut ); } return TRUE; @@ -208,7 +208,7 @@ DWORD WINAPI VWIN32_VxDCall( DWORD service, CONTEXT *context )
context->Eax = callnum; context->Ecx = parm; - __wine_call_int_handler( context, 0x31 ); + __wine_call_int_handler16( 0x31, context ); return LOWORD(context->Eax); } case 0x002a: /* Int41 dispatch - parm = int41 service number */