www.pudn.com > drdossrc.zip > CRIT.ASM


;    File              : $Workfile: CRIT.ASM$ 
; 
;    Description       : 
; 
;    Original Author   : DIGITAL RESEARCH 
; 
;    Last Edited By    : $CALDERA$ 
; 
;-----------------------------------------------------------------------; 
;    Copyright Work of Caldera, Inc. All Rights Reserved. 
;       
;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL, 
;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC. 
;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES 
;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF 
;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO 
;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE 
;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE 
;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED, 
;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED, 
;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST, 
;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF 
;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT 
;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND 
;    CIVIL LIABILITY. 
;-----------------------------------------------------------------------; 
; 
;    *** Current Edit History *** 
;    *** End of Current Edit History *** 
; 
;    $Log$ 
;    CRIT.ASM 1.11 94/12/01 10:05:21 
;    Changed critical error message display so that the default message 
;    is 'I/O error' and that all share-related codes are converted to 
;    'File sharing conflict' 
;     
;    CRIT.ASM 1.9 93/09/10 15:56:08  
;    Use device driver header at BP:SI instead of AH to determine if disk/char device 
;    That way we get "device NETWORK" rather than "drive D" on VLM critical errors 
;    ENDLOG 
; 
; 19/Sep/88 Move the messages into a separate module 
; 15/Dec/88 Critical Error messages processed by STDERR 
; 06/Apr/89 DR DOS version taken from PCMODE & put in COMMAND.COM 
; 10/Aug/89 Issue INT 2F's so application can give it's own error message 
; 08/Sep/89 'No FCBs' message 
; 02/Nov/89 abort_char etc become ABS rather than CHAR (saves a few bytes) 
; 13/Nov/89 Reduced number of external messages referenced to one 
;		(crit_top) to aid Dual Language Support. 
; 12/Feb/90 Changed code to avoid problems with double byte character sets. 
;  8/Mar/90 Remove extra pair of CR/LF's that were output after error 
; 20/Apr/90 DLS data into R_TEXT for Watcom C v7.0 
;  9/May/90 Critical errors go to STDERR on command PSP, not current_psp 
 
	include msdos.equ 
	include mserror.equ 
	include	driver.equ 
; 
dataOFFSET	equ offset DGROUP: 
 
 
PSP_XFTPTR	equ	es:dword ptr 34h	; from i:PSP.DEF 
 
;	Critical Error responses from the default INT 24 handler and 
;	the DO_INT24 routine. 
; 
ERR_IGNORE	equ	0		; Ignore Error 
ERR_RETRY	equ	1		; Retry the Operation 
ERR_ABORT	equ	2		; Terminate the Process 
ERR_FAIL	equ	3		; Fail Function 
; 
OK_FAIL		equ	00001000b	; Fail is a Valid Response 
OK_RETRY	equ	00010000b	; Retry is a Valid Response 
OK_IGNORE	equ	00100000b	; Ignore is a valid Response 
OK_RIF		equ	00111000b	; All Responsese are Valid 
OK_RI		equ	00110000b	; Retry and Ignore are Valid 
OK_RF		equ	00011000b	; Retry and Fail are Valid 
; 
; 
;	The following equates allow us to access the users registers 
;	and flags during normal system call emulation. 
; 
;NOTE:-	The users INT21 structure is not normally available because of the 
;	stack switch which occurs on entry and only the general purpose 
;	registers are copied to the new stack. 
; 
dos_AX		equ	word ptr 0[bp] 
dos_BX		equ	word ptr 2[bp] 
dos_CX		equ	word ptr 4[bp] 
dos_DX		equ	word ptr 6[bp] 
dos_SI		equ	word ptr 8[bp] 
dos_DI		equ	word ptr 10[bp] 
dos_BP		equ	word ptr 12[bp] 
dos_DS		equ	word ptr 14[bp] 
dos_ES		equ	word ptr 16[bp] 
; 
; 
; 
ifdef CDOSTMP 
DGROUP	GROUP	R_TEXT 
 
R_TEXT		SEGMENT byte public 'CDOS_DATA' 
 
else 
 
DGROUP	GROUP	_DATA, R_TEXT, ED_TEXT 
 
R_TEXT		SEGMENT byte public 'CDOS_DATA' 
R_TEXT		ENDS 
 
