mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-15 06:20:47 +00:00
krnl386: Return to a generated 16-bit entry point when calling builtin interrupt handlers.
Instead of manually building a STACK16FRAME. Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a6118baa56
commit
5b38636b95
|
@ -97,7 +97,7 @@ static void CONTEXT_2_win32apieq(const CONTEXT *pCxt, struct win32apireq *pOut)
|
||||||
/* FIXME: pOut->ar_pad ignored */
|
/* 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.@)
|
* DeviceIoControl (IFSMGR.VXD.@)
|
||||||
|
@ -132,9 +132,9 @@ BOOL WINAPI IFSMGR_DeviceIoControl(DWORD dwIoControlCode, LPVOID lpvInBuffer, DW
|
||||||
win32apieq_2_CONTEXT(pIn,&cxt);
|
win32apieq_2_CONTEXT(pIn,&cxt);
|
||||||
|
|
||||||
if(dwIoControlCode==IFS_IOCTL_21)
|
if(dwIoControlCode==IFS_IOCTL_21)
|
||||||
__wine_call_int_handler( &cxt, 0x21 );
|
__wine_call_int_handler16( 0x21, &cxt );
|
||||||
else
|
else
|
||||||
__wine_call_int_handler( &cxt, 0x2f );
|
__wine_call_int_handler16( 0x2f, &cxt );
|
||||||
|
|
||||||
CONTEXT_2_win32apieq(&cxt,pOut);
|
CONTEXT_2_win32apieq(&cxt,pOut);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -40,7 +40,6 @@ typedef void (WINAPI *INTPROC)(CONTEXT*);
|
||||||
|
|
||||||
extern WORD DOSVM_psp DECLSPEC_HIDDEN; /* psp of current DOS task */
|
extern WORD DOSVM_psp DECLSPEC_HIDDEN; /* psp of current DOS task */
|
||||||
extern WORD int16_sel DECLSPEC_HIDDEN;
|
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)))
|
#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;
|
extern void WINAPI DOSVM_Int31Handler(CONTEXT*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* interrupts.c */
|
/* 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 BOOL DOSVM_EmulateInterruptPM( CONTEXT *, BYTE ) DECLSPEC_HIDDEN;
|
||||||
extern FARPROC16 DOSVM_GetPMHandler16( BYTE ) DECLSPEC_HIDDEN;
|
extern FARPROC16 DOSVM_GetPMHandler16( BYTE ) DECLSPEC_HIDDEN;
|
||||||
extern void DOSVM_SetPMHandler16( BYTE, FARPROC16 ) 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 DWORD DOSVM_inport( int port, int size ) DECLSPEC_HIDDEN;
|
||||||
extern void DOSVM_outport( int port, int size, DWORD value ) 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 */
|
#endif /* __WINE_DOSEXE_H */
|
||||||
|
|
|
@ -44,7 +44,6 @@ WORD DOSMEM_BiosSysSeg; /* BIOS ROM segment at 0xf000:0 */
|
||||||
|
|
||||||
WORD DOSVM_psp = 0;
|
WORD DOSVM_psp = 0;
|
||||||
WORD int16_sel = 0;
|
WORD int16_sel = 0;
|
||||||
WORD relay_code_sel = 0;
|
|
||||||
|
|
||||||
/* DOS memory highest address (including HMA) */
|
/* DOS memory highest address (including HMA) */
|
||||||
#define DOSMEM_SIZE 0x110000
|
#define DOSMEM_SIZE 0x110000
|
||||||
|
@ -302,11 +301,6 @@ static void DOSMEM_InitSegments(void)
|
||||||
LPSTR ptr;
|
LPSTR ptr;
|
||||||
int i;
|
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.
|
* 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;
|
ptr[i * 5 + 4] = 0x00;
|
||||||
}
|
}
|
||||||
GlobalUnlock16( int16_sel );
|
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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
|
|
@ -895,7 +895,7 @@ LONG CALLBACK INSTR_vectored_handler( EXCEPTION_POINTERS *ptrs )
|
||||||
*/
|
*/
|
||||||
void WINAPI DOS3Call( CONTEXT *context )
|
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 )
|
void WINAPI NetBIOSCall16( CONTEXT *context )
|
||||||
{
|
{
|
||||||
__wine_call_int_handler( context, 0x5c );
|
__wine_call_int_handler16( 0x5c, context );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -120,18 +120,24 @@ static INTPROC DOSVM_GetBuiltinHandler( BYTE intnum )
|
||||||
return DOSVM_DefaultHandler;
|
return DOSVM_DefaultHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set up the context so that we will call __wine_call_int_handler16 upon
|
||||||
/**********************************************************************
|
* resuming execution.
|
||||||
* DOSVM_IntProcRelay
|
|
||||||
*
|
*
|
||||||
* Simple DOSRELAY that interprets its argument as INTPROC and calls it.
|
* 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
|
||||||
static void DOSVM_IntProcRelay( CONTEXT *context, LPVOID data )
|
* 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;
|
FARPROC16 addr = GetProcAddress16( GetModuleHandle16( "KERNEL" ), "__wine_call_int_handler" );
|
||||||
proc(context);
|
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
|
* DOSVM_PushFlags
|
||||||
|
@ -205,10 +211,7 @@ static void DOSVM_HardwareInterruptPM( CONTEXT *context, BYTE intnum )
|
||||||
if (intnum == 0x25 || intnum == 0x26)
|
if (intnum == 0x25 || intnum == 0x26)
|
||||||
DOSVM_PushFlags( context, FALSE, FALSE );
|
DOSVM_PushFlags( context, FALSE, FALSE );
|
||||||
|
|
||||||
DOSVM_BuildCallFrame( context,
|
return_to_interrupt_handler( context, OFFSETOF(addr) / DOSVM_STUB_PM16 );
|
||||||
DOSVM_IntProcRelay,
|
|
||||||
DOSVM_GetBuiltinHandler(
|
|
||||||
OFFSETOF(addr)/DOSVM_STUB_PM16 ) );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -267,9 +270,7 @@ BOOL DOSVM_EmulateInterruptPM( CONTEXT *context, BYTE intnum )
|
||||||
if (intnum == 0x25 || intnum == 0x26)
|
if (intnum == 0x25 || intnum == 0x26)
|
||||||
DOSVM_PushFlags( context, FALSE, TRUE );
|
DOSVM_PushFlags( context, FALSE, TRUE );
|
||||||
|
|
||||||
DOSVM_BuildCallFrame( context,
|
return_to_interrupt_handler( context, intnum );
|
||||||
DOSVM_IntProcRelay,
|
|
||||||
DOSVM_GetBuiltinHandler(intnum) );
|
|
||||||
}
|
}
|
||||||
else if (ldt_is_system(context->SegCs))
|
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();
|
DOSMEM_InitDosMemory();
|
||||||
DOSVM_CallBuiltinHandler( context, intnum );
|
DOSVM_CallBuiltinHandler( context, intnum );
|
||||||
|
|
|
@ -741,7 +741,8 @@
|
||||||
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
|
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
|
||||||
|
|
||||||
# DOS support
|
# 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
|
# VxDs
|
||||||
@ cdecl -arch=win32 -private __wine_vxd_open(wstr long ptr)
|
@ cdecl -arch=win32 -private __wine_vxd_open(wstr long ptr)
|
||||||
|
|
|
@ -551,47 +551,3 @@ int relay_call_from_16( void *entry_point, unsigned char *args16, CONTEXT *conte
|
||||||
}
|
}
|
||||||
return ret_val;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ typedef struct tagMID {
|
||||||
} MID, *PMID;
|
} MID, *PMID;
|
||||||
#include <poppack.h>
|
#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 */
|
/* Pop a DWORD from the 32-bit stack */
|
||||||
static inline DWORD stack32_pop( CONTEXT *context )
|
static inline DWORD stack32_pop( CONTEXT *context )
|
||||||
|
@ -155,7 +155,7 @@ BOOL WINAPI VWIN32_DeviceIoControl(DWORD dwIoControlCode,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
__wine_call_int_handler( &cxt, intnum );
|
__wine_call_int_handler16( intnum, &cxt );
|
||||||
CONTEXT_2_DIOCRegs( &cxt, pOut );
|
CONTEXT_2_DIOCRegs( &cxt, pOut );
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -208,7 +208,7 @@ DWORD WINAPI VWIN32_VxDCall( DWORD service, CONTEXT *context )
|
||||||
|
|
||||||
context->Eax = callnum;
|
context->Eax = callnum;
|
||||||
context->Ecx = parm;
|
context->Ecx = parm;
|
||||||
__wine_call_int_handler( context, 0x31 );
|
__wine_call_int_handler16( 0x31, context );
|
||||||
return LOWORD(context->Eax);
|
return LOWORD(context->Eax);
|
||||||
}
|
}
|
||||||
case 0x002a: /* Int41 dispatch - parm = int41 service number */
|
case 0x002a: /* Int41 dispatch - parm = int41 service number */
|
||||||
|
|
Loading…
Reference in a new issue