]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/CTRLC.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / CTRLC.ASM
1 ; SCCSID = @(#)ctrlc.asm 1.4 85/08/16
2 ; Low level routines for detecting special characters on CON input,
3 ; the ^C exit/int code, the Hard error INT 24 code, the
4 ; process termination code, and the INT 0 divide overflow handler.
5 ;
6 ; FATAL
7 ; FATAL1
8 ; reset_environment
9 ; DSKSTATCHK
10 ; SPOOLINT
11 ; STATCHK
12 ; CNTCHAND
13 ; DIVOV
14 ; CHARHARD
15 ; HardErr
16 ;
17 ; Revision history:
18 ;
19 ; AN000 version 4.0 Jan 1988
20 ; A002 PTM -- dir >lpt3 hangs
21 ; A003 PTM 3957- fake version for IBMCAHE.COM
22
23 ;
24 ; get the appropriate segment definitions
25 ;
26 .xlist
27 include dosseg.asm
28
29 CODE SEGMENT BYTE PUBLIC 'CODE'
30 ASSUME SS:DOSGROUP,CS:DOSGROUP
31
32 .xcref
33 INCLUDE DOSSYM.INC
34 INCLUDE DEVSYM.INC
35 include version.inc
36 .cref
37 .list
38
39 I_need SFN,WORD
40 I_NEED pJFN,DWORD
41 i_need DevIOBuf,BYTE
42 i_need DidCTRLC,BYTE
43 i_need INDOS,BYTE
44 i_need DSKSTCOM,BYTE
45 i_need DSKSTCALL,BYTE
46 i_need DSKSTST,WORD
47 i_need BCON,DWORD
48 i_need DSKCHRET,BYTE
49 i_need DSKSTCNT,WORD
50 i_need IDLEINT,BYTE
51 i_need CONSWAP,BYTE
52 i_need user_SS,WORD
53 i_need user_SP,WORD
54 i_need User_In_AX,WORD
55 i_need ERRORMODE,BYTE
56 i_need ConC_spsave,WORD
57 i_need Exit_type,BYTE
58 i_need PFLAG,BYTE
59 i_need ExitHold,DWORD
60 i_need WPErr,BYTE
61 i_need ReadOp,BYTE
62 i_need CONTSTK,WORD
63 i_need Exit_Code,WORD
64 i_need CurrentPDB,WORD
65 i_need DIVMES,BYTE
66 i_need DivMesLen,WORD
67 i_need ALLOWED,BYTE
68 i_need FAILERR,BYTE
69 i_need EXTERR,WORD
70 i_need ERR_TABLE_24,BYTE
71 I_need ErrMap24,BYTE
72 I_need ErrMap24End,BYTE
73 I_need fAborting,BYTE
74 I_need AUXStack,BYTE
75 I_need SCAN_FLAG,BYTE
76 I_need EXTOPEN_ON,BYTE ;AN000; DOS 4.0
77 I_need InterCon,BYTE ;AN000; DOS 4.0
78 I_need DOS34_FLAG,WORD ;AN000; DOS 4.0
79 I_need ACT_PAGE,WORD ;AN000; DOS 4.0
80 I_need Special_Version,WORD ;AN007; DOS 4.0
81 if debug
82 I_need BugLev,WORD
83 I_need BugTyp,WORD
84 include bugtyp.asm
85 endif
86 IF BUFFERFLAG
87 extrn restore_user_map:near
88 ENDIF
89
90 Break <Checks for ^C in CON I/O>
91
92 ASSUME DS:NOTHING,ES:NOTHING
93
94 procedure DSKSTATCHK,NEAR ; Check for ^C if only one level in
95 CMP BYTE PTR [INDOS],1
96 retnz ; Do NOTHING
97 PUSH CX
98 PUSH ES
99 PUSH BX
100 PUSH DS
101 PUSH SI
102 PUSH CS
103 POP ES
104 Context DS
105 DOSAssume CS,<DS>,"DskStatChk"
106 MOV BYTE PTR [DSKSTCOM],DEVRDND
107 MOV BYTE PTR [DSKSTCALL],DRDNDHL
108 MOV [DSKSTST],0
109 IF DBCS ;AN000;
110 MOV AL, [InterCon] ;AN000;get type of status read 2/13/KK
111 MOV BYTE PTR [DSKCHRET],AL ;AN000; load interim flag into packet
112 ENDIF ;AN000;
113 MOV BX,OFFSET DOSGROUP:DSKSTCALL
114 LDS SI,[BCON]
115 ASSUME DS:NOTHING
116 invoke DEVIOCALL2
117 TEST [DSKSTST],STBUI
118 JZ GotCh ; No characters available
119 XOR AL,AL ; Set zero
120 RET36:
121 POP SI
122 POP DS
123 POP BX
124 POP ES
125 POP CX
126 return
127
128 GotCh:
129 MOV AL,BYTE PTR [DSKCHRET]
130 DSK1:
131 CMP AL,"C"-"@"
132 JNZ RET36
133 MOV BYTE PTR [DSKSTCOM],DEVRD
134 MOV BYTE PTR [DSKSTCALL],DRDWRHL
135 MOV BYTE PTR [DSKCHRET],CL
136 MOV [DSKSTST],0
137 MOV [DSKSTCNT],1
138 invoke DEVIOCALL2 ; Eat the ^C
139 POP SI
140 POP DS
141 POP BX ; Clean stack
142 POP ES
143 POP CX
144 JMP CNTCHAND
145
146 NOSTOP:
147 CMP AL,"P"-"@"
148 JNZ check_next
149 CMP BYTE PTR [SCAN_FLAG],0 ; ALT_Q ?
150 JZ INCHKJ ; no
151 return
152 check_next:
153 IF NOT TOGLPRN
154 CMP AL,"N"-"@"
155 JZ INCHKJ
156 ENDIF
157
158 CMP AL,"C"-"@"
159 JZ INCHKJ
160 check_end:
161 return
162
163 INCHKJ:
164 JMP INCHK
165
166 EndProc DSKSTATCHK
167
168 ;
169 ; SpoolInt - signal processes that the DOS is truly idle. We are allowed to
170 ; do this ONLY if we are working on a 1-12 system call AND if we are not in
171 ; the middle of an INT 24.
172 ;
173 procedure SPOOLINT,NEAR
174 PUSHF
175 test IdleInt,-1
176 jz POPFRet
177 test ErrorMode,-1
178 jnz POPFRet
179 ;
180 ; Note that we are going to allow an external program to issue system calls
181 ; at this time. We MUST preserve IdleInt across this.
182 ;
183 PUSH WORD PTR IdleInt
184 INT int_spooler
185 POP WORD PTR IdleInt
186 POPFRET:
187 POPF
188 return
189 EndProc SPOOLINT
190
191 procedure STATCHK,NEAR
192
193 invoke DSKSTATCHK ; Allows ^C to be detected under
194 ; input redirection
195 PUSH BX
196 XOR BX,BX
197 invoke GET_IO_SFT
198 POP BX
199 retc
200 MOV AH,1
201 invoke IOFUNC
202 JZ SPOOLINT
203 CMP AL,"S"-"@"
204 JNZ NOSTOP
205
206 CMP BYTE PTR [SCAN_FLAG],0 ;AN000; ALT_R ?
207 JNZ check_end ;AN000; yes
208 XOR AH,AH
209 invoke IOFUNC ; Eat Cntrl-S
210 JMP SHORT PAUSOSTRT
211 PRINTOFF:
212 PRINTON:
213 NOT BYTE PTR [PFLAG]
214 PUSH BX
215 MOV BX,4
216 invoke GET_IO_SFT
217 POP BX
218 retc
219 PUSH ES
220 PUSH DI
221 PUSH DS
222 POP ES
223 MOV DI,SI ; ES:DI -> SFT
224 TEST ES:[DI.sf_flags],sf_net_spool
225 JZ NORM_PR ; Not redirected, echo is OK
226 Callinstall NetSpoolEchoCheck,MultNet,38,<AX>,<AX> ; See if allowed
227 JNC NORM_PR ; Echo is OK
228 MOV BYTE PTR [PFLAG],0 ; If not allowed, disable echo
229 Callinstall NetSpoolClose,MultNet,36,<AX>,<AX> ; and close
230 JMP SHORT RETP6
231
232 NORM_PR:
233 CMP BYTE PTR [PFLAG],0
234 JNZ PRNOPN
235 invoke DEV_CLOSE_SFT
236 JMP SHORT RETP6
237
238 PRNOPN:
239 invoke DEV_OPEN_SFT
240 RETP6:
241 POP DI
242 POP ES
243 return
244
245 PAUSOLP:
246 CALL SPOOLINT
247 PAUSOSTRT:
248 MOV AH,1
249 invoke IOFUNC
250 JZ PAUSOLP
251 INCHK:
252 PUSH BX
253 XOR BX,BX
254 invoke GET_IO_SFT
255 POP BX
256 retc
257 XOR AH,AH
258 invoke IOFUNC
259 CMP AL,"P"-"@"
260 ;;;;; 7/14/86 ALT_Q key fix
261
262 JZ PRINTON ; no! must be CTRL_P
263
264 NOPRINT:
265 ;;;;; 7/14/86 ALT_Q key fix
266 IF NOT TOGLPRN
267 CMP AL,"N"-"@"
268 JZ PRINTOFF
269 ENDIF
270 CMP AL,"C"-"@"
271 retnz
272 EndProc STATCHK
273
274 procedure CNTCHAND,NEAR
275 ; Ctrl-C handler.
276 ; "^C" and CR/LF is printed. Then the user registers are restored and the
277 ; user CTRL-C handler is executed. At this point the top of the stack has 1)
278 ; the interrupt return address should the user CTRL-C handler wish to allow
279 ; processing to continue; 2) the original interrupt return address to the code
280 ; that performed the function call in the first place. If the user CTRL-C
281 ; handler wishes to continue, it must leave all registers unchanged and RET
282 ; (not IRET) with carry CLEAR. If carry is SET then an terminate system call
283 ; is simulated.
284 TEST [DOS34_FLAG],CTRL_BREAK_FLAG ;AN002; from RAWOUT
285 JNZ around_deadlock ;AN002;
286 MOV AL,3 ; Display "^C"
287 invoke BUFOUT
288 invoke CRLF
289 around_deadlock: ;AN002;
290 Context DS
291 CMP BYTE PTR [CONSWAP],0
292 JZ NOSWAP
293 invoke SWAPBACK
294 NOSWAP:
295 CLI ; Prepare to play with stack
296 MOV SS,[user_SS] ; User stack now restored
297 ASSUME SS:NOTHING
298 MOV SP,[user_SP]
299 invoke restore_world ; User registers now restored
300 ASSUME DS:NOTHING
301 MOV BYTE PTR [INDOS],0 ; Go to known state
302 MOV BYTE PTR [ERRORMODE],0
303 MOV [ConC_spsave],SP ; save his SP
304 CLC
305 INT int_ctrl_c ; Execute user Ctrl-C handler
306 ;
307 ; The user has returned to us. The circumstances we allow are:
308 ;
309 ; IRET We retry the operation by redispatching the system call
310 ; CLC/RETF POP the stack and retry
311 ; ... Exit the current process with ^C exit
312 ;
313 ; User's may RETURN to us and leave interrupts on. Turn 'em off just to be
314 ; sure
315 ;
316 CLI
317 MOV [user_IN_AX],ax ; save the AX
318 PUSHF ; and the flags (maybe new call)
319 POP AX
320 ;
321 ; See if the input stack is identical to the output stack
322 ;
323 CMP SP,[ConC_spsave]
324 JNZ ctrlc_try_new ; current SP not the same as saved SP
325 ;
326 ; Repeat the operation by redispatching the system call.
327 ;
328 ctrlc_repeat:
329 MOV AX,User_In_AX
330 transfer COMMAND
331 ;
332 ; The current SP is NOT the same as the input SP. Presume that he RETF'd
333 ; leaving some flags on the stack and examine the input
334 ;
335 ctrlc_try_new:
336 ADD SP,2 ; pop those flags
337 TEST AX,f_carry ; did he return with carry?
338 JZ Ctrlc_Repeat ; no carry set, just retry
339 ;
340 ; Well... time to abort the user. Signal a ^C exit and use the EXIT system
341 ; call..
342 ;
343 ctrlc_abort:
344 MOV AX,(EXIT SHL 8) + 0
345 MOV DidCTRLC,-1
346 transfer COMMAND ; give up by faking $EXIT
347
348 EndProc CNTCHAND
349
350 Break <DIVISION OVERFLOW INTERRUPT>
351
352 ; Default handler for division overflow trap
353 procedure DIVOV,NEAR
354 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
355 MOV SI,OFFSET DOSGROUP:DIVMES
356 MOV BX,DivMesLen
357 MOV AX,CS
358 MOV SS,AX
359 MOV SP,OFFSET DOSGROUP:AUXSTACK ; Enough stack for interrupts
360 CALL OutMes
361 JMP ctrlc_abort ; Use Ctrl-C abort on divide overflow
362 EndProc DIVOV
363
364 ;
365 ; OutMes: perform message output
366 ; Inputs: SS:SI points to message
367 ; BX has message length
368 ; Outputs: message to BCON
369 ;
370 procedure OutMes,NEAR
371
372 Context ES ; get ES addressability
373 Context DS ; get DS addressability
374
375 MOV BYTE PTR [DskStCom],DevWrt
376 MOV BYTE PTR [DskStCall],DRdWrHL
377 MOV [DskSTST],0
378 MOV [DskStCnt],BX
379 MOV BX,OFFSET DOSGROUP:DskStCall
380 MOV WORD PTR [DskChRet+1],SI ; transfer address (need an EQU)
381 LDS SI,[BCON]
382 ASSUME DS:NOTHING
383 invoke DEVIOCALL2
384 MOV WORD PTR [DskChRet+1],OFFSET DOSGROUP:DevIOBuf
385 MOV [DskStCnt],1
386 return
387 EndProc OutMes
388
389 Break <CHARHRD,HARDERR,ERROR -- HANDLE DISK ERRORS AND RETURN TO USER>
390
391 procedure CHARHARD,NEAR
392 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
393
394 ; Character device error handler
395 ; Same function as HARDERR
396
397 OR AH,allowed_FAIL + allowed_IGNORE + allowed_RETRY
398 MOV Allowed,AH
399 MOV WORD PTR [EXITHOLD+2],ES
400 MOV WORD PTR [EXITHOLD],BP
401 PUSH SI
402 AND DI,STECODE
403 MOV BP,DS ; Device pointer is BP:SI
404 CALL FATALC
405 POP SI
406 return
407 EndProc CHARHARD
408
409 ; Hard disk error handler. Entry conditions:
410 ; DS:BX = Original disk transfer address
411 ; DX = Original logical sector number
412 ; CX = Number of sectors to go (first one gave the error)
413 ; AX = Hardware error code
414 ; DI = Original sector transfer count
415 ; ES:BP = Base of drive parameters
416 ; [READOP] = 0 for read, 1 for write
417 ; [ALLOWED] Set with allowed responses to this error (other bits MUST BE 0)
418 ; Output:
419 ; [FAILERR] will be set if user responded FAIL
420
421 procedure HardErr,NEAR
422 ASSUME DS:NOTHING,ES:NOTHING
423
424 XCHG AX,DI ; Error code in DI, count in AX
425 AND DI,STECODE ; And off status bits
426 CMP DI,error_I24_write_protect ; Write Protect Error?
427 JNZ NOSETWRPERR
428 PUSH AX
429 MOV AL,ES:[BP.dpb_drive]
430 MOV BYTE PTR [WPERR],AL ; Flag drive with WP error
431 POP AX
432 NOSETWRPERR:
433 SUB AX,CX ; Number of sectors successfully transferred
434 ADD DX,AX ; First sector number to retry
435 PUSH DX
436 MUL ES:[BP.dpb_sector_size] ; Number of bytes transferred
437 POP DX
438 ADD BX,AX ; First address for retry
439 XOR AH,AH ; Flag disk section in error
440 CMP DX,ES:[BP.dpb_first_FAT] ; In reserved area?
441 JB ERRINT
442 INC AH ; Flag for FAT
443 CMP DX,ES:[BP.dpb_dir_sector] ; In FAT?
444 JAE TESTDIR ; No
445 MOV ES:[BP.dpb_free_cnt],-1 ; Err in FAT must force recomp of freespace
446 JMP SHORT ERRINT
447
448 TESTDIR:
449 INC AH
450 CMP DX,ES:[BP.dpb_first_sector] ; In directory?
451 JB ERRINT
452 INC AH ; Must be in data area
453 ERRINT:
454 SHL AH,1 ; Make room for read/write bit
455 OR AH,BYTE PTR [READOP] ; Set bit 0
456 ; If we have a write protect error when writing on a critical area on disk,
457 ; do not allow a retry as this may write out garbage on any subsequent disk.
458 ;test ah,1
459 ;jz Not_Crit
460 ;cmp ah,5
461 ;ja Not_Crit
462 ;and [ALLOWED],NOT Allowed_RETRY
463 Not_Crit:
464 OR AH,[ALLOWED] ; Set the allowed_ bits
465 entry FATAL
466 MOV AL,ES:[BP.dpb_drive] ; Get drive number
467 entry FATAL1
468 MOV WORD PTR [EXITHOLD+2],ES
469 MOV WORD PTR [EXITHOLD],BP ; The only things we preserve
470 LES SI,ES:[BP.dpb_driver_addr]
471 MOV BP,ES ; BP:SI points to the device involved
472 ;
473 ; DI has the INT-24-style extended error. We now map the error code for this
474 ; into the normalized get extended error set by using the ErrMap24 table as an
475 ; translate table. Note that we translate ONLY the device returned codes and
476 ; leave all others beyond the look up table alone.
477 ;
478 FATALC:
479 call SET_I24_EXTENDED_ERROR
480 CMP DI,error_I24_gen_failure
481 JBE GOT_RIGHT_CODE ; Error codes above gen_failure get
482 MOV DI,error_I24_gen_failure ; mapped to gen_failure. Real codes
483 ; Only come via GetExtendedError
484
485 entry NET_I24_ENTRY
486 ; Entry point used by REDIRector on Network I 24 errors.
487 ;
488 ; ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
489 ;
490 ; ALL I 24 regs set up. ALL Extended error info SET. ALLOWED Set.
491 ; EXITHOLD set for restore of ES:BP.
492
493 GOT_RIGHT_CODE:
494 CMP BYTE PTR [ERRORMODE],0 ; No INT 24s if already INT 24
495 JZ NoSetFail
496 MOV AL,3
497 JMP FailRet
498 NoSetFail:
499 IF BUFFERFLAG
500 invoke RESTORE_USER_MAP ;AN000;LB. restore user's EMS map
501 ENDIF
502 MOV [CONTSTK],SP
503 Context ES
504 fmt TypINT24,LevLog,<"INT 24: AX = $x DI = $x\n">,<AX,DI>
505 ;
506 ; Wango!!! We may need to free some user state info... In particular, we
507 ; may have locked down a JFN for a user and he may NEVER return to us. Thus,
508 ; we need to free it here and then reallocate it when we come back.
509 ;
510 CMP SFN,-1
511 JZ NoFree
512 SaveReg <DS,SI>
513 LDS SI,pJFN
514 MOV BYTE PTR [SI],0FFH
515 RestoreReg <SI,DS>
516 NoFree:
517 CLI ; Prepare to play with stack
518 INC BYTE PTR [ERRORMODE] ; Flag INT 24 in progress
519 DEC BYTE PTR [INDOS] ; INT 24 handler might not return
520 ;; Extneded Open hooks
521 TEST [DOS34_FLAG],Force_I24_Fail ;AN000;IFS. form IFS Call Back ;AN000;
522 JNZ faili24 ;AN000;IFS. ;AN000;
523 TEST [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;IFS.I24 error disabled ;AN000;
524 JZ i24yes ;AN000;IFS.no ;AN000;
525 faili24: ;AN000;
526 MOV AL,3 ;AN000;IFS.fake fail ;AN000;
527 JMP passi24 ;AN000;IFS.exit ;AN000;
528 i24yes: ;AN000;
529
530 ;; Extended Open hooks
531 MOV SS,[user_SS]
532 ASSUME SS:NOTHING
533 MOV SP,ES:[user_SP] ; User stack pointer restored
534 INT int_fatal_abort ; Fatal error interrupt vector, must preserve ES
535 MOV ES:[user_SP],SP ; restore our stack
536 MOV ES:[user_SS],SS
537 MOV BP,ES
538 MOV SS,BP
539 ASSUME SS:DOSGROUP
540 passi24: ;AN000;
541 MOV SP,[CONTSTK]
542 INC BYTE PTR [INDOS] ; Back in the DOS
543 MOV BYTE PTR [ERRORMODE],0 ; Back from INT 24
544 STI
545 ;; MOV [ACT_PAGE],-1 ;LB. invalidate DOS active page ;AN000;
546 ;; invoke SAVE_MAP ;LB. save user's EMS map ;AN000;
547 fmt TypINT24,LevLog,<"INT 24: User reply = $x\n">,<AX>
548 FAILRET:
549 LES BP,[EXITHOLD]
550 ASSUME ES:NOTHING
551 ;
552 ; Triage the user's reply.
553 ;
554 CMP AL,1
555 JB CheckIgnore ; 0 => ignore
556 JZ CheckRetry ; 1 => retry
557 CMP AL,3 ; 3 => fail
558 JNZ DoAbort ; 2, invalid => abort
559 ;
560 ; The reply was fail. See if we are allowed to fail.
561 ;
562 TEST [ALLOWED],allowed_FAIL ; Can we?
563 JZ DoAbort ; No, do abort
564 DoFail:
565 MOV AL,3 ; just in case...
566 TEST [EXTOPEN_ON],EXT_OPEN_I24_OFF ;AN000;EO. I24 error disabled
567 JNZ cleanup ;AN000;EO. no
568 INC [FAILERR] ; Tell everybody
569 CleanUp:
570 MOV WpErr,-1
571 CMP SFN,-1
572 retz
573 SaveReg <DS,SI,AX>
574 MOV AX,SFN
575 LDS SI,pJFN
576 MOV [SI],AL
577 RestoreReg <AX,SI,DS>
578 return
579 ;
580 ; The reply was IGNORE. See if we are allowed to ignore.
581 ;
582 CheckIgnore:
583 TEST [ALLOWED],allowed_IGNORE ; Can we?
584 JZ DoFail ; No, do fail
585 JMP CleanUp
586 ;
587 ; The reply was RETRY. See if we are allowed to retry.
588 ;
589 CheckRetry:
590 TEST [ALLOWED],allowed_RETRY ; Can we?
591 JZ DoFail ; No, do fail
592 JMP CleanUp
593 ;
594 ; The reply was ABORT.
595 ;
596 DoAbort:
597 Context DS
598 CMP BYTE PTR [CONSWAP],0
599 JZ NOSWAP2
600 invoke SWAPBACK
601 NOSWAP2:
602 ;
603 ; See if we are to truly abort. If we are in the process of aborting, turn
604 ; this abort into a fail.
605 ;
606 TEST fAborting,-1
607 JNZ DoFail
608 ;
609 ; Set return code
610 ;
611 MOV BYTE PTR [exit_Type],Exit_hard_error
612 XOR AL,AL
613 ;
614 ; we are truly aborting the process. Go restore information from the PDB as
615 ; necessary.
616 ;
617 Transfer exit_inner
618 ;
619 ; reset_environment checks the DS value against the CurrentPDB. If they are
620 ; different, then an old-style return is performed. If they are the same,
621 ; then we release jfns and restore to parent. We still use the PDB at DS:0 as
622 ; the source of the terminate addresses.
623 ;
624 ; Some subtlety: We are about to issue a bunch of calls that *may* generate
625 ; INT 24s. We *cannot* allow the user to restart the abort process; we may
626 ; end up aborting the wrong process or turn a terminate/stay/resident into a
627 ; normal abort and leave interrupt handlers around. What we do is to set a
628 ; flag that will indicate that if any abort code is seen, we just continue the
629 ; operation. In essence, we dis-allow the abort response.
630 ;
631 ; output: none.
632 ;
633 entry reset_environment
634 ASSUME DS:NOTHING,ES:NOTHING
635
636 invoke Reset_Version ;AN007;MS. reset version number
637 PUSH DS ; save PDB of process
638
639 ;
640 ; There are no critical sections in force. Although we may enter here with
641 ; critical sections locked down, they are no longer relevant. We may safely
642 ; free all allocated resources.
643 ;
644 MOV AH,82h
645 INT int_IBM
646
647 MOV fAborting,-1 ; signal abort in progress
648
649 CallInstall NetResetEnvironment, multNet, 34 ;DOS 4.00 doesn't need it
650 ; Allow REDIR to clear some stuff
651 ; On process exit.
652 MOV AL,int_Terminate
653 invoke $Get_interrupt_vector ; and who to go to
654
655 POP CX ; get ThisPDB
656 SaveReg <ES,BX> ; save return address
657
658 MOV BX,[CurrentPDB] ; get currentPDB
659 MOV DS,BX
660 MOV AX,DS:[PDB_Parent_PID] ; get parentPDB
661
662 ;
663 ; AX = parentPDB, BX = CurrentPDB, CX = ThisPDB
664 ; Only free handles if AX <> BX and BX = CX and [exit_code].upper is not
665 ; Exit_keep_process
666 ;
667 CMP AX,BX
668 JZ reset_return ; parentPDB = CurrentPDB
669 CMP BX,CX
670 JNZ reset_return ; CurrentPDB <> ThisPDB
671 PUSH AX ; save parent
672 CMP BYTE PTR [exit_type],Exit_keep_process
673 JZ reset_to_parent ; keeping this process
674 ;
675 ; We are truly removing a process. Free all allocation blocks belonging to
676 ; this PDB
677 ;
678 invoke arena_free_process
679 ;
680 ; Kill off remainder of this process. Close file handles and signal to
681 ; relevant network folks that this process is dead. Remember that CurrentPDB
682 ; is STILL the current process!
683 ;
684 invoke DOS_ABORT
685
686 reset_to_parent:
687 POP [CurrentPDB] ; set up process as parent
688
689 reset_return: ; come here for normal return
690 PUSH CS
691 POP DS
692 ASSUME DS:DOSGROUP
693 MOV AL,-1
694 ;
695 ; make sure that everything is clean In this case ignore any errors, we cannot
696 ; "FAIL" the abort, the program being aborted is dead.
697 ;
698 EnterCrit critDisk
699 invoke FLUSHBUF
700 LeaveCrit critDisk
701 ;
702 ; Decrement open ref. count if we had done a virtual open earlier.
703 ;
704 invoke CHECK_VIRT_OPEN
705 IF BUFFERFLAG
706 invoke RESTORE_USER_MAP ;AN000;LB. restore user's EMS map
707 ENDIF
708 CLI
709 MOV BYTE PTR [INDOS],0 ; Go to known state
710 MOV BYTE PTR [WPERR],-1 ; Forget about WP error
711 MOV fAborting,0 ; let aborts occur
712 POP WORD PTR ExitHold
713 POP WORD PTR ExitHold+2
714 ;
715 ; Snake into multitasking... Get stack from CurrentPDB person
716 ;
717 MOV DS,[CurrentPDB]
718 ASSUME DS:NOTHING
719 MOV SS,WORD PTR DS:[PDB_user_stack+2]
720 MOV SP,WORD PTR DS:[PDB_user_stack]
721
722 ASSUME SS:NOTHING
723 invoke restore_world
724 ASSUME ES:NOTHING
725 MOV User_SP,AX
726 POP AX ; suck off CS:IP of interrupt...
727 POP AX
728 POP AX
729 MOV AX,0F202h ; STI
730 PUSH AX
731 PUSH WORD PTR [EXITHOLD+2]
732 PUSH WORD PTR [EXITHOLD]
733 MOV AX,User_SP
734 IRET ; Long return back to user terminate address
735 EndProc HardErr
736
737 ;
738 ; This routine handles extended error codes.
739 ; Input : DI = error code from device
740 ; Output: All EXTERR fields are set
741 ;
742 Procedure SET_I24_EXTENDED_ERROR,NEAR
743 PUSH AX
744 MOV AX,OFFSET DOSGroup:ErrMap24End
745 SUB AX,OFFSET DOSGroup:ErrMap24
746 ;
747 ; AX is the index of the first unavailable error. Do not translate if
748 ; greater or equal to AX.
749 ;
750 CMP DI,AX
751 MOV AX,DI
752 JAE NoTrans
753 MOV AL,ErrMap24[DI]
754 XOR AH,AH
755 NoTrans:
756 MOV [EXTERR],AX
757 POP AX
758 ;
759 ; Now Extended error is set correctly. Translate it to get correct error
760 ; locus class and recommended action.
761 ;
762 PUSH SI
763 MOV SI,OFFSET DOSGROUP:ERR_TABLE_24
764 invoke CAL_LK ; Set other extended error fields
765 POP SI
766 ret
767 EndProc SET_I24_EXTENDED_ERROR
768
769 CODE ENDS
770 END
771 \1a