_DATA		SEGMENT byte public 'DATA' 
 
endif 
	extrn	_country:WORD 
	extrn	__psp:WORD 
 
ifdef DLS 
TEXT_LEN	equ	320		; it needs to be this size for Japanese 
 
	Public	_crit_msgs 
 
	; crit_table gives offset into crit_msgs table. 
 
crit_table	db	0		; (00) Write to Read Only Disk 
		db	2		; (01) Unknown Unit 
		db	4		; (02) Drive Not Ready 
		db	2		; (03) Unknown Command 
		db	6		; (04) Data Error (CRC) 
		db	2		; (05) Bad Request Length Structure 
		db	8		; (06) Seek Error 
		db	10		; (07) Unknown Media Type 
		db	12		; (08) Sector Not Found 
		db	14		; (09) Printer Out Of Paper 
		db	2		; (0A) Write Fault 
		db	2		; (0B) Read Fault 
		db	2		; (0C) General Failure 
		db	16		; (0D) File Sharing Error 
		db	16		; (0E) Locking Error 
		db	18		; (0F) FCB Unavailable 
 
_crit_msgs	dw	TEXT_LEN	; size of this message buffer 
crit_top	dw	0,0,0,0,0,0,0,0,0,0 
msg_crlf	dw	0	 
readmsg		dw	0 
writemsg	dw	0 
drivemsg	dw	0 
charmsg		dw	0 
abort_char	dw	0 
abort_msg	dw	0 
retry_char	dw	0 
retry_msg	dw	0 
ignore_char	dw	0 
ignore_msg	dw	0 
fail_char	dw	0 
fail_msg	dw	0 
prompt_msg	dw	0 
		dw	0	; end of list 
 
public	_crit_text 
_crit_text	db	TEXT_LEN dup(?)	; message text is placed here 
 
CRIT_LEN	equ	$-crit_top 
 
 
else 
 
	extrn	msg0:byte, msg2:byte, msg3:byte, msg4:byte 
	extrn	msg6:byte, msg7:byte, msg8:byte 
	extrn	msg20:byte, msg21:byte, msg22:byte 
 
crit_top	dw	offset DGROUP:msg0	; (00) Write to Read Only Disk 
		dw	offset DGROUP:msg3	; (01) Unknown Unit 
		dw	offset DGROUP:msg2	; (02) Drive Not Ready 
		dw	offset DGROUP:msg3	; (03) Unknown Command 
		dw	offset DGROUP:msg4	; (04) Data Error (CRC) 
		dw	offset DGROUP:msg3	; (05) Bad Request Length Structure 
		dw	offset DGROUP:msg6	; (06) Seek Error 
		dw	offset DGROUP:msg7	; (07) Unknown Media Type 
		dw	offset DGROUP:msg8	; (08) Sector Not Found 
		dw	offset DGROUP:msg21	; (09) Printer Out Of Paper 
		dw	offset DGROUP:msg3	; (0A) Write Fault 
		dw	offset DGROUP:msg3	; (0B) Read Fault 
		dw	offset DGROUP:msg3	; (0C) General Failure 
		dw	offset DGROUP:msg20	; (0D) File Sharing Error 
		dw	offset DGROUP:msg20	; (0E) Locking Error 
		dw	offset DGROUP:msg22	; (0F) FCB Unavailable 
 
 
	Extrn	msg_crlf:byte 
	Extrn	readmsg:byte, writemsg:byte, drivemsg:byte, charmsg:byte 
	Extrn	abort_char:byte, abort_msg:byte 
	Extrn	retry_char:byte, retry_msg:byte 
	Extrn	ignore_char:byte, ignore_msg:byte 
	Extrn	fail_char:byte, fail_msg:byte, prompt_msg:byte 
endif 
ifndef CDOSTMP 
_DATA	ends 
ED_TEXT		SEGMENT para public 'CDATA' 
endif 
 
	assume cs:DGROUP, ds:nothing, es:nothing, ss:nothing 
