This patch cleans up DOS exit paths. ExitProcess seems to work better than ExitThread for some reason. DOS exit process functions int20 and int21/00 really don't support DPMI mode, so some sanity checks were added. DPMI exit function int21/4c now properly returns to StartPM so proper cleanup routine could be added there later. The reason why I'm posting lots of small patches is that I'm currently working on a big RMCB fix which seems to still have some minor problems and I want to submit working parts from that patch in order to reduce the amount of changed code I have. Changelog: Make DOS process exit using ExitProcess instead of ExitThread. Make calling DOS exit functions from DPMI either return to StartPM or print error message if not allowed by DPMI specification. Index: dlls/winedos/module.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/module.c,v retrieving revision 1.36 diff -u -r1.36 module.c --- dlls/winedos/module.c 25 Aug 2003 01:01:01 -0000 1.36 +++ dlls/winedos/module.c 30 Aug 2003 16:37:06 -0000 @@ -623,7 +623,7 @@ loop_thread = 0; loop_tid = 0; VGA_Clean(); - ExitThread(rv); + ExitProcess(rv); } /*********************************************************************** Index: dlls/winedos/int20.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/int20.c,v retrieving revision 1.4 diff -u -r1.4 int20.c --- dlls/winedos/int20.c 6 Nov 2002 19:57:49 -0000 1.4 +++ dlls/winedos/int20.c 30 Aug 2003 16:37:12 -0000 @@ -18,10 +18,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <stdlib.h> -#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" ); } Index: dlls/winedos/int21.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/int21.c,v retrieving revision 1.38 diff -u -r1.38 int21.c --- dlls/winedos/int21.c 16 Jun 2003 01:18:01 -0000 1.38 +++ dlls/winedos/int21.c 30 Aug 2003 16:37:15 -0000 @@ -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 @@ 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 @@ 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 */ Index: dlls/winedos/int31.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/int31.c,v retrieving revision 1.32 diff -u -r1.32 int31.c --- dlls/winedos/int31.c 27 Aug 2003 02:52:18 -0000 1.32 +++ dlls/winedos/int31.c 30 Aug 2003 16:37:19 -0000 @@ -69,6 +69,7 @@ static RMCB *FirstRMCB = NULL; static WORD dpmi_flag; static void* lastvalloced = NULL; +static BYTE DPMI_retval; /********************************************************************** * DOSVM_IsDos32 @@ -100,6 +101,14 @@ 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 @@ } __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); -- Jukka Heinonen <http://www.iki.fi/jhei/>