This patch changes DOSVM exit logic. In the old logic, terminating DOS programs in real mode posted WM_QUIT to service thread while terminating in protected mode just called ExitThread (this is likely required by Win16?). Now, both use ExitThread which means that DOSVM can be shutdown properly in both real and protected mode. Changelog: Terminating DOS program in real mode now calls ExitThread which is exactly what terminating in protected mode does. Index: dlls/winedos/dosexe.h =================================================================== RCS file: /home/wine/wine/dlls/winedos/dosexe.h,v retrieving revision 1.5 diff -u -r1.5 dosexe.h --- dlls/winedos/dosexe.h 3 Apr 2002 02:34:45 -0000 1.5 +++ dlls/winedos/dosexe.h 5 May 2002 08:37:10 -0000 @@ -53,7 +53,7 @@ extern void WINAPI MZ_RunInThread( PAPCFUNC proc, ULONG_PTR arg ); extern INT WINAPI DOSVM_Enter( CONTEXT86 *context ); extern void WINAPI DOSVM_Wait( INT read_pipe, HANDLE hObject ); -extern DWORD WINAPI DOSVM_Loop( LPVOID lpExtra ); +extern DWORD WINAPI DOSVM_Loop( HANDLE hThread ); extern void WINAPI DOSVM_QueueEvent( INT irq, INT priority, DOSRELAY relay, LPVOID data ); extern void WINAPI DOSVM_PIC_ioport_out( WORD port, BYTE val ); extern void WINAPI DOSVM_SetTimer( UINT ticks ); Index: dlls/winedos/module.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/module.c,v retrieving revision 1.15 diff -u -r1.15 module.c --- dlls/winedos/module.c 1 May 2002 18:04:11 -0000 1.15 +++ dlls/winedos/module.c 5 May 2002 08:37:41 -0000 @@ -94,7 +94,6 @@ static void MZ_Launch(void); static BOOL MZ_InitTask(void); -static void MZ_KillTask(void); static void MZ_CreatePSP( LPVOID lpPSP, WORD env, WORD par ) { @@ -474,6 +473,7 @@ TDB *pTask = TASK_GetCurrent(); BYTE *psp_start = PTR_REAL_TO_LIN( DOSVM_psp, 0 ); LPSTR cmdline = GetCommandLineA(); + DWORD rv; MZ_FillPSP(psp_start, cmdline, cmdline ? strlen(cmdline) : 0); pTask->flags |= TDBF_WINOLDAP; @@ -481,20 +481,15 @@ _LeaveWin16Lock(); ResumeThread(dosvm_thread); - DOSVM_Loop(NULL); - ExitThread(0); -} + rv = DOSVM_Loop(dosvm_thread); -static void MZ_KillTask(void) -{ - TRACE("killing DOS task\n"); - VGA_Clean(); - PostThreadMessageA(loop_tid, WM_QUIT, 0, 0); - WaitForSingleObject(loop_thread, INFINITE); /* ? */ CloseHandle(dosvm_thread); dosvm_thread = 0; dosvm_tid = 0; CloseHandle(loop_thread); loop_thread = 0; loop_tid = 0; + + VGA_Clean(); + ExitThread(rv); } /*********************************************************************** @@ -531,7 +526,7 @@ context->Esp = OFFSETOF(psp->saveStack); return; } else - MZ_KillTask(); + TRACE("killing DOS task\n"); } ExitThread( retval ); } Index: dlls/winedos/dosvm.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/dosvm.c,v retrieving revision 1.16 diff -u -r1.16 dosvm.c --- dlls/winedos/dosvm.c 2 Apr 2002 19:20:12 -0000 1.16 +++ dlls/winedos/dosvm.c 5 May 2002 08:38:12 -0000 @@ -370,19 +370,30 @@ } while (TRUE); } -DWORD WINAPI DOSVM_Loop( LPVOID lpExtra ) +DWORD WINAPI DOSVM_Loop( HANDLE hThread ) { - HANDLE obj = GetStdHandle(STD_INPUT_HANDLE); + HANDLE objs[2]; MSG msg; DWORD waitret; + objs[0] = GetStdHandle(STD_INPUT_HANDLE); + objs[1] = hThread; + for(;;) { TRACE_(int)("waiting for action\n"); - waitret = MsgWaitForMultipleObjects(1, &obj, FALSE, INFINITE, QS_ALLINPUT); + waitret = MsgWaitForMultipleObjects(2, objs, FALSE, INFINITE, QS_ALLINPUT); if (waitret == WAIT_OBJECT_0) { DOSVM_ProcessConsole(); } else if (waitret == WAIT_OBJECT_0 + 1) { + DWORD rv; + if(!GetExitCodeThread(hThread, &rv)) { + ERR("Failed to get thread exit code!\n"); + rv = 0; + } + return rv; + } + else if (waitret == WAIT_OBJECT_0 + 2) { while (PeekMessageA(&msg,0,0,0,PM_REMOVE)) { if (msg.hwnd) { /* it's a window message */ -- Jukka Heinonen <http://www.iki.fi/jhei/>