; 
;	This is the default critical error handler which will prompt 
;	the user with an error message and wait for a response. This handler 
;	is usually replaced by the DOS application 
; 
;	+++++++++++++++++++++++++++++++ 
;	Int 24 - Critical Error Handler 
;	+++++++++++++++++++++++++++++++ 
; 
;	INT 24 Critical Error:- 
;	    On Entry:-	AH/7	0 = Disk Device 
;			AH/5	0 = IGNORE is an Invalid Response 
;			AH/4	0 = RETRY in an Invalid Response 
;			AH/3	0 = FAIL is an Invalid Response 
;			AH/2-1	00= DOS Area 
;				01= File Allocation Table 
;				10= Directory 
;				11= Data 
;			AH/0	0 = Read, 1 = Write 
; 
;			AL	Failing Disk Drive if AH/7 == 0 
;			BP:SI	Device Header Control Block 
;			DI	High Byte DRNET server (inverted, CDOS only) 
;				Low Byte Error Code  
; 
;	    On Exit:-	AL	0 = IGNORE Error 
;				1 = RETRY the Operation 
;				2 = TERMINATE using INT 23 
;				3 = FAIL the current DOS function 
; 
; 
 
	Public	com_criterr	 
com_criterr: 
; 
;	This is called by the int24 handler 'critical_error', in CSTART.ASM. 
; 
	sti 
	cld 
	push	es 
	push	ds 
	push	bp 
	push	di 
	push	si 
	push	dx 
	push	cx 
	push	bx 
	push	ax 
	 
	mov	bp,sp 
	mov	ah,MS_P_GETPSP 
	int	DOS_INT			; Get PSP into DS 
	mov	ds,cs:__psp	 
	mov	al,ds:byte ptr 1ah	; use COMMAND STDERR for Console INPUT 
	mov	ah,al			;  and OUTPUT 
	mov	es,bx 
	lds	bx,PSP_XFTPTR		; Get the handle table pointer 
	push	word ptr [bx]		; Save the current Values 
	mov	word ptr [bx],ax 
 
	push	cs 
	pop	ds			; DS == CS 
	call	i24_crlf		;output carriage return - line feed 
 
	mov	ah,MS_F_ERROR 
	xor	bx,bx 
	int	DOS_INT			; Get extended error code 
	mov	cx,ax			; Get the Real Error Code (ie INT21/59) 
	mov	bx,0Fh			; assume FCB unavailable 
	cmp	al,-(ED_NOFCBS)		; if FCB exhausted/closed then generate 
	 je	int24_e10		;  a more appropriate error message 
	dec	bx 
    dec bx           
	cmp	al,-(ED_SHAREFAIL)	;  check for sharing failure which 
	 je	int24_e10		;  is forced to be a DRIVE NOT READY 
	cmp	al,-(ED_NOLOCKS)	; check for sharing buffer overflow 
	 je	int24_e10 
	dec	bx			; BX = 0Ch, default error 
	mov	ax,dos_DI		; get the REAL error code 
	cmp	ax,0Eh			; is it a sensible value ? 
	 ja	int24_e10		; no, return GENERAL FAILURE 
	xchg	ax,bx			; yes, use it 
int24_e10: 
	call	int24_errmsg		; print out the offending error msg 
	call	i24_crlf		; Print CR/LF 
 
; 
;	This section of the Critical Error handler prints the correct 
;	prompt repeatedly until the user responds with a correct 
;	response. This value is returned to the PCMODE. 
; 
i24_query: 
ifdef DLS 
	mov dx,abort_msg		; Print "Abort" as this is always 
else 
	mov dx,dataOFFSET abort_msg	; Print "Abort" as this is always 
endif 
	call i24_print			; a valid response 
 
	test bh,OK_RETRY 
	 jz i24_q10			; Display ", Retry" if RETRY  
ifdef DLS 
	mov	dx,retry_msg		; is a Valid Response 
else 
	mov	dx,dataOFFSET retry_msg	; is a Valid Response 
endif 
	call	i24_print 
 
i24_q10: 
	test bh,OK_IGNORE 
	 jz i24_q20			; Display ", Ignore" if IGNORE 
ifdef DLS 
	mov	dx,ignore_msg		; is a valid response 
else 
	mov	dx,dataOFFSET ignore_msg ; is a valid response 
endif 
	call	i24_print 
 
i24_q20: 
	test bh,OK_FAIL 
	 jz i24_q30			; Display ", Fail" if FAIL is 
ifdef DLS 
	mov	dx,fail_msg		; a valid response 
