diff --git a/dlls/winedos/int20.c b/dlls/winedos/int20.c index 45fbea04310..a333b319a8c 100644 --- a/dlls/winedos/int20.c +++ b/dlls/winedos/int20.c @@ -18,10 +18,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include "winbase.h" #include "dosexe.h" -#include "miscemu.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(int); /********************************************************************** * DOSVM_Int20Handler (WINEDOS16.132) @@ -30,9 +30,10 @@ */ void WINAPI DOSVM_Int20Handler( CONTEXT86 *context ) { - /* FIXME: Is this correct in DOS DPMI? */ - if (ISV86(context)) + if (DOSVM_IsWin16()) + ExitThread( 0 ); + else if(ISV86(context)) MZ_Exit( context, TRUE, 0 ); else - ExitThread(0); + ERR( "Called from DOS protected mode\n" ); } diff --git a/dlls/winedos/int21.c b/dlls/winedos/int21.c index f050be04bf0..e7806446ba4 100644 --- a/dlls/winedos/int21.c +++ b/dlls/winedos/int21.c @@ -38,6 +38,7 @@ #include "winuser.h" #include "wine/unicode.h" #include "wine/debug.h" +#include "wine/exception.h" /* * FIXME: Delete this reference when all int21 code has been moved to winedos. @@ -2623,8 +2624,10 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) TRACE("TERMINATE PROGRAM\n"); if (DOSVM_IsWin16()) ExitThread( 0 ); - else + else if(ISV86(context)) MZ_Exit( context, FALSE, 0 ); + else + ERR( "Called from DOS protected mode\n" ); break; case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */ @@ -3398,8 +3401,16 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context ) TRACE( "EXIT with return code %d\n", AL_reg(context) ); if (DOSVM_IsWin16()) ExitThread( AL_reg(context) ); - else + else if(ISV86(context)) MZ_Exit( context, FALSE, AL_reg(context) ); + else + { + /* + * Exit from DPMI. + */ + DWORD rv = AL_reg(context); + RaiseException( EXCEPTION_VM86_INTx, 0, 1, &rv ); + } break; case 0x4d: /* GET RETURN CODE */ diff --git a/dlls/winedos/int31.c b/dlls/winedos/int31.c index 2201db3fcb9..91af7b6eda2 100644 --- a/dlls/winedos/int31.c +++ b/dlls/winedos/int31.c @@ -69,6 +69,7 @@ typedef struct tagRMCB { static RMCB *FirstRMCB = NULL; static WORD dpmi_flag; static void* lastvalloced = NULL; +static BYTE DPMI_retval; /********************************************************************** * DOSVM_IsDos32 @@ -100,6 +101,14 @@ static WINE_EXCEPTION_FILTER(dpmi_exception_handler) DOSVM_SendQueuedEvents(context); return EXCEPTION_CONTINUE_EXECUTION; } + else if (rec->ExceptionCode == EXCEPTION_VM86_INTx) + { + if (ISV86(context)) + ERR( "Real mode INTx caught by protected mode handler!\n" ); + DPMI_retval = (BYTE)rec->ExceptionInformation[0]; + return EXCEPTION_EXECUTE_HANDLER; + } + #endif return EXCEPTION_CONTINUE_SEARCH; } @@ -593,8 +602,14 @@ static void StartPM( CONTEXT86 *context ) } __ENDTRY - /* in the current state of affairs, we won't ever actually return here... */ - /* we should have int21/ah=4c do it someday, though... */ + TRACE( "Protected mode DOS program is terminating\n" ); + + /* + * FIXME: Instead of calling ExitThread, we should release all + * allocated protected mode resources and call MZ_Exit + * using real mode context. See DPMI specification. + */ + ExitThread( DPMI_retval ); #if 0 FreeSelector16(psp->environment); diff --git a/dlls/winedos/module.c b/dlls/winedos/module.c index cce91a145d6..f7dc102471a 100644 --- a/dlls/winedos/module.c +++ b/dlls/winedos/module.c @@ -623,7 +623,7 @@ static void MZ_Launch( LPCSTR cmdtail, int length ) loop_thread = 0; loop_tid = 0; VGA_Clean(); - ExitThread(rv); + ExitProcess(rv); } /***********************************************************************