diff --git a/hdr/stacks.inc b/hdr/stacks.inc index f8be91e2..f4fcabbc 100644 --- a/hdr/stacks.inc +++ b/hdr/stacks.inc @@ -135,6 +135,8 @@ irp_hi equ 26 ; error 1 2 3 %macro Protect386Registers 0 %endmacro + + %assign Size386Registers 0 %macro RestoreSP 0 mov sp, bp @@ -151,8 +153,10 @@ irp_hi equ 26 push gs %endmacro + %assign Size386Registers 4 + %macro RestoreSP 0 - lea sp, [bp-4] + lea sp, [bp - Size386Registers] %endmacro %macro Restore386Registers 0 @@ -176,8 +180,10 @@ irp_hi equ 26 pop dx %endmacro + %assign Size386Registers 6 + %macro RestoreSP 0 - lea sp, [bp-6] + lea sp, [bp - Size386Registers] %endmacro %macro Restore386Registers 0 diff --git a/kernel/entry.asm b/kernel/entry.asm index 47316d62..ebceaad9 100644 --- a/kernel/entry.asm +++ b/kernel/entry.asm @@ -41,6 +41,8 @@ segment HMA_TEXT extern _user_r extern _ErrorMode extern _InDOS + extern _term_type + extern _abort_progress %IFDEF WIN31SUPPORT extern _winInstanced %ENDIF ; WIN31SUPPORT @@ -264,11 +266,11 @@ reloc_call_int21_handler: ; NB: At this point, SS != DS and won't be set that way ; until later when which stack to run on is determined. ; -int21_reentry: - Protect386Registers mov dx,[cs:_DGROUP_] mov ds,dx - + mov byte [_term_type], 0 ; reset termination type +int21_reentry: ; entered here from int 24h abort, ds = dx => DGROUP + Protect386Registers cmp ah,33h je int21_user cmp ah,50h @@ -611,6 +613,8 @@ CritErr05: mov bp,sp push si push di + Protect386Registers + ; ; Get parameters ; @@ -644,8 +648,8 @@ CritErr05: ; ; switch to user's stack ; - mov ss,[es:PSP_USERSS] mov bp,[es:PSP_USERSP] + mov ss,[es:PSP_USERSS] RestoreSP Restore386Registers mov bp,cx @@ -659,6 +663,13 @@ CritErr05: ; cld cli + Protect386Registers + ; ecm: The extended stack frame must be restored here + ; in case the response isn't Abort. The int 21h handler + ; will expect the extended stack frame to be still + ; intact, but the stack written by the int 24h (even + ; only the int instruction) will have overwritten it. + mov bp, [cs:_DGROUP_] mov ds,bp mov ss,bp @@ -672,7 +683,13 @@ CritErr05: pop word [es:PSP_USERSP] pop word [es:PSP_USERSS] mov bp, sp - mov ah, byte [bp+4+4] ; restore old AH from nFlags + mov ah, byte [bp + 4 + 4 + Size386Registers] + ; restore old AH from nFlags + ; ecm: One 4 is the displacement of nFlags from the + ; usual bp, the other 4 accounts for the si and di + ; on the stack, the Size386Registers is added to + ; skip the fs and gs (OpenWatcom 386 build) or high + ; words that are a part of the stack frame, if any. sti ; Enable interrupts ; ; clear flags @@ -715,6 +732,8 @@ CritErr30: CritErrExit: xor ah,ah ; clear out top for return + + Restore386Registers pop di pop si pop bp @@ -724,18 +743,28 @@ CritErrExit: ; Abort processing. ; CritErrAbort: + test byte [_abort_progress], -1 + mov al, FAIL + jnz CritErrExit +%if 0 mov ax,[_cu_psp] mov es,ax cmp ax,[es:PSP_PARENT] mov al,FAIL jz CritErrExit + ; ecm: This check is done by (E)DR-DOS, but not MS-DOS. + ; Therefore, disable it and terminate the self-parented + ; process here like any other. +%endif cli - mov bp,word [_user_r+2] ;Get frame - mov ss,bp + mov ax,word [_user_r+2] ;Get frame mov bp,word [_user_r] + mov ss,ax mov sp,bp mov byte [_ErrorMode],1 ; flag abort mov ax,4C00h mov [bp+reg_ax],ax sti + mov byte [_term_type], 2 ; set int 24h abort error + mov dx, ds jmp int21_reentry ; restart the system call diff --git a/kernel/globals.h b/kernel/globals.h index ac21eca9..14d0b5c7 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -307,7 +307,8 @@ extern BYTE ASM internal_data[], /* sda areas */ ASM swap_always[], /* " " */ ASM swap_indos[], /* " " */ - ASM tsr, /* true if program is TSR */ + ASM term_type, /* 0 normal, 1 ^C, 2 int 24h, 3 TSR */ + ASM abort_progress, /* set during process termination */ ASM break_flg, /* true if break was detected */ ASM break_ena; /* break enabled flag */ extern void FAR * ASM dta; /* Disk transfer area (kludge) */ diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 40209fea..46422c82 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -811,7 +811,7 @@ VOID ASMCFUNC int21_service(iregs FAR * r) case 0x31: DosMemChange(cu_psp, lr.DX < 6 ? 6 : lr.DX, 0); return_code = lr.AL | 0x300; - tsr = TRUE; + term_type = 3; /* ecm: TSR terminate */ return_user(); break; @@ -1104,18 +1104,11 @@ VOID ASMCFUNC int21_service(iregs FAR * r) /* End Program */ case 0x4c: - tsr = FALSE; - rc = 0; - if (ErrorMode) - { - ErrorMode = FALSE; - rc = 0x200; - } - else if (break_flg) - { + if (break_flg) { break_flg = FALSE; - rc = 0x100; + term_type = 1; } + rc = term_type << 8; return_code = lr.AL | rc; if (DosMemCheck() != SUCCESS) panic("MCB chain corrupted"); @@ -1784,7 +1777,7 @@ VOID INRPT FAR int23_handler(int es, int ds, int di, int si, int bp, int sp, int bx, int dx, int cx, int ax, int ip, int cs, int flags) { - tsr = FALSE; + term_type = 1; return_mode = 1; return_code = -1; mod_sto(CTL_C); diff --git a/kernel/kernel.asm b/kernel/kernel.asm index dd891654..1590b5c5 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -796,6 +796,7 @@ _DayOfWeek db 2 ; 36 - day of week _console_swap db 0 ; 37 console swapped during read from dev global _dosidle_flag _dosidle_flag db 1 ; 38 - safe to call int28 if nonzero + global _abort_progress _abort_progress db 0 ; 39 - abort in progress global _CharReqHdr _CharReqHdr: @@ -838,8 +839,12 @@ _Server_Call db 0 ;252 - Server call Func 5D sub 0 ; Pad to 05CCh times (25ch - ($ - _internal_data)) db 0 - global _tsr ; used by break and critical error -_tsr db 0 ;25C - handlers during termination + global _term_type ; used by break and critical error +_term_type db 0 ;25C - handlers during termination + ; ecm: 00h = normal terminate, + ; 01h = control-c terminate, + ; 02h = critical error abort, + ; 03h = TSR terminate db 0 ;25D - padding global term_psp term_psp dw 0 ;25E - 0?? diff --git a/kernel/procsupt.asm b/kernel/procsupt.asm index 623caf6a..c382ae6e 100644 --- a/kernel/procsupt.asm +++ b/kernel/procsupt.asm @@ -34,6 +34,7 @@ extern _user_r extern _break_flg ; break detected flag + extern _term_type extern _int21_handler ; far call system services %include "stacks.inc" @@ -257,6 +258,12 @@ _spawn_int23: push ds ;; we need DGROUP mov ds, [cs:_DGROUP_] inc byte [_break_flg] + mov byte [_term_type], 1 + ; ecm: This is overwritten in the int 21h handler, + ; but is passed from the int 23h caller to the + ; terminate code in MS-DOS by writing this. + ; For us, break_flg is used in function 4Ch to + ; re-set term_type to 1 later. pop ds xor ah, ah ;; clear ah --> perform DOS-00 --> terminate diff --git a/kernel/task.c b/kernel/task.c index 8ddb6e31..1f31b926 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -588,12 +588,14 @@ VOID return_user(void) setvec(0x23, p->ps_isv23); setvec(0x24, p->ps_isv24); + abort_progress = -1; + /* And free all process memory if not a TSR return */ network_redirector(REM_PROCESS_END); /* might be a good idea to do that after closing but doesn't help NET either TE */ - if (!tsr && p->ps_parent != cu_psp) + if (term_type != 3 && p->ps_parent != cu_psp) { network_redirector(REM_CLOSEALL); for (i = 0; i < p->ps_maxfiles; i++) @@ -607,6 +609,8 @@ VOID return_user(void) cu_psp = p->ps_parent; q = MK_FP(cu_psp, 0); + abort_progress = 0; + irp = (iregs FAR *) q->ps_stack; irp->CS = FP_SEG(p->ps_isv22);