else 
	mov	dx,dataOFFSET fail_msg	; a valid response 
endif 
	call	i24_print 
 
i24_q30: 
ifdef DLS 
	mov	dx,prompt_msg 
else 
	mov	dx,dataOFFSET prompt_msg 
endif 
	call	i24_print 
 
	mov	ah,MS_C_FLUSH		; Clear type ahead buffer 
	mov	al,MS_C_READ		; and then get a character 
	int	DOS_INT 
 
; In case we get double byte characters... 
; If we had access to the dbcs_lead() routine (in the non-resident code) 
; we could test for a double byte character and consume the second byte. 
; Since we can't do this I have used the following code, which simply 
; consumes and displays all bytes in type-ahead buffer. 
	push	ax			; save first character received 
dbcs_loop: 
	mov	ah, MS_C_RAWIO		; char in type-ahead buffer? 
	mov	dl, 0FFh 
	int	DOS_INT 
	 jz	dbcs_exit		;  no - exit loop 
	mov	dl, al 
	mov	ah, MS_C_WRITE		;  yes - display char 
	int	DOS_INT 
	jmp short dbcs_loop		; loop until type-ahead buffer empty 
dbcs_exit: 
	pop	ax			; restore the first character 
 
; Check that character lies in the range 'a' <= ch <= 'z' before anding it 
; with 5Fh to uppercase it (incase the character is a DBCS lead byte). 
 
	cmp	al, 'a'			; ch < 'a' ? 
	 jb	uc_done			;  yes - skip upper casing 
	cmp	al, 'z'			; ch > 'z' ? 
	 ja	uc_intl			;  yes - may be intl 
	and	al, 5Fh			; uppercase ch 
	jmp short uc_done 
uc_intl: 
	cmp	al, 80h			; international char? 
	 jb	uc_done 
; ch >= 80h  -- call international routine 
UCASE	equ	18			; offset of dword ptr to uppercase func 
	call	dword ptr [_country+UCASE] 
uc_done: 
 
	push	ax 
	call	i24_crlf 
	pop	dx 
 
	mov	ah,bh 
	xor	al,al			; AL == 0 IGNORE Error 
ifdef DLS 
	test	ah,OK_IGNORE 
	 jz	i24_q40			; Is it a valid response 
	mov	bx,ignore_char 
	cmp	dl,[bx] 
else 
	test	bh,OK_IGNORE 
	 jz	i24_q40			; Is it a valid response 
	cmp	dl,ignore_char 
endif 
	 jz 	i24_exit 
 
i24_q40: 
	inc	ax			; AL == 1 RETRY Function 
ifdef DLS 
	test	ah,OK_RETRY 
	 jz	i24_q50			; Is it a valid response 
	mov	bx,retry_char 
	cmp	dl,[bx] 
else 
	test	bh,OK_RETRY 
	 jz	i24_q50			; Is it a valid response 
	cmp	dl,retry_char 
endif 
	 jz	i24_exit 
 
i24_q50: 
	inc	ax			; AL == 2 ABORT Process 
ifdef DLS 
	mov	bx,abort_char 
	cmp	dl,[bx] 
else 
	cmp	dl,abort_char 
endif 
	 jz	i24_exit 
 
	inc	ax			; AL == 3 FAIL Function 
ifdef DLS 
	test	ah,OK_FAIL 
	 jz	i24_query_again		; Is it a valid response 
	mov	bx,fail_char 
	cmp	dl,[bx] 
	 jz	i24_exit 
i24_query_again: 
	mov	bh, ah			; restore valid response bit set 
	jmp	i24_query 
else 
	test	bh,OK_FAIL 
	 jz	i24_query_again		; Is it a valid response 
	cmp	dl,fail_char 
	 jz	i24_exit 
i24_query_again: 
	jmp	i24_query 
endif 
 
 
i24_exit: 
	mov	dos_AX,ax 
	mov	ah,MS_P_GETPSP 
	int	DOS_INT			; Get PSP into DS 
	mov	es,bx 
	lds	bx,PSP_XFTPTR		; the handle table pointer 
	pop	word ptr [bx]		; Restore the original handle Values 
	 
	pop	ax 
	pop	bx 
	pop	cx 
	pop	dx 
	pop	si 
	pop	di 
	pop	bp 
	pop	ds 
	pop	es 
 
	ret 
 
