;       SCCSID = @(#)d_brest.asm	6.1 91/02/15
;	SCCSID = @(#)d_brest.asm	1.4 90/01/22
; ****************************************************************************
; *									     *
; *			  IBM/Microsoft Confidential			     *
; *									     *
; *		    Copyright (c) IBM Corporation  1987, 1990		     *
; *		    Copyright (c) Microsoft Corp.  1987, 1990		     *
; *			      All Rights Reserved			     *
; *									     *
; ****************************************************************************
;
;	Modification History
;
;	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.
;
;	11-June-87 (CWY): add call to api_get_extended after the int 21
;			  returns error.
;
;	17-June-87 (stevee): fix to insure that all FAPI file handles are
;	less than MAX_HANDLES (p5553)

;	17-June-87 (robertc) routine re-written using subroutine to do
;	the handle flushing. Now only handles marked valid in DOSOPEN's
;	handle table will be flushed. PTM 5550
;

;	24-July-87 (robertc) p6581 fix infinite loop

;	16-Aug-88 (robertc) p1669 put handle into AX before call to
;	Flush_handle.
;
;/*************** START OF SPECIFICATIONS ******************************/
;/*								       */
;/* SUBROUTINE NAME: DosBufReset				       */
;/*								       */
;/* SOURCE FILE NAME: D_BREST.ASM				       */
;/*								       */
;/* DESCRIPTIVE NAME: Dos Buffer Reset				       */
;/*								       */
;/* FUNCTION:  Commits a file					       */
;/*								       */
;/* NOTES:  @@ DosBufReset is a new routine to the 1.10 Family API     */
;/*	    Library.						       */
;/*								       */
;/*	    When called in a pre PC DOS V3.30 environment,	       */
;/*	    DosBufReset will issue a Disk Reset interrupt	       */
;/*	    to flush the buffers.  The file handle to be	       */
;/*	    reset will be duplicated then closed to update	       */
;/*	    the directory listing.				       */
;/*								       */
;/*								       */
;/* ENTRY POINT:						       */
;/*	    LINKAGE:  EXTRN DosBufReset:FAR			       */
;/*								       */
;/* INPUT:	      PUSH  WORD  FileHandle	;File handle	       */
;/*		      call  DosBufReset				       */
;/*								       */
;/*								       */
;/* EXIT-NORMAL:  AX = 0					       */
;/*								       */
;/* EXIT-ERROR:	 AX = Error Code				       */
;/*								       */
;/*    ReturnCode Value = 6, Error_invalid_handle		       */
;/*								       */
;/* EFFECTS:  BP and ES registers are saved.			       */
;/*								       */
;/* PSUEDO CODE:						       */
;/*								       */
;/*	save registers						       */
;/*								       */
;/*	get DOS version						       */
;/*								       */
;/*	use BP as pointer to stack parameters			       */
;/*								       */
;/*	Issue a disk reset to flush all buffers			       */
;/*	Duplicate file handle					       */
;/*	Close the duplicated file handle to update directory	       */
;/*								       */
;/*	AX=0							       */
;/*								       */
;/* DosBufResetError:						       */
;/*								       */
;/*	restore registers					       */
;/*								       */
;/*	return clearing stack frame				       */
;/*								       */
;/* INTERNAL REFERENCES:					       */
;/*    ROUTINES:						       */
;/*								       */
;/* EXTERNAL REFERENCES:					       */
;/*    ROUTINES:    INT 21H FUNCTION 6800H    COMMIT A FILE	       */
;/*		    INT 21H FUNCTION 3000H    GET DOS VERSION	       */
;/*		    INT 21H FUNCTION 3E00H    CLOSE A FILE	       */
;/*		    INT 21H FUNCTION 4500H    DUPLICATE A FILE HANDLE  */
;/*		    INT 21H FUNCTION 0D00H    DISK RESET	       */
;/*								       */
;/*************** END OF SPECIFICATIONS ********************************/
;
;
; LIBRARIES
;
.XLIST
include error2.inc
include error.inc
include api.inc

	EXTRN	api_get_extended:far	 ;@@ support for DOSErrorClass
	EXTRN	__api_begin:near
	EXTRN	__api_end:near
	EXTRN	__api_devtab_ptr:near
	extrn __api_dev_table : word
.LIST
;
; PUBLIC SYMBOLS
;
	PUBLIC	DosBufReset

	PAGE

_TEXT	segment byte public 'CODE'
	assume	CS:_TEXT,DS:NOTHING
;
; stack frame:
; +0	bp
; +2	ip
; +4	cs
; +6	file handle
;
str	struc
old_bp		dw	?
return		dd	?
filehandle	dw	?
str	ends

;
DosBufReset	PROC	FAR

	call	__api_begin	; init bp and save bp,ds,bx,cx,dx,si,di,es
				; required to save: bp,es + cx
		mov	ah,0Dh			; Disk reset causes buffers to
		int	21H			; Flush, no directories updated

		mov	Cx,[bp].FileHandle

		cmp	Cx,0ffffH		; For all file handles, or a
		je	Do_all			; specfic one, ffffh = all

		cmp	cx,MAX_HANDLES		;@@ check for valid specific hndl
		jb	br0			;@@ handle is valid, continue
		mov	ax,ERROR_INVALID_HANDLE ;@@ handle out of range
		jmp	short Normal_Exit	;@@ quit

br0:
		mov	ax,cx			;p3231 Handle must be in AX for
						;   flush_handle
		call	Flush_handle		; we know here that ffffH is NOT
						; the handle number.
		jmp	Normal_exit		; Flush_handle returns error
						; in AX if any.

Do_all:
		xor	cx,cx			; Start at handle 0
Do_all_loop:
		mov	ax,cx			;p3231 Handle must be in AX for
						;   flush_handle
		call	Flush_handle		; Try to flush it and ignore
						; errors
		inc	cx			; next handle
		cmp	cx,MAX_HANDLES		; will the next one break us?
		jb	Do_all_loop		; if not do next one
		xor	ax,ax			;@@ Really ignore the errors

Normal_exit:
;

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

		ret	size str - 6		; Clear stack frame
DosBufReset	ENDP

;Flush_handle : internal subroutine
; on entry: AX => Handle to Flush
; on exit : AX => 0 for no error, Error_Code for error if carry set
; all registers except AX are preserved.


Flush_handle	PROC	NEAR
		push	bx	       ; save users BX

		call	__api_devtab_ptr	 ; cs[bx] => handinfo
		test	cs:[bx].hi_validity,HANDLE_VALID   ; is handle valid
		jz	Not_in_table		; no, report not_in_table

		mov	bx,cx
		mov	ah,45h			; BX = file handle to duplicate
		int	21H			; Dup file handle into Ax
		jc	Invalid_handle		;@@

; close_handle
		push	Bx			; Save handle that was dupped
		mov	Bx,AX			; BX = handle to close
		mov	ah,3Eh			; Close dupped file handle
		int	21H
		pop	Bx
		jc	Invalid_handle		; @@

		xor	ax, ax			;@@clear ax (no error condition)
		jmp	short	Exit
Not_in_table:
		mov	ax,  ERROR_INVALID_HANDLE ;set error cause not in table
		jmp	short	ErrorExit
Invalid_handle:
		call	api_get_extended       ; @@ get extended code
ErrorExit:				       ;p3231 only set carry on error
		stc
Exit:
		pop	bx
		ret
Flush_handle	ENDP
_TEXT	ends
		END
