;       SCCSID = @(#)d_err.asm	6.1 91/02/15
;	SCCSID = @(#)d_err.asm	6.2 90/01/22
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
; **** D_ERR.ASM - API stub routine DosError
;
;	Member of API library
;	Steven Zeck
;	David Silverstein
;	(C) Copyright Microsoft Corporation, 1986
;	Date Written May 1986
;
;	library routine for API simulator
;	Called from dos 2.x,3.x compatible dos 5.x applications
;
;	Modification History
;
;	7-18-86 (davidsi) - Added parameter checking with an error
;		return code.
;
;	8-18-86 (davidsi) - Added pushes of registers being modified.
;
;	9-24-86 (davidsi) - replaced critical error hooking with calls to
;		FapiAddSigCatch and FapiSubSigCatch
;
;	06-Jan-87 (billme): Replace initial pushes and final pops
;	with calls to __api_begin and __api_end resp.  This will
;	reduce the size of FAPI and allow support for signals.
;
;	04-Jun-87 (chernow): add call to external crit_err_accum to
;	get hard error info for return

include dos2equ.inc
include error.inc
include api.inc

	EXTRN	__api_begin:near
	EXTRN	__api_end:near

;***	DosError  - Fail all system calls with an error returned to user
;
;	simulates DOS 5.0 call from DOS 2.x,3.x environment
;
;	We replace the critical error vector with our own.
;	When an int 24 happens, simply fail the call.
;

_TEXT	segment byte public 'CODE'
	assume	CS:_TEXT, DS:nothing

	public	DOSERROR

	extrn	_api_getvrsn :NEAR
	extrn	FapiAddSigCatch :FAR
	extrn	FapiSubSigCatch :FAR
	extrn	crit_err_accum :NEAR

Flag	equ	[bp + 6]	;0 => disable int 24 errors, 1 => enable
Clear_Bit_1	equ    0fffdh

fFlushingBuffers	db	0	; in process of flushing cach buffers
FInt24Happened		db	0	; cach buffer caused another int24
DosVersion		db	0	; Dos major version number
Int24Installed		db	0	; int24 handler installed flag

DOSERROR	proc	far

	call	__api_begin	; init bp and save bp,ds,bx,cx,dx,si,di,es
				; required to save: bp,ds,dx,bx

	and	word ptr [Flag], Clear_Bit_1
	cmp	word ptr [Flag], 0		; disable int24 errors?
	je	derr1
	cmp	word ptr [Flag], 1		; enable int24 errors?
	je	derr2
	mov	ax, error_invalid_parameter	; load error code & exit
	jmp	short derr4

derr1:
	; disable int24 errors and fail the system call instead

	cmp	_TEXT:[Int24Installed], 1	; int24 vec already installed?
	je	derr3				; skip it
	call	_api_getvrsn			; get Dos version number
	mov	_TEXT:DosVersion, ah		; save it

	push	cs				; ds:dx <= int24 handler address
	pop	ds
	mov	dx, offset _TEXT:myint24
	mov	bx, DERROR			; load fapi library function #
	call	FapiAddSigCatch			; install new int24 handler
	mov	_TEXT:[Int24Installed], 1	; flag installed
	jmp	short derr3

derr2:
	; enable or reenable int24 error handling

	cmp	[Int24Installed], 0		; is handler not installed?
	je	derr3				; nothing to do
	mov	[Int24Installed], 0		; flag not installed
	mov	bx, DERROR			; load fapi library function #
	call	FapiSubSigCatch			; deinstall our int24 handler
derr3:
	xor	ax, ax				; clear error code
derr4:

	call	__api_end	; check sigs & restore es,di,si,dx,cx,bx,ds,bp

	ret	2

DOSERROR	endp



myInt24 proc	far	   ;My critical error handler

	push	ax

	cmp	_TEXT:[DosVersion], 2
	jne	i19

	; Dos 2.x doesn't define the fail option from a critical
	; error,  so return from the system call via cleaning up the
	; stack and returning error info in the registers and flags
	;
	; Since DOS has multiple buffers we must force all the buffers
	; to be flushed to the device whiched caused the error.  This
	; so later system activity, unrelated to the bad device doesn't
	; cause spurrous errors.  This done by issuing system resets
	; until on int 24 event happens.

	cmp	_TEXT:[fFlushingBuffers], 1
	jne	i11

	inc	_TEXT:[fInt24Happened]	    ;just note event
	pop	ax
	mov	al,0			    ;Fail call
	iret

i11:
	inc	_TEXT:[fFlushingBuffers]
i12:
	mov	_TEXT:[fInt24Happened], 0
	mov	ah, D2_ResetDisk
	int	21H
	cmp	_TEXT:[fInt24Happened], 0
	jne	i12

	dec	_TEXT:[fFlushingBuffers]

	; all buffers are flushed now, tear down the stack and return
	; with carry set and an error in AX

	add	sp, 2			;dump save ax
	mov	di,sp			;set the carry bit on in the flags
	or	ss:word ptr[di].28,1	;word on the user stack
	add	sp,8			;disgard ip,cs,flags,ax
	pop	Bx			;restore users register at int 21
	pop	Cx
	pop	Dx
	pop	Si
	pop	Di
	pop	Bp
	pop	Ds
	pop	Es
	mov	Ax,ERROR_FAIL_I24	;fail on int 24--hope API understands
	iret
i19:
	call	crit_err_accum	    ;@@ get critical error data.
	pop	ax
	mov	al,3			;On DOS 3.x just fail the system call
	iret

myInt24 endp

_TEXT	ends

	end