int24_errmsg: 
; Print out an appropriate error message (eg. "Drive not ready") 
; Call INT 2F functions in case system extentions (eg. CDROM) wish to 
; give another error message. 
	push	bx			; save error code 
	push	cx 
	mov	ax,500h 
	int	2fh			; query if user msg handler installed 
	cmp	al,0ffh			; yes if FF returned 
	pop	cx 
	pop	bx 
	 jne	int24_errmsg10 
	push	bx 
	push	cx 
if 0 
; the DOS 3 way 
	mov	ah,5			; OK. now we ask for a message 
	mov	al,cl			;  with the error code in AL 
else 
; the DOS 5 way 
	mov	ax,501h 
	mov	bx,cx 
endif 
	int	2fh			; ES:DI -> msg 
	pop	cx 
	pop	bx 
	 jc	int24_errmsg10		; did they give us a msg ? 
	mov	si,di			; ES:SI -> msg 
	mov	ah,MS_C_WRITE		; write it out 
int24_errmsg1: 
	lods	es:byte ptr [si]	; get a character 
	test	al,al			; until end of an ASCIIZ string 
	 jz	int24_errmsg2 
	mov	dl,al			; character into DL 
	int	DOS_INT			; write it 
	jmp short int24_errmsg1 
int24_errmsg2: 
	mov	bx,dos_AX		; get original AX for Abort/Retry etc 
	ret 
	 
int24_errmsg10: 
; No-one wants to supply a message - we'd better generate one ourselves 
; 
	xor	bh,bh			  
ifdef	DLS 
	mov	bl, crit_table[bx] 
else 
	shl	bx,1 
endif 
	mov	dx, crit_top[bx]	 
	call	i24_print		 
 
	mov	bx,dos_AX		; Get the Original AX 
	test 	bh,01h			; check to see if the error occured  
	jnz 	prwrite			; while reading or writing 
ifdef DLS 
	mov 	dx,readmsg 		; print 'reading' 
else 
	mov 	dx,dataOFFSET readmsg 	; print 'reading' 
endif 
	jmp short prread 
prwrite: 
ifdef DLS 
	mov 	dx,writemsg		; print 'writing' 
else 
	mov 	dx,dataOFFSET writemsg	; print 'writing' 
endif 
prread: 
	call	i24_print		; appropriate string 
;;	test	bh,80h 
	mov	es,dos_BP		; ES:SI = driver header 
	test	es:DH_ATTRIB[si],DA_CHARDEV 
	 jz	disk_error		; Was this a DISK error 
 
; 
;	For Character Device errors print the failing Device Name 
;	and then prompt the user for a valid response. 
; 
;character_error: 
ifdef DLS 
	mov	dx,charmsg 
else 
	mov	dx,dataOFFSET charmsg 
endif 
	call	i24_print 
 
;;	mov	es,dos_BP		; ES:SI = driver header 
	mov	cx,8			; Print the 8 Character device name 
char_name: 
	mov	dl,DH_NAME[si]		; Get the next character and 
	mov	ah,MS_C_WRITE		; display on the console 
	int 	DOS_INT 
	inc	si			; Increment the character pointer 
	loop	char_name		; and Loop till complete name displayed 
	ret				; Now query the user 
 
; 
;	For DISK errors print the failing drive code and then 
;	prompt the user for a valid response. 
; 
disk_error: 
ifdef DLS 
	mov	dx,drivemsg		; 
else 
	mov	dx,dataOFFSET drivemsg	; 
endif 
	call	i24_print		; print 'drive d' 
	mov	dl,bl			; Get the Drive Code 
	add 	dl,'A'			; convert drive to ascii  
	mov 	ah,MS_C_WRITE		; print the drive 
	int	DOS_INT 
	ret 
 
i24_crlf: 
ifdef DLS 
	mov	dx,msg_crlf 
else 
	mov	dx,dataOFFSET msg_crlf 
endif 
 
i24_print: 
	mov 	ah,MS_C_WRITESTR 
	int	DOS_INT 
	ret 
 
ifdef CDOSTMP 
R_TEXT	ENDS 
else 
ED_TEXT	ENDS 
endif 
	end